aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/rv770.c
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2013-04-08 06:41:29 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-04-09 10:31:33 -0400
commitf2ba57b5eab8817d86d0f108fdf1878e51dc0a37 (patch)
treee784f0573069f6341768968fe3d49df6d2c9a534 /drivers/gpu/drm/radeon/rv770.c
parent4474f3a91f95e3fcc62d97e36f1e8e3392c96ee0 (diff)
drm/radeon: UVD bringup v8
Just everything needed to decode videos using UVD. v6: just all the bugfixes and support for R7xx-SI merged in one patch v7: UVD_CGC_GATE is a write only register, lockup detection fix v8: split out VRAM fallback changes, remove support for RV770, add support for HEMLOCK, add buffer sizes checks Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/rv770.c')
-rw-r--r--drivers/gpu/drm/radeon/rv770.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index d4d9be17cfb9..a47e7b903cbc 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -68,6 +68,105 @@ u32 rv770_get_xclk(struct radeon_device *rdev)
68 return reference_clock; 68 return reference_clock;
69} 69}
70 70
71int rv770_uvd_resume(struct radeon_device *rdev)
72{
73 uint64_t addr;
74 uint32_t chip_id, size;
75 int r;
76
77 r = radeon_uvd_resume(rdev);
78 if (r)
79 return r;
80
81 /* programm the VCPU memory controller bits 0-27 */
82 addr = rdev->uvd.gpu_addr >> 3;
83 size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
84 WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
85 WREG32(UVD_VCPU_CACHE_SIZE0, size);
86
87 addr += size;
88 size = RADEON_UVD_STACK_SIZE >> 3;
89 WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
90 WREG32(UVD_VCPU_CACHE_SIZE1, size);
91
92 addr += size;
93 size = RADEON_UVD_HEAP_SIZE >> 3;
94 WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
95 WREG32(UVD_VCPU_CACHE_SIZE2, size);
96
97 /* bits 28-31 */
98 addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
99 WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
100
101 /* bits 32-39 */
102 addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
103 WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
104
105 /* tell firmware which hardware it is running on */
106 switch (rdev->family) {
107 default:
108 return -EINVAL;
109 case CHIP_RV710:
110 chip_id = 0x01000005;
111 break;
112 case CHIP_RV730:
113 chip_id = 0x01000006;
114 break;
115 case CHIP_RV740:
116 chip_id = 0x01000007;
117 break;
118 case CHIP_CYPRESS:
119 case CHIP_HEMLOCK:
120 chip_id = 0x01000008;
121 break;
122 case CHIP_JUNIPER:
123 chip_id = 0x01000009;
124 break;
125 case CHIP_REDWOOD:
126 chip_id = 0x0100000a;
127 break;
128 case CHIP_CEDAR:
129 chip_id = 0x0100000b;
130 break;
131 case CHIP_SUMO:
132 chip_id = 0x0100000c;
133 break;
134 case CHIP_SUMO2:
135 chip_id = 0x0100000d;
136 break;
137 case CHIP_PALM:
138 chip_id = 0x0100000e;
139 break;
140 case CHIP_CAYMAN:
141 chip_id = 0x0100000f;
142 break;
143 case CHIP_BARTS:
144 chip_id = 0x01000010;
145 break;
146 case CHIP_TURKS:
147 chip_id = 0x01000011;
148 break;
149 case CHIP_CAICOS:
150 chip_id = 0x01000012;
151 break;
152 case CHIP_TAHITI:
153 chip_id = 0x01000014;
154 break;
155 case CHIP_VERDE:
156 chip_id = 0x01000015;
157 break;
158 case CHIP_PITCAIRN:
159 chip_id = 0x01000016;
160 break;
161 case CHIP_ARUBA:
162 chip_id = 0x01000017;
163 break;
164 }
165 WREG32(UVD_VCPU_CHIP_ID, chip_id);
166
167 return 0;
168}
169
71u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) 170u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
72{ 171{
73 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; 172 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
@@ -1040,6 +1139,17 @@ static int rv770_startup(struct radeon_device *rdev)
1040 return r; 1139 return r;
1041 } 1140 }
1042 1141
1142 r = rv770_uvd_resume(rdev);
1143 if (!r) {
1144 r = radeon_fence_driver_start_ring(rdev,
1145 R600_RING_TYPE_UVD_INDEX);
1146 if (r)
1147 dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
1148 }
1149
1150 if (r)
1151 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
1152
1043 /* Enable IRQ */ 1153 /* Enable IRQ */
1044 r = r600_irq_init(rdev); 1154 r = r600_irq_init(rdev);
1045 if (r) { 1155 if (r) {
@@ -1074,6 +1184,19 @@ static int rv770_startup(struct radeon_device *rdev)
1074 if (r) 1184 if (r)
1075 return r; 1185 return r;
1076 1186
1187 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
1188 if (ring->ring_size) {
1189 r = radeon_ring_init(rdev, ring, ring->ring_size,
1190 R600_WB_UVD_RPTR_OFFSET,
1191 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
1192 0, 0xfffff, RADEON_CP_PACKET2);
1193 if (!r)
1194 r = r600_uvd_init(rdev);
1195
1196 if (r)
1197 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
1198 }
1199
1077 r = radeon_ib_pool_init(rdev); 1200 r = radeon_ib_pool_init(rdev);
1078 if (r) { 1201 if (r) {
1079 dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 1202 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
@@ -1115,6 +1238,7 @@ int rv770_resume(struct radeon_device *rdev)
1115int rv770_suspend(struct radeon_device *rdev) 1238int rv770_suspend(struct radeon_device *rdev)
1116{ 1239{
1117 r600_audio_fini(rdev); 1240 r600_audio_fini(rdev);
1241 radeon_uvd_suspend(rdev);
1118 r700_cp_stop(rdev); 1242 r700_cp_stop(rdev);
1119 r600_dma_stop(rdev); 1243 r600_dma_stop(rdev);
1120 r600_irq_suspend(rdev); 1244 r600_irq_suspend(rdev);
@@ -1190,6 +1314,13 @@ int rv770_init(struct radeon_device *rdev)
1190 rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL; 1314 rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
1191 r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024); 1315 r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
1192 1316
1317 r = radeon_uvd_init(rdev);
1318 if (!r) {
1319 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
1320 r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX],
1321 4096);
1322 }
1323
1193 rdev->ih.ring_obj = NULL; 1324 rdev->ih.ring_obj = NULL;
1194 r600_ih_ring_init(rdev, 64 * 1024); 1325 r600_ih_ring_init(rdev, 64 * 1024);
1195 1326
@@ -1224,6 +1355,7 @@ void rv770_fini(struct radeon_device *rdev)
1224 radeon_ib_pool_fini(rdev); 1355 radeon_ib_pool_fini(rdev);
1225 radeon_irq_kms_fini(rdev); 1356 radeon_irq_kms_fini(rdev);
1226 rv770_pcie_gart_fini(rdev); 1357 rv770_pcie_gart_fini(rdev);
1358 radeon_uvd_fini(rdev);
1227 r600_vram_scratch_fini(rdev); 1359 r600_vram_scratch_fini(rdev);
1228 radeon_gem_fini(rdev); 1360 radeon_gem_fini(rdev);
1229 radeon_fence_driver_fini(rdev); 1361 radeon_fence_driver_fini(rdev);