int32_t cmdq_rec_finalize_command(cmdqRecHandle handle, bool loop) { int32_t status = 0; uint32_t argB = 0; if (!handle->finalized) { if ((handle->prefetchCount > 0) && cmdq_core_should_enable_prefetch(handle->scenario)) { CMDQ_ERR("not insert prefetch disble marker when prefetch enabled, prefetchCount:%d\n", handle->prefetchCount); cmdqRecDumpCommand(handle); status = -EFAULT; return status; } /* insert EOF instruction */ argB = 0x1; /* generate IRQ for each command iteration */ status = cmdq_append_command(handle, CMDQ_CODE_EOC, 0, argB, 0, 0); if (0 != status) { return status; } /* insert JUMP to loop to beginning or as a scheduling mark(8) */ status = cmdq_append_command(handle, CMDQ_CODE_JUMP, 0, /* not absolute */ loop ? -handle->blockSize : 8, 0, 0); if (0 != status) { return status; } handle->finalized = true; } return status; }
int32_t cmdqRecDisablePrefetch(cmdqRecHandle handle) { uint32_t argB = 0; uint32_t argA = 0; int32_t status = 0; if (!handle->finalized) { if (handle->prefetchCount > 0) { /* with prefetch threads we should end with */ /* bit 48: no_inc_exec_cmds_cnt = 1 */ /* bit 20: prefetch_mark = 1 */ /* bit 17: prefetch_mark_en = 0 */ /* bit 16: prefetch_en = 0 */ argB = 0x00100000; argA = (0x1 << 16); /* not increse execute counter */ /* since we're finalized, no more prefetch */ handle->prefetchCount = 0; status = cmdq_append_command(handle, CMDQ_CODE_EOC, argA, argB, 0, 0); } if (0 != status) { return status; } } CMDQ_MSG("cmdqRecDisablePrefetch, status:%d\n", status); return status; }
int32_t cmdqRecMark(cmdqRecHandle handle) { int32_t status; /* Do not check prefetch-ability here. */ /* because cmdqRecMark may have other purposes. */ /* bit 53: non-suspendable. set to 1 because we don't want */ /* CPU suspend this thread during pre-fetching. */ /* If CPU change PC, then there will be a mess, */ /* because prefetch buffer is not properly cleared. */ /* bit 48: do not increase CMD_COUNTER (because this is not the end of the task) */ /* bit 20: prefetch_marker */ /* bit 17: prefetch_marker_en */ /* bit 16: prefetch_en */ /* bit 0: irq_en (set to 0 since we don't want EOC interrupt) */ status = cmdq_append_command(handle, CMDQ_CODE_EOC, (0x1 << (53 - 32)) | (0x1 << (48 - 32)), 0x00130000, 0, 0); /* if we're in a prefetch region, */ /* this ends the region so set count to 0. */ /* otherwise we start the region by setting count to 1. */ handle->prefetchCount = 1; if (0 != status) { return -EFAULT; } return 0; }
int32_t cmdqRecPoll(cmdqRecHandle handle, uint32_t addr, uint32_t value, uint32_t mask) { int32_t status; status = cmdq_append_command(handle, CMDQ_CODE_MOVE, 0, ~mask, 0, 0); if (0 != status) { return status; } status = cmdq_append_command(handle, CMDQ_CODE_POLL, (addr | 0x1), value, 0, 0); if (0 != status) { return status; } return 0; }
int32_t cmdqRecBackupUpdateSlot(cmdqRecHandle handle, cmdqBackupSlotHandle hBackupSlot, uint32_t slotIndex, uint32_t value) { #ifdef CMDQ_GPR_SUPPORT const CMDQ_DATA_REGISTER_ENUM valueRegId = CMDQ_DATA_REG_DEBUG; const CMDQ_DATA_REGISTER_ENUM destRegId = CMDQ_DATA_REG_DEBUG_DST; const CMDQ_EVENT_ENUM regAccessToken = CMDQ_SYNC_TOKEN_GPR_SET_4; const dma_addr_t dramAddr = hBackupSlot + slotIndex * sizeof(uint32_t); /* lock GPR because we may access it in multiple CMDQ HW threads */ cmdqRecWait(handle, regAccessToken); /* Assign 32-bit GRP with value */ cmdq_append_command( handle, CMDQ_CODE_RAW, (CMDQ_CODE_MOVE << 24) | (valueRegId << 16) | (4 << 21), /* argA is GPR */ value); /* Note that <MOVE> argB is 48-bit */ /* so writeAddress is split into 2 parts */ /* and we store address in 64-bit GPR (P0-P7) */ cmdq_append_command(handle, CMDQ_CODE_MOVE, #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT ((dramAddr >> 32) & 0xffff) | #endif ((destRegId & 0x1f) << 16) | (4 << 21), (uint32_t) dramAddr); /* write value in GPR to memory pointed by GPR */ cmdq_append_command( handle, CMDQ_CODE_RAW, (CMDQ_CODE_WRITE << 24) | (0 & 0xffff) | ((destRegId & 0x1f) << 16) | (6 << 21), valueRegId); /* release the GPR lock */ cmdqRecSetEventToken(handle, regAccessToken); return 0; #else CMDQ_ERR("func:%s failed since CMDQ dosen't support GPR\n", __func__); return -EFAULT; #endif /* CMDQ_GPR_SUPPORT */ }
int32_t cmdqRecWaitNoClear(cmdqRecHandle handle, CMDQ_EVENT_ENUM event) { if (CMDQ_SYNC_TOKEN_INVALID == event || CMDQ_SYNC_TOKEN_MAX <= event || 0 > event) { return -EINVAL; } return cmdq_append_command(handle, CMDQ_CODE_WAIT_NO_CLEAR, event, 0, 0, 0); }
int32_t cmdq_rec_finalize_command(cmdqRecHandle handle, bool loop) { int32_t status = 0; uint32_t argB = 0; if (!handle->finalized) { #if 0 /* we don't generate these instructions now. */ /* FOR disp sys, we should insert CONFIG_DIRTY event */ /* so that trigger loop wakes up */ if (cmdq_core_should_enable_prefetch(handle->scenario)) { cmdq_append_command(handle, CMDQ_CODE_SET_TOKEN, CMDQ_SYNC_TOKEN_CONFIG_DIRTY, 1 /* actually this param is ignored. */ ); } #endif argB = 0x1; /* generate IRQ for each command iteration */ if (handle->prefetchCount > 0) { /* with prefetch threads we should end with */ /* bit 17: prefetch_mark_en = 1 */ /* bit 20: prefetch_mark = 1 */ /* bit 16: prefetch_en = 0 */ argB |= 0x00120000; /* since we're finalized, no more prefetch */ handle->prefetchCount = 0; } status = cmdq_append_command(handle, CMDQ_CODE_EOC, 0, argB); if (0 != status) { return status; } /* insert JUMP to loop to beginning or as a scheduling mark(8) */ status = cmdq_append_command(handle, CMDQ_CODE_JUMP, 0, /* not absolute */ loop ? -handle->blockSize : 8); if (0 != status) { return status; } handle->finalized = true; } return status; }
int32_t cmdqRecSetEventToken(cmdqRecHandle handle, CMDQ_EVENT_ENUM event) { if (CMDQ_SYNC_TOKEN_INVALID == event || CMDQ_SYNC_TOKEN_MAX <= event || 0 > event) { return -EINVAL; } return cmdq_append_command(handle, CMDQ_CODE_SET_TOKEN, event, 1, /* actually this param is ignored. */ 0, 0); }
int32_t cmdqRecWrite(cmdqRecHandle handle, uint32_t addr, uint32_t value, uint32_t mask) { int32_t status; if (0xFFFFFFFF != mask) { status = cmdq_append_command(handle, CMDQ_CODE_MOVE, 0, ~mask, 0, 0); if (0 != status) { return status; } addr = addr | 0x1; } status = cmdq_append_command(handle, CMDQ_CODE_WRITE, addr, value, 0, 0); if (0 != status) { return status; } return 0; }
int32_t cmdqRecReadToDataRegister(cmdqRecHandle handle, uint32_t hwRegAddr, CMDQ_DATA_REGISTER_ENUM dstDataReg) { #ifdef CMDQ_GPR_SUPPORT /* read from hwRegAddr(argA) to dstDataReg(argB) */ return cmdq_append_command(handle, CMDQ_CODE_READ, hwRegAddr, dstDataReg, 0, 1); #else CMDQ_ERR("func:%s failed since CMDQ dosen't support GPR\n", __func__); return -EFAULT; #endif }
int32_t cmdqRecWriteFromDataRegister(cmdqRecHandle handle, CMDQ_DATA_REGISTER_ENUM srcDataReg, uint32_t hwRegAddr) { #ifdef CMDQ_GPR_SUPPORT const uint32_t subsys = cmdq_subsys_from_phys_addr(hwRegAddr); const uint32_t subsysBit = cmdq_core_get_subsys_LSB_in_argA(); /* write HW register(argA) with data of GPR data register(argB)*/ return cmdq_append_command(handle, CMDQ_CODE_WRITE, hwRegAddr, srcDataReg, 0, 1); #else CMDQ_ERR("func:%s failed since CMDQ dosen't support GPR\n", __func__); return -EFAULT; #endif /* CMDQ_GPR_SUPPORT */ }
int32_t cmdqRecBackupWriteRegisterFromSlot(cmdqRecHandle handle, cmdqBackupSlotHandle hBackupSlot, uint32_t slotIndex, uint32_t addr) { #ifdef CMDQ_GPR_SUPPORT const CMDQ_DATA_REGISTER_ENUM valueRegId = CMDQ_DATA_REG_DEBUG; const CMDQ_DATA_REGISTER_ENUM addrRegId = CMDQ_DATA_REG_DEBUG_DST; const CMDQ_EVENT_ENUM regAccessToken = CMDQ_SYNC_TOKEN_GPR_SET_4; const dma_addr_t dramAddr = hBackupSlot + slotIndex * sizeof(uint32_t); /* lock GPR because we may access it in multiple CMDQ HW threads */ cmdqRecWait(handle, regAccessToken); /* 1. MOVE slot address to addr GPR */ /* Note that <MOVE> argB is 48-bit */ /* so writeAddress is split into 2 parts */ /* and we store address in 64-bit GPR (P0-P7) */ cmdq_append_command(handle, CMDQ_CODE_MOVE, #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT ((dramAddr >> 32) & 0xffff) | #endif ((addrRegId & 0x1f) << 16) | (4 << 21), (uint32_t) dramAddr); /* argA is GPR */ /* 2. read value from src address, which is stroed in GPR, to valueRegId */ cmdq_append_command(handle, CMDQ_CODE_RAW, (CMDQ_CODE_READ << 24) | (0 & 0xffff) | ((addrRegId & 0x1f) << 16) | (6 << 21), valueRegId); /* 3. write from data register */ cmdqRecWriteFromDataRegister(handle, valueRegId, addr); /* release the GPR lock */ cmdqRecSetEventToken(handle, regAccessToken); return 0; #else CMDQ_ERR("func:%s failed since CMDQ dosen't support GPR\n", __func__); return -EFAULT; #endif /* CMDQ_GPR_SUPPORT */ }
int32_t cmdqRecClearEventToken(cmdqRecHandle handle, CMDQ_EVENT_ENUM event) { return cmdq_append_command(handle, CMDQ_CODE_CLEAR_TOKEN, event, 1 /* actually this param is ignored. */ ); }
int32_t cmdqRecWaitNoClear(cmdqRecHandle handle, CMDQ_EVENT_ENUM event) { return cmdq_append_command(handle, CMDQ_CODE_WAIT_NO_CLEAR, event, 0); }
int32_t cmdqRecWait(cmdqRecHandle handle, CMDQ_EVENT_ENUM event) { return cmdq_append_command(handle, CMDQ_CODE_WFE, event, 0); }