aboutsummaryrefslogtreecommitdiffstats
path: root/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch')
-rw-r--r--meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch780
1 files changed, 780 insertions, 0 deletions
diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch
new file mode 100644
index 00000000..8540cbf0
--- /dev/null
+++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch
@@ -0,0 +1,780 @@
+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 <arindam.nath@amd.com>
+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 <linux/hdmi.h>
++#include <linux/gcd.h>
+ #include <drm/drmP.h>
+ #include <drm/radeon_drm.h>
+ #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 {