This single patch is a backport from kernel version 3.12.10 to kernel version 3.12. This lays the ground for the next set of patches which had been created on top of 3.12.10. Signed-off-by: Arindam Nath diff -Naur a/drivers/acpi/bus.c b/drivers/acpi/bus.c --- a/drivers/acpi/bus.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/acpi/bus.c 2014-04-03 02:38:06.049166833 +0530 @@ -156,6 +156,16 @@ } EXPORT_SYMBOL(acpi_bus_get_private_data); +void acpi_bus_no_hotplug(acpi_handle handle) +{ + struct acpi_device *adev = NULL; + + acpi_bus_get_device(handle, &adev); + if (adev) + adev->flags.no_hotplug = true; +} +EXPORT_SYMBOL_GPL(acpi_bus_no_hotplug); + static void acpi_print_osc_error(acpi_handle handle, struct acpi_osc_context *context, char *error) { diff -Naur a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c --- a/drivers/gpu/drm/radeon/atombios_crtc.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/atombios_crtc.c 2014-04-03 01:45:50.161111970 +0530 @@ -1180,23 +1180,18 @@ fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); if (rdev->family >= CHIP_BONAIRE) { - u32 num_pipe_configs = rdev->config.cik.max_tile_pipes; - u32 num_rb = rdev->config.cik.max_backends_per_se; - if (num_pipe_configs > 8) - num_pipe_configs = 8; - if (num_pipe_configs == 8) - fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P8_32x32_16x16); - else if (num_pipe_configs == 4) { - if (num_rb == 4) - fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_16x16); - else if (num_rb < 4) - fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_8x16); - } else if (num_pipe_configs == 2) - fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P2); + /* Read the pipe config from the 2D TILED SCANOUT mode. + * It should be the same for the other modes too, but not all + * modes set the pipe config field. */ + u32 pipe_config = (rdev->config.cik.tile_mode_array[10] >> 6) & 0x1f; + + fb_format |= CIK_GRPH_PIPE_CONFIG(pipe_config); } else if ((rdev->family == CHIP_TAHITI) || (rdev->family == CHIP_PITCAIRN)) fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); - else if (rdev->family == CHIP_VERDE) + else if ((rdev->family == CHIP_VERDE) || + (rdev->family == CHIP_OLAND) || + (rdev->family == CHIP_HAINAN)) /* for completeness. HAINAN has no display hw */ fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); switch (radeon_crtc->crtc_id) { @@ -1753,7 +1748,7 @@ if (pll != ATOM_PPLL_INVALID) return pll; } - } else { + } else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */ /* use the same PPLL for all monitors with the same clock */ pll = radeon_get_shared_nondp_ppll(crtc); if (pll != ATOM_PPLL_INVALID) diff -Naur a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c --- a/drivers/gpu/drm/radeon/atombios_i2c.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/atombios_i2c.c 2014-04-03 01:45:50.161111970 +0530 @@ -44,7 +44,7 @@ PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); unsigned char *base; - u16 out; + u16 out = cpu_to_le16(0); memset(&args, 0, sizeof(args)); @@ -55,9 +55,14 @@ DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 3)\n", num); return -EINVAL; } - args.ucRegIndex = buf[0]; - if (num > 1) - memcpy(&out, &buf[1], num - 1); + if (buf == NULL) + args.ucRegIndex = 0; + else + args.ucRegIndex = buf[0]; + if (num) + num--; + if (num) + memcpy(&out, &buf[1], num); args.lpI2CDataOut = cpu_to_le16(out); } else { if (num > ATOM_MAX_HW_I2C_READ) { @@ -94,14 +99,14 @@ struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); struct i2c_msg *p; int i, remaining, current_count, buffer_offset, max_bytes, ret; - u8 buf = 0, flags; + u8 flags; /* check for bus probe */ p = &msgs[0]; if ((num == 1) && (p->len == 0)) { ret = radeon_process_i2c_ch(i2c, p->addr, HW_I2C_WRITE, - &buf, 1); + NULL, 0); if (ret) return ret; else diff -Naur a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c --- a/drivers/gpu/drm/radeon/cik.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/cik.c 2014-04-03 01:45:50.165111971 +0530 @@ -2608,7 +2608,7 @@ * Returns the disabled RB bitmask. */ static u32 cik_get_rb_disabled(struct radeon_device *rdev, - u32 max_rb_num, u32 se_num, + u32 max_rb_num_per_se, u32 sh_per_se) { u32 data, mask; @@ -2622,7 +2622,7 @@ data >>= BACKEND_DISABLE_SHIFT; - mask = cik_create_bitmask(max_rb_num / se_num / sh_per_se); + mask = cik_create_bitmask(max_rb_num_per_se / sh_per_se); return data & mask; } @@ -2639,7 +2639,7 @@ */ static void cik_setup_rb(struct radeon_device *rdev, u32 se_num, u32 sh_per_se, - u32 max_rb_num) + u32 max_rb_num_per_se) { int i, j; u32 data, mask; @@ -2649,19 +2649,21 @@ for (i = 0; i < se_num; i++) { for (j = 0; j < sh_per_se; j++) { cik_select_se_sh(rdev, i, j); - data = cik_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); + data = cik_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); } } cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); mask = 1; - for (i = 0; i < max_rb_num; i++) { + for (i = 0; i < max_rb_num_per_se * se_num; i++) { if (!(disabled_rbs & mask)) enabled_rbs |= mask; mask <<= 1; } + rdev->config.cik.backend_enable_mask = enabled_rbs; + for (i = 0; i < se_num; i++) { cik_select_se_sh(rdev, i, 0xffffffff); data = 0; diff -Naur a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c --- a/drivers/gpu/drm/radeon/cik_sdma.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/cik_sdma.c 2014-04-03 01:45:50.169111972 +0530 @@ -468,7 +468,7 @@ radeon_ring_write(ring, 0); /* src/dst endian swap */ radeon_ring_write(ring, src_offset & 0xffffffff); radeon_ring_write(ring, upper_32_bits(src_offset) & 0xffffffff); - radeon_ring_write(ring, dst_offset & 0xfffffffc); + radeon_ring_write(ring, dst_offset & 0xffffffff); radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xffffffff); src_offset += cur_size_in_bytes; dst_offset += cur_size_in_bytes; diff -Naur a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c --- a/drivers/gpu/drm/radeon/dce6_afmt.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/dce6_afmt.c 2014-04-03 01:45:50.169111972 +0530 @@ -132,7 +132,7 @@ } sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); - if (sad_count < 0) { + if (sad_count <= 0) { DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); return; } @@ -193,7 +193,7 @@ } sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); - if (sad_count < 0) { + if (sad_count <= 0) { DRM_ERROR("Couldn't read SADs: %d\n", sad_count); return; } diff -Naur a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c 2014-04-03 01:45:50.169111972 +0530 @@ -81,7 +81,7 @@ } sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); - if (sad_count < 0) { + if (sad_count <= 0) { DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); return; } @@ -134,7 +134,7 @@ } sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); - if (sad_count < 0) { + if (sad_count <= 0) { DRM_ERROR("Couldn't read SADs: %d\n", sad_count); return; } diff -Naur a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c --- a/drivers/gpu/drm/radeon/ni.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/ni.c 2014-04-03 01:45:50.169111972 +0530 @@ -900,6 +900,10 @@ (rdev->pdev->device == 0x999C)) { rdev->config.cayman.max_simds_per_se = 6; rdev->config.cayman.max_backends_per_se = 2; + rdev->config.cayman.max_hw_contexts = 8; + rdev->config.cayman.sx_max_export_size = 256; + rdev->config.cayman.sx_max_export_pos_size = 64; + rdev->config.cayman.sx_max_export_smx_size = 192; } else if ((rdev->pdev->device == 0x9903) || (rdev->pdev->device == 0x9904) || (rdev->pdev->device == 0x990A) || @@ -910,6 +914,10 @@ (rdev->pdev->device == 0x999D)) { rdev->config.cayman.max_simds_per_se = 4; rdev->config.cayman.max_backends_per_se = 2; + rdev->config.cayman.max_hw_contexts = 8; + rdev->config.cayman.sx_max_export_size = 256; + rdev->config.cayman.sx_max_export_pos_size = 64; + rdev->config.cayman.sx_max_export_smx_size = 192; } else if ((rdev->pdev->device == 0x9919) || (rdev->pdev->device == 0x9990) || (rdev->pdev->device == 0x9991) || @@ -920,9 +928,17 @@ (rdev->pdev->device == 0x99A0)) { rdev->config.cayman.max_simds_per_se = 3; rdev->config.cayman.max_backends_per_se = 1; + rdev->config.cayman.max_hw_contexts = 4; + rdev->config.cayman.sx_max_export_size = 128; + rdev->config.cayman.sx_max_export_pos_size = 32; + rdev->config.cayman.sx_max_export_smx_size = 96; } else { rdev->config.cayman.max_simds_per_se = 2; rdev->config.cayman.max_backends_per_se = 1; + rdev->config.cayman.max_hw_contexts = 4; + rdev->config.cayman.sx_max_export_size = 128; + rdev->config.cayman.sx_max_export_pos_size = 32; + rdev->config.cayman.sx_max_export_smx_size = 96; } rdev->config.cayman.max_texture_channel_caches = 2; rdev->config.cayman.max_gprs = 256; @@ -930,10 +946,6 @@ rdev->config.cayman.max_gs_threads = 32; rdev->config.cayman.max_stack_entries = 512; rdev->config.cayman.sx_num_of_sets = 8; - rdev->config.cayman.sx_max_export_size = 256; - rdev->config.cayman.sx_max_export_pos_size = 64; - rdev->config.cayman.sx_max_export_smx_size = 192; - rdev->config.cayman.max_hw_contexts = 8; rdev->config.cayman.sq_num_cf_insts = 2; rdev->config.cayman.sc_prim_fifo_size = 0x40; diff -Naur a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c --- a/drivers/gpu/drm/radeon/r600_hdmi.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/r600_hdmi.c 2014-04-03 01:45:50.169111972 +0530 @@ -24,6 +24,7 @@ * Authors: Christian König */ #include +#include #include #include #include "radeon.h" @@ -57,35 +58,57 @@ static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { /* 32kHz 44.1kHz 48kHz */ /* Clock N CTS N CTS N CTS */ - { 25175, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ + { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ - { 74176, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */ + { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ - { 148352, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */ + { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ - { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */ }; + /* - * calculate CTS value if it's not found in the table + * calculate CTS and N values if they are not found in the table */ -static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq) +static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) { - u64 n; - u32 d; + int n, cts; + unsigned long div, mul; - if (*CTS == 0) { - n = (u64)clock * (u64)N * 1000ULL; - d = 128 * freq; - do_div(n, d); - *CTS = n; - } - DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n", - N, *CTS, freq); + /* Safe, but overly large values */ + n = 128 * freq; + cts = clock * 1000; + + /* Smallest valid fraction */ + div = gcd(n, cts); + + n /= div; + cts /= div; + + /* + * The optimal N is 128*freq/1000. Calculate the closest larger + * value that doesn't truncate any bits. + */ + mul = ((128*freq/1000) + (n-1))/n; + + n *= mul; + cts *= mul; + + /* Check that we are in spec (not always possible) */ + if (n < (128*freq/1500)) + printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); + if (n > (128*freq/300)) + printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); + + *N = n; + *CTS = cts; + + DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", + *N, *CTS, freq); } struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) @@ -93,15 +116,16 @@ struct radeon_hdmi_acr res; u8 i; - for (i = 0; r600_hdmi_predefined_acr[i].clock != clock && - r600_hdmi_predefined_acr[i].clock != 0; i++) - ; - res = r600_hdmi_predefined_acr[i]; - - /* In case some CTS are missing */ - r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000); - r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100); - r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000); + /* Precalculated values for common clocks */ + for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) { + if (r600_hdmi_predefined_acr[i].clock == clock) + return r600_hdmi_predefined_acr[i]; + } + + /* And odd clocks get manually calculated */ + r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); + r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); + r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); return res; } @@ -280,9 +304,9 @@ WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ } - } else if (ASIC_IS_DCE3(rdev)) { + } else { /* according to the reg specs, this should DCE3.2 only, but in - * practice it seems to cover DCE3.0/3.1 as well. + * practice it seems to cover DCE2.0/3.0/3.1 as well. */ if (dig->dig_encoder == 0) { WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); @@ -293,10 +317,6 @@ WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ } - } else { - /* according to the reg specs, this should be DCE2.0 and DCE3.0/3.1 */ - WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | - AUDIO_DTO_MODULE(clock / 10)); } } diff -Naur a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c --- a/drivers/gpu/drm/radeon/radeon_asic.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon_asic.c 2014-04-03 01:45:50.173111972 +0530 @@ -2019,6 +2019,8 @@ .bandwidth_update = &dce8_bandwidth_update, .get_vblank_counter = &evergreen_get_vblank_counter, .wait_for_vblank = &dce4_wait_for_vblank, + .set_backlight_level = &atombios_set_backlight_level, + .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, .hdmi_setmode = &evergreen_hdmi_setmode, }, @@ -2119,6 +2121,8 @@ .bandwidth_update = &dce8_bandwidth_update, .get_vblank_counter = &evergreen_get_vblank_counter, .wait_for_vblank = &dce4_wait_for_vblank, + .set_backlight_level = &atombios_set_backlight_level, + .get_backlight_level = &atombios_get_backlight_level, .hdmi_enable = &evergreen_hdmi_enable, .hdmi_setmode = &evergreen_hdmi_setmode, }, diff -Naur a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c --- a/drivers/gpu/drm/radeon/radeon_atombios.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon_atombios.c 2014-04-03 01:45:50.173111972 +0530 @@ -2918,7 +2918,7 @@ mpll_param->dll_speed = args.ucDllSpeed; mpll_param->bwcntl = args.ucBWCntl; mpll_param->vco_mode = - (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK) ? 1 : 0; + (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK); mpll_param->yclk_sel = (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0; mpll_param->qdr = diff -Naur a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c 2014-04-03 01:45:50.173111972 +0530 @@ -34,6 +34,7 @@ bool atpx_detected; /* handle for device - and atpx */ acpi_handle dhandle; + acpi_handle other_handle; struct radeon_atpx atpx; } radeon_atpx_priv; @@ -448,9 +449,10 @@ return false; status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { + radeon_atpx_priv.other_handle = dhandle; return false; - + } radeon_atpx_priv.dhandle = dhandle; radeon_atpx_priv.atpx.handle = atpx_handle; return true; @@ -527,6 +529,16 @@ printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", acpi_method_name); radeon_atpx_priv.atpx_detected = true; + /* + * On some systems hotplug events are generated for the device + * being switched off when ATPX is executed. They cause ACPI + * hotplug to trigger and attempt to remove the device from + * the system, which causes it to break down. Prevent that from + * happening by setting the no_hotplug flag for the involved + * ACPI device objects. + */ + acpi_bus_no_hotplug(radeon_atpx_priv.dhandle); + acpi_bus_no_hotplug(radeon_atpx_priv.other_handle); return true; } return false; diff -Naur a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c --- a/drivers/gpu/drm/radeon/radeon_gart.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon_gart.c 2014-04-03 01:45:50.173111972 +0530 @@ -1156,6 +1156,8 @@ return -ENOMEM; r = radeon_ib_get(rdev, ridx, &ib, NULL, ndw * 4); + if (r) + return r; ib.length_dw = 0; r = radeon_vm_update_pdes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset); diff -Naur a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h --- a/drivers/gpu/drm/radeon/radeon.h 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon.h 2014-04-03 01:45:50.177111972 +0530 @@ -1930,7 +1930,7 @@ unsigned sc_earlyz_tile_fifo_size; unsigned num_tile_pipes; - unsigned num_backends_per_se; + unsigned backend_enable_mask; unsigned backend_disable_mask_per_asic; unsigned backend_map; unsigned num_texture_channel_caches; @@ -1960,7 +1960,7 @@ unsigned sc_earlyz_tile_fifo_size; unsigned num_tile_pipes; - unsigned num_backends_per_se; + unsigned backend_enable_mask; unsigned backend_disable_mask_per_asic; unsigned backend_map; unsigned num_texture_channel_caches; diff -Naur a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c --- a/drivers/gpu/drm/radeon/radeon_kms.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon_kms.c 2014-04-03 01:45:50.177111972 +0530 @@ -436,6 +436,15 @@ case RADEON_INFO_SI_CP_DMA_COMPUTE: *value = 1; break; + case RADEON_INFO_SI_BACKEND_ENABLED_MASK: + if (rdev->family >= CHIP_BONAIRE) { + *value = rdev->config.cik.backend_enable_mask; + } else if (rdev->family >= CHIP_TAHITI) { + *value = rdev->config.si.backend_enable_mask; + } else { + DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n"); + } + break; default: DRM_DEBUG_KMS("Invalid request %d\n", info->request); return -EINVAL; diff -Naur a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c 2014-04-03 01:45:50.181111972 +0530 @@ -422,6 +422,7 @@ /* Pin framebuffer & get tilling informations */ obj = radeon_fb->obj; rbo = gem_to_radeon_bo(obj); +retry: r = radeon_bo_reserve(rbo, false); if (unlikely(r != 0)) return r; @@ -430,6 +431,33 @@ &base); if (unlikely(r != 0)) { radeon_bo_unreserve(rbo); + + /* On old GPU like RN50 with little vram pining can fails because + * current fb is taking all space needed. So instead of unpining + * the old buffer after pining the new one, first unpin old one + * and then retry pining new one. + * + * As only master can set mode only master can pin and it is + * unlikely the master client will race with itself especialy + * on those old gpu with single crtc. + * + * We don't shutdown the display controller because new buffer + * will end up in same spot. + */ + if (!atomic && fb && fb != crtc->fb) { + struct radeon_bo *old_rbo; + unsigned long nsize, osize; + + old_rbo = gem_to_radeon_bo(to_radeon_framebuffer(fb)->obj); + osize = radeon_bo_size(old_rbo); + nsize = radeon_bo_size(rbo); + if (nsize <= osize && !radeon_bo_reserve(old_rbo, false)) { + radeon_bo_unpin(old_rbo); + radeon_bo_unreserve(old_rbo); + fb = NULL; + goto retry; + } + } return -EINVAL; } radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); diff -Naur a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c --- a/drivers/gpu/drm/radeon/radeon_uvd.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/radeon_uvd.c 2014-04-03 01:45:50.181111972 +0530 @@ -240,6 +240,8 @@ if (handle != 0 && rdev->uvd.filp[i] == filp) { struct radeon_fence *fence; + radeon_uvd_note_usage(rdev); + r = radeon_uvd_get_destroy_msg(rdev, R600_RING_TYPE_UVD_INDEX, handle, &fence); if (r) { @@ -470,7 +472,7 @@ return -EINVAL; } - if ((start >> 28) != (end >> 28)) { + if ((start >> 28) != ((end - 1) >> 28)) { DRM_ERROR("reloc %LX-%LX crossing 256MB boundary!\n", start, end); return -EINVAL; @@ -620,7 +622,7 @@ if (r) goto err; - r = radeon_ib_get(rdev, ring, &ib, NULL, 16); + r = radeon_ib_get(rdev, ring, &ib, NULL, 64); if (r) goto err; diff -Naur a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c --- a/drivers/gpu/drm/radeon/rs690.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/rs690.c 2014-04-03 01:45:50.181111972 +0530 @@ -162,6 +162,16 @@ base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); base = G_000100_MC_FB_START(base) << 16; rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); + /* Some boards seem to be configured for 128MB of sideport memory, + * but really only have 64MB. Just skip the sideport and use + * UMA memory. + */ + if (rdev->mc.igp_sideport_enabled && + (rdev->mc.real_vram_size == (384 * 1024 * 1024))) { + base += 128 * 1024 * 1024; + rdev->mc.real_vram_size -= 128 * 1024 * 1024; + rdev->mc.mc_vram_size = rdev->mc.real_vram_size; + } /* Use K8 direct mapping for fast fb access. */ rdev->fastfb_working = false; diff -Naur a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c --- a/drivers/gpu/drm/radeon/rv770_dpm.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/rv770_dpm.c 2014-04-03 01:45:50.185111972 +0530 @@ -2328,6 +2328,12 @@ pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, ASIC_INTERNAL_MEMORY_SS, 0); + /* disable ss, causes hangs on some cayman boards */ + if (rdev->family == CHIP_CAYMAN) { + pi->sclk_ss = false; + pi->mclk_ss = false; + } + if (pi->sclk_ss || pi->mclk_ss) pi->dynamic_ss = true; else diff -Naur a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c --- a/drivers/gpu/drm/radeon/si.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/si.c 2014-04-03 01:45:50.189111972 +0530 @@ -2816,7 +2816,7 @@ } static u32 si_get_rb_disabled(struct radeon_device *rdev, - u32 max_rb_num, u32 se_num, + u32 max_rb_num_per_se, u32 sh_per_se) { u32 data, mask; @@ -2830,14 +2830,14 @@ data >>= BACKEND_DISABLE_SHIFT; - mask = si_create_bitmask(max_rb_num / se_num / sh_per_se); + mask = si_create_bitmask(max_rb_num_per_se / sh_per_se); return data & mask; } static void si_setup_rb(struct radeon_device *rdev, u32 se_num, u32 sh_per_se, - u32 max_rb_num) + u32 max_rb_num_per_se) { int i, j; u32 data, mask; @@ -2847,19 +2847,21 @@ for (i = 0; i < se_num; i++) { for (j = 0; j < sh_per_se; j++) { si_select_se_sh(rdev, i, j); - data = si_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); + data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH); } } si_select_se_sh(rdev, 0xffffffff, 0xffffffff); mask = 1; - for (i = 0; i < max_rb_num; i++) { + for (i = 0; i < max_rb_num_per_se * se_num; i++) { if (!(disabled_rbs & mask)) enabled_rbs |= mask; mask <<= 1; } + rdev->config.si.backend_enable_mask = enabled_rbs; + for (i = 0; i < se_num; i++) { si_select_se_sh(rdev, i, 0xffffffff); data = 0; @@ -3887,8 +3889,15 @@ rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); /* size in MB on si */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; + tmp = RREG32(CONFIG_MEMSIZE); + /* some boards may have garbage in the upper 16 bits */ + if (tmp & 0xffff0000) { + DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); + if (tmp & 0xffff) + tmp &= 0xffff; + } + rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL; + rdev->mc.real_vram_size = rdev->mc.mc_vram_size; rdev->mc.visible_vram_size = rdev->mc.aper_size; si_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); diff -Naur a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h --- a/drivers/gpu/drm/radeon/sid.h 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/sid.h 2014-04-03 01:45:50.189111972 +0530 @@ -478,7 +478,7 @@ #define STATE3_MASK (0x1f << 15) #define STATE3_SHIFT 15 -#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x2808 +#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x28e8 #define TRAIN_DONE_D0 (1 << 30) #define TRAIN_DONE_D1 (1 << 31) diff -Naur a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c --- a/drivers/gpu/drm/radeon/trinity_dpm.c 2013-11-04 05:11:51.000000000 +0530 +++ b/drivers/gpu/drm/radeon/trinity_dpm.c 2014-04-03 01:45:50.193111972 +0530 @@ -1873,9 +1873,9 @@ pi->enable_sclk_ds = true; pi->enable_gfx_power_gating = true; pi->enable_gfx_clock_gating = true; - pi->enable_mg_clock_gating = true; - pi->enable_gfx_dynamic_mgpg = true; /* ??? */ - pi->override_dynamic_mgpg = true; + pi->enable_mg_clock_gating = false; + pi->enable_gfx_dynamic_mgpg = false; + pi->override_dynamic_mgpg = false; pi->enable_auto_thermal_throttling = true; pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */ pi->uvd_dpm = true; /* ??? */ diff -Naur a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h --- a/include/acpi/acpi_bus.h 2013-11-04 05:11:51.000000000 +0530 +++ b/include/acpi/acpi_bus.h 2014-04-03 02:41:15.381170177 +0530 @@ -168,6 +168,7 @@ u32 ejectable:1; u32 power_manageable:1; u32 match_driver:1; + u32 no_hotplug:1; u32 reserved:27; }; @@ -356,6 +357,7 @@ extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); void acpi_bus_private_data_handler(acpi_handle, void *); int acpi_bus_get_private_data(acpi_handle, void **); +void acpi_bus_no_hotplug(acpi_handle handle); extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); extern int register_acpi_notifier(struct notifier_block *); extern int unregister_acpi_notifier(struct notifier_block *); diff -Naur a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h --- a/include/uapi/drm/radeon_drm.h 2013-11-04 05:11:51.000000000 +0530 +++ b/include/uapi/drm/radeon_drm.h 2014-04-03 02:30:27.125158815 +0530 @@ -981,6 +981,8 @@ #define RADEON_INFO_SI_TILE_MODE_ARRAY 0x16 /* query if CP DMA is supported on the compute ring */ #define RADEON_INFO_SI_CP_DMA_COMPUTE 0x17 +/* query the number of render backends */ +#define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19 struct drm_radeon_info {