Rev 5078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 6104 | ||
---|---|---|---|
Line 29... | Line 29... | ||
29 | #include |
29 | #include |
30 | #include "radeon.h" |
30 | #include "radeon.h" |
31 | #include "radeon_asic.h" |
31 | #include "radeon_asic.h" |
32 | #include "sid.h" |
32 | #include "sid.h" |
Line -... | Line 33... | ||
- | 33 | ||
- | 34 | #define VCE_V1_0_FW_SIZE (256 * 1024) |
|
- | 35 | #define VCE_V1_0_STACK_SIZE (64 * 1024) |
|
- | 36 | #define VCE_V1_0_DATA_SIZE (7808 * (RADEON_MAX_VCE_HANDLES + 1)) |
|
- | 37 | ||
- | 38 | struct vce_v1_0_fw_signature |
|
- | 39 | { |
|
- | 40 | int32_t off; |
|
- | 41 | uint32_t len; |
|
- | 42 | int32_t num; |
|
- | 43 | struct { |
|
- | 44 | uint32_t chip_id; |
|
- | 45 | uint32_t keyselect; |
|
- | 46 | uint32_t nonce[4]; |
|
- | 47 | uint32_t sigval[4]; |
|
- | 48 | } val[8]; |
|
- | 49 | }; |
|
33 | 50 | ||
34 | /** |
51 | /** |
35 | * vce_v1_0_get_rptr - get read pointer |
52 | * vce_v1_0_get_rptr - get read pointer |
36 | * |
53 | * |
37 | * @rdev: radeon_device pointer |
54 | * @rdev: radeon_device pointer |
Line 80... | Line 97... | ||
80 | WREG32(VCE_RB_WPTR, ring->wptr); |
97 | WREG32(VCE_RB_WPTR, ring->wptr); |
81 | else |
98 | else |
82 | WREG32(VCE_RB_WPTR2, ring->wptr); |
99 | WREG32(VCE_RB_WPTR2, ring->wptr); |
83 | } |
100 | } |
Line -... | Line 101... | ||
- | 101 | ||
- | 102 | void vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable) |
|
- | 103 | { |
|
- | 104 | u32 tmp; |
|
- | 105 | ||
- | 106 | if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) { |
|
- | 107 | tmp = RREG32(VCE_CLOCK_GATING_A); |
|
- | 108 | tmp |= CGC_DYN_CLOCK_MODE; |
|
- | 109 | WREG32(VCE_CLOCK_GATING_A, tmp); |
|
- | 110 | ||
- | 111 | tmp = RREG32(VCE_UENC_CLOCK_GATING); |
|
- | 112 | tmp &= ~0x1ff000; |
|
- | 113 | tmp |= 0xff800000; |
|
- | 114 | WREG32(VCE_UENC_CLOCK_GATING, tmp); |
|
- | 115 | ||
- | 116 | tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); |
|
- | 117 | tmp &= ~0x3ff; |
|
- | 118 | WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); |
|
- | 119 | } else { |
|
- | 120 | tmp = RREG32(VCE_CLOCK_GATING_A); |
|
- | 121 | tmp &= ~CGC_DYN_CLOCK_MODE; |
|
- | 122 | WREG32(VCE_CLOCK_GATING_A, tmp); |
|
- | 123 | ||
- | 124 | tmp = RREG32(VCE_UENC_CLOCK_GATING); |
|
- | 125 | tmp |= 0x1ff000; |
|
- | 126 | tmp &= ~0xff800000; |
|
- | 127 | WREG32(VCE_UENC_CLOCK_GATING, tmp); |
|
- | 128 | ||
- | 129 | tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); |
|
- | 130 | tmp |= 0x3ff; |
|
- | 131 | WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); |
|
- | 132 | } |
|
- | 133 | } |
|
- | 134 | ||
- | 135 | static void vce_v1_0_init_cg(struct radeon_device *rdev) |
|
- | 136 | { |
|
- | 137 | u32 tmp; |
|
- | 138 | ||
- | 139 | tmp = RREG32(VCE_CLOCK_GATING_A); |
|
- | 140 | tmp |= CGC_DYN_CLOCK_MODE; |
|
- | 141 | WREG32(VCE_CLOCK_GATING_A, tmp); |
|
- | 142 | ||
- | 143 | tmp = RREG32(VCE_CLOCK_GATING_B); |
|
- | 144 | tmp |= 0x1e; |
|
- | 145 | tmp &= ~0xe100e1; |
|
- | 146 | WREG32(VCE_CLOCK_GATING_B, tmp); |
|
- | 147 | ||
- | 148 | tmp = RREG32(VCE_UENC_CLOCK_GATING); |
|
- | 149 | tmp &= ~0xff9ff000; |
|
- | 150 | WREG32(VCE_UENC_CLOCK_GATING, tmp); |
|
- | 151 | ||
- | 152 | tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); |
|
- | 153 | tmp &= ~0x3ff; |
|
- | 154 | WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); |
|
- | 155 | } |
|
- | 156 | ||
- | 157 | int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) |
|
- | 158 | { |
|
- | 159 | struct vce_v1_0_fw_signature *sign = (void*)rdev->vce_fw->data; |
|
- | 160 | uint32_t chip_id; |
|
- | 161 | int i; |
|
- | 162 | ||
- | 163 | switch (rdev->family) { |
|
- | 164 | case CHIP_TAHITI: |
|
- | 165 | chip_id = 0x01000014; |
|
- | 166 | break; |
|
- | 167 | case CHIP_VERDE: |
|
- | 168 | chip_id = 0x01000015; |
|
- | 169 | break; |
|
- | 170 | case CHIP_PITCAIRN: |
|
- | 171 | case CHIP_OLAND: |
|
- | 172 | chip_id = 0x01000016; |
|
- | 173 | break; |
|
- | 174 | case CHIP_ARUBA: |
|
- | 175 | chip_id = 0x01000017; |
|
- | 176 | break; |
|
- | 177 | default: |
|
- | 178 | return -EINVAL; |
|
- | 179 | } |
|
- | 180 | ||
- | 181 | for (i = 0; i < sign->num; ++i) { |
|
- | 182 | if (sign->val[i].chip_id == chip_id) |
|
- | 183 | break; |
|
- | 184 | } |
|
- | 185 | ||
- | 186 | if (i == sign->num) |
|
- | 187 | return -EINVAL; |
|
- | 188 | ||
- | 189 | data += (256 - 64) / 4; |
|
- | 190 | data[0] = sign->val[i].nonce[0]; |
|
- | 191 | data[1] = sign->val[i].nonce[1]; |
|
- | 192 | data[2] = sign->val[i].nonce[2]; |
|
- | 193 | data[3] = sign->val[i].nonce[3]; |
|
- | 194 | data[4] = sign->len + 64; |
|
- | 195 | ||
- | 196 | memset(&data[5], 0, 44); |
|
- | 197 | memcpy(&data[16], &sign[1], rdev->vce_fw->size - sizeof(*sign)); |
|
- | 198 | ||
- | 199 | data += data[4] / 4; |
|
- | 200 | data[0] = sign->val[i].sigval[0]; |
|
- | 201 | data[1] = sign->val[i].sigval[1]; |
|
- | 202 | data[2] = sign->val[i].sigval[2]; |
|
- | 203 | data[3] = sign->val[i].sigval[3]; |
|
- | 204 | ||
- | 205 | rdev->vce.keyselect = sign->val[i].keyselect; |
|
- | 206 | ||
- | 207 | return 0; |
|
- | 208 | } |
|
- | 209 | ||
- | 210 | unsigned vce_v1_0_bo_size(struct radeon_device *rdev) |
|
- | 211 | { |
|
- | 212 | WARN_ON(VCE_V1_0_FW_SIZE < rdev->vce_fw->size); |
|
- | 213 | return VCE_V1_0_FW_SIZE + VCE_V1_0_STACK_SIZE + VCE_V1_0_DATA_SIZE; |
|
- | 214 | } |
|
- | 215 | ||
- | 216 | int vce_v1_0_resume(struct radeon_device *rdev) |
|
- | 217 | { |
|
- | 218 | uint64_t addr = rdev->vce.gpu_addr; |
|
- | 219 | uint32_t size; |
|
- | 220 | int i; |
|
- | 221 | ||
- | 222 | WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16)); |
|
- | 223 | WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); |
|
- | 224 | WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); |
|
- | 225 | WREG32(VCE_CLOCK_GATING_B, 0); |
|
- | 226 | ||
- | 227 | WREG32_P(VCE_LMI_FW_PERIODIC_CTRL, 0x4, ~0x4); |
|
- | 228 | ||
- | 229 | WREG32(VCE_LMI_CTRL, 0x00398000); |
|
- | 230 | WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1); |
|
- | 231 | WREG32(VCE_LMI_SWAP_CNTL, 0); |
|
- | 232 | WREG32(VCE_LMI_SWAP_CNTL1, 0); |
|
- | 233 | WREG32(VCE_LMI_VM_CTRL, 0); |
|
- | 234 | ||
- | 235 | WREG32(VCE_VCPU_SCRATCH7, RADEON_MAX_VCE_HANDLES); |
|
- | 236 | ||
- | 237 | addr += 256; |
|
- | 238 | size = VCE_V1_0_FW_SIZE; |
|
- | 239 | WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff); |
|
- | 240 | WREG32(VCE_VCPU_CACHE_SIZE0, size); |
|
- | 241 | ||
- | 242 | addr += size; |
|
- | 243 | size = VCE_V1_0_STACK_SIZE; |
|
- | 244 | WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff); |
|
- | 245 | WREG32(VCE_VCPU_CACHE_SIZE1, size); |
|
- | 246 | ||
- | 247 | addr += size; |
|
- | 248 | size = VCE_V1_0_DATA_SIZE; |
|
- | 249 | WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff); |
|
- | 250 | WREG32(VCE_VCPU_CACHE_SIZE2, size); |
|
- | 251 | ||
- | 252 | WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100); |
|
- | 253 | ||
- | 254 | WREG32(VCE_LMI_FW_START_KEYSEL, rdev->vce.keyselect); |
|
- | 255 | ||
- | 256 | for (i = 0; i < 10; ++i) { |
|
- | 257 | mdelay(10); |
|
- | 258 | if (RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_DONE) |
|
- | 259 | break; |
|
- | 260 | } |
|
- | 261 | ||
- | 262 | if (i == 10) |
|
- | 263 | return -ETIMEDOUT; |
|
- | 264 | ||
- | 265 | if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_PASS)) |
|
- | 266 | return -EINVAL; |
|
- | 267 | ||
- | 268 | for (i = 0; i < 10; ++i) { |
|
- | 269 | mdelay(10); |
|
- | 270 | if (!(RREG32(VCE_FW_REG_STATUS) & VCE_FW_REG_STATUS_BUSY)) |
|
- | 271 | break; |
|
- | 272 | } |
|
- | 273 | ||
- | 274 | if (i == 10) |
|
- | 275 | return -ETIMEDOUT; |
|
- | 276 | ||
- | 277 | vce_v1_0_init_cg(rdev); |
|
- | 278 | ||
- | 279 | return 0; |
|
- | 280 | } |
|
84 | 281 | ||
85 | /** |
282 | /** |
86 | * vce_v1_0_start - start VCE block |
283 | * vce_v1_0_start - start VCE block |
87 | * |
284 | * |
88 | * @rdev: radeon_device pointer |
285 | * @rdev: radeon_device pointer |