1c349dbc7Sjsg /* 2c349dbc7Sjsg * Copyright 2019 Advanced Micro Devices, Inc. 3c349dbc7Sjsg * 4c349dbc7Sjsg * Permission is hereby granted, free of charge, to any person obtaining a 5c349dbc7Sjsg * copy of this software and associated documentation files (the "Software"), 6c349dbc7Sjsg * to deal in the Software without restriction, including without limitation 7c349dbc7Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8c349dbc7Sjsg * and/or sell copies of the Software, and to permit persons to whom the 9c349dbc7Sjsg * Software is furnished to do so, subject to the following conditions: 10c349dbc7Sjsg * 11c349dbc7Sjsg * The above copyright notice and this permission notice shall be included in 12c349dbc7Sjsg * all copies or substantial portions of the Software. 13c349dbc7Sjsg * 14c349dbc7Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15c349dbc7Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16c349dbc7Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17c349dbc7Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18c349dbc7Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19c349dbc7Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20c349dbc7Sjsg * OTHER DEALINGS IN THE SOFTWARE. 21c349dbc7Sjsg * 22c349dbc7Sjsg */ 23c349dbc7Sjsg 24c349dbc7Sjsg #include "amdgpu.h" 25c349dbc7Sjsg #include "amdgpu_jpeg.h" 26*b5a27a99Sjsg #include "amdgpu_cs.h" 27c349dbc7Sjsg #include "soc15.h" 28c349dbc7Sjsg #include "soc15d.h" 29c349dbc7Sjsg #include "vcn_v1_0.h" 30ad8b1aafSjsg #include "jpeg_v1_0.h" 31c349dbc7Sjsg 32c349dbc7Sjsg #include "vcn/vcn_1_0_offset.h" 33c349dbc7Sjsg #include "vcn/vcn_1_0_sh_mask.h" 34c349dbc7Sjsg 35c349dbc7Sjsg static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); 36c349dbc7Sjsg static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev); 37ad8b1aafSjsg static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring); 38*b5a27a99Sjsg static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser, 39*b5a27a99Sjsg struct amdgpu_job *job, 40*b5a27a99Sjsg struct amdgpu_ib *ib); 41c349dbc7Sjsg 42c349dbc7Sjsg static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val) 43c349dbc7Sjsg { 44c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 45c349dbc7Sjsg ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0); 46c349dbc7Sjsg if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 47c349dbc7Sjsg ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 48c349dbc7Sjsg ring->ring[(*ptr)++] = 0; 49c349dbc7Sjsg ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0); 50c349dbc7Sjsg } else { 51c349dbc7Sjsg ring->ring[(*ptr)++] = reg_offset; 52c349dbc7Sjsg ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0); 53c349dbc7Sjsg } 54c349dbc7Sjsg ring->ring[(*ptr)++] = val; 55c349dbc7Sjsg } 56c349dbc7Sjsg 57c349dbc7Sjsg static void jpeg_v1_0_decode_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr) 58c349dbc7Sjsg { 59c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 60c349dbc7Sjsg 61c349dbc7Sjsg uint32_t reg, reg_offset, val, mask, i; 62c349dbc7Sjsg 63c349dbc7Sjsg // 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW 64c349dbc7Sjsg reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW); 65c349dbc7Sjsg reg_offset = (reg << 2); 66c349dbc7Sjsg val = lower_32_bits(ring->gpu_addr); 67c349dbc7Sjsg jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 68c349dbc7Sjsg 69c349dbc7Sjsg // 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH 70c349dbc7Sjsg reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH); 71c349dbc7Sjsg reg_offset = (reg << 2); 72c349dbc7Sjsg val = upper_32_bits(ring->gpu_addr); 73c349dbc7Sjsg jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 74c349dbc7Sjsg 75c349dbc7Sjsg // 3rd to 5th: issue MEM_READ commands 76c349dbc7Sjsg for (i = 0; i <= 2; i++) { 77c349dbc7Sjsg ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2); 78c349dbc7Sjsg ring->ring[ptr++] = 0; 79c349dbc7Sjsg } 80c349dbc7Sjsg 81c349dbc7Sjsg // 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability 82c349dbc7Sjsg reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); 83c349dbc7Sjsg reg_offset = (reg << 2); 84c349dbc7Sjsg val = 0x13; 85c349dbc7Sjsg jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 86c349dbc7Sjsg 87c349dbc7Sjsg // 7th: program mmUVD_JRBC_RB_REF_DATA 88c349dbc7Sjsg reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA); 89c349dbc7Sjsg reg_offset = (reg << 2); 90c349dbc7Sjsg val = 0x1; 91c349dbc7Sjsg jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 92c349dbc7Sjsg 93c349dbc7Sjsg // 8th: issue conditional register read mmUVD_JRBC_RB_CNTL 94c349dbc7Sjsg reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); 95c349dbc7Sjsg reg_offset = (reg << 2); 96c349dbc7Sjsg val = 0x1; 97c349dbc7Sjsg mask = 0x1; 98c349dbc7Sjsg 99c349dbc7Sjsg ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0); 100c349dbc7Sjsg ring->ring[ptr++] = 0x01400200; 101c349dbc7Sjsg ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0); 102c349dbc7Sjsg ring->ring[ptr++] = val; 103c349dbc7Sjsg ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0); 104c349dbc7Sjsg if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 105c349dbc7Sjsg ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 106c349dbc7Sjsg ring->ring[ptr++] = 0; 107c349dbc7Sjsg ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3); 108c349dbc7Sjsg } else { 109c349dbc7Sjsg ring->ring[ptr++] = reg_offset; 110c349dbc7Sjsg ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3); 111c349dbc7Sjsg } 112c349dbc7Sjsg ring->ring[ptr++] = mask; 113c349dbc7Sjsg 114c349dbc7Sjsg //9th to 21st: insert no-op 115c349dbc7Sjsg for (i = 0; i <= 12; i++) { 116c349dbc7Sjsg ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); 117c349dbc7Sjsg ring->ring[ptr++] = 0; 118c349dbc7Sjsg } 119c349dbc7Sjsg 120c349dbc7Sjsg //22nd: reset mmUVD_JRBC_RB_RPTR 121c349dbc7Sjsg reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_RPTR); 122c349dbc7Sjsg reg_offset = (reg << 2); 123c349dbc7Sjsg val = 0; 124c349dbc7Sjsg jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 125c349dbc7Sjsg 126c349dbc7Sjsg //23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch 127c349dbc7Sjsg reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL); 128c349dbc7Sjsg reg_offset = (reg << 2); 129c349dbc7Sjsg val = 0x12; 130c349dbc7Sjsg jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val); 131c349dbc7Sjsg } 132c349dbc7Sjsg 133c349dbc7Sjsg /** 134c349dbc7Sjsg * jpeg_v1_0_decode_ring_get_rptr - get read pointer 135c349dbc7Sjsg * 136c349dbc7Sjsg * @ring: amdgpu_ring pointer 137c349dbc7Sjsg * 138c349dbc7Sjsg * Returns the current hardware read pointer 139c349dbc7Sjsg */ 140c349dbc7Sjsg static uint64_t jpeg_v1_0_decode_ring_get_rptr(struct amdgpu_ring *ring) 141c349dbc7Sjsg { 142c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 143c349dbc7Sjsg 144c349dbc7Sjsg return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR); 145c349dbc7Sjsg } 146c349dbc7Sjsg 147c349dbc7Sjsg /** 148c349dbc7Sjsg * jpeg_v1_0_decode_ring_get_wptr - get write pointer 149c349dbc7Sjsg * 150c349dbc7Sjsg * @ring: amdgpu_ring pointer 151c349dbc7Sjsg * 152c349dbc7Sjsg * Returns the current hardware write pointer 153c349dbc7Sjsg */ 154c349dbc7Sjsg static uint64_t jpeg_v1_0_decode_ring_get_wptr(struct amdgpu_ring *ring) 155c349dbc7Sjsg { 156c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 157c349dbc7Sjsg 158c349dbc7Sjsg return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 159c349dbc7Sjsg } 160c349dbc7Sjsg 161c349dbc7Sjsg /** 162c349dbc7Sjsg * jpeg_v1_0_decode_ring_set_wptr - set write pointer 163c349dbc7Sjsg * 164c349dbc7Sjsg * @ring: amdgpu_ring pointer 165c349dbc7Sjsg * 166c349dbc7Sjsg * Commits the write pointer to the hardware 167c349dbc7Sjsg */ 168c349dbc7Sjsg static void jpeg_v1_0_decode_ring_set_wptr(struct amdgpu_ring *ring) 169c349dbc7Sjsg { 170c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 171c349dbc7Sjsg 172c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); 173c349dbc7Sjsg } 174c349dbc7Sjsg 175c349dbc7Sjsg /** 176c349dbc7Sjsg * jpeg_v1_0_decode_ring_insert_start - insert a start command 177c349dbc7Sjsg * 178c349dbc7Sjsg * @ring: amdgpu_ring pointer 179c349dbc7Sjsg * 180c349dbc7Sjsg * Write a start command to the ring. 181c349dbc7Sjsg */ 182c349dbc7Sjsg static void jpeg_v1_0_decode_ring_insert_start(struct amdgpu_ring *ring) 183c349dbc7Sjsg { 184c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 185c349dbc7Sjsg 186c349dbc7Sjsg amdgpu_ring_write(ring, 187c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 188c349dbc7Sjsg amdgpu_ring_write(ring, 0x68e04); 189c349dbc7Sjsg 190c349dbc7Sjsg amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 191c349dbc7Sjsg amdgpu_ring_write(ring, 0x80010000); 192c349dbc7Sjsg } 193c349dbc7Sjsg 194c349dbc7Sjsg /** 195c349dbc7Sjsg * jpeg_v1_0_decode_ring_insert_end - insert a end command 196c349dbc7Sjsg * 197c349dbc7Sjsg * @ring: amdgpu_ring pointer 198c349dbc7Sjsg * 199c349dbc7Sjsg * Write a end command to the ring. 200c349dbc7Sjsg */ 201c349dbc7Sjsg static void jpeg_v1_0_decode_ring_insert_end(struct amdgpu_ring *ring) 202c349dbc7Sjsg { 203c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 204c349dbc7Sjsg 205c349dbc7Sjsg amdgpu_ring_write(ring, 206c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 207c349dbc7Sjsg amdgpu_ring_write(ring, 0x68e04); 208c349dbc7Sjsg 209c349dbc7Sjsg amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 210c349dbc7Sjsg amdgpu_ring_write(ring, 0x00010000); 211c349dbc7Sjsg } 212c349dbc7Sjsg 213c349dbc7Sjsg /** 214c349dbc7Sjsg * jpeg_v1_0_decode_ring_emit_fence - emit an fence & trap command 215c349dbc7Sjsg * 216c349dbc7Sjsg * @ring: amdgpu_ring pointer 2175ca02815Sjsg * @addr: address 2185ca02815Sjsg * @seq: sequence number 2195ca02815Sjsg * @flags: fence related flags 220c349dbc7Sjsg * 221c349dbc7Sjsg * Write a fence and a trap command to the ring. 222c349dbc7Sjsg */ 223c349dbc7Sjsg static void jpeg_v1_0_decode_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, 224c349dbc7Sjsg unsigned flags) 225c349dbc7Sjsg { 226c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 227c349dbc7Sjsg 228c349dbc7Sjsg WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); 229c349dbc7Sjsg 230c349dbc7Sjsg amdgpu_ring_write(ring, 231c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0)); 232c349dbc7Sjsg amdgpu_ring_write(ring, seq); 233c349dbc7Sjsg 234c349dbc7Sjsg amdgpu_ring_write(ring, 235c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0)); 236c349dbc7Sjsg amdgpu_ring_write(ring, seq); 237c349dbc7Sjsg 238c349dbc7Sjsg amdgpu_ring_write(ring, 239c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 240c349dbc7Sjsg amdgpu_ring_write(ring, lower_32_bits(addr)); 241c349dbc7Sjsg 242c349dbc7Sjsg amdgpu_ring_write(ring, 243c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 244c349dbc7Sjsg amdgpu_ring_write(ring, upper_32_bits(addr)); 245c349dbc7Sjsg 246c349dbc7Sjsg amdgpu_ring_write(ring, 247c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0)); 248c349dbc7Sjsg amdgpu_ring_write(ring, 0x8); 249c349dbc7Sjsg 250c349dbc7Sjsg amdgpu_ring_write(ring, 251c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); 252c349dbc7Sjsg amdgpu_ring_write(ring, 0); 253c349dbc7Sjsg 254c349dbc7Sjsg amdgpu_ring_write(ring, 255c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 256c349dbc7Sjsg amdgpu_ring_write(ring, 0x01400200); 257c349dbc7Sjsg 258c349dbc7Sjsg amdgpu_ring_write(ring, 259c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 260c349dbc7Sjsg amdgpu_ring_write(ring, seq); 261c349dbc7Sjsg 262c349dbc7Sjsg amdgpu_ring_write(ring, 263c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 264c349dbc7Sjsg amdgpu_ring_write(ring, lower_32_bits(addr)); 265c349dbc7Sjsg 266c349dbc7Sjsg amdgpu_ring_write(ring, 267c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 268c349dbc7Sjsg amdgpu_ring_write(ring, upper_32_bits(addr)); 269c349dbc7Sjsg 270c349dbc7Sjsg amdgpu_ring_write(ring, 271c349dbc7Sjsg PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2)); 272c349dbc7Sjsg amdgpu_ring_write(ring, 0xffffffff); 273c349dbc7Sjsg 274c349dbc7Sjsg amdgpu_ring_write(ring, 275c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 276c349dbc7Sjsg amdgpu_ring_write(ring, 0x3fbc); 277c349dbc7Sjsg 278c349dbc7Sjsg amdgpu_ring_write(ring, 279c349dbc7Sjsg PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 280c349dbc7Sjsg amdgpu_ring_write(ring, 0x1); 281c349dbc7Sjsg 282c349dbc7Sjsg /* emit trap */ 283c349dbc7Sjsg amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7)); 284c349dbc7Sjsg amdgpu_ring_write(ring, 0); 285c349dbc7Sjsg } 286c349dbc7Sjsg 287c349dbc7Sjsg /** 288c349dbc7Sjsg * jpeg_v1_0_decode_ring_emit_ib - execute indirect buffer 289c349dbc7Sjsg * 290c349dbc7Sjsg * @ring: amdgpu_ring pointer 2915ca02815Sjsg * @job: job to retrieve vmid from 292c349dbc7Sjsg * @ib: indirect buffer to execute 2935ca02815Sjsg * @flags: unused 294c349dbc7Sjsg * 295c349dbc7Sjsg * Write ring commands to execute the indirect buffer. 296c349dbc7Sjsg */ 297c349dbc7Sjsg static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring, 298c349dbc7Sjsg struct amdgpu_job *job, 299c349dbc7Sjsg struct amdgpu_ib *ib, 300c349dbc7Sjsg uint32_t flags) 301c349dbc7Sjsg { 302c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 303c349dbc7Sjsg unsigned vmid = AMDGPU_JOB_GET_VMID(job); 304c349dbc7Sjsg 305c349dbc7Sjsg amdgpu_ring_write(ring, 306c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0)); 307*b5a27a99Sjsg if (ring->funcs->parse_cs) 308*b5a27a99Sjsg amdgpu_ring_write(ring, 0); 309*b5a27a99Sjsg else 310c349dbc7Sjsg amdgpu_ring_write(ring, (vmid | (vmid << 4))); 311c349dbc7Sjsg 312c349dbc7Sjsg amdgpu_ring_write(ring, 313c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0)); 314c349dbc7Sjsg amdgpu_ring_write(ring, (vmid | (vmid << 4))); 315c349dbc7Sjsg 316c349dbc7Sjsg amdgpu_ring_write(ring, 317c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 318c349dbc7Sjsg amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); 319c349dbc7Sjsg 320c349dbc7Sjsg amdgpu_ring_write(ring, 321c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 322c349dbc7Sjsg amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); 323c349dbc7Sjsg 324c349dbc7Sjsg amdgpu_ring_write(ring, 325c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0)); 326c349dbc7Sjsg amdgpu_ring_write(ring, ib->length_dw); 327c349dbc7Sjsg 328c349dbc7Sjsg amdgpu_ring_write(ring, 329c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0)); 330c349dbc7Sjsg amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); 331c349dbc7Sjsg 332c349dbc7Sjsg amdgpu_ring_write(ring, 333c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0)); 334c349dbc7Sjsg amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr)); 335c349dbc7Sjsg 336c349dbc7Sjsg amdgpu_ring_write(ring, 337c349dbc7Sjsg PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2)); 338c349dbc7Sjsg amdgpu_ring_write(ring, 0); 339c349dbc7Sjsg 340c349dbc7Sjsg amdgpu_ring_write(ring, 341c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 342c349dbc7Sjsg amdgpu_ring_write(ring, 0x01400200); 343c349dbc7Sjsg 344c349dbc7Sjsg amdgpu_ring_write(ring, 345c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 346c349dbc7Sjsg amdgpu_ring_write(ring, 0x2); 347c349dbc7Sjsg 348c349dbc7Sjsg amdgpu_ring_write(ring, 349c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); 350c349dbc7Sjsg amdgpu_ring_write(ring, 0x2); 351c349dbc7Sjsg } 352c349dbc7Sjsg 353c349dbc7Sjsg static void jpeg_v1_0_decode_ring_emit_reg_wait(struct amdgpu_ring *ring, 354c349dbc7Sjsg uint32_t reg, uint32_t val, 355c349dbc7Sjsg uint32_t mask) 356c349dbc7Sjsg { 357c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 358c349dbc7Sjsg uint32_t reg_offset = (reg << 2); 359c349dbc7Sjsg 360c349dbc7Sjsg amdgpu_ring_write(ring, 361c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0)); 362c349dbc7Sjsg amdgpu_ring_write(ring, 0x01400200); 363c349dbc7Sjsg 364c349dbc7Sjsg amdgpu_ring_write(ring, 365c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0)); 366c349dbc7Sjsg amdgpu_ring_write(ring, val); 367c349dbc7Sjsg 368c349dbc7Sjsg amdgpu_ring_write(ring, 369c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 370c349dbc7Sjsg if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 371c349dbc7Sjsg ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 372c349dbc7Sjsg amdgpu_ring_write(ring, 0); 373c349dbc7Sjsg amdgpu_ring_write(ring, 374c349dbc7Sjsg PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3)); 375c349dbc7Sjsg } else { 376c349dbc7Sjsg amdgpu_ring_write(ring, reg_offset); 377c349dbc7Sjsg amdgpu_ring_write(ring, 378c349dbc7Sjsg PACKETJ(0, 0, 0, PACKETJ_TYPE3)); 379c349dbc7Sjsg } 380c349dbc7Sjsg amdgpu_ring_write(ring, mask); 381c349dbc7Sjsg } 382c349dbc7Sjsg 383c349dbc7Sjsg static void jpeg_v1_0_decode_ring_emit_vm_flush(struct amdgpu_ring *ring, 384c349dbc7Sjsg unsigned vmid, uint64_t pd_addr) 385c349dbc7Sjsg { 386f005ef32Sjsg struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->vm_hub]; 387c349dbc7Sjsg uint32_t data0, data1, mask; 388c349dbc7Sjsg 389c349dbc7Sjsg pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); 390c349dbc7Sjsg 391c349dbc7Sjsg /* wait for register write */ 392ad8b1aafSjsg data0 = hub->ctx0_ptb_addr_lo32 + vmid * hub->ctx_addr_distance; 393c349dbc7Sjsg data1 = lower_32_bits(pd_addr); 394c349dbc7Sjsg mask = 0xffffffff; 395c349dbc7Sjsg jpeg_v1_0_decode_ring_emit_reg_wait(ring, data0, data1, mask); 396c349dbc7Sjsg } 397c349dbc7Sjsg 398c349dbc7Sjsg static void jpeg_v1_0_decode_ring_emit_wreg(struct amdgpu_ring *ring, 399c349dbc7Sjsg uint32_t reg, uint32_t val) 400c349dbc7Sjsg { 401c349dbc7Sjsg struct amdgpu_device *adev = ring->adev; 402c349dbc7Sjsg uint32_t reg_offset = (reg << 2); 403c349dbc7Sjsg 404c349dbc7Sjsg amdgpu_ring_write(ring, 405c349dbc7Sjsg PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0)); 406c349dbc7Sjsg if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) || 407c349dbc7Sjsg ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) { 408c349dbc7Sjsg amdgpu_ring_write(ring, 0); 409c349dbc7Sjsg amdgpu_ring_write(ring, 410c349dbc7Sjsg PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0)); 411c349dbc7Sjsg } else { 412c349dbc7Sjsg amdgpu_ring_write(ring, reg_offset); 413c349dbc7Sjsg amdgpu_ring_write(ring, 414c349dbc7Sjsg PACKETJ(0, 0, 0, PACKETJ_TYPE0)); 415c349dbc7Sjsg } 416c349dbc7Sjsg amdgpu_ring_write(ring, val); 417c349dbc7Sjsg } 418c349dbc7Sjsg 419c349dbc7Sjsg static void jpeg_v1_0_decode_ring_nop(struct amdgpu_ring *ring, uint32_t count) 420c349dbc7Sjsg { 421c349dbc7Sjsg int i; 422c349dbc7Sjsg 423c349dbc7Sjsg WARN_ON(ring->wptr % 2 || count % 2); 424c349dbc7Sjsg 425c349dbc7Sjsg for (i = 0; i < count / 2; i++) { 426c349dbc7Sjsg amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6)); 427c349dbc7Sjsg amdgpu_ring_write(ring, 0); 428c349dbc7Sjsg } 429c349dbc7Sjsg } 430c349dbc7Sjsg 431c349dbc7Sjsg static int jpeg_v1_0_set_interrupt_state(struct amdgpu_device *adev, 432c349dbc7Sjsg struct amdgpu_irq_src *source, 433c349dbc7Sjsg unsigned type, 434c349dbc7Sjsg enum amdgpu_interrupt_state state) 435c349dbc7Sjsg { 436c349dbc7Sjsg return 0; 437c349dbc7Sjsg } 438c349dbc7Sjsg 439c349dbc7Sjsg static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev, 440c349dbc7Sjsg struct amdgpu_irq_src *source, 441c349dbc7Sjsg struct amdgpu_iv_entry *entry) 442c349dbc7Sjsg { 443c349dbc7Sjsg DRM_DEBUG("IH: JPEG decode TRAP\n"); 444c349dbc7Sjsg 445c349dbc7Sjsg switch (entry->src_id) { 446c349dbc7Sjsg case 126: 447f005ef32Sjsg amdgpu_fence_process(adev->jpeg.inst->ring_dec); 448c349dbc7Sjsg break; 449c349dbc7Sjsg default: 450c349dbc7Sjsg DRM_ERROR("Unhandled interrupt: %d %d\n", 451c349dbc7Sjsg entry->src_id, entry->src_data[0]); 452c349dbc7Sjsg break; 453c349dbc7Sjsg } 454c349dbc7Sjsg 455c349dbc7Sjsg return 0; 456c349dbc7Sjsg } 457c349dbc7Sjsg 458c349dbc7Sjsg /** 459c349dbc7Sjsg * jpeg_v1_0_early_init - set function pointers 460c349dbc7Sjsg * 461c349dbc7Sjsg * @handle: amdgpu_device pointer 462c349dbc7Sjsg * 463c349dbc7Sjsg * Set ring and irq function pointers 464c349dbc7Sjsg */ 465c349dbc7Sjsg int jpeg_v1_0_early_init(void *handle) 466c349dbc7Sjsg { 467c349dbc7Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)handle; 468c349dbc7Sjsg 469c349dbc7Sjsg adev->jpeg.num_jpeg_inst = 1; 470f005ef32Sjsg adev->jpeg.num_jpeg_rings = 1; 471c349dbc7Sjsg 472c349dbc7Sjsg jpeg_v1_0_set_dec_ring_funcs(adev); 473c349dbc7Sjsg jpeg_v1_0_set_irq_funcs(adev); 474c349dbc7Sjsg 475c349dbc7Sjsg return 0; 476c349dbc7Sjsg } 477c349dbc7Sjsg 478c349dbc7Sjsg /** 479c349dbc7Sjsg * jpeg_v1_0_sw_init - sw init for JPEG block 480c349dbc7Sjsg * 481c349dbc7Sjsg * @handle: amdgpu_device pointer 482c349dbc7Sjsg * 483c349dbc7Sjsg */ 484c349dbc7Sjsg int jpeg_v1_0_sw_init(void *handle) 485c349dbc7Sjsg { 486c349dbc7Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)handle; 487c349dbc7Sjsg struct amdgpu_ring *ring; 488c349dbc7Sjsg int r; 489c349dbc7Sjsg 490c349dbc7Sjsg /* JPEG TRAP */ 491c349dbc7Sjsg r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->jpeg.inst->irq); 492c349dbc7Sjsg if (r) 493c349dbc7Sjsg return r; 494c349dbc7Sjsg 495f005ef32Sjsg ring = adev->jpeg.inst->ring_dec; 496f005ef32Sjsg ring->vm_hub = AMDGPU_MMHUB0(0); 497c349dbc7Sjsg snprintf(ring->name, sizeof(ring->name), "jpeg_dec"); 498ad8b1aafSjsg r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 4995ca02815Sjsg 0, AMDGPU_RING_PRIO_DEFAULT, NULL); 500c349dbc7Sjsg if (r) 501c349dbc7Sjsg return r; 502c349dbc7Sjsg 503f005ef32Sjsg adev->jpeg.internal.jpeg_pitch[0] = adev->jpeg.inst->external.jpeg_pitch[0] = 504c349dbc7Sjsg SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH); 505c349dbc7Sjsg 506c349dbc7Sjsg return 0; 507c349dbc7Sjsg } 508c349dbc7Sjsg 509c349dbc7Sjsg /** 510c349dbc7Sjsg * jpeg_v1_0_sw_fini - sw fini for JPEG block 511c349dbc7Sjsg * 512c349dbc7Sjsg * @handle: amdgpu_device pointer 513c349dbc7Sjsg * 514c349dbc7Sjsg * JPEG free up sw allocation 515c349dbc7Sjsg */ 516c349dbc7Sjsg void jpeg_v1_0_sw_fini(void *handle) 517c349dbc7Sjsg { 518c349dbc7Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)handle; 519c349dbc7Sjsg 520f005ef32Sjsg amdgpu_ring_fini(adev->jpeg.inst->ring_dec); 521c349dbc7Sjsg } 522c349dbc7Sjsg 523c349dbc7Sjsg /** 524c349dbc7Sjsg * jpeg_v1_0_start - start JPEG block 525c349dbc7Sjsg * 526c349dbc7Sjsg * @adev: amdgpu_device pointer 5275ca02815Sjsg * @mode: SPG or DPG mode 528c349dbc7Sjsg * 529c349dbc7Sjsg * Setup and start the JPEG block 530c349dbc7Sjsg */ 531c349dbc7Sjsg void jpeg_v1_0_start(struct amdgpu_device *adev, int mode) 532c349dbc7Sjsg { 533f005ef32Sjsg struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec; 534c349dbc7Sjsg 535c349dbc7Sjsg if (mode == 0) { 536c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0); 537c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK | 538c349dbc7Sjsg UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); 539c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr)); 540c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr)); 541c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0); 542c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0); 543c349dbc7Sjsg WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK); 544c349dbc7Sjsg } 545c349dbc7Sjsg 546c349dbc7Sjsg /* initialize wptr */ 547c349dbc7Sjsg ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 548c349dbc7Sjsg 549c349dbc7Sjsg /* copy patch commands to the jpeg ring */ 550c349dbc7Sjsg jpeg_v1_0_decode_ring_set_patch_ring(ring, 551c349dbc7Sjsg (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission)); 552c349dbc7Sjsg } 553c349dbc7Sjsg 554c349dbc7Sjsg static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = { 555c349dbc7Sjsg .type = AMDGPU_RING_TYPE_VCN_JPEG, 556c349dbc7Sjsg .align_mask = 0xf, 557c349dbc7Sjsg .nop = PACKET0(0x81ff, 0), 558c349dbc7Sjsg .support_64bit_ptrs = false, 559c349dbc7Sjsg .no_user_fence = true, 560c349dbc7Sjsg .extra_dw = 64, 561c349dbc7Sjsg .get_rptr = jpeg_v1_0_decode_ring_get_rptr, 562c349dbc7Sjsg .get_wptr = jpeg_v1_0_decode_ring_get_wptr, 563c349dbc7Sjsg .set_wptr = jpeg_v1_0_decode_ring_set_wptr, 564*b5a27a99Sjsg .parse_cs = jpeg_v1_dec_ring_parse_cs, 565c349dbc7Sjsg .emit_frame_size = 566c349dbc7Sjsg 6 + 6 + /* hdp invalidate / flush */ 567c349dbc7Sjsg SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 568c349dbc7Sjsg SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 569c349dbc7Sjsg 8 + /* jpeg_v1_0_decode_ring_emit_vm_flush */ 570c349dbc7Sjsg 26 + 26 + /* jpeg_v1_0_decode_ring_emit_fence x2 vm fence */ 571c349dbc7Sjsg 6, 572c349dbc7Sjsg .emit_ib_size = 22, /* jpeg_v1_0_decode_ring_emit_ib */ 573c349dbc7Sjsg .emit_ib = jpeg_v1_0_decode_ring_emit_ib, 574c349dbc7Sjsg .emit_fence = jpeg_v1_0_decode_ring_emit_fence, 575c349dbc7Sjsg .emit_vm_flush = jpeg_v1_0_decode_ring_emit_vm_flush, 576c349dbc7Sjsg .test_ring = amdgpu_jpeg_dec_ring_test_ring, 577c349dbc7Sjsg .test_ib = amdgpu_jpeg_dec_ring_test_ib, 578c349dbc7Sjsg .insert_nop = jpeg_v1_0_decode_ring_nop, 579c349dbc7Sjsg .insert_start = jpeg_v1_0_decode_ring_insert_start, 580c349dbc7Sjsg .insert_end = jpeg_v1_0_decode_ring_insert_end, 581c349dbc7Sjsg .pad_ib = amdgpu_ring_generic_pad_ib, 582ad8b1aafSjsg .begin_use = jpeg_v1_0_ring_begin_use, 583ad8b1aafSjsg .end_use = vcn_v1_0_ring_end_use, 584c349dbc7Sjsg .emit_wreg = jpeg_v1_0_decode_ring_emit_wreg, 585c349dbc7Sjsg .emit_reg_wait = jpeg_v1_0_decode_ring_emit_reg_wait, 586c349dbc7Sjsg .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 587c349dbc7Sjsg }; 588c349dbc7Sjsg 589c349dbc7Sjsg static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) 590c349dbc7Sjsg { 591f005ef32Sjsg adev->jpeg.inst->ring_dec->funcs = &jpeg_v1_0_decode_ring_vm_funcs; 592c349dbc7Sjsg DRM_INFO("JPEG decode is enabled in VM mode\n"); 593c349dbc7Sjsg } 594c349dbc7Sjsg 595c349dbc7Sjsg static const struct amdgpu_irq_src_funcs jpeg_v1_0_irq_funcs = { 596c349dbc7Sjsg .set = jpeg_v1_0_set_interrupt_state, 597c349dbc7Sjsg .process = jpeg_v1_0_process_interrupt, 598c349dbc7Sjsg }; 599c349dbc7Sjsg 600c349dbc7Sjsg static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev) 601c349dbc7Sjsg { 602c349dbc7Sjsg adev->jpeg.inst->irq.funcs = &jpeg_v1_0_irq_funcs; 603c349dbc7Sjsg } 604ad8b1aafSjsg 605ad8b1aafSjsg static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring) 606ad8b1aafSjsg { 607ad8b1aafSjsg struct amdgpu_device *adev = ring->adev; 608ad8b1aafSjsg bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); 609ad8b1aafSjsg int cnt = 0; 610ad8b1aafSjsg 611ad8b1aafSjsg mutex_lock(&adev->vcn.vcn1_jpeg1_workaround); 612ad8b1aafSjsg 613ad8b1aafSjsg if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_dec)) 614ad8b1aafSjsg DRM_ERROR("JPEG dec: vcn dec ring may not be empty\n"); 615ad8b1aafSjsg 616ad8b1aafSjsg for (cnt = 0; cnt < adev->vcn.num_enc_rings; cnt++) { 617ad8b1aafSjsg if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_enc[cnt])) 618ad8b1aafSjsg DRM_ERROR("JPEG dec: vcn enc ring[%d] may not be empty\n", cnt); 619ad8b1aafSjsg } 620ad8b1aafSjsg 621ad8b1aafSjsg vcn_v1_0_set_pg_for_begin_use(ring, set_clocks); 622ad8b1aafSjsg } 623*b5a27a99Sjsg 624*b5a27a99Sjsg /** 625*b5a27a99Sjsg * jpeg_v1_dec_ring_parse_cs - command submission parser 626*b5a27a99Sjsg * 627*b5a27a99Sjsg * @parser: Command submission parser context 628*b5a27a99Sjsg * @job: the job to parse 629*b5a27a99Sjsg * @ib: the IB to parse 630*b5a27a99Sjsg * 631*b5a27a99Sjsg * Parse the command stream, return -EINVAL for invalid packet, 632*b5a27a99Sjsg * 0 otherwise 633*b5a27a99Sjsg */ 634*b5a27a99Sjsg static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser, 635*b5a27a99Sjsg struct amdgpu_job *job, 636*b5a27a99Sjsg struct amdgpu_ib *ib) 637*b5a27a99Sjsg { 638*b5a27a99Sjsg u32 i, reg, res, cond, type; 639*b5a27a99Sjsg int ret = 0; 640*b5a27a99Sjsg struct amdgpu_device *adev = parser->adev; 641*b5a27a99Sjsg 642*b5a27a99Sjsg for (i = 0; i < ib->length_dw ; i += 2) { 643*b5a27a99Sjsg reg = CP_PACKETJ_GET_REG(ib->ptr[i]); 644*b5a27a99Sjsg res = CP_PACKETJ_GET_RES(ib->ptr[i]); 645*b5a27a99Sjsg cond = CP_PACKETJ_GET_COND(ib->ptr[i]); 646*b5a27a99Sjsg type = CP_PACKETJ_GET_TYPE(ib->ptr[i]); 647*b5a27a99Sjsg 648*b5a27a99Sjsg if (res || cond != PACKETJ_CONDITION_CHECK0) /* only allow 0 for now */ 649*b5a27a99Sjsg return -EINVAL; 650*b5a27a99Sjsg 651*b5a27a99Sjsg if (reg >= JPEG_V1_REG_RANGE_START && reg <= JPEG_V1_REG_RANGE_END) 652*b5a27a99Sjsg continue; 653*b5a27a99Sjsg 654*b5a27a99Sjsg switch (type) { 655*b5a27a99Sjsg case PACKETJ_TYPE0: 656*b5a27a99Sjsg if (reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_HIGH && 657*b5a27a99Sjsg reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_LOW && 658*b5a27a99Sjsg reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_HIGH && 659*b5a27a99Sjsg reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_LOW && 660*b5a27a99Sjsg reg != JPEG_V1_REG_CTX_INDEX && 661*b5a27a99Sjsg reg != JPEG_V1_REG_CTX_DATA) { 662*b5a27a99Sjsg ret = -EINVAL; 663*b5a27a99Sjsg } 664*b5a27a99Sjsg break; 665*b5a27a99Sjsg case PACKETJ_TYPE1: 666*b5a27a99Sjsg if (reg != JPEG_V1_REG_CTX_DATA) 667*b5a27a99Sjsg ret = -EINVAL; 668*b5a27a99Sjsg break; 669*b5a27a99Sjsg case PACKETJ_TYPE3: 670*b5a27a99Sjsg if (reg != JPEG_V1_REG_SOFT_RESET) 671*b5a27a99Sjsg ret = -EINVAL; 672*b5a27a99Sjsg break; 673*b5a27a99Sjsg case PACKETJ_TYPE6: 674*b5a27a99Sjsg if (ib->ptr[i] != CP_PACKETJ_NOP) 675*b5a27a99Sjsg ret = -EINVAL; 676*b5a27a99Sjsg break; 677*b5a27a99Sjsg default: 678*b5a27a99Sjsg ret = -EINVAL; 679*b5a27a99Sjsg } 680*b5a27a99Sjsg 681*b5a27a99Sjsg if (ret) { 682*b5a27a99Sjsg dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); 683*b5a27a99Sjsg break; 684*b5a27a99Sjsg } 685*b5a27a99Sjsg } 686*b5a27a99Sjsg 687*b5a27a99Sjsg return ret; 688*b5a27a99Sjsg } 689