Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/imagination: Implement firmware infrastructure and META FW support

The infrastructure includes parsing of the firmware image, initialising
FW-side structures, handling the kernel and firmware command
ringbuffers and starting & stopping the firmware processor.

This patch also adds the necessary support code for the META firmware
processor.

Changes since v8:
- Fix documentation for pvr_fwccb_process()
- Corrected license identifiers

Changes since v6:
- Add a minimum retry count to pvr_kccb_reserve_slot_sync()

Changes since v5:
- Add workaround for BRN 71242
- Attempt to recover GPU on MMU flush command failure

Changes since v4:
- Remove use of drm_gem_shmem_get_pages()
- Remove interrupt resource name

Changes since v3:
- Hard reset FW processor on watchdog timeout
- Switch to threaded IRQ
- Rework FW object creation/initialisation to aid hard reset
- Added MODULE_FIRMWARE()
- Use drm_dev_{enter,exit}

Signed-off-by: Sarah Walker <sarah.walker@imgtec.com>
Signed-off-by: Donald Robson <donald.robson@imgtec.com>
Link: https://lore.kernel.org/r/bb52a8dc84f296b37dc6668dfe8fbaf2ba551139.1700668843.git.donald.robson@imgtec.com
Signed-off-by: Maxime Ripard <mripard@kernel.org>

authored by

Sarah Walker and committed by
Maxime Ripard
cc1aeedb 727538a4

