diff options
author | Boyuan Zhang <boyuan.zhang@amd.com> | 2018-05-30 14:39:07 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-06-15 13:20:35 -0400 |
commit | 221f36c460d7d671e9d19d0d8184225aa068d3a8 (patch) | |
tree | 74bb872e84a1ace3ef5f13aa751b5946206f6c8b /drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |
parent | 50613395abc00f150f051d6bc440877741b6fae9 (diff) |
drm/amdgpu: implement jpeg ring functions
Implement all ring functions needed for jpeg ring
v2: remove unnecessary mem read function.
Signed-off-by: Boyuan Zhang <boyuan.zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 29684c3ea4ef..4f15833df8aa 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |||
@@ -1126,6 +1126,292 @@ static void vcn_v1_0_enc_ring_emit_wreg(struct amdgpu_ring *ring, | |||
1126 | amdgpu_ring_write(ring, val); | 1126 | amdgpu_ring_write(ring, val); |
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | |||
1130 | /** | ||
1131 | * vcn_v1_0_jpeg_ring_get_rptr - get read pointer | ||
1132 | * | ||
1133 | * @ring: amdgpu_ring pointer | ||
1134 | * | ||
1135 | * Returns the current hardware read pointer | ||
1136 | */ | ||
1137 | static uint64_t vcn_v1_0_jpeg_ring_get_rptr(struct amdgpu_ring *ring) | ||
1138 | { | ||
1139 | struct amdgpu_device *adev = ring->adev; | ||
1140 | |||
1141 | return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR); | ||
1142 | } | ||
1143 | |||
1144 | /** | ||
1145 | * vcn_v1_0_jpeg_ring_get_wptr - get write pointer | ||
1146 | * | ||
1147 | * @ring: amdgpu_ring pointer | ||
1148 | * | ||
1149 | * Returns the current hardware write pointer | ||
1150 | */ | ||
1151 | static uint64_t vcn_v1_0_jpeg_ring_get_wptr(struct amdgpu_ring *ring) | ||
1152 | { | ||
1153 | struct amdgpu_device *adev = ring->adev; | ||
1154 | |||
1155 | return RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR); | ||
1156 | } | ||
1157 | |||
1158 | /** | ||
1159 | * vcn_v1_0_jpeg_ring_set_wptr - set write pointer | ||
1160 | * | ||
1161 | * @ring: amdgpu_ring pointer | ||
1162 | * | ||
1163 | * Commits the write pointer to the hardware | ||
1164 | */ | ||
1165 | static void vcn_v1_0_jpeg_ring_set_wptr(struct amdgpu_ring *ring) | ||
1166 | { | ||
1167 | struct amdgpu_device *adev = ring->adev; | ||
1168 | |||
1169 | WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); | ||
1170 | } | ||
1171 | |||
1172 | /** | ||
1173 | * vcn_v1_0_jpeg_ring_insert_start - insert a start command | ||
1174 | * | ||
1175 | * @ring: amdgpu_ring pointer | ||
1176 | * | ||
1177 | * Write a start command to the ring. | ||
1178 | */ | ||
1179 | static void vcn_v1_0_jpeg_ring_insert_start(struct amdgpu_ring *ring) | ||
1180 | { | ||
1181 | struct amdgpu_device *adev = ring->adev; | ||
1182 | |||
1183 | amdgpu_ring_write(ring, | ||
1184 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); | ||
1185 | amdgpu_ring_write(ring, 0x68e04); | ||
1186 | |||
1187 | amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); | ||
1188 | amdgpu_ring_write(ring, 0x80010000); | ||
1189 | } | ||
1190 | |||
1191 | /** | ||
1192 | * vcn_v1_0_jpeg_ring_insert_end - insert a end command | ||
1193 | * | ||
1194 | * @ring: amdgpu_ring pointer | ||
1195 | * | ||
1196 | * Write a end command to the ring. | ||
1197 | */ | ||
1198 | static void vcn_v1_0_jpeg_ring_insert_end(struct amdgpu_ring *ring) | ||
1199 | { | ||
1200 | struct amdgpu_device *adev = ring->adev; | ||
1201 | |||
1202 | amdgpu_ring_write(ring, | ||
1203 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); | ||
1204 | amdgpu_ring_write(ring, 0x68e04); | ||
1205 | |||
1206 | amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); | ||
1207 | amdgpu_ring_write(ring, 0x00010000); | ||
1208 | } | ||
1209 | |||
1210 | /** | ||
1211 | * vcn_v1_0_jpeg_ring_emit_fence - emit an fence & trap command | ||
1212 | * | ||
1213 | * @ring: amdgpu_ring pointer | ||
1214 | * @fence: fence to emit | ||
1215 | * | ||
1216 | * Write a fence and a trap command to the ring. | ||
1217 | */ | ||
1218 | static void vcn_v1_0_jpeg_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, | ||
1219 | unsigned flags) | ||
1220 | { | ||
1221 | struct amdgpu_device *adev = ring->adev; | ||
1222 | |||
1223 | WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); | ||
1224 | |||
1225 | amdgpu_ring_write(ring, | ||
1226 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0)); | ||
1227 | amdgpu_ring_write(ring, seq); | ||
1228 | |||
1229 | amdgpu_ring_write(ring, | ||
1230 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0)); | ||
1231 | amdgpu_ring_write(ring, seq); | ||
1232 | |||
1233 | amdgpu_ring_write(ring, | ||
1234 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); | ||
1235 | amdgpu_ring_write(ring, lower_32_bits(addr)); | ||
1236 | |||
1237 | amdgpu_ring_write(ring, | ||
1238 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); | ||
1239 | amdgpu_ring_write(ring, upper_32_bits(addr)); | ||
1240 | |||
1241 | amdgpu_ring_write(ring, | ||
1242 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0)); | ||
1243 | amdgpu_ring_write(ring, 0x8); | ||
1244 | |||
1245 | amdgpu_ring_write(ring, | ||
1246 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); | ||
1247 | amdgpu_ring_write(ring, 0); | ||
1248 | |||
1249 | amdgpu_ring_write(ring, | ||
1250 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); | ||
1251 | amdgpu_ring_write(ring, 0x01400200); | ||
1252 | |||
1253 | amdgpu_ring_write(ring, | ||
1254 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); | ||
1255 | amdgpu_ring_write(ring, seq); | ||
1256 | |||
1257 | amdgpu_ring_write(ring, | ||
1258 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); | ||
1259 | amdgpu_ring_write(ring, lower_32_bits(addr)); | ||
1260 | |||
1261 | amdgpu_ring_write(ring, | ||
1262 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); | ||
1263 | amdgpu_ring_write(ring, upper_32_bits(addr)); | ||
1264 | |||
1265 | amdgpu_ring_write(ring, | ||
1266 | PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2)); | ||
1267 | amdgpu_ring_write(ring, 0xffffffff); | ||
1268 | |||
1269 | amdgpu_ring_write(ring, | ||
1270 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); | ||
1271 | amdgpu_ring_write(ring, 0x3fbc); | ||
1272 | |||
1273 | amdgpu_ring_write(ring, | ||
1274 | PACKETJ(0, 0, 0, PACKETJ_TYPE0)); | ||
1275 | amdgpu_ring_write(ring, 0x1); | ||
1276 | } | ||
1277 | |||
1278 | /** | ||
1279 | * vcn_v1_0_jpeg_ring_emit_ib - execute indirect buffer | ||
1280 | * | ||
1281 | * @ring: amdgpu_ring pointer | ||
1282 | * @ib: indirect buffer to execute | ||
1283 | * | ||
1284 | * Write ring commands to execute the indirect buffer. | ||
1285 | */ | ||
1286 | static void vcn_v1_0_jpeg_ring_emit_ib(struct amdgpu_ring *ring, | ||
1287 | struct amdgpu_ib *ib, | ||
1288 | unsigned vmid, bool ctx_switch) | ||
1289 | { | ||
1290 | struct amdgpu_device *adev = ring->adev; | ||
1291 | |||
1292 | amdgpu_ring_write(ring, | ||
1293 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); | ||
1294 | amdgpu_ring_write(ring, (vmid | (vmid << 4))); | ||
1295 | |||
1296 | amdgpu_ring_write(ring, | ||
1297 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0)); | ||
1298 | amdgpu_ring_write(ring, (vmid | (vmid << 4))); | ||
1299 | |||
1300 | amdgpu_ring_write(ring, | ||
1301 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); | ||
1302 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | ||
1303 | |||
1304 | amdgpu_ring_write(ring, | ||
1305 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); | ||
1306 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); | ||
1307 | |||
1308 | amdgpu_ring_write(ring, | ||
1309 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0)); | ||
1310 | amdgpu_ring_write(ring, ib->length_dw); | ||
1311 | |||
1312 | amdgpu_ring_write(ring, | ||
1313 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); | ||
1314 | amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); | ||
1315 | |||
1316 | amdgpu_ring_write(ring, | ||
1317 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); | ||
1318 | amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr)); | ||
1319 | |||
1320 | amdgpu_ring_write(ring, | ||
1321 | PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2)); | ||
1322 | amdgpu_ring_write(ring, 0); | ||
1323 | |||
1324 | amdgpu_ring_write(ring, | ||
1325 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); | ||
1326 | amdgpu_ring_write(ring, 0x01400200); | ||
1327 | |||
1328 | amdgpu_ring_write(ring, | ||
1329 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); | ||
1330 | amdgpu_ring_write(ring, 0x2); | ||
1331 | |||
1332 | amdgpu_ring_write(ring, | ||
1333 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); | ||
1334 | amdgpu_ring_write(ring, 0x2); | ||
1335 | } | ||
1336 | |||
1337 | static void vcn_v1_0_jpeg_ring_emit_reg_wait(struct amdgpu_ring *ring, | ||
1338 | uint32_t reg, uint32_t val, | ||
1339 | uint32_t mask) | ||
1340 | { | ||
1341 | struct amdgpu_device *adev = ring->adev; | ||
1342 | uint32_t reg_offset = (reg << 2); | ||
1343 | |||
1344 | amdgpu_ring_write(ring, | ||
1345 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); | ||
1346 | amdgpu_ring_write(ring, 0x01400200); | ||
1347 | |||
1348 | amdgpu_ring_write(ring, | ||
1349 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); | ||
1350 | amdgpu_ring_write(ring, val); | ||
1351 | |||
1352 | amdgpu_ring_write(ring, | ||
1353 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); | ||
1354 | if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || | ||
1355 | ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { | ||
1356 | amdgpu_ring_write(ring, 0); | ||
1357 | amdgpu_ring_write(ring, | ||
1358 | PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3)); | ||
1359 | } else { | ||
1360 | amdgpu_ring_write(ring, reg_offset); | ||
1361 | amdgpu_ring_write(ring, | ||
1362 | PACKETJ(0, 0, 0, PACKETJ_TYPE3)); | ||
1363 | } | ||
1364 | amdgpu_ring_write(ring, mask); | ||
1365 | } | ||
1366 | |||
1367 | static void vcn_v1_0_jpeg_ring_emit_vm_flush(struct amdgpu_ring *ring, | ||
1368 | unsigned vmid, uint64_t pd_addr) | ||
1369 | { | ||
1370 | struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub]; | ||
1371 | uint32_t data0, data1, mask; | ||
1372 | |||
1373 | pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); | ||
1374 | |||
1375 | /* wait for register write */ | ||
1376 | data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2; | ||
1377 | data1 = lower_32_bits(pd_addr); | ||
1378 | mask = 0xffffffff; | ||
1379 | vcn_v1_0_jpeg_ring_emit_reg_wait(ring, data0, data1, mask); | ||
1380 | } | ||
1381 | |||
1382 | static void vcn_v1_0_jpeg_ring_emit_wreg(struct amdgpu_ring *ring, | ||
1383 | uint32_t reg, uint32_t val) | ||
1384 | { | ||
1385 | struct amdgpu_device *adev = ring->adev; | ||
1386 | uint32_t reg_offset = (reg << 2); | ||
1387 | |||
1388 | amdgpu_ring_write(ring, | ||
1389 | PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); | ||
1390 | if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || | ||
1391 | ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { | ||
1392 | amdgpu_ring_write(ring, 0); | ||
1393 | amdgpu_ring_write(ring, | ||
1394 | PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0)); | ||
1395 | } else { | ||
1396 | amdgpu_ring_write(ring, reg_offset); | ||
1397 | amdgpu_ring_write(ring, | ||
1398 | PACKETJ(0, 0, 0, PACKETJ_TYPE0)); | ||
1399 | } | ||
1400 | amdgpu_ring_write(ring, val); | ||
1401 | } | ||
1402 | |||
1403 | static void vcn_v1_0_jpeg_ring_nop(struct amdgpu_ring *ring, uint32_t count) | ||
1404 | { | ||
1405 | int i; | ||
1406 | |||
1407 | WARN_ON(ring->wptr % 2 || count % 2); | ||
1408 | |||
1409 | for (i = 0; i < count / 2; i++) { | ||
1410 | amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6)); | ||
1411 | amdgpu_ring_write(ring, 0); | ||
1412 | } | ||
1413 | } | ||
1414 | |||
1129 | static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev, | 1415 | static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev, |
1130 | struct amdgpu_irq_src *source, | 1416 | struct amdgpu_irq_src *source, |
1131 | unsigned type, | 1417 | unsigned type, |