void lcdif_schedule_continuous_refresh(void *buffer, unsigned w, unsigned h) { logf("refresh %dx%d\n", w, h); lcdif_write_reg(0x36, w - 1); lcdif_write_reg(0x37, 0); lcdif_write_reg(0x38, h - 1); lcdif_write_reg(0x39, 0); lcdif_write_reg(0x20, 0); lcdif_write_reg(0x21, 0); lcdif_write_data(false, 0x22); lcdif_wait_ready(); __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__WORD_LENGTH_BM; __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BM; __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__WORD_LENGTH_16_BIT; __REG_SET(HW_LCDIF_CTRL1) = 0xf << HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BP; g_lcdif_word_length = HW_LCDIF_CTRL__WORD_LENGTH_16_BIT; __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__INPUT_DATA_SWIZZLE_BM; __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__INPUT_DATA_SWIZZLE__NO_SWAP; HW_LCDIF_TRANSFER_COUNT = (h << 16) | w; int rem_size = w * h * 2; for(int i = 0; i < NR_CMDS; i++) { int xfer_size = MIN(rem_size, IMX233_MAX_SINGLE_DMA_XFER_SIZE); lcdif_dma[i].cmd.next = &lcdif_dma[(i + 1) % NR_CMDS].cmd; lcdif_dma[i].cmd.buffer = buffer; lcdif_dma[i].cmd.cmd = HW_APB_CHx_CMD__COMMAND__READ | HW_APB_CHx_CMD__CHAIN | xfer_size << HW_APB_CHx_CMD__XFER_COUNT_BP; logf("rem_size=0x%x xfer_size=0x%x\n", rem_size, xfer_size); logf("cmd[%d][0x%x] nxt=0x%x buf=0x%x cmd=0x%x\n", i, (uint32_t)&lcdif_dma[i].cmd, lcdif_dma[i].cmd.next, lcdif_dma[i].cmd.buffer, lcdif_dma[i].cmd.cmd); rem_size -= xfer_size; buffer += xfer_size; } lcdif_dma[0].cmd.cmd |= 1 << HW_APB_CHx_CMD__CMDWORDS_BP; lcdif_dma[0].ctrl = HW_LCDIF_CTRL__RUN | HW_LCDIF_CTRL__DATA_SELECT; lcdif_dma[NR_CMDS - 1].cmd.cmd |= HW_APB_CHx_CMD__WAIT4ENDCMD; dma_clkgate_channel(APB_LCDIF, true); dma_reset_channel(APB_LCDIF); dma_start_command(APB_LCDIF, &lcdif_dma[0].cmd); }