mirror of
https://github.com/torvalds/linux.git
synced 2024-11-07 20:51:47 +00:00
Merge branch 'drm-radeon-fusion' of ../drm-radeon-next into drm-core-next
* 'drm-radeon-fusion' of ../drm-radeon-next: drm/radeon/kms: add Ontario APU ucode loading support drm/radeon/kms: add Ontario Fusion APU pci ids drm/radeon/kms: enable MSIs on fusion APUs drm/radeon/kms: add power table parsing support for Ontario fusion APUs drm/radeon/kms: refactor atombios power state fetching drm/radeon/kms: add bo blit support for Ontario fusion APUs drm/radeon/kms: add thermal sensor support for fusion APUs drm/radeon/kms: fill in GPU init for AMD Ontario Fusion APUs drm/radeon/kms: add radeon_asic struct for AMD Ontario fusion APUs drm/radeon/kms: evergreen.c updates for fusion drm/radeon/kms: MC setup changes for fusion APUs drm/radeon/kms: move r7xx/evergreen to its own vram_gtt setup function drm/radeon/kms: add support for ss overrides on Fusion APUs drm/radeon/kms: Add support for external encoders on fusion APUs drm/radeon/kms: atom changes for DCE4.1 devices drm/radeon/kms: add new family id for AMD Ontario APUs drm/radeon/kms: upstream power table updates drm/radeon/kms: upstream atombios.h updates drm/radeon/kms: upstream ObjectID.h updates drm/radeon/kms: setup mc chremap properly on r7xx/evergreen
This commit is contained in:
commit
f7eb0c5541
@ -37,6 +37,8 @@
|
||||
#define GRAPH_OBJECT_TYPE_CONNECTOR 0x3
|
||||
#define GRAPH_OBJECT_TYPE_ROUTER 0x4
|
||||
/* deleted */
|
||||
#define GRAPH_OBJECT_TYPE_DISPLAY_PATH 0x6
|
||||
#define GRAPH_OBJECT_TYPE_GENERIC 0x7
|
||||
|
||||
/****************************************************/
|
||||
/* Encoder Object ID Definition */
|
||||
@ -64,6 +66,9 @@
|
||||
#define ENCODER_OBJECT_ID_VT1623 0x10
|
||||
#define ENCODER_OBJECT_ID_HDMI_SI1930 0x11
|
||||
#define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12
|
||||
#define ENCODER_OBJECT_ID_ALMOND 0x22
|
||||
#define ENCODER_OBJECT_ID_TRAVIS 0x23
|
||||
#define ENCODER_OBJECT_ID_NUTMEG 0x22
|
||||
/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13
|
||||
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14
|
||||
@ -108,6 +113,7 @@
|
||||
#define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13
|
||||
#define CONNECTOR_OBJECT_ID_eDP 0x14
|
||||
#define CONNECTOR_OBJECT_ID_MXM 0x15
|
||||
#define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16
|
||||
|
||||
/* deleted */
|
||||
|
||||
@ -124,6 +130,7 @@
|
||||
#define GENERIC_OBJECT_ID_GLSYNC 0x01
|
||||
#define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02
|
||||
#define GENERIC_OBJECT_ID_MXM_OPM 0x03
|
||||
#define GENERIC_OBJECT_ID_STEREO_PIN 0x04 //This object could show up from Misc Object table, it follows ATOM_OBJECT format, and contains one ATOM_OBJECT_GPIO_CNTL_RECORD for the stereo pin
|
||||
|
||||
/****************************************************/
|
||||
/* Graphics Object ENUM ID Definition */
|
||||
@ -360,6 +367,26 @@
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_ALMOND_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_ALMOND_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_TRAVIS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_TRAVIS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT)
|
||||
|
||||
#define ENCODER_NUTMEG_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Connector Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
@ -421,6 +448,14 @@
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
|
||||
@ -512,6 +547,7 @@
|
||||
#define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT)
|
||||
@ -593,6 +629,14 @@
|
||||
GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC
|
||||
|
||||
#define CONNECTOR_LVDS_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT)
|
||||
|
||||
#define CONNECTOR_LVDS_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
|
||||
CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Router Object ID definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
@ -621,6 +665,10 @@
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT)
|
||||
|
||||
#define GENERICOBJECT_STEREO_PIN_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
|
||||
GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
|
||||
GENERIC_OBJECT_ID_STEREO_PIN << OBJECT_ID_SHIFT)
|
||||
|
||||
/****************************************************/
|
||||
/* Object Cap definition - Shared with BIOS */
|
||||
/****************************************************/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -112,6 +112,14 @@ u32 evergreen_get_temp(struct radeon_device *rdev)
|
||||
return actual_temp * 1000;
|
||||
}
|
||||
|
||||
u32 sumo_get_temp(struct radeon_device *rdev)
|
||||
{
|
||||
u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff;
|
||||
u32 actual_temp = (temp >> 1) & 0xff;
|
||||
|
||||
return actual_temp * 1000;
|
||||
}
|
||||
|
||||
void evergreen_pm_misc(struct radeon_device *rdev)
|
||||
{
|
||||
int req_ps_idx = rdev->pm.requested_power_state_index;
|
||||
@ -943,31 +951,39 @@ static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa
|
||||
save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
|
||||
save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
|
||||
save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
|
||||
save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
|
||||
save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
|
||||
save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
|
||||
}
|
||||
|
||||
/* Stop all video */
|
||||
WREG32(VGA_RENDER_CONTROL, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
|
||||
}
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
|
||||
WREG32(D1VGA_CONTROL, 0);
|
||||
WREG32(D2VGA_CONTROL, 0);
|
||||
@ -997,6 +1013,7 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_
|
||||
WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
||||
(u32)rdev->mc.vram_start);
|
||||
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
||||
upper_32_bits(rdev->mc.vram_start));
|
||||
WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
||||
@ -1032,6 +1049,7 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_
|
||||
(u32)rdev->mc.vram_start);
|
||||
WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
||||
(u32)rdev->mc.vram_start);
|
||||
}
|
||||
|
||||
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
|
||||
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
|
||||
@ -1047,22 +1065,28 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_
|
||||
WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
|
||||
}
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]);
|
||||
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]);
|
||||
}
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
||||
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
|
||||
}
|
||||
|
||||
@ -1338,6 +1362,7 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
|
||||
switch (rdev->family) {
|
||||
case CHIP_CEDAR:
|
||||
case CHIP_REDWOOD:
|
||||
case CHIP_PALM:
|
||||
force_no_swizzle = false;
|
||||
break;
|
||||
case CHIP_CYPRESS:
|
||||
@ -1437,6 +1462,43 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
|
||||
return backend_map;
|
||||
}
|
||||
|
||||
static void evergreen_program_channel_remap(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp;
|
||||
|
||||
tmp = RREG32(MC_SHARED_CHMAP);
|
||||
switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
default:
|
||||
/* default mapping */
|
||||
mc_shared_chremap = 0x00fac688;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (rdev->family) {
|
||||
case CHIP_HEMLOCK:
|
||||
case CHIP_CYPRESS:
|
||||
tcp_chan_steer_lo = 0x54763210;
|
||||
tcp_chan_steer_hi = 0x0000ba98;
|
||||
break;
|
||||
case CHIP_JUNIPER:
|
||||
case CHIP_REDWOOD:
|
||||
case CHIP_CEDAR:
|
||||
case CHIP_PALM:
|
||||
default:
|
||||
tcp_chan_steer_lo = 0x76543210;
|
||||
tcp_chan_steer_hi = 0x0000ba98;
|
||||
break;
|
||||
}
|
||||
|
||||
WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo);
|
||||
WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi);
|
||||
WREG32(MC_SHARED_CHREMAP, mc_shared_chremap);
|
||||
}
|
||||
|
||||
static void evergreen_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
u32 cc_rb_backend_disable = 0;
|
||||
@ -1544,6 +1606,27 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
||||
rdev->config.evergreen.max_hw_contexts = 4;
|
||||
rdev->config.evergreen.sq_num_cf_insts = 1;
|
||||
|
||||
rdev->config.evergreen.sc_prim_fifo_size = 0x40;
|
||||
rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
|
||||
rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
|
||||
break;
|
||||
case CHIP_PALM:
|
||||
rdev->config.evergreen.num_ses = 1;
|
||||
rdev->config.evergreen.max_pipes = 2;
|
||||
rdev->config.evergreen.max_tile_pipes = 2;
|
||||
rdev->config.evergreen.max_simds = 2;
|
||||
rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
|
||||
rdev->config.evergreen.max_gprs = 256;
|
||||
rdev->config.evergreen.max_threads = 192;
|
||||
rdev->config.evergreen.max_gs_threads = 16;
|
||||
rdev->config.evergreen.max_stack_entries = 256;
|
||||
rdev->config.evergreen.sx_num_of_sets = 4;
|
||||
rdev->config.evergreen.sx_max_export_size = 128;
|
||||
rdev->config.evergreen.sx_max_export_pos_size = 32;
|
||||
rdev->config.evergreen.sx_max_export_smx_size = 96;
|
||||
rdev->config.evergreen.max_hw_contexts = 4;
|
||||
rdev->config.evergreen.sq_num_cf_insts = 1;
|
||||
|
||||
rdev->config.evergreen.sc_prim_fifo_size = 0x40;
|
||||
rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
|
||||
rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
|
||||
@ -1740,6 +1823,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
||||
WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
|
||||
WREG32(HDP_ADDR_CONFIG, gb_addr_config);
|
||||
|
||||
evergreen_program_channel_remap(rdev);
|
||||
|
||||
num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1;
|
||||
grbm_gfx_index = INSTANCE_BROADCAST_WRITES;
|
||||
|
||||
@ -1822,9 +1907,15 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
||||
GS_PRIO(2) |
|
||||
ES_PRIO(3));
|
||||
|
||||
if (rdev->family == CHIP_CEDAR)
|
||||
switch (rdev->family) {
|
||||
case CHIP_CEDAR:
|
||||
case CHIP_PALM:
|
||||
/* no vertex cache */
|
||||
sq_config &= ~VC_ENABLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT);
|
||||
|
||||
@ -1836,10 +1927,15 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
||||
sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32);
|
||||
sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32);
|
||||
|
||||
if (rdev->family == CHIP_CEDAR)
|
||||
switch (rdev->family) {
|
||||
case CHIP_CEDAR:
|
||||
case CHIP_PALM:
|
||||
ps_thread_count = 96;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
ps_thread_count = 128;
|
||||
break;
|
||||
}
|
||||
|
||||
sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count);
|
||||
sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
|
||||
@ -1870,10 +1966,15 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
|
||||
WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
|
||||
FORCE_EOV_MAX_REZ_CNT(255)));
|
||||
|
||||
if (rdev->family == CHIP_CEDAR)
|
||||
switch (rdev->family) {
|
||||
case CHIP_CEDAR:
|
||||
case CHIP_PALM:
|
||||
vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC);
|
||||
break;
|
||||
}
|
||||
vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO);
|
||||
WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation);
|
||||
|
||||
@ -1957,12 +2058,18 @@ int evergreen_mc_init(struct radeon_device *rdev)
|
||||
rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
|
||||
rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
|
||||
/* Setup GPU memory space */
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
/* size in bytes on fusion */
|
||||
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
} else {
|
||||
/* size in MB on evergreen */
|
||||
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
|
||||
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
|
||||
}
|
||||
rdev->mc.visible_vram_size = rdev->mc.aper_size;
|
||||
rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
|
||||
r600_vram_gtt_location(rdev, &rdev->mc);
|
||||
r700_vram_gtt_location(rdev, &rdev->mc);
|
||||
radeon_update_bandwidth_info(rdev);
|
||||
|
||||
return 0;
|
||||
@ -2079,17 +2186,21 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev)
|
||||
WREG32(GRBM_INT_CNTL, 0);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
||||
}
|
||||
|
||||
WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
|
||||
WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
|
||||
@ -2205,10 +2316,12 @@ int evergreen_irq_set(struct radeon_device *rdev)
|
||||
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
|
||||
if (!(rdev->flags & RADEON_IS_IGP)) {
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
|
||||
WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
|
||||
}
|
||||
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
|
||||
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
|
||||
@ -2765,6 +2878,10 @@ static bool evergreen_card_posted(struct radeon_device *rdev)
|
||||
u32 reg;
|
||||
|
||||
/* first check CRTCs */
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
|
||||
RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
|
||||
else
|
||||
reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
|
||||
RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
|
||||
RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
|
||||
|
@ -147,7 +147,8 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
|
||||
radeon_ring_write(rdev, 0);
|
||||
radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30);
|
||||
|
||||
if (rdev->family == CHIP_CEDAR)
|
||||
if ((rdev->family == CHIP_CEDAR) ||
|
||||
(rdev->family == CHIP_PALM))
|
||||
cp_set_surface_sync(rdev,
|
||||
PACKET3_TC_ACTION_ENA, 48, gpu_addr);
|
||||
else
|
||||
@ -331,9 +332,31 @@ set_default_state(struct radeon_device *rdev)
|
||||
num_hs_stack_entries = 85;
|
||||
num_ls_stack_entries = 85;
|
||||
break;
|
||||
case CHIP_PALM:
|
||||
num_ps_gprs = 93;
|
||||
num_vs_gprs = 46;
|
||||
num_temp_gprs = 4;
|
||||
num_gs_gprs = 31;
|
||||
num_es_gprs = 31;
|
||||
num_hs_gprs = 23;
|
||||
num_ls_gprs = 23;
|
||||
num_ps_threads = 96;
|
||||
num_vs_threads = 16;
|
||||
num_gs_threads = 16;
|
||||
num_es_threads = 16;
|
||||
num_hs_threads = 16;
|
||||
num_ls_threads = 16;
|
||||
num_ps_stack_entries = 42;
|
||||
num_vs_stack_entries = 42;
|
||||
num_gs_stack_entries = 42;
|
||||
num_es_stack_entries = 42;
|
||||
num_hs_stack_entries = 42;
|
||||
num_ls_stack_entries = 42;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rdev->family == CHIP_CEDAR)
|
||||
if ((rdev->family == CHIP_CEDAR) ||
|
||||
(rdev->family == CHIP_PALM))
|
||||
sq_config = 0;
|
||||
else
|
||||
sq_config = VC_ENABLE;
|
||||
|
@ -164,11 +164,13 @@
|
||||
#define SE_SC_BUSY (1 << 29)
|
||||
#define SE_DB_BUSY (1 << 30)
|
||||
#define SE_CB_BUSY (1 << 31)
|
||||
|
||||
/* evergreen */
|
||||
#define CG_MULT_THERMAL_STATUS 0x740
|
||||
#define ASIC_T(x) ((x) << 16)
|
||||
#define ASIC_T_MASK 0x7FF0000
|
||||
#define ASIC_T_SHIFT 16
|
||||
/* APU */
|
||||
#define CG_THERMAL_STATUS 0x678
|
||||
|
||||
#define HDP_HOST_PATH_CNTL 0x2C00
|
||||
#define HDP_NONSURFACE_BASE 0x2C04
|
||||
@ -180,6 +182,7 @@
|
||||
#define MC_SHARED_CHMAP 0x2004
|
||||
#define NOOFCHAN_SHIFT 12
|
||||
#define NOOFCHAN_MASK 0x00003000
|
||||
#define MC_SHARED_CHREMAP 0x2008
|
||||
|
||||
#define MC_ARB_RAMCFG 0x2760
|
||||
#define NOOFBANK_SHIFT 0
|
||||
@ -348,6 +351,9 @@
|
||||
#define SYNC_WALKER (1 << 25)
|
||||
#define SYNC_ALIGNER (1 << 26)
|
||||
|
||||
#define TCP_CHAN_STEER_LO 0x960c
|
||||
#define TCP_CHAN_STEER_HI 0x9610
|
||||
|
||||
#define VGT_CACHE_INVALIDATION 0x88C4
|
||||
#define CACHE_INVALIDATION(x) ((x) << 0)
|
||||
#define VC_ONLY 0
|
||||
|
@ -83,6 +83,9 @@ MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin");
|
||||
MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/CYPRESS_me.bin");
|
||||
MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin");
|
||||
MODULE_FIRMWARE("radeon/PALM_pfp.bin");
|
||||
MODULE_FIRMWARE("radeon/PALM_me.bin");
|
||||
MODULE_FIRMWARE("radeon/SUMO_rlc.bin");
|
||||
|
||||
int r600_debugfs_mc_info_init(struct radeon_device *rdev);
|
||||
|
||||
@ -1161,7 +1164,7 @@ static void r600_mc_program(struct radeon_device *rdev)
|
||||
* Note: GTT start, end, size should be initialized before calling this
|
||||
* function on AGP platform.
|
||||
*/
|
||||
void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
|
||||
static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
|
||||
{
|
||||
u64 size_bf, size_af;
|
||||
|
||||
@ -1998,6 +2001,10 @@ int r600_init_microcode(struct radeon_device *rdev)
|
||||
chip_name = "CYPRESS";
|
||||
rlc_chip_name = "CYPRESS";
|
||||
break;
|
||||
case CHIP_PALM:
|
||||
chip_name = "PALM";
|
||||
rlc_chip_name = "SUMO";
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
|
||||
|
@ -181,6 +181,7 @@ void rs690_pm_info(struct radeon_device *rdev);
|
||||
extern u32 rv6xx_get_temp(struct radeon_device *rdev);
|
||||
extern u32 rv770_get_temp(struct radeon_device *rdev);
|
||||
extern u32 evergreen_get_temp(struct radeon_device *rdev);
|
||||
extern u32 sumo_get_temp(struct radeon_device *rdev);
|
||||
|
||||
/*
|
||||
* Fences.
|
||||
@ -737,6 +738,7 @@ enum radeon_int_thermal_type {
|
||||
THERMAL_TYPE_RV6XX,
|
||||
THERMAL_TYPE_RV770,
|
||||
THERMAL_TYPE_EVERGREEN,
|
||||
THERMAL_TYPE_SUMO,
|
||||
};
|
||||
|
||||
struct radeon_voltage {
|
||||
@ -1323,6 +1325,7 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
|
||||
#define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
|
||||
#define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
|
||||
#define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
|
||||
#define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM))
|
||||
|
||||
/*
|
||||
* BIOS helpers.
|
||||
@ -1489,7 +1492,6 @@ extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
|
||||
struct drm_display_mode *mode2);
|
||||
|
||||
/* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */
|
||||
extern void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
|
||||
extern bool r600_card_posted(struct radeon_device *rdev);
|
||||
extern void r600_cp_stop(struct radeon_device *rdev);
|
||||
extern int r600_cp_start(struct radeon_device *rdev);
|
||||
@ -1535,6 +1537,7 @@ extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mo
|
||||
extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
|
||||
extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder);
|
||||
|
||||
extern void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
|
||||
extern void r700_cp_stop(struct radeon_device *rdev);
|
||||
extern void r700_cp_fini(struct radeon_device *rdev);
|
||||
extern void evergreen_disable_interrupt_state(struct radeon_device *rdev);
|
||||
|
@ -793,6 +793,49 @@ static struct radeon_asic evergreen_asic = {
|
||||
.post_page_flip = &evergreen_post_page_flip,
|
||||
};
|
||||
|
||||
static struct radeon_asic sumo_asic = {
|
||||
.init = &evergreen_init,
|
||||
.fini = &evergreen_fini,
|
||||
.suspend = &evergreen_suspend,
|
||||
.resume = &evergreen_resume,
|
||||
.cp_commit = &r600_cp_commit,
|
||||
.gpu_is_lockup = &evergreen_gpu_is_lockup,
|
||||
.asic_reset = &evergreen_asic_reset,
|
||||
.vga_set_state = &r600_vga_set_state,
|
||||
.gart_tlb_flush = &evergreen_pcie_gart_tlb_flush,
|
||||
.gart_set_page = &rs600_gart_set_page,
|
||||
.ring_test = &r600_ring_test,
|
||||
.ring_ib_execute = &r600_ring_ib_execute,
|
||||
.irq_set = &evergreen_irq_set,
|
||||
.irq_process = &evergreen_irq_process,
|
||||
.get_vblank_counter = &evergreen_get_vblank_counter,
|
||||
.fence_ring_emit = &r600_fence_ring_emit,
|
||||
.cs_parse = &evergreen_cs_parse,
|
||||
.copy_blit = &evergreen_copy_blit,
|
||||
.copy_dma = &evergreen_copy_blit,
|
||||
.copy = &evergreen_copy_blit,
|
||||
.get_engine_clock = &radeon_atom_get_engine_clock,
|
||||
.set_engine_clock = &radeon_atom_set_engine_clock,
|
||||
.get_memory_clock = NULL,
|
||||
.set_memory_clock = NULL,
|
||||
.get_pcie_lanes = NULL,
|
||||
.set_pcie_lanes = NULL,
|
||||
.set_clock_gating = NULL,
|
||||
.set_surface_reg = r600_set_surface_reg,
|
||||
.clear_surface_reg = r600_clear_surface_reg,
|
||||
.bandwidth_update = &evergreen_bandwidth_update,
|
||||
.hpd_init = &evergreen_hpd_init,
|
||||
.hpd_fini = &evergreen_hpd_fini,
|
||||
.hpd_sense = &evergreen_hpd_sense,
|
||||
.hpd_set_polarity = &evergreen_hpd_set_polarity,
|
||||
.gui_idle = &r600_gui_idle,
|
||||
.pm_misc = &evergreen_pm_misc,
|
||||
.pm_prepare = &evergreen_pm_prepare,
|
||||
.pm_finish = &evergreen_pm_finish,
|
||||
.pm_init_profile = &rs780_pm_init_profile,
|
||||
.pm_get_dynpm_state = &r600_pm_get_dynpm_state,
|
||||
};
|
||||
|
||||
int radeon_asic_init(struct radeon_device *rdev)
|
||||
{
|
||||
radeon_register_accessor_init(rdev);
|
||||
@ -877,6 +920,9 @@ int radeon_asic_init(struct radeon_device *rdev)
|
||||
case CHIP_HEMLOCK:
|
||||
rdev->asic = &evergreen_asic;
|
||||
break;
|
||||
case CHIP_PALM:
|
||||
rdev->asic = &sumo_asic;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
return -EINVAL;
|
||||
@ -891,7 +937,9 @@ int radeon_asic_init(struct radeon_device *rdev)
|
||||
if (rdev->flags & RADEON_SINGLE_CRTC)
|
||||
rdev->num_crtc = 1;
|
||||
else {
|
||||
if (ASIC_IS_DCE4(rdev))
|
||||
if (ASIC_IS_DCE41(rdev))
|
||||
rdev->num_crtc = 2;
|
||||
else if (ASIC_IS_DCE4(rdev))
|
||||
rdev->num_crtc = 6;
|
||||
else
|
||||
rdev->num_crtc = 2;
|
||||
|
@ -1321,6 +1321,43 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev,
|
||||
return false;
|
||||
}
|
||||
|
||||
static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev,
|
||||
struct radeon_atom_ss *ss,
|
||||
int id)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
|
||||
u16 data_offset, size;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info;
|
||||
u8 frev, crev;
|
||||
u16 percentage = 0, rate = 0;
|
||||
|
||||
/* get any igp specific overrides */
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, &size,
|
||||
&frev, &crev, &data_offset)) {
|
||||
igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *)
|
||||
(mode_info->atom_context->bios + data_offset);
|
||||
switch (id) {
|
||||
case ASIC_INTERNAL_SS_ON_TMDS:
|
||||
percentage = le16_to_cpu(igp_info->usDVISSPercentage);
|
||||
rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz);
|
||||
break;
|
||||
case ASIC_INTERNAL_SS_ON_HDMI:
|
||||
percentage = le16_to_cpu(igp_info->usHDMISSPercentage);
|
||||
rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz);
|
||||
break;
|
||||
case ASIC_INTERNAL_SS_ON_LVDS:
|
||||
percentage = le16_to_cpu(igp_info->usLvdsSSPercentage);
|
||||
rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz);
|
||||
break;
|
||||
}
|
||||
if (percentage)
|
||||
ss->percentage = percentage;
|
||||
if (rate)
|
||||
ss->rate = rate;
|
||||
}
|
||||
}
|
||||
|
||||
union asic_ss_info {
|
||||
struct _ATOM_ASIC_INTERNAL_SS_INFO info;
|
||||
struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2;
|
||||
@ -1385,6 +1422,8 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
|
||||
le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage);
|
||||
ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode;
|
||||
ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz);
|
||||
if (rdev->flags & RADEON_IS_IGP)
|
||||
radeon_atombios_get_igp_ss_overrides(rdev, ss, id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1724,39 +1763,91 @@ static const char *pp_lib_thermal_controller_names[] = {
|
||||
"RV6xx",
|
||||
"RV770",
|
||||
"adt7473",
|
||||
"NONE",
|
||||
"External GPIO",
|
||||
"Evergreen",
|
||||
"adt7473 with internal",
|
||||
|
||||
"emc2103",
|
||||
"Sumo",
|
||||
};
|
||||
|
||||
union power_info {
|
||||
struct _ATOM_POWERPLAY_INFO info;
|
||||
struct _ATOM_POWERPLAY_INFO_V2 info_2;
|
||||
struct _ATOM_POWERPLAY_INFO_V3 info_3;
|
||||
struct _ATOM_PPLIB_POWERPLAYTABLE info_4;
|
||||
struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
|
||||
struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
|
||||
struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
|
||||
};
|
||||
|
||||
void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
union pplib_clock_info {
|
||||
struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
|
||||
struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
|
||||
struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
|
||||
struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
|
||||
};
|
||||
|
||||
union pplib_power_state {
|
||||
struct _ATOM_PPLIB_STATE v1;
|
||||
struct _ATOM_PPLIB_STATE_V2 v2;
|
||||
};
|
||||
|
||||
static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev,
|
||||
int state_index,
|
||||
u32 misc, u32 misc2)
|
||||
{
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
/* order matters! */
|
||||
if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_POWERSAVE;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_PERFORMANCE;
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
}
|
||||
if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
} else if (state_index == 0) {
|
||||
rdev->pm.power_state[state_index].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
}
|
||||
|
||||
static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
u32 misc, misc2 = 0;
|
||||
int num_modes = 0, i;
|
||||
int state_index = 0;
|
||||
struct radeon_i2c_bus_rec i2c_bus;
|
||||
union power_info *power_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
|
||||
u16 data_offset;
|
||||
u8 frev, crev;
|
||||
u32 misc, misc2 = 0, sclk, mclk;
|
||||
union power_info *power_info;
|
||||
struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
|
||||
struct _ATOM_PPLIB_STATE *power_state;
|
||||
int num_modes = 0, i, j;
|
||||
int state_index = 0, mode_index = 0;
|
||||
struct radeon_i2c_bus_rec i2c_bus;
|
||||
|
||||
rdev->pm.default_power_state_index = -1;
|
||||
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset))
|
||||
return state_index;
|
||||
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
|
||||
if (frev < 4) {
|
||||
|
||||
/* add the i2c bus for thermal/fan chip */
|
||||
if (power_info->info.ucOverdriveThermalController > 0) {
|
||||
DRM_INFO("Possible %s thermal controller at 0x%02x\n",
|
||||
@ -1813,38 +1904,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex;
|
||||
}
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
/* order matters! */
|
||||
if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_POWERSAVE;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_PERFORMANCE;
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
}
|
||||
if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
} else if (state_index == 0) {
|
||||
rdev->pm.power_state[state_index].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0);
|
||||
state_index++;
|
||||
break;
|
||||
case 2:
|
||||
@ -1881,45 +1941,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex;
|
||||
}
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
/* order matters! */
|
||||
if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_POWERSAVE;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_PERFORMANCE;
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
}
|
||||
if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc2 & ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT)
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
} else if (state_index == 0) {
|
||||
rdev->pm.power_state[state_index].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);
|
||||
state_index++;
|
||||
break;
|
||||
case 3:
|
||||
@ -1962,40 +1984,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
}
|
||||
}
|
||||
rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
/* order matters! */
|
||||
if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_POWERSAVE;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BATTERY;
|
||||
if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_PERFORMANCE;
|
||||
rdev->pm.power_state[state_index].flags &=
|
||||
~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY;
|
||||
}
|
||||
if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE)
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_BALANCED;
|
||||
if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) {
|
||||
rdev->pm.power_state[state_index].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
rdev->pm.default_power_state_index = state_index;
|
||||
rdev->pm.power_state[state_index].default_clock_mode =
|
||||
&rdev->pm.power_state[state_index].clock_info[0];
|
||||
} else if (state_index == 0) {
|
||||
rdev->pm.power_state[state_index].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2);
|
||||
state_index++;
|
||||
break;
|
||||
}
|
||||
@ -2012,20 +2001,13 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[state_index].misc = 0;
|
||||
rdev->pm.power_state[state_index].misc2 = 0;
|
||||
}
|
||||
} else {
|
||||
int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
|
||||
uint8_t fw_frev, fw_crev;
|
||||
uint16_t fw_data_offset, vddc = 0;
|
||||
union firmware_info *firmware_info;
|
||||
ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController;
|
||||
return state_index;
|
||||
}
|
||||
|
||||
if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL,
|
||||
&fw_frev, &fw_crev, &fw_data_offset)) {
|
||||
firmware_info =
|
||||
(union firmware_info *)(mode_info->atom_context->bios +
|
||||
fw_data_offset);
|
||||
vddc = firmware_info->info_14.usBootUpVDDCVoltage;
|
||||
}
|
||||
static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev,
|
||||
ATOM_PPLIB_THERMALCONTROLLER *controller)
|
||||
{
|
||||
struct radeon_i2c_bus_rec i2c_bus;
|
||||
|
||||
/* add the i2c bus for thermal/fan chip */
|
||||
if (controller->ucType > 0) {
|
||||
@ -2044,10 +2026,17 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
(controller->ucFanParameters &
|
||||
ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
|
||||
rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
|
||||
} else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {
|
||||
DRM_INFO("Internal thermal controller %s fan control\n",
|
||||
(controller->ucFanParameters &
|
||||
ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
|
||||
rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO;
|
||||
} else if ((controller->ucType ==
|
||||
ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) ||
|
||||
(controller->ucType ==
|
||||
ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) {
|
||||
ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) ||
|
||||
(controller->ucType ==
|
||||
ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) {
|
||||
DRM_INFO("Special thermal controller config\n");
|
||||
} else {
|
||||
DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
|
||||
@ -2064,93 +2053,39 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
strlcpy(info.type, name, sizeof(info.type));
|
||||
i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
|
||||
u8 frev, crev;
|
||||
u16 data_offset;
|
||||
union firmware_info *firmware_info;
|
||||
u16 vddc = 0;
|
||||
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
firmware_info =
|
||||
(union firmware_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
vddc = firmware_info->info_14.usBootUpVDDCVoltage;
|
||||
}
|
||||
}
|
||||
/* first mode is usually default, followed by low to high */
|
||||
for (i = 0; i < power_info->info_4.ucNumStates; i++) {
|
||||
mode_index = 0;
|
||||
power_state = (struct _ATOM_PPLIB_STATE *)
|
||||
(mode_info->atom_context->bios +
|
||||
data_offset +
|
||||
le16_to_cpu(power_info->info_4.usStateArrayOffset) +
|
||||
i * power_info->info_4.ucStateEntrySize);
|
||||
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
|
||||
(mode_info->atom_context->bios +
|
||||
data_offset +
|
||||
le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) +
|
||||
(power_state->ucNonClockStateIndex *
|
||||
power_info->info_4.ucNonClockSize));
|
||||
for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) {
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info =
|
||||
(struct _ATOM_PPLIB_RS780_CLOCK_INFO *)
|
||||
(mode_info->atom_context->bios +
|
||||
data_offset +
|
||||
le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) +
|
||||
(power_state->ucClockStateIndices[j] *
|
||||
power_info->info_4.ucClockInfoSize));
|
||||
sclk = le16_to_cpu(clock_info->usLowEngineClockLow);
|
||||
sclk |= clock_info->ucLowEngineClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
/* skip invalid modes */
|
||||
if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)
|
||||
continue;
|
||||
/* voltage works differently on IGPs */
|
||||
mode_index++;
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info =
|
||||
(struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *)
|
||||
(mode_info->atom_context->bios +
|
||||
data_offset +
|
||||
le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) +
|
||||
(power_state->ucClockStateIndices[j] *
|
||||
power_info->info_4.ucClockInfoSize));
|
||||
sclk = le16_to_cpu(clock_info->usEngineClockLow);
|
||||
sclk |= clock_info->ucEngineClockHigh << 16;
|
||||
mclk = le16_to_cpu(clock_info->usMemoryClockLow);
|
||||
mclk |= clock_info->ucMemoryClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
/* skip invalid modes */
|
||||
if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||
|
||||
(rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))
|
||||
continue;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
|
||||
VOLTAGE_SW;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
|
||||
clock_info->usVDDC;
|
||||
/* XXX usVDDCI */
|
||||
mode_index++;
|
||||
} else {
|
||||
struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info =
|
||||
(struct _ATOM_PPLIB_R600_CLOCK_INFO *)
|
||||
(mode_info->atom_context->bios +
|
||||
data_offset +
|
||||
le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) +
|
||||
(power_state->ucClockStateIndices[j] *
|
||||
power_info->info_4.ucClockInfoSize));
|
||||
sclk = le16_to_cpu(clock_info->usEngineClockLow);
|
||||
sclk |= clock_info->ucEngineClockHigh << 16;
|
||||
mclk = le16_to_cpu(clock_info->usMemoryClockLow);
|
||||
mclk |= clock_info->ucMemoryClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
/* skip invalid modes */
|
||||
if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||
|
||||
(rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))
|
||||
continue;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
|
||||
VOLTAGE_SW;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
|
||||
clock_info->usVDDC;
|
||||
mode_index++;
|
||||
}
|
||||
}
|
||||
rdev->pm.power_state[state_index].num_clock_modes = mode_index;
|
||||
if (mode_index) {
|
||||
misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
|
||||
misc2 = le16_to_cpu(non_clock_info->usClassification);
|
||||
|
||||
return vddc;
|
||||
}
|
||||
|
||||
static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev,
|
||||
int state_index, int mode_index,
|
||||
struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info)
|
||||
{
|
||||
int j;
|
||||
u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
|
||||
u32 misc2 = le16_to_cpu(non_clock_info->usClassification);
|
||||
u16 vddc = radeon_atombios_get_default_vddc(rdev);
|
||||
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
rdev->pm.power_state[state_index].pcie_lanes =
|
||||
@ -2196,6 +2131,109 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
vddc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
|
||||
int state_index, int mode_index,
|
||||
union pplib_clock_info *clock_info)
|
||||
{
|
||||
u32 sclk, mclk;
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
if (rdev->family >= CHIP_PALM) {
|
||||
sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
|
||||
sclk |= clock_info->sumo.ucEngineClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
} else {
|
||||
sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);
|
||||
sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
}
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
|
||||
sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
|
||||
mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
|
||||
mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
|
||||
VOLTAGE_SW;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
|
||||
clock_info->evergreen.usVDDC;
|
||||
} else {
|
||||
sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
|
||||
sclk |= clock_info->r600.ucEngineClockHigh << 16;
|
||||
mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
|
||||
mclk |= clock_info->r600.ucMemoryClockHigh << 16;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
|
||||
VOLTAGE_SW;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
|
||||
clock_info->r600.usVDDC;
|
||||
}
|
||||
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
/* skip invalid modes */
|
||||
if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)
|
||||
return false;
|
||||
} else {
|
||||
/* skip invalid modes */
|
||||
if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) ||
|
||||
(rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
|
||||
union pplib_power_state *power_state;
|
||||
int i, j;
|
||||
int state_index = 0, mode_index = 0;
|
||||
union pplib_clock_info *clock_info;
|
||||
bool valid;
|
||||
union power_info *power_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
|
||||
u16 data_offset;
|
||||
u8 frev, crev;
|
||||
|
||||
if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset))
|
||||
return state_index;
|
||||
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
|
||||
/* first mode is usually default, followed by low to high */
|
||||
for (i = 0; i < power_info->pplib.ucNumStates; i++) {
|
||||
mode_index = 0;
|
||||
power_state = (union pplib_power_state *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usStateArrayOffset) +
|
||||
i * power_info->pplib.ucStateEntrySize);
|
||||
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
|
||||
(power_state->v1.ucNonClockStateIndex *
|
||||
power_info->pplib.ucNonClockSize));
|
||||
for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
|
||||
clock_info = (union pplib_clock_info *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
|
||||
(power_state->v1.ucClockStateIndices[j] *
|
||||
power_info->pplib.ucClockInfoSize));
|
||||
valid = radeon_atombios_parse_pplib_clock_info(rdev,
|
||||
state_index, mode_index,
|
||||
clock_info);
|
||||
if (valid)
|
||||
mode_index++;
|
||||
}
|
||||
rdev->pm.power_state[state_index].num_clock_modes = mode_index;
|
||||
if (mode_index) {
|
||||
radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
|
||||
non_clock_info);
|
||||
state_index++;
|
||||
}
|
||||
}
|
||||
@ -2213,6 +2251,112 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
rdev->pm.power_state[0].default_clock_mode =
|
||||
&rdev->pm.power_state[0].clock_info[0];
|
||||
}
|
||||
return state_index;
|
||||
}
|
||||
|
||||
static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
|
||||
union pplib_power_state *power_state;
|
||||
int i, j, non_clock_array_index, clock_array_index;
|
||||
int state_index = 0, mode_index = 0;
|
||||
union pplib_clock_info *clock_info;
|
||||
struct StateArray *state_array;
|
||||
struct ClockInfoArray *clock_info_array;
|
||||
struct NonClockInfoArray *non_clock_info_array;
|
||||
bool valid;
|
||||
union power_info *power_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
|
||||
u16 data_offset;
|
||||
u8 frev, crev;
|
||||
|
||||
if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset))
|
||||
return state_index;
|
||||
power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
|
||||
|
||||
radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
|
||||
state_array = (struct StateArray *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
power_info->pplib.usStateArrayOffset);
|
||||
clock_info_array = (struct ClockInfoArray *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
power_info->pplib.usClockInfoArrayOffset);
|
||||
non_clock_info_array = (struct NonClockInfoArray *)
|
||||
(mode_info->atom_context->bios + data_offset +
|
||||
power_info->pplib.usNonClockInfoArrayOffset);
|
||||
for (i = 0; i < state_array->ucNumEntries; i++) {
|
||||
mode_index = 0;
|
||||
power_state = (union pplib_power_state *)&state_array->states[i];
|
||||
/* XXX this might be an inagua bug... */
|
||||
non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
|
||||
non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
|
||||
&non_clock_info_array->nonClockInfo[non_clock_array_index];
|
||||
for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
|
||||
clock_array_index = power_state->v2.clockInfoIndex[j];
|
||||
/* XXX this might be an inagua bug... */
|
||||
if (clock_array_index >= clock_info_array->ucNumEntries)
|
||||
continue;
|
||||
clock_info = (union pplib_clock_info *)
|
||||
&clock_info_array->clockInfo[clock_array_index];
|
||||
valid = radeon_atombios_parse_pplib_clock_info(rdev,
|
||||
state_index, mode_index,
|
||||
clock_info);
|
||||
if (valid)
|
||||
mode_index++;
|
||||
}
|
||||
rdev->pm.power_state[state_index].num_clock_modes = mode_index;
|
||||
if (mode_index) {
|
||||
radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index,
|
||||
non_clock_info);
|
||||
state_index++;
|
||||
}
|
||||
}
|
||||
/* if multiple clock modes, mark the lowest as no display */
|
||||
for (i = 0; i < state_index; i++) {
|
||||
if (rdev->pm.power_state[i].num_clock_modes > 1)
|
||||
rdev->pm.power_state[i].clock_info[0].flags |=
|
||||
RADEON_PM_MODE_NO_DISPLAY;
|
||||
}
|
||||
/* first mode is usually default */
|
||||
if (rdev->pm.default_power_state_index == -1) {
|
||||
rdev->pm.power_state[0].type =
|
||||
POWER_STATE_TYPE_DEFAULT;
|
||||
rdev->pm.default_power_state_index = 0;
|
||||
rdev->pm.power_state[0].default_clock_mode =
|
||||
&rdev->pm.power_state[0].clock_info[0];
|
||||
}
|
||||
return state_index;
|
||||
}
|
||||
|
||||
void radeon_atombios_get_power_modes(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
|
||||
u16 data_offset;
|
||||
u8 frev, crev;
|
||||
int state_index = 0;
|
||||
|
||||
rdev->pm.default_power_state_index = -1;
|
||||
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
switch (frev) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
state_index = radeon_atombios_parse_power_table_1_3(rdev);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
state_index = radeon_atombios_parse_power_table_4_5(rdev);
|
||||
break;
|
||||
case 6:
|
||||
state_index = radeon_atombios_parse_power_table_6(rdev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* add the default mode */
|
||||
|
@ -335,7 +335,12 @@ bool radeon_card_posted(struct radeon_device *rdev)
|
||||
uint32_t reg;
|
||||
|
||||
/* first check CRTCs */
|
||||
if (ASIC_IS_DCE4(rdev)) {
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
|
||||
RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
|
||||
if (reg & EVERGREEN_CRTC_MASTER_EN)
|
||||
return true;
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) |
|
||||
RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) |
|
||||
RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) |
|
||||
|
@ -485,7 +485,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
|
||||
radeon_legacy_init_crtc(dev, radeon_crtc);
|
||||
}
|
||||
|
||||
static const char *encoder_names[34] = {
|
||||
static const char *encoder_names[36] = {
|
||||
"NONE",
|
||||
"INTERNAL_LVDS",
|
||||
"INTERNAL_TMDS1",
|
||||
@ -520,6 +520,8 @@ static const char *encoder_names[34] = {
|
||||
"INTERNAL_KLDSCP_LVTMA",
|
||||
"INTERNAL_UNIPHY1",
|
||||
"INTERNAL_UNIPHY2",
|
||||
"NUTMEG",
|
||||
"TRAVIS",
|
||||
};
|
||||
|
||||
static const char *connector_names[15] = {
|
||||
|
@ -713,7 +713,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
||||
* DIG1/2 can drive UNIPHY0/1/2 link A or link B
|
||||
*
|
||||
* DCE 4.0
|
||||
* - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B).
|
||||
* - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
|
||||
* Supports up to 6 digital outputs
|
||||
* - 6 DIG encoder blocks.
|
||||
* - DIG to PHY mapping is hardcoded
|
||||
@ -724,6 +724,12 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
||||
* DIG5 drives UNIPHY2 link A, A+B
|
||||
* DIG6 drives UNIPHY2 link B
|
||||
*
|
||||
* DCE 4.1
|
||||
* - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
|
||||
* Supports up to 6 digital outputs
|
||||
* - 2 DIG encoder blocks.
|
||||
* DIG1/2 can drive UNIPHY0/1/2 link A or link B
|
||||
*
|
||||
* Routing
|
||||
* crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
|
||||
* Examples:
|
||||
@ -904,10 +910,16 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
||||
else
|
||||
args.v3.ucLaneNum = 4;
|
||||
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
args.v3.acConfig.ucEncoderSel = dig->dig_encoder;
|
||||
if (dig->linkb)
|
||||
args.v3.acConfig.ucLinkSel = 1;
|
||||
} else {
|
||||
if (dig->linkb) {
|
||||
args.v3.acConfig.ucLinkSel = 1;
|
||||
args.v3.acConfig.ucEncoderSel = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the PLL for the PHY
|
||||
* DP PHY should be clocked from external src if there is
|
||||
@ -1044,6 +1056,7 @@ atombios_set_edp_panel_power(struct drm_connector *connector, int action)
|
||||
|
||||
union external_encoder_control {
|
||||
EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
|
||||
EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -1054,6 +1067,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
|
||||
union external_encoder_control args;
|
||||
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
|
||||
int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
|
||||
@ -1061,6 +1075,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
|
||||
int dp_clock = 0;
|
||||
int dp_lane_count = 0;
|
||||
int connector_object_id = 0;
|
||||
u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
|
||||
|
||||
if (connector) {
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
@ -1099,6 +1114,37 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
|
||||
else
|
||||
args.v1.sDigEncoder.ucLaneNum = 4;
|
||||
break;
|
||||
case 3:
|
||||
args.v3.sExtEncoder.ucAction = action;
|
||||
if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
|
||||
args.v3.sExtEncoder.usConnectorId = connector_object_id;
|
||||
else
|
||||
args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
||||
args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
|
||||
|
||||
if (args.v3.sExtEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
|
||||
if (dp_clock == 270000)
|
||||
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
|
||||
else if (dp_clock == 540000)
|
||||
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
|
||||
args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
|
||||
} else if (radeon_encoder->pixel_clock > 165000)
|
||||
args.v3.sExtEncoder.ucLaneNum = 8;
|
||||
else
|
||||
args.v3.sExtEncoder.ucLaneNum = 4;
|
||||
switch (ext_enum) {
|
||||
case GRAPH_OBJECT_ENUM_ID1:
|
||||
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;
|
||||
break;
|
||||
case GRAPH_OBJECT_ENUM_ID2:
|
||||
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;
|
||||
break;
|
||||
case GRAPH_OBJECT_ENUM_ID3:
|
||||
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
|
||||
break;
|
||||
}
|
||||
args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
|
||||
return;
|
||||
@ -1289,11 +1335,17 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
default:
|
||||
if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP))
|
||||
action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT;
|
||||
else
|
||||
action = ATOM_ENABLE;
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP))
|
||||
action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT;
|
||||
else
|
||||
action = ATOM_DISABLE;
|
||||
break;
|
||||
}
|
||||
@ -1483,6 +1535,11 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
|
||||
struct radeon_encoder_atom_dig *dig;
|
||||
uint32_t dig_enc_in_use = 0;
|
||||
|
||||
/* on DCE41 and encoder can driver any phy so just crtc id */
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
return radeon_crtc->crtc_id;
|
||||
}
|
||||
|
||||
if (ASIC_IS_DCE4(rdev)) {
|
||||
dig = radeon_encoder->enc_priv;
|
||||
switch (radeon_encoder->encoder_id) {
|
||||
@ -1610,6 +1667,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
|
||||
}
|
||||
|
||||
if (ext_encoder) {
|
||||
if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP)) {
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
|
||||
} else
|
||||
atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
|
||||
}
|
||||
|
||||
@ -2029,6 +2092,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
|
||||
case ENCODER_OBJECT_ID_TITFP513:
|
||||
case ENCODER_OBJECT_ID_VT1623:
|
||||
case ENCODER_OBJECT_ID_HDMI_SI1930:
|
||||
case ENCODER_OBJECT_ID_TRAVIS:
|
||||
case ENCODER_OBJECT_ID_NUTMEG:
|
||||
/* these are handled by the primary encoders */
|
||||
radeon_encoder->is_ext_encoder = true;
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
||||
|
@ -80,6 +80,7 @@ enum radeon_family {
|
||||
CHIP_JUNIPER,
|
||||
CHIP_CYPRESS,
|
||||
CHIP_HEMLOCK,
|
||||
CHIP_PALM,
|
||||
CHIP_LAST,
|
||||
};
|
||||
|
||||
|
@ -125,7 +125,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
|
||||
* chips. Disable MSI on them for now.
|
||||
*/
|
||||
if ((rdev->family >= CHIP_RV380) &&
|
||||
(!(rdev->flags & RADEON_IS_IGP)) &&
|
||||
((!(rdev->flags & RADEON_IS_IGP)) || (rdev->family >= CHIP_PALM)) &&
|
||||
(!(rdev->flags & RADEON_IS_AGP))) {
|
||||
int ret = pci_enable_msi(rdev->pdev);
|
||||
if (!ret) {
|
||||
|
@ -449,6 +449,9 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev,
|
||||
case THERMAL_TYPE_EVERGREEN:
|
||||
temp = evergreen_get_temp(rdev);
|
||||
break;
|
||||
case THERMAL_TYPE_SUMO:
|
||||
temp = sumo_get_temp(rdev);
|
||||
break;
|
||||
default:
|
||||
temp = 0;
|
||||
break;
|
||||
@ -487,6 +490,7 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
|
||||
case THERMAL_TYPE_RV6XX:
|
||||
case THERMAL_TYPE_RV770:
|
||||
case THERMAL_TYPE_EVERGREEN:
|
||||
case THERMAL_TYPE_SUMO:
|
||||
rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
|
||||
if (IS_ERR(rdev->pm.int_hwmon_dev)) {
|
||||
err = PTR_ERR(rdev->pm.int_hwmon_dev);
|
||||
|
@ -271,6 +271,12 @@ static void rv770_mc_program(struct radeon_device *rdev)
|
||||
rdev->mc.vram_end >> 12);
|
||||
}
|
||||
WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;
|
||||
tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24;
|
||||
tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20;
|
||||
WREG32(MC_FUS_VM_FB_OFFSET, tmp);
|
||||
}
|
||||
tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
|
||||
tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
|
||||
WREG32(MC_VM_FB_LOCATION, tmp);
|
||||
@ -523,6 +529,49 @@ static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
|
||||
return backend_map;
|
||||
}
|
||||
|
||||
static void rv770_program_channel_remap(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tcp_chan_steer, mc_shared_chremap, tmp;
|
||||
bool force_no_swizzle;
|
||||
|
||||
switch (rdev->family) {
|
||||
case CHIP_RV770:
|
||||
case CHIP_RV730:
|
||||
force_no_swizzle = false;
|
||||
break;
|
||||
case CHIP_RV710:
|
||||
case CHIP_RV740:
|
||||
default:
|
||||
force_no_swizzle = true;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = RREG32(MC_SHARED_CHMAP);
|
||||
switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
/* default mapping */
|
||||
mc_shared_chremap = 0x00fac688;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
if (force_no_swizzle)
|
||||
mc_shared_chremap = 0x00fac688;
|
||||
else
|
||||
mc_shared_chremap = 0x00bbc298;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rdev->family == CHIP_RV740)
|
||||
tcp_chan_steer = 0x00ef2a60;
|
||||
else
|
||||
tcp_chan_steer = 0x00fac688;
|
||||
|
||||
WREG32(TCP_CHAN_STEER, tcp_chan_steer);
|
||||
WREG32(MC_SHARED_CHREMAP, mc_shared_chremap);
|
||||
}
|
||||
|
||||
static void rv770_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
int i, j, num_qd_pipes;
|
||||
@ -722,6 +771,8 @@ static void rv770_gpu_init(struct radeon_device *rdev)
|
||||
WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
|
||||
WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
|
||||
|
||||
rv770_program_channel_remap(rdev);
|
||||
|
||||
WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
|
||||
WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
|
||||
WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
|
||||
@ -990,6 +1041,50 @@ static void rv770_vram_scratch_fini(struct radeon_device *rdev)
|
||||
radeon_bo_unref(&rdev->vram_scratch.robj);
|
||||
}
|
||||
|
||||
void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
|
||||
{
|
||||
u64 size_bf, size_af;
|
||||
|
||||
if (mc->mc_vram_size > 0xE0000000) {
|
||||
/* leave room for at least 512M GTT */
|
||||
dev_warn(rdev->dev, "limiting VRAM\n");
|
||||
mc->real_vram_size = 0xE0000000;
|
||||
mc->mc_vram_size = 0xE0000000;
|
||||
}
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
size_bf = mc->gtt_start;
|
||||
size_af = 0xFFFFFFFF - mc->gtt_end + 1;
|
||||
if (size_bf > size_af) {
|
||||
if (mc->mc_vram_size > size_bf) {
|
||||
dev_warn(rdev->dev, "limiting VRAM\n");
|
||||
mc->real_vram_size = size_bf;
|
||||
mc->mc_vram_size = size_bf;
|
||||
}
|
||||
mc->vram_start = mc->gtt_start - mc->mc_vram_size;
|
||||
} else {
|
||||
if (mc->mc_vram_size > size_af) {
|
||||
dev_warn(rdev->dev, "limiting VRAM\n");
|
||||
mc->real_vram_size = size_af;
|
||||
mc->mc_vram_size = size_af;
|
||||
}
|
||||
mc->vram_start = mc->gtt_end;
|
||||
}
|
||||
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
|
||||
dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n",
|
||||
mc->mc_vram_size >> 20, mc->vram_start,
|
||||
mc->vram_end, mc->real_vram_size >> 20);
|
||||
} else {
|
||||
u64 base = 0;
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
|
||||
base |= RREG32(MC_FUS_VM_FB_OFFSET) & 0x00F00000;
|
||||
}
|
||||
radeon_vram_location(rdev, &rdev->mc, base);
|
||||
rdev->mc.gtt_base_align = 0;
|
||||
radeon_gtt_location(rdev, mc);
|
||||
}
|
||||
}
|
||||
|
||||
int rv770_mc_init(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
@ -1030,7 +1125,7 @@ int rv770_mc_init(struct radeon_device *rdev)
|
||||
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
rdev->mc.visible_vram_size = rdev->mc.aper_size;
|
||||
rdev->mc.active_vram_size = rdev->mc.visible_vram_size;
|
||||
r600_vram_gtt_location(rdev, &rdev->mc);
|
||||
r700_vram_gtt_location(rdev, &rdev->mc);
|
||||
radeon_update_bandwidth_info(rdev);
|
||||
|
||||
return 0;
|
||||
|
@ -138,6 +138,7 @@
|
||||
#define MC_SHARED_CHMAP 0x2004
|
||||
#define NOOFCHAN_SHIFT 12
|
||||
#define NOOFCHAN_MASK 0x00003000
|
||||
#define MC_SHARED_CHREMAP 0x2008
|
||||
|
||||
#define MC_ARB_RAMCFG 0x2760
|
||||
#define NOOFBANK_SHIFT 0
|
||||
@ -157,6 +158,7 @@
|
||||
#define MC_VM_AGP_BOT 0x202C
|
||||
#define MC_VM_AGP_BASE 0x2030
|
||||
#define MC_VM_FB_LOCATION 0x2024
|
||||
#define MC_FUS_VM_FB_OFFSET 0x2898
|
||||
#define MC_VM_MB_L1_TLB0_CNTL 0x2234
|
||||
#define MC_VM_MB_L1_TLB1_CNTL 0x2238
|
||||
#define MC_VM_MB_L1_TLB2_CNTL 0x223C
|
||||
@ -303,6 +305,7 @@
|
||||
#define BILINEAR_PRECISION_8_BIT (1 << 31)
|
||||
|
||||
#define TCP_CNTL 0x9610
|
||||
#define TCP_CHAN_STEER 0x9614
|
||||
|
||||
#define VGT_CACHE_INVALIDATION 0x88C4
|
||||
#define CACHE_INVALIDATION(x) ((x)<<0)
|
||||
|
@ -419,6 +419,10 @@
|
||||
{0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
|
||||
{0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
|
||||
{0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
|
||||
{0x1002, 0x9802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
|
||||
{0x1002, 0x9803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
|
||||
{0x1002, 0x9804, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
|
||||
{0x1002, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
|
||||
{0, 0, 0}
|
||||
|
||||
#define r128_PCI_IDS \
|
||||
|
Loading…
Reference in New Issue
Block a user