diff options
author | Dave Airlie <airlied@redhat.com> | 2013-11-05 01:22:08 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-11-05 01:22:08 -0500 |
commit | bbf1f8bfef7fbe1ea5634d7559770b805510ad8d (patch) | |
tree | f3c8ee9642cec7d1508c422292f8bdf0aa37a7f4 /drivers | |
parent | 90c37067b70d6090a316227698a0cba40f8003bd (diff) | |
parent | 70471860ff9f335c60c004d42ebd48945bfa5403 (diff) |
Merge branch 'drm-next-3.13' of git://people.freedesktop.org/~agd5f/linux into drm-next
Initial pull request for radeon drm-next 3.13. Highlights:
- Enable DPM on a number of asics by default
- Enable audio by default
- Dynamically power down dGPUs on PowerXpress systems
- Lots of bug fixes
* 'drm-next-3.13' of git://people.freedesktop.org/~agd5f/linux: (36 commits)
drm/radeon: don't share PPLLs on DCE4.1
drm/radeon/dpm: fix typo in setting smc flag
drm/radeon: fixup locking inversion between, mmap_sem and reservations
drm/radeon: clear the page directory using the DMA
drm/radeon: initially clear page tables
drm/radeon: drop CP page table updates & cleanup v2
drm/radeon: add vm_set_page tracepoint
drm/radeon: rework and fix reset detection v2
drm/radeon: don't use PACKET2 on CIK
drm/radeon: fix UVD destroy IB size
drm/radeon: activate UVD clocks before sending the destroy msg
drm/radeon/si: fix define for MC_SEQ_TRAIN_WAKEUP_CNTL
drm/radeon: fix endian handling in rlc buffer setup
drm/radeon/dpm: retain user selected performance level across state changes
drm/radeon: disable force performance state when thermal state is active
drm/radeon: enable DPM by default on r7xx asics
drm/radeon: enable DPM by default on evergreen asics
drm/radeon: enable DPM by default on BTC asics
drm/radeon: enable DPM by default on SI asics
drm/radeon: enable DPM by default on SUMO/PALM APUs
...
Diffstat (limited to 'drivers')
40 files changed, 1561 insertions, 881 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index bf87f6d435f8..86d9ee08b13f 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1753,7 +1753,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1753 | if (pll != ATOM_PPLL_INVALID) | 1753 | if (pll != ATOM_PPLL_INVALID) |
1754 | return pll; | 1754 | return pll; |
1755 | } | 1755 | } |
1756 | } else { | 1756 | } else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */ |
1757 | /* use the same PPLL for all monitors with the same clock */ | 1757 | /* use the same PPLL for all monitors with the same clock */ |
1758 | pll = radeon_get_shared_nondp_ppll(crtc); | 1758 | pll = radeon_get_shared_nondp_ppll(crtc); |
1759 | if (pll != ATOM_PPLL_INVALID) | 1759 | if (pll != ATOM_PPLL_INVALID) |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 28e2dc48e015..eb3ba60a2e92 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -1644,19 +1644,11 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1644 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | 1644 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); |
1645 | /* enable the transmitter */ | 1645 | /* enable the transmitter */ |
1646 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1646 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1647 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1648 | } else { | 1647 | } else { |
1649 | /* setup and enable the encoder and transmitter */ | 1648 | /* setup and enable the encoder and transmitter */ |
1650 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | 1649 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); |
1651 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | 1650 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
1652 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1651 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1653 | /* some dce3.x boards have a bug in their transmitter control table. | ||
1654 | * ACTION_ENABLE_OUTPUT can probably be dropped since ACTION_ENABLE | ||
1655 | * does the same thing and more. | ||
1656 | */ | ||
1657 | if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) && | ||
1658 | (rdev->family != CHIP_RS880)) | ||
1659 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1660 | } | 1652 | } |
1661 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1653 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
1662 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1654 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
@@ -1674,16 +1666,11 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1674 | case DRM_MODE_DPMS_STANDBY: | 1666 | case DRM_MODE_DPMS_STANDBY: |
1675 | case DRM_MODE_DPMS_SUSPEND: | 1667 | case DRM_MODE_DPMS_SUSPEND: |
1676 | case DRM_MODE_DPMS_OFF: | 1668 | case DRM_MODE_DPMS_OFF: |
1677 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1669 | if (ASIC_IS_DCE4(rdev)) { |
1678 | /* disable the transmitter */ | ||
1679 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1680 | } else if (ASIC_IS_DCE4(rdev)) { | ||
1681 | /* disable the transmitter */ | 1670 | /* disable the transmitter */ |
1682 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1683 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1671 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1684 | } else { | 1672 | } else { |
1685 | /* disable the encoder and transmitter */ | 1673 | /* disable the encoder and transmitter */ |
1686 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1687 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1674 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1688 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | 1675 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); |
1689 | } | 1676 | } |
@@ -2392,6 +2379,15 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
2392 | 2379 | ||
2393 | /* this is needed for the pll/ss setup to work correctly in some cases */ | 2380 | /* this is needed for the pll/ss setup to work correctly in some cases */ |
2394 | atombios_set_encoder_crtc_source(encoder); | 2381 | atombios_set_encoder_crtc_source(encoder); |
2382 | /* set up the FMT blocks */ | ||
2383 | if (ASIC_IS_DCE8(rdev)) | ||
2384 | dce8_program_fmt(encoder); | ||
2385 | else if (ASIC_IS_DCE4(rdev)) | ||
2386 | dce4_program_fmt(encoder); | ||
2387 | else if (ASIC_IS_DCE3(rdev)) | ||
2388 | dce3_program_fmt(encoder); | ||
2389 | else if (ASIC_IS_AVIVO(rdev)) | ||
2390 | avivo_program_fmt(encoder); | ||
2395 | } | 2391 | } |
2396 | 2392 | ||
2397 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 2393 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index d02fd1c045d5..2e48f902e3b5 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -67,11 +67,6 @@ extern void si_init_uvd_internal_cg(struct radeon_device *rdev); | |||
67 | extern int cik_sdma_resume(struct radeon_device *rdev); | 67 | extern int cik_sdma_resume(struct radeon_device *rdev); |
68 | extern void cik_sdma_enable(struct radeon_device *rdev, bool enable); | 68 | extern void cik_sdma_enable(struct radeon_device *rdev, bool enable); |
69 | extern void cik_sdma_fini(struct radeon_device *rdev); | 69 | extern void cik_sdma_fini(struct radeon_device *rdev); |
70 | extern void cik_sdma_vm_set_page(struct radeon_device *rdev, | ||
71 | struct radeon_ib *ib, | ||
72 | uint64_t pe, | ||
73 | uint64_t addr, unsigned count, | ||
74 | uint32_t incr, uint32_t flags); | ||
75 | static void cik_rlc_stop(struct radeon_device *rdev); | 70 | static void cik_rlc_stop(struct radeon_device *rdev); |
76 | static void cik_pcie_gen3_enable(struct radeon_device *rdev); | 71 | static void cik_pcie_gen3_enable(struct radeon_device *rdev); |
77 | static void cik_program_aspm(struct radeon_device *rdev); | 72 | static void cik_program_aspm(struct radeon_device *rdev); |
@@ -3094,6 +3089,85 @@ void cik_semaphore_ring_emit(struct radeon_device *rdev, | |||
3094 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); | 3089 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); |
3095 | } | 3090 | } |
3096 | 3091 | ||
3092 | /** | ||
3093 | * cik_copy_cpdma - copy pages using the CP DMA engine | ||
3094 | * | ||
3095 | * @rdev: radeon_device pointer | ||
3096 | * @src_offset: src GPU address | ||
3097 | * @dst_offset: dst GPU address | ||
3098 | * @num_gpu_pages: number of GPU pages to xfer | ||
3099 | * @fence: radeon fence object | ||
3100 | * | ||
3101 | * Copy GPU paging using the CP DMA engine (CIK+). | ||
3102 | * Used by the radeon ttm implementation to move pages if | ||
3103 | * registered as the asic copy callback. | ||
3104 | */ | ||
3105 | int cik_copy_cpdma(struct radeon_device *rdev, | ||
3106 | uint64_t src_offset, uint64_t dst_offset, | ||
3107 | unsigned num_gpu_pages, | ||
3108 | struct radeon_fence **fence) | ||
3109 | { | ||
3110 | struct radeon_semaphore *sem = NULL; | ||
3111 | int ring_index = rdev->asic->copy.blit_ring_index; | ||
3112 | struct radeon_ring *ring = &rdev->ring[ring_index]; | ||
3113 | u32 size_in_bytes, cur_size_in_bytes, control; | ||
3114 | int i, num_loops; | ||
3115 | int r = 0; | ||
3116 | |||
3117 | r = radeon_semaphore_create(rdev, &sem); | ||
3118 | if (r) { | ||
3119 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
3120 | return r; | ||
3121 | } | ||
3122 | |||
3123 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | ||
3124 | num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); | ||
3125 | r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18); | ||
3126 | if (r) { | ||
3127 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
3128 | radeon_semaphore_free(rdev, &sem, NULL); | ||
3129 | return r; | ||
3130 | } | ||
3131 | |||
3132 | if (radeon_fence_need_sync(*fence, ring->idx)) { | ||
3133 | radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, | ||
3134 | ring->idx); | ||
3135 | radeon_fence_note_sync(*fence, ring->idx); | ||
3136 | } else { | ||
3137 | radeon_semaphore_free(rdev, &sem, NULL); | ||
3138 | } | ||
3139 | |||
3140 | for (i = 0; i < num_loops; i++) { | ||
3141 | cur_size_in_bytes = size_in_bytes; | ||
3142 | if (cur_size_in_bytes > 0x1fffff) | ||
3143 | cur_size_in_bytes = 0x1fffff; | ||
3144 | size_in_bytes -= cur_size_in_bytes; | ||
3145 | control = 0; | ||
3146 | if (size_in_bytes == 0) | ||
3147 | control |= PACKET3_DMA_DATA_CP_SYNC; | ||
3148 | radeon_ring_write(ring, PACKET3(PACKET3_DMA_DATA, 5)); | ||
3149 | radeon_ring_write(ring, control); | ||
3150 | radeon_ring_write(ring, lower_32_bits(src_offset)); | ||
3151 | radeon_ring_write(ring, upper_32_bits(src_offset)); | ||
3152 | radeon_ring_write(ring, lower_32_bits(dst_offset)); | ||
3153 | radeon_ring_write(ring, upper_32_bits(dst_offset)); | ||
3154 | radeon_ring_write(ring, cur_size_in_bytes); | ||
3155 | src_offset += cur_size_in_bytes; | ||
3156 | dst_offset += cur_size_in_bytes; | ||
3157 | } | ||
3158 | |||
3159 | r = radeon_fence_emit(rdev, fence, ring->idx); | ||
3160 | if (r) { | ||
3161 | radeon_ring_unlock_undo(rdev, ring); | ||
3162 | return r; | ||
3163 | } | ||
3164 | |||
3165 | radeon_ring_unlock_commit(rdev, ring); | ||
3166 | radeon_semaphore_free(rdev, &sem, *fence); | ||
3167 | |||
3168 | return r; | ||
3169 | } | ||
3170 | |||
3097 | /* | 3171 | /* |
3098 | * IB stuff | 3172 | * IB stuff |
3099 | */ | 3173 | */ |
@@ -4824,62 +4898,6 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
4824 | } | 4898 | } |
4825 | } | 4899 | } |
4826 | 4900 | ||
4827 | /** | ||
4828 | * cik_vm_set_page - update the page tables using sDMA | ||
4829 | * | ||
4830 | * @rdev: radeon_device pointer | ||
4831 | * @ib: indirect buffer to fill with commands | ||
4832 | * @pe: addr of the page entry | ||
4833 | * @addr: dst addr to write into pe | ||
4834 | * @count: number of page entries to update | ||
4835 | * @incr: increase next addr by incr bytes | ||
4836 | * @flags: access flags | ||
4837 | * | ||
4838 | * Update the page tables using CP or sDMA (CIK). | ||
4839 | */ | ||
4840 | void cik_vm_set_page(struct radeon_device *rdev, | ||
4841 | struct radeon_ib *ib, | ||
4842 | uint64_t pe, | ||
4843 | uint64_t addr, unsigned count, | ||
4844 | uint32_t incr, uint32_t flags) | ||
4845 | { | ||
4846 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | ||
4847 | uint64_t value; | ||
4848 | unsigned ndw; | ||
4849 | |||
4850 | if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { | ||
4851 | /* CP */ | ||
4852 | while (count) { | ||
4853 | ndw = 2 + count * 2; | ||
4854 | if (ndw > 0x3FFE) | ||
4855 | ndw = 0x3FFE; | ||
4856 | |||
4857 | ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw); | ||
4858 | ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) | | ||
4859 | WRITE_DATA_DST_SEL(1)); | ||
4860 | ib->ptr[ib->length_dw++] = pe; | ||
4861 | ib->ptr[ib->length_dw++] = upper_32_bits(pe); | ||
4862 | for (; ndw > 2; ndw -= 2, --count, pe += 8) { | ||
4863 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
4864 | value = radeon_vm_map_gart(rdev, addr); | ||
4865 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
4866 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
4867 | value = addr; | ||
4868 | } else { | ||
4869 | value = 0; | ||
4870 | } | ||
4871 | addr += incr; | ||
4872 | value |= r600_flags; | ||
4873 | ib->ptr[ib->length_dw++] = value; | ||
4874 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | ||
4875 | } | ||
4876 | } | ||
4877 | } else { | ||
4878 | /* DMA */ | ||
4879 | cik_sdma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); | ||
4880 | } | ||
4881 | } | ||
4882 | |||
4883 | /* | 4901 | /* |
4884 | * RLC | 4902 | * RLC |
4885 | * The RLC is a multi-purpose microengine that handles a | 4903 | * The RLC is a multi-purpose microengine that handles a |
@@ -5546,7 +5564,7 @@ void cik_init_cp_pg_table(struct radeon_device *rdev) | |||
5546 | } | 5564 | } |
5547 | 5565 | ||
5548 | for (i = 0; i < CP_ME_TABLE_SIZE; i ++) { | 5566 | for (i = 0; i < CP_ME_TABLE_SIZE; i ++) { |
5549 | dst_ptr[bo_offset + i] = be32_to_cpu(fw_data[table_offset + i]); | 5567 | dst_ptr[bo_offset + i] = cpu_to_le32(be32_to_cpu(fw_data[table_offset + i])); |
5550 | } | 5568 | } |
5551 | bo_offset += CP_ME_TABLE_SIZE; | 5569 | bo_offset += CP_ME_TABLE_SIZE; |
5552 | } | 5570 | } |
@@ -5768,52 +5786,53 @@ void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) | |||
5768 | if (buffer == NULL) | 5786 | if (buffer == NULL) |
5769 | return; | 5787 | return; |
5770 | 5788 | ||
5771 | buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); | 5789 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); |
5772 | buffer[count++] = PACKET3_PREAMBLE_BEGIN_CLEAR_STATE; | 5790 | buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); |
5773 | 5791 | ||
5774 | buffer[count++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1); | 5792 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); |
5775 | buffer[count++] = 0x80000000; | 5793 | buffer[count++] = cpu_to_le32(0x80000000); |
5776 | buffer[count++] = 0x80000000; | 5794 | buffer[count++] = cpu_to_le32(0x80000000); |
5777 | 5795 | ||
5778 | for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { | 5796 | for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { |
5779 | for (ext = sect->section; ext->extent != NULL; ++ext) { | 5797 | for (ext = sect->section; ext->extent != NULL; ++ext) { |
5780 | if (sect->id == SECT_CONTEXT) { | 5798 | if (sect->id == SECT_CONTEXT) { |
5781 | buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count); | 5799 | buffer[count++] = |
5782 | buffer[count++] = ext->reg_index - 0xa000; | 5800 | cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); |
5801 | buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000); | ||
5783 | for (i = 0; i < ext->reg_count; i++) | 5802 | for (i = 0; i < ext->reg_count; i++) |
5784 | buffer[count++] = ext->extent[i]; | 5803 | buffer[count++] = cpu_to_le32(ext->extent[i]); |
5785 | } else { | 5804 | } else { |
5786 | return; | 5805 | return; |
5787 | } | 5806 | } |
5788 | } | 5807 | } |
5789 | } | 5808 | } |
5790 | 5809 | ||
5791 | buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); | 5810 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 2)); |
5792 | buffer[count++] = PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START; | 5811 | buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); |
5793 | switch (rdev->family) { | 5812 | switch (rdev->family) { |
5794 | case CHIP_BONAIRE: | 5813 | case CHIP_BONAIRE: |
5795 | buffer[count++] = 0x16000012; | 5814 | buffer[count++] = cpu_to_le32(0x16000012); |
5796 | buffer[count++] = 0x00000000; | 5815 | buffer[count++] = cpu_to_le32(0x00000000); |
5797 | break; | 5816 | break; |
5798 | case CHIP_KAVERI: | 5817 | case CHIP_KAVERI: |
5799 | buffer[count++] = 0x00000000; /* XXX */ | 5818 | buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ |
5800 | buffer[count++] = 0x00000000; | 5819 | buffer[count++] = cpu_to_le32(0x00000000); |
5801 | break; | 5820 | break; |
5802 | case CHIP_KABINI: | 5821 | case CHIP_KABINI: |
5803 | buffer[count++] = 0x00000000; /* XXX */ | 5822 | buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ |
5804 | buffer[count++] = 0x00000000; | 5823 | buffer[count++] = cpu_to_le32(0x00000000); |
5805 | break; | 5824 | break; |
5806 | default: | 5825 | default: |
5807 | buffer[count++] = 0x00000000; | 5826 | buffer[count++] = cpu_to_le32(0x00000000); |
5808 | buffer[count++] = 0x00000000; | 5827 | buffer[count++] = cpu_to_le32(0x00000000); |
5809 | break; | 5828 | break; |
5810 | } | 5829 | } |
5811 | 5830 | ||
5812 | buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); | 5831 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); |
5813 | buffer[count++] = PACKET3_PREAMBLE_END_CLEAR_STATE; | 5832 | buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); |
5814 | 5833 | ||
5815 | buffer[count++] = PACKET3(PACKET3_CLEAR_STATE, 0); | 5834 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); |
5816 | buffer[count++] = 0; | 5835 | buffer[count++] = cpu_to_le32(0); |
5817 | } | 5836 | } |
5818 | 5837 | ||
5819 | static void cik_init_pg(struct radeon_device *rdev) | 5838 | static void cik_init_pg(struct radeon_device *rdev) |
@@ -7108,7 +7127,7 @@ static int cik_startup(struct radeon_device *rdev) | |||
7108 | ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 7127 | ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
7109 | r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, | 7128 | r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, |
7110 | CP_RB0_RPTR, CP_RB0_WPTR, | 7129 | CP_RB0_RPTR, CP_RB0_WPTR, |
7111 | RADEON_CP_PACKET2); | 7130 | PACKET3(PACKET3_NOP, 0x3FFF)); |
7112 | if (r) | 7131 | if (r) |
7113 | return r; | 7132 | return r; |
7114 | 7133 | ||
@@ -7418,6 +7437,70 @@ void cik_fini(struct radeon_device *rdev) | |||
7418 | rdev->bios = NULL; | 7437 | rdev->bios = NULL; |
7419 | } | 7438 | } |
7420 | 7439 | ||
7440 | void dce8_program_fmt(struct drm_encoder *encoder) | ||
7441 | { | ||
7442 | struct drm_device *dev = encoder->dev; | ||
7443 | struct radeon_device *rdev = dev->dev_private; | ||
7444 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
7445 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
7446 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
7447 | int bpc = 0; | ||
7448 | u32 tmp = 0; | ||
7449 | enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE; | ||
7450 | |||
7451 | if (connector) { | ||
7452 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
7453 | bpc = radeon_get_monitor_bpc(connector); | ||
7454 | dither = radeon_connector->dither; | ||
7455 | } | ||
7456 | |||
7457 | /* LVDS/eDP FMT is set up by atom */ | ||
7458 | if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) | ||
7459 | return; | ||
7460 | |||
7461 | /* not needed for analog */ | ||
7462 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) || | ||
7463 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2)) | ||
7464 | return; | ||
7465 | |||
7466 | if (bpc == 0) | ||
7467 | return; | ||
7468 | |||
7469 | switch (bpc) { | ||
7470 | case 6: | ||
7471 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
7472 | /* XXX sort out optimal dither settings */ | ||
7473 | tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | | ||
7474 | FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(0)); | ||
7475 | else | ||
7476 | tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(0)); | ||
7477 | break; | ||
7478 | case 8: | ||
7479 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
7480 | /* XXX sort out optimal dither settings */ | ||
7481 | tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | | ||
7482 | FMT_RGB_RANDOM_ENABLE | | ||
7483 | FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(1)); | ||
7484 | else | ||
7485 | tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(1)); | ||
7486 | break; | ||
7487 | case 10: | ||
7488 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
7489 | /* XXX sort out optimal dither settings */ | ||
7490 | tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | | ||
7491 | FMT_RGB_RANDOM_ENABLE | | ||
7492 | FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(2)); | ||
7493 | else | ||
7494 | tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(2)); | ||
7495 | break; | ||
7496 | default: | ||
7497 | /* not needed */ | ||
7498 | break; | ||
7499 | } | ||
7500 | |||
7501 | WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp); | ||
7502 | } | ||
7503 | |||
7421 | /* display watermark setup */ | 7504 | /* display watermark setup */ |
7422 | /** | 7505 | /** |
7423 | * dce8_line_buffer_adjust - Set up the line buffer | 7506 | * dce8_line_buffer_adjust - Set up the line buffer |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index b6286068e111..8d84ebe2b6fa 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | 27 | #include "radeon_asic.h" |
28 | #include "radeon_trace.h" | ||
28 | #include "cikd.h" | 29 | #include "cikd.h" |
29 | 30 | ||
30 | /* sdma */ | 31 | /* sdma */ |
@@ -653,11 +654,12 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, | |||
653 | uint64_t addr, unsigned count, | 654 | uint64_t addr, unsigned count, |
654 | uint32_t incr, uint32_t flags) | 655 | uint32_t incr, uint32_t flags) |
655 | { | 656 | { |
656 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | ||
657 | uint64_t value; | 657 | uint64_t value; |
658 | unsigned ndw; | 658 | unsigned ndw; |
659 | 659 | ||
660 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 660 | trace_radeon_vm_set_page(pe, addr, count, incr, flags); |
661 | |||
662 | if (flags & R600_PTE_SYSTEM) { | ||
661 | while (count) { | 663 | while (count) { |
662 | ndw = count * 2; | 664 | ndw = count * 2; |
663 | if (ndw > 0xFFFFE) | 665 | if (ndw > 0xFFFFE) |
@@ -669,16 +671,10 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, | |||
669 | ib->ptr[ib->length_dw++] = upper_32_bits(pe); | 671 | ib->ptr[ib->length_dw++] = upper_32_bits(pe); |
670 | ib->ptr[ib->length_dw++] = ndw; | 672 | ib->ptr[ib->length_dw++] = ndw; |
671 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { | 673 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
672 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 674 | value = radeon_vm_map_gart(rdev, addr); |
673 | value = radeon_vm_map_gart(rdev, addr); | 675 | value &= 0xFFFFFFFFFFFFF000ULL; |
674 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
675 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
676 | value = addr; | ||
677 | } else { | ||
678 | value = 0; | ||
679 | } | ||
680 | addr += incr; | 676 | addr += incr; |
681 | value |= r600_flags; | 677 | value |= flags; |
682 | ib->ptr[ib->length_dw++] = value; | 678 | ib->ptr[ib->length_dw++] = value; |
683 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | 679 | ib->ptr[ib->length_dw++] = upper_32_bits(value); |
684 | } | 680 | } |
@@ -689,7 +685,7 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, | |||
689 | if (ndw > 0x7FFFF) | 685 | if (ndw > 0x7FFFF) |
690 | ndw = 0x7FFFF; | 686 | ndw = 0x7FFFF; |
691 | 687 | ||
692 | if (flags & RADEON_VM_PAGE_VALID) | 688 | if (flags & R600_PTE_VALID) |
693 | value = addr; | 689 | value = addr; |
694 | else | 690 | else |
695 | value = 0; | 691 | value = 0; |
@@ -697,7 +693,7 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, | |||
697 | ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0); | 693 | ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0); |
698 | ib->ptr[ib->length_dw++] = pe; /* dst addr */ | 694 | ib->ptr[ib->length_dw++] = pe; /* dst addr */ |
699 | ib->ptr[ib->length_dw++] = upper_32_bits(pe); | 695 | ib->ptr[ib->length_dw++] = upper_32_bits(pe); |
700 | ib->ptr[ib->length_dw++] = r600_flags; /* mask */ | 696 | ib->ptr[ib->length_dw++] = flags; /* mask */ |
701 | ib->ptr[ib->length_dw++] = 0; | 697 | ib->ptr[ib->length_dw++] = 0; |
702 | ib->ptr[ib->length_dw++] = value; /* value */ | 698 | ib->ptr[ib->length_dw++] = value; /* value */ |
703 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | 699 | ib->ptr[ib->length_dw++] = upper_32_bits(value); |
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 203d2a09a1f5..380cea311a2b 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h | |||
@@ -906,6 +906,39 @@ | |||
906 | #define DPG_PIPE_STUTTER_CONTROL 0x6cd4 | 906 | #define DPG_PIPE_STUTTER_CONTROL 0x6cd4 |
907 | # define STUTTER_ENABLE (1 << 0) | 907 | # define STUTTER_ENABLE (1 << 0) |
908 | 908 | ||
909 | /* DCE8 FMT blocks */ | ||
910 | #define FMT_DYNAMIC_EXP_CNTL 0x6fb4 | ||
911 | # define FMT_DYNAMIC_EXP_EN (1 << 0) | ||
912 | # define FMT_DYNAMIC_EXP_MODE (1 << 4) | ||
913 | /* 0 = 10bit -> 12bit, 1 = 8bit -> 12bit */ | ||
914 | #define FMT_CONTROL 0x6fb8 | ||
915 | # define FMT_PIXEL_ENCODING (1 << 16) | ||
916 | /* 0 = RGB 4:4:4 or YCbCr 4:4:4, 1 = YCbCr 4:2:2 */ | ||
917 | #define FMT_BIT_DEPTH_CONTROL 0x6fc8 | ||
918 | # define FMT_TRUNCATE_EN (1 << 0) | ||
919 | # define FMT_TRUNCATE_MODE (1 << 1) | ||
920 | # define FMT_TRUNCATE_DEPTH(x) ((x) << 4) /* 0 - 18bpp, 1 - 24bpp, 2 - 30bpp */ | ||
921 | # define FMT_SPATIAL_DITHER_EN (1 << 8) | ||
922 | # define FMT_SPATIAL_DITHER_MODE(x) ((x) << 9) | ||
923 | # define FMT_SPATIAL_DITHER_DEPTH(x) ((x) << 11) /* 0 - 18bpp, 1 - 24bpp, 2 - 30bpp */ | ||
924 | # define FMT_FRAME_RANDOM_ENABLE (1 << 13) | ||
925 | # define FMT_RGB_RANDOM_ENABLE (1 << 14) | ||
926 | # define FMT_HIGHPASS_RANDOM_ENABLE (1 << 15) | ||
927 | # define FMT_TEMPORAL_DITHER_EN (1 << 16) | ||
928 | # define FMT_TEMPORAL_DITHER_DEPTH(x) ((x) << 17) /* 0 - 18bpp, 1 - 24bpp, 2 - 30bpp */ | ||
929 | # define FMT_TEMPORAL_DITHER_OFFSET(x) ((x) << 21) | ||
930 | # define FMT_TEMPORAL_LEVEL (1 << 24) | ||
931 | # define FMT_TEMPORAL_DITHER_RESET (1 << 25) | ||
932 | # define FMT_25FRC_SEL(x) ((x) << 26) | ||
933 | # define FMT_50FRC_SEL(x) ((x) << 28) | ||
934 | # define FMT_75FRC_SEL(x) ((x) << 30) | ||
935 | #define FMT_CLAMP_CONTROL 0x6fe4 | ||
936 | # define FMT_CLAMP_DATA_EN (1 << 0) | ||
937 | # define FMT_CLAMP_COLOR_FORMAT(x) ((x) << 16) | ||
938 | # define FMT_CLAMP_6BPC 0 | ||
939 | # define FMT_CLAMP_8BPC 1 | ||
940 | # define FMT_CLAMP_10BPC 2 | ||
941 | |||
909 | #define GRBM_CNTL 0x8000 | 942 | #define GRBM_CNTL 0x8000 |
910 | #define GRBM_READ_TIMEOUT(x) ((x) << 0) | 943 | #define GRBM_READ_TIMEOUT(x) ((x) << 0) |
911 | 944 | ||
@@ -1714,6 +1747,68 @@ | |||
1714 | # define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28) | 1747 | # define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28) |
1715 | # define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28) | 1748 | # define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28) |
1716 | #define PACKET3_DMA_DATA 0x50 | 1749 | #define PACKET3_DMA_DATA 0x50 |
1750 | /* 1. header | ||
1751 | * 2. CONTROL | ||
1752 | * 3. SRC_ADDR_LO or DATA [31:0] | ||
1753 | * 4. SRC_ADDR_HI [31:0] | ||
1754 | * 5. DST_ADDR_LO [31:0] | ||
1755 | * 6. DST_ADDR_HI [7:0] | ||
1756 | * 7. COMMAND [30:21] | BYTE_COUNT [20:0] | ||
1757 | */ | ||
1758 | /* CONTROL */ | ||
1759 | # define PACKET3_DMA_DATA_ENGINE(x) ((x) << 0) | ||
1760 | /* 0 - ME | ||
1761 | * 1 - PFP | ||
1762 | */ | ||
1763 | # define PACKET3_DMA_DATA_SRC_CACHE_POLICY(x) ((x) << 13) | ||
1764 | /* 0 - LRU | ||
1765 | * 1 - Stream | ||
1766 | * 2 - Bypass | ||
1767 | */ | ||
1768 | # define PACKET3_DMA_DATA_SRC_VOLATILE (1 << 15) | ||
1769 | # define PACKET3_DMA_DATA_DST_SEL(x) ((x) << 20) | ||
1770 | /* 0 - DST_ADDR using DAS | ||
1771 | * 1 - GDS | ||
1772 | * 3 - DST_ADDR using L2 | ||
1773 | */ | ||
1774 | # define PACKET3_DMA_DATA_DST_CACHE_POLICY(x) ((x) << 25) | ||
1775 | /* 0 - LRU | ||
1776 | * 1 - Stream | ||
1777 | * 2 - Bypass | ||
1778 | */ | ||
1779 | # define PACKET3_DMA_DATA_DST_VOLATILE (1 << 27) | ||
1780 | # define PACKET3_DMA_DATA_SRC_SEL(x) ((x) << 29) | ||
1781 | /* 0 - SRC_ADDR using SAS | ||
1782 | * 1 - GDS | ||
1783 | * 2 - DATA | ||
1784 | * 3 - SRC_ADDR using L2 | ||
1785 | */ | ||
1786 | # define PACKET3_DMA_DATA_CP_SYNC (1 << 31) | ||
1787 | /* COMMAND */ | ||
1788 | # define PACKET3_DMA_DATA_DIS_WC (1 << 21) | ||
1789 | # define PACKET3_DMA_DATA_CMD_SRC_SWAP(x) ((x) << 22) | ||
1790 | /* 0 - none | ||
1791 | * 1 - 8 in 16 | ||
1792 | * 2 - 8 in 32 | ||
1793 | * 3 - 8 in 64 | ||
1794 | */ | ||
1795 | # define PACKET3_DMA_DATA_CMD_DST_SWAP(x) ((x) << 24) | ||
1796 | /* 0 - none | ||
1797 | * 1 - 8 in 16 | ||
1798 | * 2 - 8 in 32 | ||
1799 | * 3 - 8 in 64 | ||
1800 | */ | ||
1801 | # define PACKET3_DMA_DATA_CMD_SAS (1 << 26) | ||
1802 | /* 0 - memory | ||
1803 | * 1 - register | ||
1804 | */ | ||
1805 | # define PACKET3_DMA_DATA_CMD_DAS (1 << 27) | ||
1806 | /* 0 - memory | ||
1807 | * 1 - register | ||
1808 | */ | ||
1809 | # define PACKET3_DMA_DATA_CMD_SAIC (1 << 28) | ||
1810 | # define PACKET3_DMA_DATA_CMD_DAIC (1 << 29) | ||
1811 | # define PACKET3_DMA_DATA_CMD_RAW_WAIT (1 << 30) | ||
1717 | #define PACKET3_AQUIRE_MEM 0x58 | 1812 | #define PACKET3_AQUIRE_MEM 0x58 |
1718 | #define PACKET3_REWIND 0x59 | 1813 | #define PACKET3_REWIND 0x59 |
1719 | #define PACKET3_LOAD_UCONFIG_REG 0x5E | 1814 | #define PACKET3_LOAD_UCONFIG_REG 0x5E |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 85a69d2ea3d2..5929056beca6 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -102,6 +102,49 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder) | |||
102 | AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id)); | 102 | AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id)); |
103 | } | 103 | } |
104 | 104 | ||
105 | void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | ||
106 | struct drm_display_mode *mode) | ||
107 | { | ||
108 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
109 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
110 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
111 | struct drm_connector *connector; | ||
112 | struct radeon_connector *radeon_connector = NULL; | ||
113 | u32 tmp = 0, offset; | ||
114 | |||
115 | if (!dig->afmt->pin) | ||
116 | return; | ||
117 | |||
118 | offset = dig->afmt->pin->offset; | ||
119 | |||
120 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
121 | if (connector->encoder == encoder) { | ||
122 | radeon_connector = to_radeon_connector(connector); | ||
123 | break; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | if (!radeon_connector) { | ||
128 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { | ||
133 | if (connector->latency_present[1]) | ||
134 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | | ||
135 | AUDIO_LIPSYNC(connector->audio_latency[1]); | ||
136 | else | ||
137 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); | ||
138 | } else { | ||
139 | if (connector->latency_present[0]) | ||
140 | tmp = VIDEO_LIPSYNC(connector->video_latency[0]) | | ||
141 | AUDIO_LIPSYNC(connector->audio_latency[0]); | ||
142 | else | ||
143 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); | ||
144 | } | ||
145 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); | ||
146 | } | ||
147 | |||
105 | void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | 148 | void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) |
106 | { | 149 | { |
107 | struct radeon_device *rdev = encoder->dev->dev_private; | 150 | struct radeon_device *rdev = encoder->dev->dev_private; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 555164e270a7..7a84d0cdeda7 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1193,6 +1193,62 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | |||
1193 | } | 1193 | } |
1194 | } | 1194 | } |
1195 | 1195 | ||
1196 | void dce4_program_fmt(struct drm_encoder *encoder) | ||
1197 | { | ||
1198 | struct drm_device *dev = encoder->dev; | ||
1199 | struct radeon_device *rdev = dev->dev_private; | ||
1200 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1201 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
1202 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1203 | int bpc = 0; | ||
1204 | u32 tmp = 0; | ||
1205 | enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE; | ||
1206 | |||
1207 | if (connector) { | ||
1208 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
1209 | bpc = radeon_get_monitor_bpc(connector); | ||
1210 | dither = radeon_connector->dither; | ||
1211 | } | ||
1212 | |||
1213 | /* LVDS/eDP FMT is set up by atom */ | ||
1214 | if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) | ||
1215 | return; | ||
1216 | |||
1217 | /* not needed for analog */ | ||
1218 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) || | ||
1219 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2)) | ||
1220 | return; | ||
1221 | |||
1222 | if (bpc == 0) | ||
1223 | return; | ||
1224 | |||
1225 | switch (bpc) { | ||
1226 | case 6: | ||
1227 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
1228 | /* XXX sort out optimal dither settings */ | ||
1229 | tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | | ||
1230 | FMT_SPATIAL_DITHER_EN); | ||
1231 | else | ||
1232 | tmp |= FMT_TRUNCATE_EN; | ||
1233 | break; | ||
1234 | case 8: | ||
1235 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
1236 | /* XXX sort out optimal dither settings */ | ||
1237 | tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | | ||
1238 | FMT_RGB_RANDOM_ENABLE | | ||
1239 | FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH); | ||
1240 | else | ||
1241 | tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH); | ||
1242 | break; | ||
1243 | case 10: | ||
1244 | default: | ||
1245 | /* not needed */ | ||
1246 | break; | ||
1247 | } | ||
1248 | |||
1249 | WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp); | ||
1250 | } | ||
1251 | |||
1196 | static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc) | 1252 | static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc) |
1197 | { | 1253 | { |
1198 | if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) | 1254 | if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) |
@@ -3963,7 +4019,7 @@ int sumo_rlc_init(struct radeon_device *rdev) | |||
3963 | if (rdev->family >= CHIP_TAHITI) { | 4019 | if (rdev->family >= CHIP_TAHITI) { |
3964 | /* SI */ | 4020 | /* SI */ |
3965 | for (i = 0; i < rdev->rlc.reg_list_size; i++) | 4021 | for (i = 0; i < rdev->rlc.reg_list_size; i++) |
3966 | dst_ptr[i] = src_ptr[i]; | 4022 | dst_ptr[i] = cpu_to_le32(src_ptr[i]); |
3967 | } else { | 4023 | } else { |
3968 | /* ON/LN/TN */ | 4024 | /* ON/LN/TN */ |
3969 | /* format: | 4025 | /* format: |
@@ -3977,10 +4033,10 @@ int sumo_rlc_init(struct radeon_device *rdev) | |||
3977 | if (i < dws) | 4033 | if (i < dws) |
3978 | data |= (src_ptr[i] >> 2) << 16; | 4034 | data |= (src_ptr[i] >> 2) << 16; |
3979 | j = (((i - 1) * 3) / 2); | 4035 | j = (((i - 1) * 3) / 2); |
3980 | dst_ptr[j] = data; | 4036 | dst_ptr[j] = cpu_to_le32(data); |
3981 | } | 4037 | } |
3982 | j = ((i * 3) / 2); | 4038 | j = ((i * 3) / 2); |
3983 | dst_ptr[j] = RLC_SAVE_RESTORE_LIST_END_MARKER; | 4039 | dst_ptr[j] = cpu_to_le32(RLC_SAVE_RESTORE_LIST_END_MARKER); |
3984 | } | 4040 | } |
3985 | radeon_bo_kunmap(rdev->rlc.save_restore_obj); | 4041 | radeon_bo_kunmap(rdev->rlc.save_restore_obj); |
3986 | radeon_bo_unreserve(rdev->rlc.save_restore_obj); | 4042 | radeon_bo_unreserve(rdev->rlc.save_restore_obj); |
@@ -4042,40 +4098,40 @@ int sumo_rlc_init(struct radeon_device *rdev) | |||
4042 | cik_get_csb_buffer(rdev, dst_ptr); | 4098 | cik_get_csb_buffer(rdev, dst_ptr); |
4043 | } else if (rdev->family >= CHIP_TAHITI) { | 4099 | } else if (rdev->family >= CHIP_TAHITI) { |
4044 | reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + 256; | 4100 | reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + 256; |
4045 | dst_ptr[0] = upper_32_bits(reg_list_mc_addr); | 4101 | dst_ptr[0] = cpu_to_le32(upper_32_bits(reg_list_mc_addr)); |
4046 | dst_ptr[1] = lower_32_bits(reg_list_mc_addr); | 4102 | dst_ptr[1] = cpu_to_le32(lower_32_bits(reg_list_mc_addr)); |
4047 | dst_ptr[2] = rdev->rlc.clear_state_size; | 4103 | dst_ptr[2] = cpu_to_le32(rdev->rlc.clear_state_size); |
4048 | si_get_csb_buffer(rdev, &dst_ptr[(256/4)]); | 4104 | si_get_csb_buffer(rdev, &dst_ptr[(256/4)]); |
4049 | } else { | 4105 | } else { |
4050 | reg_list_hdr_blk_index = 0; | 4106 | reg_list_hdr_blk_index = 0; |
4051 | reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4); | 4107 | reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4); |
4052 | data = upper_32_bits(reg_list_mc_addr); | 4108 | data = upper_32_bits(reg_list_mc_addr); |
4053 | dst_ptr[reg_list_hdr_blk_index] = data; | 4109 | dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); |
4054 | reg_list_hdr_blk_index++; | 4110 | reg_list_hdr_blk_index++; |
4055 | for (i = 0; cs_data[i].section != NULL; i++) { | 4111 | for (i = 0; cs_data[i].section != NULL; i++) { |
4056 | for (j = 0; cs_data[i].section[j].extent != NULL; j++) { | 4112 | for (j = 0; cs_data[i].section[j].extent != NULL; j++) { |
4057 | reg_num = cs_data[i].section[j].reg_count; | 4113 | reg_num = cs_data[i].section[j].reg_count; |
4058 | data = reg_list_mc_addr & 0xffffffff; | 4114 | data = reg_list_mc_addr & 0xffffffff; |
4059 | dst_ptr[reg_list_hdr_blk_index] = data; | 4115 | dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); |
4060 | reg_list_hdr_blk_index++; | 4116 | reg_list_hdr_blk_index++; |
4061 | 4117 | ||
4062 | data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff; | 4118 | data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff; |
4063 | dst_ptr[reg_list_hdr_blk_index] = data; | 4119 | dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); |
4064 | reg_list_hdr_blk_index++; | 4120 | reg_list_hdr_blk_index++; |
4065 | 4121 | ||
4066 | data = 0x08000000 | (reg_num * 4); | 4122 | data = 0x08000000 | (reg_num * 4); |
4067 | dst_ptr[reg_list_hdr_blk_index] = data; | 4123 | dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); |
4068 | reg_list_hdr_blk_index++; | 4124 | reg_list_hdr_blk_index++; |
4069 | 4125 | ||
4070 | for (k = 0; k < reg_num; k++) { | 4126 | for (k = 0; k < reg_num; k++) { |
4071 | data = cs_data[i].section[j].extent[k]; | 4127 | data = cs_data[i].section[j].extent[k]; |
4072 | dst_ptr[reg_list_blk_index + k] = data; | 4128 | dst_ptr[reg_list_blk_index + k] = cpu_to_le32(data); |
4073 | } | 4129 | } |
4074 | reg_list_mc_addr += reg_num * 4; | 4130 | reg_list_mc_addr += reg_num * 4; |
4075 | reg_list_blk_index += reg_num; | 4131 | reg_list_blk_index += reg_num; |
4076 | } | 4132 | } |
4077 | } | 4133 | } |
4078 | dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER; | 4134 | dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(RLC_CLEAR_STATE_END_MARKER); |
4079 | } | 4135 | } |
4080 | radeon_bo_kunmap(rdev->rlc.clear_state_obj); | 4136 | radeon_bo_kunmap(rdev->rlc.clear_state_obj); |
4081 | radeon_bo_unreserve(rdev->rlc.clear_state_obj); | 4137 | radeon_bo_unreserve(rdev->rlc.clear_state_obj); |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index f71ce390aebe..678736542ed8 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -35,6 +35,8 @@ | |||
35 | extern void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder); | 35 | extern void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder); |
36 | extern void dce6_afmt_write_sad_regs(struct drm_encoder *encoder); | 36 | extern void dce6_afmt_write_sad_regs(struct drm_encoder *encoder); |
37 | extern void dce6_afmt_select_pin(struct drm_encoder *encoder); | 37 | extern void dce6_afmt_select_pin(struct drm_encoder *encoder); |
38 | extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | ||
39 | struct drm_display_mode *mode); | ||
38 | 40 | ||
39 | /* | 41 | /* |
40 | * update the N and CTS parameters for a given pixel clock rate | 42 | * update the N and CTS parameters for a given pixel clock rate |
@@ -58,6 +60,42 @@ static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t cloc | |||
58 | WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); | 60 | WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); |
59 | } | 61 | } |
60 | 62 | ||
63 | static void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, | ||
64 | struct drm_display_mode *mode) | ||
65 | { | ||
66 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
67 | struct drm_connector *connector; | ||
68 | struct radeon_connector *radeon_connector = NULL; | ||
69 | u32 tmp = 0; | ||
70 | |||
71 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
72 | if (connector->encoder == encoder) { | ||
73 | radeon_connector = to_radeon_connector(connector); | ||
74 | break; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | if (!radeon_connector) { | ||
79 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
80 | return; | ||
81 | } | ||
82 | |||
83 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { | ||
84 | if (connector->latency_present[1]) | ||
85 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | | ||
86 | AUDIO_LIPSYNC(connector->audio_latency[1]); | ||
87 | else | ||
88 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); | ||
89 | } else { | ||
90 | if (connector->latency_present[0]) | ||
91 | tmp = VIDEO_LIPSYNC(connector->video_latency[0]) | | ||
92 | AUDIO_LIPSYNC(connector->audio_latency[0]); | ||
93 | else | ||
94 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); | ||
95 | } | ||
96 | WREG32(AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC, tmp); | ||
97 | } | ||
98 | |||
61 | static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | 99 | static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) |
62 | { | 100 | { |
63 | struct radeon_device *rdev = encoder->dev->dev_private; | 101 | struct radeon_device *rdev = encoder->dev->dev_private; |
@@ -68,8 +106,10 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
68 | int sad_count; | 106 | int sad_count; |
69 | 107 | ||
70 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 108 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
71 | if (connector->encoder == encoder) | 109 | if (connector->encoder == encoder) { |
72 | radeon_connector = to_radeon_connector(connector); | 110 | radeon_connector = to_radeon_connector(connector); |
111 | break; | ||
112 | } | ||
73 | } | 113 | } |
74 | 114 | ||
75 | if (!radeon_connector) { | 115 | if (!radeon_connector) { |
@@ -121,8 +161,10 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) | |||
121 | }; | 161 | }; |
122 | 162 | ||
123 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 163 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
124 | if (connector->encoder == encoder) | 164 | if (connector->encoder == encoder) { |
125 | radeon_connector = to_radeon_connector(connector); | 165 | radeon_connector = to_radeon_connector(connector); |
166 | break; | ||
167 | } | ||
126 | } | 168 | } |
127 | 169 | ||
128 | if (!radeon_connector) { | 170 | if (!radeon_connector) { |
@@ -321,8 +363,10 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
321 | if (ASIC_IS_DCE6(rdev)) { | 363 | if (ASIC_IS_DCE6(rdev)) { |
322 | dce6_afmt_select_pin(encoder); | 364 | dce6_afmt_select_pin(encoder); |
323 | dce6_afmt_write_sad_regs(encoder); | 365 | dce6_afmt_write_sad_regs(encoder); |
366 | dce6_afmt_write_latency_fields(encoder, mode); | ||
324 | } else { | 367 | } else { |
325 | evergreen_hdmi_write_sad_regs(encoder); | 368 | evergreen_hdmi_write_sad_regs(encoder); |
369 | dce4_afmt_write_latency_fields(encoder, mode); | ||
326 | } | 370 | } |
327 | 371 | ||
328 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); | 372 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 8768fd6a1e27..11e002a47b55 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -750,6 +750,44 @@ | |||
750 | * bit6 = 192 kHz | 750 | * bit6 = 192 kHz |
751 | */ | 751 | */ |
752 | 752 | ||
753 | #define AZ_CHANNEL_COUNT_CONTROL 0x5fe4 | ||
754 | # define HBR_CHANNEL_COUNT(x) (((x) & 0x7) << 0) | ||
755 | # define COMPRESSED_CHANNEL_COUNT(x) (((x) & 0x7) << 4) | ||
756 | /* HBR_CHANNEL_COUNT, COMPRESSED_CHANNEL_COUNT | ||
757 | * 0 = use stream header | ||
758 | * 1-7 = channel count - 1 | ||
759 | */ | ||
760 | #define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_LIPSYNC 0x5fe8 | ||
761 | # define VIDEO_LIPSYNC(x) (((x) & 0xff) << 0) | ||
762 | # define AUDIO_LIPSYNC(x) (((x) & 0xff) << 8) | ||
763 | /* VIDEO_LIPSYNC, AUDIO_LIPSYNC | ||
764 | * 0 = invalid | ||
765 | * x = legal delay value | ||
766 | * 255 = sync not supported | ||
767 | */ | ||
768 | #define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_HBR 0x5fec | ||
769 | # define HBR_CAPABLE (1 << 0) /* enabled by default */ | ||
770 | |||
771 | #define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_AV_ASSOCIATION0 0x5ff4 | ||
772 | # define DISPLAY0_TYPE(x) (((x) & 0x3) << 0) | ||
773 | # define DISPLAY_TYPE_NONE 0 | ||
774 | # define DISPLAY_TYPE_HDMI 1 | ||
775 | # define DISPLAY_TYPE_DP 2 | ||
776 | # define DISPLAY0_ID(x) (((x) & 0x3f) << 2) | ||
777 | # define DISPLAY1_TYPE(x) (((x) & 0x3) << 8) | ||
778 | # define DISPLAY1_ID(x) (((x) & 0x3f) << 10) | ||
779 | # define DISPLAY2_TYPE(x) (((x) & 0x3) << 16) | ||
780 | # define DISPLAY2_ID(x) (((x) & 0x3f) << 18) | ||
781 | # define DISPLAY3_TYPE(x) (((x) & 0x3) << 24) | ||
782 | # define DISPLAY3_ID(x) (((x) & 0x3f) << 26) | ||
783 | #define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_AV_ASSOCIATION1 0x5ff8 | ||
784 | # define DISPLAY4_TYPE(x) (((x) & 0x3) << 0) | ||
785 | # define DISPLAY4_ID(x) (((x) & 0x3f) << 2) | ||
786 | # define DISPLAY5_TYPE(x) (((x) & 0x3) << 8) | ||
787 | # define DISPLAY5_ID(x) (((x) & 0x3f) << 10) | ||
788 | #define AZ_F0_CODEC_PIN0_CONTROL_RESPONSE_AV_NUMBER 0x5ffc | ||
789 | # define NUMBER_OF_DISPLAY_ID(x) (((x) & 0x7) << 0) | ||
790 | |||
753 | #define AZ_HOT_PLUG_CONTROL 0x5e78 | 791 | #define AZ_HOT_PLUG_CONTROL 0x5e78 |
754 | # define AZ_FORCE_CODEC_WAKE (1 << 0) | 792 | # define AZ_FORCE_CODEC_WAKE (1 << 0) |
755 | # define PIN0_JACK_DETECTION_ENABLE (1 << 4) | 793 | # define PIN0_JACK_DETECTION_ENABLE (1 << 4) |
@@ -1312,6 +1350,38 @@ | |||
1312 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) | 1350 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) |
1313 | # define DC_HPDx_EN (1 << 28) | 1351 | # define DC_HPDx_EN (1 << 28) |
1314 | 1352 | ||
1353 | /* DCE4/5/6 FMT blocks */ | ||
1354 | #define FMT_DYNAMIC_EXP_CNTL 0x6fb4 | ||
1355 | # define FMT_DYNAMIC_EXP_EN (1 << 0) | ||
1356 | # define FMT_DYNAMIC_EXP_MODE (1 << 4) | ||
1357 | /* 0 = 10bit -> 12bit, 1 = 8bit -> 12bit */ | ||
1358 | #define FMT_CONTROL 0x6fb8 | ||
1359 | # define FMT_PIXEL_ENCODING (1 << 16) | ||
1360 | /* 0 = RGB 4:4:4 or YCbCr 4:4:4, 1 = YCbCr 4:2:2 */ | ||
1361 | #define FMT_BIT_DEPTH_CONTROL 0x6fc8 | ||
1362 | # define FMT_TRUNCATE_EN (1 << 0) | ||
1363 | # define FMT_TRUNCATE_DEPTH (1 << 4) | ||
1364 | # define FMT_SPATIAL_DITHER_EN (1 << 8) | ||
1365 | # define FMT_SPATIAL_DITHER_MODE(x) ((x) << 9) | ||
1366 | # define FMT_SPATIAL_DITHER_DEPTH (1 << 12) | ||
1367 | # define FMT_FRAME_RANDOM_ENABLE (1 << 13) | ||
1368 | # define FMT_RGB_RANDOM_ENABLE (1 << 14) | ||
1369 | # define FMT_HIGHPASS_RANDOM_ENABLE (1 << 15) | ||
1370 | # define FMT_TEMPORAL_DITHER_EN (1 << 16) | ||
1371 | # define FMT_TEMPORAL_DITHER_DEPTH (1 << 20) | ||
1372 | # define FMT_TEMPORAL_DITHER_OFFSET(x) ((x) << 21) | ||
1373 | # define FMT_TEMPORAL_LEVEL (1 << 24) | ||
1374 | # define FMT_TEMPORAL_DITHER_RESET (1 << 25) | ||
1375 | # define FMT_25FRC_SEL(x) ((x) << 26) | ||
1376 | # define FMT_50FRC_SEL(x) ((x) << 28) | ||
1377 | # define FMT_75FRC_SEL(x) ((x) << 30) | ||
1378 | #define FMT_CLAMP_CONTROL 0x6fe4 | ||
1379 | # define FMT_CLAMP_DATA_EN (1 << 0) | ||
1380 | # define FMT_CLAMP_COLOR_FORMAT(x) ((x) << 16) | ||
1381 | # define FMT_CLAMP_6BPC 0 | ||
1382 | # define FMT_CLAMP_8BPC 1 | ||
1383 | # define FMT_CLAMP_10BPC 2 | ||
1384 | |||
1315 | /* ASYNC DMA */ | 1385 | /* ASYNC DMA */ |
1316 | #define DMA_RB_RPTR 0xd008 | 1386 | #define DMA_RB_RPTR 0xd008 |
1317 | #define DMA_RB_WPTR 0xd00c | 1387 | #define DMA_RB_WPTR 0xd00c |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 93c1f9ef5da9..e299a38e683a 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -174,11 +174,6 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | |||
174 | extern void evergreen_program_aspm(struct radeon_device *rdev); | 174 | extern void evergreen_program_aspm(struct radeon_device *rdev); |
175 | extern void sumo_rlc_fini(struct radeon_device *rdev); | 175 | extern void sumo_rlc_fini(struct radeon_device *rdev); |
176 | extern int sumo_rlc_init(struct radeon_device *rdev); | 176 | extern int sumo_rlc_init(struct radeon_device *rdev); |
177 | extern void cayman_dma_vm_set_page(struct radeon_device *rdev, | ||
178 | struct radeon_ib *ib, | ||
179 | uint64_t pe, | ||
180 | uint64_t addr, unsigned count, | ||
181 | uint32_t incr, uint32_t flags); | ||
182 | 177 | ||
183 | /* Firmware Names */ | 178 | /* Firmware Names */ |
184 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); | 179 | MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); |
@@ -2399,77 +2394,6 @@ void cayman_vm_decode_fault(struct radeon_device *rdev, | |||
2399 | block, mc_id); | 2394 | block, mc_id); |
2400 | } | 2395 | } |
2401 | 2396 | ||
2402 | #define R600_ENTRY_VALID (1 << 0) | ||
2403 | #define R600_PTE_SYSTEM (1 << 1) | ||
2404 | #define R600_PTE_SNOOPED (1 << 2) | ||
2405 | #define R600_PTE_READABLE (1 << 5) | ||
2406 | #define R600_PTE_WRITEABLE (1 << 6) | ||
2407 | |||
2408 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) | ||
2409 | { | ||
2410 | uint32_t r600_flags = 0; | ||
2411 | r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0; | ||
2412 | r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; | ||
2413 | r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; | ||
2414 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
2415 | r600_flags |= R600_PTE_SYSTEM; | ||
2416 | r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0; | ||
2417 | } | ||
2418 | return r600_flags; | ||
2419 | } | ||
2420 | |||
2421 | /** | ||
2422 | * cayman_vm_set_page - update the page tables using the CP | ||
2423 | * | ||
2424 | * @rdev: radeon_device pointer | ||
2425 | * @ib: indirect buffer to fill with commands | ||
2426 | * @pe: addr of the page entry | ||
2427 | * @addr: dst addr to write into pe | ||
2428 | * @count: number of page entries to update | ||
2429 | * @incr: increase next addr by incr bytes | ||
2430 | * @flags: access flags | ||
2431 | * | ||
2432 | * Update the page tables using the CP (cayman/TN). | ||
2433 | */ | ||
2434 | void cayman_vm_set_page(struct radeon_device *rdev, | ||
2435 | struct radeon_ib *ib, | ||
2436 | uint64_t pe, | ||
2437 | uint64_t addr, unsigned count, | ||
2438 | uint32_t incr, uint32_t flags) | ||
2439 | { | ||
2440 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | ||
2441 | uint64_t value; | ||
2442 | unsigned ndw; | ||
2443 | |||
2444 | if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { | ||
2445 | while (count) { | ||
2446 | ndw = 1 + count * 2; | ||
2447 | if (ndw > 0x3FFF) | ||
2448 | ndw = 0x3FFF; | ||
2449 | |||
2450 | ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw); | ||
2451 | ib->ptr[ib->length_dw++] = pe; | ||
2452 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; | ||
2453 | for (; ndw > 1; ndw -= 2, --count, pe += 8) { | ||
2454 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
2455 | value = radeon_vm_map_gart(rdev, addr); | ||
2456 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
2457 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
2458 | value = addr; | ||
2459 | } else { | ||
2460 | value = 0; | ||
2461 | } | ||
2462 | addr += incr; | ||
2463 | value |= r600_flags; | ||
2464 | ib->ptr[ib->length_dw++] = value; | ||
2465 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | ||
2466 | } | ||
2467 | } | ||
2468 | } else { | ||
2469 | cayman_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); | ||
2470 | } | ||
2471 | } | ||
2472 | |||
2473 | /** | 2397 | /** |
2474 | * cayman_vm_flush - vm flush using the CP | 2398 | * cayman_vm_flush - vm flush using the CP |
2475 | * | 2399 | * |
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index dd6e9688fbef..bdeb65ed3658 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <drm/drmP.h> | 24 | #include <drm/drmP.h> |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_asic.h" | 26 | #include "radeon_asic.h" |
27 | #include "radeon_trace.h" | ||
27 | #include "nid.h" | 28 | #include "nid.h" |
28 | 29 | ||
29 | u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev); | 30 | u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev); |
@@ -245,8 +246,7 @@ bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
245 | * @addr: dst addr to write into pe | 246 | * @addr: dst addr to write into pe |
246 | * @count: number of page entries to update | 247 | * @count: number of page entries to update |
247 | * @incr: increase next addr by incr bytes | 248 | * @incr: increase next addr by incr bytes |
248 | * @flags: access flags | 249 | * @flags: hw access flags |
249 | * @r600_flags: hw access flags | ||
250 | * | 250 | * |
251 | * Update the page tables using the DMA (cayman/TN). | 251 | * Update the page tables using the DMA (cayman/TN). |
252 | */ | 252 | */ |
@@ -256,11 +256,12 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, | |||
256 | uint64_t addr, unsigned count, | 256 | uint64_t addr, unsigned count, |
257 | uint32_t incr, uint32_t flags) | 257 | uint32_t incr, uint32_t flags) |
258 | { | 258 | { |
259 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | ||
260 | uint64_t value; | 259 | uint64_t value; |
261 | unsigned ndw; | 260 | unsigned ndw; |
262 | 261 | ||
263 | if ((flags & RADEON_VM_PAGE_SYSTEM) || (count == 1)) { | 262 | trace_radeon_vm_set_page(pe, addr, count, incr, flags); |
263 | |||
264 | if ((flags & R600_PTE_SYSTEM) || (count == 1)) { | ||
264 | while (count) { | 265 | while (count) { |
265 | ndw = count * 2; | 266 | ndw = count * 2; |
266 | if (ndw > 0xFFFFE) | 267 | if (ndw > 0xFFFFE) |
@@ -271,16 +272,16 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, | |||
271 | ib->ptr[ib->length_dw++] = pe; | 272 | ib->ptr[ib->length_dw++] = pe; |
272 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; | 273 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; |
273 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { | 274 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
274 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 275 | if (flags & R600_PTE_SYSTEM) { |
275 | value = radeon_vm_map_gart(rdev, addr); | 276 | value = radeon_vm_map_gart(rdev, addr); |
276 | value &= 0xFFFFFFFFFFFFF000ULL; | 277 | value &= 0xFFFFFFFFFFFFF000ULL; |
277 | } else if (flags & RADEON_VM_PAGE_VALID) { | 278 | } else if (flags & R600_PTE_VALID) { |
278 | value = addr; | 279 | value = addr; |
279 | } else { | 280 | } else { |
280 | value = 0; | 281 | value = 0; |
281 | } | 282 | } |
282 | addr += incr; | 283 | addr += incr; |
283 | value |= r600_flags; | 284 | value |= flags; |
284 | ib->ptr[ib->length_dw++] = value; | 285 | ib->ptr[ib->length_dw++] = value; |
285 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | 286 | ib->ptr[ib->length_dw++] = upper_32_bits(value); |
286 | } | 287 | } |
@@ -291,7 +292,7 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, | |||
291 | if (ndw > 0xFFFFE) | 292 | if (ndw > 0xFFFFE) |
292 | ndw = 0xFFFFE; | 293 | ndw = 0xFFFFE; |
293 | 294 | ||
294 | if (flags & RADEON_VM_PAGE_VALID) | 295 | if (flags & R600_PTE_VALID) |
295 | value = addr; | 296 | value = addr; |
296 | else | 297 | else |
297 | value = 0; | 298 | value = 0; |
@@ -299,7 +300,7 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, | |||
299 | ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); | 300 | ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); |
300 | ib->ptr[ib->length_dw++] = pe; /* dst addr */ | 301 | ib->ptr[ib->length_dw++] = pe; /* dst addr */ |
301 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; | 302 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; |
302 | ib->ptr[ib->length_dw++] = r600_flags; /* mask */ | 303 | ib->ptr[ib->length_dw++] = flags; /* mask */ |
303 | ib->ptr[ib->length_dw++] = 0; | 304 | ib->ptr[ib->length_dw++] = 0; |
304 | ib->ptr[ib->length_dw++] = value; /* value */ | 305 | ib->ptr[ib->length_dw++] = value; /* value */ |
305 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | 306 | ib->ptr[ib->length_dw++] = upper_32_bits(value); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 2a1b1876b431..af922e297a12 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -124,6 +124,59 @@ int r600_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) | |||
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | 126 | ||
127 | void dce3_program_fmt(struct drm_encoder *encoder) | ||
128 | { | ||
129 | struct drm_device *dev = encoder->dev; | ||
130 | struct radeon_device *rdev = dev->dev_private; | ||
131 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
132 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
133 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
134 | int bpc = 0; | ||
135 | u32 tmp = 0; | ||
136 | enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE; | ||
137 | |||
138 | if (connector) { | ||
139 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
140 | bpc = radeon_get_monitor_bpc(connector); | ||
141 | dither = radeon_connector->dither; | ||
142 | } | ||
143 | |||
144 | /* LVDS FMT is set up by atom */ | ||
145 | if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) | ||
146 | return; | ||
147 | |||
148 | /* not needed for analog */ | ||
149 | if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) || | ||
150 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2)) | ||
151 | return; | ||
152 | |||
153 | if (bpc == 0) | ||
154 | return; | ||
155 | |||
156 | switch (bpc) { | ||
157 | case 6: | ||
158 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
159 | /* XXX sort out optimal dither settings */ | ||
160 | tmp |= FMT_SPATIAL_DITHER_EN; | ||
161 | else | ||
162 | tmp |= FMT_TRUNCATE_EN; | ||
163 | break; | ||
164 | case 8: | ||
165 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
166 | /* XXX sort out optimal dither settings */ | ||
167 | tmp |= (FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH); | ||
168 | else | ||
169 | tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH); | ||
170 | break; | ||
171 | case 10: | ||
172 | default: | ||
173 | /* not needed */ | ||
174 | break; | ||
175 | } | ||
176 | |||
177 | WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp); | ||
178 | } | ||
179 | |||
127 | /* get temperature in millidegrees */ | 180 | /* get temperature in millidegrees */ |
128 | int rv6xx_get_temp(struct radeon_device *rdev) | 181 | int rv6xx_get_temp(struct radeon_device *rdev) |
129 | { | 182 | { |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 01a3ec83f284..1abaa2be460d 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -2328,13 +2328,8 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
2328 | unsigned i; | 2328 | unsigned i; |
2329 | 2329 | ||
2330 | kfree(parser->relocs); | 2330 | kfree(parser->relocs); |
2331 | for (i = 0; i < parser->nchunks; i++) { | 2331 | for (i = 0; i < parser->nchunks; i++) |
2332 | kfree(parser->chunks[i].kdata); | 2332 | drm_free_large(parser->chunks[i].kdata); |
2333 | if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) { | ||
2334 | kfree(parser->chunks[i].kpage[0]); | ||
2335 | kfree(parser->chunks[i].kpage[1]); | ||
2336 | } | ||
2337 | } | ||
2338 | kfree(parser->chunks); | 2333 | kfree(parser->chunks); |
2339 | kfree(parser->chunks_array); | 2334 | kfree(parser->chunks_array); |
2340 | } | 2335 | } |
@@ -2391,13 +2386,12 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, | |||
2391 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; | 2386 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; |
2392 | parser.ib.length_dw = ib_chunk->length_dw; | 2387 | parser.ib.length_dw = ib_chunk->length_dw; |
2393 | *l = parser.ib.length_dw; | 2388 | *l = parser.ib.length_dw; |
2394 | r = r600_cs_parse(&parser); | 2389 | if (DRM_COPY_FROM_USER(ib, ib_chunk->user_ptr, ib_chunk->length_dw * 4)) { |
2395 | if (r) { | 2390 | r = -EFAULT; |
2396 | DRM_ERROR("Invalid command stream !\n"); | ||
2397 | r600_cs_parser_fini(&parser, r); | 2391 | r600_cs_parser_fini(&parser, r); |
2398 | return r; | 2392 | return r; |
2399 | } | 2393 | } |
2400 | r = radeon_cs_finish_pages(&parser); | 2394 | r = r600_cs_parse(&parser); |
2401 | if (r) { | 2395 | if (r) { |
2402 | DRM_ERROR("Invalid command stream !\n"); | 2396 | DRM_ERROR("Invalid command stream !\n"); |
2403 | r600_cs_parser_fini(&parser, r); | 2397 | r600_cs_parser_fini(&parser, r); |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index b0fa6002af3e..21f2b74e20e6 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -303,8 +303,10 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
303 | int sad_count; | 303 | int sad_count; |
304 | 304 | ||
305 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 305 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
306 | if (connector->encoder == encoder) | 306 | if (connector->encoder == encoder) { |
307 | radeon_connector = to_radeon_connector(connector); | 307 | radeon_connector = to_radeon_connector(connector); |
308 | break; | ||
309 | } | ||
308 | } | 310 | } |
309 | 311 | ||
310 | if (!radeon_connector) { | 312 | if (!radeon_connector) { |
@@ -356,8 +358,10 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
356 | }; | 358 | }; |
357 | 359 | ||
358 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 360 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
359 | if (connector->encoder == encoder) | 361 | if (connector->encoder == encoder) { |
360 | radeon_connector = to_radeon_connector(connector); | 362 | radeon_connector = to_radeon_connector(connector); |
363 | break; | ||
364 | } | ||
361 | } | 365 | } |
362 | 366 | ||
363 | if (!radeon_connector) { | 367 | if (!radeon_connector) { |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index e673fe26ea84..8e01b126aaeb 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -1199,6 +1199,34 @@ | |||
1199 | # define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29) | 1199 | # define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29) |
1200 | # define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30) | 1200 | # define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30) |
1201 | 1201 | ||
1202 | /* DCE3 FMT blocks */ | ||
1203 | #define FMT_CONTROL 0x6700 | ||
1204 | # define FMT_PIXEL_ENCODING (1 << 16) | ||
1205 | /* 0 = RGB 4:4:4 or YCbCr 4:4:4, 1 = YCbCr 4:2:2 */ | ||
1206 | #define FMT_BIT_DEPTH_CONTROL 0x6710 | ||
1207 | # define FMT_TRUNCATE_EN (1 << 0) | ||
1208 | # define FMT_TRUNCATE_DEPTH (1 << 4) | ||
1209 | # define FMT_SPATIAL_DITHER_EN (1 << 8) | ||
1210 | # define FMT_SPATIAL_DITHER_MODE(x) ((x) << 9) | ||
1211 | # define FMT_SPATIAL_DITHER_DEPTH (1 << 12) | ||
1212 | # define FMT_FRAME_RANDOM_ENABLE (1 << 13) | ||
1213 | # define FMT_RGB_RANDOM_ENABLE (1 << 14) | ||
1214 | # define FMT_HIGHPASS_RANDOM_ENABLE (1 << 15) | ||
1215 | # define FMT_TEMPORAL_DITHER_EN (1 << 16) | ||
1216 | # define FMT_TEMPORAL_DITHER_DEPTH (1 << 20) | ||
1217 | # define FMT_TEMPORAL_DITHER_OFFSET(x) ((x) << 21) | ||
1218 | # define FMT_TEMPORAL_LEVEL (1 << 24) | ||
1219 | # define FMT_TEMPORAL_DITHER_RESET (1 << 25) | ||
1220 | # define FMT_25FRC_SEL(x) ((x) << 26) | ||
1221 | # define FMT_50FRC_SEL(x) ((x) << 28) | ||
1222 | # define FMT_75FRC_SEL(x) ((x) << 30) | ||
1223 | #define FMT_CLAMP_CONTROL 0x672c | ||
1224 | # define FMT_CLAMP_DATA_EN (1 << 0) | ||
1225 | # define FMT_CLAMP_COLOR_FORMAT(x) ((x) << 16) | ||
1226 | # define FMT_CLAMP_6BPC 0 | ||
1227 | # define FMT_CLAMP_8BPC 1 | ||
1228 | # define FMT_CLAMP_10BPC 2 | ||
1229 | |||
1202 | /* Power management */ | 1230 | /* Power management */ |
1203 | #define CG_SPLL_FUNC_CNTL 0x600 | 1231 | #define CG_SPLL_FUNC_CNTL 0x600 |
1204 | # define SPLL_RESET (1 << 0) | 1232 | # define SPLL_RESET (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a400ac1c4147..b264af6e8b9c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -98,6 +98,7 @@ extern int radeon_lockup_timeout; | |||
98 | extern int radeon_fastfb; | 98 | extern int radeon_fastfb; |
99 | extern int radeon_dpm; | 99 | extern int radeon_dpm; |
100 | extern int radeon_aspm; | 100 | extern int radeon_aspm; |
101 | extern int radeon_runtime_pm; | ||
101 | 102 | ||
102 | /* | 103 | /* |
103 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 104 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
@@ -327,7 +328,6 @@ struct radeon_fence_driver { | |||
327 | /* sync_seq is protected by ring emission lock */ | 328 | /* sync_seq is protected by ring emission lock */ |
328 | uint64_t sync_seq[RADEON_NUM_RINGS]; | 329 | uint64_t sync_seq[RADEON_NUM_RINGS]; |
329 | atomic64_t last_seq; | 330 | atomic64_t last_seq; |
330 | unsigned long last_activity; | ||
331 | bool initialized; | 331 | bool initialized; |
332 | }; | 332 | }; |
333 | 333 | ||
@@ -832,6 +832,12 @@ struct radeon_mec { | |||
832 | #define RADEON_VM_PTB_ALIGN_MASK (RADEON_VM_PTB_ALIGN_SIZE - 1) | 832 | #define RADEON_VM_PTB_ALIGN_MASK (RADEON_VM_PTB_ALIGN_SIZE - 1) |
833 | #define RADEON_VM_PTB_ALIGN(a) (((a) + RADEON_VM_PTB_ALIGN_MASK) & ~RADEON_VM_PTB_ALIGN_MASK) | 833 | #define RADEON_VM_PTB_ALIGN(a) (((a) + RADEON_VM_PTB_ALIGN_MASK) & ~RADEON_VM_PTB_ALIGN_MASK) |
834 | 834 | ||
835 | #define R600_PTE_VALID (1 << 0) | ||
836 | #define R600_PTE_SYSTEM (1 << 1) | ||
837 | #define R600_PTE_SNOOPED (1 << 2) | ||
838 | #define R600_PTE_READABLE (1 << 5) | ||
839 | #define R600_PTE_WRITEABLE (1 << 6) | ||
840 | |||
835 | struct radeon_vm { | 841 | struct radeon_vm { |
836 | struct list_head list; | 842 | struct list_head list; |
837 | struct list_head va; | 843 | struct list_head va; |
@@ -967,12 +973,8 @@ struct radeon_cs_reloc { | |||
967 | struct radeon_cs_chunk { | 973 | struct radeon_cs_chunk { |
968 | uint32_t chunk_id; | 974 | uint32_t chunk_id; |
969 | uint32_t length_dw; | 975 | uint32_t length_dw; |
970 | int kpage_idx[2]; | ||
971 | uint32_t *kpage[2]; | ||
972 | uint32_t *kdata; | 976 | uint32_t *kdata; |
973 | void __user *user_ptr; | 977 | void __user *user_ptr; |
974 | int last_copied_page; | ||
975 | int last_page_index; | ||
976 | }; | 978 | }; |
977 | 979 | ||
978 | struct radeon_cs_parser { | 980 | struct radeon_cs_parser { |
@@ -1007,8 +1009,15 @@ struct radeon_cs_parser { | |||
1007 | struct ww_acquire_ctx ticket; | 1009 | struct ww_acquire_ctx ticket; |
1008 | }; | 1010 | }; |
1009 | 1011 | ||
1010 | extern int radeon_cs_finish_pages(struct radeon_cs_parser *p); | 1012 | static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) |
1011 | extern u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx); | 1013 | { |
1014 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | ||
1015 | |||
1016 | if (ibc->kdata) | ||
1017 | return ibc->kdata[idx]; | ||
1018 | return p->ib.ptr[idx]; | ||
1019 | } | ||
1020 | |||
1012 | 1021 | ||
1013 | struct radeon_cs_packet { | 1022 | struct radeon_cs_packet { |
1014 | unsigned idx; | 1023 | unsigned idx; |
@@ -1675,8 +1684,6 @@ struct radeon_asic { | |||
1675 | struct { | 1684 | struct { |
1676 | int (*init)(struct radeon_device *rdev); | 1685 | int (*init)(struct radeon_device *rdev); |
1677 | void (*fini)(struct radeon_device *rdev); | 1686 | void (*fini)(struct radeon_device *rdev); |
1678 | |||
1679 | u32 pt_ring_index; | ||
1680 | void (*set_page)(struct radeon_device *rdev, | 1687 | void (*set_page)(struct radeon_device *rdev, |
1681 | struct radeon_ib *ib, | 1688 | struct radeon_ib *ib, |
1682 | uint64_t pe, | 1689 | uint64_t pe, |
@@ -2170,6 +2177,7 @@ struct radeon_device { | |||
2170 | bool need_dma32; | 2177 | bool need_dma32; |
2171 | bool accel_working; | 2178 | bool accel_working; |
2172 | bool fastfb_working; /* IGP feature*/ | 2179 | bool fastfb_working; /* IGP feature*/ |
2180 | bool needs_reset; | ||
2173 | struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; | 2181 | struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; |
2174 | const struct firmware *me_fw; /* all family ME firmware */ | 2182 | const struct firmware *me_fw; /* all family ME firmware */ |
2175 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | 2183 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
@@ -2212,6 +2220,9 @@ struct radeon_device { | |||
2212 | /* clock, powergating flags */ | 2220 | /* clock, powergating flags */ |
2213 | u32 cg_flags; | 2221 | u32 cg_flags; |
2214 | u32 pg_flags; | 2222 | u32 pg_flags; |
2223 | |||
2224 | struct dev_pm_domain vga_pm_domain; | ||
2225 | bool have_disp_power_ref; | ||
2215 | }; | 2226 | }; |
2216 | 2227 | ||
2217 | int radeon_device_init(struct radeon_device *rdev, | 2228 | int radeon_device_init(struct radeon_device *rdev, |
@@ -2673,8 +2684,8 @@ extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); | |||
2673 | extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); | 2684 | extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); |
2674 | extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); | 2685 | extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); |
2675 | extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | 2686 | extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); |
2676 | extern int radeon_resume_kms(struct drm_device *dev); | 2687 | extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); |
2677 | extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | 2688 | extern int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); |
2678 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); | 2689 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); |
2679 | extern void radeon_program_register_sequence(struct radeon_device *rdev, | 2690 | extern void radeon_program_register_sequence(struct radeon_device *rdev, |
2680 | const u32 *registers, | 2691 | const u32 *registers, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 8f7e04538fd6..d4b91675671d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1622,8 +1622,7 @@ static struct radeon_asic cayman_asic = { | |||
1622 | .vm = { | 1622 | .vm = { |
1623 | .init = &cayman_vm_init, | 1623 | .init = &cayman_vm_init, |
1624 | .fini = &cayman_vm_fini, | 1624 | .fini = &cayman_vm_fini, |
1625 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 1625 | .set_page = &cayman_dma_vm_set_page, |
1626 | .set_page = &cayman_vm_set_page, | ||
1627 | }, | 1626 | }, |
1628 | .ring = { | 1627 | .ring = { |
1629 | [RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring, | 1628 | [RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring, |
@@ -1723,8 +1722,7 @@ static struct radeon_asic trinity_asic = { | |||
1723 | .vm = { | 1722 | .vm = { |
1724 | .init = &cayman_vm_init, | 1723 | .init = &cayman_vm_init, |
1725 | .fini = &cayman_vm_fini, | 1724 | .fini = &cayman_vm_fini, |
1726 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 1725 | .set_page = &cayman_dma_vm_set_page, |
1727 | .set_page = &cayman_vm_set_page, | ||
1728 | }, | 1726 | }, |
1729 | .ring = { | 1727 | .ring = { |
1730 | [RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring, | 1728 | [RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring, |
@@ -1854,8 +1852,7 @@ static struct radeon_asic si_asic = { | |||
1854 | .vm = { | 1852 | .vm = { |
1855 | .init = &si_vm_init, | 1853 | .init = &si_vm_init, |
1856 | .fini = &si_vm_fini, | 1854 | .fini = &si_vm_fini, |
1857 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 1855 | .set_page = &si_dma_vm_set_page, |
1858 | .set_page = &si_vm_set_page, | ||
1859 | }, | 1856 | }, |
1860 | .ring = { | 1857 | .ring = { |
1861 | [RADEON_RING_TYPE_GFX_INDEX] = &si_gfx_ring, | 1858 | [RADEON_RING_TYPE_GFX_INDEX] = &si_gfx_ring, |
@@ -1879,7 +1876,7 @@ static struct radeon_asic si_asic = { | |||
1879 | .hdmi_setmode = &evergreen_hdmi_setmode, | 1876 | .hdmi_setmode = &evergreen_hdmi_setmode, |
1880 | }, | 1877 | }, |
1881 | .copy = { | 1878 | .copy = { |
1882 | .blit = NULL, | 1879 | .blit = &r600_copy_cpdma, |
1883 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1880 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1884 | .dma = &si_copy_dma, | 1881 | .dma = &si_copy_dma, |
1885 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, | 1882 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
@@ -2000,8 +1997,7 @@ static struct radeon_asic ci_asic = { | |||
2000 | .vm = { | 1997 | .vm = { |
2001 | .init = &cik_vm_init, | 1998 | .init = &cik_vm_init, |
2002 | .fini = &cik_vm_fini, | 1999 | .fini = &cik_vm_fini, |
2003 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 2000 | .set_page = &cik_sdma_vm_set_page, |
2004 | .set_page = &cik_vm_set_page, | ||
2005 | }, | 2001 | }, |
2006 | .ring = { | 2002 | .ring = { |
2007 | [RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring, | 2003 | [RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring, |
@@ -2100,8 +2096,7 @@ static struct radeon_asic kv_asic = { | |||
2100 | .vm = { | 2096 | .vm = { |
2101 | .init = &cik_vm_init, | 2097 | .init = &cik_vm_init, |
2102 | .fini = &cik_vm_fini, | 2098 | .fini = &cik_vm_fini, |
2103 | .pt_ring_index = R600_RING_TYPE_DMA_INDEX, | 2099 | .set_page = &cik_sdma_vm_set_page, |
2104 | .set_page = &cik_vm_set_page, | ||
2105 | }, | 2100 | }, |
2106 | .ring = { | 2101 | .ring = { |
2107 | [RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring, | 2102 | [RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 70c29d5e080d..f2833ee3a613 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -581,17 +581,18 @@ int cayman_vm_init(struct radeon_device *rdev); | |||
581 | void cayman_vm_fini(struct radeon_device *rdev); | 581 | void cayman_vm_fini(struct radeon_device *rdev); |
582 | void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 582 | void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
583 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); | 583 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); |
584 | void cayman_vm_set_page(struct radeon_device *rdev, | ||
585 | struct radeon_ib *ib, | ||
586 | uint64_t pe, | ||
587 | uint64_t addr, unsigned count, | ||
588 | uint32_t incr, uint32_t flags); | ||
589 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 584 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
590 | int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 585 | int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
591 | void cayman_dma_ring_ib_execute(struct radeon_device *rdev, | 586 | void cayman_dma_ring_ib_execute(struct radeon_device *rdev, |
592 | struct radeon_ib *ib); | 587 | struct radeon_ib *ib); |
593 | bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); | 588 | bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); |
594 | bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); | 589 | bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); |
590 | void cayman_dma_vm_set_page(struct radeon_device *rdev, | ||
591 | struct radeon_ib *ib, | ||
592 | uint64_t pe, | ||
593 | uint64_t addr, unsigned count, | ||
594 | uint32_t incr, uint32_t flags); | ||
595 | |||
595 | void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 596 | void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
596 | 597 | ||
597 | int ni_dpm_init(struct radeon_device *rdev); | 598 | int ni_dpm_init(struct radeon_device *rdev); |
@@ -653,17 +654,17 @@ int si_irq_set(struct radeon_device *rdev); | |||
653 | int si_irq_process(struct radeon_device *rdev); | 654 | int si_irq_process(struct radeon_device *rdev); |
654 | int si_vm_init(struct radeon_device *rdev); | 655 | int si_vm_init(struct radeon_device *rdev); |
655 | void si_vm_fini(struct radeon_device *rdev); | 656 | void si_vm_fini(struct radeon_device *rdev); |
656 | void si_vm_set_page(struct radeon_device *rdev, | ||
657 | struct radeon_ib *ib, | ||
658 | uint64_t pe, | ||
659 | uint64_t addr, unsigned count, | ||
660 | uint32_t incr, uint32_t flags); | ||
661 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 657 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
662 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 658 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
663 | int si_copy_dma(struct radeon_device *rdev, | 659 | int si_copy_dma(struct radeon_device *rdev, |
664 | uint64_t src_offset, uint64_t dst_offset, | 660 | uint64_t src_offset, uint64_t dst_offset, |
665 | unsigned num_gpu_pages, | 661 | unsigned num_gpu_pages, |
666 | struct radeon_fence **fence); | 662 | struct radeon_fence **fence); |
663 | void si_dma_vm_set_page(struct radeon_device *rdev, | ||
664 | struct radeon_ib *ib, | ||
665 | uint64_t pe, | ||
666 | uint64_t addr, unsigned count, | ||
667 | uint32_t incr, uint32_t flags); | ||
667 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 668 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
668 | u32 si_get_xclk(struct radeon_device *rdev); | 669 | u32 si_get_xclk(struct radeon_device *rdev); |
669 | uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev); | 670 | uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev); |
@@ -705,6 +706,10 @@ int cik_copy_dma(struct radeon_device *rdev, | |||
705 | uint64_t src_offset, uint64_t dst_offset, | 706 | uint64_t src_offset, uint64_t dst_offset, |
706 | unsigned num_gpu_pages, | 707 | unsigned num_gpu_pages, |
707 | struct radeon_fence **fence); | 708 | struct radeon_fence **fence); |
709 | int cik_copy_cpdma(struct radeon_device *rdev, | ||
710 | uint64_t src_offset, uint64_t dst_offset, | ||
711 | unsigned num_gpu_pages, | ||
712 | struct radeon_fence **fence); | ||
708 | int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); | 713 | int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); |
709 | int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | 714 | int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); |
710 | bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); | 715 | bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); |
@@ -731,11 +736,11 @@ int cik_irq_process(struct radeon_device *rdev); | |||
731 | int cik_vm_init(struct radeon_device *rdev); | 736 | int cik_vm_init(struct radeon_device *rdev); |
732 | void cik_vm_fini(struct radeon_device *rdev); | 737 | void cik_vm_fini(struct radeon_device *rdev); |
733 | void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 738 | void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
734 | void cik_vm_set_page(struct radeon_device *rdev, | 739 | void cik_sdma_vm_set_page(struct radeon_device *rdev, |
735 | struct radeon_ib *ib, | 740 | struct radeon_ib *ib, |
736 | uint64_t pe, | 741 | uint64_t pe, |
737 | uint64_t addr, unsigned count, | 742 | uint64_t addr, unsigned count, |
738 | uint32_t incr, uint32_t flags); | 743 | uint32_t incr, uint32_t flags); |
739 | void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 744 | void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
740 | int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 745 | int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
741 | u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, | 746 | u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index d96070bf8388..6153ec18943a 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -59,6 +59,10 @@ struct atpx_mux { | |||
59 | u16 mux; | 59 | u16 mux; |
60 | } __packed; | 60 | } __packed; |
61 | 61 | ||
62 | bool radeon_is_px(void) { | ||
63 | return radeon_atpx_priv.atpx_detected; | ||
64 | } | ||
65 | |||
62 | /** | 66 | /** |
63 | * radeon_atpx_call - call an ATPX method | 67 | * radeon_atpx_call - call an ATPX method |
64 | * | 68 | * |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 79159b5da05b..e972143e5a36 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "atom.h" | 32 | #include "atom.h" |
33 | 33 | ||
34 | #include <linux/pm_runtime.h> | ||
35 | |||
34 | extern void | 36 | extern void |
35 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, | 37 | radeon_combios_connected_scratch_regs(struct drm_connector *connector, |
36 | struct drm_encoder *encoder, | 38 | struct drm_encoder *encoder, |
@@ -411,6 +413,21 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct | |||
411 | } | 413 | } |
412 | } | 414 | } |
413 | 415 | ||
416 | if (property == rdev->mode_info.dither_property) { | ||
417 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
418 | /* need to find digital encoder on connector */ | ||
419 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); | ||
420 | if (!encoder) | ||
421 | return 0; | ||
422 | |||
423 | radeon_encoder = to_radeon_encoder(encoder); | ||
424 | |||
425 | if (radeon_connector->dither != val) { | ||
426 | radeon_connector->dither = val; | ||
427 | radeon_property_change_mode(&radeon_encoder->base); | ||
428 | } | ||
429 | } | ||
430 | |||
414 | if (property == rdev->mode_info.underscan_property) { | 431 | if (property == rdev->mode_info.underscan_property) { |
415 | /* need to find digital encoder on connector */ | 432 | /* need to find digital encoder on connector */ |
416 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); | 433 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); |
@@ -626,6 +643,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
626 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 643 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
627 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 644 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
628 | enum drm_connector_status ret = connector_status_disconnected; | 645 | enum drm_connector_status ret = connector_status_disconnected; |
646 | int r; | ||
647 | |||
648 | r = pm_runtime_get_sync(connector->dev->dev); | ||
649 | if (r < 0) | ||
650 | return connector_status_disconnected; | ||
629 | 651 | ||
630 | if (encoder) { | 652 | if (encoder) { |
631 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 653 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
@@ -651,6 +673,8 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) | |||
651 | /* check acpi lid status ??? */ | 673 | /* check acpi lid status ??? */ |
652 | 674 | ||
653 | radeon_connector_update_scratch_regs(connector, ret); | 675 | radeon_connector_update_scratch_regs(connector, ret); |
676 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
677 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
654 | return ret; | 678 | return ret; |
655 | } | 679 | } |
656 | 680 | ||
@@ -750,6 +774,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
750 | struct drm_encoder_helper_funcs *encoder_funcs; | 774 | struct drm_encoder_helper_funcs *encoder_funcs; |
751 | bool dret = false; | 775 | bool dret = false; |
752 | enum drm_connector_status ret = connector_status_disconnected; | 776 | enum drm_connector_status ret = connector_status_disconnected; |
777 | int r; | ||
778 | |||
779 | r = pm_runtime_get_sync(connector->dev->dev); | ||
780 | if (r < 0) | ||
781 | return connector_status_disconnected; | ||
753 | 782 | ||
754 | encoder = radeon_best_single_encoder(connector); | 783 | encoder = radeon_best_single_encoder(connector); |
755 | if (!encoder) | 784 | if (!encoder) |
@@ -790,9 +819,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
790 | * detected a monitor via load. | 819 | * detected a monitor via load. |
791 | */ | 820 | */ |
792 | if (radeon_connector->detected_by_load) | 821 | if (radeon_connector->detected_by_load) |
793 | return connector->status; | 822 | ret = connector->status; |
794 | else | 823 | goto out; |
795 | return ret; | ||
796 | } | 824 | } |
797 | 825 | ||
798 | if (radeon_connector->dac_load_detect && encoder) { | 826 | if (radeon_connector->dac_load_detect && encoder) { |
@@ -817,6 +845,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
817 | } | 845 | } |
818 | 846 | ||
819 | radeon_connector_update_scratch_regs(connector, ret); | 847 | radeon_connector_update_scratch_regs(connector, ret); |
848 | |||
849 | out: | ||
850 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
851 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
852 | |||
820 | return ret; | 853 | return ret; |
821 | } | 854 | } |
822 | 855 | ||
@@ -873,10 +906,15 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | |||
873 | struct drm_encoder_helper_funcs *encoder_funcs; | 906 | struct drm_encoder_helper_funcs *encoder_funcs; |
874 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 907 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
875 | enum drm_connector_status ret = connector_status_disconnected; | 908 | enum drm_connector_status ret = connector_status_disconnected; |
909 | int r; | ||
876 | 910 | ||
877 | if (!radeon_connector->dac_load_detect) | 911 | if (!radeon_connector->dac_load_detect) |
878 | return ret; | 912 | return ret; |
879 | 913 | ||
914 | r = pm_runtime_get_sync(connector->dev->dev); | ||
915 | if (r < 0) | ||
916 | return connector_status_disconnected; | ||
917 | |||
880 | encoder = radeon_best_single_encoder(connector); | 918 | encoder = radeon_best_single_encoder(connector); |
881 | if (!encoder) | 919 | if (!encoder) |
882 | ret = connector_status_disconnected; | 920 | ret = connector_status_disconnected; |
@@ -887,6 +925,8 @@ radeon_tv_detect(struct drm_connector *connector, bool force) | |||
887 | if (ret == connector_status_connected) | 925 | if (ret == connector_status_connected) |
888 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); | 926 | ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); |
889 | radeon_connector_update_scratch_regs(connector, ret); | 927 | radeon_connector_update_scratch_regs(connector, ret); |
928 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
929 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
890 | return ret; | 930 | return ret; |
891 | } | 931 | } |
892 | 932 | ||
@@ -954,12 +994,18 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
954 | struct drm_encoder *encoder = NULL; | 994 | struct drm_encoder *encoder = NULL; |
955 | struct drm_encoder_helper_funcs *encoder_funcs; | 995 | struct drm_encoder_helper_funcs *encoder_funcs; |
956 | struct drm_mode_object *obj; | 996 | struct drm_mode_object *obj; |
957 | int i; | 997 | int i, r; |
958 | enum drm_connector_status ret = connector_status_disconnected; | 998 | enum drm_connector_status ret = connector_status_disconnected; |
959 | bool dret = false, broken_edid = false; | 999 | bool dret = false, broken_edid = false; |
960 | 1000 | ||
961 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 1001 | r = pm_runtime_get_sync(connector->dev->dev); |
962 | return connector->status; | 1002 | if (r < 0) |
1003 | return connector_status_disconnected; | ||
1004 | |||
1005 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | ||
1006 | ret = connector->status; | ||
1007 | goto exit; | ||
1008 | } | ||
963 | 1009 | ||
964 | if (radeon_connector->ddc_bus) | 1010 | if (radeon_connector->ddc_bus) |
965 | dret = radeon_ddc_probe(radeon_connector, false); | 1011 | dret = radeon_ddc_probe(radeon_connector, false); |
@@ -1110,6 +1156,11 @@ out: | |||
1110 | 1156 | ||
1111 | /* updated in get modes as well since we need to know if it's analog or digital */ | 1157 | /* updated in get modes as well since we need to know if it's analog or digital */ |
1112 | radeon_connector_update_scratch_regs(connector, ret); | 1158 | radeon_connector_update_scratch_regs(connector, ret); |
1159 | |||
1160 | exit: | ||
1161 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
1162 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
1163 | |||
1113 | return ret; | 1164 | return ret; |
1114 | } | 1165 | } |
1115 | 1166 | ||
@@ -1377,9 +1428,16 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1377 | enum drm_connector_status ret = connector_status_disconnected; | 1428 | enum drm_connector_status ret = connector_status_disconnected; |
1378 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 1429 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
1379 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 1430 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
1431 | int r; | ||
1380 | 1432 | ||
1381 | if (!force && radeon_check_hpd_status_unchanged(connector)) | 1433 | r = pm_runtime_get_sync(connector->dev->dev); |
1382 | return connector->status; | 1434 | if (r < 0) |
1435 | return connector_status_disconnected; | ||
1436 | |||
1437 | if (!force && radeon_check_hpd_status_unchanged(connector)) { | ||
1438 | ret = connector->status; | ||
1439 | goto out; | ||
1440 | } | ||
1383 | 1441 | ||
1384 | if (radeon_connector->edid) { | 1442 | if (radeon_connector->edid) { |
1385 | kfree(radeon_connector->edid); | 1443 | kfree(radeon_connector->edid); |
@@ -1443,6 +1501,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1443 | } | 1501 | } |
1444 | 1502 | ||
1445 | radeon_connector_update_scratch_regs(connector, ret); | 1503 | radeon_connector_update_scratch_regs(connector, ret); |
1504 | out: | ||
1505 | pm_runtime_mark_last_busy(connector->dev->dev); | ||
1506 | pm_runtime_put_autosuspend(connector->dev->dev); | ||
1507 | |||
1446 | return ret; | 1508 | return ret; |
1447 | } | 1509 | } |
1448 | 1510 | ||
@@ -1660,7 +1722,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1660 | 0); | 1722 | 0); |
1661 | drm_object_attach_property(&radeon_connector->base.base, | 1723 | drm_object_attach_property(&radeon_connector->base.base, |
1662 | rdev->mode_info.audio_property, | 1724 | rdev->mode_info.audio_property, |
1663 | RADEON_AUDIO_DISABLE); | 1725 | RADEON_AUDIO_AUTO); |
1726 | drm_object_attach_property(&radeon_connector->base.base, | ||
1727 | rdev->mode_info.dither_property, | ||
1728 | RADEON_FMT_DITHER_DISABLE); | ||
1664 | subpixel_order = SubPixelHorizontalRGB; | 1729 | subpixel_order = SubPixelHorizontalRGB; |
1665 | connector->interlace_allowed = true; | 1730 | connector->interlace_allowed = true; |
1666 | if (connector_type == DRM_MODE_CONNECTOR_HDMIB) | 1731 | if (connector_type == DRM_MODE_CONNECTOR_HDMIB) |
@@ -1757,7 +1822,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1757 | if (ASIC_IS_DCE2(rdev)) { | 1822 | if (ASIC_IS_DCE2(rdev)) { |
1758 | drm_object_attach_property(&radeon_connector->base.base, | 1823 | drm_object_attach_property(&radeon_connector->base.base, |
1759 | rdev->mode_info.audio_property, | 1824 | rdev->mode_info.audio_property, |
1760 | RADEON_AUDIO_DISABLE); | 1825 | RADEON_AUDIO_AUTO); |
1826 | } | ||
1827 | if (ASIC_IS_AVIVO(rdev)) { | ||
1828 | drm_object_attach_property(&radeon_connector->base.base, | ||
1829 | rdev->mode_info.dither_property, | ||
1830 | RADEON_FMT_DITHER_DISABLE); | ||
1761 | } | 1831 | } |
1762 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | 1832 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
1763 | radeon_connector->dac_load_detect = true; | 1833 | radeon_connector->dac_load_detect = true; |
@@ -1802,7 +1872,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1802 | if (ASIC_IS_DCE2(rdev)) { | 1872 | if (ASIC_IS_DCE2(rdev)) { |
1803 | drm_object_attach_property(&radeon_connector->base.base, | 1873 | drm_object_attach_property(&radeon_connector->base.base, |
1804 | rdev->mode_info.audio_property, | 1874 | rdev->mode_info.audio_property, |
1805 | RADEON_AUDIO_DISABLE); | 1875 | RADEON_AUDIO_AUTO); |
1876 | } | ||
1877 | if (ASIC_IS_AVIVO(rdev)) { | ||
1878 | drm_object_attach_property(&radeon_connector->base.base, | ||
1879 | rdev->mode_info.dither_property, | ||
1880 | RADEON_FMT_DITHER_DISABLE); | ||
1806 | } | 1881 | } |
1807 | subpixel_order = SubPixelHorizontalRGB; | 1882 | subpixel_order = SubPixelHorizontalRGB; |
1808 | connector->interlace_allowed = true; | 1883 | connector->interlace_allowed = true; |
@@ -1846,7 +1921,12 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1846 | if (ASIC_IS_DCE2(rdev)) { | 1921 | if (ASIC_IS_DCE2(rdev)) { |
1847 | drm_object_attach_property(&radeon_connector->base.base, | 1922 | drm_object_attach_property(&radeon_connector->base.base, |
1848 | rdev->mode_info.audio_property, | 1923 | rdev->mode_info.audio_property, |
1849 | RADEON_AUDIO_DISABLE); | 1924 | RADEON_AUDIO_AUTO); |
1925 | } | ||
1926 | if (ASIC_IS_AVIVO(rdev)) { | ||
1927 | drm_object_attach_property(&radeon_connector->base.base, | ||
1928 | rdev->mode_info.dither_property, | ||
1929 | RADEON_FMT_DITHER_DISABLE); | ||
1850 | } | 1930 | } |
1851 | connector->interlace_allowed = true; | 1931 | connector->interlace_allowed = true; |
1852 | /* in theory with a DP to VGA converter... */ | 1932 | /* in theory with a DP to VGA converter... */ |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 66c222836631..c8ab019a980e 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -213,9 +213,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
213 | return -EFAULT; | 213 | return -EFAULT; |
214 | } | 214 | } |
215 | p->chunks[i].length_dw = user_chunk.length_dw; | 215 | p->chunks[i].length_dw = user_chunk.length_dw; |
216 | p->chunks[i].kdata = NULL; | ||
217 | p->chunks[i].chunk_id = user_chunk.chunk_id; | 216 | p->chunks[i].chunk_id = user_chunk.chunk_id; |
218 | p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; | ||
219 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) { | 217 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) { |
220 | p->chunk_relocs_idx = i; | 218 | p->chunk_relocs_idx = i; |
221 | } | 219 | } |
@@ -238,25 +236,31 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
238 | return -EINVAL; | 236 | return -EINVAL; |
239 | } | 237 | } |
240 | 238 | ||
241 | cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; | 239 | size = p->chunks[i].length_dw; |
242 | if ((p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) || | 240 | cdata = (void __user *)(unsigned long)user_chunk.chunk_data; |
243 | (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS)) { | 241 | p->chunks[i].user_ptr = cdata; |
244 | size = p->chunks[i].length_dw * sizeof(uint32_t); | 242 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) |
245 | p->chunks[i].kdata = kmalloc(size, GFP_KERNEL); | 243 | continue; |
246 | if (p->chunks[i].kdata == NULL) { | 244 | |
247 | return -ENOMEM; | 245 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) { |
248 | } | 246 | if (!p->rdev || !(p->rdev->flags & RADEON_IS_AGP)) |
249 | if (DRM_COPY_FROM_USER(p->chunks[i].kdata, | 247 | continue; |
250 | p->chunks[i].user_ptr, size)) { | 248 | } |
251 | return -EFAULT; | 249 | |
252 | } | 250 | p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t)); |
253 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { | 251 | size *= sizeof(uint32_t); |
254 | p->cs_flags = p->chunks[i].kdata[0]; | 252 | if (p->chunks[i].kdata == NULL) { |
255 | if (p->chunks[i].length_dw > 1) | 253 | return -ENOMEM; |
256 | ring = p->chunks[i].kdata[1]; | 254 | } |
257 | if (p->chunks[i].length_dw > 2) | 255 | if (DRM_COPY_FROM_USER(p->chunks[i].kdata, cdata, size)) { |
258 | priority = (s32)p->chunks[i].kdata[2]; | 256 | return -EFAULT; |
259 | } | 257 | } |
258 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { | ||
259 | p->cs_flags = p->chunks[i].kdata[0]; | ||
260 | if (p->chunks[i].length_dw > 1) | ||
261 | ring = p->chunks[i].kdata[1]; | ||
262 | if (p->chunks[i].length_dw > 2) | ||
263 | priority = (s32)p->chunks[i].kdata[2]; | ||
260 | } | 264 | } |
261 | } | 265 | } |
262 | 266 | ||
@@ -279,34 +283,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
279 | } | 283 | } |
280 | } | 284 | } |
281 | 285 | ||
282 | /* deal with non-vm */ | ||
283 | if ((p->chunk_ib_idx != -1) && | ||
284 | ((p->cs_flags & RADEON_CS_USE_VM) == 0) && | ||
285 | (p->chunks[p->chunk_ib_idx].chunk_id == RADEON_CHUNK_ID_IB)) { | ||
286 | if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) { | ||
287 | DRM_ERROR("cs IB too big: %d\n", | ||
288 | p->chunks[p->chunk_ib_idx].length_dw); | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | if (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) { | ||
292 | p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
293 | p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
294 | if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL || | ||
295 | p->chunks[p->chunk_ib_idx].kpage[1] == NULL) { | ||
296 | kfree(p->chunks[p->chunk_ib_idx].kpage[0]); | ||
297 | kfree(p->chunks[p->chunk_ib_idx].kpage[1]); | ||
298 | p->chunks[p->chunk_ib_idx].kpage[0] = NULL; | ||
299 | p->chunks[p->chunk_ib_idx].kpage[1] = NULL; | ||
300 | return -ENOMEM; | ||
301 | } | ||
302 | } | ||
303 | p->chunks[p->chunk_ib_idx].kpage_idx[0] = -1; | ||
304 | p->chunks[p->chunk_ib_idx].kpage_idx[1] = -1; | ||
305 | p->chunks[p->chunk_ib_idx].last_copied_page = -1; | ||
306 | p->chunks[p->chunk_ib_idx].last_page_index = | ||
307 | ((p->chunks[p->chunk_ib_idx].length_dw * 4) - 1) / PAGE_SIZE; | ||
308 | } | ||
309 | |||
310 | return 0; | 286 | return 0; |
311 | } | 287 | } |
312 | 288 | ||
@@ -340,13 +316,8 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo | |||
340 | kfree(parser->track); | 316 | kfree(parser->track); |
341 | kfree(parser->relocs); | 317 | kfree(parser->relocs); |
342 | kfree(parser->relocs_ptr); | 318 | kfree(parser->relocs_ptr); |
343 | for (i = 0; i < parser->nchunks; i++) { | 319 | for (i = 0; i < parser->nchunks; i++) |
344 | kfree(parser->chunks[i].kdata); | 320 | drm_free_large(parser->chunks[i].kdata); |
345 | if ((parser->rdev->flags & RADEON_IS_AGP)) { | ||
346 | kfree(parser->chunks[i].kpage[0]); | ||
347 | kfree(parser->chunks[i].kpage[1]); | ||
348 | } | ||
349 | } | ||
350 | kfree(parser->chunks); | 321 | kfree(parser->chunks); |
351 | kfree(parser->chunks_array); | 322 | kfree(parser->chunks_array); |
352 | radeon_ib_free(parser->rdev, &parser->ib); | 323 | radeon_ib_free(parser->rdev, &parser->ib); |
@@ -356,7 +327,6 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo | |||
356 | static int radeon_cs_ib_chunk(struct radeon_device *rdev, | 327 | static int radeon_cs_ib_chunk(struct radeon_device *rdev, |
357 | struct radeon_cs_parser *parser) | 328 | struct radeon_cs_parser *parser) |
358 | { | 329 | { |
359 | struct radeon_cs_chunk *ib_chunk; | ||
360 | int r; | 330 | int r; |
361 | 331 | ||
362 | if (parser->chunk_ib_idx == -1) | 332 | if (parser->chunk_ib_idx == -1) |
@@ -365,28 +335,11 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
365 | if (parser->cs_flags & RADEON_CS_USE_VM) | 335 | if (parser->cs_flags & RADEON_CS_USE_VM) |
366 | return 0; | 336 | return 0; |
367 | 337 | ||
368 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; | ||
369 | /* Copy the packet into the IB, the parser will read from the | ||
370 | * input memory (cached) and write to the IB (which can be | ||
371 | * uncached). | ||
372 | */ | ||
373 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, | ||
374 | NULL, ib_chunk->length_dw * 4); | ||
375 | if (r) { | ||
376 | DRM_ERROR("Failed to get ib !\n"); | ||
377 | return r; | ||
378 | } | ||
379 | parser->ib.length_dw = ib_chunk->length_dw; | ||
380 | r = radeon_cs_parse(rdev, parser->ring, parser); | 338 | r = radeon_cs_parse(rdev, parser->ring, parser); |
381 | if (r || parser->parser_error) { | 339 | if (r || parser->parser_error) { |
382 | DRM_ERROR("Invalid command stream !\n"); | 340 | DRM_ERROR("Invalid command stream !\n"); |
383 | return r; | 341 | return r; |
384 | } | 342 | } |
385 | r = radeon_cs_finish_pages(parser); | ||
386 | if (r) { | ||
387 | DRM_ERROR("Invalid command stream !\n"); | ||
388 | return r; | ||
389 | } | ||
390 | 343 | ||
391 | if (parser->ring == R600_RING_TYPE_UVD_INDEX) | 344 | if (parser->ring == R600_RING_TYPE_UVD_INDEX) |
392 | radeon_uvd_note_usage(rdev); | 345 | radeon_uvd_note_usage(rdev); |
@@ -424,7 +377,6 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, | |||
424 | static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | 377 | static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, |
425 | struct radeon_cs_parser *parser) | 378 | struct radeon_cs_parser *parser) |
426 | { | 379 | { |
427 | struct radeon_cs_chunk *ib_chunk; | ||
428 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | 380 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; |
429 | struct radeon_vm *vm = &fpriv->vm; | 381 | struct radeon_vm *vm = &fpriv->vm; |
430 | int r; | 382 | int r; |
@@ -434,49 +386,13 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
434 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 386 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
435 | return 0; | 387 | return 0; |
436 | 388 | ||
437 | if ((rdev->family >= CHIP_TAHITI) && | 389 | if (parser->const_ib.length_dw) { |
438 | (parser->chunk_const_ib_idx != -1)) { | ||
439 | ib_chunk = &parser->chunks[parser->chunk_const_ib_idx]; | ||
440 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | ||
441 | DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); | ||
442 | return -EINVAL; | ||
443 | } | ||
444 | r = radeon_ib_get(rdev, parser->ring, &parser->const_ib, | ||
445 | vm, ib_chunk->length_dw * 4); | ||
446 | if (r) { | ||
447 | DRM_ERROR("Failed to get const ib !\n"); | ||
448 | return r; | ||
449 | } | ||
450 | parser->const_ib.is_const_ib = true; | ||
451 | parser->const_ib.length_dw = ib_chunk->length_dw; | ||
452 | /* Copy the packet into the IB */ | ||
453 | if (DRM_COPY_FROM_USER(parser->const_ib.ptr, ib_chunk->user_ptr, | ||
454 | ib_chunk->length_dw * 4)) { | ||
455 | return -EFAULT; | ||
456 | } | ||
457 | r = radeon_ring_ib_parse(rdev, parser->ring, &parser->const_ib); | 390 | r = radeon_ring_ib_parse(rdev, parser->ring, &parser->const_ib); |
458 | if (r) { | 391 | if (r) { |
459 | return r; | 392 | return r; |
460 | } | 393 | } |
461 | } | 394 | } |
462 | 395 | ||
463 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; | ||
464 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | ||
465 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); | ||
466 | return -EINVAL; | ||
467 | } | ||
468 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, | ||
469 | vm, ib_chunk->length_dw * 4); | ||
470 | if (r) { | ||
471 | DRM_ERROR("Failed to get ib !\n"); | ||
472 | return r; | ||
473 | } | ||
474 | parser->ib.length_dw = ib_chunk->length_dw; | ||
475 | /* Copy the packet into the IB */ | ||
476 | if (DRM_COPY_FROM_USER(parser->ib.ptr, ib_chunk->user_ptr, | ||
477 | ib_chunk->length_dw * 4)) { | ||
478 | return -EFAULT; | ||
479 | } | ||
480 | r = radeon_ring_ib_parse(rdev, parser->ring, &parser->ib); | 396 | r = radeon_ring_ib_parse(rdev, parser->ring, &parser->ib); |
481 | if (r) { | 397 | if (r) { |
482 | return r; | 398 | return r; |
@@ -528,6 +444,62 @@ static int radeon_cs_handle_lockup(struct radeon_device *rdev, int r) | |||
528 | return r; | 444 | return r; |
529 | } | 445 | } |
530 | 446 | ||
447 | static int radeon_cs_ib_fill(struct radeon_device *rdev, struct radeon_cs_parser *parser) | ||
448 | { | ||
449 | struct radeon_cs_chunk *ib_chunk; | ||
450 | struct radeon_vm *vm = NULL; | ||
451 | int r; | ||
452 | |||
453 | if (parser->chunk_ib_idx == -1) | ||
454 | return 0; | ||
455 | |||
456 | if (parser->cs_flags & RADEON_CS_USE_VM) { | ||
457 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | ||
458 | vm = &fpriv->vm; | ||
459 | |||
460 | if ((rdev->family >= CHIP_TAHITI) && | ||
461 | (parser->chunk_const_ib_idx != -1)) { | ||
462 | ib_chunk = &parser->chunks[parser->chunk_const_ib_idx]; | ||
463 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | ||
464 | DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | r = radeon_ib_get(rdev, parser->ring, &parser->const_ib, | ||
468 | vm, ib_chunk->length_dw * 4); | ||
469 | if (r) { | ||
470 | DRM_ERROR("Failed to get const ib !\n"); | ||
471 | return r; | ||
472 | } | ||
473 | parser->const_ib.is_const_ib = true; | ||
474 | parser->const_ib.length_dw = ib_chunk->length_dw; | ||
475 | if (DRM_COPY_FROM_USER(parser->const_ib.ptr, | ||
476 | ib_chunk->user_ptr, | ||
477 | ib_chunk->length_dw * 4)) | ||
478 | return -EFAULT; | ||
479 | } | ||
480 | |||
481 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; | ||
482 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | ||
483 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); | ||
484 | return -EINVAL; | ||
485 | } | ||
486 | } | ||
487 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; | ||
488 | |||
489 | r = radeon_ib_get(rdev, parser->ring, &parser->ib, | ||
490 | vm, ib_chunk->length_dw * 4); | ||
491 | if (r) { | ||
492 | DRM_ERROR("Failed to get ib !\n"); | ||
493 | return r; | ||
494 | } | ||
495 | parser->ib.length_dw = ib_chunk->length_dw; | ||
496 | if (ib_chunk->kdata) | ||
497 | memcpy(parser->ib.ptr, ib_chunk->kdata, ib_chunk->length_dw * 4); | ||
498 | else if (DRM_COPY_FROM_USER(parser->ib.ptr, ib_chunk->user_ptr, ib_chunk->length_dw * 4)) | ||
499 | return -EFAULT; | ||
500 | return 0; | ||
501 | } | ||
502 | |||
531 | int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 503 | int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
532 | { | 504 | { |
533 | struct radeon_device *rdev = dev->dev_private; | 505 | struct radeon_device *rdev = dev->dev_private; |
@@ -553,10 +525,15 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
553 | r = radeon_cs_handle_lockup(rdev, r); | 525 | r = radeon_cs_handle_lockup(rdev, r); |
554 | return r; | 526 | return r; |
555 | } | 527 | } |
556 | r = radeon_cs_parser_relocs(&parser); | 528 | |
557 | if (r) { | 529 | r = radeon_cs_ib_fill(rdev, &parser); |
558 | if (r != -ERESTARTSYS) | 530 | if (!r) { |
531 | r = radeon_cs_parser_relocs(&parser); | ||
532 | if (r && r != -ERESTARTSYS) | ||
559 | DRM_ERROR("Failed to parse relocation %d!\n", r); | 533 | DRM_ERROR("Failed to parse relocation %d!\n", r); |
534 | } | ||
535 | |||
536 | if (r) { | ||
560 | radeon_cs_parser_fini(&parser, r, false); | 537 | radeon_cs_parser_fini(&parser, r, false); |
561 | up_read(&rdev->exclusive_lock); | 538 | up_read(&rdev->exclusive_lock); |
562 | r = radeon_cs_handle_lockup(rdev, r); | 539 | r = radeon_cs_handle_lockup(rdev, r); |
@@ -580,97 +557,6 @@ out: | |||
580 | return r; | 557 | return r; |
581 | } | 558 | } |
582 | 559 | ||
583 | int radeon_cs_finish_pages(struct radeon_cs_parser *p) | ||
584 | { | ||
585 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | ||
586 | int i; | ||
587 | int size = PAGE_SIZE; | ||
588 | |||
589 | for (i = ibc->last_copied_page + 1; i <= ibc->last_page_index; i++) { | ||
590 | if (i == ibc->last_page_index) { | ||
591 | size = (ibc->length_dw * 4) % PAGE_SIZE; | ||
592 | if (size == 0) | ||
593 | size = PAGE_SIZE; | ||
594 | } | ||
595 | |||
596 | if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), | ||
597 | ibc->user_ptr + (i * PAGE_SIZE), | ||
598 | size)) | ||
599 | return -EFAULT; | ||
600 | } | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) | ||
605 | { | ||
606 | int new_page; | ||
607 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | ||
608 | int i; | ||
609 | int size = PAGE_SIZE; | ||
610 | bool copy1 = (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) ? | ||
611 | false : true; | ||
612 | |||
613 | for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { | ||
614 | if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), | ||
615 | ibc->user_ptr + (i * PAGE_SIZE), | ||
616 | PAGE_SIZE)) { | ||
617 | p->parser_error = -EFAULT; | ||
618 | return 0; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | if (pg_idx == ibc->last_page_index) { | ||
623 | size = (ibc->length_dw * 4) % PAGE_SIZE; | ||
624 | if (size == 0) | ||
625 | size = PAGE_SIZE; | ||
626 | } | ||
627 | |||
628 | new_page = ibc->kpage_idx[0] < ibc->kpage_idx[1] ? 0 : 1; | ||
629 | if (copy1) | ||
630 | ibc->kpage[new_page] = p->ib.ptr + (pg_idx * (PAGE_SIZE / 4)); | ||
631 | |||
632 | if (DRM_COPY_FROM_USER(ibc->kpage[new_page], | ||
633 | ibc->user_ptr + (pg_idx * PAGE_SIZE), | ||
634 | size)) { | ||
635 | p->parser_error = -EFAULT; | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | /* copy to IB for non single case */ | ||
640 | if (!copy1) | ||
641 | memcpy((void *)(p->ib.ptr+(pg_idx*(PAGE_SIZE/4))), ibc->kpage[new_page], size); | ||
642 | |||
643 | ibc->last_copied_page = pg_idx; | ||
644 | ibc->kpage_idx[new_page] = pg_idx; | ||
645 | |||
646 | return new_page; | ||
647 | } | ||
648 | |||
649 | u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) | ||
650 | { | ||
651 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | ||
652 | u32 pg_idx, pg_offset; | ||
653 | u32 idx_value = 0; | ||
654 | int new_page; | ||
655 | |||
656 | pg_idx = (idx * 4) / PAGE_SIZE; | ||
657 | pg_offset = (idx * 4) % PAGE_SIZE; | ||
658 | |||
659 | if (ibc->kpage_idx[0] == pg_idx) | ||
660 | return ibc->kpage[0][pg_offset/4]; | ||
661 | if (ibc->kpage_idx[1] == pg_idx) | ||
662 | return ibc->kpage[1][pg_offset/4]; | ||
663 | |||
664 | new_page = radeon_cs_update_pages(p, pg_idx); | ||
665 | if (new_page < 0) { | ||
666 | p->parser_error = new_page; | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | idx_value = ibc->kpage[new_page][pg_offset/4]; | ||
671 | return idx_value; | ||
672 | } | ||
673 | |||
674 | /** | 560 | /** |
675 | * radeon_cs_packet_parse() - parse cp packet and point ib index to next packet | 561 | * radeon_cs_packet_parse() - parse cp packet and point ib index to next packet |
676 | * @parser: parser structure holding parsing context. | 562 | * @parser: parser structure holding parsing context. |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 841d0e09be3e..61dbdd938133 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -101,6 +101,12 @@ static const char radeon_family_name[][16] = { | |||
101 | "LAST", | 101 | "LAST", |
102 | }; | 102 | }; |
103 | 103 | ||
104 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
105 | bool radeon_is_px(void); | ||
106 | #else | ||
107 | static inline bool radeon_is_px(void) { return false; } | ||
108 | #endif | ||
109 | |||
104 | /** | 110 | /** |
105 | * radeon_program_register_sequence - program an array of registers. | 111 | * radeon_program_register_sequence - program an array of registers. |
106 | * | 112 | * |
@@ -1076,7 +1082,10 @@ static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev) | |||
1076 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) | 1082 | static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) |
1077 | { | 1083 | { |
1078 | struct drm_device *dev = pci_get_drvdata(pdev); | 1084 | struct drm_device *dev = pci_get_drvdata(pdev); |
1079 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; | 1085 | |
1086 | if (radeon_is_px() && state == VGA_SWITCHEROO_OFF) | ||
1087 | return; | ||
1088 | |||
1080 | if (state == VGA_SWITCHEROO_ON) { | 1089 | if (state == VGA_SWITCHEROO_ON) { |
1081 | unsigned d3_delay = dev->pdev->d3_delay; | 1090 | unsigned d3_delay = dev->pdev->d3_delay; |
1082 | 1091 | ||
@@ -1087,7 +1096,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
1087 | if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) | 1096 | if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) |
1088 | dev->pdev->d3_delay = 20; | 1097 | dev->pdev->d3_delay = 20; |
1089 | 1098 | ||
1090 | radeon_resume_kms(dev); | 1099 | radeon_resume_kms(dev, true, true); |
1091 | 1100 | ||
1092 | dev->pdev->d3_delay = d3_delay; | 1101 | dev->pdev->d3_delay = d3_delay; |
1093 | 1102 | ||
@@ -1097,7 +1106,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
1097 | printk(KERN_INFO "radeon: switched off\n"); | 1106 | printk(KERN_INFO "radeon: switched off\n"); |
1098 | drm_kms_helper_poll_disable(dev); | 1107 | drm_kms_helper_poll_disable(dev); |
1099 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 1108 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
1100 | radeon_suspend_kms(dev, pmm); | 1109 | radeon_suspend_kms(dev, true, true); |
1101 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; | 1110 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; |
1102 | } | 1111 | } |
1103 | } | 1112 | } |
@@ -1147,6 +1156,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1147 | { | 1156 | { |
1148 | int r, i; | 1157 | int r, i; |
1149 | int dma_bits; | 1158 | int dma_bits; |
1159 | bool runtime = false; | ||
1150 | 1160 | ||
1151 | rdev->shutdown = false; | 1161 | rdev->shutdown = false; |
1152 | rdev->dev = &pdev->dev; | 1162 | rdev->dev = &pdev->dev; |
@@ -1293,7 +1303,14 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1293 | /* this will fail for cards that aren't VGA class devices, just | 1303 | /* this will fail for cards that aren't VGA class devices, just |
1294 | * ignore it */ | 1304 | * ignore it */ |
1295 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); | 1305 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); |
1296 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, false); | 1306 | |
1307 | if (radeon_runtime_pm == 1) | ||
1308 | runtime = true; | ||
1309 | if ((radeon_runtime_pm == -1) && radeon_is_px()) | ||
1310 | runtime = true; | ||
1311 | vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); | ||
1312 | if (runtime) | ||
1313 | vga_switcheroo_init_domain_pm_ops(rdev->dev, &rdev->vga_pm_domain); | ||
1297 | 1314 | ||
1298 | r = radeon_init(rdev); | 1315 | r = radeon_init(rdev); |
1299 | if (r) | 1316 | if (r) |
@@ -1383,7 +1400,7 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
1383 | * Returns 0 for success or an error on failure. | 1400 | * Returns 0 for success or an error on failure. |
1384 | * Called at driver suspend. | 1401 | * Called at driver suspend. |
1385 | */ | 1402 | */ |
1386 | int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | 1403 | int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) |
1387 | { | 1404 | { |
1388 | struct radeon_device *rdev; | 1405 | struct radeon_device *rdev; |
1389 | struct drm_crtc *crtc; | 1406 | struct drm_crtc *crtc; |
@@ -1394,9 +1411,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
1394 | if (dev == NULL || dev->dev_private == NULL) { | 1411 | if (dev == NULL || dev->dev_private == NULL) { |
1395 | return -ENODEV; | 1412 | return -ENODEV; |
1396 | } | 1413 | } |
1397 | if (state.event == PM_EVENT_PRETHAW) { | 1414 | |
1398 | return 0; | ||
1399 | } | ||
1400 | rdev = dev->dev_private; | 1415 | rdev = dev->dev_private; |
1401 | 1416 | ||
1402 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 1417 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
@@ -1455,14 +1470,17 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
1455 | radeon_agp_suspend(rdev); | 1470 | radeon_agp_suspend(rdev); |
1456 | 1471 | ||
1457 | pci_save_state(dev->pdev); | 1472 | pci_save_state(dev->pdev); |
1458 | if (state.event == PM_EVENT_SUSPEND) { | 1473 | if (suspend) { |
1459 | /* Shut down the device */ | 1474 | /* Shut down the device */ |
1460 | pci_disable_device(dev->pdev); | 1475 | pci_disable_device(dev->pdev); |
1461 | pci_set_power_state(dev->pdev, PCI_D3hot); | 1476 | pci_set_power_state(dev->pdev, PCI_D3hot); |
1462 | } | 1477 | } |
1463 | console_lock(); | 1478 | |
1464 | radeon_fbdev_set_suspend(rdev, 1); | 1479 | if (fbcon) { |
1465 | console_unlock(); | 1480 | console_lock(); |
1481 | radeon_fbdev_set_suspend(rdev, 1); | ||
1482 | console_unlock(); | ||
1483 | } | ||
1466 | return 0; | 1484 | return 0; |
1467 | } | 1485 | } |
1468 | 1486 | ||
@@ -1475,7 +1493,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
1475 | * Returns 0 for success or an error on failure. | 1493 | * Returns 0 for success or an error on failure. |
1476 | * Called at driver resume. | 1494 | * Called at driver resume. |
1477 | */ | 1495 | */ |
1478 | int radeon_resume_kms(struct drm_device *dev) | 1496 | int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) |
1479 | { | 1497 | { |
1480 | struct drm_connector *connector; | 1498 | struct drm_connector *connector; |
1481 | struct radeon_device *rdev = dev->dev_private; | 1499 | struct radeon_device *rdev = dev->dev_private; |
@@ -1484,12 +1502,17 @@ int radeon_resume_kms(struct drm_device *dev) | |||
1484 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 1502 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
1485 | return 0; | 1503 | return 0; |
1486 | 1504 | ||
1487 | console_lock(); | 1505 | if (fbcon) { |
1488 | pci_set_power_state(dev->pdev, PCI_D0); | 1506 | console_lock(); |
1489 | pci_restore_state(dev->pdev); | 1507 | } |
1490 | if (pci_enable_device(dev->pdev)) { | 1508 | if (resume) { |
1491 | console_unlock(); | 1509 | pci_set_power_state(dev->pdev, PCI_D0); |
1492 | return -1; | 1510 | pci_restore_state(dev->pdev); |
1511 | if (pci_enable_device(dev->pdev)) { | ||
1512 | if (fbcon) | ||
1513 | console_unlock(); | ||
1514 | return -1; | ||
1515 | } | ||
1493 | } | 1516 | } |
1494 | /* resume AGP if in use */ | 1517 | /* resume AGP if in use */ |
1495 | radeon_agp_resume(rdev); | 1518 | radeon_agp_resume(rdev); |
@@ -1502,9 +1525,11 @@ int radeon_resume_kms(struct drm_device *dev) | |||
1502 | radeon_pm_resume(rdev); | 1525 | radeon_pm_resume(rdev); |
1503 | radeon_restore_bios_scratch_regs(rdev); | 1526 | radeon_restore_bios_scratch_regs(rdev); |
1504 | 1527 | ||
1505 | radeon_fbdev_set_suspend(rdev, 0); | 1528 | if (fbcon) { |
1506 | console_unlock(); | 1529 | radeon_fbdev_set_suspend(rdev, 0); |
1507 | 1530 | console_unlock(); | |
1531 | } | ||
1532 | |||
1508 | /* init dig PHYs, disp eng pll */ | 1533 | /* init dig PHYs, disp eng pll */ |
1509 | if (rdev->is_atom_bios) { | 1534 | if (rdev->is_atom_bios) { |
1510 | radeon_atom_encoder_init(rdev); | 1535 | radeon_atom_encoder_init(rdev); |
@@ -1549,6 +1574,14 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
1549 | int resched; | 1574 | int resched; |
1550 | 1575 | ||
1551 | down_write(&rdev->exclusive_lock); | 1576 | down_write(&rdev->exclusive_lock); |
1577 | |||
1578 | if (!rdev->needs_reset) { | ||
1579 | up_write(&rdev->exclusive_lock); | ||
1580 | return 0; | ||
1581 | } | ||
1582 | |||
1583 | rdev->needs_reset = false; | ||
1584 | |||
1552 | radeon_save_bios_scratch_regs(rdev); | 1585 | radeon_save_bios_scratch_regs(rdev); |
1553 | /* block TTM */ | 1586 | /* block TTM */ |
1554 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | 1587 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0d1aa050d41d..0e52cc532c26 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "atom.h" | 30 | #include "atom.h" |
31 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
32 | 32 | ||
33 | #include <linux/pm_runtime.h> | ||
33 | #include <drm/drm_crtc_helper.h> | 34 | #include <drm/drm_crtc_helper.h> |
34 | #include <drm/drm_edid.h> | 35 | #include <drm/drm_edid.h> |
35 | 36 | ||
@@ -494,11 +495,55 @@ unlock_free: | |||
494 | return r; | 495 | return r; |
495 | } | 496 | } |
496 | 497 | ||
498 | static int | ||
499 | radeon_crtc_set_config(struct drm_mode_set *set) | ||
500 | { | ||
501 | struct drm_device *dev; | ||
502 | struct radeon_device *rdev; | ||
503 | struct drm_crtc *crtc; | ||
504 | bool active = false; | ||
505 | int ret; | ||
506 | |||
507 | if (!set || !set->crtc) | ||
508 | return -EINVAL; | ||
509 | |||
510 | dev = set->crtc->dev; | ||
511 | |||
512 | ret = pm_runtime_get_sync(dev->dev); | ||
513 | if (ret < 0) | ||
514 | return ret; | ||
515 | |||
516 | ret = drm_crtc_helper_set_config(set); | ||
517 | |||
518 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
519 | if (crtc->enabled) | ||
520 | active = true; | ||
521 | |||
522 | pm_runtime_mark_last_busy(dev->dev); | ||
523 | |||
524 | rdev = dev->dev_private; | ||
525 | /* if we have active crtcs and we don't have a power ref, | ||
526 | take the current one */ | ||
527 | if (active && !rdev->have_disp_power_ref) { | ||
528 | rdev->have_disp_power_ref = true; | ||
529 | return ret; | ||
530 | } | ||
531 | /* if we have no active crtcs, then drop the power ref | ||
532 | we got before */ | ||
533 | if (!active && rdev->have_disp_power_ref) { | ||
534 | pm_runtime_put_autosuspend(dev->dev); | ||
535 | rdev->have_disp_power_ref = false; | ||
536 | } | ||
537 | |||
538 | /* drop the power reference we got coming in here */ | ||
539 | pm_runtime_put_autosuspend(dev->dev); | ||
540 | return ret; | ||
541 | } | ||
497 | static const struct drm_crtc_funcs radeon_crtc_funcs = { | 542 | static const struct drm_crtc_funcs radeon_crtc_funcs = { |
498 | .cursor_set = radeon_crtc_cursor_set, | 543 | .cursor_set = radeon_crtc_cursor_set, |
499 | .cursor_move = radeon_crtc_cursor_move, | 544 | .cursor_move = radeon_crtc_cursor_move, |
500 | .gamma_set = radeon_crtc_gamma_set, | 545 | .gamma_set = radeon_crtc_gamma_set, |
501 | .set_config = drm_crtc_helper_set_config, | 546 | .set_config = radeon_crtc_set_config, |
502 | .destroy = radeon_crtc_destroy, | 547 | .destroy = radeon_crtc_destroy, |
503 | .page_flip = radeon_crtc_page_flip, | 548 | .page_flip = radeon_crtc_page_flip, |
504 | }; | 549 | }; |
@@ -1178,6 +1223,12 @@ static struct drm_prop_enum_list radeon_audio_enum_list[] = | |||
1178 | { RADEON_AUDIO_AUTO, "auto" }, | 1223 | { RADEON_AUDIO_AUTO, "auto" }, |
1179 | }; | 1224 | }; |
1180 | 1225 | ||
1226 | /* XXX support different dither options? spatial, temporal, both, etc. */ | ||
1227 | static struct drm_prop_enum_list radeon_dither_enum_list[] = | ||
1228 | { { RADEON_FMT_DITHER_DISABLE, "off" }, | ||
1229 | { RADEON_FMT_DITHER_ENABLE, "on" }, | ||
1230 | }; | ||
1231 | |||
1181 | static int radeon_modeset_create_props(struct radeon_device *rdev) | 1232 | static int radeon_modeset_create_props(struct radeon_device *rdev) |
1182 | { | 1233 | { |
1183 | int sz; | 1234 | int sz; |
@@ -1234,6 +1285,12 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) | |||
1234 | "audio", | 1285 | "audio", |
1235 | radeon_audio_enum_list, sz); | 1286 | radeon_audio_enum_list, sz); |
1236 | 1287 | ||
1288 | sz = ARRAY_SIZE(radeon_dither_enum_list); | ||
1289 | rdev->mode_info.dither_property = | ||
1290 | drm_property_create_enum(rdev->ddev, 0, | ||
1291 | "dither", | ||
1292 | radeon_dither_enum_list, sz); | ||
1293 | |||
1237 | return 0; | 1294 | return 0; |
1238 | } | 1295 | } |
1239 | 1296 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 22f685827b7e..dfd4149a43b6 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -36,8 +36,9 @@ | |||
36 | #include <drm/drm_pciids.h> | 36 | #include <drm/drm_pciids.h> |
37 | #include <linux/console.h> | 37 | #include <linux/console.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | 39 | #include <linux/pm_runtime.h> | |
40 | 40 | #include <linux/vga_switcheroo.h> | |
41 | #include "drm_crtc_helper.h" | ||
41 | /* | 42 | /* |
42 | * KMS wrapper. | 43 | * KMS wrapper. |
43 | * - 2.0.0 - initial interface | 44 | * - 2.0.0 - initial interface |
@@ -87,8 +88,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev, | |||
87 | struct drm_file *file_priv); | 88 | struct drm_file *file_priv); |
88 | void radeon_driver_preclose_kms(struct drm_device *dev, | 89 | void radeon_driver_preclose_kms(struct drm_device *dev, |
89 | struct drm_file *file_priv); | 90 | struct drm_file *file_priv); |
90 | int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | 91 | int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon); |
91 | int radeon_resume_kms(struct drm_device *dev); | 92 | int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); |
92 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); | 93 | u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); |
93 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); | 94 | int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); |
94 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); | 95 | void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); |
@@ -136,9 +137,11 @@ void radeon_debugfs_cleanup(struct drm_minor *minor); | |||
136 | #if defined(CONFIG_VGA_SWITCHEROO) | 137 | #if defined(CONFIG_VGA_SWITCHEROO) |
137 | void radeon_register_atpx_handler(void); | 138 | void radeon_register_atpx_handler(void); |
138 | void radeon_unregister_atpx_handler(void); | 139 | void radeon_unregister_atpx_handler(void); |
140 | bool radeon_is_px(void); | ||
139 | #else | 141 | #else |
140 | static inline void radeon_register_atpx_handler(void) {} | 142 | static inline void radeon_register_atpx_handler(void) {} |
141 | static inline void radeon_unregister_atpx_handler(void) {} | 143 | static inline void radeon_unregister_atpx_handler(void) {} |
144 | static inline bool radeon_is_px(void) { return false; } | ||
142 | #endif | 145 | #endif |
143 | 146 | ||
144 | int radeon_no_wb; | 147 | int radeon_no_wb; |
@@ -161,6 +164,7 @@ int radeon_lockup_timeout = 10000; | |||
161 | int radeon_fastfb = 0; | 164 | int radeon_fastfb = 0; |
162 | int radeon_dpm = -1; | 165 | int radeon_dpm = -1; |
163 | int radeon_aspm = -1; | 166 | int radeon_aspm = -1; |
167 | int radeon_runtime_pm = -1; | ||
164 | 168 | ||
165 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 169 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
166 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 170 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
@@ -222,6 +226,9 @@ module_param_named(dpm, radeon_dpm, int, 0444); | |||
222 | MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); | 226 | MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)"); |
223 | module_param_named(aspm, radeon_aspm, int, 0444); | 227 | module_param_named(aspm, radeon_aspm, int, 0444); |
224 | 228 | ||
229 | MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)"); | ||
230 | module_param_named(runpm, radeon_runtime_pm, int, 0444); | ||
231 | |||
225 | static struct pci_device_id pciidlist[] = { | 232 | static struct pci_device_id pciidlist[] = { |
226 | radeon_PCI_IDS | 233 | radeon_PCI_IDS |
227 | }; | 234 | }; |
@@ -258,6 +265,7 @@ static int radeon_resume(struct drm_device *dev) | |||
258 | return 0; | 265 | return 0; |
259 | } | 266 | } |
260 | 267 | ||
268 | |||
261 | static const struct file_operations radeon_driver_old_fops = { | 269 | static const struct file_operations radeon_driver_old_fops = { |
262 | .owner = THIS_MODULE, | 270 | .owner = THIS_MODULE, |
263 | .open = drm_open, | 271 | .open = drm_open, |
@@ -352,25 +360,144 @@ radeon_pci_remove(struct pci_dev *pdev) | |||
352 | drm_put_dev(dev); | 360 | drm_put_dev(dev); |
353 | } | 361 | } |
354 | 362 | ||
355 | static int | 363 | static int radeon_pmops_suspend(struct device *dev) |
356 | radeon_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
357 | { | 364 | { |
358 | struct drm_device *dev = pci_get_drvdata(pdev); | 365 | struct pci_dev *pdev = to_pci_dev(dev); |
359 | return radeon_suspend_kms(dev, state); | 366 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
367 | return radeon_suspend_kms(drm_dev, true, true); | ||
360 | } | 368 | } |
361 | 369 | ||
362 | static int | 370 | static int radeon_pmops_resume(struct device *dev) |
363 | radeon_pci_resume(struct pci_dev *pdev) | ||
364 | { | 371 | { |
365 | struct drm_device *dev = pci_get_drvdata(pdev); | 372 | struct pci_dev *pdev = to_pci_dev(dev); |
366 | return radeon_resume_kms(dev); | 373 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
374 | return radeon_resume_kms(drm_dev, true, true); | ||
375 | } | ||
376 | |||
377 | static int radeon_pmops_freeze(struct device *dev) | ||
378 | { | ||
379 | struct pci_dev *pdev = to_pci_dev(dev); | ||
380 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
381 | return radeon_suspend_kms(drm_dev, false, true); | ||
382 | } | ||
383 | |||
384 | static int radeon_pmops_thaw(struct device *dev) | ||
385 | { | ||
386 | struct pci_dev *pdev = to_pci_dev(dev); | ||
387 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
388 | return radeon_resume_kms(drm_dev, false, true); | ||
389 | } | ||
390 | |||
391 | static int radeon_pmops_runtime_suspend(struct device *dev) | ||
392 | { | ||
393 | struct pci_dev *pdev = to_pci_dev(dev); | ||
394 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
395 | int ret; | ||
396 | |||
397 | if (radeon_runtime_pm == 0) | ||
398 | return -EINVAL; | ||
399 | |||
400 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
401 | drm_kms_helper_poll_disable(drm_dev); | ||
402 | vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); | ||
403 | |||
404 | ret = radeon_suspend_kms(drm_dev, false, false); | ||
405 | pci_save_state(pdev); | ||
406 | pci_disable_device(pdev); | ||
407 | pci_set_power_state(pdev, PCI_D3cold); | ||
408 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int radeon_pmops_runtime_resume(struct device *dev) | ||
414 | { | ||
415 | struct pci_dev *pdev = to_pci_dev(dev); | ||
416 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
417 | int ret; | ||
418 | |||
419 | if (radeon_runtime_pm == 0) | ||
420 | return -EINVAL; | ||
421 | |||
422 | drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
423 | |||
424 | pci_set_power_state(pdev, PCI_D0); | ||
425 | pci_restore_state(pdev); | ||
426 | ret = pci_enable_device(pdev); | ||
427 | if (ret) | ||
428 | return ret; | ||
429 | pci_set_master(pdev); | ||
430 | |||
431 | ret = radeon_resume_kms(drm_dev, false, false); | ||
432 | drm_kms_helper_poll_enable(drm_dev); | ||
433 | vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); | ||
434 | drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; | ||
435 | return 0; | ||
367 | } | 436 | } |
368 | 437 | ||
438 | static int radeon_pmops_runtime_idle(struct device *dev) | ||
439 | { | ||
440 | struct pci_dev *pdev = to_pci_dev(dev); | ||
441 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
442 | struct drm_crtc *crtc; | ||
443 | |||
444 | if (radeon_runtime_pm == 0) | ||
445 | return -EBUSY; | ||
446 | |||
447 | /* are we PX enabled? */ | ||
448 | if (radeon_runtime_pm == -1 && !radeon_is_px()) { | ||
449 | DRM_DEBUG_DRIVER("failing to power off - not px\n"); | ||
450 | return -EBUSY; | ||
451 | } | ||
452 | |||
453 | list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) { | ||
454 | if (crtc->enabled) { | ||
455 | DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); | ||
456 | return -EBUSY; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | pm_runtime_mark_last_busy(dev); | ||
461 | pm_runtime_autosuspend(dev); | ||
462 | /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ | ||
463 | return 1; | ||
464 | } | ||
465 | |||
466 | long radeon_drm_ioctl(struct file *filp, | ||
467 | unsigned int cmd, unsigned long arg) | ||
468 | { | ||
469 | struct drm_file *file_priv = filp->private_data; | ||
470 | struct drm_device *dev; | ||
471 | long ret; | ||
472 | dev = file_priv->minor->dev; | ||
473 | ret = pm_runtime_get_sync(dev->dev); | ||
474 | if (ret < 0) | ||
475 | return ret; | ||
476 | |||
477 | ret = drm_ioctl(filp, cmd, arg); | ||
478 | |||
479 | pm_runtime_mark_last_busy(dev->dev); | ||
480 | pm_runtime_put_autosuspend(dev->dev); | ||
481 | return ret; | ||
482 | } | ||
483 | |||
484 | static const struct dev_pm_ops radeon_pm_ops = { | ||
485 | .suspend = radeon_pmops_suspend, | ||
486 | .resume = radeon_pmops_resume, | ||
487 | .freeze = radeon_pmops_freeze, | ||
488 | .thaw = radeon_pmops_thaw, | ||
489 | .poweroff = radeon_pmops_freeze, | ||
490 | .restore = radeon_pmops_resume, | ||
491 | .runtime_suspend = radeon_pmops_runtime_suspend, | ||
492 | .runtime_resume = radeon_pmops_runtime_resume, | ||
493 | .runtime_idle = radeon_pmops_runtime_idle, | ||
494 | }; | ||
495 | |||
369 | static const struct file_operations radeon_driver_kms_fops = { | 496 | static const struct file_operations radeon_driver_kms_fops = { |
370 | .owner = THIS_MODULE, | 497 | .owner = THIS_MODULE, |
371 | .open = drm_open, | 498 | .open = drm_open, |
372 | .release = drm_release, | 499 | .release = drm_release, |
373 | .unlocked_ioctl = drm_ioctl, | 500 | .unlocked_ioctl = radeon_drm_ioctl, |
374 | .mmap = radeon_mmap, | 501 | .mmap = radeon_mmap, |
375 | .poll = drm_poll, | 502 | .poll = drm_poll, |
376 | .read = drm_read, | 503 | .read = drm_read, |
@@ -379,6 +506,15 @@ static const struct file_operations radeon_driver_kms_fops = { | |||
379 | #endif | 506 | #endif |
380 | }; | 507 | }; |
381 | 508 | ||
509 | |||
510 | static void | ||
511 | radeon_pci_shutdown(struct pci_dev *pdev) | ||
512 | { | ||
513 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
514 | |||
515 | radeon_driver_unload_kms(dev); | ||
516 | } | ||
517 | |||
382 | static struct drm_driver kms_driver = { | 518 | static struct drm_driver kms_driver = { |
383 | .driver_features = | 519 | .driver_features = |
384 | DRIVER_USE_AGP | | 520 | DRIVER_USE_AGP | |
@@ -391,8 +527,6 @@ static struct drm_driver kms_driver = { | |||
391 | .postclose = radeon_driver_postclose_kms, | 527 | .postclose = radeon_driver_postclose_kms, |
392 | .lastclose = radeon_driver_lastclose_kms, | 528 | .lastclose = radeon_driver_lastclose_kms, |
393 | .unload = radeon_driver_unload_kms, | 529 | .unload = radeon_driver_unload_kms, |
394 | .suspend = radeon_suspend_kms, | ||
395 | .resume = radeon_resume_kms, | ||
396 | .get_vblank_counter = radeon_get_vblank_counter_kms, | 530 | .get_vblank_counter = radeon_get_vblank_counter_kms, |
397 | .enable_vblank = radeon_enable_vblank_kms, | 531 | .enable_vblank = radeon_enable_vblank_kms, |
398 | .disable_vblank = radeon_disable_vblank_kms, | 532 | .disable_vblank = radeon_disable_vblank_kms, |
@@ -449,8 +583,8 @@ static struct pci_driver radeon_kms_pci_driver = { | |||
449 | .id_table = pciidlist, | 583 | .id_table = pciidlist, |
450 | .probe = radeon_pci_probe, | 584 | .probe = radeon_pci_probe, |
451 | .remove = radeon_pci_remove, | 585 | .remove = radeon_pci_remove, |
452 | .suspend = radeon_pci_suspend, | 586 | .driver.pm = &radeon_pm_ops, |
453 | .resume = radeon_pci_resume, | 587 | .shutdown = radeon_pci_shutdown, |
454 | }; | 588 | }; |
455 | 589 | ||
456 | static int __init radeon_init(void) | 590 | static int __init radeon_init(void) |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index b369d42f7de5..543dcfae7e6f 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -113,6 +113,9 @@ | |||
113 | #define DRIVER_MINOR 33 | 113 | #define DRIVER_MINOR 33 |
114 | #define DRIVER_PATCHLEVEL 0 | 114 | #define DRIVER_PATCHLEVEL 0 |
115 | 115 | ||
116 | long radeon_drm_ioctl(struct file *filp, | ||
117 | unsigned int cmd, unsigned long arg); | ||
118 | |||
116 | /* The rest of the file is DEPRECATED! */ | 119 | /* The rest of the file is DEPRECATED! */ |
117 | #ifdef CONFIG_DRM_RADEON_UMS | 120 | #ifdef CONFIG_DRM_RADEON_UMS |
118 | 121 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index ddb8f8e04eb5..b8f68b2c47d4 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -190,10 +190,8 @@ void radeon_fence_process(struct radeon_device *rdev, int ring) | |||
190 | } | 190 | } |
191 | } while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq); | 191 | } while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq); |
192 | 192 | ||
193 | if (wake) { | 193 | if (wake) |
194 | rdev->fence_drv[ring].last_activity = jiffies; | ||
195 | wake_up_all(&rdev->fence_queue); | 194 | wake_up_all(&rdev->fence_queue); |
196 | } | ||
197 | } | 195 | } |
198 | 196 | ||
199 | /** | 197 | /** |
@@ -212,13 +210,13 @@ static void radeon_fence_destroy(struct kref *kref) | |||
212 | } | 210 | } |
213 | 211 | ||
214 | /** | 212 | /** |
215 | * radeon_fence_seq_signaled - check if a fence sequeuce number has signaled | 213 | * radeon_fence_seq_signaled - check if a fence sequence number has signaled |
216 | * | 214 | * |
217 | * @rdev: radeon device pointer | 215 | * @rdev: radeon device pointer |
218 | * @seq: sequence number | 216 | * @seq: sequence number |
219 | * @ring: ring index the fence is associated with | 217 | * @ring: ring index the fence is associated with |
220 | * | 218 | * |
221 | * Check if the last singled fence sequnce number is >= the requested | 219 | * Check if the last signaled fence sequnce number is >= the requested |
222 | * sequence number (all asics). | 220 | * sequence number (all asics). |
223 | * Returns true if the fence has signaled (current fence value | 221 | * Returns true if the fence has signaled (current fence value |
224 | * is >= requested value) or false if it has not (current fence | 222 | * is >= requested value) or false if it has not (current fence |
@@ -263,113 +261,131 @@ bool radeon_fence_signaled(struct radeon_fence *fence) | |||
263 | } | 261 | } |
264 | 262 | ||
265 | /** | 263 | /** |
266 | * radeon_fence_wait_seq - wait for a specific sequence number | 264 | * radeon_fence_any_seq_signaled - check if any sequence number is signaled |
267 | * | 265 | * |
268 | * @rdev: radeon device pointer | 266 | * @rdev: radeon device pointer |
269 | * @target_seq: sequence number we want to wait for | 267 | * @seq: sequence numbers |
270 | * @ring: ring index the fence is associated with | 268 | * |
269 | * Check if the last signaled fence sequnce number is >= the requested | ||
270 | * sequence number (all asics). | ||
271 | * Returns true if any has signaled (current value is >= requested value) | ||
272 | * or false if it has not. Helper function for radeon_fence_wait_seq. | ||
273 | */ | ||
274 | static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) | ||
275 | { | ||
276 | unsigned i; | ||
277 | |||
278 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
279 | if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i)) | ||
280 | return true; | ||
281 | } | ||
282 | return false; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * radeon_fence_wait_seq - wait for a specific sequence numbers | ||
287 | * | ||
288 | * @rdev: radeon device pointer | ||
289 | * @target_seq: sequence number(s) we want to wait for | ||
271 | * @intr: use interruptable sleep | 290 | * @intr: use interruptable sleep |
272 | * @lock_ring: whether the ring should be locked or not | 291 | * @lock_ring: whether the ring should be locked or not |
273 | * | 292 | * |
274 | * Wait for the requested sequence number to be written (all asics). | 293 | * Wait for the requested sequence number(s) to be written by any ring |
294 | * (all asics). Sequnce number array is indexed by ring id. | ||
275 | * @intr selects whether to use interruptable (true) or non-interruptable | 295 | * @intr selects whether to use interruptable (true) or non-interruptable |
276 | * (false) sleep when waiting for the sequence number. Helper function | 296 | * (false) sleep when waiting for the sequence number. Helper function |
277 | * for radeon_fence_wait(), et al. | 297 | * for radeon_fence_wait_*(). |
278 | * Returns 0 if the sequence number has passed, error for all other cases. | 298 | * Returns 0 if the sequence number has passed, error for all other cases. |
279 | * -EDEADLK is returned when a GPU lockup has been detected and the ring is | 299 | * -EDEADLK is returned when a GPU lockup has been detected. |
280 | * marked as not ready so no further jobs get scheduled until a successful | ||
281 | * reset. | ||
282 | */ | 300 | */ |
283 | static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq, | 301 | static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 *target_seq, |
284 | unsigned ring, bool intr, bool lock_ring) | 302 | bool intr, bool lock_ring) |
285 | { | 303 | { |
286 | unsigned long timeout, last_activity; | 304 | uint64_t last_seq[RADEON_NUM_RINGS]; |
287 | uint64_t seq; | ||
288 | unsigned i; | ||
289 | bool signaled; | 305 | bool signaled; |
290 | int r; | 306 | int i, r; |
307 | |||
308 | while (!radeon_fence_any_seq_signaled(rdev, target_seq)) { | ||
309 | |||
310 | /* Save current sequence values, used to check for GPU lockups */ | ||
311 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
312 | if (!target_seq[i]) | ||
313 | continue; | ||
291 | 314 | ||
292 | while (target_seq > atomic64_read(&rdev->fence_drv[ring].last_seq)) { | 315 | last_seq[i] = atomic64_read(&rdev->fence_drv[i].last_seq); |
293 | if (!rdev->ring[ring].ready) { | 316 | trace_radeon_fence_wait_begin(rdev->ddev, target_seq[i]); |
294 | return -EBUSY; | 317 | radeon_irq_kms_sw_irq_get(rdev, i); |
295 | } | 318 | } |
296 | 319 | ||
297 | timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT; | 320 | if (intr) { |
298 | if (time_after(rdev->fence_drv[ring].last_activity, timeout)) { | 321 | r = wait_event_interruptible_timeout(rdev->fence_queue, ( |
299 | /* the normal case, timeout is somewhere before last_activity */ | 322 | (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)) |
300 | timeout = rdev->fence_drv[ring].last_activity - timeout; | 323 | || rdev->needs_reset), RADEON_FENCE_JIFFIES_TIMEOUT); |
301 | } else { | 324 | } else { |
302 | /* either jiffies wrapped around, or no fence was signaled in the last 500ms | 325 | r = wait_event_timeout(rdev->fence_queue, ( |
303 | * anyway we will just wait for the minimum amount and then check for a lockup | 326 | (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)) |
304 | */ | 327 | || rdev->needs_reset), RADEON_FENCE_JIFFIES_TIMEOUT); |
305 | timeout = 1; | ||
306 | } | 328 | } |
307 | seq = atomic64_read(&rdev->fence_drv[ring].last_seq); | ||
308 | /* Save current last activity valuee, used to check for GPU lockups */ | ||
309 | last_activity = rdev->fence_drv[ring].last_activity; | ||
310 | 329 | ||
311 | trace_radeon_fence_wait_begin(rdev->ddev, seq); | 330 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
312 | radeon_irq_kms_sw_irq_get(rdev, ring); | 331 | if (!target_seq[i]) |
313 | if (intr) { | 332 | continue; |
314 | r = wait_event_interruptible_timeout(rdev->fence_queue, | 333 | |
315 | (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)), | 334 | radeon_irq_kms_sw_irq_put(rdev, i); |
316 | timeout); | 335 | trace_radeon_fence_wait_end(rdev->ddev, target_seq[i]); |
317 | } else { | ||
318 | r = wait_event_timeout(rdev->fence_queue, | ||
319 | (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)), | ||
320 | timeout); | ||
321 | } | 336 | } |
322 | radeon_irq_kms_sw_irq_put(rdev, ring); | 337 | |
323 | if (unlikely(r < 0)) { | 338 | if (unlikely(r < 0)) |
324 | return r; | 339 | return r; |
325 | } | ||
326 | trace_radeon_fence_wait_end(rdev->ddev, seq); | ||
327 | 340 | ||
328 | if (unlikely(!signaled)) { | 341 | if (unlikely(!signaled)) { |
342 | if (rdev->needs_reset) | ||
343 | return -EDEADLK; | ||
344 | |||
329 | /* we were interrupted for some reason and fence | 345 | /* we were interrupted for some reason and fence |
330 | * isn't signaled yet, resume waiting */ | 346 | * isn't signaled yet, resume waiting */ |
331 | if (r) { | 347 | if (r) |
332 | continue; | 348 | continue; |
349 | |||
350 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
351 | if (!target_seq[i]) | ||
352 | continue; | ||
353 | |||
354 | if (last_seq[i] != atomic64_read(&rdev->fence_drv[i].last_seq)) | ||
355 | break; | ||
333 | } | 356 | } |
334 | 357 | ||
335 | /* check if sequence value has changed since last_activity */ | 358 | if (i != RADEON_NUM_RINGS) |
336 | if (seq != atomic64_read(&rdev->fence_drv[ring].last_seq)) { | ||
337 | continue; | 359 | continue; |
338 | } | ||
339 | 360 | ||
340 | if (lock_ring) { | 361 | if (lock_ring) |
341 | mutex_lock(&rdev->ring_lock); | 362 | mutex_lock(&rdev->ring_lock); |
342 | } | ||
343 | 363 | ||
344 | /* test if somebody else has already decided that this is a lockup */ | 364 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
345 | if (last_activity != rdev->fence_drv[ring].last_activity) { | 365 | if (!target_seq[i]) |
346 | if (lock_ring) { | 366 | continue; |
347 | mutex_unlock(&rdev->ring_lock); | 367 | |
348 | } | 368 | if (radeon_ring_is_lockup(rdev, i, &rdev->ring[i])) |
349 | continue; | 369 | break; |
350 | } | 370 | } |
351 | 371 | ||
352 | if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) { | 372 | if (i < RADEON_NUM_RINGS) { |
353 | /* good news we believe it's a lockup */ | 373 | /* good news we believe it's a lockup */ |
354 | dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx last fence id 0x%016llx)\n", | 374 | dev_warn(rdev->dev, "GPU lockup (waiting for " |
355 | target_seq, seq); | 375 | "0x%016llx last fence id 0x%016llx on" |
356 | 376 | " ring %d)\n", | |
357 | /* change last activity so nobody else think there is a lockup */ | 377 | target_seq[i], last_seq[i], i); |
358 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 378 | |
359 | rdev->fence_drv[i].last_activity = jiffies; | 379 | /* remember that we need an reset */ |
360 | } | 380 | rdev->needs_reset = true; |
361 | 381 | if (lock_ring) | |
362 | /* mark the ring as not ready any more */ | ||
363 | rdev->ring[ring].ready = false; | ||
364 | if (lock_ring) { | ||
365 | mutex_unlock(&rdev->ring_lock); | 382 | mutex_unlock(&rdev->ring_lock); |
366 | } | 383 | wake_up_all(&rdev->fence_queue); |
367 | return -EDEADLK; | 384 | return -EDEADLK; |
368 | } | 385 | } |
369 | 386 | ||
370 | if (lock_ring) { | 387 | if (lock_ring) |
371 | mutex_unlock(&rdev->ring_lock); | 388 | mutex_unlock(&rdev->ring_lock); |
372 | } | ||
373 | } | 389 | } |
374 | } | 390 | } |
375 | return 0; | 391 | return 0; |
@@ -388,6 +404,7 @@ static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq, | |||
388 | */ | 404 | */ |
389 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) | 405 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) |
390 | { | 406 | { |
407 | uint64_t seq[RADEON_NUM_RINGS] = {}; | ||
391 | int r; | 408 | int r; |
392 | 409 | ||
393 | if (fence == NULL) { | 410 | if (fence == NULL) { |
@@ -395,147 +412,15 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) | |||
395 | return -EINVAL; | 412 | return -EINVAL; |
396 | } | 413 | } |
397 | 414 | ||
398 | r = radeon_fence_wait_seq(fence->rdev, fence->seq, | 415 | seq[fence->ring] = fence->seq; |
399 | fence->ring, intr, true); | 416 | if (seq[fence->ring] == RADEON_FENCE_SIGNALED_SEQ) |
400 | if (r) { | 417 | return 0; |
401 | return r; | ||
402 | } | ||
403 | fence->seq = RADEON_FENCE_SIGNALED_SEQ; | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) | ||
408 | { | ||
409 | unsigned i; | ||
410 | |||
411 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
412 | if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i)) { | ||
413 | return true; | ||
414 | } | ||
415 | } | ||
416 | return false; | ||
417 | } | ||
418 | |||
419 | /** | ||
420 | * radeon_fence_wait_any_seq - wait for a sequence number on any ring | ||
421 | * | ||
422 | * @rdev: radeon device pointer | ||
423 | * @target_seq: sequence number(s) we want to wait for | ||
424 | * @intr: use interruptable sleep | ||
425 | * | ||
426 | * Wait for the requested sequence number(s) to be written by any ring | ||
427 | * (all asics). Sequnce number array is indexed by ring id. | ||
428 | * @intr selects whether to use interruptable (true) or non-interruptable | ||
429 | * (false) sleep when waiting for the sequence number. Helper function | ||
430 | * for radeon_fence_wait_any(), et al. | ||
431 | * Returns 0 if the sequence number has passed, error for all other cases. | ||
432 | */ | ||
433 | static int radeon_fence_wait_any_seq(struct radeon_device *rdev, | ||
434 | u64 *target_seq, bool intr) | ||
435 | { | ||
436 | unsigned long timeout, last_activity, tmp; | ||
437 | unsigned i, ring = RADEON_NUM_RINGS; | ||
438 | bool signaled; | ||
439 | int r; | ||
440 | |||
441 | for (i = 0, last_activity = 0; i < RADEON_NUM_RINGS; ++i) { | ||
442 | if (!target_seq[i]) { | ||
443 | continue; | ||
444 | } | ||
445 | |||
446 | /* use the most recent one as indicator */ | ||
447 | if (time_after(rdev->fence_drv[i].last_activity, last_activity)) { | ||
448 | last_activity = rdev->fence_drv[i].last_activity; | ||
449 | } | ||
450 | |||
451 | /* For lockup detection just pick the lowest ring we are | ||
452 | * actively waiting for | ||
453 | */ | ||
454 | if (i < ring) { | ||
455 | ring = i; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | /* nothing to wait for ? */ | ||
460 | if (ring == RADEON_NUM_RINGS) { | ||
461 | return -ENOENT; | ||
462 | } | ||
463 | |||
464 | while (!radeon_fence_any_seq_signaled(rdev, target_seq)) { | ||
465 | timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT; | ||
466 | if (time_after(last_activity, timeout)) { | ||
467 | /* the normal case, timeout is somewhere before last_activity */ | ||
468 | timeout = last_activity - timeout; | ||
469 | } else { | ||
470 | /* either jiffies wrapped around, or no fence was signaled in the last 500ms | ||
471 | * anyway we will just wait for the minimum amount and then check for a lockup | ||
472 | */ | ||
473 | timeout = 1; | ||
474 | } | ||
475 | 418 | ||
476 | trace_radeon_fence_wait_begin(rdev->ddev, target_seq[ring]); | 419 | r = radeon_fence_wait_seq(fence->rdev, seq, intr, true); |
477 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 420 | if (r) |
478 | if (target_seq[i]) { | 421 | return r; |
479 | radeon_irq_kms_sw_irq_get(rdev, i); | ||
480 | } | ||
481 | } | ||
482 | if (intr) { | ||
483 | r = wait_event_interruptible_timeout(rdev->fence_queue, | ||
484 | (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)), | ||
485 | timeout); | ||
486 | } else { | ||
487 | r = wait_event_timeout(rdev->fence_queue, | ||
488 | (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)), | ||
489 | timeout); | ||
490 | } | ||
491 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
492 | if (target_seq[i]) { | ||
493 | radeon_irq_kms_sw_irq_put(rdev, i); | ||
494 | } | ||
495 | } | ||
496 | if (unlikely(r < 0)) { | ||
497 | return r; | ||
498 | } | ||
499 | trace_radeon_fence_wait_end(rdev->ddev, target_seq[ring]); | ||
500 | |||
501 | if (unlikely(!signaled)) { | ||
502 | /* we were interrupted for some reason and fence | ||
503 | * isn't signaled yet, resume waiting */ | ||
504 | if (r) { | ||
505 | continue; | ||
506 | } | ||
507 | |||
508 | mutex_lock(&rdev->ring_lock); | ||
509 | for (i = 0, tmp = 0; i < RADEON_NUM_RINGS; ++i) { | ||
510 | if (time_after(rdev->fence_drv[i].last_activity, tmp)) { | ||
511 | tmp = rdev->fence_drv[i].last_activity; | ||
512 | } | ||
513 | } | ||
514 | /* test if somebody else has already decided that this is a lockup */ | ||
515 | if (last_activity != tmp) { | ||
516 | last_activity = tmp; | ||
517 | mutex_unlock(&rdev->ring_lock); | ||
518 | continue; | ||
519 | } | ||
520 | |||
521 | if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) { | ||
522 | /* good news we believe it's a lockup */ | ||
523 | dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx)\n", | ||
524 | target_seq[ring]); | ||
525 | |||
526 | /* change last activity so nobody else think there is a lockup */ | ||
527 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | ||
528 | rdev->fence_drv[i].last_activity = jiffies; | ||
529 | } | ||
530 | 422 | ||
531 | /* mark the ring as not ready any more */ | 423 | fence->seq = RADEON_FENCE_SIGNALED_SEQ; |
532 | rdev->ring[ring].ready = false; | ||
533 | mutex_unlock(&rdev->ring_lock); | ||
534 | return -EDEADLK; | ||
535 | } | ||
536 | mutex_unlock(&rdev->ring_lock); | ||
537 | } | ||
538 | } | ||
539 | return 0; | 424 | return 0; |
540 | } | 425 | } |
541 | 426 | ||
@@ -557,7 +442,7 @@ int radeon_fence_wait_any(struct radeon_device *rdev, | |||
557 | bool intr) | 442 | bool intr) |
558 | { | 443 | { |
559 | uint64_t seq[RADEON_NUM_RINGS]; | 444 | uint64_t seq[RADEON_NUM_RINGS]; |
560 | unsigned i; | 445 | unsigned i, num_rings = 0; |
561 | int r; | 446 | int r; |
562 | 447 | ||
563 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 448 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
@@ -567,15 +452,19 @@ int radeon_fence_wait_any(struct radeon_device *rdev, | |||
567 | continue; | 452 | continue; |
568 | } | 453 | } |
569 | 454 | ||
570 | if (fences[i]->seq == RADEON_FENCE_SIGNALED_SEQ) { | ||
571 | /* something was allready signaled */ | ||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | seq[i] = fences[i]->seq; | 455 | seq[i] = fences[i]->seq; |
456 | ++num_rings; | ||
457 | |||
458 | /* test if something was allready signaled */ | ||
459 | if (seq[i] == RADEON_FENCE_SIGNALED_SEQ) | ||
460 | return 0; | ||
576 | } | 461 | } |
577 | 462 | ||
578 | r = radeon_fence_wait_any_seq(rdev, seq, intr); | 463 | /* nothing to wait for ? */ |
464 | if (num_rings == 0) | ||
465 | return -ENOENT; | ||
466 | |||
467 | r = radeon_fence_wait_seq(rdev, seq, intr, true); | ||
579 | if (r) { | 468 | if (r) { |
580 | return r; | 469 | return r; |
581 | } | 470 | } |
@@ -594,15 +483,15 @@ int radeon_fence_wait_any(struct radeon_device *rdev, | |||
594 | */ | 483 | */ |
595 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) | 484 | int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) |
596 | { | 485 | { |
597 | uint64_t seq; | 486 | uint64_t seq[RADEON_NUM_RINGS] = {}; |
598 | 487 | ||
599 | seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL; | 488 | seq[ring] = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL; |
600 | if (seq >= rdev->fence_drv[ring].sync_seq[ring]) { | 489 | if (seq[ring] >= rdev->fence_drv[ring].sync_seq[ring]) { |
601 | /* nothing to wait for, last_seq is | 490 | /* nothing to wait for, last_seq is |
602 | already the last emited fence */ | 491 | already the last emited fence */ |
603 | return -ENOENT; | 492 | return -ENOENT; |
604 | } | 493 | } |
605 | return radeon_fence_wait_seq(rdev, seq, ring, false, false); | 494 | return radeon_fence_wait_seq(rdev, seq, false, false); |
606 | } | 495 | } |
607 | 496 | ||
608 | /** | 497 | /** |
@@ -617,14 +506,15 @@ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) | |||
617 | */ | 506 | */ |
618 | int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) | 507 | int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) |
619 | { | 508 | { |
620 | uint64_t seq = rdev->fence_drv[ring].sync_seq[ring]; | 509 | uint64_t seq[RADEON_NUM_RINGS] = {}; |
621 | int r; | 510 | int r; |
622 | 511 | ||
623 | r = radeon_fence_wait_seq(rdev, seq, ring, false, false); | 512 | seq[ring] = rdev->fence_drv[ring].sync_seq[ring]; |
513 | r = radeon_fence_wait_seq(rdev, seq, false, false); | ||
624 | if (r) { | 514 | if (r) { |
625 | if (r == -EDEADLK) { | 515 | if (r == -EDEADLK) |
626 | return -EDEADLK; | 516 | return -EDEADLK; |
627 | } | 517 | |
628 | dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%d)\n", | 518 | dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%d)\n", |
629 | ring, r); | 519 | ring, r); |
630 | } | 520 | } |
@@ -826,7 +716,6 @@ static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) | |||
826 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | 716 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
827 | rdev->fence_drv[ring].sync_seq[i] = 0; | 717 | rdev->fence_drv[ring].sync_seq[i] = 0; |
828 | atomic64_set(&rdev->fence_drv[ring].last_seq, 0); | 718 | atomic64_set(&rdev->fence_drv[ring].last_seq, 0); |
829 | rdev->fence_drv[ring].last_activity = jiffies; | ||
830 | rdev->fence_drv[ring].initialized = false; | 719 | rdev->fence_drv[ring].initialized = false; |
831 | } | 720 | } |
832 | 721 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index b990b1a2bd50..8a83b89d4709 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -607,8 +607,8 @@ static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm) | |||
607 | */ | 607 | */ |
608 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) | 608 | int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) |
609 | { | 609 | { |
610 | unsigned pd_size, pts_size; | 610 | unsigned pd_size, pd_entries, pts_size; |
611 | u64 *pd_addr; | 611 | struct radeon_ib ib; |
612 | int r; | 612 | int r; |
613 | 613 | ||
614 | if (vm == NULL) { | 614 | if (vm == NULL) { |
@@ -619,8 +619,10 @@ int radeon_vm_alloc_pt(struct radeon_device *rdev, struct radeon_vm *vm) | |||
619 | return 0; | 619 | return 0; |
620 | } | 620 | } |
621 | 621 | ||
622 | retry: | ||
623 | pd_size = radeon_vm_directory_size(rdev); | 622 | pd_size = radeon_vm_directory_size(rdev); |
623 | pd_entries = radeon_vm_num_pdes(rdev); | ||
624 | |||
625 | retry: | ||
624 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, | 626 | r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, |
625 | &vm->page_directory, pd_size, | 627 | &vm->page_directory, pd_size, |
626 | RADEON_VM_PTB_ALIGN_SIZE, false); | 628 | RADEON_VM_PTB_ALIGN_SIZE, false); |
@@ -637,9 +639,31 @@ retry: | |||
637 | vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->page_directory); | 639 | vm->pd_gpu_addr = radeon_sa_bo_gpu_addr(vm->page_directory); |
638 | 640 | ||
639 | /* Initially clear the page directory */ | 641 | /* Initially clear the page directory */ |
640 | pd_addr = radeon_sa_bo_cpu_addr(vm->page_directory); | 642 | r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, |
641 | memset(pd_addr, 0, pd_size); | 643 | NULL, pd_entries * 2 + 64); |
644 | if (r) { | ||
645 | radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence); | ||
646 | return r; | ||
647 | } | ||
648 | |||
649 | ib.length_dw = 0; | ||
650 | |||
651 | radeon_asic_vm_set_page(rdev, &ib, vm->pd_gpu_addr, | ||
652 | 0, pd_entries, 0, 0); | ||
653 | |||
654 | radeon_ib_sync_to(&ib, vm->fence); | ||
655 | r = radeon_ib_schedule(rdev, &ib, NULL); | ||
656 | if (r) { | ||
657 | radeon_ib_free(rdev, &ib); | ||
658 | radeon_sa_bo_free(rdev, &vm->page_directory, vm->fence); | ||
659 | return r; | ||
660 | } | ||
661 | radeon_fence_unref(&vm->fence); | ||
662 | vm->fence = radeon_fence_ref(ib.fence); | ||
663 | radeon_ib_free(rdev, &ib); | ||
664 | radeon_fence_unref(&vm->last_flush); | ||
642 | 665 | ||
666 | /* allocate page table array */ | ||
643 | pts_size = radeon_vm_num_pdes(rdev) * sizeof(struct radeon_sa_bo *); | 667 | pts_size = radeon_vm_num_pdes(rdev) * sizeof(struct radeon_sa_bo *); |
644 | vm->page_tables = kzalloc(pts_size, GFP_KERNEL); | 668 | vm->page_tables = kzalloc(pts_size, GFP_KERNEL); |
645 | 669 | ||
@@ -914,6 +938,26 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) | |||
914 | } | 938 | } |
915 | 939 | ||
916 | /** | 940 | /** |
941 | * radeon_vm_page_flags - translate page flags to what the hw uses | ||
942 | * | ||
943 | * @flags: flags comming from userspace | ||
944 | * | ||
945 | * Translate the flags the userspace ABI uses to hw flags. | ||
946 | */ | ||
947 | static uint32_t radeon_vm_page_flags(uint32_t flags) | ||
948 | { | ||
949 | uint32_t hw_flags = 0; | ||
950 | hw_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0; | ||
951 | hw_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; | ||
952 | hw_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; | ||
953 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
954 | hw_flags |= R600_PTE_SYSTEM; | ||
955 | hw_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0; | ||
956 | } | ||
957 | return hw_flags; | ||
958 | } | ||
959 | |||
960 | /** | ||
917 | * radeon_vm_update_pdes - make sure that page directory is valid | 961 | * radeon_vm_update_pdes - make sure that page directory is valid |
918 | * | 962 | * |
919 | * @rdev: radeon_device pointer | 963 | * @rdev: radeon_device pointer |
@@ -974,7 +1018,11 @@ retry: | |||
974 | if (count) { | 1018 | if (count) { |
975 | radeon_asic_vm_set_page(rdev, ib, last_pde, | 1019 | radeon_asic_vm_set_page(rdev, ib, last_pde, |
976 | last_pt, count, incr, | 1020 | last_pt, count, incr, |
977 | RADEON_VM_PAGE_VALID); | 1021 | R600_PTE_VALID); |
1022 | |||
1023 | count *= RADEON_VM_PTE_COUNT; | ||
1024 | radeon_asic_vm_set_page(rdev, ib, last_pt, 0, | ||
1025 | count, 0, 0); | ||
978 | } | 1026 | } |
979 | 1027 | ||
980 | count = 1; | 1028 | count = 1; |
@@ -987,8 +1035,11 @@ retry: | |||
987 | 1035 | ||
988 | if (count) { | 1036 | if (count) { |
989 | radeon_asic_vm_set_page(rdev, ib, last_pde, last_pt, count, | 1037 | radeon_asic_vm_set_page(rdev, ib, last_pde, last_pt, count, |
990 | incr, RADEON_VM_PAGE_VALID); | 1038 | incr, R600_PTE_VALID); |
991 | 1039 | ||
1040 | count *= RADEON_VM_PTE_COUNT; | ||
1041 | radeon_asic_vm_set_page(rdev, ib, last_pt, 0, | ||
1042 | count, 0, 0); | ||
992 | } | 1043 | } |
993 | 1044 | ||
994 | return 0; | 1045 | return 0; |
@@ -1082,7 +1133,6 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
1082 | struct radeon_bo *bo, | 1133 | struct radeon_bo *bo, |
1083 | struct ttm_mem_reg *mem) | 1134 | struct ttm_mem_reg *mem) |
1084 | { | 1135 | { |
1085 | unsigned ridx = rdev->asic->vm.pt_ring_index; | ||
1086 | struct radeon_ib ib; | 1136 | struct radeon_ib ib; |
1087 | struct radeon_bo_va *bo_va; | 1137 | struct radeon_bo_va *bo_va; |
1088 | unsigned nptes, npdes, ndw; | 1138 | unsigned nptes, npdes, ndw; |
@@ -1151,11 +1201,14 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
1151 | /* reserve space for pde addresses */ | 1201 | /* reserve space for pde addresses */ |
1152 | ndw += npdes * 2; | 1202 | ndw += npdes * 2; |
1153 | 1203 | ||
1204 | /* reserve space for clearing new page tables */ | ||
1205 | ndw += npdes * 2 * RADEON_VM_PTE_COUNT; | ||
1206 | |||
1154 | /* update too big for an IB */ | 1207 | /* update too big for an IB */ |
1155 | if (ndw > 0xfffff) | 1208 | if (ndw > 0xfffff) |
1156 | return -ENOMEM; | 1209 | return -ENOMEM; |
1157 | 1210 | ||
1158 | r = radeon_ib_get(rdev, ridx, &ib, NULL, ndw * 4); | 1211 | r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, ndw * 4); |
1159 | ib.length_dw = 0; | 1212 | ib.length_dw = 0; |
1160 | 1213 | ||
1161 | r = radeon_vm_update_pdes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset); | 1214 | r = radeon_vm_update_pdes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset); |
@@ -1165,7 +1218,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
1165 | } | 1218 | } |
1166 | 1219 | ||
1167 | radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset, | 1220 | radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset, |
1168 | addr, bo_va->flags); | 1221 | addr, radeon_vm_page_flags(bo_va->flags)); |
1169 | 1222 | ||
1170 | radeon_ib_sync_to(&ib, vm->fence); | 1223 | radeon_ib_sync_to(&ib, vm->fence); |
1171 | r = radeon_ib_schedule(rdev, &ib, NULL); | 1224 | r = radeon_ib_schedule(rdev, &ib, NULL); |
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c index c180df8e84db..bdb0f93e73bc 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ b/drivers/gpu/drm/radeon/radeon_ioc32.c | |||
@@ -418,7 +418,7 @@ long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long | |||
418 | if (nr < DRM_COMMAND_BASE) | 418 | if (nr < DRM_COMMAND_BASE) |
419 | return drm_compat_ioctl(filp, cmd, arg); | 419 | return drm_compat_ioctl(filp, cmd, arg); |
420 | 420 | ||
421 | ret = drm_ioctl(filp, cmd, arg); | 421 | ret = radeon_drm_ioctl(filp, cmd, arg); |
422 | 422 | ||
423 | return ret; | 423 | return ret; |
424 | } | 424 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index cc9e8482cf30..ec6240b00469 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include "radeon.h" | 32 | #include "radeon.h" |
33 | #include "atom.h" | 33 | #include "atom.h" |
34 | 34 | ||
35 | #include <linux/pm_runtime.h> | ||
36 | |||
35 | #define RADEON_WAIT_IDLE_TIMEOUT 200 | 37 | #define RADEON_WAIT_IDLE_TIMEOUT 200 |
36 | 38 | ||
37 | /** | 39 | /** |
@@ -47,8 +49,12 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) | |||
47 | { | 49 | { |
48 | struct drm_device *dev = (struct drm_device *) arg; | 50 | struct drm_device *dev = (struct drm_device *) arg; |
49 | struct radeon_device *rdev = dev->dev_private; | 51 | struct radeon_device *rdev = dev->dev_private; |
52 | irqreturn_t ret; | ||
50 | 53 | ||
51 | return radeon_irq_process(rdev); | 54 | ret = radeon_irq_process(rdev); |
55 | if (ret == IRQ_HANDLED) | ||
56 | pm_runtime_mark_last_busy(dev->dev); | ||
57 | return ret; | ||
52 | } | 58 | } |
53 | 59 | ||
54 | /* | 60 | /* |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index d6b36766e8c9..bb8710531a1b 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/vga_switcheroo.h> | 33 | #include <linux/vga_switcheroo.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | 35 | #include <linux/pm_runtime.h> | |
36 | /** | 36 | /** |
37 | * radeon_driver_unload_kms - Main unload function for KMS. | 37 | * radeon_driver_unload_kms - Main unload function for KMS. |
38 | * | 38 | * |
@@ -50,9 +50,14 @@ int radeon_driver_unload_kms(struct drm_device *dev) | |||
50 | 50 | ||
51 | if (rdev == NULL) | 51 | if (rdev == NULL) |
52 | return 0; | 52 | return 0; |
53 | |||
53 | if (rdev->rmmio == NULL) | 54 | if (rdev->rmmio == NULL) |
54 | goto done_free; | 55 | goto done_free; |
56 | |||
57 | pm_runtime_get_sync(dev->dev); | ||
58 | |||
55 | radeon_acpi_fini(rdev); | 59 | radeon_acpi_fini(rdev); |
60 | |||
56 | radeon_modeset_fini(rdev); | 61 | radeon_modeset_fini(rdev); |
57 | radeon_device_fini(rdev); | 62 | radeon_device_fini(rdev); |
58 | 63 | ||
@@ -125,9 +130,20 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
125 | "Error during ACPI methods call\n"); | 130 | "Error during ACPI methods call\n"); |
126 | } | 131 | } |
127 | 132 | ||
133 | if (radeon_runtime_pm != 0) { | ||
134 | pm_runtime_use_autosuspend(dev->dev); | ||
135 | pm_runtime_set_autosuspend_delay(dev->dev, 5000); | ||
136 | pm_runtime_set_active(dev->dev); | ||
137 | pm_runtime_allow(dev->dev); | ||
138 | pm_runtime_mark_last_busy(dev->dev); | ||
139 | pm_runtime_put_autosuspend(dev->dev); | ||
140 | } | ||
141 | |||
128 | out: | 142 | out: |
129 | if (r) | 143 | if (r) |
130 | radeon_driver_unload_kms(dev); | 144 | radeon_driver_unload_kms(dev); |
145 | |||
146 | |||
131 | return r; | 147 | return r; |
132 | } | 148 | } |
133 | 149 | ||
@@ -475,9 +491,14 @@ void radeon_driver_lastclose_kms(struct drm_device *dev) | |||
475 | int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | 491 | int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) |
476 | { | 492 | { |
477 | struct radeon_device *rdev = dev->dev_private; | 493 | struct radeon_device *rdev = dev->dev_private; |
494 | int r; | ||
478 | 495 | ||
479 | file_priv->driver_priv = NULL; | 496 | file_priv->driver_priv = NULL; |
480 | 497 | ||
498 | r = pm_runtime_get_sync(dev->dev); | ||
499 | if (r < 0) | ||
500 | return r; | ||
501 | |||
481 | /* new gpu have virtual address space support */ | 502 | /* new gpu have virtual address space support */ |
482 | if (rdev->family >= CHIP_CAYMAN) { | 503 | if (rdev->family >= CHIP_CAYMAN) { |
483 | struct radeon_fpriv *fpriv; | 504 | struct radeon_fpriv *fpriv; |
@@ -506,6 +527,9 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
506 | 527 | ||
507 | file_priv->driver_priv = fpriv; | 528 | file_priv->driver_priv = fpriv; |
508 | } | 529 | } |
530 | |||
531 | pm_runtime_mark_last_busy(dev->dev); | ||
532 | pm_runtime_put_autosuspend(dev->dev); | ||
509 | return 0; | 533 | return 0; |
510 | } | 534 | } |
511 | 535 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index ef63d3f00b2f..8b4e712c1e5c 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -249,6 +249,8 @@ struct radeon_mode_info { | |||
249 | struct drm_property *underscan_vborder_property; | 249 | struct drm_property *underscan_vborder_property; |
250 | /* audio */ | 250 | /* audio */ |
251 | struct drm_property *audio_property; | 251 | struct drm_property *audio_property; |
252 | /* FMT dithering */ | ||
253 | struct drm_property *dither_property; | ||
252 | /* hardcoded DFP edid from BIOS */ | 254 | /* hardcoded DFP edid from BIOS */ |
253 | struct edid *bios_hardcoded_edid; | 255 | struct edid *bios_hardcoded_edid; |
254 | int bios_hardcoded_edid_size; | 256 | int bios_hardcoded_edid_size; |
@@ -479,6 +481,11 @@ enum radeon_connector_audio { | |||
479 | RADEON_AUDIO_AUTO = 2 | 481 | RADEON_AUDIO_AUTO = 2 |
480 | }; | 482 | }; |
481 | 483 | ||
484 | enum radeon_connector_dither { | ||
485 | RADEON_FMT_DITHER_DISABLE = 0, | ||
486 | RADEON_FMT_DITHER_ENABLE = 1, | ||
487 | }; | ||
488 | |||
482 | struct radeon_connector { | 489 | struct radeon_connector { |
483 | struct drm_connector base; | 490 | struct drm_connector base; |
484 | uint32_t connector_id; | 491 | uint32_t connector_id; |
@@ -498,6 +505,7 @@ struct radeon_connector { | |||
498 | struct radeon_router router; | 505 | struct radeon_router router; |
499 | struct radeon_i2c_chan *router_bus; | 506 | struct radeon_i2c_chan *router_bus; |
500 | enum radeon_connector_audio audio; | 507 | enum radeon_connector_audio audio; |
508 | enum radeon_connector_dither dither; | ||
501 | }; | 509 | }; |
502 | 510 | ||
503 | struct radeon_framebuffer { | 511 | struct radeon_framebuffer { |
@@ -850,6 +858,12 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, | |||
850 | struct drm_display_mode *mode, | 858 | struct drm_display_mode *mode, |
851 | struct drm_display_mode *adjusted_mode); | 859 | struct drm_display_mode *adjusted_mode); |
852 | 860 | ||
861 | /* fmt blocks */ | ||
862 | void avivo_program_fmt(struct drm_encoder *encoder); | ||
863 | void dce3_program_fmt(struct drm_encoder *encoder); | ||
864 | void dce4_program_fmt(struct drm_encoder *encoder); | ||
865 | void dce8_program_fmt(struct drm_encoder *encoder); | ||
866 | |||
853 | /* fbdev layer */ | 867 | /* fbdev layer */ |
854 | int radeon_fbdev_init(struct radeon_device *rdev); | 868 | int radeon_fbdev_init(struct radeon_device *rdev); |
855 | void radeon_fbdev_fini(struct radeon_device *rdev); | 869 | void radeon_fbdev_fini(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index ac07ad1d4f8c..2baa0fa75e36 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -508,17 +508,21 @@ static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev, | |||
508 | } else if (strncmp("auto", buf, strlen("auto")) == 0) { | 508 | } else if (strncmp("auto", buf, strlen("auto")) == 0) { |
509 | level = RADEON_DPM_FORCED_LEVEL_AUTO; | 509 | level = RADEON_DPM_FORCED_LEVEL_AUTO; |
510 | } else { | 510 | } else { |
511 | mutex_unlock(&rdev->pm.mutex); | ||
512 | count = -EINVAL; | 511 | count = -EINVAL; |
513 | goto fail; | 512 | goto fail; |
514 | } | 513 | } |
515 | if (rdev->asic->dpm.force_performance_level) { | 514 | if (rdev->asic->dpm.force_performance_level) { |
515 | if (rdev->pm.dpm.thermal_active) { | ||
516 | count = -EINVAL; | ||
517 | goto fail; | ||
518 | } | ||
516 | ret = radeon_dpm_force_performance_level(rdev, level); | 519 | ret = radeon_dpm_force_performance_level(rdev, level); |
517 | if (ret) | 520 | if (ret) |
518 | count = -EINVAL; | 521 | count = -EINVAL; |
519 | } | 522 | } |
520 | mutex_unlock(&rdev->pm.mutex); | ||
521 | fail: | 523 | fail: |
524 | mutex_unlock(&rdev->pm.mutex); | ||
525 | |||
522 | return count; | 526 | return count; |
523 | } | 527 | } |
524 | 528 | ||
@@ -881,11 +885,12 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) | |||
881 | } | 885 | } |
882 | } | 886 | } |
883 | 887 | ||
884 | printk("switching from power state:\n"); | 888 | if (radeon_dpm == 1) { |
885 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); | 889 | printk("switching from power state:\n"); |
886 | printk("switching to power state:\n"); | 890 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); |
887 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps); | 891 | printk("switching to power state:\n"); |
888 | 892 | radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps); | |
893 | } | ||
889 | mutex_lock(&rdev->ddev->struct_mutex); | 894 | mutex_lock(&rdev->ddev->struct_mutex); |
890 | down_write(&rdev->pm.mclk_lock); | 895 | down_write(&rdev->pm.mclk_lock); |
891 | mutex_lock(&rdev->ring_lock); | 896 | mutex_lock(&rdev->ring_lock); |
@@ -918,12 +923,16 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) | |||
918 | radeon_dpm_post_set_power_state(rdev); | 923 | radeon_dpm_post_set_power_state(rdev); |
919 | 924 | ||
920 | if (rdev->asic->dpm.force_performance_level) { | 925 | if (rdev->asic->dpm.force_performance_level) { |
921 | if (rdev->pm.dpm.thermal_active) | 926 | if (rdev->pm.dpm.thermal_active) { |
927 | enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; | ||
922 | /* force low perf level for thermal */ | 928 | /* force low perf level for thermal */ |
923 | radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_LOW); | 929 | radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_LOW); |
924 | else | 930 | /* save the user's level */ |
925 | /* otherwise, enable auto */ | 931 | rdev->pm.dpm.forced_level = level; |
926 | radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); | 932 | } else { |
933 | /* otherwise, user selected level */ | ||
934 | radeon_dpm_force_performance_level(rdev, rdev->pm.dpm.forced_level); | ||
935 | } | ||
927 | } | 936 | } |
928 | 937 | ||
929 | done: | 938 | done: |
@@ -1176,7 +1185,8 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) | |||
1176 | mutex_lock(&rdev->pm.mutex); | 1185 | mutex_lock(&rdev->pm.mutex); |
1177 | radeon_dpm_init(rdev); | 1186 | radeon_dpm_init(rdev); |
1178 | rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps; | 1187 | rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps; |
1179 | radeon_dpm_print_power_states(rdev); | 1188 | if (radeon_dpm == 1) |
1189 | radeon_dpm_print_power_states(rdev); | ||
1180 | radeon_dpm_setup_asic(rdev); | 1190 | radeon_dpm_setup_asic(rdev); |
1181 | ret = radeon_dpm_enable(rdev); | 1191 | ret = radeon_dpm_enable(rdev); |
1182 | mutex_unlock(&rdev->pm.mutex); | 1192 | mutex_unlock(&rdev->pm.mutex); |
@@ -1238,6 +1248,23 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1238 | case CHIP_RV670: | 1248 | case CHIP_RV670: |
1239 | case CHIP_RS780: | 1249 | case CHIP_RS780: |
1240 | case CHIP_RS880: | 1250 | case CHIP_RS880: |
1251 | case CHIP_CAYMAN: | ||
1252 | case CHIP_ARUBA: | ||
1253 | case CHIP_BONAIRE: | ||
1254 | case CHIP_KABINI: | ||
1255 | case CHIP_KAVERI: | ||
1256 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ | ||
1257 | if (!rdev->rlc_fw) | ||
1258 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
1259 | else if ((rdev->family >= CHIP_RV770) && | ||
1260 | (!(rdev->flags & RADEON_IS_IGP)) && | ||
1261 | (!rdev->smc_fw)) | ||
1262 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
1263 | else if (radeon_dpm == 1) | ||
1264 | rdev->pm.pm_method = PM_METHOD_DPM; | ||
1265 | else | ||
1266 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
1267 | break; | ||
1241 | case CHIP_RV770: | 1268 | case CHIP_RV770: |
1242 | case CHIP_RV730: | 1269 | case CHIP_RV730: |
1243 | case CHIP_RV710: | 1270 | case CHIP_RV710: |
@@ -1253,16 +1280,11 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1253 | case CHIP_BARTS: | 1280 | case CHIP_BARTS: |
1254 | case CHIP_TURKS: | 1281 | case CHIP_TURKS: |
1255 | case CHIP_CAICOS: | 1282 | case CHIP_CAICOS: |
1256 | case CHIP_CAYMAN: | ||
1257 | case CHIP_ARUBA: | ||
1258 | case CHIP_TAHITI: | 1283 | case CHIP_TAHITI: |
1259 | case CHIP_PITCAIRN: | 1284 | case CHIP_PITCAIRN: |
1260 | case CHIP_VERDE: | 1285 | case CHIP_VERDE: |
1261 | case CHIP_OLAND: | 1286 | case CHIP_OLAND: |
1262 | case CHIP_HAINAN: | 1287 | case CHIP_HAINAN: |
1263 | case CHIP_BONAIRE: | ||
1264 | case CHIP_KABINI: | ||
1265 | case CHIP_KAVERI: | ||
1266 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ | 1288 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ |
1267 | if (!rdev->rlc_fw) | 1289 | if (!rdev->rlc_fw) |
1268 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1290 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
@@ -1270,10 +1292,10 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1270 | (!(rdev->flags & RADEON_IS_IGP)) && | 1292 | (!(rdev->flags & RADEON_IS_IGP)) && |
1271 | (!rdev->smc_fw)) | 1293 | (!rdev->smc_fw)) |
1272 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1294 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1273 | else if (radeon_dpm == 1) | 1295 | else if (radeon_dpm == 0) |
1274 | rdev->pm.pm_method = PM_METHOD_DPM; | ||
1275 | else | ||
1276 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1296 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1297 | else | ||
1298 | rdev->pm.pm_method = PM_METHOD_DPM; | ||
1277 | break; | 1299 | break; |
1278 | default: | 1300 | default: |
1279 | /* default to profile method */ | 1301 | /* default to profile method */ |
diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h index f7e367815964..811bca691b36 100644 --- a/drivers/gpu/drm/radeon/radeon_trace.h +++ b/drivers/gpu/drm/radeon/radeon_trace.h | |||
@@ -47,6 +47,30 @@ TRACE_EVENT(radeon_cs, | |||
47 | __entry->fences) | 47 | __entry->fences) |
48 | ); | 48 | ); |
49 | 49 | ||
50 | TRACE_EVENT(radeon_vm_set_page, | ||
51 | TP_PROTO(uint64_t pe, uint64_t addr, unsigned count, | ||
52 | uint32_t incr, uint32_t flags), | ||
53 | TP_ARGS(pe, addr, count, incr, flags), | ||
54 | TP_STRUCT__entry( | ||
55 | __field(u64, pe) | ||
56 | __field(u64, addr) | ||
57 | __field(u32, count) | ||
58 | __field(u32, incr) | ||
59 | __field(u32, flags) | ||
60 | ), | ||
61 | |||
62 | TP_fast_assign( | ||
63 | __entry->pe = pe; | ||
64 | __entry->addr = addr; | ||
65 | __entry->count = count; | ||
66 | __entry->incr = incr; | ||
67 | __entry->flags = flags; | ||
68 | ), | ||
69 | TP_printk("pe=%010Lx, addr=%010Lx, incr=%u, flags=%08x, count=%u", | ||
70 | __entry->pe, __entry->addr, __entry->incr, | ||
71 | __entry->flags, __entry->count) | ||
72 | ); | ||
73 | |||
50 | DECLARE_EVENT_CLASS(radeon_fence_request, | 74 | DECLARE_EVENT_CLASS(radeon_fence_request, |
51 | 75 | ||
52 | TP_PROTO(struct drm_device *dev, u32 seqno), | 76 | TP_PROTO(struct drm_device *dev, u32 seqno), |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index a0f11856ddde..234b2a3b8add 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -240,6 +240,8 @@ void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp) | |||
240 | if (handle != 0 && rdev->uvd.filp[i] == filp) { | 240 | if (handle != 0 && rdev->uvd.filp[i] == filp) { |
241 | struct radeon_fence *fence; | 241 | struct radeon_fence *fence; |
242 | 242 | ||
243 | radeon_uvd_note_usage(rdev); | ||
244 | |||
243 | r = radeon_uvd_get_destroy_msg(rdev, | 245 | r = radeon_uvd_get_destroy_msg(rdev, |
244 | R600_RING_TYPE_UVD_INDEX, handle, &fence); | 246 | R600_RING_TYPE_UVD_INDEX, handle, &fence); |
245 | if (r) { | 247 | if (r) { |
@@ -619,7 +621,7 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev, | |||
619 | if (r) | 621 | if (r) |
620 | goto err; | 622 | goto err; |
621 | 623 | ||
622 | r = radeon_ib_get(rdev, ring, &ib, NULL, 16); | 624 | r = radeon_ib_get(rdev, ring, &ib, NULL, 64); |
623 | if (r) | 625 | if (r) |
624 | goto err; | 626 | goto err; |
625 | 627 | ||
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 6acba8017b9a..76cc8d3aafec 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -153,6 +153,70 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
153 | return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; | 153 | return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; |
154 | } | 154 | } |
155 | 155 | ||
156 | void avivo_program_fmt(struct drm_encoder *encoder) | ||
157 | { | ||
158 | struct drm_device *dev = encoder->dev; | ||
159 | struct radeon_device *rdev = dev->dev_private; | ||
160 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
161 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
162 | int bpc = 0; | ||
163 | u32 tmp = 0; | ||
164 | enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE; | ||
165 | |||
166 | if (connector) { | ||
167 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
168 | bpc = radeon_get_monitor_bpc(connector); | ||
169 | dither = radeon_connector->dither; | ||
170 | } | ||
171 | |||
172 | /* LVDS FMT is set up by atom */ | ||
173 | if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) | ||
174 | return; | ||
175 | |||
176 | if (bpc == 0) | ||
177 | return; | ||
178 | |||
179 | switch (bpc) { | ||
180 | case 6: | ||
181 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
182 | /* XXX sort out optimal dither settings */ | ||
183 | tmp |= AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; | ||
184 | else | ||
185 | tmp |= AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN; | ||
186 | break; | ||
187 | case 8: | ||
188 | if (dither == RADEON_FMT_DITHER_ENABLE) | ||
189 | /* XXX sort out optimal dither settings */ | ||
190 | tmp |= (AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN | | ||
191 | AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH); | ||
192 | else | ||
193 | tmp |= (AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN | | ||
194 | AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH); | ||
195 | break; | ||
196 | case 10: | ||
197 | default: | ||
198 | /* not needed */ | ||
199 | break; | ||
200 | } | ||
201 | |||
202 | switch (radeon_encoder->encoder_id) { | ||
203 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
204 | WREG32(AVIVO_TMDSA_BIT_DEPTH_CONTROL, tmp); | ||
205 | break; | ||
206 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
207 | WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, tmp); | ||
208 | break; | ||
209 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
210 | WREG32(AVIVO_DVOA_BIT_DEPTH_CONTROL, tmp); | ||
211 | break; | ||
212 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
213 | WREG32(AVIVO_DDIA_BIT_DEPTH_CONTROL, tmp); | ||
214 | break; | ||
215 | default: | ||
216 | break; | ||
217 | } | ||
218 | } | ||
219 | |||
156 | void rs600_pm_misc(struct radeon_device *rdev) | 220 | void rs600_pm_misc(struct radeon_device *rdev) |
157 | { | 221 | { |
158 | int requested_index = rdev->pm.requested_power_state_index; | 222 | int requested_index = rdev->pm.requested_power_state_index; |
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index 5811d277a36a..26633a025252 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c | |||
@@ -407,9 +407,9 @@ static void rv6xx_enable_engine_feedback_and_reference_sync(struct radeon_device | |||
407 | WREG32_P(SPLL_CNTL_MODE, SPLL_DIV_SYNC, ~SPLL_DIV_SYNC); | 407 | WREG32_P(SPLL_CNTL_MODE, SPLL_DIV_SYNC, ~SPLL_DIV_SYNC); |
408 | } | 408 | } |
409 | 409 | ||
410 | static u64 rv6xx_clocks_per_unit(u32 unit) | 410 | static u32 rv6xx_clocks_per_unit(u32 unit) |
411 | { | 411 | { |
412 | u64 tmp = 1 << (2 * unit); | 412 | u32 tmp = 1 << (2 * unit); |
413 | 413 | ||
414 | return tmp; | 414 | return tmp; |
415 | } | 415 | } |
@@ -417,7 +417,7 @@ static u64 rv6xx_clocks_per_unit(u32 unit) | |||
417 | static u32 rv6xx_scale_count_given_unit(struct radeon_device *rdev, | 417 | static u32 rv6xx_scale_count_given_unit(struct radeon_device *rdev, |
418 | u32 unscaled_count, u32 unit) | 418 | u32 unscaled_count, u32 unit) |
419 | { | 419 | { |
420 | u32 count_per_unit = (u32)rv6xx_clocks_per_unit(unit); | 420 | u32 count_per_unit = rv6xx_clocks_per_unit(unit); |
421 | 421 | ||
422 | return (unscaled_count + count_per_unit - 1) / count_per_unit; | 422 | return (unscaled_count + count_per_unit - 1) / count_per_unit; |
423 | } | 423 | } |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c354c1094967..2acfe561796f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -78,11 +78,6 @@ extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ | |||
78 | extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); | 78 | extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); |
79 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); | 79 | extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); |
80 | extern bool evergreen_is_display_hung(struct radeon_device *rdev); | 80 | extern bool evergreen_is_display_hung(struct radeon_device *rdev); |
81 | extern void si_dma_vm_set_page(struct radeon_device *rdev, | ||
82 | struct radeon_ib *ib, | ||
83 | uint64_t pe, | ||
84 | uint64_t addr, unsigned count, | ||
85 | uint32_t incr, uint32_t flags); | ||
86 | static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, | 81 | static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, |
87 | bool enable); | 82 | bool enable); |
88 | 83 | ||
@@ -4662,61 +4657,6 @@ static void si_vm_decode_fault(struct radeon_device *rdev, | |||
4662 | block, mc_id); | 4657 | block, mc_id); |
4663 | } | 4658 | } |
4664 | 4659 | ||
4665 | /** | ||
4666 | * si_vm_set_page - update the page tables using the CP | ||
4667 | * | ||
4668 | * @rdev: radeon_device pointer | ||
4669 | * @ib: indirect buffer to fill with commands | ||
4670 | * @pe: addr of the page entry | ||
4671 | * @addr: dst addr to write into pe | ||
4672 | * @count: number of page entries to update | ||
4673 | * @incr: increase next addr by incr bytes | ||
4674 | * @flags: access flags | ||
4675 | * | ||
4676 | * Update the page tables using the CP (SI). | ||
4677 | */ | ||
4678 | void si_vm_set_page(struct radeon_device *rdev, | ||
4679 | struct radeon_ib *ib, | ||
4680 | uint64_t pe, | ||
4681 | uint64_t addr, unsigned count, | ||
4682 | uint32_t incr, uint32_t flags) | ||
4683 | { | ||
4684 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | ||
4685 | uint64_t value; | ||
4686 | unsigned ndw; | ||
4687 | |||
4688 | if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { | ||
4689 | while (count) { | ||
4690 | ndw = 2 + count * 2; | ||
4691 | if (ndw > 0x3FFE) | ||
4692 | ndw = 0x3FFE; | ||
4693 | |||
4694 | ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw); | ||
4695 | ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) | | ||
4696 | WRITE_DATA_DST_SEL(1)); | ||
4697 | ib->ptr[ib->length_dw++] = pe; | ||
4698 | ib->ptr[ib->length_dw++] = upper_32_bits(pe); | ||
4699 | for (; ndw > 2; ndw -= 2, --count, pe += 8) { | ||
4700 | if (flags & RADEON_VM_PAGE_SYSTEM) { | ||
4701 | value = radeon_vm_map_gart(rdev, addr); | ||
4702 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
4703 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
4704 | value = addr; | ||
4705 | } else { | ||
4706 | value = 0; | ||
4707 | } | ||
4708 | addr += incr; | ||
4709 | value |= r600_flags; | ||
4710 | ib->ptr[ib->length_dw++] = value; | ||
4711 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | ||
4712 | } | ||
4713 | } | ||
4714 | } else { | ||
4715 | /* DMA */ | ||
4716 | si_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); | ||
4717 | } | ||
4718 | } | ||
4719 | |||
4720 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | 4660 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) |
4721 | { | 4661 | { |
4722 | struct radeon_ring *ring = &rdev->ring[ridx]; | 4662 | struct radeon_ring *ring = &rdev->ring[ridx]; |
@@ -5361,52 +5301,53 @@ void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) | |||
5361 | if (buffer == NULL) | 5301 | if (buffer == NULL) |
5362 | return; | 5302 | return; |
5363 | 5303 | ||
5364 | buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); | 5304 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); |
5365 | buffer[count++] = PACKET3_PREAMBLE_BEGIN_CLEAR_STATE; | 5305 | buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); |
5366 | 5306 | ||
5367 | buffer[count++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1); | 5307 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); |
5368 | buffer[count++] = 0x80000000; | 5308 | buffer[count++] = cpu_to_le32(0x80000000); |
5369 | buffer[count++] = 0x80000000; | 5309 | buffer[count++] = cpu_to_le32(0x80000000); |
5370 | 5310 | ||
5371 | for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { | 5311 | for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { |
5372 | for (ext = sect->section; ext->extent != NULL; ++ext) { | 5312 | for (ext = sect->section; ext->extent != NULL; ++ext) { |
5373 | if (sect->id == SECT_CONTEXT) { | 5313 | if (sect->id == SECT_CONTEXT) { |
5374 | buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count); | 5314 | buffer[count++] = |
5375 | buffer[count++] = ext->reg_index - 0xa000; | 5315 | cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); |
5316 | buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000); | ||
5376 | for (i = 0; i < ext->reg_count; i++) | 5317 | for (i = 0; i < ext->reg_count; i++) |
5377 | buffer[count++] = ext->extent[i]; | 5318 | buffer[count++] = cpu_to_le32(ext->extent[i]); |
5378 | } else { | 5319 | } else { |
5379 | return; | 5320 | return; |
5380 | } | 5321 | } |
5381 | } | 5322 | } |
5382 | } | 5323 | } |
5383 | 5324 | ||
5384 | buffer[count++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); | 5325 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1)); |
5385 | buffer[count++] = PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START; | 5326 | buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); |
5386 | switch (rdev->family) { | 5327 | switch (rdev->family) { |
5387 | case CHIP_TAHITI: | 5328 | case CHIP_TAHITI: |
5388 | case CHIP_PITCAIRN: | 5329 | case CHIP_PITCAIRN: |
5389 | buffer[count++] = 0x2a00126a; | 5330 | buffer[count++] = cpu_to_le32(0x2a00126a); |
5390 | break; | 5331 | break; |
5391 | case CHIP_VERDE: | 5332 | case CHIP_VERDE: |
5392 | buffer[count++] = 0x0000124a; | 5333 | buffer[count++] = cpu_to_le32(0x0000124a); |
5393 | break; | 5334 | break; |
5394 | case CHIP_OLAND: | 5335 | case CHIP_OLAND: |
5395 | buffer[count++] = 0x00000082; | 5336 | buffer[count++] = cpu_to_le32(0x00000082); |
5396 | break; | 5337 | break; |
5397 | case CHIP_HAINAN: | 5338 | case CHIP_HAINAN: |
5398 | buffer[count++] = 0x00000000; | 5339 | buffer[count++] = cpu_to_le32(0x00000000); |
5399 | break; | 5340 | break; |
5400 | default: | 5341 | default: |
5401 | buffer[count++] = 0x00000000; | 5342 | buffer[count++] = cpu_to_le32(0x00000000); |
5402 | break; | 5343 | break; |
5403 | } | 5344 | } |
5404 | 5345 | ||
5405 | buffer[count++] = PACKET3(PACKET3_PREAMBLE_CNTL, 0); | 5346 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); |
5406 | buffer[count++] = PACKET3_PREAMBLE_END_CLEAR_STATE; | 5347 | buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); |
5407 | 5348 | ||
5408 | buffer[count++] = PACKET3(PACKET3_CLEAR_STATE, 0); | 5349 | buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); |
5409 | buffer[count++] = 0; | 5350 | buffer[count++] = cpu_to_le32(0); |
5410 | } | 5351 | } |
5411 | 5352 | ||
5412 | static void si_init_pg(struct radeon_device *rdev) | 5353 | static void si_init_pg(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index 49909d23dfce..8e8f46133532 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <drm/drmP.h> | 24 | #include <drm/drmP.h> |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_asic.h" | 26 | #include "radeon_asic.h" |
27 | #include "radeon_trace.h" | ||
27 | #include "sid.h" | 28 | #include "sid.h" |
28 | 29 | ||
29 | u32 si_gpu_check_soft_reset(struct radeon_device *rdev); | 30 | u32 si_gpu_check_soft_reset(struct radeon_device *rdev); |
@@ -75,11 +76,12 @@ void si_dma_vm_set_page(struct radeon_device *rdev, | |||
75 | uint64_t addr, unsigned count, | 76 | uint64_t addr, unsigned count, |
76 | uint32_t incr, uint32_t flags) | 77 | uint32_t incr, uint32_t flags) |
77 | { | 78 | { |
78 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); | ||
79 | uint64_t value; | 79 | uint64_t value; |
80 | unsigned ndw; | 80 | unsigned ndw; |
81 | 81 | ||
82 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 82 | trace_radeon_vm_set_page(pe, addr, count, incr, flags); |
83 | |||
84 | if (flags & R600_PTE_SYSTEM) { | ||
83 | while (count) { | 85 | while (count) { |
84 | ndw = count * 2; | 86 | ndw = count * 2; |
85 | if (ndw > 0xFFFFE) | 87 | if (ndw > 0xFFFFE) |
@@ -90,16 +92,10 @@ void si_dma_vm_set_page(struct radeon_device *rdev, | |||
90 | ib->ptr[ib->length_dw++] = pe; | 92 | ib->ptr[ib->length_dw++] = pe; |
91 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; | 93 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; |
92 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { | 94 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
93 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 95 | value = radeon_vm_map_gart(rdev, addr); |
94 | value = radeon_vm_map_gart(rdev, addr); | 96 | value &= 0xFFFFFFFFFFFFF000ULL; |
95 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
96 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
97 | value = addr; | ||
98 | } else { | ||
99 | value = 0; | ||
100 | } | ||
101 | addr += incr; | 97 | addr += incr; |
102 | value |= r600_flags; | 98 | value |= flags; |
103 | ib->ptr[ib->length_dw++] = value; | 99 | ib->ptr[ib->length_dw++] = value; |
104 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | 100 | ib->ptr[ib->length_dw++] = upper_32_bits(value); |
105 | } | 101 | } |
@@ -110,7 +106,7 @@ void si_dma_vm_set_page(struct radeon_device *rdev, | |||
110 | if (ndw > 0xFFFFE) | 106 | if (ndw > 0xFFFFE) |
111 | ndw = 0xFFFFE; | 107 | ndw = 0xFFFFE; |
112 | 108 | ||
113 | if (flags & RADEON_VM_PAGE_VALID) | 109 | if (flags & R600_PTE_VALID) |
114 | value = addr; | 110 | value = addr; |
115 | else | 111 | else |
116 | value = 0; | 112 | value = 0; |
@@ -118,7 +114,7 @@ void si_dma_vm_set_page(struct radeon_device *rdev, | |||
118 | ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); | 114 | ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); |
119 | ib->ptr[ib->length_dw++] = pe; /* dst addr */ | 115 | ib->ptr[ib->length_dw++] = pe; /* dst addr */ |
120 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; | 116 | ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; |
121 | ib->ptr[ib->length_dw++] = r600_flags; /* mask */ | 117 | ib->ptr[ib->length_dw++] = flags; /* mask */ |
122 | ib->ptr[ib->length_dw++] = 0; | 118 | ib->ptr[ib->length_dw++] = 0; |
123 | ib->ptr[ib->length_dw++] = value; /* value */ | 119 | ib->ptr[ib->length_dw++] = value; /* value */ |
124 | ib->ptr[ib->length_dw++] = upper_32_bits(value); | 120 | ib->ptr[ib->length_dw++] = upper_32_bits(value); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 9ace28702c76..a24ada406046 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -3589,7 +3589,12 @@ static void si_program_display_gap(struct radeon_device *rdev) | |||
3589 | WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp); | 3589 | WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp); |
3590 | } | 3590 | } |
3591 | 3591 | ||
3592 | si_notify_smc_display_change(rdev, rdev->pm.dpm.new_active_crtc_count > 0); | 3592 | /* Setting this to false forces the performance state to low if the crtcs are disabled. |
3593 | * This can be a problem on PowerXpress systems or if you want to use the card | ||
3594 | * for offscreen rendering or compute if there are no crtcs enabled. Set it to | ||
3595 | * true for now so that performance scales even if the displays are off. | ||
3596 | */ | ||
3597 | si_notify_smc_display_change(rdev, true /*rdev->pm.dpm.new_active_crtc_count > 0*/); | ||
3593 | } | 3598 | } |
3594 | 3599 | ||
3595 | static void si_enable_spread_spectrum(struct radeon_device *rdev, bool enable) | 3600 | static void si_enable_spread_spectrum(struct radeon_device *rdev, bool enable) |
@@ -4553,7 +4558,7 @@ static int si_init_smc_table(struct radeon_device *rdev) | |||
4553 | table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5; | 4558 | table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5; |
4554 | 4559 | ||
4555 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY) | 4560 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY) |
4556 | table->systemFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH; | 4561 | table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH; |
4557 | 4562 | ||
4558 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) { | 4563 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) { |
4559 | table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO; | 4564 | table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO; |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 52d2ab6b67a0..5691a7c30686 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -478,7 +478,7 @@ | |||
478 | #define STATE3_MASK (0x1f << 15) | 478 | #define STATE3_MASK (0x1f << 15) |
479 | #define STATE3_SHIFT 15 | 479 | #define STATE3_SHIFT 15 |
480 | 480 | ||
481 | #define MC_SEQ_TRAIN_WAKEUP_CNTL 0x2808 | 481 | #define MC_SEQ_TRAIN_WAKEUP_CNTL 0x28e8 |
482 | #define TRAIN_DONE_D0 (1 << 30) | 482 | #define TRAIN_DONE_D0 (1 << 30) |
483 | #define TRAIN_DONE_D1 (1 << 31) | 483 | #define TRAIN_DONE_D1 (1 << 31) |
484 | 484 | ||
@@ -683,6 +683,51 @@ | |||
683 | * bit5 = 176.4 kHz | 683 | * bit5 = 176.4 kHz |
684 | * bit6 = 192 kHz | 684 | * bit6 = 192 kHz |
685 | */ | 685 | */ |
686 | |||
687 | #define AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC 0x37 | ||
688 | # define VIDEO_LIPSYNC(x) (((x) & 0xff) << 0) | ||
689 | # define AUDIO_LIPSYNC(x) (((x) & 0xff) << 8) | ||
690 | /* VIDEO_LIPSYNC, AUDIO_LIPSYNC | ||
691 | * 0 = invalid | ||
692 | * x = legal delay value | ||
693 | * 255 = sync not supported | ||
694 | */ | ||
695 | #define AZ_F0_CODEC_PIN_CONTROL_RESPONSE_HBR 0x38 | ||
696 | # define HBR_CAPABLE (1 << 0) /* enabled by default */ | ||
697 | |||
698 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO0 0x3a | ||
699 | # define MANUFACTURER_ID(x) (((x) & 0xffff) << 0) | ||
700 | # define PRODUCT_ID(x) (((x) & 0xffff) << 16) | ||
701 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO1 0x3b | ||
702 | # define SINK_DESCRIPTION_LEN(x) (((x) & 0xff) << 0) | ||
703 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO2 0x3c | ||
704 | # define PORT_ID0(x) (((x) & 0xffffffff) << 0) | ||
705 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO3 0x3d | ||
706 | # define PORT_ID1(x) (((x) & 0xffffffff) << 0) | ||
707 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO4 0x3e | ||
708 | # define DESCRIPTION0(x) (((x) & 0xff) << 0) | ||
709 | # define DESCRIPTION1(x) (((x) & 0xff) << 8) | ||
710 | # define DESCRIPTION2(x) (((x) & 0xff) << 16) | ||
711 | # define DESCRIPTION3(x) (((x) & 0xff) << 24) | ||
712 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO5 0x3f | ||
713 | # define DESCRIPTION4(x) (((x) & 0xff) << 0) | ||
714 | # define DESCRIPTION5(x) (((x) & 0xff) << 8) | ||
715 | # define DESCRIPTION6(x) (((x) & 0xff) << 16) | ||
716 | # define DESCRIPTION7(x) (((x) & 0xff) << 24) | ||
717 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO6 0x40 | ||
718 | # define DESCRIPTION8(x) (((x) & 0xff) << 0) | ||
719 | # define DESCRIPTION9(x) (((x) & 0xff) << 8) | ||
720 | # define DESCRIPTION10(x) (((x) & 0xff) << 16) | ||
721 | # define DESCRIPTION11(x) (((x) & 0xff) << 24) | ||
722 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO7 0x41 | ||
723 | # define DESCRIPTION12(x) (((x) & 0xff) << 0) | ||
724 | # define DESCRIPTION13(x) (((x) & 0xff) << 8) | ||
725 | # define DESCRIPTION14(x) (((x) & 0xff) << 16) | ||
726 | # define DESCRIPTION15(x) (((x) & 0xff) << 24) | ||
727 | #define AZ_F0_CODEC_PIN_CONTROL_SINK_INFO8 0x42 | ||
728 | # define DESCRIPTION16(x) (((x) & 0xff) << 0) | ||
729 | # define DESCRIPTION17(x) (((x) & 0xff) << 8) | ||
730 | |||
686 | #define AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL 0x54 | 731 | #define AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL 0x54 |
687 | # define AUDIO_ENABLED (1 << 31) | 732 | # define AUDIO_ENABLED (1 << 31) |
688 | 733 | ||