+4015 -24
+4
drivers/gpu/drm/imagination/Makefile
··· 4 4 subdir-ccflags-y := -I$(srctree)/$(src) 5 5 6 6 powervr-y := \ 7 + pvr_ccb.o \ 7 8 pvr_device.o \ 8 9 pvr_device_info.o \ 9 10 pvr_drv.o \ 10 11 pvr_fw.o \ 12 + pvr_fw_meta.o \ 13 + pvr_fw_startstop.o \ 14 + pvr_fw_trace.o \ 11 15 pvr_gem.o \ 12 16 pvr_mmu.o \ 13 17 pvr_power.o \
+635
drivers/gpu/drm/imagination/pvr_ccb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #include "pvr_ccb.h" 5 + #include "pvr_device.h" 6 + #include "pvr_drv.h" 7 + #include "pvr_fw.h" 8 + #include "pvr_gem.h" 9 + #include "pvr_power.h" 10 + 11 + #include <drm/drm_managed.h> 12 + #include <linux/compiler.h> 13 + #include <linux/delay.h> 14 + #include <linux/jiffies.h> 15 + #include <linux/kernel.h> 16 + #include <linux/mutex.h> 17 + #include <linux/types.h> 18 + #include <linux/workqueue.h> 19 + 20 + #define RESERVE_SLOT_TIMEOUT (1 * HZ) /* 1s */ 21 + #define RESERVE_SLOT_MIN_RETRIES 10 22 + 23 + static void 24 + ccb_ctrl_init(void *cpu_ptr, void *priv) 25 + { 26 + struct rogue_fwif_ccb_ctl *ctrl = cpu_ptr; 27 + struct pvr_ccb *pvr_ccb = priv; 28 + 29 + ctrl->write_offset = 0; 30 + ctrl->read_offset = 0; 31 + ctrl->wrap_mask = pvr_ccb->num_cmds - 1; 32 + ctrl->cmd_size = pvr_ccb->cmd_size; 33 + } 34 + 35 + /** 36 + * pvr_ccb_init() - Initialise a CCB 37 + * @pvr_dev: Device pointer. 38 + * @pvr_ccb: Pointer to CCB structure to initialise. 39 + * @num_cmds_log2: Log2 of number of commands in this CCB. 40 + * @cmd_size: Command size for this CCB. 41 + * 42 + * Return: 43 + * * Zero on success, or 44 + * * Any error code returned by pvr_fw_object_create_and_map(). 45 + */ 46 + static int 47 + pvr_ccb_init(struct pvr_device *pvr_dev, struct pvr_ccb *pvr_ccb, 48 + u32 num_cmds_log2, size_t cmd_size) 49 + { 50 + u32 num_cmds = 1 << num_cmds_log2; 51 + u32 ccb_size = num_cmds * cmd_size; 52 + int err; 53 + 54 + pvr_ccb->num_cmds = num_cmds; 55 + pvr_ccb->cmd_size = cmd_size; 56 + 57 + err = drmm_mutex_init(from_pvr_device(pvr_dev), &pvr_ccb->lock); 58 + if (err) 59 + return err; 60 + 61 + /* 62 + * Map CCB and control structure as uncached, so we don't have to flush 63 + * CPU cache repeatedly when polling for space. 64 + */ 65 + pvr_ccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, sizeof(*pvr_ccb->ctrl), 66 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 67 + ccb_ctrl_init, pvr_ccb, &pvr_ccb->ctrl_obj); 68 + if (IS_ERR(pvr_ccb->ctrl)) 69 + return PTR_ERR(pvr_ccb->ctrl); 70 + 71 + pvr_ccb->ccb = pvr_fw_object_create_and_map(pvr_dev, ccb_size, 72 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 73 + NULL, NULL, &pvr_ccb->ccb_obj); 74 + if (IS_ERR(pvr_ccb->ccb)) { 75 + err = PTR_ERR(pvr_ccb->ccb); 76 + goto err_free_ctrl; 77 + } 78 + 79 + pvr_fw_object_get_fw_addr(pvr_ccb->ctrl_obj, &pvr_ccb->ctrl_fw_addr); 80 + pvr_fw_object_get_fw_addr(pvr_ccb->ccb_obj, &pvr_ccb->ccb_fw_addr); 81 + 82 + WRITE_ONCE(pvr_ccb->ctrl->write_offset, 0); 83 + WRITE_ONCE(pvr_ccb->ctrl->read_offset, 0); 84 + WRITE_ONCE(pvr_ccb->ctrl->wrap_mask, num_cmds - 1); 85 + WRITE_ONCE(pvr_ccb->ctrl->cmd_size, cmd_size); 86 + 87 + return 0; 88 + 89 + err_free_ctrl: 90 + pvr_fw_object_unmap_and_destroy(pvr_ccb->ctrl_obj); 91 + 92 + return err; 93 + } 94 + 95 + /** 96 + * pvr_ccb_fini() - Release CCB structure 97 + * @pvr_ccb: CCB to release. 98 + */ 99 + void 100 + pvr_ccb_fini(struct pvr_ccb *pvr_ccb) 101 + { 102 + pvr_fw_object_unmap_and_destroy(pvr_ccb->ccb_obj); 103 + pvr_fw_object_unmap_and_destroy(pvr_ccb->ctrl_obj); 104 + } 105 + 106 + /** 107 + * pvr_ccb_slot_available_locked() - Test whether any slots are available in CCB 108 + * @pvr_ccb: CCB to test. 109 + * @write_offset: Address to store number of next available slot. May be %NULL. 110 + * 111 + * Caller must hold @pvr_ccb->lock. 112 + * 113 + * Return: 114 + * * %true if a slot is available, or 115 + * * %false if no slot is available. 116 + */ 117 + static __always_inline bool 118 + pvr_ccb_slot_available_locked(struct pvr_ccb *pvr_ccb, u32 *write_offset) 119 + { 120 + struct rogue_fwif_ccb_ctl *ctrl = pvr_ccb->ctrl; 121 + u32 next_write_offset = (READ_ONCE(ctrl->write_offset) + 1) & READ_ONCE(ctrl->wrap_mask); 122 + 123 + lockdep_assert_held(&pvr_ccb->lock); 124 + 125 + if (READ_ONCE(ctrl->read_offset) != next_write_offset) { 126 + if (write_offset) 127 + *write_offset = next_write_offset; 128 + return true; 129 + } 130 + 131 + return false; 132 + } 133 + 134 + static void 135 + process_fwccb_command(struct pvr_device *pvr_dev, struct rogue_fwif_fwccb_cmd *cmd) 136 + { 137 + switch (cmd->cmd_type) { 138 + case ROGUE_FWIF_FWCCB_CMD_REQUEST_GPU_RESTART: 139 + pvr_power_reset(pvr_dev, false); 140 + break; 141 + 142 + default: 143 + drm_info(from_pvr_device(pvr_dev), "Received unknown FWCCB command %x\n", 144 + cmd->cmd_type); 145 + break; 146 + } 147 + } 148 + 149 + /** 150 + * pvr_fwccb_process() - Process any pending FWCCB commands 151 + * @pvr_dev: Target PowerVR device 152 + */ 153 + void pvr_fwccb_process(struct pvr_device *pvr_dev) 154 + { 155 + struct rogue_fwif_fwccb_cmd *fwccb = pvr_dev->fwccb.ccb; 156 + struct rogue_fwif_ccb_ctl *ctrl = pvr_dev->fwccb.ctrl; 157 + u32 read_offset; 158 + 159 + mutex_lock(&pvr_dev->fwccb.lock); 160 + 161 + while ((read_offset = READ_ONCE(ctrl->read_offset)) != READ_ONCE(ctrl->write_offset)) { 162 + struct rogue_fwif_fwccb_cmd cmd = fwccb[read_offset]; 163 + 164 + WRITE_ONCE(ctrl->read_offset, (read_offset + 1) & READ_ONCE(ctrl->wrap_mask)); 165 + 166 + /* Drop FWCCB lock while we process command. */ 167 + mutex_unlock(&pvr_dev->fwccb.lock); 168 + 169 + process_fwccb_command(pvr_dev, &cmd); 170 + 171 + mutex_lock(&pvr_dev->fwccb.lock); 172 + } 173 + 174 + mutex_unlock(&pvr_dev->fwccb.lock); 175 + } 176 + 177 + /** 178 + * pvr_kccb_capacity() - Returns the maximum number of usable KCCB slots. 179 + * @pvr_dev: Target PowerVR device 180 + * 181 + * Return: 182 + * * The maximum number of active slots. 183 + */ 184 + static u32 pvr_kccb_capacity(struct pvr_device *pvr_dev) 185 + { 186 + /* Capacity is the number of slot minus one to cope with the wrapping 187 + * mechanisms. If we were to use all slots, we might end up with 188 + * read_offset == write_offset, which the FW considers as a KCCB-is-empty 189 + * condition. 190 + */ 191 + return pvr_dev->kccb.slot_count - 1; 192 + } 193 + 194 + /** 195 + * pvr_kccb_used_slot_count_locked() - Get the number of used slots 196 + * @pvr_dev: Device pointer. 197 + * 198 + * KCCB lock must be held. 199 + * 200 + * Return: 201 + * * The number of slots currently used. 202 + */ 203 + static u32 204 + pvr_kccb_used_slot_count_locked(struct pvr_device *pvr_dev) 205 + { 206 + struct pvr_ccb *pvr_ccb = &pvr_dev->kccb.ccb; 207 + struct rogue_fwif_ccb_ctl *ctrl = pvr_ccb->ctrl; 208 + u32 wr_offset = READ_ONCE(ctrl->write_offset); 209 + u32 rd_offset = READ_ONCE(ctrl->read_offset); 210 + u32 used_count; 211 + 212 + lockdep_assert_held(&pvr_ccb->lock); 213 + 214 + if (wr_offset >= rd_offset) 215 + used_count = wr_offset - rd_offset; 216 + else 217 + used_count = wr_offset + pvr_dev->kccb.slot_count - rd_offset; 218 + 219 + return used_count; 220 + } 221 + 222 + /** 223 + * pvr_kccb_send_cmd_reserved_powered() - Send command to the KCCB, with the PM ref 224 + * held and a slot pre-reserved 225 + * @pvr_dev: Device pointer. 226 + * @cmd: Command to sent. 227 + * @kccb_slot: Address to store the KCCB slot for this command. May be %NULL. 228 + */ 229 + void 230 + pvr_kccb_send_cmd_reserved_powered(struct pvr_device *pvr_dev, 231 + struct rogue_fwif_kccb_cmd *cmd, 232 + u32 *kccb_slot) 233 + { 234 + struct pvr_ccb *pvr_ccb = &pvr_dev->kccb.ccb; 235 + struct rogue_fwif_kccb_cmd *kccb = pvr_ccb->ccb; 236 + struct rogue_fwif_ccb_ctl *ctrl = pvr_ccb->ctrl; 237 + u32 old_write_offset; 238 + u32 new_write_offset; 239 + 240 + WARN_ON(pvr_dev->lost); 241 + 242 + mutex_lock(&pvr_ccb->lock); 243 + 244 + if (WARN_ON(!pvr_dev->kccb.reserved_count)) 245 + goto out_unlock; 246 + 247 + old_write_offset = READ_ONCE(ctrl->write_offset); 248 + 249 + /* We reserved the slot, we should have one available. */ 250 + if (WARN_ON(!pvr_ccb_slot_available_locked(pvr_ccb, &new_write_offset))) 251 + goto out_unlock; 252 + 253 + memcpy(&kccb[old_write_offset], cmd, 254 + sizeof(struct rogue_fwif_kccb_cmd)); 255 + if (kccb_slot) { 256 + *kccb_slot = old_write_offset; 257 + /* Clear return status for this slot. */ 258 + WRITE_ONCE(pvr_dev->kccb.rtn[old_write_offset], 259 + ROGUE_FWIF_KCCB_RTN_SLOT_NO_RESPONSE); 260 + } 261 + mb(); /* memory barrier */ 262 + WRITE_ONCE(ctrl->write_offset, new_write_offset); 263 + pvr_dev->kccb.reserved_count--; 264 + 265 + /* Kick MTS */ 266 + pvr_fw_mts_schedule(pvr_dev, 267 + PVR_FWIF_DM_GP & ~ROGUE_CR_MTS_SCHEDULE_DM_CLRMSK); 268 + 269 + out_unlock: 270 + mutex_unlock(&pvr_ccb->lock); 271 + } 272 + 273 + /** 274 + * pvr_kccb_try_reserve_slot() - Try to reserve a KCCB slot 275 + * @pvr_dev: Device pointer. 276 + * 277 + * Return: 278 + * * true if a KCCB slot was reserved, or 279 + * * false otherwise. 280 + */ 281 + static bool pvr_kccb_try_reserve_slot(struct pvr_device *pvr_dev) 282 + { 283 + bool reserved = false; 284 + u32 used_count; 285 + 286 + mutex_lock(&pvr_dev->kccb.ccb.lock); 287 + 288 + used_count = pvr_kccb_used_slot_count_locked(pvr_dev); 289 + if (pvr_dev->kccb.reserved_count < pvr_kccb_capacity(pvr_dev) - used_count) { 290 + pvr_dev->kccb.reserved_count++; 291 + reserved = true; 292 + } 293 + 294 + mutex_unlock(&pvr_dev->kccb.ccb.lock); 295 + 296 + return reserved; 297 + } 298 + 299 + /** 300 + * pvr_kccb_reserve_slot_sync() - Try to reserve a slot synchronously 301 + * @pvr_dev: Device pointer. 302 + * 303 + * Return: 304 + * * 0 on success, or 305 + * * -EBUSY if no slots were reserved after %RESERVE_SLOT_TIMEOUT, with a minimum of 306 + * %RESERVE_SLOT_MIN_RETRIES retries. 307 + */ 308 + static int pvr_kccb_reserve_slot_sync(struct pvr_device *pvr_dev) 309 + { 310 + unsigned long start_timestamp = jiffies; 311 + bool reserved = false; 312 + u32 retries = 0; 313 + 314 + while ((jiffies - start_timestamp) < (u32)RESERVE_SLOT_TIMEOUT || 315 + retries < RESERVE_SLOT_MIN_RETRIES) { 316 + reserved = pvr_kccb_try_reserve_slot(pvr_dev); 317 + if (reserved) 318 + break; 319 + 320 + usleep_range(1, 50); 321 + 322 + if (retries < U32_MAX) 323 + retries++; 324 + } 325 + 326 + return reserved ? 0 : -EBUSY; 327 + } 328 + 329 + /** 330 + * pvr_kccb_send_cmd_powered() - Send command to the KCCB, with a PM ref held 331 + * @pvr_dev: Device pointer. 332 + * @cmd: Command to sent. 333 + * @kccb_slot: Address to store the KCCB slot for this command. May be %NULL. 334 + * 335 + * Returns: 336 + * * Zero on success, or 337 + * * -EBUSY if timeout while waiting for a free KCCB slot. 338 + */ 339 + int 340 + pvr_kccb_send_cmd_powered(struct pvr_device *pvr_dev, struct rogue_fwif_kccb_cmd *cmd, 341 + u32 *kccb_slot) 342 + { 343 + int err; 344 + 345 + err = pvr_kccb_reserve_slot_sync(pvr_dev); 346 + if (err) 347 + return err; 348 + 349 + pvr_kccb_send_cmd_reserved_powered(pvr_dev, cmd, kccb_slot); 350 + return 0; 351 + } 352 + 353 + /** 354 + * pvr_kccb_send_cmd() - Send command to the KCCB 355 + * @pvr_dev: Device pointer. 356 + * @cmd: Command to sent. 357 + * @kccb_slot: Address to store the KCCB slot for this command. May be %NULL. 358 + * 359 + * Returns: 360 + * * Zero on success, or 361 + * * -EBUSY if timeout while waiting for a free KCCB slot. 362 + */ 363 + int 364 + pvr_kccb_send_cmd(struct pvr_device *pvr_dev, struct rogue_fwif_kccb_cmd *cmd, 365 + u32 *kccb_slot) 366 + { 367 + int err; 368 + 369 + err = pvr_power_get(pvr_dev); 370 + if (err) 371 + return err; 372 + 373 + err = pvr_kccb_send_cmd_powered(pvr_dev, cmd, kccb_slot); 374 + 375 + pvr_power_put(pvr_dev); 376 + 377 + return err; 378 + } 379 + 380 + /** 381 + * pvr_kccb_wait_for_completion() - Wait for a KCCB command to complete 382 + * @pvr_dev: Device pointer. 383 + * @slot_nr: KCCB slot to wait on. 384 + * @timeout: Timeout length (in jiffies). 385 + * @rtn_out: Location to store KCCB command result. May be %NULL. 386 + * 387 + * Returns: 388 + * * Zero on success, or 389 + * * -ETIMEDOUT on timeout. 390 + */ 391 + int 392 + pvr_kccb_wait_for_completion(struct pvr_device *pvr_dev, u32 slot_nr, 393 + u32 timeout, u32 *rtn_out) 394 + { 395 + int ret = wait_event_timeout(pvr_dev->kccb.rtn_q, READ_ONCE(pvr_dev->kccb.rtn[slot_nr]) & 396 + ROGUE_FWIF_KCCB_RTN_SLOT_CMD_EXECUTED, timeout); 397 + 398 + if (ret && rtn_out) 399 + *rtn_out = READ_ONCE(pvr_dev->kccb.rtn[slot_nr]); 400 + 401 + return ret ? 0 : -ETIMEDOUT; 402 + } 403 + 404 + /** 405 + * pvr_kccb_is_idle() - Returns whether the device's KCCB is idle 406 + * @pvr_dev: Device pointer 407 + * 408 + * Returns: 409 + * * %true if the KCCB is idle (contains no commands), or 410 + * * %false if the KCCB contains pending commands. 411 + */ 412 + bool 413 + pvr_kccb_is_idle(struct pvr_device *pvr_dev) 414 + { 415 + struct rogue_fwif_ccb_ctl *ctrl = pvr_dev->kccb.ccb.ctrl; 416 + bool idle; 417 + 418 + mutex_lock(&pvr_dev->kccb.ccb.lock); 419 + 420 + idle = (READ_ONCE(ctrl->write_offset) == READ_ONCE(ctrl->read_offset)); 421 + 422 + mutex_unlock(&pvr_dev->kccb.ccb.lock); 423 + 424 + return idle; 425 + } 426 + 427 + static const char * 428 + pvr_kccb_fence_get_driver_name(struct dma_fence *f) 429 + { 430 + return PVR_DRIVER_NAME; 431 + } 432 + 433 + static const char * 434 + pvr_kccb_fence_get_timeline_name(struct dma_fence *f) 435 + { 436 + return "kccb"; 437 + } 438 + 439 + static const struct dma_fence_ops pvr_kccb_fence_ops = { 440 + .get_driver_name = pvr_kccb_fence_get_driver_name, 441 + .get_timeline_name = pvr_kccb_fence_get_timeline_name, 442 + }; 443 + 444 + /** 445 + * struct pvr_kccb_fence - Fence object used to wait for a KCCB slot 446 + */ 447 + struct pvr_kccb_fence { 448 + /** @base: Base dma_fence object. */ 449 + struct dma_fence base; 450 + 451 + /** @node: Node used to insert the fence in the pvr_device::kccb::waiters list. */ 452 + struct list_head node; 453 + }; 454 + 455 + /** 456 + * pvr_kccb_wake_up_waiters() - Check the KCCB waiters 457 + * @pvr_dev: Target PowerVR device 458 + * 459 + * Signal as many KCCB fences as we have slots available. 460 + */ 461 + void pvr_kccb_wake_up_waiters(struct pvr_device *pvr_dev) 462 + { 463 + struct pvr_kccb_fence *fence, *tmp_fence; 464 + u32 used_count, available_count; 465 + 466 + /* Wake up those waiting for KCCB slot execution. */ 467 + wake_up_all(&pvr_dev->kccb.rtn_q); 468 + 469 + /* Then iterate over all KCCB fences and signal as many as we can. */ 470 + mutex_lock(&pvr_dev->kccb.ccb.lock); 471 + used_count = pvr_kccb_used_slot_count_locked(pvr_dev); 472 + 473 + if (WARN_ON(used_count + pvr_dev->kccb.reserved_count > pvr_kccb_capacity(pvr_dev))) 474 + goto out_unlock; 475 + 476 + available_count = pvr_kccb_capacity(pvr_dev) - used_count - pvr_dev->kccb.reserved_count; 477 + list_for_each_entry_safe(fence, tmp_fence, &pvr_dev->kccb.waiters, node) { 478 + if (!available_count) 479 + break; 480 + 481 + list_del(&fence->node); 482 + pvr_dev->kccb.reserved_count++; 483 + available_count--; 484 + dma_fence_signal(&fence->base); 485 + dma_fence_put(&fence->base); 486 + } 487 + 488 + out_unlock: 489 + mutex_unlock(&pvr_dev->kccb.ccb.lock); 490 + } 491 + 492 + /** 493 + * pvr_kccb_fini() - Cleanup device KCCB 494 + * @pvr_dev: Target PowerVR device 495 + */ 496 + void pvr_kccb_fini(struct pvr_device *pvr_dev) 497 + { 498 + pvr_ccb_fini(&pvr_dev->kccb.ccb); 499 + WARN_ON(!list_empty(&pvr_dev->kccb.waiters)); 500 + WARN_ON(pvr_dev->kccb.reserved_count); 501 + } 502 + 503 + /** 504 + * pvr_kccb_init() - Initialise device KCCB 505 + * @pvr_dev: Target PowerVR device 506 + * 507 + * Returns: 508 + * * 0 on success, or 509 + * * Any error returned by pvr_ccb_init(). 510 + */ 511 + int 512 + pvr_kccb_init(struct pvr_device *pvr_dev) 513 + { 514 + pvr_dev->kccb.slot_count = 1 << ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; 515 + INIT_LIST_HEAD(&pvr_dev->kccb.waiters); 516 + pvr_dev->kccb.fence_ctx.id = dma_fence_context_alloc(1); 517 + spin_lock_init(&pvr_dev->kccb.fence_ctx.lock); 518 + 519 + return pvr_ccb_init(pvr_dev, &pvr_dev->kccb.ccb, 520 + ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT, 521 + sizeof(struct rogue_fwif_kccb_cmd)); 522 + } 523 + 524 + /** 525 + * pvr_kccb_fence_alloc() - Allocate a pvr_kccb_fence object 526 + * 527 + * Return: 528 + * * NULL if the allocation fails, or 529 + * * A valid dma_fence pointer otherwise. 530 + */ 531 + struct dma_fence *pvr_kccb_fence_alloc(void) 532 + { 533 + struct pvr_kccb_fence *kccb_fence; 534 + 535 + kccb_fence = kzalloc(sizeof(*kccb_fence), GFP_KERNEL); 536 + if (!kccb_fence) 537 + return NULL; 538 + 539 + return &kccb_fence->base; 540 + } 541 + 542 + /** 543 + * pvr_kccb_fence_put() - Drop a KCCB fence reference 544 + * @fence: The fence to drop the reference on. 545 + * 546 + * If the fence hasn't been initialized yet, dma_fence_free() is called. This 547 + * way we have a single function taking care of both cases. 548 + */ 549 + void pvr_kccb_fence_put(struct dma_fence *fence) 550 + { 551 + if (!fence) 552 + return; 553 + 554 + if (!fence->ops) { 555 + dma_fence_free(fence); 556 + } else { 557 + WARN_ON(fence->ops != &pvr_kccb_fence_ops); 558 + dma_fence_put(fence); 559 + } 560 + } 561 + 562 + /** 563 + * pvr_kccb_reserve_slot() - Reserve a KCCB slot for later use 564 + * @pvr_dev: Target PowerVR device 565 + * @f: KCCB fence object previously allocated with pvr_kccb_fence_alloc() 566 + * 567 + * Try to reserve a KCCB slot, and if there's no slot available, 568 + * initializes the fence object and queue it to the waiters list. 569 + * 570 + * If NULL is returned, that means the slot is reserved. In that case, 571 + * the @f is freed and shouldn't be accessed after that point. 572 + * 573 + * Return: 574 + * * NULL if a slot was available directly, or 575 + * * A valid dma_fence object to wait on if no slot was available. 576 + */ 577 + struct dma_fence * 578 + pvr_kccb_reserve_slot(struct pvr_device *pvr_dev, struct dma_fence *f) 579 + { 580 + struct pvr_kccb_fence *fence = container_of(f, struct pvr_kccb_fence, base); 581 + struct dma_fence *out_fence = NULL; 582 + u32 used_count; 583 + 584 + mutex_lock(&pvr_dev->kccb.ccb.lock); 585 + 586 + used_count = pvr_kccb_used_slot_count_locked(pvr_dev); 587 + if (pvr_dev->kccb.reserved_count >= pvr_kccb_capacity(pvr_dev) - used_count) { 588 + dma_fence_init(&fence->base, &pvr_kccb_fence_ops, 589 + &pvr_dev->kccb.fence_ctx.lock, 590 + pvr_dev->kccb.fence_ctx.id, 591 + atomic_inc_return(&pvr_dev->kccb.fence_ctx.seqno)); 592 + out_fence = dma_fence_get(&fence->base); 593 + list_add_tail(&fence->node, &pvr_dev->kccb.waiters); 594 + } else { 595 + pvr_kccb_fence_put(f); 596 + pvr_dev->kccb.reserved_count++; 597 + } 598 + 599 + mutex_unlock(&pvr_dev->kccb.ccb.lock); 600 + 601 + return out_fence; 602 + } 603 + 604 + /** 605 + * pvr_kccb_release_slot() - Release a KCCB slot reserved with 606 + * pvr_kccb_reserve_slot() 607 + * @pvr_dev: Target PowerVR device 608 + * 609 + * Should only be called if something failed after the 610 + * pvr_kccb_reserve_slot() call and you know you won't call 611 + * pvr_kccb_send_cmd_reserved(). 612 + */ 613 + void pvr_kccb_release_slot(struct pvr_device *pvr_dev) 614 + { 615 + mutex_lock(&pvr_dev->kccb.ccb.lock); 616 + if (!WARN_ON(!pvr_dev->kccb.reserved_count)) 617 + pvr_dev->kccb.reserved_count--; 618 + mutex_unlock(&pvr_dev->kccb.ccb.lock); 619 + } 620 + 621 + /** 622 + * pvr_fwccb_init() - Initialise device FWCCB 623 + * @pvr_dev: Target PowerVR device 624 + * 625 + * Returns: 626 + * * 0 on success, or 627 + * * Any error returned by pvr_ccb_init(). 628 + */ 629 + int 630 + pvr_fwccb_init(struct pvr_device *pvr_dev) 631 + { 632 + return pvr_ccb_init(pvr_dev, &pvr_dev->fwccb, 633 + ROGUE_FWIF_FWCCB_NUMCMDS_LOG2, 634 + sizeof(struct rogue_fwif_fwccb_cmd)); 635 + }
+71
drivers/gpu/drm/imagination/pvr_ccb.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #ifndef PVR_CCB_H 5 + #define PVR_CCB_H 6 + 7 + #include "pvr_rogue_fwif.h" 8 + 9 + #include <linux/mutex.h> 10 + #include <linux/types.h> 11 + 12 + /* Forward declaration from pvr_device.h. */ 13 + struct pvr_device; 14 + 15 + /* Forward declaration from pvr_gem.h. */ 16 + struct pvr_fw_object; 17 + 18 + struct pvr_ccb { 19 + /** @ctrl_obj: FW object representing CCB control structure. */ 20 + struct pvr_fw_object *ctrl_obj; 21 + /** @ccb_obj: FW object representing CCB. */ 22 + struct pvr_fw_object *ccb_obj; 23 + 24 + /** @ctrl_fw_addr: FW virtual address of CCB control structure. */ 25 + u32 ctrl_fw_addr; 26 + /** @ccb_fw_addr: FW virtual address of CCB. */ 27 + u32 ccb_fw_addr; 28 + 29 + /** @num_cmds: Number of commands in this CCB. */ 30 + u32 num_cmds; 31 + 32 + /** @cmd_size: Size of each command in this CCB, in bytes. */ 33 + u32 cmd_size; 34 + 35 + /** @lock: Mutex protecting @ctrl and @ccb. */ 36 + struct mutex lock; 37 + /** 38 + * @ctrl: Kernel mapping of CCB control structure. @lock must be held 39 + * when accessing. 40 + */ 41 + struct rogue_fwif_ccb_ctl *ctrl; 42 + /** @ccb: Kernel mapping of CCB. @lock must be held when accessing. */ 43 + void *ccb; 44 + }; 45 + 46 + int pvr_kccb_init(struct pvr_device *pvr_dev); 47 + void pvr_kccb_fini(struct pvr_device *pvr_dev); 48 + int pvr_fwccb_init(struct pvr_device *pvr_dev); 49 + void pvr_ccb_fini(struct pvr_ccb *ccb); 50 + 51 + void pvr_fwccb_process(struct pvr_device *pvr_dev); 52 + 53 + struct dma_fence *pvr_kccb_fence_alloc(void); 54 + void pvr_kccb_fence_put(struct dma_fence *fence); 55 + struct dma_fence * 56 + pvr_kccb_reserve_slot(struct pvr_device *pvr_dev, struct dma_fence *f); 57 + void pvr_kccb_release_slot(struct pvr_device *pvr_dev); 58 + int pvr_kccb_send_cmd(struct pvr_device *pvr_dev, 59 + struct rogue_fwif_kccb_cmd *cmd, u32 *kccb_slot); 60 + int pvr_kccb_send_cmd_powered(struct pvr_device *pvr_dev, 61 + struct rogue_fwif_kccb_cmd *cmd, 62 + u32 *kccb_slot); 63 + void pvr_kccb_send_cmd_reserved_powered(struct pvr_device *pvr_dev, 64 + struct rogue_fwif_kccb_cmd *cmd, 65 + u32 *kccb_slot); 66 + int pvr_kccb_wait_for_completion(struct pvr_device *pvr_dev, u32 slot_nr, u32 timeout, 67 + u32 *rtn_out); 68 + bool pvr_kccb_is_idle(struct pvr_device *pvr_dev); 69 + void pvr_kccb_wake_up_waiters(struct pvr_device *pvr_dev); 70 + 71 + #endif /* PVR_CCB_H */
+103
drivers/gpu/drm/imagination/pvr_device.c
··· 114 114 return 0; 115 115 } 116 116 117 + static irqreturn_t pvr_device_irq_thread_handler(int irq, void *data) 118 + { 119 + struct pvr_device *pvr_dev = data; 120 + irqreturn_t ret = IRQ_NONE; 121 + 122 + /* We are in the threaded handler, we can keep dequeuing events until we 123 + * don't see any. This should allow us to reduce the number of interrupts 124 + * when the GPU is receiving a massive amount of short jobs. 125 + */ 126 + while (pvr_fw_irq_pending(pvr_dev)) { 127 + pvr_fw_irq_clear(pvr_dev); 128 + 129 + if (pvr_dev->fw_dev.booted) { 130 + pvr_fwccb_process(pvr_dev); 131 + pvr_kccb_wake_up_waiters(pvr_dev); 132 + } 133 + 134 + pm_runtime_mark_last_busy(from_pvr_device(pvr_dev)->dev); 135 + 136 + ret = IRQ_HANDLED; 137 + } 138 + 139 + /* Unmask FW irqs before returning, so new interrupts can be received. */ 140 + pvr_fw_irq_enable(pvr_dev); 141 + return ret; 142 + } 143 + 144 + static irqreturn_t pvr_device_irq_handler(int irq, void *data) 145 + { 146 + struct pvr_device *pvr_dev = data; 147 + 148 + if (!pvr_fw_irq_pending(pvr_dev)) 149 + return IRQ_NONE; /* Spurious IRQ - ignore. */ 150 + 151 + /* Mask the FW interrupts before waking up the thread. Will be unmasked 152 + * when the thread handler is done processing events. 153 + */ 154 + pvr_fw_irq_disable(pvr_dev); 155 + return IRQ_WAKE_THREAD; 156 + } 157 + 158 + /** 159 + * pvr_device_irq_init() - Initialise IRQ required by a PowerVR device 160 + * @pvr_dev: Target PowerVR device. 161 + * 162 + * Returns: 163 + * * 0 on success, 164 + * * Any error returned by platform_get_irq_byname(), or 165 + * * Any error returned by request_irq(). 166 + */ 167 + static int 168 + pvr_device_irq_init(struct pvr_device *pvr_dev) 169 + { 170 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 171 + struct platform_device *plat_dev = to_platform_device(drm_dev->dev); 172 + 173 + init_waitqueue_head(&pvr_dev->kccb.rtn_q); 174 + 175 + pvr_dev->irq = platform_get_irq(plat_dev, 0); 176 + if (pvr_dev->irq < 0) 177 + return pvr_dev->irq; 178 + 179 + /* Clear any pending events before requesting the IRQ line. */ 180 + pvr_fw_irq_clear(pvr_dev); 181 + pvr_fw_irq_enable(pvr_dev); 182 + 183 + return request_threaded_irq(pvr_dev->irq, pvr_device_irq_handler, 184 + pvr_device_irq_thread_handler, 185 + IRQF_SHARED, "gpu", pvr_dev); 186 + } 187 + 188 + /** 189 + * pvr_device_irq_fini() - Deinitialise IRQ required by a PowerVR device 190 + * @pvr_dev: Target PowerVR device. 191 + */ 192 + static void 193 + pvr_device_irq_fini(struct pvr_device *pvr_dev) 194 + { 195 + free_irq(pvr_dev->irq, pvr_dev); 196 + } 197 + 117 198 /** 118 199 * pvr_build_firmware_filename() - Construct a PowerVR firmware filename 119 200 * @pvr_dev: Target PowerVR device. ··· 405 324 return PTR_ERR(pvr_dev->kernel_vm_ctx); 406 325 } 407 326 327 + err = pvr_fw_init(pvr_dev); 328 + if (err) 329 + goto err_vm_ctx_put; 330 + 408 331 return 0; 332 + 333 + err_vm_ctx_put: 334 + if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { 335 + pvr_vm_context_put(pvr_dev->kernel_vm_ctx); 336 + pvr_dev->kernel_vm_ctx = NULL; 337 + } 338 + 339 + return err; 409 340 } 410 341 411 342 /** ··· 427 334 static void 428 335 pvr_device_gpu_fini(struct pvr_device *pvr_dev) 429 336 { 337 + pvr_fw_fini(pvr_dev); 338 + 430 339 if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { 431 340 WARN_ON(!pvr_vm_context_put(pvr_dev->kernel_vm_ctx)); 432 341 pvr_dev->kernel_vm_ctx = NULL; ··· 481 386 if (err) 482 387 goto err_pm_runtime_put; 483 388 389 + err = pvr_device_irq_init(pvr_dev); 390 + if (err) 391 + goto err_device_gpu_fini; 392 + 484 393 pm_runtime_put(dev); 485 394 486 395 return 0; 396 + 397 + err_device_gpu_fini: 398 + pvr_device_gpu_fini(pvr_dev); 487 399 488 400 err_pm_runtime_put: 489 401 pm_runtime_put_sync_suspend(dev); ··· 509 407 * Deinitialization stages are performed in reverse order compared to 510 408 * the initialization stages in pvr_device_init(). 511 409 */ 410 + pvr_device_irq_fini(pvr_dev); 512 411 pvr_device_gpu_fini(pvr_dev); 513 412 } 514 413
+60
drivers/gpu/drm/imagination/pvr_device.h
··· 4 4 #ifndef PVR_DEVICE_H 5 5 #define PVR_DEVICE_H 6 6 7 + #include "pvr_ccb.h" 7 8 #include "pvr_device_info.h" 8 9 #include "pvr_fw.h" 9 10 ··· 124 123 */ 125 124 struct clk *mem_clk; 126 125 126 + /** @irq: IRQ number. */ 127 + int irq; 128 + 129 + /** @fwccb: Firmware CCB. */ 130 + struct pvr_ccb fwccb; 131 + 127 132 /** 128 133 * @kernel_vm_ctx: Virtual memory context used for kernel mappings. 129 134 * ··· 160 153 u32 kccb_stall_count; 161 154 } watchdog; 162 155 156 + struct { 157 + /** @ccb: Kernel CCB. */ 158 + struct pvr_ccb ccb; 159 + 160 + /** @rtn_q: Waitqueue for KCCB command return waiters. */ 161 + wait_queue_head_t rtn_q; 162 + 163 + /** @rtn_obj: Object representing KCCB return slots. */ 164 + struct pvr_fw_object *rtn_obj; 165 + 166 + /** 167 + * @rtn: Pointer to CPU mapping of KCCB return slots. Must be accessed by 168 + * READ_ONCE()/WRITE_ONCE(). 169 + */ 170 + u32 *rtn; 171 + 172 + /** @slot_count: Total number of KCCB slots available. */ 173 + u32 slot_count; 174 + 175 + /** @reserved_count: Number of KCCB slots reserved for future use. */ 176 + u32 reserved_count; 177 + 178 + /** 179 + * @waiters: List of KCCB slot waiters. 180 + */ 181 + struct list_head waiters; 182 + 183 + /** @fence_ctx: KCCB fence context. */ 184 + struct { 185 + /** @id: KCCB fence context ID allocated with dma_fence_context_alloc(). */ 186 + u64 id; 187 + 188 + /** @seqno: Sequence number incremented each time a fence is created. */ 189 + atomic_t seqno; 190 + 191 + /** 192 + * @lock: Lock used to synchronize access to fences allocated by this 193 + * context. 194 + */ 195 + spinlock_t lock; 196 + } fence_ctx; 197 + } kccb; 198 + 163 199 /** 164 200 * @lost: %true if the device has been lost. 165 201 * ··· 210 160 * firmware processor has stopped responding and can not be revived via a hard reset. 211 161 */ 212 162 bool lost; 163 + 164 + /** 165 + * @reset_sem: Reset semaphore. 166 + * 167 + * GPU reset code will lock this for writing. Any code that submits commands to the firmware 168 + * that isn't in an IRQ handler or on the scheduler workqueue must lock this for reading. 169 + * Once this has been successfully locked, &pvr_dev->lost _must_ be checked, and -%EIO must 170 + * be returned if it is set. 171 + */ 172 + struct rw_semaphore reset_sem; 213 173 214 174 /** @sched_wq: Workqueue for schedulers. */ 215 175 struct workqueue_struct *sched_wq;
+1
drivers/gpu/drm/imagination/pvr_drv.c
··· 1331 1331 MODULE_DESCRIPTION(PVR_DRIVER_DESC); 1332 1332 MODULE_LICENSE("Dual MIT/GPL"); 1333 1333 MODULE_IMPORT_NS(DMA_BUF); 1334 + MODULE_FIRMWARE("powervr/rogue_33.15.11.3_v1.fw");
+1342
drivers/gpu/drm/imagination/pvr_fw.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 2 /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 3 4 + #include "pvr_ccb.h" 4 5 #include "pvr_device.h" 5 6 #include "pvr_device_info.h" 6 7 #include "pvr_fw.h" 8 + #include "pvr_fw_info.h" 9 + #include "pvr_fw_startstop.h" 10 + #include "pvr_fw_trace.h" 11 + #include "pvr_gem.h" 12 + #include "pvr_power.h" 13 + #include "pvr_rogue_fwif_dev_info.h" 14 + #include "pvr_rogue_heap_config.h" 15 + #include "pvr_vm.h" 7 16 8 17 #include <drm/drm_drv.h> 18 + #include <drm/drm_managed.h> 19 + #include <drm/drm_mm.h> 20 + #include <linux/clk.h> 9 21 #include <linux/firmware.h> 22 + #include <linux/math.h> 23 + #include <linux/minmax.h> 10 24 #include <linux/sizes.h> 11 25 12 26 #define FW_MAX_SUPPORTED_MAJOR_VERSION 1 27 + 28 + #define FW_BOOT_TIMEOUT_USEC 5000000 29 + 30 + /* Config heap occupies top 192k of the firmware heap. */ 31 + #define PVR_ROGUE_FW_CONFIG_HEAP_GRANULARITY SZ_64K 32 + #define PVR_ROGUE_FW_CONFIG_HEAP_SIZE (3 * PVR_ROGUE_FW_CONFIG_HEAP_GRANULARITY) 33 + 34 + /* Main firmware allocations should come from the remainder of the heap. */ 35 + #define PVR_ROGUE_FW_MAIN_HEAP_BASE ROGUE_FW_HEAP_BASE 36 + 37 + /* Offsets from start of configuration area of FW heap. */ 38 + #define PVR_ROGUE_FWIF_CONNECTION_CTL_OFFSET 0 39 + #define PVR_ROGUE_FWIF_OSINIT_OFFSET \ 40 + (PVR_ROGUE_FWIF_CONNECTION_CTL_OFFSET + PVR_ROGUE_FW_CONFIG_HEAP_GRANULARITY) 41 + #define PVR_ROGUE_FWIF_SYSINIT_OFFSET \ 42 + (PVR_ROGUE_FWIF_OSINIT_OFFSET + PVR_ROGUE_FW_CONFIG_HEAP_GRANULARITY) 43 + 44 + #define PVR_ROGUE_FAULT_PAGE_SIZE SZ_4K 45 + 46 + #define PVR_SYNC_OBJ_SIZE sizeof(u32) 47 + 48 + const struct pvr_fw_layout_entry * 49 + pvr_fw_find_layout_entry(struct pvr_device *pvr_dev, enum pvr_fw_section_id id) 50 + { 51 + const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; 52 + u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; 53 + u32 entry; 54 + 55 + for (entry = 0; entry < num_layout_entries; entry++) { 56 + if (layout_entries[entry].id == id) 57 + return &layout_entries[entry]; 58 + } 59 + 60 + return NULL; 61 + } 62 + 63 + static const struct pvr_fw_layout_entry * 64 + pvr_fw_find_private_data(struct pvr_device *pvr_dev) 65 + { 66 + const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; 67 + u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; 68 + u32 entry; 69 + 70 + for (entry = 0; entry < num_layout_entries; entry++) { 71 + if (layout_entries[entry].id == META_PRIVATE_DATA || 72 + layout_entries[entry].id == MIPS_PRIVATE_DATA || 73 + layout_entries[entry].id == RISCV_PRIVATE_DATA) 74 + return &layout_entries[entry]; 75 + } 76 + 77 + return NULL; 78 + } 79 + 80 + #define DEV_INFO_MASK_SIZE(x) DIV_ROUND_UP(x, 64) 13 81 14 82 /** 15 83 * pvr_fw_validate() - Parse firmware header and check compatibility ··· 190 122 header->feature_param_size); 191 123 } 192 124 125 + static void 126 + layout_get_sizes(struct pvr_device *pvr_dev) 127 + { 128 + const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; 129 + u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; 130 + struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; 131 + 132 + fw_mem->code_alloc_size = 0; 133 + fw_mem->data_alloc_size = 0; 134 + fw_mem->core_code_alloc_size = 0; 135 + fw_mem->core_data_alloc_size = 0; 136 + 137 + /* Extract section sizes from FW layout table. */ 138 + for (u32 entry = 0; entry < num_layout_entries; entry++) { 139 + switch (layout_entries[entry].type) { 140 + case FW_CODE: 141 + fw_mem->code_alloc_size += layout_entries[entry].alloc_size; 142 + break; 143 + case FW_DATA: 144 + fw_mem->data_alloc_size += layout_entries[entry].alloc_size; 145 + break; 146 + case FW_COREMEM_CODE: 147 + fw_mem->core_code_alloc_size += 148 + layout_entries[entry].alloc_size; 149 + break; 150 + case FW_COREMEM_DATA: 151 + fw_mem->core_data_alloc_size += 152 + layout_entries[entry].alloc_size; 153 + break; 154 + case NONE: 155 + break; 156 + } 157 + } 158 + } 159 + 160 + int 161 + pvr_fw_find_mmu_segment(struct pvr_device *pvr_dev, u32 addr, u32 size, void *fw_code_ptr, 162 + void *fw_data_ptr, void *fw_core_code_ptr, void *fw_core_data_ptr, 163 + void **host_addr_out) 164 + { 165 + const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; 166 + u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; 167 + u32 end_addr = addr + size; 168 + int entry = 0; 169 + 170 + /* Ensure requested range is not zero, and size is not causing addr to overflow. */ 171 + if (end_addr <= addr) 172 + return -EINVAL; 173 + 174 + for (entry = 0; entry < num_layout_entries; entry++) { 175 + u32 entry_start_addr = layout_entries[entry].base_addr; 176 + u32 entry_end_addr = entry_start_addr + layout_entries[entry].alloc_size; 177 + 178 + if (addr >= entry_start_addr && addr < entry_end_addr && 179 + end_addr > entry_start_addr && end_addr <= entry_end_addr) { 180 + switch (layout_entries[entry].type) { 181 + case FW_CODE: 182 + *host_addr_out = fw_code_ptr; 183 + break; 184 + 185 + case FW_DATA: 186 + *host_addr_out = fw_data_ptr; 187 + break; 188 + 189 + case FW_COREMEM_CODE: 190 + *host_addr_out = fw_core_code_ptr; 191 + break; 192 + 193 + case FW_COREMEM_DATA: 194 + *host_addr_out = fw_core_data_ptr; 195 + break; 196 + 197 + default: 198 + return -EINVAL; 199 + } 200 + /* Direct Mem write to mapped memory */ 201 + addr -= layout_entries[entry].base_addr; 202 + addr += layout_entries[entry].alloc_offset; 203 + 204 + /* 205 + * Add offset to pointer to FW allocation only if that 206 + * allocation is available 207 + */ 208 + *(u8 **)host_addr_out += addr; 209 + return 0; 210 + } 211 + } 212 + 213 + return -EINVAL; 214 + } 215 + 216 + static int 217 + pvr_fw_create_fwif_connection_ctl(struct pvr_device *pvr_dev) 218 + { 219 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 220 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 221 + 222 + fw_dev->fwif_connection_ctl = 223 + pvr_fw_object_create_and_map_offset(pvr_dev, 224 + fw_dev->fw_heap_info.config_offset + 225 + PVR_ROGUE_FWIF_CONNECTION_CTL_OFFSET, 226 + sizeof(*fw_dev->fwif_connection_ctl), 227 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 228 + NULL, NULL, 229 + &fw_dev->mem.fwif_connection_ctl_obj); 230 + if (IS_ERR(fw_dev->fwif_connection_ctl)) { 231 + drm_err(drm_dev, 232 + "Unable to allocate FWIF connection control memory\n"); 233 + return PTR_ERR(fw_dev->fwif_connection_ctl); 234 + } 235 + 236 + return 0; 237 + } 238 + 239 + static void 240 + pvr_fw_fini_fwif_connection_ctl(struct pvr_device *pvr_dev) 241 + { 242 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 243 + 244 + pvr_fw_object_unmap_and_destroy(fw_dev->mem.fwif_connection_ctl_obj); 245 + } 246 + 247 + static void 248 + fw_osinit_init(void *cpu_ptr, void *priv) 249 + { 250 + struct rogue_fwif_osinit *fwif_osinit = cpu_ptr; 251 + struct pvr_device *pvr_dev = priv; 252 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 253 + struct pvr_fw_mem *fw_mem = &fw_dev->mem; 254 + 255 + fwif_osinit->kernel_ccbctl_fw_addr = pvr_dev->kccb.ccb.ctrl_fw_addr; 256 + fwif_osinit->kernel_ccb_fw_addr = pvr_dev->kccb.ccb.ccb_fw_addr; 257 + pvr_fw_object_get_fw_addr(pvr_dev->kccb.rtn_obj, 258 + &fwif_osinit->kernel_ccb_rtn_slots_fw_addr); 259 + 260 + fwif_osinit->firmware_ccbctl_fw_addr = pvr_dev->fwccb.ctrl_fw_addr; 261 + fwif_osinit->firmware_ccb_fw_addr = pvr_dev->fwccb.ccb_fw_addr; 262 + 263 + fwif_osinit->work_est_firmware_ccbctl_fw_addr = 0; 264 + fwif_osinit->work_est_firmware_ccb_fw_addr = 0; 265 + 266 + pvr_fw_object_get_fw_addr(fw_mem->hwrinfobuf_obj, 267 + &fwif_osinit->rogue_fwif_hwr_info_buf_ctl_fw_addr); 268 + pvr_fw_object_get_fw_addr(fw_mem->osdata_obj, &fwif_osinit->fw_os_data_fw_addr); 269 + 270 + fwif_osinit->hwr_debug_dump_limit = 0; 271 + 272 + rogue_fwif_compchecks_bvnc_init(&fwif_osinit->rogue_comp_checks.hw_bvnc); 273 + rogue_fwif_compchecks_bvnc_init(&fwif_osinit->rogue_comp_checks.fw_bvnc); 274 + } 275 + 276 + static void 277 + fw_osdata_init(void *cpu_ptr, void *priv) 278 + { 279 + struct rogue_fwif_osdata *fwif_osdata = cpu_ptr; 280 + struct pvr_device *pvr_dev = priv; 281 + struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; 282 + 283 + pvr_fw_object_get_fw_addr(fw_mem->power_sync_obj, &fwif_osdata->power_sync_fw_addr); 284 + } 285 + 286 + static void 287 + fw_fault_page_init(void *cpu_ptr, void *priv) 288 + { 289 + u32 *fault_page = cpu_ptr; 290 + 291 + for (int i = 0; i < PVR_ROGUE_FAULT_PAGE_SIZE / sizeof(*fault_page); i++) 292 + fault_page[i] = 0xdeadbee0; 293 + } 294 + 295 + static void 296 + fw_sysinit_init(void *cpu_ptr, void *priv) 297 + { 298 + struct rogue_fwif_sysinit *fwif_sysinit = cpu_ptr; 299 + struct pvr_device *pvr_dev = priv; 300 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 301 + struct pvr_fw_mem *fw_mem = &fw_dev->mem; 302 + dma_addr_t fault_dma_addr = 0; 303 + u32 clock_speed_hz = clk_get_rate(pvr_dev->core_clk); 304 + 305 + WARN_ON(!clock_speed_hz); 306 + 307 + WARN_ON(pvr_fw_object_get_dma_addr(fw_mem->fault_page_obj, 0, &fault_dma_addr)); 308 + fwif_sysinit->fault_phys_addr = (u64)fault_dma_addr; 309 + 310 + fwif_sysinit->pds_exec_base = ROGUE_PDSCODEDATA_HEAP_BASE; 311 + fwif_sysinit->usc_exec_base = ROGUE_USCCODE_HEAP_BASE; 312 + 313 + pvr_fw_object_get_fw_addr(fw_mem->runtime_cfg_obj, &fwif_sysinit->runtime_cfg_fw_addr); 314 + pvr_fw_object_get_fw_addr(fw_dev->fw_trace.tracebuf_ctrl_obj, 315 + &fwif_sysinit->trace_buf_ctl_fw_addr); 316 + pvr_fw_object_get_fw_addr(fw_mem->sysdata_obj, &fwif_sysinit->fw_sys_data_fw_addr); 317 + pvr_fw_object_get_fw_addr(fw_mem->gpu_util_fwcb_obj, 318 + &fwif_sysinit->gpu_util_fw_cb_ctl_fw_addr); 319 + if (fw_mem->core_data_obj) { 320 + pvr_fw_object_get_fw_addr(fw_mem->core_data_obj, 321 + &fwif_sysinit->coremem_data_store.fw_addr); 322 + } 323 + 324 + /* Currently unsupported. */ 325 + fwif_sysinit->counter_dump_ctl.buffer_fw_addr = 0; 326 + fwif_sysinit->counter_dump_ctl.size_in_dwords = 0; 327 + 328 + /* Skip alignment checks. */ 329 + fwif_sysinit->align_checks = 0; 330 + 331 + fwif_sysinit->filter_flags = 0; 332 + fwif_sysinit->hw_perf_filter = 0; 333 + fwif_sysinit->firmware_perf = FW_PERF_CONF_NONE; 334 + fwif_sysinit->initial_core_clock_speed = clock_speed_hz; 335 + fwif_sysinit->active_pm_latency_ms = 0; 336 + fwif_sysinit->gpio_validation_mode = ROGUE_FWIF_GPIO_VAL_OFF; 337 + fwif_sysinit->firmware_started = false; 338 + fwif_sysinit->marker_val = 1; 339 + 340 + memset(&fwif_sysinit->bvnc_km_feature_flags, 0, 341 + sizeof(fwif_sysinit->bvnc_km_feature_flags)); 342 + } 343 + 344 + #define ROGUE_FWIF_SLC_MIN_SIZE_FOR_DM_OVERLAP_KB 4 345 + 346 + static void 347 + fw_sysdata_init(void *cpu_ptr, void *priv) 348 + { 349 + struct rogue_fwif_sysdata *fwif_sysdata = cpu_ptr; 350 + struct pvr_device *pvr_dev = priv; 351 + u32 slc_size_in_kilobytes = 0; 352 + u32 config_flags = 0; 353 + 354 + WARN_ON(PVR_FEATURE_VALUE(pvr_dev, slc_size_in_kilobytes, &slc_size_in_kilobytes)); 355 + 356 + if (slc_size_in_kilobytes < ROGUE_FWIF_SLC_MIN_SIZE_FOR_DM_OVERLAP_KB) 357 + config_flags |= ROGUE_FWIF_INICFG_DISABLE_DM_OVERLAP; 358 + 359 + fwif_sysdata->config_flags = config_flags; 360 + } 361 + 362 + static void 363 + fw_runtime_cfg_init(void *cpu_ptr, void *priv) 364 + { 365 + struct rogue_fwif_runtime_cfg *runtime_cfg = cpu_ptr; 366 + struct pvr_device *pvr_dev = priv; 367 + u32 clock_speed_hz = clk_get_rate(pvr_dev->core_clk); 368 + 369 + WARN_ON(!clock_speed_hz); 370 + 371 + runtime_cfg->core_clock_speed = clock_speed_hz; 372 + runtime_cfg->active_pm_latency_ms = 0; 373 + runtime_cfg->active_pm_latency_persistant = true; 374 + WARN_ON(PVR_FEATURE_VALUE(pvr_dev, num_clusters, 375 + &runtime_cfg->default_dusts_num_init) != 0); 376 + } 377 + 378 + static void 379 + fw_gpu_util_fwcb_init(void *cpu_ptr, void *priv) 380 + { 381 + struct rogue_fwif_gpu_util_fwcb *gpu_util_fwcb = cpu_ptr; 382 + 383 + gpu_util_fwcb->last_word = PVR_FWIF_GPU_UTIL_STATE_IDLE; 384 + } 385 + 386 + static int 387 + pvr_fw_create_structures(struct pvr_device *pvr_dev) 388 + { 389 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 390 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 391 + struct pvr_fw_mem *fw_mem = &fw_dev->mem; 392 + int err; 393 + 394 + fw_dev->power_sync = pvr_fw_object_create_and_map(pvr_dev, sizeof(*fw_dev->power_sync), 395 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 396 + NULL, NULL, &fw_mem->power_sync_obj); 397 + if (IS_ERR(fw_dev->power_sync)) { 398 + drm_err(drm_dev, "Unable to allocate FW power_sync structure\n"); 399 + return PTR_ERR(fw_dev->power_sync); 400 + } 401 + 402 + fw_dev->hwrinfobuf = pvr_fw_object_create_and_map(pvr_dev, sizeof(*fw_dev->hwrinfobuf), 403 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 404 + NULL, NULL, &fw_mem->hwrinfobuf_obj); 405 + if (IS_ERR(fw_dev->hwrinfobuf)) { 406 + drm_err(drm_dev, 407 + "Unable to allocate FW hwrinfobuf structure\n"); 408 + err = PTR_ERR(fw_dev->hwrinfobuf); 409 + goto err_release_power_sync; 410 + } 411 + 412 + err = pvr_fw_object_create(pvr_dev, PVR_SYNC_OBJ_SIZE, 413 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 414 + NULL, NULL, &fw_mem->mmucache_sync_obj); 415 + if (err) { 416 + drm_err(drm_dev, 417 + "Unable to allocate MMU cache sync object\n"); 418 + goto err_release_hwrinfobuf; 419 + } 420 + 421 + fw_dev->fwif_sysdata = pvr_fw_object_create_and_map(pvr_dev, 422 + sizeof(*fw_dev->fwif_sysdata), 423 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 424 + fw_sysdata_init, pvr_dev, 425 + &fw_mem->sysdata_obj); 426 + if (IS_ERR(fw_dev->fwif_sysdata)) { 427 + drm_err(drm_dev, "Unable to allocate FW SYSDATA structure\n"); 428 + err = PTR_ERR(fw_dev->fwif_sysdata); 429 + goto err_release_mmucache_sync_obj; 430 + } 431 + 432 + err = pvr_fw_object_create(pvr_dev, PVR_ROGUE_FAULT_PAGE_SIZE, 433 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 434 + fw_fault_page_init, NULL, &fw_mem->fault_page_obj); 435 + if (err) { 436 + drm_err(drm_dev, "Unable to allocate FW fault page\n"); 437 + goto err_release_sysdata; 438 + } 439 + 440 + err = pvr_fw_object_create(pvr_dev, sizeof(struct rogue_fwif_gpu_util_fwcb), 441 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 442 + fw_gpu_util_fwcb_init, pvr_dev, &fw_mem->gpu_util_fwcb_obj); 443 + if (err) { 444 + drm_err(drm_dev, "Unable to allocate GPU util FWCB\n"); 445 + goto err_release_fault_page; 446 + } 447 + 448 + err = pvr_fw_object_create(pvr_dev, sizeof(struct rogue_fwif_runtime_cfg), 449 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 450 + fw_runtime_cfg_init, pvr_dev, &fw_mem->runtime_cfg_obj); 451 + if (err) { 452 + drm_err(drm_dev, "Unable to allocate FW runtime config\n"); 453 + goto err_release_gpu_util_fwcb; 454 + } 455 + 456 + err = pvr_fw_trace_init(pvr_dev); 457 + if (err) 458 + goto err_release_runtime_cfg; 459 + 460 + fw_dev->fwif_osdata = pvr_fw_object_create_and_map(pvr_dev, 461 + sizeof(*fw_dev->fwif_osdata), 462 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 463 + fw_osdata_init, pvr_dev, 464 + &fw_mem->osdata_obj); 465 + if (IS_ERR(fw_dev->fwif_osdata)) { 466 + drm_err(drm_dev, "Unable to allocate FW OSDATA structure\n"); 467 + err = PTR_ERR(fw_dev->fwif_osdata); 468 + goto err_fw_trace_fini; 469 + } 470 + 471 + fw_dev->fwif_osinit = 472 + pvr_fw_object_create_and_map_offset(pvr_dev, 473 + fw_dev->fw_heap_info.config_offset + 474 + PVR_ROGUE_FWIF_OSINIT_OFFSET, 475 + sizeof(*fw_dev->fwif_osinit), 476 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 477 + fw_osinit_init, pvr_dev, &fw_mem->osinit_obj); 478 + if (IS_ERR(fw_dev->fwif_osinit)) { 479 + drm_err(drm_dev, "Unable to allocate FW OSINIT structure\n"); 480 + err = PTR_ERR(fw_dev->fwif_osinit); 481 + goto err_release_osdata; 482 + } 483 + 484 + fw_dev->fwif_sysinit = 485 + pvr_fw_object_create_and_map_offset(pvr_dev, 486 + fw_dev->fw_heap_info.config_offset + 487 + PVR_ROGUE_FWIF_SYSINIT_OFFSET, 488 + sizeof(*fw_dev->fwif_sysinit), 489 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 490 + fw_sysinit_init, pvr_dev, &fw_mem->sysinit_obj); 491 + if (IS_ERR(fw_dev->fwif_sysinit)) { 492 + drm_err(drm_dev, "Unable to allocate FW SYSINIT structure\n"); 493 + err = PTR_ERR(fw_dev->fwif_sysinit); 494 + goto err_release_osinit; 495 + } 496 + 497 + return 0; 498 + 499 + err_release_osinit: 500 + pvr_fw_object_unmap_and_destroy(fw_mem->osinit_obj); 501 + 502 + err_release_osdata: 503 + pvr_fw_object_unmap_and_destroy(fw_mem->osdata_obj); 504 + 505 + err_fw_trace_fini: 506 + pvr_fw_trace_fini(pvr_dev); 507 + 508 + err_release_runtime_cfg: 509 + pvr_fw_object_destroy(fw_mem->runtime_cfg_obj); 510 + 511 + err_release_gpu_util_fwcb: 512 + pvr_fw_object_destroy(fw_mem->gpu_util_fwcb_obj); 513 + 514 + err_release_fault_page: 515 + pvr_fw_object_destroy(fw_mem->fault_page_obj); 516 + 517 + err_release_sysdata: 518 + pvr_fw_object_unmap_and_destroy(fw_mem->sysdata_obj); 519 + 520 + err_release_mmucache_sync_obj: 521 + pvr_fw_object_destroy(fw_mem->mmucache_sync_obj); 522 + 523 + err_release_hwrinfobuf: 524 + pvr_fw_object_unmap_and_destroy(fw_mem->hwrinfobuf_obj); 525 + 526 + err_release_power_sync: 527 + pvr_fw_object_unmap_and_destroy(fw_mem->power_sync_obj); 528 + 529 + return err; 530 + } 531 + 532 + static void 533 + pvr_fw_destroy_structures(struct pvr_device *pvr_dev) 534 + { 535 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 536 + struct pvr_fw_mem *fw_mem = &fw_dev->mem; 537 + 538 + pvr_fw_trace_fini(pvr_dev); 539 + pvr_fw_object_destroy(fw_mem->runtime_cfg_obj); 540 + pvr_fw_object_destroy(fw_mem->gpu_util_fwcb_obj); 541 + pvr_fw_object_destroy(fw_mem->fault_page_obj); 542 + pvr_fw_object_unmap_and_destroy(fw_mem->sysdata_obj); 543 + pvr_fw_object_unmap_and_destroy(fw_mem->sysinit_obj); 544 + 545 + pvr_fw_object_destroy(fw_mem->mmucache_sync_obj); 546 + pvr_fw_object_unmap_and_destroy(fw_mem->hwrinfobuf_obj); 547 + pvr_fw_object_unmap_and_destroy(fw_mem->power_sync_obj); 548 + pvr_fw_object_unmap_and_destroy(fw_mem->osdata_obj); 549 + pvr_fw_object_unmap_and_destroy(fw_mem->osinit_obj); 550 + } 551 + 552 + /** 553 + * pvr_fw_process() - Process firmware image, allocate FW memory and create boot 554 + * arguments 555 + * @pvr_dev: Device pointer. 556 + * 557 + * Returns: 558 + * * 0 on success, or 559 + * * Any error returned by pvr_fw_object_create_and_map_offset(), or 560 + * * Any error returned by pvr_fw_object_create_and_map(). 561 + */ 562 + static int 563 + pvr_fw_process(struct pvr_device *pvr_dev) 564 + { 565 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 566 + struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; 567 + const u8 *fw = pvr_dev->fw_dev.firmware->data; 568 + const struct pvr_fw_layout_entry *private_data; 569 + u8 *fw_code_ptr; 570 + u8 *fw_data_ptr; 571 + u8 *fw_core_code_ptr; 572 + u8 *fw_core_data_ptr; 573 + int err; 574 + 575 + layout_get_sizes(pvr_dev); 576 + 577 + private_data = pvr_fw_find_private_data(pvr_dev); 578 + if (!private_data) 579 + return -EINVAL; 580 + 581 + /* Allocate and map memory for firmware sections. */ 582 + 583 + /* 584 + * Code allocation must be at the start of the firmware heap, otherwise 585 + * firmware processor will be unable to boot. 586 + * 587 + * This has the useful side-effect that for every other object in the 588 + * driver, a firmware address of 0 is invalid. 589 + */ 590 + fw_code_ptr = pvr_fw_object_create_and_map_offset(pvr_dev, 0, fw_mem->code_alloc_size, 591 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 592 + NULL, NULL, &fw_mem->code_obj); 593 + if (IS_ERR(fw_code_ptr)) { 594 + drm_err(drm_dev, "Unable to allocate FW code memory\n"); 595 + return PTR_ERR(fw_code_ptr); 596 + } 597 + 598 + if (pvr_dev->fw_dev.defs->has_fixed_data_addr()) { 599 + u32 base_addr = private_data->base_addr & pvr_dev->fw_dev.fw_heap_info.offset_mask; 600 + 601 + fw_data_ptr = 602 + pvr_fw_object_create_and_map_offset(pvr_dev, base_addr, 603 + fw_mem->data_alloc_size, 604 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 605 + NULL, NULL, &fw_mem->data_obj); 606 + } else { 607 + fw_data_ptr = pvr_fw_object_create_and_map(pvr_dev, fw_mem->data_alloc_size, 608 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 609 + NULL, NULL, &fw_mem->data_obj); 610 + } 611 + if (IS_ERR(fw_data_ptr)) { 612 + drm_err(drm_dev, "Unable to allocate FW data memory\n"); 613 + err = PTR_ERR(fw_data_ptr); 614 + goto err_free_fw_code_obj; 615 + } 616 + 617 + /* Core code and data sections are optional. */ 618 + if (fw_mem->core_code_alloc_size) { 619 + fw_core_code_ptr = 620 + pvr_fw_object_create_and_map(pvr_dev, fw_mem->core_code_alloc_size, 621 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 622 + NULL, NULL, &fw_mem->core_code_obj); 623 + if (IS_ERR(fw_core_code_ptr)) { 624 + drm_err(drm_dev, 625 + "Unable to allocate FW core code memory\n"); 626 + err = PTR_ERR(fw_core_code_ptr); 627 + goto err_free_fw_data_obj; 628 + } 629 + } else { 630 + fw_core_code_ptr = NULL; 631 + } 632 + 633 + if (fw_mem->core_data_alloc_size) { 634 + fw_core_data_ptr = 635 + pvr_fw_object_create_and_map(pvr_dev, fw_mem->core_data_alloc_size, 636 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 637 + NULL, NULL, &fw_mem->core_data_obj); 638 + if (IS_ERR(fw_core_data_ptr)) { 639 + drm_err(drm_dev, 640 + "Unable to allocate FW core data memory\n"); 641 + err = PTR_ERR(fw_core_data_ptr); 642 + goto err_free_fw_core_code_obj; 643 + } 644 + } else { 645 + fw_core_data_ptr = NULL; 646 + } 647 + 648 + fw_mem->code = kzalloc(fw_mem->code_alloc_size, GFP_KERNEL); 649 + fw_mem->data = kzalloc(fw_mem->data_alloc_size, GFP_KERNEL); 650 + if (fw_mem->core_code_alloc_size) 651 + fw_mem->core_code = kzalloc(fw_mem->core_code_alloc_size, GFP_KERNEL); 652 + if (fw_mem->core_data_alloc_size) 653 + fw_mem->core_data = kzalloc(fw_mem->core_data_alloc_size, GFP_KERNEL); 654 + 655 + if (!fw_mem->code || !fw_mem->data || 656 + (!fw_mem->core_code && fw_mem->core_code_alloc_size) || 657 + (!fw_mem->core_data && fw_mem->core_data_alloc_size)) { 658 + err = -ENOMEM; 659 + goto err_free_kdata; 660 + } 661 + 662 + err = pvr_dev->fw_dev.defs->fw_process(pvr_dev, fw, 663 + fw_mem->code, fw_mem->data, fw_mem->core_code, 664 + fw_mem->core_data, fw_mem->core_code_alloc_size); 665 + 666 + if (err) 667 + goto err_free_fw_core_data_obj; 668 + 669 + memcpy(fw_code_ptr, fw_mem->code, fw_mem->code_alloc_size); 670 + memcpy(fw_data_ptr, fw_mem->data, fw_mem->data_alloc_size); 671 + if (fw_mem->core_code) 672 + memcpy(fw_core_code_ptr, fw_mem->core_code, fw_mem->core_code_alloc_size); 673 + if (fw_mem->core_data) 674 + memcpy(fw_core_data_ptr, fw_mem->core_data, fw_mem->core_data_alloc_size); 675 + 676 + /* We're finished with the firmware section memory on the CPU, unmap. */ 677 + if (fw_core_data_ptr) 678 + pvr_fw_object_vunmap(fw_mem->core_data_obj); 679 + if (fw_core_code_ptr) 680 + pvr_fw_object_vunmap(fw_mem->core_code_obj); 681 + pvr_fw_object_vunmap(fw_mem->data_obj); 682 + fw_data_ptr = NULL; 683 + pvr_fw_object_vunmap(fw_mem->code_obj); 684 + fw_code_ptr = NULL; 685 + 686 + err = pvr_fw_create_fwif_connection_ctl(pvr_dev); 687 + if (err) 688 + goto err_free_fw_core_data_obj; 689 + 690 + return 0; 691 + 692 + err_free_kdata: 693 + kfree(fw_mem->core_data); 694 + kfree(fw_mem->core_code); 695 + kfree(fw_mem->data); 696 + kfree(fw_mem->code); 697 + 698 + err_free_fw_core_data_obj: 699 + if (fw_core_data_ptr) 700 + pvr_fw_object_unmap_and_destroy(fw_mem->core_data_obj); 701 + 702 + err_free_fw_core_code_obj: 703 + if (fw_core_code_ptr) 704 + pvr_fw_object_unmap_and_destroy(fw_mem->core_code_obj); 705 + 706 + err_free_fw_data_obj: 707 + if (fw_data_ptr) 708 + pvr_fw_object_vunmap(fw_mem->data_obj); 709 + pvr_fw_object_destroy(fw_mem->data_obj); 710 + 711 + err_free_fw_code_obj: 712 + if (fw_code_ptr) 713 + pvr_fw_object_vunmap(fw_mem->code_obj); 714 + pvr_fw_object_destroy(fw_mem->code_obj); 715 + 716 + return err; 717 + } 718 + 719 + static int 720 + pvr_copy_to_fw(struct pvr_fw_object *dest_obj, u8 *src_ptr, u32 size) 721 + { 722 + u8 *dest_ptr = pvr_fw_object_vmap(dest_obj); 723 + 724 + if (IS_ERR(dest_ptr)) 725 + return PTR_ERR(dest_ptr); 726 + 727 + memcpy(dest_ptr, src_ptr, size); 728 + 729 + pvr_fw_object_vunmap(dest_obj); 730 + 731 + return 0; 732 + } 733 + 734 + static int 735 + pvr_fw_reinit_code_data(struct pvr_device *pvr_dev) 736 + { 737 + struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; 738 + int err; 739 + 740 + err = pvr_copy_to_fw(fw_mem->code_obj, fw_mem->code, fw_mem->code_alloc_size); 741 + if (err) 742 + return err; 743 + 744 + err = pvr_copy_to_fw(fw_mem->data_obj, fw_mem->data, fw_mem->data_alloc_size); 745 + if (err) 746 + return err; 747 + 748 + if (fw_mem->core_code) { 749 + err = pvr_copy_to_fw(fw_mem->core_code_obj, fw_mem->core_code, 750 + fw_mem->core_code_alloc_size); 751 + if (err) 752 + return err; 753 + } 754 + 755 + if (fw_mem->core_data) { 756 + err = pvr_copy_to_fw(fw_mem->core_data_obj, fw_mem->core_data, 757 + fw_mem->core_data_alloc_size); 758 + if (err) 759 + return err; 760 + } 761 + 762 + return 0; 763 + } 764 + 765 + static void 766 + pvr_fw_cleanup(struct pvr_device *pvr_dev) 767 + { 768 + struct pvr_fw_mem *fw_mem = &pvr_dev->fw_dev.mem; 769 + 770 + pvr_fw_fini_fwif_connection_ctl(pvr_dev); 771 + if (fw_mem->core_code_obj) 772 + pvr_fw_object_destroy(fw_mem->core_code_obj); 773 + if (fw_mem->core_data_obj) 774 + pvr_fw_object_destroy(fw_mem->core_data_obj); 775 + pvr_fw_object_destroy(fw_mem->code_obj); 776 + pvr_fw_object_destroy(fw_mem->data_obj); 777 + } 778 + 779 + /** 780 + * pvr_wait_for_fw_boot() - Wait for firmware to finish booting 781 + * @pvr_dev: Target PowerVR device. 782 + * 783 + * Returns: 784 + * * 0 on success, or 785 + * * -%ETIMEDOUT if firmware fails to boot within timeout. 786 + */ 787 + int 788 + pvr_wait_for_fw_boot(struct pvr_device *pvr_dev) 789 + { 790 + ktime_t deadline = ktime_add_us(ktime_get(), FW_BOOT_TIMEOUT_USEC); 791 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 792 + 793 + while (ktime_to_ns(ktime_sub(deadline, ktime_get())) > 0) { 794 + if (READ_ONCE(fw_dev->fwif_sysinit->firmware_started)) 795 + return 0; 796 + } 797 + 798 + return -ETIMEDOUT; 799 + } 800 + 801 + /* 802 + * pvr_fw_heap_info_init() - Calculate size and masks for FW heap 803 + * @pvr_dev: Target PowerVR device. 804 + * @log2_size: Log2 of raw heap size. 805 + * @reserved_size: Size of reserved area of heap, in bytes. May be zero. 806 + */ 807 + void 808 + pvr_fw_heap_info_init(struct pvr_device *pvr_dev, u32 log2_size, u32 reserved_size) 809 + { 810 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 811 + 812 + fw_dev->fw_heap_info.gpu_addr = PVR_ROGUE_FW_MAIN_HEAP_BASE; 813 + fw_dev->fw_heap_info.log2_size = log2_size; 814 + fw_dev->fw_heap_info.reserved_size = reserved_size; 815 + fw_dev->fw_heap_info.raw_size = 1 << fw_dev->fw_heap_info.log2_size; 816 + fw_dev->fw_heap_info.offset_mask = fw_dev->fw_heap_info.raw_size - 1; 817 + fw_dev->fw_heap_info.config_offset = fw_dev->fw_heap_info.raw_size - 818 + PVR_ROGUE_FW_CONFIG_HEAP_SIZE; 819 + fw_dev->fw_heap_info.size = fw_dev->fw_heap_info.raw_size - 820 + (PVR_ROGUE_FW_CONFIG_HEAP_SIZE + reserved_size); 821 + } 822 + 193 823 /** 194 824 * pvr_fw_validate_init_device_info() - Validate firmware and initialise device information 195 825 * @pvr_dev: Target PowerVR device. ··· 908 142 return err; 909 143 910 144 return pvr_fw_get_device_info(pvr_dev); 145 + } 146 + 147 + /** 148 + * pvr_fw_init() - Initialise and boot firmware 149 + * @pvr_dev: Target PowerVR device 150 + * 151 + * On successful completion of the function the PowerVR device will be 152 + * initialised and ready to use. 153 + * 154 + * Returns: 155 + * * 0 on success, 156 + * * -%EINVAL on invalid firmware image, 157 + * * -%ENOMEM on out of memory, or 158 + * * -%ETIMEDOUT if firmware processor fails to boot or on register poll timeout. 159 + */ 160 + int 161 + pvr_fw_init(struct pvr_device *pvr_dev) 162 + { 163 + u32 kccb_size_log2 = ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; 164 + u32 kccb_rtn_size = (1 << kccb_size_log2) * sizeof(*pvr_dev->kccb.rtn); 165 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 166 + int err; 167 + 168 + if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_META) 169 + fw_dev->defs = &pvr_fw_defs_meta; 170 + else 171 + return -EINVAL; 172 + 173 + err = fw_dev->defs->init(pvr_dev); 174 + if (err) 175 + return err; 176 + 177 + drm_mm_init(&fw_dev->fw_mm, ROGUE_FW_HEAP_BASE, fw_dev->fw_heap_info.raw_size); 178 + fw_dev->fw_mm_base = ROGUE_FW_HEAP_BASE; 179 + spin_lock_init(&fw_dev->fw_mm_lock); 180 + 181 + INIT_LIST_HEAD(&fw_dev->fw_objs.list); 182 + err = drmm_mutex_init(from_pvr_device(pvr_dev), &fw_dev->fw_objs.lock); 183 + if (err) 184 + goto err_mm_takedown; 185 + 186 + err = pvr_fw_process(pvr_dev); 187 + if (err) 188 + goto err_mm_takedown; 189 + 190 + /* Initialise KCCB and FWCCB. */ 191 + err = pvr_kccb_init(pvr_dev); 192 + if (err) 193 + goto err_fw_cleanup; 194 + 195 + err = pvr_fwccb_init(pvr_dev); 196 + if (err) 197 + goto err_kccb_fini; 198 + 199 + /* Allocate memory for KCCB return slots. */ 200 + pvr_dev->kccb.rtn = pvr_fw_object_create_and_map(pvr_dev, kccb_rtn_size, 201 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 202 + NULL, NULL, &pvr_dev->kccb.rtn_obj); 203 + if (IS_ERR(pvr_dev->kccb.rtn)) { 204 + err = PTR_ERR(pvr_dev->kccb.rtn); 205 + goto err_fwccb_fini; 206 + } 207 + 208 + err = pvr_fw_create_structures(pvr_dev); 209 + if (err) 210 + goto err_kccb_rtn_release; 211 + 212 + err = pvr_fw_start(pvr_dev); 213 + if (err) 214 + goto err_destroy_structures; 215 + 216 + err = pvr_wait_for_fw_boot(pvr_dev); 217 + if (err) { 218 + drm_err(from_pvr_device(pvr_dev), "Firmware failed to boot\n"); 219 + goto err_fw_stop; 220 + } 221 + 222 + fw_dev->booted = true; 223 + 224 + return 0; 225 + 226 + err_fw_stop: 227 + pvr_fw_stop(pvr_dev); 228 + 229 + err_destroy_structures: 230 + pvr_fw_destroy_structures(pvr_dev); 231 + 232 + err_kccb_rtn_release: 233 + pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); 234 + 235 + err_fwccb_fini: 236 + pvr_ccb_fini(&pvr_dev->fwccb); 237 + 238 + err_kccb_fini: 239 + pvr_kccb_fini(pvr_dev); 240 + 241 + err_fw_cleanup: 242 + pvr_fw_cleanup(pvr_dev); 243 + 244 + err_mm_takedown: 245 + drm_mm_takedown(&fw_dev->fw_mm); 246 + 247 + if (fw_dev->defs->fini) 248 + fw_dev->defs->fini(pvr_dev); 249 + 250 + return err; 251 + } 252 + 253 + /** 254 + * pvr_fw_fini() - Shutdown firmware processor and free associated memory 255 + * @pvr_dev: Target PowerVR device 256 + */ 257 + void 258 + pvr_fw_fini(struct pvr_device *pvr_dev) 259 + { 260 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 261 + 262 + fw_dev->booted = false; 263 + 264 + pvr_fw_destroy_structures(pvr_dev); 265 + pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); 266 + 267 + /* 268 + * Ensure FWCCB worker has finished executing before destroying FWCCB. The IRQ handler has 269 + * been unregistered at this point so no new work should be being submitted. 270 + */ 271 + pvr_ccb_fini(&pvr_dev->fwccb); 272 + pvr_kccb_fini(pvr_dev); 273 + pvr_fw_cleanup(pvr_dev); 274 + 275 + mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); 276 + WARN_ON(!list_empty(&pvr_dev->fw_dev.fw_objs.list)); 277 + mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); 278 + 279 + drm_mm_takedown(&fw_dev->fw_mm); 280 + 281 + if (fw_dev->defs->fini) 282 + fw_dev->defs->fini(pvr_dev); 283 + } 284 + 285 + /** 286 + * pvr_fw_mts_schedule() - Schedule work via an MTS kick 287 + * @pvr_dev: Target PowerVR device 288 + * @val: Kick mask. Should be a combination of %ROGUE_CR_MTS_SCHEDULE_* 289 + */ 290 + void 291 + pvr_fw_mts_schedule(struct pvr_device *pvr_dev, u32 val) 292 + { 293 + /* Ensure memory is flushed before kicking MTS. */ 294 + wmb(); 295 + 296 + pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_SCHEDULE, val); 297 + 298 + /* Ensure the MTS kick goes through before continuing. */ 299 + mb(); 300 + } 301 + 302 + /** 303 + * pvr_fw_structure_cleanup() - Send FW cleanup request for an object 304 + * @pvr_dev: Target PowerVR device. 305 + * @type: Type of object to cleanup. Must be one of &enum rogue_fwif_cleanup_type. 306 + * @fw_obj: Pointer to FW object containing object to cleanup. 307 + * @offset: Offset within FW object of object to cleanup. 308 + * 309 + * Returns: 310 + * * 0 on success, 311 + * * -EBUSY if object is busy, 312 + * * -ETIMEDOUT on timeout, or 313 + * * -EIO if device is lost. 314 + */ 315 + int 316 + pvr_fw_structure_cleanup(struct pvr_device *pvr_dev, u32 type, struct pvr_fw_object *fw_obj, 317 + u32 offset) 318 + { 319 + struct rogue_fwif_kccb_cmd cmd; 320 + int slot_nr; 321 + int idx; 322 + int err; 323 + u32 rtn; 324 + 325 + struct rogue_fwif_cleanup_request *cleanup_req = &cmd.cmd_data.cleanup_data; 326 + 327 + down_read(&pvr_dev->reset_sem); 328 + 329 + if (!drm_dev_enter(from_pvr_device(pvr_dev), &idx)) { 330 + err = -EIO; 331 + goto err_up_read; 332 + } 333 + 334 + cmd.cmd_type = ROGUE_FWIF_KCCB_CMD_CLEANUP; 335 + cmd.kccb_flags = 0; 336 + cleanup_req->cleanup_type = type; 337 + 338 + switch (type) { 339 + case ROGUE_FWIF_CLEANUP_FWCOMMONCONTEXT: 340 + pvr_fw_object_get_fw_addr_offset(fw_obj, offset, 341 + &cleanup_req->cleanup_data.context_fw_addr); 342 + break; 343 + case ROGUE_FWIF_CLEANUP_HWRTDATA: 344 + pvr_fw_object_get_fw_addr_offset(fw_obj, offset, 345 + &cleanup_req->cleanup_data.hwrt_data_fw_addr); 346 + break; 347 + case ROGUE_FWIF_CLEANUP_FREELIST: 348 + pvr_fw_object_get_fw_addr_offset(fw_obj, offset, 349 + &cleanup_req->cleanup_data.freelist_fw_addr); 350 + break; 351 + default: 352 + err = -EINVAL; 353 + goto err_drm_dev_exit; 354 + } 355 + 356 + err = pvr_kccb_send_cmd(pvr_dev, &cmd, &slot_nr); 357 + if (err) 358 + goto err_drm_dev_exit; 359 + 360 + err = pvr_kccb_wait_for_completion(pvr_dev, slot_nr, HZ, &rtn); 361 + if (err) 362 + goto err_drm_dev_exit; 363 + 364 + if (rtn & ROGUE_FWIF_KCCB_RTN_SLOT_CLEANUP_BUSY) 365 + err = -EBUSY; 366 + 367 + err_drm_dev_exit: 368 + drm_dev_exit(idx); 369 + 370 + err_up_read: 371 + up_read(&pvr_dev->reset_sem); 372 + 373 + return err; 374 + } 375 + 376 + /** 377 + * pvr_fw_object_fw_map() - Map a FW object in firmware address space 378 + * @pvr_dev: Device pointer. 379 + * @fw_obj: FW object to map. 380 + * @dev_addr: Desired address in device space, if a specific address is 381 + * required. 0 otherwise. 382 + * 383 + * Returns: 384 + * * 0 on success, or 385 + * * -%EINVAL if @fw_obj is already mapped but has no references, or 386 + * * Any error returned by DRM. 387 + */ 388 + static int 389 + pvr_fw_object_fw_map(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj, u64 dev_addr) 390 + { 391 + struct pvr_gem_object *pvr_obj = fw_obj->gem; 392 + struct drm_gem_object *gem_obj = gem_from_pvr_gem(pvr_obj); 393 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 394 + 395 + int err; 396 + 397 + spin_lock(&fw_dev->fw_mm_lock); 398 + 399 + if (drm_mm_node_allocated(&fw_obj->fw_mm_node)) { 400 + err = -EINVAL; 401 + goto err_unlock; 402 + } 403 + 404 + if (!dev_addr) { 405 + /* 406 + * Allocate from the main heap only (firmware heap minus 407 + * config space). 408 + */ 409 + err = drm_mm_insert_node_in_range(&fw_dev->fw_mm, &fw_obj->fw_mm_node, 410 + gem_obj->size, 0, 0, 411 + fw_dev->fw_heap_info.gpu_addr, 412 + fw_dev->fw_heap_info.gpu_addr + 413 + fw_dev->fw_heap_info.size, 0); 414 + if (err) 415 + goto err_unlock; 416 + } else { 417 + fw_obj->fw_mm_node.start = dev_addr; 418 + fw_obj->fw_mm_node.size = gem_obj->size; 419 + err = drm_mm_reserve_node(&fw_dev->fw_mm, &fw_obj->fw_mm_node); 420 + if (err) 421 + goto err_unlock; 422 + } 423 + 424 + spin_unlock(&fw_dev->fw_mm_lock); 425 + 426 + /* Map object on GPU. */ 427 + err = fw_dev->defs->vm_map(pvr_dev, fw_obj); 428 + if (err) 429 + goto err_remove_node; 430 + 431 + fw_obj->fw_addr_offset = (u32)(fw_obj->fw_mm_node.start - fw_dev->fw_mm_base); 432 + 433 + return 0; 434 + 435 + err_remove_node: 436 + spin_lock(&fw_dev->fw_mm_lock); 437 + drm_mm_remove_node(&fw_obj->fw_mm_node); 438 + 439 + err_unlock: 440 + spin_unlock(&fw_dev->fw_mm_lock); 441 + 442 + return err; 443 + } 444 + 445 + /** 446 + * pvr_fw_object_fw_unmap() - Unmap a previously mapped FW object 447 + * @fw_obj: FW object to unmap. 448 + * 449 + * Returns: 450 + * * 0 on success, or 451 + * * -%EINVAL if object is not currently mapped. 452 + */ 453 + static int 454 + pvr_fw_object_fw_unmap(struct pvr_fw_object *fw_obj) 455 + { 456 + struct pvr_gem_object *pvr_obj = fw_obj->gem; 457 + struct drm_gem_object *gem_obj = gem_from_pvr_gem(pvr_obj); 458 + struct pvr_device *pvr_dev = to_pvr_device(gem_obj->dev); 459 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 460 + 461 + fw_dev->defs->vm_unmap(pvr_dev, fw_obj); 462 + 463 + spin_lock(&fw_dev->fw_mm_lock); 464 + 465 + if (!drm_mm_node_allocated(&fw_obj->fw_mm_node)) { 466 + spin_unlock(&fw_dev->fw_mm_lock); 467 + return -EINVAL; 468 + } 469 + 470 + drm_mm_remove_node(&fw_obj->fw_mm_node); 471 + 472 + spin_unlock(&fw_dev->fw_mm_lock); 473 + 474 + return 0; 475 + } 476 + 477 + static void * 478 + pvr_fw_object_create_and_map_common(struct pvr_device *pvr_dev, size_t size, 479 + u64 flags, u64 dev_addr, 480 + void (*init)(void *cpu_ptr, void *priv), 481 + void *init_priv, struct pvr_fw_object **fw_obj_out) 482 + { 483 + struct pvr_fw_object *fw_obj; 484 + void *cpu_ptr; 485 + int err; 486 + 487 + /* %DRM_PVR_BO_PM_FW_PROTECT is implicit for FW objects. */ 488 + flags |= DRM_PVR_BO_PM_FW_PROTECT; 489 + 490 + fw_obj = kzalloc(sizeof(*fw_obj), GFP_KERNEL); 491 + if (!fw_obj) 492 + return ERR_PTR(-ENOMEM); 493 + 494 + INIT_LIST_HEAD(&fw_obj->node); 495 + fw_obj->init = init; 496 + fw_obj->init_priv = init_priv; 497 + 498 + fw_obj->gem = pvr_gem_object_create(pvr_dev, size, flags); 499 + if (IS_ERR(fw_obj->gem)) { 500 + err = PTR_ERR(fw_obj->gem); 501 + fw_obj->gem = NULL; 502 + goto err_put_object; 503 + } 504 + 505 + err = pvr_fw_object_fw_map(pvr_dev, fw_obj, dev_addr); 506 + if (err) 507 + goto err_put_object; 508 + 509 + cpu_ptr = pvr_fw_object_vmap(fw_obj); 510 + if (IS_ERR(cpu_ptr)) { 511 + err = PTR_ERR(cpu_ptr); 512 + goto err_put_object; 513 + } 514 + 515 + *fw_obj_out = fw_obj; 516 + 517 + if (fw_obj->init) 518 + fw_obj->init(cpu_ptr, fw_obj->init_priv); 519 + 520 + mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); 521 + list_add_tail(&fw_obj->node, &pvr_dev->fw_dev.fw_objs.list); 522 + mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); 523 + 524 + return cpu_ptr; 525 + 526 + err_put_object: 527 + pvr_fw_object_destroy(fw_obj); 528 + 529 + return ERR_PTR(err); 530 + } 531 + 532 + /** 533 + * pvr_fw_object_create() - Create a FW object and map to firmware 534 + * @pvr_dev: PowerVR device pointer. 535 + * @size: Size of object, in bytes. 536 + * @flags: Options which affect both this operation and future mapping 537 + * operations performed on the returned object. Must be a combination of 538 + * DRM_PVR_BO_* and/or PVR_BO_* flags. 539 + * @init: Initialisation callback. 540 + * @init_priv: Private pointer to pass to initialisation callback. 541 + * @fw_obj_out: Pointer to location to store created object pointer. 542 + * 543 + * %DRM_PVR_BO_DEVICE_PM_FW_PROTECT is implied for all FW objects. Consequently, 544 + * this function will fail if @flags has %DRM_PVR_BO_CPU_ALLOW_USERSPACE_ACCESS 545 + * set. 546 + * 547 + * Returns: 548 + * * 0 on success, or 549 + * * Any error returned by pvr_fw_object_create_common(). 550 + */ 551 + int 552 + pvr_fw_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags, 553 + void (*init)(void *cpu_ptr, void *priv), void *init_priv, 554 + struct pvr_fw_object **fw_obj_out) 555 + { 556 + void *cpu_ptr; 557 + 558 + cpu_ptr = pvr_fw_object_create_and_map_common(pvr_dev, size, flags, 0, init, init_priv, 559 + fw_obj_out); 560 + if (IS_ERR(cpu_ptr)) 561 + return PTR_ERR(cpu_ptr); 562 + 563 + pvr_fw_object_vunmap(*fw_obj_out); 564 + 565 + return 0; 566 + } 567 + 568 + /** 569 + * pvr_fw_object_create_and_map() - Create a FW object and map to firmware and CPU 570 + * @pvr_dev: PowerVR device pointer. 571 + * @size: Size of object, in bytes. 572 + * @flags: Options which affect both this operation and future mapping 573 + * operations performed on the returned object. Must be a combination of 574 + * DRM_PVR_BO_* and/or PVR_BO_* flags. 575 + * @init: Initialisation callback. 576 + * @init_priv: Private pointer to pass to initialisation callback. 577 + * @fw_obj_out: Pointer to location to store created object pointer. 578 + * 579 + * %DRM_PVR_BO_DEVICE_PM_FW_PROTECT is implied for all FW objects. Consequently, 580 + * this function will fail if @flags has %DRM_PVR_BO_CPU_ALLOW_USERSPACE_ACCESS 581 + * set. 582 + * 583 + * Caller is responsible for calling pvr_fw_object_vunmap() to release the CPU 584 + * mapping. 585 + * 586 + * Returns: 587 + * * Pointer to CPU mapping of newly created object, or 588 + * * Any error returned by pvr_fw_object_create(), or 589 + * * Any error returned by pvr_fw_object_vmap(). 590 + */ 591 + void * 592 + pvr_fw_object_create_and_map(struct pvr_device *pvr_dev, size_t size, u64 flags, 593 + void (*init)(void *cpu_ptr, void *priv), 594 + void *init_priv, struct pvr_fw_object **fw_obj_out) 595 + { 596 + return pvr_fw_object_create_and_map_common(pvr_dev, size, flags, 0, init, init_priv, 597 + fw_obj_out); 598 + } 599 + 600 + /** 601 + * pvr_fw_object_create_and_map_offset() - Create a FW object and map to 602 + * firmware at the provided offset and to the CPU. 603 + * @pvr_dev: PowerVR device pointer. 604 + * @dev_offset: Base address of desired FW mapping, offset from start of FW heap. 605 + * @size: Size of object, in bytes. 606 + * @flags: Options which affect both this operation and future mapping 607 + * operations performed on the returned object. Must be a combination of 608 + * DRM_PVR_BO_* and/or PVR_BO_* flags. 609 + * @init: Initialisation callback. 610 + * @init_priv: Private pointer to pass to initialisation callback. 611 + * @fw_obj_out: Pointer to location to store created object pointer. 612 + * 613 + * %DRM_PVR_BO_DEVICE_PM_FW_PROTECT is implied for all FW objects. Consequently, 614 + * this function will fail if @flags has %DRM_PVR_BO_CPU_ALLOW_USERSPACE_ACCESS 615 + * set. 616 + * 617 + * Caller is responsible for calling pvr_fw_object_vunmap() to release the CPU 618 + * mapping. 619 + * 620 + * Returns: 621 + * * Pointer to CPU mapping of newly created object, or 622 + * * Any error returned by pvr_fw_object_create(), or 623 + * * Any error returned by pvr_fw_object_vmap(). 624 + */ 625 + void * 626 + pvr_fw_object_create_and_map_offset(struct pvr_device *pvr_dev, 627 + u32 dev_offset, size_t size, u64 flags, 628 + void (*init)(void *cpu_ptr, void *priv), 629 + void *init_priv, struct pvr_fw_object **fw_obj_out) 630 + { 631 + u64 dev_addr = pvr_dev->fw_dev.fw_mm_base + dev_offset; 632 + 633 + return pvr_fw_object_create_and_map_common(pvr_dev, size, flags, dev_addr, init, init_priv, 634 + fw_obj_out); 635 + } 636 + 637 + /** 638 + * pvr_fw_object_destroy() - Destroy a pvr_fw_object 639 + * @fw_obj: Pointer to object to destroy. 640 + */ 641 + void pvr_fw_object_destroy(struct pvr_fw_object *fw_obj) 642 + { 643 + struct pvr_gem_object *pvr_obj = fw_obj->gem; 644 + struct drm_gem_object *gem_obj = gem_from_pvr_gem(pvr_obj); 645 + struct pvr_device *pvr_dev = to_pvr_device(gem_obj->dev); 646 + 647 + mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); 648 + list_del(&fw_obj->node); 649 + mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); 650 + 651 + if (drm_mm_node_allocated(&fw_obj->fw_mm_node)) { 652 + /* If we can't unmap, leak the memory. */ 653 + if (WARN_ON(pvr_fw_object_fw_unmap(fw_obj))) 654 + return; 655 + } 656 + 657 + if (fw_obj->gem) 658 + pvr_gem_object_put(fw_obj->gem); 659 + 660 + kfree(fw_obj); 661 + } 662 + 663 + /** 664 + * pvr_fw_object_get_fw_addr_offset() - Return address of object in firmware address space, with 665 + * given offset. 666 + * @fw_obj: Pointer to object. 667 + * @offset: Desired offset from start of object. 668 + * @fw_addr_out: Location to store address to. 669 + */ 670 + void pvr_fw_object_get_fw_addr_offset(struct pvr_fw_object *fw_obj, u32 offset, u32 *fw_addr_out) 671 + { 672 + struct pvr_gem_object *pvr_obj = fw_obj->gem; 673 + struct pvr_device *pvr_dev = to_pvr_device(gem_from_pvr_gem(pvr_obj)->dev); 674 + 675 + *fw_addr_out = pvr_dev->fw_dev.defs->get_fw_addr_with_offset(fw_obj, offset); 676 + } 677 + 678 + /* 679 + * pvr_fw_hard_reset() - Re-initialise the FW code and data segments, and reset all global FW 680 + * structures 681 + * @pvr_dev: Device pointer 682 + * 683 + * If this function returns an error then the caller must regard the device as lost. 684 + * 685 + * Returns: 686 + * * 0 on success, or 687 + * * Any error returned by pvr_fw_init_dev_structures() or pvr_fw_reset_all(). 688 + */ 689 + int 690 + pvr_fw_hard_reset(struct pvr_device *pvr_dev) 691 + { 692 + struct list_head *pos; 693 + int err; 694 + 695 + /* Reset all FW objects */ 696 + mutex_lock(&pvr_dev->fw_dev.fw_objs.lock); 697 + 698 + list_for_each(pos, &pvr_dev->fw_dev.fw_objs.list) { 699 + struct pvr_fw_object *fw_obj = container_of(pos, struct pvr_fw_object, node); 700 + void *cpu_ptr = pvr_fw_object_vmap(fw_obj); 701 + 702 + WARN_ON(IS_ERR(cpu_ptr)); 703 + 704 + if (!(fw_obj->gem->flags & PVR_BO_FW_NO_CLEAR_ON_RESET)) { 705 + memset(cpu_ptr, 0, pvr_gem_object_size(fw_obj->gem)); 706 + 707 + if (fw_obj->init) 708 + fw_obj->init(cpu_ptr, fw_obj->init_priv); 709 + } 710 + 711 + pvr_fw_object_vunmap(fw_obj); 712 + } 713 + 714 + mutex_unlock(&pvr_dev->fw_dev.fw_objs.lock); 715 + 716 + err = pvr_fw_reinit_code_data(pvr_dev); 717 + if (err) 718 + return err; 719 + 720 + return 0; 911 721 }
+474
drivers/gpu/drm/imagination/pvr_fw.h
··· 5 5 #define PVR_FW_H 6 6 7 7 #include "pvr_fw_info.h" 8 + #include "pvr_fw_trace.h" 9 + #include "pvr_gem.h" 10 + 11 + #include <drm/drm_mm.h> 8 12 9 13 #include <linux/types.h> 10 14 11 15 /* Forward declarations from "pvr_device.h". */ 12 16 struct pvr_device; 13 17 struct pvr_file; 18 + 19 + /* Forward declaration from "pvr_vm.h". */ 20 + struct pvr_vm_context; 21 + 22 + #define ROGUE_FWIF_FWCCB_NUMCMDS_LOG2 5 23 + 24 + #define ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT 7 25 + 26 + /** 27 + * struct pvr_fw_object - container for firmware memory allocations 28 + */ 29 + struct pvr_fw_object { 30 + /** @ref_count: FW object reference counter. */ 31 + struct kref ref_count; 32 + 33 + /** @gem: GEM object backing the FW object. */ 34 + struct pvr_gem_object *gem; 35 + 36 + /** 37 + * @fw_mm_node: Node representing mapping in FW address space. @pvr_obj->lock must 38 + * be held when writing. 39 + */ 40 + struct drm_mm_node fw_mm_node; 41 + 42 + /** 43 + * @fw_addr_offset: Virtual address offset of firmware mapping. Only 44 + * valid if @flags has %PVR_GEM_OBJECT_FLAGS_FW_MAPPED 45 + * set. 46 + */ 47 + u32 fw_addr_offset; 48 + 49 + /** 50 + * @init: Initialisation callback. Will be called on object creation and FW hard reset. 51 + * Object will have been zeroed before this is called. 52 + */ 53 + void (*init)(void *cpu_ptr, void *priv); 54 + 55 + /** @init_priv: Private data for initialisation callback. */ 56 + void *init_priv; 57 + 58 + /** @node: Node for firmware object list. */ 59 + struct list_head node; 60 + }; 61 + 62 + /** 63 + * struct pvr_fw_defs - FW processor function table and static definitions 64 + */ 65 + struct pvr_fw_defs { 66 + /** 67 + * @init: 68 + * 69 + * FW processor specific initialisation. 70 + * @pvr_dev: Target PowerVR device. 71 + * 72 + * This function must call pvr_fw_heap_calculate() to initialise the firmware heap for this 73 + * FW processor. 74 + * 75 + * This function is mandatory. 76 + * 77 + * Returns: 78 + * * 0 on success, or 79 + * * Any appropriate error on failure. 80 + */ 81 + int (*init)(struct pvr_device *pvr_dev); 82 + 83 + /** 84 + * @fini: 85 + * 86 + * FW processor specific finalisation. 87 + * @pvr_dev: Target PowerVR device. 88 + * 89 + * This function is optional. 90 + */ 91 + void (*fini)(struct pvr_device *pvr_dev); 92 + 93 + /** 94 + * @fw_process: 95 + * 96 + * Load and process firmware image. 97 + * @pvr_dev: Target PowerVR device. 98 + * @fw: Pointer to firmware image. 99 + * @fw_code_ptr: Pointer to firmware code section. 100 + * @fw_data_ptr: Pointer to firmware data section. 101 + * @fw_core_code_ptr: Pointer to firmware core code section. May be %NULL. 102 + * @fw_core_data_ptr: Pointer to firmware core data section. May be %NULL. 103 + * @core_code_alloc_size: Total allocation size of core code section. 104 + * 105 + * This function is mandatory. 106 + * 107 + * Returns: 108 + * * 0 on success, or 109 + * * Any appropriate error on failure. 110 + */ 111 + int (*fw_process)(struct pvr_device *pvr_dev, const u8 *fw, 112 + u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr, 113 + u8 *fw_core_data_ptr, u32 core_code_alloc_size); 114 + 115 + /** 116 + * @vm_map: 117 + * 118 + * Map FW object into FW processor address space. 119 + * @pvr_dev: Target PowerVR device. 120 + * @fw_obj: FW object to map. 121 + * 122 + * This function is mandatory. 123 + * 124 + * Returns: 125 + * * 0 on success, or 126 + * * Any appropriate error on failure. 127 + */ 128 + int (*vm_map)(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj); 129 + 130 + /** 131 + * @vm_unmap: 132 + * 133 + * Unmap FW object from FW processor address space. 134 + * @pvr_dev: Target PowerVR device. 135 + * @fw_obj: FW object to map. 136 + * 137 + * This function is mandatory. 138 + */ 139 + void (*vm_unmap)(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj); 140 + 141 + /** 142 + * @get_fw_addr_with_offset: 143 + * 144 + * Called to get address of object in firmware address space, with offset. 145 + * @fw_obj: Pointer to object. 146 + * @offset: Desired offset from start of object. 147 + * 148 + * This function is mandatory. 149 + * 150 + * Returns: 151 + * * Address in firmware address space. 152 + */ 153 + u32 (*get_fw_addr_with_offset)(struct pvr_fw_object *fw_obj, u32 offset); 154 + 155 + /** 156 + * @wrapper_init: 157 + * 158 + * Called to initialise FW wrapper. 159 + * @pvr_dev: Target PowerVR device. 160 + * 161 + * This function is mandatory. 162 + * 163 + * Returns: 164 + * * 0 on success. 165 + * * Any appropriate error on failure. 166 + */ 167 + int (*wrapper_init)(struct pvr_device *pvr_dev); 168 + 169 + /** 170 + * @has_fixed_data_addr: 171 + * 172 + * Called to check if firmware fixed data must be loaded at the address given by the 173 + * firmware layout table. 174 + * 175 + * This function is mandatory. 176 + * 177 + * Returns: 178 + * * %true if firmware fixed data must be loaded at the address given by the firmware 179 + * layout table. 180 + * * %false otherwise. 181 + */ 182 + bool (*has_fixed_data_addr)(void); 183 + 184 + /** 185 + * @irq: FW Interrupt information. 186 + * 187 + * Those are processor dependent, and should be initialized by the 188 + * processor backend in pvr_fw_funcs::init(). 189 + */ 190 + struct { 191 + /** @enable_reg: FW interrupt enable register. */ 192 + u32 enable_reg; 193 + 194 + /** @status_reg: FW interrupt status register. */ 195 + u32 status_reg; 196 + 197 + /** 198 + * @clear_reg: FW interrupt clear register. 199 + * 200 + * If @status_reg == @clear_reg, we clear by write a bit to zero, 201 + * otherwise we clear by writing a bit to one. 202 + */ 203 + u32 clear_reg; 204 + 205 + /** @event_mask: Bitmask of events to listen for. */ 206 + u32 event_mask; 207 + 208 + /** @clear_mask: Value to write to the clear_reg in order to clear FW IRQs. */ 209 + u32 clear_mask; 210 + } irq; 211 + }; 212 + 213 + /** 214 + * struct pvr_fw_mem - FW memory allocations 215 + */ 216 + struct pvr_fw_mem { 217 + /** @code_obj: Object representing firmware code. */ 218 + struct pvr_fw_object *code_obj; 219 + 220 + /** @data_obj: Object representing firmware data. */ 221 + struct pvr_fw_object *data_obj; 222 + 223 + /** 224 + * @core_code_obj: Object representing firmware core code. May be 225 + * %NULL if firmware does not contain this section. 226 + */ 227 + struct pvr_fw_object *core_code_obj; 228 + 229 + /** 230 + * @core_data_obj: Object representing firmware core data. May be 231 + * %NULL if firmware does not contain this section. 232 + */ 233 + struct pvr_fw_object *core_data_obj; 234 + 235 + /** @code: Driver-side copy of firmware code. */ 236 + u8 *code; 237 + 238 + /** @data: Driver-side copy of firmware data. */ 239 + u8 *data; 240 + 241 + /** 242 + * @core_code: Driver-side copy of firmware core code. May be %NULL if firmware does not 243 + * contain this section. 244 + */ 245 + u8 *core_code; 246 + 247 + /** 248 + * @core_data: Driver-side copy of firmware core data. May be %NULL if firmware does not 249 + * contain this section. 250 + */ 251 + u8 *core_data; 252 + 253 + /** @code_alloc_size: Allocation size of firmware code section. */ 254 + u32 code_alloc_size; 255 + 256 + /** @data_alloc_size: Allocation size of firmware data section. */ 257 + u32 data_alloc_size; 258 + 259 + /** @core_code_alloc_size: Allocation size of firmware core code section. */ 260 + u32 core_code_alloc_size; 261 + 262 + /** @core_data_alloc_size: Allocation size of firmware core data section. */ 263 + u32 core_data_alloc_size; 264 + 265 + /** 266 + * @fwif_connection_ctl_obj: Object representing FWIF connection control 267 + * structure. 268 + */ 269 + struct pvr_fw_object *fwif_connection_ctl_obj; 270 + 271 + /** @osinit_obj: Object representing FW OSINIT structure. */ 272 + struct pvr_fw_object *osinit_obj; 273 + 274 + /** @sysinit_obj: Object representing FW SYSINIT structure. */ 275 + struct pvr_fw_object *sysinit_obj; 276 + 277 + /** @osdata_obj: Object representing FW OSDATA structure. */ 278 + struct pvr_fw_object *osdata_obj; 279 + 280 + /** @hwrinfobuf_obj: Object representing FW hwrinfobuf structure. */ 281 + struct pvr_fw_object *hwrinfobuf_obj; 282 + 283 + /** @sysdata_obj: Object representing FW SYSDATA structure. */ 284 + struct pvr_fw_object *sysdata_obj; 285 + 286 + /** @power_sync_obj: Object representing power sync state. */ 287 + struct pvr_fw_object *power_sync_obj; 288 + 289 + /** @fault_page_obj: Object representing FW fault page. */ 290 + struct pvr_fw_object *fault_page_obj; 291 + 292 + /** @gpu_util_fwcb_obj: Object representing FW GPU utilisation control structure. */ 293 + struct pvr_fw_object *gpu_util_fwcb_obj; 294 + 295 + /** @runtime_cfg_obj: Object representing FW runtime config structure. */ 296 + struct pvr_fw_object *runtime_cfg_obj; 297 + 298 + /** @mmucache_sync_obj: Object used as the sync parameter in an MMU cache operation. */ 299 + struct pvr_fw_object *mmucache_sync_obj; 300 + }; 14 301 15 302 struct pvr_fw_device { 16 303 /** @firmware: Handle to the firmware loaded into the device. */ ··· 309 22 /** @layout_entries: Pointer to firmware layout. */ 310 23 const struct pvr_fw_layout_entry *layout_entries; 311 24 25 + /** @mem: Structure containing objects representing firmware memory allocations. */ 26 + struct pvr_fw_mem mem; 27 + 28 + /** @booted: %true if the firmware has been booted, %false otherwise. */ 29 + bool booted; 30 + 312 31 /** 313 32 * @processor_type: FW processor type for this device. Must be one of 314 33 * %PVR_FW_PROCESSOR_TYPE_*. 315 34 */ 316 35 u16 processor_type; 36 + 37 + /** @funcs: Function table for the FW processor used by this device. */ 38 + const struct pvr_fw_defs *defs; 39 + 40 + /** @processor_data: Pointer to data specific to FW processor. */ 41 + union { 42 + /** @mips_data: Pointer to MIPS-specific data. */ 43 + struct pvr_fw_mips_data *mips_data; 44 + } processor_data; 45 + 46 + /** @fw_heap_info: Firmware heap information. */ 47 + struct { 48 + /** @gpu_addr: Base address of firmware heap in GPU address space. */ 49 + u64 gpu_addr; 50 + 51 + /** @size: Size of main area of heap. */ 52 + u32 size; 53 + 54 + /** @offset_mask: Mask for offsets within FW heap. */ 55 + u32 offset_mask; 56 + 57 + /** @raw_size: Raw size of heap, including reserved areas. */ 58 + u32 raw_size; 59 + 60 + /** @log2_size: Log2 of raw size of heap. */ 61 + u32 log2_size; 62 + 63 + /** @config_offset: Offset of config area within heap. */ 64 + u32 config_offset; 65 + 66 + /** @reserved_size: Size of reserved area in heap. */ 67 + u32 reserved_size; 68 + } fw_heap_info; 69 + 70 + /** @fw_mm: Firmware address space allocator. */ 71 + struct drm_mm fw_mm; 72 + 73 + /** @fw_mm_lock: Lock protecting access to &fw_mm. */ 74 + spinlock_t fw_mm_lock; 75 + 76 + /** @fw_mm_base: Base address of address space managed by @fw_mm. */ 77 + u64 fw_mm_base; 78 + 79 + /** 80 + * @fwif_connection_ctl: Pointer to CPU mapping of FWIF connection 81 + * control structure. 82 + */ 83 + struct rogue_fwif_connection_ctl *fwif_connection_ctl; 84 + 85 + /** @fwif_sysinit: Pointer to CPU mapping of FW SYSINIT structure. */ 86 + struct rogue_fwif_sysinit *fwif_sysinit; 87 + 88 + /** @fwif_sysdata: Pointer to CPU mapping of FW SYSDATA structure. */ 89 + struct rogue_fwif_sysdata *fwif_sysdata; 90 + 91 + /** @fwif_osinit: Pointer to CPU mapping of FW OSINIT structure. */ 92 + struct rogue_fwif_osinit *fwif_osinit; 93 + 94 + /** @fwif_osdata: Pointer to CPU mapping of FW OSDATA structure. */ 95 + struct rogue_fwif_osdata *fwif_osdata; 96 + 97 + /** @power_sync: Pointer to CPU mapping of power sync state. */ 98 + u32 *power_sync; 99 + 100 + /** @hwrinfobuf: Pointer to CPU mapping of FW HWR info buffer. */ 101 + struct rogue_fwif_hwrinfobuf *hwrinfobuf; 102 + 103 + /** @fw_trace: Device firmware trace buffer state. */ 104 + struct pvr_fw_trace fw_trace; 105 + 106 + /** @fw_objs: Structure tracking FW objects. */ 107 + struct { 108 + /** @list: Head of FW object list. */ 109 + struct list_head list; 110 + 111 + /** @lock: Lock protecting access to FW object list. */ 112 + struct mutex lock; 113 + } fw_objs; 317 114 }; 318 115 116 + #define pvr_fw_irq_read_reg(pvr_dev, name) \ 117 + pvr_cr_read32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg) 118 + 119 + #define pvr_fw_irq_write_reg(pvr_dev, name, value) \ 120 + pvr_cr_write32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg, value) 121 + 122 + #define pvr_fw_irq_pending(pvr_dev) \ 123 + (pvr_fw_irq_read_reg(pvr_dev, status) & (pvr_dev)->fw_dev.defs->irq.event_mask) 124 + 125 + #define pvr_fw_irq_clear(pvr_dev) \ 126 + pvr_fw_irq_write_reg(pvr_dev, clear, (pvr_dev)->fw_dev.defs->irq.clear_mask) 127 + 128 + #define pvr_fw_irq_enable(pvr_dev) \ 129 + pvr_fw_irq_write_reg(pvr_dev, enable, (pvr_dev)->fw_dev.defs->irq.event_mask) 130 + 131 + #define pvr_fw_irq_disable(pvr_dev) \ 132 + pvr_fw_irq_write_reg(pvr_dev, enable, 0) 133 + 134 + extern const struct pvr_fw_defs pvr_fw_defs_meta; 135 + extern const struct pvr_fw_defs pvr_fw_defs_mips; 136 + 319 137 int pvr_fw_validate_init_device_info(struct pvr_device *pvr_dev); 138 + int pvr_fw_init(struct pvr_device *pvr_dev); 139 + void pvr_fw_fini(struct pvr_device *pvr_dev); 140 + 141 + int pvr_wait_for_fw_boot(struct pvr_device *pvr_dev); 142 + 143 + int 144 + pvr_fw_hard_reset(struct pvr_device *pvr_dev); 145 + 146 + void pvr_fw_mts_schedule(struct pvr_device *pvr_dev, u32 val); 147 + 148 + void 149 + pvr_fw_heap_info_init(struct pvr_device *pvr_dev, u32 log2_size, u32 reserved_size); 150 + 151 + const struct pvr_fw_layout_entry * 152 + pvr_fw_find_layout_entry(struct pvr_device *pvr_dev, enum pvr_fw_section_id id); 153 + int 154 + pvr_fw_find_mmu_segment(struct pvr_device *pvr_dev, u32 addr, u32 size, void *fw_code_ptr, 155 + void *fw_data_ptr, void *fw_core_code_ptr, void *fw_core_data_ptr, 156 + void **host_addr_out); 157 + 158 + int 159 + pvr_fw_structure_cleanup(struct pvr_device *pvr_dev, u32 type, struct pvr_fw_object *fw_obj, 160 + u32 offset); 161 + 162 + int pvr_fw_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags, 163 + void (*init)(void *cpu_ptr, void *priv), void *init_priv, 164 + struct pvr_fw_object **pvr_obj_out); 165 + 166 + void *pvr_fw_object_create_and_map(struct pvr_device *pvr_dev, size_t size, u64 flags, 167 + void (*init)(void *cpu_ptr, void *priv), 168 + void *init_priv, struct pvr_fw_object **pvr_obj_out); 169 + 170 + void * 171 + pvr_fw_object_create_and_map_offset(struct pvr_device *pvr_dev, u32 dev_offset, size_t size, 172 + u64 flags, void (*init)(void *cpu_ptr, void *priv), 173 + void *init_priv, struct pvr_fw_object **pvr_obj_out); 174 + 175 + static __always_inline void * 176 + pvr_fw_object_vmap(struct pvr_fw_object *fw_obj) 177 + { 178 + return pvr_gem_object_vmap(fw_obj->gem); 179 + } 180 + 181 + static __always_inline void 182 + pvr_fw_object_vunmap(struct pvr_fw_object *fw_obj) 183 + { 184 + pvr_gem_object_vunmap(fw_obj->gem); 185 + } 186 + 187 + void pvr_fw_object_destroy(struct pvr_fw_object *fw_obj); 188 + 189 + static __always_inline void 190 + pvr_fw_object_unmap_and_destroy(struct pvr_fw_object *fw_obj) 191 + { 192 + pvr_fw_object_vunmap(fw_obj); 193 + pvr_fw_object_destroy(fw_obj); 194 + } 195 + 196 + /** 197 + * pvr_fw_get_dma_addr() - Get DMA address for given offset in firmware object 198 + * @fw_obj: Pointer to object to lookup address in. 199 + * @offset: Offset within object to lookup address at. 200 + * @dma_addr_out: Pointer to location to store DMA address. 201 + * 202 + * Returns: 203 + * * 0 on success, or 204 + * * -%EINVAL if object is not currently backed, or if @offset is out of valid 205 + * range for this object. 206 + */ 207 + static __always_inline int 208 + pvr_fw_object_get_dma_addr(struct pvr_fw_object *fw_obj, u32 offset, dma_addr_t *dma_addr_out) 209 + { 210 + return pvr_gem_get_dma_addr(fw_obj->gem, offset, dma_addr_out); 211 + } 212 + 213 + void pvr_fw_object_get_fw_addr_offset(struct pvr_fw_object *fw_obj, u32 offset, u32 *fw_addr_out); 214 + 215 + static __always_inline void 216 + pvr_fw_object_get_fw_addr(struct pvr_fw_object *fw_obj, u32 *fw_addr_out) 217 + { 218 + pvr_fw_object_get_fw_addr_offset(fw_obj, 0, fw_addr_out); 219 + } 320 220 321 221 #endif /* PVR_FW_H */
+554
drivers/gpu/drm/imagination/pvr_fw_meta.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #include "pvr_device.h" 5 + #include "pvr_fw.h" 6 + #include "pvr_fw_info.h" 7 + #include "pvr_gem.h" 8 + #include "pvr_rogue_cr_defs.h" 9 + #include "pvr_rogue_meta.h" 10 + #include "pvr_vm.h" 11 + 12 + #include <linux/compiler.h> 13 + #include <linux/delay.h> 14 + #include <linux/firmware.h> 15 + #include <linux/ktime.h> 16 + #include <linux/types.h> 17 + 18 + #define ROGUE_FW_HEAP_META_SHIFT 25 /* 32 MB */ 19 + 20 + #define POLL_TIMEOUT_USEC 1000000 21 + 22 + /** 23 + * pvr_meta_cr_read32() - Read a META register via the Slave Port 24 + * @pvr_dev: Device pointer. 25 + * @reg_addr: Address of register to read. 26 + * @reg_value_out: Pointer to location to store register value. 27 + * 28 + * Returns: 29 + * * 0 on success, or 30 + * * Any error returned by pvr_cr_poll_reg32(). 31 + */ 32 + int 33 + pvr_meta_cr_read32(struct pvr_device *pvr_dev, u32 reg_addr, u32 *reg_value_out) 34 + { 35 + int err; 36 + 37 + /* Wait for Slave Port to be Ready. */ 38 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_META_SP_MSLVCTRL1, 39 + ROGUE_CR_META_SP_MSLVCTRL1_READY_EN | 40 + ROGUE_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, 41 + ROGUE_CR_META_SP_MSLVCTRL1_READY_EN | 42 + ROGUE_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, 43 + POLL_TIMEOUT_USEC); 44 + if (err) 45 + return err; 46 + 47 + /* Issue a Read. */ 48 + pvr_cr_write32(pvr_dev, ROGUE_CR_META_SP_MSLVCTRL0, 49 + reg_addr | ROGUE_CR_META_SP_MSLVCTRL0_RD_EN); 50 + (void)pvr_cr_read32(pvr_dev, ROGUE_CR_META_SP_MSLVCTRL0); /* Fence write. */ 51 + 52 + /* Wait for Slave Port to be Ready. */ 53 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_META_SP_MSLVCTRL1, 54 + ROGUE_CR_META_SP_MSLVCTRL1_READY_EN | 55 + ROGUE_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, 56 + ROGUE_CR_META_SP_MSLVCTRL1_READY_EN | 57 + ROGUE_CR_META_SP_MSLVCTRL1_GBLPORT_IDLE_EN, 58 + POLL_TIMEOUT_USEC); 59 + if (err) 60 + return err; 61 + 62 + *reg_value_out = pvr_cr_read32(pvr_dev, ROGUE_CR_META_SP_MSLVDATAX); 63 + 64 + return 0; 65 + } 66 + 67 + static int 68 + pvr_meta_wrapper_init(struct pvr_device *pvr_dev) 69 + { 70 + u64 garten_config; 71 + 72 + /* Configure META to Master boot. */ 73 + pvr_cr_write64(pvr_dev, ROGUE_CR_META_BOOT, ROGUE_CR_META_BOOT_MODE_EN); 74 + 75 + /* Set Garten IDLE to META idle and Set the Garten Wrapper BIF Fence address. */ 76 + 77 + /* Garten IDLE bit controlled by META. */ 78 + garten_config = ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META; 79 + 80 + /* The fence addr is set during the fw init sequence. */ 81 + 82 + /* Set PC = 0 for fences. */ 83 + garten_config &= 84 + ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_CLRMSK; 85 + garten_config |= 86 + (u64)MMU_CONTEXT_MAPPING_FWPRIV 87 + << ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_PC_BASE_SHIFT; 88 + 89 + /* Set SLC DM=META. */ 90 + garten_config |= ((u64)ROGUE_FW_SEGMMU_META_BIFDM_ID) 91 + << ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG_FENCE_DM_SHIFT; 92 + 93 + pvr_cr_write64(pvr_dev, ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG, garten_config); 94 + 95 + return 0; 96 + } 97 + 98 + static __always_inline void 99 + add_boot_arg(u32 **boot_conf, u32 param, u32 data) 100 + { 101 + *(*boot_conf)++ = param; 102 + *(*boot_conf)++ = data; 103 + } 104 + 105 + static int 106 + meta_ldr_cmd_loadmem(struct drm_device *drm_dev, const u8 *fw, 107 + struct rogue_meta_ldr_l1_data_blk *l1_data, u32 coremem_size, u8 *fw_code_ptr, 108 + u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr, const u32 fw_size) 109 + { 110 + struct rogue_meta_ldr_l2_data_blk *l2_block = 111 + (struct rogue_meta_ldr_l2_data_blk *)(fw + 112 + l1_data->cmd_data[1]); 113 + struct pvr_device *pvr_dev = to_pvr_device(drm_dev); 114 + u32 offset = l1_data->cmd_data[0]; 115 + u32 data_size; 116 + void *write_addr; 117 + int err; 118 + 119 + /* Verify header is within bounds. */ 120 + if (((u8 *)l2_block - fw) >= fw_size || ((u8 *)(l2_block + 1) - fw) >= fw_size) 121 + return -EINVAL; 122 + 123 + data_size = l2_block->length - 6 /* L2 Tag length and checksum */; 124 + 125 + /* Verify data is within bounds. */ 126 + if (((u8 *)l2_block->block_data - fw) >= fw_size || 127 + ((((u8 *)l2_block->block_data) + data_size) - fw) >= fw_size) 128 + return -EINVAL; 129 + 130 + if (!ROGUE_META_IS_COREMEM_CODE(offset, coremem_size) && 131 + !ROGUE_META_IS_COREMEM_DATA(offset, coremem_size)) { 132 + /* Global range is aliased to local range */ 133 + offset &= ~META_MEM_GLOBAL_RANGE_BIT; 134 + } 135 + 136 + err = pvr_fw_find_mmu_segment(pvr_dev, offset, data_size, fw_code_ptr, fw_data_ptr, 137 + fw_core_code_ptr, fw_core_data_ptr, &write_addr); 138 + if (err) { 139 + drm_err(drm_dev, 140 + "Addr 0x%x (size: %d) not found in any firmware segment", 141 + offset, data_size); 142 + return err; 143 + } 144 + 145 + memcpy(write_addr, l2_block->block_data, data_size); 146 + 147 + return 0; 148 + } 149 + 150 + static int 151 + meta_ldr_cmd_zeromem(struct drm_device *drm_dev, 152 + struct rogue_meta_ldr_l1_data_blk *l1_data, u32 coremem_size, 153 + u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr) 154 + { 155 + struct pvr_device *pvr_dev = to_pvr_device(drm_dev); 156 + u32 offset = l1_data->cmd_data[0]; 157 + u32 byte_count = l1_data->cmd_data[1]; 158 + void *write_addr; 159 + int err; 160 + 161 + if (ROGUE_META_IS_COREMEM_DATA(offset, coremem_size)) { 162 + /* cannot zero coremem directly */ 163 + return 0; 164 + } 165 + 166 + /* Global range is aliased to local range */ 167 + offset &= ~META_MEM_GLOBAL_RANGE_BIT; 168 + 169 + err = pvr_fw_find_mmu_segment(pvr_dev, offset, byte_count, fw_code_ptr, fw_data_ptr, 170 + fw_core_code_ptr, fw_core_data_ptr, &write_addr); 171 + if (err) { 172 + drm_err(drm_dev, 173 + "Addr 0x%x (size: %d) not found in any firmware segment", 174 + offset, byte_count); 175 + return err; 176 + } 177 + 178 + memset(write_addr, 0, byte_count); 179 + 180 + return 0; 181 + } 182 + 183 + static int 184 + meta_ldr_cmd_config(struct drm_device *drm_dev, const u8 *fw, 185 + struct rogue_meta_ldr_l1_data_blk *l1_data, 186 + const u32 fw_size, u32 **boot_conf_ptr) 187 + { 188 + struct rogue_meta_ldr_l2_data_blk *l2_block = 189 + (struct rogue_meta_ldr_l2_data_blk *)(fw + 190 + l1_data->cmd_data[0]); 191 + struct rogue_meta_ldr_cfg_blk *config_command; 192 + u32 l2_block_size; 193 + u32 curr_block_size = 0; 194 + u32 *boot_conf = boot_conf_ptr ? *boot_conf_ptr : NULL; 195 + 196 + /* Verify block header is within bounds. */ 197 + if (((u8 *)l2_block - fw) >= fw_size || ((u8 *)(l2_block + 1) - fw) >= fw_size) 198 + return -EINVAL; 199 + 200 + l2_block_size = l2_block->length - 6 /* L2 Tag length and checksum */; 201 + config_command = (struct rogue_meta_ldr_cfg_blk *)l2_block->block_data; 202 + 203 + if (((u8 *)config_command - fw) >= fw_size || 204 + ((((u8 *)config_command) + l2_block_size) - fw) >= fw_size) 205 + return -EINVAL; 206 + 207 + while (l2_block_size >= 12) { 208 + if (config_command->type != ROGUE_META_LDR_CFG_WRITE) 209 + return -EINVAL; 210 + 211 + /* 212 + * Only write to bootloader if we got a valid pointer to the FW 213 + * code allocation. 214 + */ 215 + if (boot_conf) { 216 + u32 register_offset = config_command->block_data[0]; 217 + u32 register_value = config_command->block_data[1]; 218 + 219 + /* Do register write */ 220 + add_boot_arg(&boot_conf, register_offset, 221 + register_value); 222 + } 223 + 224 + curr_block_size = 12; 225 + l2_block_size -= curr_block_size; 226 + config_command = (struct rogue_meta_ldr_cfg_blk 227 + *)((uintptr_t)config_command + 228 + curr_block_size); 229 + } 230 + 231 + if (boot_conf_ptr) 232 + *boot_conf_ptr = boot_conf; 233 + 234 + return 0; 235 + } 236 + 237 + /** 238 + * process_ldr_command_stream() - Process LDR firmware image and populate 239 + * firmware sections 240 + * @pvr_dev: Device pointer. 241 + * @fw: Pointer to firmware image. 242 + * @fw_code_ptr: Pointer to FW code section. 243 + * @fw_data_ptr: Pointer to FW data section. 244 + * @fw_core_code_ptr: Pointer to FW coremem code section. 245 + * @fw_core_data_ptr: Pointer to FW coremem data section. 246 + * @boot_conf_ptr: Pointer to boot config argument pointer. 247 + * 248 + * Returns : 249 + * * 0 on success, or 250 + * * -EINVAL on any error in LDR command stream. 251 + */ 252 + static int 253 + process_ldr_command_stream(struct pvr_device *pvr_dev, const u8 *fw, u8 *fw_code_ptr, 254 + u8 *fw_data_ptr, u8 *fw_core_code_ptr, 255 + u8 *fw_core_data_ptr, u32 **boot_conf_ptr) 256 + { 257 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 258 + struct rogue_meta_ldr_block_hdr *ldr_header = 259 + (struct rogue_meta_ldr_block_hdr *)fw; 260 + struct rogue_meta_ldr_l1_data_blk *l1_data = 261 + (struct rogue_meta_ldr_l1_data_blk *)(fw + ldr_header->sl_data); 262 + const u32 fw_size = pvr_dev->fw_dev.firmware->size; 263 + int err; 264 + 265 + u32 *boot_conf = boot_conf_ptr ? *boot_conf_ptr : NULL; 266 + u32 coremem_size; 267 + 268 + err = PVR_FEATURE_VALUE(pvr_dev, meta_coremem_size, &coremem_size); 269 + if (err) 270 + return err; 271 + 272 + coremem_size *= SZ_1K; 273 + 274 + while (l1_data) { 275 + /* Verify block header is within bounds. */ 276 + if (((u8 *)l1_data - fw) >= fw_size || ((u8 *)(l1_data + 1) - fw) >= fw_size) 277 + return -EINVAL; 278 + 279 + if (ROGUE_META_LDR_BLK_IS_COMMENT(l1_data->cmd)) { 280 + /* Don't process comment blocks */ 281 + goto next_block; 282 + } 283 + 284 + switch (l1_data->cmd & ROGUE_META_LDR_CMD_MASK) 285 + case ROGUE_META_LDR_CMD_LOADMEM: { 286 + err = meta_ldr_cmd_loadmem(drm_dev, fw, l1_data, 287 + coremem_size, 288 + fw_code_ptr, fw_data_ptr, 289 + fw_core_code_ptr, 290 + fw_core_data_ptr, fw_size); 291 + if (err) 292 + return err; 293 + break; 294 + 295 + case ROGUE_META_LDR_CMD_START_THREADS: 296 + /* Don't process this block */ 297 + break; 298 + 299 + case ROGUE_META_LDR_CMD_ZEROMEM: 300 + err = meta_ldr_cmd_zeromem(drm_dev, l1_data, 301 + coremem_size, 302 + fw_code_ptr, fw_data_ptr, 303 + fw_core_code_ptr, 304 + fw_core_data_ptr); 305 + if (err) 306 + return err; 307 + break; 308 + 309 + case ROGUE_META_LDR_CMD_CONFIG: 310 + err = meta_ldr_cmd_config(drm_dev, fw, l1_data, fw_size, 311 + &boot_conf); 312 + if (err) 313 + return err; 314 + break; 315 + 316 + default: 317 + return -EINVAL; 318 + } 319 + 320 + next_block: 321 + if (l1_data->next == 0xFFFFFFFF) 322 + break; 323 + 324 + l1_data = (struct rogue_meta_ldr_l1_data_blk *)(fw + 325 + l1_data->next); 326 + } 327 + 328 + if (boot_conf_ptr) 329 + *boot_conf_ptr = boot_conf; 330 + 331 + return 0; 332 + } 333 + 334 + static void 335 + configure_seg_id(u64 seg_out_addr, u32 seg_base, u32 seg_limit, u32 seg_id, 336 + u32 **boot_conf_ptr) 337 + { 338 + u32 seg_out_addr0 = seg_out_addr & 0x00000000FFFFFFFFUL; 339 + u32 seg_out_addr1 = (seg_out_addr >> 32) & 0x00000000FFFFFFFFUL; 340 + u32 *boot_conf = *boot_conf_ptr; 341 + 342 + /* META segments have a minimum size. */ 343 + u32 limit_off = max(seg_limit, ROGUE_FW_SEGMMU_ALIGN); 344 + 345 + /* The limit is an offset, therefore off = size - 1. */ 346 + limit_off -= 1; 347 + 348 + seg_base |= ROGUE_FW_SEGMMU_ALLTHRS_WRITEABLE; 349 + 350 + add_boot_arg(&boot_conf, META_CR_MMCU_SEGMENT_N_BASE(seg_id), seg_base); 351 + add_boot_arg(&boot_conf, META_CR_MMCU_SEGMENT_N_LIMIT(seg_id), limit_off); 352 + add_boot_arg(&boot_conf, META_CR_MMCU_SEGMENT_N_OUTA0(seg_id), seg_out_addr0); 353 + add_boot_arg(&boot_conf, META_CR_MMCU_SEGMENT_N_OUTA1(seg_id), seg_out_addr1); 354 + 355 + *boot_conf_ptr = boot_conf; 356 + } 357 + 358 + static u64 get_fw_obj_gpu_addr(struct pvr_fw_object *fw_obj) 359 + { 360 + struct pvr_device *pvr_dev = to_pvr_device(gem_from_pvr_gem(fw_obj->gem)->dev); 361 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 362 + 363 + return fw_obj->fw_addr_offset + fw_dev->fw_heap_info.gpu_addr; 364 + } 365 + 366 + static void 367 + configure_seg_mmu(struct pvr_device *pvr_dev, u32 **boot_conf_ptr) 368 + { 369 + const struct pvr_fw_layout_entry *layout_entries = pvr_dev->fw_dev.layout_entries; 370 + u32 num_layout_entries = pvr_dev->fw_dev.header->layout_entry_num; 371 + u64 seg_out_addr_top; 372 + u32 i; 373 + 374 + seg_out_addr_top = 375 + ROGUE_FW_SEGMMU_OUTADDR_TOP_SLC(MMU_CONTEXT_MAPPING_FWPRIV, 376 + ROGUE_FW_SEGMMU_META_BIFDM_ID); 377 + 378 + for (i = 0; i < num_layout_entries; i++) { 379 + /* 380 + * FW code is using the bootloader segment which is already 381 + * configured on boot. FW coremem code and data don't use the 382 + * segment MMU. Only the FW data segment needs to be configured. 383 + */ 384 + if (layout_entries[i].type == FW_DATA) { 385 + u32 seg_id = ROGUE_FW_SEGMMU_DATA_ID; 386 + u64 seg_out_addr = get_fw_obj_gpu_addr(pvr_dev->fw_dev.mem.data_obj); 387 + 388 + seg_out_addr += layout_entries[i].alloc_offset; 389 + seg_out_addr |= seg_out_addr_top; 390 + 391 + /* Write the sequence to the bootldr. */ 392 + configure_seg_id(seg_out_addr, 393 + layout_entries[i].base_addr, 394 + layout_entries[i].alloc_size, seg_id, 395 + boot_conf_ptr); 396 + 397 + break; 398 + } 399 + } 400 + } 401 + 402 + static void 403 + configure_meta_caches(u32 **boot_conf_ptr) 404 + { 405 + u32 *boot_conf = *boot_conf_ptr; 406 + u32 d_cache_t0, i_cache_t0; 407 + u32 d_cache_t1, i_cache_t1; 408 + u32 d_cache_t2, i_cache_t2; 409 + u32 d_cache_t3, i_cache_t3; 410 + 411 + /* Initialise I/Dcache settings */ 412 + d_cache_t0 = META_CR_SYSC_DCPARTX_CACHED_WRITE_ENABLE; 413 + d_cache_t1 = META_CR_SYSC_DCPARTX_CACHED_WRITE_ENABLE; 414 + d_cache_t2 = META_CR_SYSC_DCPARTX_CACHED_WRITE_ENABLE; 415 + d_cache_t3 = META_CR_SYSC_DCPARTX_CACHED_WRITE_ENABLE; 416 + i_cache_t0 = 0; 417 + i_cache_t1 = 0; 418 + i_cache_t2 = 0; 419 + i_cache_t3 = 0; 420 + 421 + d_cache_t0 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_FULL_CACHE; 422 + i_cache_t0 |= META_CR_SYSC_XCPARTX_LOCAL_ADDR_FULL_CACHE; 423 + 424 + /* Local region MMU enhanced bypass: WIN-3 mode for code and data caches */ 425 + add_boot_arg(&boot_conf, META_CR_MMCU_LOCAL_EBCTRL, 426 + META_CR_MMCU_LOCAL_EBCTRL_ICWIN | 427 + META_CR_MMCU_LOCAL_EBCTRL_DCWIN); 428 + 429 + /* Data cache partitioning thread 0 to 3 */ 430 + add_boot_arg(&boot_conf, META_CR_SYSC_DCPART(0), d_cache_t0); 431 + add_boot_arg(&boot_conf, META_CR_SYSC_DCPART(1), d_cache_t1); 432 + add_boot_arg(&boot_conf, META_CR_SYSC_DCPART(2), d_cache_t2); 433 + add_boot_arg(&boot_conf, META_CR_SYSC_DCPART(3), d_cache_t3); 434 + 435 + /* Enable data cache hits */ 436 + add_boot_arg(&boot_conf, META_CR_MMCU_DCACHE_CTRL, 437 + META_CR_MMCU_XCACHE_CTRL_CACHE_HITS_EN); 438 + 439 + /* Instruction cache partitioning thread 0 to 3 */ 440 + add_boot_arg(&boot_conf, META_CR_SYSC_ICPART(0), i_cache_t0); 441 + add_boot_arg(&boot_conf, META_CR_SYSC_ICPART(1), i_cache_t1); 442 + add_boot_arg(&boot_conf, META_CR_SYSC_ICPART(2), i_cache_t2); 443 + add_boot_arg(&boot_conf, META_CR_SYSC_ICPART(3), i_cache_t3); 444 + 445 + /* Enable instruction cache hits */ 446 + add_boot_arg(&boot_conf, META_CR_MMCU_ICACHE_CTRL, 447 + META_CR_MMCU_XCACHE_CTRL_CACHE_HITS_EN); 448 + 449 + add_boot_arg(&boot_conf, 0x040000C0, 0); 450 + 451 + *boot_conf_ptr = boot_conf; 452 + } 453 + 454 + static int 455 + pvr_meta_fw_process(struct pvr_device *pvr_dev, const u8 *fw, 456 + u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr, 457 + u32 core_code_alloc_size) 458 + { 459 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 460 + u32 *boot_conf; 461 + int err; 462 + 463 + boot_conf = ((u32 *)fw_code_ptr) + ROGUE_FW_BOOTLDR_CONF_OFFSET; 464 + 465 + /* Slave port and JTAG accesses are privileged. */ 466 + add_boot_arg(&boot_conf, META_CR_SYSC_JTAG_THREAD, 467 + META_CR_SYSC_JTAG_THREAD_PRIV_EN); 468 + 469 + configure_seg_mmu(pvr_dev, &boot_conf); 470 + 471 + /* Populate FW sections from LDR image. */ 472 + err = process_ldr_command_stream(pvr_dev, fw, fw_code_ptr, fw_data_ptr, fw_core_code_ptr, 473 + fw_core_data_ptr, &boot_conf); 474 + if (err) 475 + return err; 476 + 477 + configure_meta_caches(&boot_conf); 478 + 479 + /* End argument list. */ 480 + add_boot_arg(&boot_conf, 0, 0); 481 + 482 + if (fw_dev->mem.core_code_obj) { 483 + u32 core_code_fw_addr; 484 + 485 + pvr_fw_object_get_fw_addr(fw_dev->mem.core_code_obj, &core_code_fw_addr); 486 + add_boot_arg(&boot_conf, core_code_fw_addr, core_code_alloc_size); 487 + } else { 488 + add_boot_arg(&boot_conf, 0, 0); 489 + } 490 + /* None of the cores supported by this driver have META DMA. */ 491 + add_boot_arg(&boot_conf, 0, 0); 492 + 493 + return 0; 494 + } 495 + 496 + static int 497 + pvr_meta_init(struct pvr_device *pvr_dev) 498 + { 499 + pvr_fw_heap_info_init(pvr_dev, ROGUE_FW_HEAP_META_SHIFT, 0); 500 + 501 + return 0; 502 + } 503 + 504 + static u32 505 + pvr_meta_get_fw_addr_with_offset(struct pvr_fw_object *fw_obj, u32 offset) 506 + { 507 + u32 fw_addr = fw_obj->fw_addr_offset + offset + ROGUE_FW_SEGMMU_DATA_BASE_ADDRESS; 508 + 509 + /* META cacheability is determined by address. */ 510 + if (fw_obj->gem->flags & PVR_BO_FW_FLAGS_DEVICE_UNCACHED) 511 + fw_addr |= ROGUE_FW_SEGMMU_DATA_META_UNCACHED | 512 + ROGUE_FW_SEGMMU_DATA_VIVT_SLC_UNCACHED; 513 + 514 + return fw_addr; 515 + } 516 + 517 + static int 518 + pvr_meta_vm_map(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj) 519 + { 520 + struct pvr_gem_object *pvr_obj = fw_obj->gem; 521 + 522 + return pvr_vm_map(pvr_dev->kernel_vm_ctx, pvr_obj, 0, fw_obj->fw_mm_node.start, 523 + pvr_gem_object_size(pvr_obj)); 524 + } 525 + 526 + static void 527 + pvr_meta_vm_unmap(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj) 528 + { 529 + pvr_vm_unmap(pvr_dev->kernel_vm_ctx, fw_obj->fw_mm_node.start, 530 + fw_obj->fw_mm_node.size); 531 + } 532 + 533 + static bool 534 + pvr_meta_has_fixed_data_addr(void) 535 + { 536 + return false; 537 + } 538 + 539 + const struct pvr_fw_defs pvr_fw_defs_meta = { 540 + .init = pvr_meta_init, 541 + .fw_process = pvr_meta_fw_process, 542 + .vm_map = pvr_meta_vm_map, 543 + .vm_unmap = pvr_meta_vm_unmap, 544 + .get_fw_addr_with_offset = pvr_meta_get_fw_addr_with_offset, 545 + .wrapper_init = pvr_meta_wrapper_init, 546 + .has_fixed_data_addr = pvr_meta_has_fixed_data_addr, 547 + .irq = { 548 + .enable_reg = ROGUE_CR_META_SP_MSLVIRQENABLE, 549 + .status_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS, 550 + .clear_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS, 551 + .event_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN, 552 + .clear_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK, 553 + }, 554 + };
+14
drivers/gpu/drm/imagination/pvr_fw_meta.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #ifndef PVR_FW_META_H 5 + #define PVR_FW_META_H 6 + 7 + #include <linux/types.h> 8 + 9 + /* Forward declaration from pvr_device.h */ 10 + struct pvr_device; 11 + 12 + int pvr_meta_cr_read32(struct pvr_device *pvr_dev, u32 reg_addr, u32 *reg_value_out); 13 + 14 + #endif /* PVR_FW_META_H */
+306
drivers/gpu/drm/imagination/pvr_fw_startstop.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #include "pvr_device.h" 5 + #include "pvr_fw.h" 6 + #include "pvr_fw_meta.h" 7 + #include "pvr_fw_startstop.h" 8 + #include "pvr_rogue_cr_defs.h" 9 + #include "pvr_rogue_meta.h" 10 + #include "pvr_vm.h" 11 + 12 + #include <linux/compiler.h> 13 + #include <linux/delay.h> 14 + #include <linux/ktime.h> 15 + #include <linux/types.h> 16 + 17 + #define POLL_TIMEOUT_USEC 1000000 18 + 19 + static void 20 + rogue_axi_ace_list_init(struct pvr_device *pvr_dev) 21 + { 22 + /* Setup AXI-ACE config. Set everything to outer cache. */ 23 + u64 reg_val = 24 + (3U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_NON_SNOOPING_SHIFT) | 25 + (3U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_NON_SNOOPING_SHIFT) | 26 + (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_CACHE_MAINTENANCE_SHIFT) | 27 + (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_AWDOMAIN_COHERENT_SHIFT) | 28 + (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARDOMAIN_COHERENT_SHIFT) | 29 + (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_AWCACHE_COHERENT_SHIFT) | 30 + (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_COHERENT_SHIFT) | 31 + (2U << ROGUE_CR_AXI_ACE_LITE_CONFIGURATION_ARCACHE_CACHE_MAINTENANCE_SHIFT); 32 + 33 + pvr_cr_write64(pvr_dev, ROGUE_CR_AXI_ACE_LITE_CONFIGURATION, reg_val); 34 + } 35 + 36 + static void 37 + rogue_bif_init(struct pvr_device *pvr_dev) 38 + { 39 + dma_addr_t pc_dma_addr; 40 + u64 pc_addr; 41 + 42 + /* Acquire the address of the Kernel Page Catalogue. */ 43 + pc_dma_addr = pvr_vm_get_page_table_root_addr(pvr_dev->kernel_vm_ctx); 44 + 45 + /* Write the kernel catalogue base. */ 46 + pc_addr = ((((u64)pc_dma_addr >> ROGUE_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT) 47 + << ROGUE_CR_BIF_CAT_BASE0_ADDR_SHIFT) & 48 + ~ROGUE_CR_BIF_CAT_BASE0_ADDR_CLRMSK); 49 + 50 + pvr_cr_write64(pvr_dev, BIF_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV), 51 + pc_addr); 52 + } 53 + 54 + static int 55 + rogue_slc_init(struct pvr_device *pvr_dev) 56 + { 57 + u16 slc_cache_line_size_bits; 58 + u32 reg_val; 59 + int err; 60 + 61 + /* 62 + * SLC Misc control. 63 + * 64 + * Note: This is a 64bit register and we set only the lower 32bits 65 + * leaving the top 32bits (ROGUE_CR_SLC_CTRL_MISC_SCRAMBLE_BITS) 66 + * unchanged from the HW default. 67 + */ 68 + reg_val = (pvr_cr_read32(pvr_dev, ROGUE_CR_SLC_CTRL_MISC) & 69 + ROGUE_CR_SLC_CTRL_MISC_ENABLE_PSG_HAZARD_CHECK_EN) | 70 + ROGUE_CR_SLC_CTRL_MISC_ADDR_DECODE_MODE_PVR_HASH1; 71 + 72 + err = PVR_FEATURE_VALUE(pvr_dev, slc_cache_line_size_bits, &slc_cache_line_size_bits); 73 + if (err) 74 + return err; 75 + 76 + /* Bypass burst combiner if SLC line size is smaller than 1024 bits. */ 77 + if (slc_cache_line_size_bits < 1024) 78 + reg_val |= ROGUE_CR_SLC_CTRL_MISC_BYPASS_BURST_COMBINER_EN; 79 + 80 + if (PVR_HAS_QUIRK(pvr_dev, 71242) && !PVR_HAS_FEATURE(pvr_dev, gpu_multicore_support)) 81 + reg_val |= ROGUE_CR_SLC_CTRL_MISC_LAZYWB_OVERRIDE_EN; 82 + 83 + pvr_cr_write32(pvr_dev, ROGUE_CR_SLC_CTRL_MISC, reg_val); 84 + 85 + return 0; 86 + } 87 + 88 + /** 89 + * pvr_fw_start() - Start FW processor and boot firmware 90 + * @pvr_dev: Target PowerVR device. 91 + * 92 + * Returns: 93 + * * 0 on success, or 94 + * * Any error returned by rogue_slc_init(). 95 + */ 96 + int 97 + pvr_fw_start(struct pvr_device *pvr_dev) 98 + { 99 + bool has_reset2 = PVR_HAS_FEATURE(pvr_dev, xe_tpu2); 100 + u64 soft_reset_mask; 101 + int err; 102 + 103 + if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe)) 104 + soft_reset_mask = ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL; 105 + else 106 + soft_reset_mask = ROGUE_CR_SOFT_RESET_MASKFULL; 107 + 108 + if (PVR_HAS_FEATURE(pvr_dev, sys_bus_secure_reset)) { 109 + /* 110 + * Disable the default sys_bus_secure protection to perform 111 + * minimal setup. 112 + */ 113 + pvr_cr_write32(pvr_dev, ROGUE_CR_SYS_BUS_SECURE, 0); 114 + (void)pvr_cr_read32(pvr_dev, ROGUE_CR_SYS_BUS_SECURE); /* Fence write */ 115 + } 116 + 117 + /* Set Rogue in soft-reset. */ 118 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask); 119 + if (has_reset2) 120 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, ROGUE_CR_SOFT_RESET2_MASKFULL); 121 + 122 + /* Read soft-reset to fence previous write in order to clear the SOCIF pipeline. */ 123 + (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET); 124 + if (has_reset2) 125 + (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2); 126 + 127 + /* Take Rascal and Dust out of reset. */ 128 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, 129 + soft_reset_mask ^ ROGUE_CR_SOFT_RESET_RASCALDUSTS_EN); 130 + if (has_reset2) 131 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0); 132 + 133 + (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET); 134 + if (has_reset2) 135 + (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2); 136 + 137 + /* Take everything out of reset but the FW processor. */ 138 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_GARTEN_EN); 139 + if (has_reset2) 140 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET2, 0); 141 + 142 + (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET); 143 + if (has_reset2) 144 + (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET2); 145 + 146 + err = rogue_slc_init(pvr_dev); 147 + if (err) 148 + goto err_reset; 149 + 150 + /* Initialise Firmware wrapper. */ 151 + pvr_dev->fw_dev.defs->wrapper_init(pvr_dev); 152 + 153 + /* We must init the AXI-ACE interface before first BIF transaction. */ 154 + rogue_axi_ace_list_init(pvr_dev); 155 + 156 + if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { 157 + /* Initialise BIF. */ 158 + rogue_bif_init(pvr_dev); 159 + } 160 + 161 + /* Need to wait for at least 16 cycles before taking the FW processor out of reset ... */ 162 + udelay(3); 163 + 164 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, 0x0); 165 + (void)pvr_cr_read64(pvr_dev, ROGUE_CR_SOFT_RESET); 166 + 167 + /* ... and afterwards. */ 168 + udelay(3); 169 + 170 + return 0; 171 + 172 + err_reset: 173 + /* Put everything back into soft-reset. */ 174 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask); 175 + 176 + return err; 177 + } 178 + 179 + /** 180 + * pvr_fw_stop() - Stop FW processor 181 + * @pvr_dev: Target PowerVR device. 182 + * 183 + * Returns: 184 + * * 0 on success, or 185 + * * Any error returned by pvr_cr_poll_reg32(). 186 + */ 187 + int 188 + pvr_fw_stop(struct pvr_device *pvr_dev) 189 + { 190 + const u32 sidekick_idle_mask = ROGUE_CR_SIDEKICK_IDLE_MASKFULL & 191 + ~(ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN | 192 + ROGUE_CR_SIDEKICK_IDLE_SOCIF_EN | 193 + ROGUE_CR_SIDEKICK_IDLE_HOSTIF_EN); 194 + bool skip_garten_idle = false; 195 + u32 reg_value; 196 + int err; 197 + 198 + /* 199 + * Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper. 200 + * For cores with the LAYOUT_MARS feature, SIDEKICK would have been 201 + * powered down by the FW. 202 + */ 203 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask, 204 + sidekick_idle_mask, POLL_TIMEOUT_USEC); 205 + if (err) 206 + return err; 207 + 208 + /* Unset MTS DM association with threads. */ 209 + pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC, 210 + ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_MASKFULL & 211 + ROGUE_CR_MTS_INTCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK); 212 + pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC, 213 + ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_MASKFULL & 214 + ROGUE_CR_MTS_BGCTX_THREAD0_DM_ASSOC_DM_ASSOC_CLRMSK); 215 + pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC, 216 + ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_MASKFULL & 217 + ROGUE_CR_MTS_INTCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK); 218 + pvr_cr_write32(pvr_dev, ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC, 219 + ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_MASKFULL & 220 + ROGUE_CR_MTS_BGCTX_THREAD1_DM_ASSOC_DM_ASSOC_CLRMSK); 221 + 222 + /* Extra Idle checks. */ 223 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_STATUS_MMU, 0, 224 + ROGUE_CR_BIF_STATUS_MMU_MASKFULL, 225 + POLL_TIMEOUT_USEC); 226 + if (err) 227 + return err; 228 + 229 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_STATUS_MMU, 0, 230 + ROGUE_CR_BIFPM_STATUS_MMU_MASKFULL, 231 + POLL_TIMEOUT_USEC); 232 + if (err) 233 + return err; 234 + 235 + if (!PVR_HAS_FEATURE(pvr_dev, xt_top_infrastructure)) { 236 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIF_READS_EXT_STATUS, 0, 237 + ROGUE_CR_BIF_READS_EXT_STATUS_MASKFULL, 238 + POLL_TIMEOUT_USEC); 239 + if (err) 240 + return err; 241 + } 242 + 243 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_BIFPM_READS_EXT_STATUS, 0, 244 + ROGUE_CR_BIFPM_READS_EXT_STATUS_MASKFULL, 245 + POLL_TIMEOUT_USEC); 246 + if (err) 247 + return err; 248 + 249 + err = pvr_cr_poll_reg64(pvr_dev, ROGUE_CR_SLC_STATUS1, 0, 250 + ROGUE_CR_SLC_STATUS1_MASKFULL, 251 + POLL_TIMEOUT_USEC); 252 + if (err) 253 + return err; 254 + 255 + /* 256 + * Wait for SLC to signal IDLE. 257 + * For cores with the LAYOUT_MARS feature, SLC would have been powered 258 + * down by the FW. 259 + */ 260 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SLC_IDLE, 261 + ROGUE_CR_SLC_IDLE_MASKFULL, 262 + ROGUE_CR_SLC_IDLE_MASKFULL, POLL_TIMEOUT_USEC); 263 + if (err) 264 + return err; 265 + 266 + /* 267 + * Wait for Sidekick/Jones to signal IDLE except for the Garten Wrapper. 268 + * For cores with the LAYOUT_MARS feature, SIDEKICK would have been powered 269 + * down by the FW. 270 + */ 271 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, sidekick_idle_mask, 272 + sidekick_idle_mask, POLL_TIMEOUT_USEC); 273 + if (err) 274 + return err; 275 + 276 + if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_META) { 277 + err = pvr_meta_cr_read32(pvr_dev, META_CR_TxVECINT_BHALT, &reg_value); 278 + if (err) 279 + return err; 280 + 281 + /* 282 + * Wait for Sidekick/Jones to signal IDLE including the Garten 283 + * Wrapper if there is no debugger attached (TxVECINT_BHALT = 284 + * 0x0). 285 + */ 286 + if (reg_value) 287 + skip_garten_idle = true; 288 + } 289 + 290 + if (!skip_garten_idle) { 291 + err = pvr_cr_poll_reg32(pvr_dev, ROGUE_CR_SIDEKICK_IDLE, 292 + ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN, 293 + ROGUE_CR_SIDEKICK_IDLE_GARTEN_EN, 294 + POLL_TIMEOUT_USEC); 295 + if (err) 296 + return err; 297 + } 298 + 299 + if (PVR_HAS_FEATURE(pvr_dev, pbe2_in_xe)) 300 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, 301 + ROGUE_CR_SOFT_RESET__PBE2_XE__MASKFULL); 302 + else 303 + pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, ROGUE_CR_SOFT_RESET_MASKFULL); 304 + 305 + return 0; 306 + }
+13
drivers/gpu/drm/imagination/pvr_fw_startstop.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #ifndef PVR_FW_STARTSTOP_H 5 + #define PVR_FW_STARTSTOP_H 6 + 7 + /* Forward declaration from pvr_device.h. */ 8 + struct pvr_device; 9 + 10 + int pvr_fw_start(struct pvr_device *pvr_dev); 11 + int pvr_fw_stop(struct pvr_device *pvr_dev); 12 + 13 + #endif /* PVR_FW_STARTSTOP_H */
+120
drivers/gpu/drm/imagination/pvr_fw_trace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #include "pvr_device.h" 5 + #include "pvr_gem.h" 6 + #include "pvr_rogue_fwif.h" 7 + #include "pvr_fw_trace.h" 8 + 9 + #include <drm/drm_file.h> 10 + 11 + #include <linux/build_bug.h> 12 + #include <linux/dcache.h> 13 + #include <linux/sysfs.h> 14 + #include <linux/types.h> 15 + 16 + static void 17 + tracebuf_ctrl_init(void *cpu_ptr, void *priv) 18 + { 19 + struct rogue_fwif_tracebuf *tracebuf_ctrl = cpu_ptr; 20 + struct pvr_fw_trace *fw_trace = priv; 21 + u32 thread_nr; 22 + 23 + tracebuf_ctrl->tracebuf_size_in_dwords = ROGUE_FW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS; 24 + tracebuf_ctrl->tracebuf_flags = 0; 25 + 26 + if (fw_trace->group_mask) 27 + tracebuf_ctrl->log_type = fw_trace->group_mask | ROGUE_FWIF_LOG_TYPE_TRACE; 28 + else 29 + tracebuf_ctrl->log_type = ROGUE_FWIF_LOG_TYPE_NONE; 30 + 31 + for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) { 32 + struct rogue_fwif_tracebuf_space *tracebuf_space = 33 + &tracebuf_ctrl->tracebuf[thread_nr]; 34 + struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr]; 35 + 36 + pvr_fw_object_get_fw_addr(trace_buffer->buf_obj, 37 + &tracebuf_space->trace_buffer_fw_addr); 38 + 39 + tracebuf_space->trace_buffer = trace_buffer->buf; 40 + tracebuf_space->trace_pointer = 0; 41 + } 42 + } 43 + 44 + int pvr_fw_trace_init(struct pvr_device *pvr_dev) 45 + { 46 + struct pvr_fw_trace *fw_trace = &pvr_dev->fw_dev.fw_trace; 47 + struct drm_device *drm_dev = from_pvr_device(pvr_dev); 48 + u32 thread_nr; 49 + int err; 50 + 51 + for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) { 52 + struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr]; 53 + 54 + trace_buffer->buf = 55 + pvr_fw_object_create_and_map(pvr_dev, 56 + ROGUE_FW_TRACE_BUF_DEFAULT_SIZE_IN_DWORDS * 57 + sizeof(*trace_buffer->buf), 58 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED | 59 + PVR_BO_FW_NO_CLEAR_ON_RESET, 60 + NULL, NULL, &trace_buffer->buf_obj); 61 + if (IS_ERR(trace_buffer->buf)) { 62 + drm_err(drm_dev, "Unable to allocate trace buffer\n"); 63 + err = PTR_ERR(trace_buffer->buf); 64 + trace_buffer->buf = NULL; 65 + goto err_free_buf; 66 + } 67 + } 68 + 69 + /* TODO: Provide control of group mask. */ 70 + fw_trace->group_mask = 0; 71 + 72 + fw_trace->tracebuf_ctrl = 73 + pvr_fw_object_create_and_map(pvr_dev, 74 + sizeof(*fw_trace->tracebuf_ctrl), 75 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED | 76 + PVR_BO_FW_NO_CLEAR_ON_RESET, 77 + tracebuf_ctrl_init, fw_trace, 78 + &fw_trace->tracebuf_ctrl_obj); 79 + if (IS_ERR(fw_trace->tracebuf_ctrl)) { 80 + drm_err(drm_dev, "Unable to allocate trace buffer control structure\n"); 81 + err = PTR_ERR(fw_trace->tracebuf_ctrl); 82 + goto err_free_buf; 83 + } 84 + 85 + BUILD_BUG_ON(ARRAY_SIZE(fw_trace->tracebuf_ctrl->tracebuf) != 86 + ARRAY_SIZE(fw_trace->buffers)); 87 + 88 + for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) { 89 + struct rogue_fwif_tracebuf_space *tracebuf_space = 90 + &fw_trace->tracebuf_ctrl->tracebuf[thread_nr]; 91 + struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr]; 92 + 93 + trace_buffer->tracebuf_space = tracebuf_space; 94 + } 95 + 96 + return 0; 97 + 98 + err_free_buf: 99 + for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) { 100 + struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr]; 101 + 102 + if (trace_buffer->buf) 103 + pvr_fw_object_unmap_and_destroy(trace_buffer->buf_obj); 104 + } 105 + 106 + return err; 107 + } 108 + 109 + void pvr_fw_trace_fini(struct pvr_device *pvr_dev) 110 + { 111 + struct pvr_fw_trace *fw_trace = &pvr_dev->fw_dev.fw_trace; 112 + u32 thread_nr; 113 + 114 + for (thread_nr = 0; thread_nr < ARRAY_SIZE(fw_trace->buffers); thread_nr++) { 115 + struct pvr_fw_trace_buffer *trace_buffer = &fw_trace->buffers[thread_nr]; 116 + 117 + pvr_fw_object_unmap_and_destroy(trace_buffer->buf_obj); 118 + } 119 + pvr_fw_object_unmap_and_destroy(fw_trace->tracebuf_ctrl_obj); 120 + }
+78
drivers/gpu/drm/imagination/pvr_fw_trace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 + /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 + 4 + #ifndef PVR_FW_TRACE_H 5 + #define PVR_FW_TRACE_H 6 + 7 + #include <drm/drm_file.h> 8 + #include <linux/types.h> 9 + 10 + #include "pvr_rogue_fwif.h" 11 + 12 + /* Forward declaration from pvr_device.h. */ 13 + struct pvr_device; 14 + 15 + /* Forward declaration from pvr_gem.h. */ 16 + struct pvr_fw_object; 17 + 18 + /* Forward declarations from pvr_rogue_fwif.h */ 19 + struct rogue_fwif_tracebuf; 20 + struct rogue_fwif_tracebuf_space; 21 + 22 + /** 23 + * struct pvr_fw_trace_buffer - Structure representing a trace buffer 24 + */ 25 + struct pvr_fw_trace_buffer { 26 + /** @buf_obj: FW buffer object representing trace buffer. */ 27 + struct pvr_fw_object *buf_obj; 28 + 29 + /** @buf: Pointer to CPU mapping of trace buffer. */ 30 + u32 *buf; 31 + 32 + /** 33 + * @tracebuf_space: Pointer to FW tracebuf_space structure for this 34 + * trace buffer. 35 + */ 36 + struct rogue_fwif_tracebuf_space *tracebuf_space; 37 + }; 38 + 39 + /** 40 + * struct pvr_fw_trace - Device firmware trace data 41 + */ 42 + struct pvr_fw_trace { 43 + /** 44 + * @tracebuf_ctrl_obj: Object representing FW trace buffer control 45 + * structure. 46 + */ 47 + struct pvr_fw_object *tracebuf_ctrl_obj; 48 + 49 + /** 50 + * @tracebuf_ctrl: Pointer to CPU mapping of FW trace buffer control 51 + * structure. 52 + */ 53 + struct rogue_fwif_tracebuf *tracebuf_ctrl; 54 + 55 + /** 56 + * @buffers: Array representing the actual trace buffers owned by this 57 + * device. 58 + */ 59 + struct pvr_fw_trace_buffer buffers[ROGUE_FW_THREAD_MAX]; 60 + 61 + /** @group_mask: Mask of enabled trace groups. */ 62 + u32 group_mask; 63 + }; 64 + 65 + int pvr_fw_trace_init(struct pvr_device *pvr_dev); 66 + void pvr_fw_trace_fini(struct pvr_device *pvr_dev); 67 + 68 + #if defined(CONFIG_DEBUG_FS) 69 + /* Forward declaration from <linux/dcache.h>. */ 70 + struct dentry; 71 + 72 + void pvr_fw_trace_mask_update(struct pvr_device *pvr_dev, u32 old_mask, 73 + u32 new_mask); 74 + 75 + void pvr_fw_trace_debugfs_init(struct pvr_device *pvr_dev, struct dentry *dir); 76 + #endif /* defined(CONFIG_DEBUG_FS) */ 77 + 78 + #endif /* PVR_FW_TRACE_H */
+67 -3
drivers/gpu/drm/imagination/pvr_mmu.c
··· 3 3 4 4 #include "pvr_mmu.h" 5 5 6 + #include "pvr_ccb.h" 6 7 #include "pvr_device.h" 7 8 #include "pvr_fw.h" 8 9 #include "pvr_gem.h" 10 + #include "pvr_power.h" 9 11 #include "pvr_rogue_fwif.h" 10 12 #include "pvr_rogue_mmu_defs.h" 11 13 ··· 97 95 */ 98 96 void pvr_mmu_flush_request_all(struct pvr_device *pvr_dev) 99 97 { 100 - /* TODO: implement */ 98 + pvr_mmu_set_flush_flags(pvr_dev, PVR_MMU_SYNC_LEVEL_2_FLAGS); 101 99 } 102 100 103 101 /** ··· 122 120 */ 123 121 int pvr_mmu_flush_exec(struct pvr_device *pvr_dev, bool wait) 124 122 { 125 - /* TODO: implement */ 126 - return -ENODEV; 123 + struct rogue_fwif_kccb_cmd cmd_mmu_cache = {}; 124 + struct rogue_fwif_mmucachedata *cmd_mmu_cache_data = 125 + &cmd_mmu_cache.cmd_data.mmu_cache_data; 126 + int err = 0; 127 + u32 slot; 128 + int idx; 129 + 130 + if (!drm_dev_enter(from_pvr_device(pvr_dev), &idx)) 131 + return -EIO; 132 + 133 + /* Can't flush MMU if the firmware hasn't booted yet. */ 134 + if (!pvr_dev->fw_dev.booted) 135 + goto err_drm_dev_exit; 136 + 137 + cmd_mmu_cache_data->cache_flags = 138 + atomic_xchg(&pvr_dev->mmu_flush_cache_flags, 0); 139 + 140 + if (!cmd_mmu_cache_data->cache_flags) 141 + goto err_drm_dev_exit; 142 + 143 + cmd_mmu_cache.cmd_type = ROGUE_FWIF_KCCB_CMD_MMUCACHE; 144 + 145 + pvr_fw_object_get_fw_addr(pvr_dev->fw_dev.mem.mmucache_sync_obj, 146 + &cmd_mmu_cache_data->mmu_cache_sync_fw_addr); 147 + cmd_mmu_cache_data->mmu_cache_sync_update_value = 0; 148 + 149 + err = pvr_kccb_send_cmd(pvr_dev, &cmd_mmu_cache, &slot); 150 + if (err) 151 + goto err_reset_and_retry; 152 + 153 + err = pvr_kccb_wait_for_completion(pvr_dev, slot, HZ, NULL); 154 + if (err) 155 + goto err_reset_and_retry; 156 + 157 + drm_dev_exit(idx); 158 + 159 + return 0; 160 + 161 + err_reset_and_retry: 162 + /* 163 + * Flush command failure is most likely the result of a firmware lockup. Hard 164 + * reset the GPU and retry. 165 + */ 166 + err = pvr_power_reset(pvr_dev, true); 167 + if (err) 168 + goto err_drm_dev_exit; /* Device is lost. */ 169 + 170 + /* Retry sending flush request. */ 171 + err = pvr_kccb_send_cmd(pvr_dev, &cmd_mmu_cache, &slot); 172 + if (err) { 173 + pvr_device_lost(pvr_dev); 174 + goto err_drm_dev_exit; 175 + } 176 + 177 + if (wait) { 178 + err = pvr_kccb_wait_for_completion(pvr_dev, slot, HZ, NULL); 179 + if (err) 180 + pvr_device_lost(pvr_dev); 181 + } 182 + 183 + err_drm_dev_exit: 184 + drm_dev_exit(idx); 185 + 186 + return err; 127 187 } 128 188 129 189 /**
+150 -16
drivers/gpu/drm/imagination/pvr_power.c
··· 3 3 4 4 #include "pvr_device.h" 5 5 #include "pvr_fw.h" 6 + #include "pvr_fw_startstop.h" 6 7 #include "pvr_power.h" 7 8 #include "pvr_rogue_fwif.h" 8 9 ··· 22 21 23 22 #define WATCHDOG_TIME_MS (500) 24 23 24 + /** 25 + * pvr_device_lost() - Mark GPU device as lost 26 + * @pvr_dev: Target PowerVR device. 27 + * 28 + * This will cause the DRM device to be unplugged. 29 + */ 30 + void 31 + pvr_device_lost(struct pvr_device *pvr_dev) 32 + { 33 + if (!pvr_dev->lost) { 34 + pvr_dev->lost = true; 35 + drm_dev_unplug(from_pvr_device(pvr_dev)); 36 + } 37 + } 38 + 25 39 static int 26 40 pvr_power_send_command(struct pvr_device *pvr_dev, struct rogue_fwif_kccb_cmd *pow_cmd) 27 41 { 28 - /* TODO: implement */ 29 - return -ENODEV; 42 + struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; 43 + u32 slot_nr; 44 + u32 value; 45 + int err; 46 + 47 + WRITE_ONCE(*fw_dev->power_sync, 0); 48 + 49 + err = pvr_kccb_send_cmd_powered(pvr_dev, pow_cmd, &slot_nr); 50 + if (err) 51 + return err; 52 + 53 + /* Wait for FW to acknowledge. */ 54 + return readl_poll_timeout(pvr_dev->fw_dev.power_sync, value, value != 0, 100, 55 + POWER_SYNC_TIMEOUT_US); 30 56 } 31 57 32 58 static int ··· 99 71 return err; 100 72 } 101 73 102 - /* TODO: stop firmware */ 103 - return -ENODEV; 74 + return pvr_fw_stop(pvr_dev); 104 75 } 105 76 106 77 static int ··· 107 80 { 108 81 int err; 109 82 110 - /* TODO: start firmware */ 111 - err = -ENODEV; 83 + err = pvr_fw_start(pvr_dev); 112 84 if (err) 113 85 return err; 86 + 87 + err = pvr_wait_for_fw_boot(pvr_dev); 88 + if (err) { 89 + drm_err(from_pvr_device(pvr_dev), "Firmware failed to boot\n"); 90 + pvr_fw_stop(pvr_dev); 91 + return err; 92 + } 114 93 115 94 queue_delayed_work(pvr_dev->sched_wq, &pvr_dev->watchdog.work, 116 95 msecs_to_jiffies(WATCHDOG_TIME_MS)); ··· 127 94 bool 128 95 pvr_power_is_idle(struct pvr_device *pvr_dev) 129 96 { 130 - /* TODO: implement */ 131 - return true; 97 + /* 98 + * FW power state can be out of date if a KCCB command has been submitted but the FW hasn't 99 + * started processing it yet. So also check the KCCB status. 100 + */ 101 + enum rogue_fwif_pow_state pow_state = READ_ONCE(pvr_dev->fw_dev.fwif_sysdata->pow_state); 102 + bool kccb_idle = pvr_kccb_is_idle(pvr_dev); 103 + 104 + return (pow_state == ROGUE_FWIF_POW_IDLE) && kccb_idle; 132 105 } 133 106 134 107 static bool 135 108 pvr_watchdog_kccb_stalled(struct pvr_device *pvr_dev) 136 109 { 137 - /* TODO: implement */ 110 + /* Check KCCB commands are progressing. */ 111 + u32 kccb_cmds_executed = pvr_dev->fw_dev.fwif_osdata->kccb_cmds_executed; 112 + bool kccb_is_idle = pvr_kccb_is_idle(pvr_dev); 113 + 114 + if (pvr_dev->watchdog.old_kccb_cmds_executed == kccb_cmds_executed && !kccb_is_idle) { 115 + pvr_dev->watchdog.kccb_stall_count++; 116 + 117 + /* 118 + * If we have commands pending with no progress for 2 consecutive polls then 119 + * consider KCCB command processing stalled. 120 + */ 121 + if (pvr_dev->watchdog.kccb_stall_count == 2) { 122 + pvr_dev->watchdog.kccb_stall_count = 0; 123 + return true; 124 + } 125 + } else { 126 + pvr_dev->watchdog.old_kccb_cmds_executed = kccb_cmds_executed; 127 + pvr_dev->watchdog.kccb_stall_count = 0; 128 + } 129 + 138 130 return false; 139 131 } 140 132 ··· 176 118 if (pm_runtime_get_if_in_use(from_pvr_device(pvr_dev)->dev) <= 0) 177 119 goto out_requeue; 178 120 121 + if (!pvr_dev->fw_dev.booted) 122 + goto out_pm_runtime_put; 123 + 179 124 stalled = pvr_watchdog_kccb_stalled(pvr_dev); 180 125 181 126 if (stalled) { ··· 188 127 /* Device may be lost at this point. */ 189 128 } 190 129 130 + out_pm_runtime_put: 191 131 pm_runtime_put(from_pvr_device(pvr_dev)->dev); 192 132 193 133 out_requeue: ··· 220 158 struct platform_device *plat_dev = to_platform_device(dev); 221 159 struct drm_device *drm_dev = platform_get_drvdata(plat_dev); 222 160 struct pvr_device *pvr_dev = to_pvr_device(drm_dev); 161 + int err = 0; 223 162 int idx; 224 163 225 164 if (!drm_dev_enter(drm_dev, &idx)) 226 165 return -EIO; 227 166 167 + if (pvr_dev->fw_dev.booted) { 168 + err = pvr_power_fw_disable(pvr_dev, false); 169 + if (err) 170 + goto err_drm_dev_exit; 171 + } 172 + 228 173 clk_disable_unprepare(pvr_dev->mem_clk); 229 174 clk_disable_unprepare(pvr_dev->sys_clk); 230 175 clk_disable_unprepare(pvr_dev->core_clk); 231 176 177 + err_drm_dev_exit: 232 178 drm_dev_exit(idx); 233 179 234 - return 0; 180 + return err; 235 181 } 236 182 237 183 int ··· 266 196 if (err) 267 197 goto err_sys_clk_disable; 268 198 199 + if (pvr_dev->fw_dev.booted) { 200 + err = pvr_power_fw_enable(pvr_dev); 201 + if (err) 202 + goto err_mem_clk_disable; 203 + } 204 + 269 205 drm_dev_exit(idx); 270 206 271 207 return 0; 208 + 209 + err_mem_clk_disable: 210 + clk_disable_unprepare(pvr_dev->mem_clk); 272 211 273 212 err_sys_clk_disable: 274 213 clk_disable_unprepare(pvr_dev->sys_clk); ··· 318 239 int 319 240 pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset) 320 241 { 321 - /* TODO: Implement hard reset. */ 322 242 int err; 323 243 324 244 /* ··· 326 248 */ 327 249 WARN_ON(pvr_power_get(pvr_dev)); 328 250 329 - err = pvr_power_fw_disable(pvr_dev, false); 330 - if (err) 331 - goto err_power_put; 251 + down_write(&pvr_dev->reset_sem); 332 252 333 - err = pvr_power_fw_enable(pvr_dev); 253 + if (pvr_dev->lost) { 254 + err = -EIO; 255 + goto err_up_write; 256 + } 334 257 335 - err_power_put: 258 + /* Disable IRQs for the duration of the reset. */ 259 + disable_irq(pvr_dev->irq); 260 + 261 + do { 262 + err = pvr_power_fw_disable(pvr_dev, hard_reset); 263 + if (!err) { 264 + if (hard_reset) { 265 + pvr_dev->fw_dev.booted = false; 266 + WARN_ON(pm_runtime_force_suspend(from_pvr_device(pvr_dev)->dev)); 267 + 268 + err = pvr_fw_hard_reset(pvr_dev); 269 + if (err) 270 + goto err_device_lost; 271 + 272 + err = pm_runtime_force_resume(from_pvr_device(pvr_dev)->dev); 273 + pvr_dev->fw_dev.booted = true; 274 + if (err) 275 + goto err_device_lost; 276 + } else { 277 + /* Clear the FW faulted flags. */ 278 + pvr_dev->fw_dev.fwif_sysdata->hwr_state_flags &= 279 + ~(ROGUE_FWIF_HWR_FW_FAULT | 280 + ROGUE_FWIF_HWR_RESTART_REQUESTED); 281 + } 282 + 283 + pvr_fw_irq_clear(pvr_dev); 284 + 285 + err = pvr_power_fw_enable(pvr_dev); 286 + } 287 + 288 + if (err && hard_reset) 289 + goto err_device_lost; 290 + 291 + if (err && !hard_reset) { 292 + drm_err(from_pvr_device(pvr_dev), "FW stalled, trying hard reset"); 293 + hard_reset = true; 294 + } 295 + } while (err); 296 + 297 + enable_irq(pvr_dev->irq); 298 + 299 + up_write(&pvr_dev->reset_sem); 300 + 301 + pvr_power_put(pvr_dev); 302 + 303 + return 0; 304 + 305 + err_device_lost: 306 + drm_err(from_pvr_device(pvr_dev), "GPU device lost"); 307 + pvr_device_lost(pvr_dev); 308 + 309 + /* Leave IRQs disabled if the device is lost. */ 310 + 311 + err_up_write: 312 + up_write(&pvr_dev->reset_sem); 313 + 336 314 pvr_power_put(pvr_dev); 337 315 338 316 return err;
+2
drivers/gpu/drm/imagination/pvr_power.h
··· 12 12 int pvr_watchdog_init(struct pvr_device *pvr_dev); 13 13 void pvr_watchdog_fini(struct pvr_device *pvr_dev); 14 14 15 + void pvr_device_lost(struct pvr_device *pvr_dev); 16 + 15 17 bool pvr_power_is_idle(struct pvr_device *pvr_dev); 16 18 17 19 int pvr_power_device_suspend(struct device *dev);
+21 -5
drivers/gpu/drm/imagination/pvr_vm.c
··· 540 540 .sm_step_unmap = pvr_vm_gpuva_unmap, 541 541 }; 542 542 543 + static void 544 + fw_mem_context_init(void *cpu_ptr, void *priv) 545 + { 546 + struct rogue_fwif_fwmemcontext *fw_mem_ctx = cpu_ptr; 547 + struct pvr_vm_context *vm_ctx = priv; 548 + 549 + fw_mem_ctx->pc_dev_paddr = pvr_vm_get_page_table_root_addr(vm_ctx); 550 + fw_mem_ctx->page_cat_base_reg_set = ROGUE_FW_BIF_INVALID_PCSET; 551 + } 552 + 543 553 /** 544 554 * pvr_vm_create_context() - Create a new VM context. 545 555 * @pvr_dev: Target PowerVR device. ··· 612 602 } 613 603 614 604 if (is_userspace_context) { 615 - /* TODO: Create FW mem context */ 616 - err = -ENODEV; 617 - goto err_put_ctx; 605 + err = pvr_fw_object_create(pvr_dev, sizeof(struct rogue_fwif_fwmemcontext), 606 + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, 607 + fw_mem_context_init, vm_ctx, &vm_ctx->fw_mem_ctx_obj); 608 + 609 + if (err) 610 + goto err_page_table_destroy; 618 611 } 619 612 620 613 return vm_ctx; 614 + 615 + err_page_table_destroy: 616 + pvr_mmu_context_destroy(vm_ctx->mmu_ctx); 621 617 622 618 err_put_ctx: 623 619 pvr_vm_context_put(vm_ctx); ··· 644 628 struct pvr_vm_context *vm_ctx = 645 629 container_of(ref_count, struct pvr_vm_context, ref_count); 646 630 647 - /* TODO: Destroy FW mem context */ 648 - WARN_ON(vm_ctx->fw_mem_ctx_obj); 631 + if (vm_ctx->fw_mem_ctx_obj) 632 + pvr_fw_object_destroy(vm_ctx->fw_mem_ctx_obj); 649 633 650 634 WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start, 651 635 vm_ctx->gpuvm_mgr.mm_range));