From 0f57bca922ed2180056aa1f948536236488b4a0d Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 29 Oct 2013 01:19:16 +0200 Subject: [PATCH 01/23] drm/radeon/audio: fix missing multichannel PCM SAD in some cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current code writing SADs to the audio registers seems to assume that there is at most a single SAD per audio format. However, that is not the case. Especially for PCM it is somewhat common for sinks to have two SADs, one for 8-channel and one for 2-channel audio, which may have different supported sample rates (i.e. the sink supports stereo audio at higher sample rates than multichannel audio). Because of this, only the 2-channel SAD may be used if it appears before the 8-channel SAD. Unless other SADs require otherwise, this may cause the ALSA HDA driver to allow stereo playback only. Fix the code to pick the PCM SAD with the highest number of channels, while merging the rate masks of PCM SADs with lower amount of channels into the additional stereo rate mask byte. Technically there are even more cases to handle (multiple non-PCM SADs of the same type, more than two PCM SADs with varying channel counts, etc), but those have not actually been encountered in the field and handling them would be non-trivial. Example affected EDID from Onkyo TX-SR674 specifying 192kHz stereo support and 96kHz 8-channel support (and other 8-channel compressed formats): 00ffffffffffff003dcb010000000001 ffff0103800000780a0dc9a057479827 12484c00000001010101010101010101 010101010101011d8018711c1620582c 2500c48e2100009e011d007251d01e20 6e285500c48e2100001e000000fc0054 582d53523637342020202020000000fd 00313d0f2e08000a202020202020019b 02032f724f8504030f0e07069413121e 1d1615012f097f070f1f071707503707 503f07c0834f000066030c00ffff808c 0ad08a20e02d10103e9600c48e210000 18011d80d0721c1620102c2580c48e21 00009e011d00bc52d01e20b8285540c4 8e2100001e8c0ad090204031200c4055 00c48e210000180000000000000000a8 Signed-off-by: Anssi Hannula Tested-by: Andre Heider Cc: Rafał Miłecki Acked-by: Rafał Miłecki Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/dce6_afmt.c | 20 +++++++++++++++----- drivers/gpu/drm/radeon/evergreen_hdmi.c | 20 +++++++++++++++----- drivers/gpu/drm/radeon/r600_hdmi.c | 20 +++++++++++++++----- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index ab92620ed83a0..85c4993b53e15 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -244,20 +244,30 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; + u8 stereo_freqs = 0; + int max_channels = -1; int j; for (j = 0; j < sad_count; j++) { struct cea_sad *sad = &sads[j]; if (sad->format == eld_reg_to_type[i][1]) { - value = MAX_CHANNELS(sad->channels) | - DESCRIPTOR_BYTE_2(sad->byte2) | - SUPPORTED_FREQUENCIES(sad->freq); + if (sad->channels > max_channels) { + value = MAX_CHANNELS(sad->channels) | + DESCRIPTOR_BYTE_2(sad->byte2) | + SUPPORTED_FREQUENCIES(sad->freq); + max_channels = sad->channels; + } + if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) - value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); - break; + stereo_freqs |= sad->freq; + else + break; } } + + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); + WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); } diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index a82b6f78d7f2b..adbfef8705010 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -184,20 +184,30 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; + u8 stereo_freqs = 0; + int max_channels = -1; int j; for (j = 0; j < sad_count; j++) { struct cea_sad *sad = &sads[j]; if (sad->format == eld_reg_to_type[i][1]) { - value = MAX_CHANNELS(sad->channels) | - DESCRIPTOR_BYTE_2(sad->byte2) | - SUPPORTED_FREQUENCIES(sad->freq); + if (sad->channels > max_channels) { + value = MAX_CHANNELS(sad->channels) | + DESCRIPTOR_BYTE_2(sad->byte2) | + SUPPORTED_FREQUENCIES(sad->freq); + max_channels = sad->channels; + } + if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) - value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); - break; + stereo_freqs |= sad->freq; + else + break; } } + + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); + WREG32(eld_reg_to_type[i][0], value); } diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 0977c303aeec4..ace4dec21bc2b 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -388,20 +388,30 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; + u8 stereo_freqs = 0; + int max_channels = -1; int j; for (j = 0; j < sad_count; j++) { struct cea_sad *sad = &sads[j]; if (sad->format == eld_reg_to_type[i][1]) { - value = MAX_CHANNELS(sad->channels) | - DESCRIPTOR_BYTE_2(sad->byte2) | - SUPPORTED_FREQUENCIES(sad->freq); + if (sad->channels > max_channels) { + value = MAX_CHANNELS(sad->channels) | + DESCRIPTOR_BYTE_2(sad->byte2) | + SUPPORTED_FREQUENCIES(sad->freq); + max_channels = sad->channels; + } + if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) - value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); - break; + stereo_freqs |= sad->freq; + else + break; } } + + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); + WREG32(eld_reg_to_type[i][0], value); } From 75b871e2d831700d8fd63079eebbbc36b6731bdf Mon Sep 17 00:00:00 2001 From: Ilija Hadzic Date: Sat, 2 Nov 2013 23:00:19 -0400 Subject: [PATCH 02/23] drm/radeon/kms: unpin fb in atombios crtc disable When drm_helper_disable_unused_functions calls disable function of the CRTC, it also sets the crtc->fb pointer to NULL. This can later (when the mode on that CRTC is setup again from user space) cause ***_do_set_base functions to "think" that there is no old buffer and skip the unpinning code. Consequently, the buffer that has been NULL-ified in drm_helper_disable_unused_functions will never be unpinned causing a leak in VRAM. This patch plugs the leak by unpinning the frame buffer in crtc_disable function. Signed-off-by: Ilija Hadzic Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 86d9ee08b13f8..4ad1562673814 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1910,6 +1910,21 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) int i; atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + if (crtc->fb) { + int r; + struct radeon_framebuffer *radeon_fb; + struct radeon_bo *rbo; + + radeon_fb = to_radeon_framebuffer(crtc->fb); + rbo = gem_to_radeon_bo(radeon_fb->obj); + r = radeon_bo_reserve(rbo, false); + if (unlikely(r)) + DRM_ERROR("failed to reserve rbo before unpin\n"); + else { + radeon_bo_unpin(rbo); + radeon_bo_unreserve(rbo); + } + } /* disable the GRPH */ if (ASIC_IS_DCE4(rdev)) WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 0); From 520a8718fe1bb03a8fb58bfe1b0c0ca083a381cc Mon Sep 17 00:00:00 2001 From: Ilija Hadzic Date: Sat, 2 Nov 2013 23:00:20 -0400 Subject: [PATCH 03/23] drm/radeon/kms: add crtc_disable function for legacy crtc To plug the VRAM memory leak (see previous patch for details) we must unpin the frame buffer when disabling the CRTC. This warrants the addition of disable function for legacy CRTC, which puts the CRTC in DPMS-OFF state and unpins the frame buffer if there is one associated with the CRTC. Signed-off-by: Ilija Hadzic Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 7cb178a34a0f1..0c7b8c66301bd 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -1056,6 +1056,26 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) } } +static void radeon_crtc_disable(struct drm_crtc *crtc) +{ + radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + if (crtc->fb) { + int r; + struct radeon_framebuffer *radeon_fb; + struct radeon_bo *rbo; + + radeon_fb = to_radeon_framebuffer(crtc->fb); + rbo = gem_to_radeon_bo(radeon_fb->obj); + r = radeon_bo_reserve(rbo, false); + if (unlikely(r)) + DRM_ERROR("failed to reserve rbo before unpin\n"); + else { + radeon_bo_unpin(rbo); + radeon_bo_unreserve(rbo); + } + } +} + static const struct drm_crtc_helper_funcs legacy_helper_funcs = { .dpms = radeon_crtc_dpms, .mode_fixup = radeon_crtc_mode_fixup, @@ -1065,6 +1085,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = { .prepare = radeon_crtc_prepare, .commit = radeon_crtc_commit, .load_lut = radeon_crtc_load_lut, + .disable = radeon_crtc_disable }; From d45fd24dd30a791ba0739a1d3c4fd29710d94b9f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 7 Nov 2013 13:43:37 -0500 Subject: [PATCH 04/23] drm/radeon: use HDP_MEM_COHERENCY_FLUSH_CNTL for sdma as well The new HDP flush method doesn't seem to work reliably on sDMA either, so use the old method here too. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik_sdma.c | 40 ++++++++++--------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 8d84ebe2b6faa..9c9529de20ee8 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -102,14 +102,6 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, { struct radeon_ring *ring = &rdev->ring[fence->ring]; u64 addr = rdev->fence_drv[fence->ring].gpu_addr; - u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | - SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ - u32 ref_and_mask; - - if (fence->ring == R600_RING_TYPE_DMA_INDEX) - ref_and_mask = SDMA0; - else - ref_and_mask = SDMA1; /* write the fence */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_FENCE, 0, 0)); @@ -119,12 +111,12 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, /* generate an interrupt */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0)); /* flush HDP */ - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); - radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); - radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); - radeon_ring_write(ring, ref_and_mask); /* REFERENCE */ - radeon_ring_write(ring, ref_and_mask); /* MASK */ - radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */ + /* We should be using the new POLL_REG_MEM special op packet here + * but it causes sDMA to hang sometimes + */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); + radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); + radeon_ring_write(ring, 0); } /** @@ -720,18 +712,10 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) { struct radeon_ring *ring = &rdev->ring[ridx]; - u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | - SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ - u32 ref_and_mask; if (vm == NULL) return; - if (ridx == R600_RING_TYPE_DMA_INDEX) - ref_and_mask = SDMA0; - else - ref_and_mask = SDMA1; - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); if (vm->id < 8) { radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); @@ -766,12 +750,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm radeon_ring_write(ring, VMID(0)); /* flush HDP */ - radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); - radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); - radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); - radeon_ring_write(ring, ref_and_mask); /* REFERENCE */ - radeon_ring_write(ring, ref_and_mask); /* MASK */ - radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */ + /* We should be using the new POLL_REG_MEM special op packet here + * but it causes sDMA to hang sometimes + */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); + radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); + radeon_ring_write(ring, 0); /* flush TLB */ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); From 1cd73ff70d13a22faa95db8323382dd6d036554e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 7 Nov 2013 18:16:23 -0500 Subject: [PATCH 05/23] drm/radeon: fix-up some float to fixed conversion thinkos Spotted by Brad Smith when porting to OpenBSD. Noticed-by: Brad Smith Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/rs690.c | 16 +++++----------- drivers/gpu/drm/radeon/rv515.c | 8 -------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 1447d794c22ad..1c560629575a8 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -345,9 +345,11 @@ static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, if (max_bandwidth.full > rdev->pm.sideport_bandwidth.full && rdev->pm.sideport_bandwidth.full) max_bandwidth = rdev->pm.sideport_bandwidth; - read_delay_latency.full = dfixed_const(370 * 800 * 1000); - read_delay_latency.full = dfixed_div(read_delay_latency, - rdev->pm.igp_sideport_mclk); + read_delay_latency.full = dfixed_const(370 * 800); + a.full = dfixed_const(1000); + b.full = dfixed_div(rdev->pm.igp_sideport_mclk, a); + read_delay_latency.full = dfixed_div(read_delay_latency, b); + read_delay_latency.full = dfixed_mul(read_delay_latency, a); } else { if (max_bandwidth.full > rdev->pm.k8_bandwidth.full && rdev->pm.k8_bandwidth.full) @@ -488,14 +490,10 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -526,8 +524,6 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -555,8 +551,6 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev, } if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 873eb4b193b4f..5d1c316115efa 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -1155,14 +1155,10 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -1193,8 +1189,6 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev, } if (wm0->priority_mark.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; if (wm0->priority_mark_max.full > priority_mark02.full) priority_mark02.full = wm0->priority_mark_max.full; *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -1222,8 +1216,6 @@ static void rv515_compute_mode_priority(struct radeon_device *rdev, } if (wm1->priority_mark.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; if (wm1->priority_mark_max.full > priority_mark12.full) priority_mark12.full = wm1->priority_mark_max.full; *d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); From 3bf599e8a283ff30c64fb37a22b2c1db5a27614a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 6 Aug 2013 15:13:36 -0400 Subject: [PATCH 06/23] drm/radeon: add Hawaii chip family Hawaii is a new CI-based dGPU. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_device.c | 1 + drivers/gpu/drm/radeon/radeon_family.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 61dbdd9381330..b9234c43f43d4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -98,6 +98,7 @@ static const char radeon_family_name[][16] = { "BONAIRE", "KAVERI", "KABINI", + "HAWAII", "LAST", }; diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 3c8289083f9d4..614ad549297f2 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h @@ -96,6 +96,7 @@ enum radeon_family { CHIP_BONAIRE, CHIP_KAVERI, CHIP_KABINI, + CHIP_HAWAII, CHIP_LAST, }; From b496038bd4d5cc5271e962e00e93767a385ff646 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 6 Aug 2013 15:42:49 -0400 Subject: [PATCH 07/23] drm/radeon: update cik_gpu_init() for hawaii This adds the hawaii asic specific configuration details. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 17 +++++++++++++++++ drivers/gpu/drm/radeon/cikd.h | 1 + 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e8544758b5695..a2a30061172fe 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -2714,6 +2714,23 @@ static void cik_gpu_init(struct radeon_device *rdev) rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; break; + case CHIP_HAWAII: + rdev->config.cik.max_shader_engines = 4; + rdev->config.cik.max_tile_pipes = 16; + rdev->config.cik.max_cu_per_sh = 11; + rdev->config.cik.max_sh_per_se = 1; + rdev->config.cik.max_backends_per_se = 4; + rdev->config.cik.max_texture_channel_caches = 16; + rdev->config.cik.max_gprs = 256; + rdev->config.cik.max_gs_threads = 32; + rdev->config.cik.max_hw_contexts = 8; + + rdev->config.cik.sc_prim_fifo_size_frontend = 0x20; + rdev->config.cik.sc_prim_fifo_size_backend = 0x100; + rdev->config.cik.sc_hiz_tile_fifo_size = 0x30; + rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = HAWAII_GB_ADDR_CONFIG_GOLDEN; + break; case CHIP_KAVERI: rdev->config.cik.max_shader_engines = 1; rdev->config.cik.max_tile_pipes = 4; diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 380cea311a2be..aeb3d004431d9 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -25,6 +25,7 @@ #define CIK_H #define BONAIRE_GB_ADDR_CONFIG_GOLDEN 0x12010001 +#define HAWAII_GB_ADDR_CONFIG_GOLDEN 0x12011003 #define CIK_RB_BITMAP_WIDTH_PER_SH 2 From 939c0d3c08124cd7707168525c47354952c62d8d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 30 Sep 2013 18:03:06 -0400 Subject: [PATCH 08/23] drm/radeon: minor updates to cik.c for hawaii Skip programming a register that was removed and adjust the mask of the VM client status. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 10 ++++++++-- drivers/gpu/drm/radeon/cikd.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index a2a30061172fe..e91a2403b1254 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -3494,7 +3494,8 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev) int r; WREG32(CP_SEM_WAIT_TIMER, 0x0); - WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); + if (rdev->family != CHIP_HAWAII) + WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); /* Set the write pointer delay */ WREG32(CP_RB_WPTR_DELAY, 0); @@ -4831,12 +4832,17 @@ void cik_vm_fini(struct radeon_device *rdev) static void cik_vm_decode_fault(struct radeon_device *rdev, u32 status, u32 addr, u32 mc_client) { - u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; + u32 mc_id; u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT; u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT; char block[5] = { mc_client >> 24, (mc_client >> 16) & 0xff, (mc_client >> 8) & 0xff, mc_client & 0xff, 0 }; + if (rdev->family == CHIP_HAWAII) + mc_id = (status & HAWAII_MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; + else + mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; + printk("VM fault (0x%02x, vmid %d) at page %u, %s from '%s' (0x%08x) (%d)\n", protections, vmid, addr, (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read", diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index aeb3d004431d9..28cbcc1baa070 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -500,6 +500,7 @@ * bit 4: write */ #define MEMORY_CLIENT_ID_MASK (0xff << 12) +#define HAWAII_MEMORY_CLIENT_ID_MASK (0x1ff << 12) #define MEMORY_CLIENT_ID_SHIFT 12 #define MEMORY_CLIENT_RW_MASK (1 << 24) #define MEMORY_CLIENT_RW_SHIFT 24 From 21e438af6413496a970e491cb4b3e7449f452a10 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 6 Aug 2013 16:58:53 -0400 Subject: [PATCH 09/23] drm/radeon: update cik_tiling_mode_table_init() for hawaii Hawaii uses a different tiling configuration. Add support for it. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 222 +++++++++++++++++++++++++++++++++- drivers/gpu/drm/radeon/cikd.h | 2 + 2 files changed, 222 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e91a2403b1254..b3b2da671c6c2 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -1758,9 +1758,227 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev) num_pipe_configs = rdev->config.cik.max_tile_pipes; if (num_pipe_configs > 8) - num_pipe_configs = 8; /* ??? */ + num_pipe_configs = 16; - if (num_pipe_configs == 8) { + if (num_pipe_configs == 16) { + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { + switch (reg_offset) { + case 0: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B)); + break; + case 1: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B)); + break; + case 2: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); + break; + case 3: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B)); + break; + case 4: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(split_equal_to_row_size)); + break; + case 5: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + break; + case 6: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); + break; + case 7: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(split_equal_to_row_size)); + break; + case 8: + gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16)); + break; + case 9: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); + break; + case 10: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 11: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 12: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 13: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); + break; + case 14: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 16: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 17: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 27: + gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); + break; + case 28: + gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 29: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + case 30: + gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + break; + default: + gb_tile_moden = 0; + break; + } + rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden; + WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); + } + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { + switch (reg_offset) { + case 0: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 1: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 2: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 3: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 4: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + break; + case 5: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + break; + case 6: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_2_BANK)); + break; + case 8: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 9: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 10: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + break; + case 11: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + break; + case 12: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + break; + case 13: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_2_BANK)); + break; + case 14: + gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_2_BANK)); + break; + default: + gb_tile_moden = 0; + break; + } + WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden); + } + } else if (num_pipe_configs == 8) { for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { switch (reg_offset) { case 0: diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 28cbcc1baa070..8eea4f2cc92c7 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -1164,6 +1164,8 @@ # define ADDR_SURF_P8_32x32_16x16 12 # define ADDR_SURF_P8_32x32_16x32 13 # define ADDR_SURF_P8_32x64_32x32 14 +# define ADDR_SURF_P16_32x32_8x16 16 +# define ADDR_SURF_P16_32x32_16x16 17 # define TILE_SPLIT(x) ((x) << 11) # define ADDR_SURF_TILE_SPLIT_64B 0 # define ADDR_SURF_TILE_SPLIT_128B 1 From 8efff33742f5e2ed6184c2dacace5a1fe695909c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 7 Aug 2013 19:20:14 -0400 Subject: [PATCH 10/23] drm/radeon: add golden register settings for hawaii The golden register settings are optimal settings for certain registers from the hardware team. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 179 +++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index b3b2da671c6c2..6ca1f87af87a0 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -1297,6 +1297,171 @@ static const u32 kalindi_mgcg_cgcg_init[] = 0xd80c, 0xff000ff0, 0x00000100 }; +static const u32 hawaii_golden_spm_registers[] = +{ + 0x30800, 0xe0ffffff, 0xe0000000 +}; + +static const u32 hawaii_golden_common_registers[] = +{ + 0x30800, 0xffffffff, 0xe0000000, + 0x28350, 0xffffffff, 0x3a00161a, + 0x28354, 0xffffffff, 0x0000002e, + 0x9a10, 0xffffffff, 0x00018208, + 0x98f8, 0xffffffff, 0x12011003 +}; + +static const u32 hawaii_golden_registers[] = +{ + 0x3354, 0x00000333, 0x00000333, + 0x9a10, 0x00010000, 0x00058208, + 0x9830, 0xffffffff, 0x00000000, + 0x9834, 0xf00fffff, 0x00000400, + 0x9838, 0x0002021c, 0x00020200, + 0xc78, 0x00000080, 0x00000000, + 0x5bb0, 0x000000f0, 0x00000070, + 0x5bc0, 0xf0311fff, 0x80300000, + 0x350c, 0x00810000, 0x408af000, + 0x7030, 0x31000111, 0x00000011, + 0x2f48, 0x73773777, 0x12010001, + 0x2120, 0x0000007f, 0x0000001b, + 0x21dc, 0x00007fb6, 0x00002191, + 0x3628, 0x0000003f, 0x0000000a, + 0x362c, 0x0000003f, 0x0000000a, + 0x2ae4, 0x00073ffe, 0x000022a2, + 0x240c, 0x000007ff, 0x00000000, + 0x8bf0, 0x00002001, 0x00000001, + 0x8b24, 0xffffffff, 0x00ffffff, + 0x30a04, 0x0000ff0f, 0x00000000, + 0x28a4c, 0x07ffffff, 0x06000000, + 0x3e78, 0x00000001, 0x00000002, + 0xc768, 0x00000008, 0x00000008, + 0xc770, 0x00000f00, 0x00000800, + 0xc774, 0x00000f00, 0x00000800, + 0xc798, 0x00ffffff, 0x00ff7fbf, + 0xc79c, 0x00ffffff, 0x00ff7faf, + 0x8c00, 0x000000ff, 0x00000800, + 0xe40, 0x00001fff, 0x00001fff, + 0x9060, 0x0000007f, 0x00000020, + 0x9508, 0x00010000, 0x00010000, + 0xae00, 0x00100000, 0x000ff07c, + 0xac14, 0x000003ff, 0x0000000f, + 0xac10, 0xffffffff, 0x7564fdec, + 0xac0c, 0xffffffff, 0x3120b9a8, + 0xac08, 0x20000000, 0x0f9c0000 +}; + +static const u32 hawaii_mgcg_cgcg_init[] = +{ + 0xc420, 0xffffffff, 0xfffffffd, + 0x30800, 0xffffffff, 0xe0000000, + 0x3c2a0, 0xffffffff, 0x00000100, + 0x3c208, 0xffffffff, 0x00000100, + 0x3c2c0, 0xffffffff, 0x00000100, + 0x3c2c8, 0xffffffff, 0x00000100, + 0x3c2c4, 0xffffffff, 0x00000100, + 0x55e4, 0xffffffff, 0x00200100, + 0x3c280, 0xffffffff, 0x00000100, + 0x3c214, 0xffffffff, 0x06000100, + 0x3c220, 0xffffffff, 0x00000100, + 0x3c218, 0xffffffff, 0x06000100, + 0x3c204, 0xffffffff, 0x00000100, + 0x3c2e0, 0xffffffff, 0x00000100, + 0x3c224, 0xffffffff, 0x00000100, + 0x3c200, 0xffffffff, 0x00000100, + 0x3c230, 0xffffffff, 0x00000100, + 0x3c234, 0xffffffff, 0x00000100, + 0x3c250, 0xffffffff, 0x00000100, + 0x3c254, 0xffffffff, 0x00000100, + 0x3c258, 0xffffffff, 0x00000100, + 0x3c25c, 0xffffffff, 0x00000100, + 0x3c260, 0xffffffff, 0x00000100, + 0x3c27c, 0xffffffff, 0x00000100, + 0x3c278, 0xffffffff, 0x00000100, + 0x3c210, 0xffffffff, 0x06000100, + 0x3c290, 0xffffffff, 0x00000100, + 0x3c274, 0xffffffff, 0x00000100, + 0x3c2b4, 0xffffffff, 0x00000100, + 0x3c2b0, 0xffffffff, 0x00000100, + 0x3c270, 0xffffffff, 0x00000100, + 0x30800, 0xffffffff, 0xe0000000, + 0x3c020, 0xffffffff, 0x00010000, + 0x3c024, 0xffffffff, 0x00030002, + 0x3c028, 0xffffffff, 0x00040007, + 0x3c02c, 0xffffffff, 0x00060005, + 0x3c030, 0xffffffff, 0x00090008, + 0x3c034, 0xffffffff, 0x00010000, + 0x3c038, 0xffffffff, 0x00030002, + 0x3c03c, 0xffffffff, 0x00040007, + 0x3c040, 0xffffffff, 0x00060005, + 0x3c044, 0xffffffff, 0x00090008, + 0x3c048, 0xffffffff, 0x00010000, + 0x3c04c, 0xffffffff, 0x00030002, + 0x3c050, 0xffffffff, 0x00040007, + 0x3c054, 0xffffffff, 0x00060005, + 0x3c058, 0xffffffff, 0x00090008, + 0x3c05c, 0xffffffff, 0x00010000, + 0x3c060, 0xffffffff, 0x00030002, + 0x3c064, 0xffffffff, 0x00040007, + 0x3c068, 0xffffffff, 0x00060005, + 0x3c06c, 0xffffffff, 0x00090008, + 0x3c070, 0xffffffff, 0x00010000, + 0x3c074, 0xffffffff, 0x00030002, + 0x3c078, 0xffffffff, 0x00040007, + 0x3c07c, 0xffffffff, 0x00060005, + 0x3c080, 0xffffffff, 0x00090008, + 0x3c084, 0xffffffff, 0x00010000, + 0x3c088, 0xffffffff, 0x00030002, + 0x3c08c, 0xffffffff, 0x00040007, + 0x3c090, 0xffffffff, 0x00060005, + 0x3c094, 0xffffffff, 0x00090008, + 0x3c098, 0xffffffff, 0x00010000, + 0x3c09c, 0xffffffff, 0x00030002, + 0x3c0a0, 0xffffffff, 0x00040007, + 0x3c0a4, 0xffffffff, 0x00060005, + 0x3c0a8, 0xffffffff, 0x00090008, + 0x3c0ac, 0xffffffff, 0x00010000, + 0x3c0b0, 0xffffffff, 0x00030002, + 0x3c0b4, 0xffffffff, 0x00040007, + 0x3c0b8, 0xffffffff, 0x00060005, + 0x3c0bc, 0xffffffff, 0x00090008, + 0x3c0c0, 0xffffffff, 0x00010000, + 0x3c0c4, 0xffffffff, 0x00030002, + 0x3c0c8, 0xffffffff, 0x00040007, + 0x3c0cc, 0xffffffff, 0x00060005, + 0x3c0d0, 0xffffffff, 0x00090008, + 0x3c0d4, 0xffffffff, 0x00010000, + 0x3c0d8, 0xffffffff, 0x00030002, + 0x3c0dc, 0xffffffff, 0x00040007, + 0x3c0e0, 0xffffffff, 0x00060005, + 0x3c0e4, 0xffffffff, 0x00090008, + 0x3c0e8, 0xffffffff, 0x00010000, + 0x3c0ec, 0xffffffff, 0x00030002, + 0x3c0f0, 0xffffffff, 0x00040007, + 0x3c0f4, 0xffffffff, 0x00060005, + 0x3c0f8, 0xffffffff, 0x00090008, + 0xc318, 0xffffffff, 0x00020200, + 0x3350, 0xffffffff, 0x00000200, + 0x15c0, 0xffffffff, 0x00000400, + 0x55e8, 0xffffffff, 0x00000000, + 0x2f50, 0xffffffff, 0x00000902, + 0x3c000, 0xffffffff, 0x96940200, + 0x8708, 0xffffffff, 0x00900100, + 0xc424, 0xffffffff, 0x0020003f, + 0x38, 0xffffffff, 0x0140001c, + 0x3c, 0x000f0000, 0x000f0000, + 0x220, 0xffffffff, 0xc060000c, + 0x224, 0xc0000fff, 0x00000100, + 0xf90, 0xffffffff, 0x00000100, + 0xf98, 0x00000101, 0x00000000, + 0x20a8, 0xffffffff, 0x00000104, + 0x55e4, 0xff000fff, 0x00000100, + 0x30cc, 0xc0000fff, 0x00000104, + 0xc1e4, 0x00000001, 0x00000001, + 0xd00c, 0xff000ff0, 0x00000100, + 0xd80c, 0xff000ff0, 0x00000100 +}; + static void cik_init_golden_registers(struct radeon_device *rdev) { switch (rdev->family) { @@ -1342,6 +1507,20 @@ static void cik_init_golden_registers(struct radeon_device *rdev) spectre_golden_spm_registers, (const u32)ARRAY_SIZE(spectre_golden_spm_registers)); break; + case CHIP_HAWAII: + radeon_program_register_sequence(rdev, + hawaii_mgcg_cgcg_init, + (const u32)ARRAY_SIZE(hawaii_mgcg_cgcg_init)); + radeon_program_register_sequence(rdev, + hawaii_golden_registers, + (const u32)ARRAY_SIZE(hawaii_golden_registers)); + radeon_program_register_sequence(rdev, + hawaii_golden_common_registers, + (const u32)ARRAY_SIZE(hawaii_golden_common_registers)); + radeon_program_register_sequence(rdev, + hawaii_golden_spm_registers, + (const u32)ARRAY_SIZE(hawaii_golden_spm_registers)); + break; default: break; } From fc821b70b0e58908e94464d0479c9898dd1074f9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 7 Aug 2013 20:14:08 -0400 Subject: [PATCH 11/23] drm/radeon: update rb setup for hawaii The formula needs to be adjusted since there are 4 RBs per SH rather than 2 as on previous asics. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 11 ++++++++++- drivers/gpu/drm/radeon/cikd.h | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 6ca1f87af87a0..24d96cbb1f037 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -3042,7 +3042,10 @@ static void cik_setup_rb(struct radeon_device *rdev, 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); - disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); + if (rdev->family == CHIP_HAWAII) + disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH); + else + disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); } } cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); @@ -3059,6 +3062,12 @@ static void cik_setup_rb(struct radeon_device *rdev, data = 0; for (j = 0; j < sh_per_se; j++) { switch (enabled_rbs & 3) { + case 0: + if (j == 0) + data |= PKR_MAP(RASTER_CONFIG_RB_MAP_3); + else + data |= PKR_MAP(RASTER_CONFIG_RB_MAP_0); + break; case 1: data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2); break; diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 8eea4f2cc92c7..5964af5e5b2d8 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -27,7 +27,8 @@ #define BONAIRE_GB_ADDR_CONFIG_GOLDEN 0x12010001 #define HAWAII_GB_ADDR_CONFIG_GOLDEN 0x12011003 -#define CIK_RB_BITMAP_WIDTH_PER_SH 2 +#define CIK_RB_BITMAP_WIDTH_PER_SH 2 +#define HAWAII_RB_BITMAP_WIDTH_PER_SH 4 /* DIDT IND registers */ #define DIDT_SQ_CTRL0 0x0 @@ -1459,6 +1460,7 @@ # define RASTER_CONFIG_RB_MAP_1 1 # define RASTER_CONFIG_RB_MAP_2 2 # define RASTER_CONFIG_RB_MAP_3 3 +#define PKR_MAP(x) ((x) << 8) #define VGT_EVENT_INITIATOR 0x28a90 # define SAMPLE_STREAMOUTSTATS1 (1 << 0) From d47756556d3f8d65a8512d6fbcc9eb2ab0069ba9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 8 Aug 2013 16:06:35 -0400 Subject: [PATCH 12/23] drm/radeon: update firmware loading for hawaii This just updates the firmware loading functions to look for the appropriate firmware files for hawaii. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 61 +++++++++++++++++++++++++-- drivers/gpu/drm/radeon/radeon_ucode.h | 4 ++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 24d96cbb1f037..c949ad23c8714 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -41,6 +41,14 @@ MODULE_FIRMWARE("radeon/BONAIRE_mc.bin"); MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin"); MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin"); MODULE_FIRMWARE("radeon/BONAIRE_smc.bin"); +MODULE_FIRMWARE("radeon/HAWAII_pfp.bin"); +MODULE_FIRMWARE("radeon/HAWAII_me.bin"); +MODULE_FIRMWARE("radeon/HAWAII_ce.bin"); +MODULE_FIRMWARE("radeon/HAWAII_mec.bin"); +MODULE_FIRMWARE("radeon/HAWAII_mc.bin"); +MODULE_FIRMWARE("radeon/HAWAII_rlc.bin"); +MODULE_FIRMWARE("radeon/HAWAII_sdma.bin"); +MODULE_FIRMWARE("radeon/HAWAII_smc.bin"); MODULE_FIRMWARE("radeon/KAVERI_pfp.bin"); MODULE_FIRMWARE("radeon/KAVERI_me.bin"); MODULE_FIRMWARE("radeon/KAVERI_ce.bin"); @@ -1628,6 +1636,35 @@ static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] = {0x0000009f, 0x00b48000} }; +#define HAWAII_IO_MC_REGS_SIZE 22 + +static const u32 hawaii_io_mc_regs[HAWAII_IO_MC_REGS_SIZE][2] = +{ + {0x0000007d, 0x40000000}, + {0x0000007e, 0x40180304}, + {0x0000007f, 0x0000ff00}, + {0x00000081, 0x00000000}, + {0x00000083, 0x00000800}, + {0x00000086, 0x00000000}, + {0x00000087, 0x00000100}, + {0x00000088, 0x00020100}, + {0x00000089, 0x00000000}, + {0x0000008b, 0x00040000}, + {0x0000008c, 0x00000100}, + {0x0000008e, 0xff010000}, + {0x00000090, 0xffffefff}, + {0x00000091, 0xfff3efff}, + {0x00000092, 0xfff3efbf}, + {0x00000093, 0xf7ffffff}, + {0x00000094, 0xffffff7f}, + {0x00000095, 0x00000fff}, + {0x00000096, 0x00116fff}, + {0x00000097, 0x60010000}, + {0x00000098, 0x10010000}, + {0x0000009f, 0x00c79000} +}; + + /** * cik_srbm_select - select specific register instances * @@ -1672,11 +1709,17 @@ static int ci_mc_load_microcode(struct radeon_device *rdev) switch (rdev->family) { case CHIP_BONAIRE: - default: io_mc_regs = (u32 *)&bonaire_io_mc_regs; ucode_size = CIK_MC_UCODE_SIZE; regs_size = BONAIRE_IO_MC_REGS_SIZE; break; + case CHIP_HAWAII: + io_mc_regs = (u32 *)&hawaii_io_mc_regs; + ucode_size = HAWAII_MC_UCODE_SIZE; + regs_size = HAWAII_IO_MC_REGS_SIZE; + break; + default: + return -EINVAL; } running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; @@ -1738,8 +1781,8 @@ static int cik_init_microcode(struct radeon_device *rdev) { const char *chip_name; size_t pfp_req_size, me_req_size, ce_req_size, - mec_req_size, rlc_req_size, mc_req_size, - sdma_req_size, smc_req_size; + mec_req_size, rlc_req_size, mc_req_size = 0, + sdma_req_size, smc_req_size = 0; char fw_name[30]; int err; @@ -1757,6 +1800,17 @@ static int cik_init_microcode(struct radeon_device *rdev) sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4); break; + case CHIP_HAWAII: + chip_name = "HAWAII"; + pfp_req_size = CIK_PFP_UCODE_SIZE * 4; + me_req_size = CIK_ME_UCODE_SIZE * 4; + ce_req_size = CIK_CE_UCODE_SIZE * 4; + mec_req_size = CIK_MEC_UCODE_SIZE * 4; + rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4; + mc_req_size = HAWAII_MC_UCODE_SIZE * 4; + sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; + smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4); + break; case CHIP_KAVERI: chip_name = "KAVERI"; pfp_req_size = CIK_PFP_UCODE_SIZE * 4; @@ -5505,6 +5559,7 @@ static int cik_rlc_resume(struct radeon_device *rdev) switch (rdev->family) { case CHIP_BONAIRE: + case CHIP_HAWAII: default: size = BONAIRE_RLC_UCODE_SIZE; break; diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h index 33858364fe89b..a77cd274dfc3f 100644 --- a/drivers/gpu/drm/radeon/radeon_ucode.h +++ b/drivers/gpu/drm/radeon/radeon_ucode.h @@ -59,6 +59,7 @@ #define SI_MC_UCODE_SIZE 7769 #define OLAND_MC_UCODE_SIZE 7863 #define CIK_MC_UCODE_SIZE 7866 +#define HAWAII_MC_UCODE_SIZE 7933 /* SDMA */ #define CIK_SDMA_UCODE_SIZE 1050 @@ -143,4 +144,7 @@ #define BONAIRE_SMC_UCODE_START 0x20000 #define BONAIRE_SMC_UCODE_SIZE 0x1FDEC +#define HAWAII_SMC_UCODE_START 0x20000 +#define HAWAII_SMC_UCODE_SIZE 0x1FDEC + #endif From 4256331ae9382de899e3810510dc2bcc6ad2c1d4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 24 Sep 2013 11:08:17 -0400 Subject: [PATCH 13/23] drm/radeon/cik: add hawaii UVD support Has same version of UVD as other CIK parts. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_uvd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index ab0a17248d55d..373d088bac66d 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -97,6 +97,7 @@ int radeon_uvd_init(struct radeon_device *rdev) case CHIP_BONAIRE: case CHIP_KABINI: case CHIP_KAVERI: + case CHIP_HAWAII: fw_name = FIRMWARE_BONAIRE; break; From 2d40038d3f99a489fc1ef6c03d5a600de34c552f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 9 Aug 2013 18:27:47 -0400 Subject: [PATCH 14/23] drm/radeon: add hawaii dpm support This updates the CI dpm (dynamic power management) support for hawaii. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 58 ++++++++++++++++++++++++------ drivers/gpu/drm/radeon/ci_smc.c | 4 +++ drivers/gpu/drm/radeon/radeon_pm.c | 1 + 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 51e947a97edf9..1ed4799763580 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -40,6 +40,20 @@ #define VOLTAGE_VID_OFFSET_SCALE1 625 #define VOLTAGE_VID_OFFSET_SCALE2 100 +static const struct ci_pt_defaults defaults_hawaii_xt = +{ + 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0xB0000, + { 0x84, 0x0, 0x0, 0x7F, 0x0, 0x0, 0x5A, 0x60, 0x51, 0x8E, 0x79, 0x6B, 0x5F, 0x90, 0x79 }, + { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC } +}; + +static const struct ci_pt_defaults defaults_hawaii_pro = +{ + 1, 0xF, 0xFD, 0x19, 5, 0x14, 0, 0x65062, + { 0x93, 0x0, 0x0, 0x97, 0x0, 0x0, 0x6B, 0x60, 0x51, 0x95, 0x79, 0x6B, 0x5F, 0x90, 0x79 }, + { 0x1EA, 0x1EA, 0x1EA, 0x224, 0x224, 0x224, 0x24F, 0x24F, 0x24F, 0x28E, 0x28E, 0x28E, 0x2BC, 0x2BC, 0x2BC } +}; + static const struct ci_pt_defaults defaults_bonaire_xt = { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0xB0000, @@ -187,22 +201,38 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev) struct ci_power_info *pi = ci_get_pi(rdev); switch (rdev->pdev->device) { - case 0x6650: - case 0x6658: - case 0x665C: - default: + case 0x6650: + case 0x6658: + case 0x665C: + default: pi->powertune_defaults = &defaults_bonaire_xt; break; - case 0x6651: - case 0x665D: + case 0x6651: + case 0x665D: pi->powertune_defaults = &defaults_bonaire_pro; break; - case 0x6640: + case 0x6640: pi->powertune_defaults = &defaults_saturn_xt; break; - case 0x6641: + case 0x6641: pi->powertune_defaults = &defaults_saturn_pro; break; + case 0x67B8: + case 0x67B0: + case 0x67A0: + case 0x67A1: + case 0x67A2: + case 0x67A8: + case 0x67A9: + case 0x67AA: + case 0x67B9: + case 0x67BE: + pi->powertune_defaults = &defaults_hawaii_xt; + break; + case 0x67BA: + case 0x67B1: + pi->powertune_defaults = &defaults_hawaii_pro; + break; } pi->dte_tj_offset = 0; @@ -5142,9 +5172,15 @@ int ci_dpm_init(struct radeon_device *rdev) rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0; rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL; - pi->thermal_temp_setting.temperature_low = 99500; - pi->thermal_temp_setting.temperature_high = 100000; - pi->thermal_temp_setting.temperature_shutdown = 104000; + if (rdev->family == CHIP_HAWAII) { + pi->thermal_temp_setting.temperature_low = 94500; + pi->thermal_temp_setting.temperature_high = 95000; + pi->thermal_temp_setting.temperature_shutdown = 104000; + } else { + pi->thermal_temp_setting.temperature_low = 99500; + pi->thermal_temp_setting.temperature_high = 100000; + pi->thermal_temp_setting.temperature_shutdown = 104000; + } pi->uvd_enabled = false; diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c index 252e10a41cf5a..9c745dd224389 100644 --- a/drivers/gpu/drm/radeon/ci_smc.c +++ b/drivers/gpu/drm/radeon/ci_smc.c @@ -217,6 +217,10 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit) ucode_start_address = BONAIRE_SMC_UCODE_START; ucode_size = BONAIRE_SMC_UCODE_SIZE; break; + case CHIP_HAWAII: + ucode_start_address = HAWAII_SMC_UCODE_START; + ucode_size = HAWAII_SMC_UCODE_SIZE; + break; default: DRM_ERROR("unknown asic in smc ucode loader\n"); BUG(); diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 00bdcd3e47baa..866ace070b918 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1256,6 +1256,7 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_BONAIRE: case CHIP_KABINI: case CHIP_KAVERI: + case CHIP_HAWAII: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw) rdev->pm.pm_method = PM_METHOD_PROFILE; From bbfe90bd4e3e5033e10bda3453c0055a9193c5d7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 13 Aug 2013 22:59:41 -0400 Subject: [PATCH 15/23] drm/radeon: update cik_get_csb_buffer for hawaii Set the PA_SC_RASTER_CONFIG[_1] registers for hawaii. The rest is the same as the other asics. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index c949ad23c8714..ae92aa041c6a5 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -6316,6 +6316,10 @@ void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ buffer[count++] = cpu_to_le32(0x00000000); break; + case CHIP_HAWAII: + buffer[count++] = 0x3a00161a; + buffer[count++] = 0x0000002e; + break; default: buffer[count++] = cpu_to_le32(0x00000000); buffer[count++] = cpu_to_le32(0x00000000); From 60669d56f5bd9f3159f48325b9f8a3fa60b59ddf Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 19 Aug 2013 19:45:47 -0400 Subject: [PATCH 16/23] drm/radeon: atombios.h updates for hawaii This updates atombios.h with the latest changes required for hawaii. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios.h | 127 +++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index af10f8571d87b..92be50c39ffd4 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -1711,7 +1711,9 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V6 #define PIXEL_CLOCK_V6_MISC_HDMI_BPP_MASK 0x0c #define PIXEL_CLOCK_V6_MISC_HDMI_24BPP 0x00 #define PIXEL_CLOCK_V6_MISC_HDMI_36BPP 0x04 +#define PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6 0x08 //for V6, the correct defintion for 36bpp should be 2 for 36bpp(2:1) #define PIXEL_CLOCK_V6_MISC_HDMI_30BPP 0x08 +#define PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6 0x04 //for V6, the correct defintion for 30bpp should be 1 for 36bpp(5:4) #define PIXEL_CLOCK_V6_MISC_HDMI_48BPP 0x0c #define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC 0x10 #define PIXEL_CLOCK_V6_MISC_GEN_DPREFCLK 0x40 @@ -2223,7 +2225,7 @@ typedef struct _SET_VOLTAGE_PARAMETERS_V2 USHORT usVoltageLevel; // real voltage level }SET_VOLTAGE_PARAMETERS_V2; - +// used by both SetVoltageTable v1.3 and v1.4 typedef struct _SET_VOLTAGE_PARAMETERS_V1_3 { UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI @@ -2290,15 +2292,36 @@ typedef struct _GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1 #define ATOM_GET_VOLTAGE_VID 0x00 #define ATOM_GET_VOTLAGE_INIT_SEQ 0x03 #define ATOM_GET_VOLTTAGE_PHASE_PHASE_VID 0x04 -// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state -#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10 +#define ATOM_GET_VOLTAGE_SVID2 0x07 //Get SVI2 Regulator Info +// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state +#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10 // for SI, this state map to 0xff01 voltage state in Power Play table, which is performance state #define ATOM_GET_VOLTAGE_STATE1_LEAKAGE_VID 0x11 -// undefined power state + #define ATOM_GET_VOLTAGE_STATE2_LEAKAGE_VID 0x12 #define ATOM_GET_VOLTAGE_STATE3_LEAKAGE_VID 0x13 +// New Added from CI Hawaii for GetVoltageInfoTable, input parameter structure +typedef struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 +{ + UCHAR ucVoltageType; // Input: To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI + UCHAR ucVoltageMode; // Input: Indicate action: Get voltage info + USHORT usVoltageLevel; // Input: real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) or Leakage Id + ULONG ulSCLKFreq; // Input: when ucVoltageMode= ATOM_GET_VOLTAGE_EVV_VOLTAGE, DPM state SCLK frequency, Define in PPTable SCLK/Voltage dependence table +}GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2; + +// New in GetVoltageInfo v1.2 ucVoltageMode +#define ATOM_GET_VOLTAGE_EVV_VOLTAGE 0x09 + +// New Added from CI Hawaii for EVV feature +typedef struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 +{ + USHORT usVoltageLevel; // real voltage level in unit of mv + USHORT usVoltageId; // Voltage Id programmed in Voltage Regulator + ULONG ulReseved; +}GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2; + /****************************************************************************/ // Structures used by TVEncoderControlTable /****************************************************************************/ @@ -3864,6 +3887,8 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT #define PP_AC_DC_SWITCH_GPIO_PINID 60 //from SMU7.x, if ucGPIO_ID=VDDC_REGULATOR_VRHOT_GPIO_PINID in GPIO_LUTable, VRHot feature is enable #define VDDC_VRHOT_GPIO_PINID 61 +//if ucGPIO_ID=VDDC_PCC_GPIO_PINID in GPIO_LUTable, Peak Current Control feature is enabled +#define VDDC_PCC_GPIO_PINID 62 typedef struct _ATOM_GPIO_PIN_LUT { @@ -4169,10 +4194,10 @@ typedef struct _ATOM_COMMON_RECORD_HEADER #define ATOM_OBJECT_LINK_RECORD_TYPE 18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record #define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19 #define ATOM_ENCODER_CAP_RECORD_TYPE 20 - +#define ATOM_BRACKET_LAYOUT_RECORD_TYPE 21 //Must be updated when new record type is added,equal to that record definition! -#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_ENCODER_CAP_RECORD_TYPE +#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_BRACKET_LAYOUT_RECORD_TYPE typedef struct _ATOM_I2C_RECORD { @@ -4397,6 +4422,31 @@ typedef struct _ATOM_CONNECTOR_REMOTE_CAP_RECORD USHORT usReserved; }ATOM_CONNECTOR_REMOTE_CAP_RECORD; +typedef struct _ATOM_CONNECTOR_LAYOUT_INFO +{ + USHORT usConnectorObjectId; + UCHAR ucConnectorType; + UCHAR ucPosition; +}ATOM_CONNECTOR_LAYOUT_INFO; + +// define ATOM_CONNECTOR_LAYOUT_INFO.ucConnectorType to describe the display connector size +#define CONNECTOR_TYPE_DVI_D 1 +#define CONNECTOR_TYPE_DVI_I 2 +#define CONNECTOR_TYPE_VGA 3 +#define CONNECTOR_TYPE_HDMI 4 +#define CONNECTOR_TYPE_DISPLAY_PORT 5 +#define CONNECTOR_TYPE_MINI_DISPLAY_PORT 6 + +typedef struct _ATOM_BRACKET_LAYOUT_RECORD +{ + ATOM_COMMON_RECORD_HEADER sheader; + UCHAR ucLength; + UCHAR ucWidth; + UCHAR ucConnNum; + UCHAR ucReserved; + ATOM_CONNECTOR_LAYOUT_INFO asConnInfo[1]; +}ATOM_BRACKET_LAYOUT_RECORD; + /****************************************************************************/ // ASIC voltage data table /****************************************************************************/ @@ -4524,8 +4574,9 @@ typedef struct _ATOM_VOLTAGE_OBJECT_HEADER_V3{ #define VOLTAGE_OBJ_VR_I2C_INIT_SEQ 3 //VOLTAGE REGULATOR INIT sequece through I2C -> ATOM_I2C_VOLTAGE_OBJECT_V3 #define VOLTAGE_OBJ_PHASE_LUT 4 //Set Vregulator Phase lookup table ->ATOM_GPIO_VOLTAGE_OBJECT_V3 #define VOLTAGE_OBJ_SVID2 7 //Indicate voltage control by SVID2 ->ATOM_SVID2_VOLTAGE_OBJECT_V3 -#define VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT 0x10 //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 -#define VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT 0x11 //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 +#define VOLTAGE_OBJ_EVV 8 +#define VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT 0x10 //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 +#define VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT 0x11 //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 #define VOLTAGE_OBJ_HIGH1_STATE_LEAKAGE_LUT 0x12 //High1 voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 typedef struct _VOLTAGE_LUT_ENTRY_V2 @@ -4552,6 +4603,10 @@ typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3 VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff }ATOM_I2C_VOLTAGE_OBJECT_V3; +// ATOM_I2C_VOLTAGE_OBJECT_V3.ucVoltageControlFlag +#define VOLTAGE_DATA_ONE_BYTE 0 +#define VOLTAGE_DATA_TWO_BYTE 1 + typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3 { ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; // voltage mode = VOLTAGE_OBJ_GPIO_LUT or VOLTAGE_OBJ_PHASE_LUT @@ -4584,7 +4639,8 @@ typedef struct _ATOM_SVID2_VOLTAGE_OBJECT_V3 // 1:0 – offset trim, USHORT usLoadLine_PSI; // GPU GPIO pin Id to SVID2 regulator VRHot pin. possible value 0~31. 0 means GPIO0, 31 means GPIO31 - UCHAR ucReserved[2]; + UCHAR ucSVDGpioId; //0~31 indicate GPIO0~31 + UCHAR ucSVCGpioId; //0~31 indicate GPIO0~31 ULONG ulReserved; }ATOM_SVID2_VOLTAGE_OBJECT_V3; @@ -4637,6 +4693,49 @@ typedef struct _ATOM_ASIC_PROFILING_INFO_V2_1 USHORT usElbVDDCI_LevelArrayOffset; // offset of 2 dimension voltage level USHORT array }ATOM_ASIC_PROFILING_INFO_V2_1; +typedef struct _ATOM_ASIC_PROFILING_INFO_V3_1 +{ + ATOM_COMMON_TABLE_HEADER asHeader; + ULONG ulEvvDerateTdp; + ULONG ulEvvDerateTdc; + ULONG ulBoardCoreTemp; + ULONG ulMaxVddc; + ULONG ulMinVddc; + ULONG ulLoadLineSlop; + ULONG ulLeakageTemp; + ULONG ulLeakageVoltage; + ULONG ulCACmEncodeRange; + ULONG ulCACmEncodeAverage; + ULONG ulCACbEncodeRange; + ULONG ulCACbEncodeAverage; + ULONG ulKt_bEncodeRange; + ULONG ulKt_bEncodeAverage; + ULONG ulKv_mEncodeRange; + ULONG ulKv_mEncodeAverage; + ULONG ulKv_bEncodeRange; + ULONG ulKv_bEncodeAverage; + ULONG ulLkgEncodeLn_MaxDivMin; + ULONG ulLkgEncodeMin; + ULONG ulEfuseLogisticAlpha; + USHORT usPowerDpm0; + USHORT usCurrentDpm0; + USHORT usPowerDpm1; + USHORT usCurrentDpm1; + USHORT usPowerDpm2; + USHORT usCurrentDpm2; + USHORT usPowerDpm3; + USHORT usCurrentDpm3; + USHORT usPowerDpm4; + USHORT usCurrentDpm4; + USHORT usPowerDpm5; + USHORT usCurrentDpm5; + USHORT usPowerDpm6; + USHORT usCurrentDpm6; + USHORT usPowerDpm7; + USHORT usCurrentDpm7; +}ATOM_ASIC_PROFILING_INFO_V3_1; + + typedef struct _ATOM_POWER_SOURCE_OBJECT { UCHAR ucPwrSrcId; // Power source @@ -5808,6 +5907,8 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S7_DOS_MODE_PIXEL_DEPTHb0 0x0C #define ATOM_S7_DOS_MODE_PIXEL_FORMATb0 0xF0 #define ATOM_S7_DOS_8BIT_DAC_ENb1 0x01 +#define ATOM_S7_ASIC_INIT_COMPLETEb1 0x02 +#define ATOM_S7_ASIC_INIT_COMPLETE_MASK 0x00000200 #define ATOM_S7_DOS_MODE_NUMBERw1 0x0FFFF #define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT 8 @@ -6242,6 +6343,7 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE #define _128Mx32 0x53 #define _256Mx8 0x61 #define _256Mx16 0x62 +#define _512Mx8 0x71 #define SAMSUNG 0x1 #define INFINEON 0x2 @@ -6987,9 +7089,10 @@ typedef struct _ATOM_DISP_OUT_INFO_V3 UCHAR ucMaxDispEngineNum; UCHAR ucMaxActiveDispEngineNum; UCHAR ucMaxPPLLNum; - UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE - UCHAR ucReserved[3]; - ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only + UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE + UCHAR ucDispCaps; + UCHAR ucReserved[2]; + ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only }ATOM_DISP_OUT_INFO_V3; //ucDispCaps From 7eeeabfcce9249b21eff1cf5f7ec3621de5d14e4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 19 Aug 2013 10:22:26 -0400 Subject: [PATCH 17/23] drm/radeon: modesetting updates for hawaii Uses the same code as bonaire. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_crtc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 4ad1562673814..80a20120e6253 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1955,7 +1955,9 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) break; case ATOM_PPLL0: /* disable the ppll */ - if ((rdev->family == CHIP_ARUBA) || (rdev->family == CHIP_BONAIRE)) + if ((rdev->family == CHIP_ARUBA) || + (rdev->family == CHIP_BONAIRE) || + (rdev->family == CHIP_HAWAII)) atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); break; From 41971b37d19d3f44620dd54671e1084d0dccfe37 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 19 Aug 2013 18:02:26 -0400 Subject: [PATCH 18/23] drm/radeon: fill in radeon_asic_init for hawaii Fill in gpu details for hawaii. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_asic.c | 57 +++++++++++++++++++--------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index d4b91675671d1..50853c0cb49d2 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2437,27 +2437,48 @@ int radeon_asic_init(struct radeon_device *rdev) } break; case CHIP_BONAIRE: + case CHIP_HAWAII: rdev->asic = &ci_asic; rdev->num_crtc = 6; rdev->has_uvd = true; - rdev->cg_flags = - RADEON_CG_SUPPORT_GFX_MGCG | - RADEON_CG_SUPPORT_GFX_MGLS | - /*RADEON_CG_SUPPORT_GFX_CGCG |*/ - RADEON_CG_SUPPORT_GFX_CGLS | - RADEON_CG_SUPPORT_GFX_CGTS | - RADEON_CG_SUPPORT_GFX_CGTS_LS | - RADEON_CG_SUPPORT_GFX_CP_LS | - RADEON_CG_SUPPORT_MC_LS | - RADEON_CG_SUPPORT_MC_MGCG | - RADEON_CG_SUPPORT_SDMA_MGCG | - RADEON_CG_SUPPORT_SDMA_LS | - RADEON_CG_SUPPORT_BIF_LS | - RADEON_CG_SUPPORT_VCE_MGCG | - RADEON_CG_SUPPORT_UVD_MGCG | - RADEON_CG_SUPPORT_HDP_LS | - RADEON_CG_SUPPORT_HDP_MGCG; - rdev->pg_flags = 0; + if (rdev->family == CHIP_BONAIRE) { + rdev->cg_flags = + RADEON_CG_SUPPORT_GFX_MGCG | + RADEON_CG_SUPPORT_GFX_MGLS | + /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGLS | + RADEON_CG_SUPPORT_GFX_CGTS | + RADEON_CG_SUPPORT_GFX_CGTS_LS | + RADEON_CG_SUPPORT_GFX_CP_LS | + RADEON_CG_SUPPORT_MC_LS | + RADEON_CG_SUPPORT_MC_MGCG | + RADEON_CG_SUPPORT_SDMA_MGCG | + RADEON_CG_SUPPORT_SDMA_LS | + RADEON_CG_SUPPORT_BIF_LS | + RADEON_CG_SUPPORT_VCE_MGCG | + RADEON_CG_SUPPORT_UVD_MGCG | + RADEON_CG_SUPPORT_HDP_LS | + RADEON_CG_SUPPORT_HDP_MGCG; + rdev->pg_flags = 0; + } else { + rdev->cg_flags = + RADEON_CG_SUPPORT_GFX_MGCG | + RADEON_CG_SUPPORT_GFX_MGLS | + /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGLS | + RADEON_CG_SUPPORT_GFX_CGTS | + RADEON_CG_SUPPORT_GFX_CP_LS | + RADEON_CG_SUPPORT_MC_LS | + RADEON_CG_SUPPORT_MC_MGCG | + RADEON_CG_SUPPORT_SDMA_MGCG | + RADEON_CG_SUPPORT_SDMA_LS | + RADEON_CG_SUPPORT_BIF_LS | + RADEON_CG_SUPPORT_VCE_MGCG | + RADEON_CG_SUPPORT_UVD_MGCG | + RADEON_CG_SUPPORT_HDP_LS | + RADEON_CG_SUPPORT_HDP_MGCG; + rdev->pg_flags = 0; + } break; case CHIP_KAVERI: case CHIP_KABINI: From 96212fe8c27b39cc713cd8eb8d8e7a55ce3405d5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 9 Aug 2013 17:28:54 -0400 Subject: [PATCH 19/23] drm/radeon: add pci ids for hawaii This adds the pci ids for hawaii. Signed-off-by: Alex Deucher --- include/drm/drm_pciids.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 3d79e513c0b36..87578c109e486 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -261,6 +261,18 @@ {0x1002, 0x679B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ {0x1002, 0x679F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67A8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67A9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67AA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67B0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67B1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67B8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67B9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67BA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x67BE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAWAII|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ From e31fadd372e9e0d00f25b000c41fa63531ca488e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 8 Nov 2013 13:03:47 -0500 Subject: [PATCH 20/23] drm/radeon: fix mismerge of drm-next with 3.12 Audio is enabled by default now. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_connectors.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index f60b310b13995..20a768ac89a8e 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1728,9 +1728,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (radeon_audio != 0) drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = true; @@ -1828,9 +1826,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); } if (ASIC_IS_AVIVO(rdev)) { drm_object_attach_property(&radeon_connector->base.base, @@ -1880,9 +1876,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); } if (ASIC_IS_AVIVO(rdev)) { drm_object_attach_property(&radeon_connector->base.base, @@ -1931,9 +1925,7 @@ radeon_add_atom_connector(struct drm_device *dev, if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) { drm_object_attach_property(&radeon_connector->base.base, rdev->mode_info.audio_property, - (radeon_audio == 1) ? - RADEON_AUDIO_AUTO : - RADEON_AUDIO_DISABLE); + RADEON_AUDIO_AUTO); } if (ASIC_IS_AVIVO(rdev)) { drm_object_attach_property(&radeon_connector->base.base, From 3e71985f2439d8c4090dc2820e497e6f3d72dcff Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 6 Nov 2013 20:00:32 +0100 Subject: [PATCH 21/23] drm/radeon/audio: correct ACR table The values were taken from the HDMI spec, but they assumed exact x/1.001 clocks. Since we round the clocks, we also need to calculate different N and CTS values. Note that the N for 25.2/1.001 MHz at 44.1 kHz audio is out of spec. Hopefully this mode is rarely used and/or HDMI sinks tolerate overly large values of N. bug: https://bugs.freedesktop.org/show_bug.cgi?id=69675 Signed-off-by: Pierre Ossman Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r600_hdmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index ace4dec21bc2b..b83962d7915b5 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -57,15 +57,15 @@ enum r600_hdmi_iec_status_bits { 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 */ }; From a2098250fbda149cfad9e626afe80abe3b21e574 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 6 Nov 2013 20:09:08 +0100 Subject: [PATCH 22/23] drm/radeon/audio: improve ACR calculation In order to have any realistic chance of calculating proper ACR values, we need to be able to calculate both N and CTS, not just CTS. We still aim for the ideal N as specified in the HDMI spec though. bug: https://bugs.freedesktop.org/show_bug.cgi?id=69675 Signed-off-by: Pierre Ossman Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r600_hdmi.c | 68 ++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index b83962d7915b5..4b89262f3f0e3 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -24,6 +24,7 @@ * Authors: Christian König */ #include +#include #include #include #include "radeon.h" @@ -67,25 +68,47 @@ static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 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; - - 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); + int n, cts; + unsigned long div, mul; + + /* 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 r600_hdmi_acr(uint32_t clock) 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]; + /* 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]; + } - /* 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); + /* 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; } From 28ed756f1f4cf778785e6b627cabdcf337070fd6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 8 Nov 2013 13:07:51 -0500 Subject: [PATCH 23/23] Revert "drm/radeon/audio: don't set speaker allocation on DCE4+" This reverts commit 555b1b651acf44bf27ebbb04235d38a8fd2d58dc. Let's try this again for 3.13. It's required for proper interaction with alsa. Was disabled previously in 3.12 to be on the safe side since it caused problems on older asics. --- drivers/gpu/drm/radeon/dce6_afmt.c | 3 --- drivers/gpu/drm/radeon/evergreen_hdmi.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 85c4993b53e15..009f46e0ce72d 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -156,9 +156,6 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) u8 *sadb; int sad_count; - /* XXX: setting this register causes hangs on some asics */ - return; - if (!dig->afmt->pin) return; diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index adbfef8705010..aa695c4feb3d0 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -105,9 +105,6 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) u8 *sadb; int sad_count; - /* XXX: setting this register causes hangs on some asics */ - return; - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { if (connector->encoder == encoder) { radeon_connector = to_radeon_connector(connector);