drm/radeon: properly set up the RLC on ON/LN/TN (v3)
This is required for certain advanced functionality. v2: save/restore list takes dword offsets v3: rebase on gpu reset changes Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
138e4e16f0
commit
2948f5e6c2
1081
drivers/gpu/drm/radeon/clearstate_cayman.h
Normal file
1081
drivers/gpu/drm/radeon/clearstate_cayman.h
Normal file
File diff suppressed because it is too large
Load Diff
44
drivers/gpu/drm/radeon/clearstate_defs.h
Normal file
44
drivers/gpu/drm/radeon/clearstate_defs.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2012 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef CLEARSTATE_DEFS_H
|
||||
#define CLEARSTATE_DEFS_H
|
||||
|
||||
enum section_id {
|
||||
SECT_NONE,
|
||||
SECT_CONTEXT,
|
||||
SECT_CLEAR,
|
||||
SECT_CTRLCONST
|
||||
};
|
||||
|
||||
struct cs_extent_def {
|
||||
const unsigned int *extent;
|
||||
const unsigned int reg_index;
|
||||
const unsigned int reg_count;
|
||||
};
|
||||
|
||||
struct cs_section_def {
|
||||
const struct cs_extent_def *section;
|
||||
const enum section_id id;
|
||||
};
|
||||
|
||||
#endif
|
1080
drivers/gpu/drm/radeon/clearstate_evergreen.h
Normal file
1080
drivers/gpu/drm/radeon/clearstate_evergreen.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -45,6 +45,94 @@ static const u32 crtc_offsets[6] =
|
||||
EVERGREEN_CRTC5_REGISTER_OFFSET
|
||||
};
|
||||
|
||||
#include "clearstate_evergreen.h"
|
||||
|
||||
static u32 sumo_rlc_save_restore_register_list[] =
|
||||
{
|
||||
0x98fc,
|
||||
0x9830,
|
||||
0x9834,
|
||||
0x9838,
|
||||
0x9870,
|
||||
0x9874,
|
||||
0x8a14,
|
||||
0x8b24,
|
||||
0x8bcc,
|
||||
0x8b10,
|
||||
0x8d00,
|
||||
0x8d04,
|
||||
0x8c00,
|
||||
0x8c04,
|
||||
0x8c08,
|
||||
0x8c0c,
|
||||
0x8d8c,
|
||||
0x8c20,
|
||||
0x8c24,
|
||||
0x8c28,
|
||||
0x8c18,
|
||||
0x8c1c,
|
||||
0x8cf0,
|
||||
0x8e2c,
|
||||
0x8e38,
|
||||
0x8c30,
|
||||
0x9508,
|
||||
0x9688,
|
||||
0x9608,
|
||||
0x960c,
|
||||
0x9610,
|
||||
0x9614,
|
||||
0x88c4,
|
||||
0x88d4,
|
||||
0xa008,
|
||||
0x900c,
|
||||
0x9100,
|
||||
0x913c,
|
||||
0x98f8,
|
||||
0x98f4,
|
||||
0x9b7c,
|
||||
0x3f8c,
|
||||
0x8950,
|
||||
0x8954,
|
||||
0x8a18,
|
||||
0x8b28,
|
||||
0x9144,
|
||||
0x9148,
|
||||
0x914c,
|
||||
0x3f90,
|
||||
0x3f94,
|
||||
0x915c,
|
||||
0x9160,
|
||||
0x9178,
|
||||
0x917c,
|
||||
0x9180,
|
||||
0x918c,
|
||||
0x9190,
|
||||
0x9194,
|
||||
0x9198,
|
||||
0x919c,
|
||||
0x91a8,
|
||||
0x91ac,
|
||||
0x91b0,
|
||||
0x91b4,
|
||||
0x91b8,
|
||||
0x91c4,
|
||||
0x91c8,
|
||||
0x91cc,
|
||||
0x91d0,
|
||||
0x91d4,
|
||||
0x91e0,
|
||||
0x91e4,
|
||||
0x91ec,
|
||||
0x91f0,
|
||||
0x91f4,
|
||||
0x9200,
|
||||
0x9204,
|
||||
0x929c,
|
||||
0x9150,
|
||||
0x802c,
|
||||
};
|
||||
static u32 sumo_rlc_save_restore_register_list_size = ARRAY_SIZE(sumo_rlc_save_restore_register_list);
|
||||
|
||||
static void evergreen_gpu_init(struct radeon_device *rdev);
|
||||
void evergreen_fini(struct radeon_device *rdev);
|
||||
void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
|
||||
@ -3723,6 +3811,241 @@ bool evergreen_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin
|
||||
return radeon_ring_test_lockup(rdev, ring);
|
||||
}
|
||||
|
||||
/*
|
||||
* RLC
|
||||
*/
|
||||
#define RLC_SAVE_RESTORE_LIST_END_MARKER 0x00000000
|
||||
#define RLC_CLEAR_STATE_END_MARKER 0x00000001
|
||||
|
||||
void sumo_rlc_fini(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* save restore block */
|
||||
if (rdev->rlc.save_restore_obj) {
|
||||
r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r);
|
||||
radeon_bo_unpin(rdev->rlc.save_restore_obj);
|
||||
radeon_bo_unreserve(rdev->rlc.save_restore_obj);
|
||||
|
||||
radeon_bo_unref(&rdev->rlc.save_restore_obj);
|
||||
rdev->rlc.save_restore_obj = NULL;
|
||||
}
|
||||
|
||||
/* clear state block */
|
||||
if (rdev->rlc.clear_state_obj) {
|
||||
r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
|
||||
if (unlikely(r != 0))
|
||||
dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r);
|
||||
radeon_bo_unpin(rdev->rlc.clear_state_obj);
|
||||
radeon_bo_unreserve(rdev->rlc.clear_state_obj);
|
||||
|
||||
radeon_bo_unref(&rdev->rlc.clear_state_obj);
|
||||
rdev->rlc.clear_state_obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int sumo_rlc_init(struct radeon_device *rdev)
|
||||
{
|
||||
u32 *src_ptr;
|
||||
volatile u32 *dst_ptr;
|
||||
u32 dws, data, i, j, k, reg_num;
|
||||
u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index;
|
||||
u64 reg_list_mc_addr;
|
||||
struct cs_section_def *cs_data;
|
||||
int r;
|
||||
|
||||
src_ptr = rdev->rlc.reg_list;
|
||||
dws = rdev->rlc.reg_list_size;
|
||||
cs_data = rdev->rlc.cs_data;
|
||||
|
||||
/* save restore block */
|
||||
if (rdev->rlc.save_restore_obj == NULL) {
|
||||
r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
|
||||
RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.save_restore_obj);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
sumo_rlc_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->rlc.save_restore_gpu_addr);
|
||||
if (r) {
|
||||
radeon_bo_unreserve(rdev->rlc.save_restore_obj);
|
||||
dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
|
||||
sumo_rlc_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
|
||||
sumo_rlc_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
/* write the sr buffer */
|
||||
dst_ptr = rdev->rlc.sr_ptr;
|
||||
/* format:
|
||||
* dw0: (reg2 << 16) | reg1
|
||||
* dw1: reg1 save space
|
||||
* dw2: reg2 save space
|
||||
*/
|
||||
for (i = 0; i < dws; i++) {
|
||||
data = src_ptr[i] >> 2;
|
||||
i++;
|
||||
if (i < dws)
|
||||
data |= (src_ptr[i] >> 2) << 16;
|
||||
j = (((i - 1) * 3) / 2);
|
||||
dst_ptr[j] = data;
|
||||
}
|
||||
j = ((i * 3) / 2);
|
||||
dst_ptr[j] = RLC_SAVE_RESTORE_LIST_END_MARKER;
|
||||
|
||||
radeon_bo_kunmap(rdev->rlc.save_restore_obj);
|
||||
radeon_bo_unreserve(rdev->rlc.save_restore_obj);
|
||||
|
||||
/* clear state block */
|
||||
reg_list_num = 0;
|
||||
dws = 0;
|
||||
for (i = 0; cs_data[i].section != NULL; i++) {
|
||||
for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
|
||||
reg_list_num++;
|
||||
dws += cs_data[i].section[j].reg_count;
|
||||
}
|
||||
}
|
||||
reg_list_blk_index = (3 * reg_list_num + 2);
|
||||
dws += reg_list_blk_index;
|
||||
|
||||
if (rdev->rlc.clear_state_obj == NULL) {
|
||||
r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
|
||||
RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.clear_state_obj);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
|
||||
sumo_rlc_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
|
||||
if (unlikely(r != 0)) {
|
||||
sumo_rlc_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
|
||||
&rdev->rlc.clear_state_gpu_addr);
|
||||
if (r) {
|
||||
|
||||
radeon_bo_unreserve(rdev->rlc.clear_state_obj);
|
||||
dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
|
||||
sumo_rlc_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
|
||||
if (r) {
|
||||
dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
|
||||
sumo_rlc_fini(rdev);
|
||||
return r;
|
||||
}
|
||||
/* set up the cs buffer */
|
||||
dst_ptr = rdev->rlc.cs_ptr;
|
||||
reg_list_hdr_blk_index = 0;
|
||||
reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
|
||||
data = upper_32_bits(reg_list_mc_addr);
|
||||
dst_ptr[reg_list_hdr_blk_index] = data;
|
||||
reg_list_hdr_blk_index++;
|
||||
for (i = 0; cs_data[i].section != NULL; i++) {
|
||||
for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
|
||||
reg_num = cs_data[i].section[j].reg_count;
|
||||
data = reg_list_mc_addr & 0xffffffff;
|
||||
dst_ptr[reg_list_hdr_blk_index] = data;
|
||||
reg_list_hdr_blk_index++;
|
||||
|
||||
data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
|
||||
dst_ptr[reg_list_hdr_blk_index] = data;
|
||||
reg_list_hdr_blk_index++;
|
||||
|
||||
data = 0x08000000 | (reg_num * 4);
|
||||
dst_ptr[reg_list_hdr_blk_index] = data;
|
||||
reg_list_hdr_blk_index++;
|
||||
|
||||
for (k = 0; k < reg_num; k++) {
|
||||
data = cs_data[i].section[j].extent[k];
|
||||
dst_ptr[reg_list_blk_index + k] = data;
|
||||
}
|
||||
reg_list_mc_addr += reg_num * 4;
|
||||
reg_list_blk_index += reg_num;
|
||||
}
|
||||
}
|
||||
dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER;
|
||||
|
||||
radeon_bo_kunmap(rdev->rlc.clear_state_obj);
|
||||
radeon_bo_unreserve(rdev->rlc.clear_state_obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void evergreen_rlc_start(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
WREG32(RLC_CNTL, RLC_ENABLE | GFX_POWER_GATING_ENABLE | GFX_POWER_GATING_SRC);
|
||||
else
|
||||
WREG32(RLC_CNTL, RLC_ENABLE);
|
||||
}
|
||||
|
||||
int evergreen_rlc_resume(struct radeon_device *rdev)
|
||||
{
|
||||
u32 i;
|
||||
const __be32 *fw_data;
|
||||
|
||||
if (!rdev->rlc_fw)
|
||||
return -EINVAL;
|
||||
|
||||
r600_rlc_stop(rdev);
|
||||
|
||||
WREG32(RLC_HB_CNTL, 0);
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
|
||||
WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
|
||||
} else {
|
||||
WREG32(RLC_HB_BASE, 0);
|
||||
WREG32(RLC_HB_RPTR, 0);
|
||||
WREG32(RLC_HB_WPTR, 0);
|
||||
}
|
||||
WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
|
||||
WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
|
||||
WREG32(RLC_MC_CNTL, 0);
|
||||
WREG32(RLC_UCODE_CNTL, 0);
|
||||
|
||||
fw_data = (const __be32 *)rdev->rlc_fw->data;
|
||||
if (rdev->family >= CHIP_ARUBA) {
|
||||
for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
} else if (rdev->family >= CHIP_CAYMAN) {
|
||||
for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
}
|
||||
WREG32(RLC_UCODE_ADDR, 0);
|
||||
|
||||
evergreen_rlc_start(rdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Interrupts */
|
||||
|
||||
u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
|
||||
@ -4721,6 +5044,18 @@ static int evergreen_startup(struct radeon_device *rdev)
|
||||
dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
|
||||
}
|
||||
|
||||
/* allocate rlc buffers */
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
rdev->rlc.reg_list = sumo_rlc_save_restore_register_list;
|
||||
rdev->rlc.reg_list_size = sumo_rlc_save_restore_register_list_size;
|
||||
rdev->rlc.cs_data = evergreen_cs_data;
|
||||
r = sumo_rlc_init(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to init rlc BOs!\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate wb buffer */
|
||||
r = radeon_wb_init(rdev);
|
||||
if (r)
|
||||
@ -4952,6 +5287,8 @@ int evergreen_init(struct radeon_device *rdev)
|
||||
r700_cp_fini(rdev);
|
||||
r600_dma_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
sumo_rlc_fini(rdev);
|
||||
radeon_wb_fini(rdev);
|
||||
radeon_ib_pool_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
@ -4980,6 +5317,8 @@ void evergreen_fini(struct radeon_device *rdev)
|
||||
r700_cp_fini(rdev);
|
||||
r600_dma_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
sumo_rlc_fini(rdev);
|
||||
radeon_wb_fini(rdev);
|
||||
radeon_ib_pool_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
|
@ -90,6 +90,25 @@
|
||||
#define CG_VCLK_STATUS 0x61c
|
||||
#define CG_SCRATCH1 0x820
|
||||
|
||||
#define RLC_CNTL 0x3f00
|
||||
# define RLC_ENABLE (1 << 0)
|
||||
# define GFX_POWER_GATING_ENABLE (1 << 7)
|
||||
# define GFX_POWER_GATING_SRC (1 << 8)
|
||||
#define RLC_HB_BASE 0x3f10
|
||||
#define RLC_HB_CNTL 0x3f0c
|
||||
#define RLC_HB_RPTR 0x3f20
|
||||
#define RLC_HB_WPTR 0x3f1c
|
||||
#define RLC_HB_WPTR_LSB_ADDR 0x3f14
|
||||
#define RLC_HB_WPTR_MSB_ADDR 0x3f18
|
||||
#define RLC_MC_CNTL 0x3f44
|
||||
#define RLC_UCODE_CNTL 0x3f48
|
||||
#define RLC_UCODE_ADDR 0x3f2c
|
||||
#define RLC_UCODE_DATA 0x3f30
|
||||
|
||||
/* new for TN */
|
||||
#define TN_RLC_SAVE_AND_RESTORE_BASE 0x3f10
|
||||
#define TN_RLC_CLEAR_STATE_RESTORE_BASE 0x3f20
|
||||
|
||||
#define GRBM_GFX_INDEX 0x802C
|
||||
#define INSTANCE_INDEX(x) ((x) << 0)
|
||||
#define SE_INDEX(x) ((x) << 16)
|
||||
|
@ -34,6 +34,134 @@
|
||||
#include "ni_reg.h"
|
||||
#include "cayman_blit_shaders.h"
|
||||
#include "radeon_ucode.h"
|
||||
#include "clearstate_cayman.h"
|
||||
|
||||
static u32 tn_rlc_save_restore_register_list[] =
|
||||
{
|
||||
0x98fc,
|
||||
0x98f0,
|
||||
0x9834,
|
||||
0x9838,
|
||||
0x9870,
|
||||
0x9874,
|
||||
0x8a14,
|
||||
0x8b24,
|
||||
0x8bcc,
|
||||
0x8b10,
|
||||
0x8c30,
|
||||
0x8d00,
|
||||
0x8d04,
|
||||
0x8c00,
|
||||
0x8c04,
|
||||
0x8c10,
|
||||
0x8c14,
|
||||
0x8d8c,
|
||||
0x8cf0,
|
||||
0x8e38,
|
||||
0x9508,
|
||||
0x9688,
|
||||
0x9608,
|
||||
0x960c,
|
||||
0x9610,
|
||||
0x9614,
|
||||
0x88c4,
|
||||
0x8978,
|
||||
0x88d4,
|
||||
0x900c,
|
||||
0x9100,
|
||||
0x913c,
|
||||
0x90e8,
|
||||
0x9354,
|
||||
0xa008,
|
||||
0x98f8,
|
||||
0x9148,
|
||||
0x914c,
|
||||
0x3f94,
|
||||
0x98f4,
|
||||
0x9b7c,
|
||||
0x3f8c,
|
||||
0x8950,
|
||||
0x8954,
|
||||
0x8a18,
|
||||
0x8b28,
|
||||
0x9144,
|
||||
0x3f90,
|
||||
0x915c,
|
||||
0x9160,
|
||||
0x9178,
|
||||
0x917c,
|
||||
0x9180,
|
||||
0x918c,
|
||||
0x9190,
|
||||
0x9194,
|
||||
0x9198,
|
||||
0x919c,
|
||||
0x91a8,
|
||||
0x91ac,
|
||||
0x91b0,
|
||||
0x91b4,
|
||||
0x91b8,
|
||||
0x91c4,
|
||||
0x91c8,
|
||||
0x91cc,
|
||||
0x91d0,
|
||||
0x91d4,
|
||||
0x91e0,
|
||||
0x91e4,
|
||||
0x91ec,
|
||||
0x91f0,
|
||||
0x91f4,
|
||||
0x9200,
|
||||
0x9204,
|
||||
0x929c,
|
||||
0x8030,
|
||||
0x9150,
|
||||
0x9a60,
|
||||
0x920c,
|
||||
0x9210,
|
||||
0x9228,
|
||||
0x922c,
|
||||
0x9244,
|
||||
0x9248,
|
||||
0x91e8,
|
||||
0x9294,
|
||||
0x9208,
|
||||
0x9224,
|
||||
0x9240,
|
||||
0x9220,
|
||||
0x923c,
|
||||
0x9258,
|
||||
0x9744,
|
||||
0xa200,
|
||||
0xa204,
|
||||
0xa208,
|
||||
0xa20c,
|
||||
0x8d58,
|
||||
0x9030,
|
||||
0x9034,
|
||||
0x9038,
|
||||
0x903c,
|
||||
0x9040,
|
||||
0x9654,
|
||||
0x897c,
|
||||
0xa210,
|
||||
0xa214,
|
||||
0x9868,
|
||||
0xa02c,
|
||||
0x9664,
|
||||
0x9698,
|
||||
0x949c,
|
||||
0x8e10,
|
||||
0x8e18,
|
||||
0x8c50,
|
||||
0x8c58,
|
||||
0x8c60,
|
||||
0x8c68,
|
||||
0x89b4,
|
||||
0x9830,
|
||||
0x802c,
|
||||
};
|
||||
static u32 tn_rlc_save_restore_register_list_size = ARRAY_SIZE(tn_rlc_save_restore_register_list);
|
||||
|
||||
extern bool evergreen_is_display_hung(struct radeon_device *rdev);
|
||||
extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
|
||||
@ -45,8 +173,8 @@ extern void evergreen_irq_suspend(struct radeon_device *rdev);
|
||||
extern int evergreen_mc_init(struct radeon_device *rdev);
|
||||
extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
|
||||
extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
|
||||
extern void si_rlc_fini(struct radeon_device *rdev);
|
||||
extern int si_rlc_init(struct radeon_device *rdev);
|
||||
extern void sumo_rlc_fini(struct radeon_device *rdev);
|
||||
extern int sumo_rlc_init(struct radeon_device *rdev);
|
||||
|
||||
/* Firmware Names */
|
||||
MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
|
||||
@ -1969,7 +2097,10 @@ static int cayman_startup(struct radeon_device *rdev)
|
||||
|
||||
/* allocate rlc buffers */
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
r = si_rlc_init(rdev);
|
||||
rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
|
||||
rdev->rlc.reg_list_size = tn_rlc_save_restore_register_list_size;
|
||||
rdev->rlc.cs_data = cayman_cs_data;
|
||||
r = sumo_rlc_init(rdev);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to init rlc BOs!\n");
|
||||
return r;
|
||||
@ -2226,7 +2357,7 @@ int cayman_init(struct radeon_device *rdev)
|
||||
cayman_dma_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
si_rlc_fini(rdev);
|
||||
sumo_rlc_fini(rdev);
|
||||
radeon_wb_fini(rdev);
|
||||
radeon_ib_pool_fini(rdev);
|
||||
radeon_vm_manager_fini(rdev);
|
||||
@ -2257,7 +2388,7 @@ void cayman_fini(struct radeon_device *rdev)
|
||||
cayman_dma_fini(rdev);
|
||||
r600_irq_fini(rdev);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
si_rlc_fini(rdev);
|
||||
sumo_rlc_fini(rdev);
|
||||
radeon_wb_fini(rdev);
|
||||
radeon_vm_manager_fini(rdev);
|
||||
radeon_ib_pool_fini(rdev);
|
||||
|
@ -97,6 +97,7 @@ static void r600_gpu_init(struct radeon_device *rdev);
|
||||
void r600_fini(struct radeon_device *rdev);
|
||||
void r600_irq_disable(struct radeon_device *rdev);
|
||||
static void r600_pcie_gen2_enable(struct radeon_device *rdev);
|
||||
extern int evergreen_rlc_resume(struct radeon_device *rdev);
|
||||
|
||||
/**
|
||||
* r600_get_xclk - get the xclk
|
||||
@ -3778,7 +3779,7 @@ static void r600_rlc_start(struct radeon_device *rdev)
|
||||
WREG32(RLC_CNTL, RLC_ENABLE);
|
||||
}
|
||||
|
||||
static int r600_rlc_init(struct radeon_device *rdev)
|
||||
static int r600_rlc_resume(struct radeon_device *rdev)
|
||||
{
|
||||
u32 i;
|
||||
const __be32 *fw_data;
|
||||
@ -3790,39 +3791,16 @@ static int r600_rlc_init(struct radeon_device *rdev)
|
||||
|
||||
WREG32(RLC_HB_CNTL, 0);
|
||||
|
||||
if (rdev->family == CHIP_ARUBA) {
|
||||
WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
|
||||
WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
|
||||
}
|
||||
if (rdev->family <= CHIP_CAYMAN) {
|
||||
WREG32(RLC_HB_BASE, 0);
|
||||
WREG32(RLC_HB_RPTR, 0);
|
||||
WREG32(RLC_HB_WPTR, 0);
|
||||
}
|
||||
if (rdev->family <= CHIP_CAICOS) {
|
||||
WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
|
||||
WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
|
||||
}
|
||||
WREG32(RLC_HB_BASE, 0);
|
||||
WREG32(RLC_HB_RPTR, 0);
|
||||
WREG32(RLC_HB_WPTR, 0);
|
||||
WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
|
||||
WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
|
||||
WREG32(RLC_MC_CNTL, 0);
|
||||
WREG32(RLC_UCODE_CNTL, 0);
|
||||
|
||||
fw_data = (const __be32 *)rdev->rlc_fw->data;
|
||||
if (rdev->family >= CHIP_ARUBA) {
|
||||
for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
} else if (rdev->family >= CHIP_CAYMAN) {
|
||||
for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
} else if (rdev->family >= CHIP_CEDAR) {
|
||||
for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
}
|
||||
} else if (rdev->family >= CHIP_RV770) {
|
||||
if (rdev->family >= CHIP_RV770) {
|
||||
for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
|
||||
WREG32(RLC_UCODE_ADDR, i);
|
||||
WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
|
||||
@ -3936,7 +3914,10 @@ int r600_irq_init(struct radeon_device *rdev)
|
||||
r600_disable_interrupts(rdev);
|
||||
|
||||
/* init rlc */
|
||||
ret = r600_rlc_init(rdev);
|
||||
if (rdev->family >= CHIP_CEDAR)
|
||||
ret = evergreen_rlc_resume(rdev);
|
||||
else
|
||||
ret = r600_rlc_resume(rdev);
|
||||
if (ret) {
|
||||
r600_ih_ring_fini(rdev);
|
||||
return ret;
|
||||
|
@ -684,10 +684,6 @@
|
||||
#define RLC_UCODE_ADDR 0x3f2c
|
||||
#define RLC_UCODE_DATA 0x3f30
|
||||
|
||||
/* new for TN */
|
||||
#define TN_RLC_SAVE_AND_RESTORE_BASE 0x3f10
|
||||
#define TN_RLC_CLEAR_STATE_RESTORE_BASE 0x3f20
|
||||
|
||||
#define SRBM_SOFT_RESET 0xe60
|
||||
# define SOFT_RESET_DMA (1 << 12)
|
||||
# define SOFT_RESET_RLC (1 << 13)
|
||||
|
@ -821,15 +821,22 @@ struct r600_blit {
|
||||
};
|
||||
|
||||
/*
|
||||
* SI RLC stuff
|
||||
* RLC stuff
|
||||
*/
|
||||
struct si_rlc {
|
||||
#include "clearstate_defs.h"
|
||||
|
||||
struct radeon_rlc {
|
||||
/* for power gating */
|
||||
struct radeon_bo *save_restore_obj;
|
||||
uint64_t save_restore_gpu_addr;
|
||||
volatile uint32_t *sr_ptr;
|
||||
u32 *reg_list;
|
||||
u32 reg_list_size;
|
||||
/* for clear state */
|
||||
struct radeon_bo *clear_state_obj;
|
||||
uint64_t clear_state_gpu_addr;
|
||||
volatile uint32_t *cs_ptr;
|
||||
struct cs_section_def *cs_data;
|
||||
};
|
||||
|
||||
int radeon_ib_get(struct radeon_device *rdev, int ring,
|
||||
@ -1773,7 +1780,7 @@ struct radeon_device {
|
||||
struct r600_vram_scratch vram_scratch;
|
||||
int msi_enabled; /* msi enabled */
|
||||
struct r600_ih ih; /* r6/700 interrupt ring */
|
||||
struct si_rlc rlc;
|
||||
struct radeon_rlc rlc;
|
||||
struct radeon_mec mec;
|
||||
struct work_struct hotplug_work;
|
||||
struct work_struct audio_work;
|
||||
|
Loading…
Reference in New Issue
Block a user