/* * Copyright 2015-2017 Freescale Semiconductor, Inc. * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include "imxdpuv1_private.h" #include "imxdpuv1_registers.h" #include "imxdpuv1_events.h" #include "imxdpuv1_be.h" #define ptr_to_uint32(__ptr__) ((uint32_t)((uint64_t)(__ptr__))) /* Private data*/ static struct imxdpuv1_soc imxdpuv1_array[IMXDPUV1_MAX_NUM]; typedef struct { uint8_t len; uint8_t buffers; } imxdpuv1_burst_entry_t; static const imxdpuv1_burst_entry_t burst_param[] = { { 0, 0 }, /* IMXDPUV1_SCAN_DIR_UNKNOWN */ { 8, 32 }, /* IMXDPUV1_SCAN_DIR_LEFT_RIGHT_DOWN */ { 16, 16 }, /* IMXDPUV1_SCAN_DIR_HORIZONTAL */ { 8, 32 }, /* IMXDPUV1_SCAN_DIR_VERTICAL possibly 8/32 here */ { 8, 32 }, /* IMXDPUV1_SCAN_DIR_FREE */ }; typedef struct { uint32_t extdst; uint32_t sub; } trigger_entry_t; static const trigger_entry_t trigger_list[IMXDPUV1_SHDLD_IDX_MAX] = { /* IMXDPUV1_SHDLD_* extdst, sub */ /* _DISP0 */{ 1, 0 }, /* _DISP1 */{ 1, 0 }, /* _CONST0 */{ IMXDPUV1_SHDLD_CONSTFRAME0, 0 }, /* _CONST1 */{ IMXDPUV1_SHDLD_CONSTFRAME1, 0 }, /* _CHAN_00 */{ IMXDPUV1_SHDLD_FETCHDECODE2, 0 }, /* _CHAN_01 */{ IMXDPUV1_SHDLD_FETCHDECODE0, 0 }, /* _CHAN_02 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_1 }, /* _CHAN_03 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_2 }, /* _CHAN_04 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_3 }, /* _CHAN_05 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_4 }, /* _CHAN_06 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_5 }, /* _CHAN_07 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_6 }, /* _CHAN_08 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_7 }, /* _CHAN_09 */{ IMXDPUV1_SHDLD_FETCHLAYER0, IMXDPUV1_SUB_8 }, /* _CHAN_10 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_1 << 16 }, /* _CHAN_11 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_2 << 16 }, /* _CHAN_12 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_3 << 16 }, /* _CHAN_13 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_4 << 16 }, /* _CHAN_14 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_5 << 16 }, /* _CHAN_15 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_6 << 16 }, /* _CHAN_16 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_7 << 16 }, /* _CHAN_17 */{ IMXDPUV1_SHDLD_FETCHWARP2, IMXDPUV1_SUB_8 << 16 }, /* _CHAN_18 */{ IMXDPUV1_SHDLD_FETCHDECODE3, 0 }, /* _CHAN_19 */{ IMXDPUV1_SHDLD_FETCHDECODE1, 0 }, /* _CHAN_20 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_1 << 8 }, /* _CHAN_21 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_2 << 8 }, /* _CHAN_22 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_3 << 8 }, /* _CHAN_23 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_4 << 8 }, /* _CHAN_24 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_5 << 8 }, /* _CHAN_25 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_6 << 8 }, /* _CHAN_26 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_7 << 8 }, /* _CHAN_27 */{ IMXDPUV1_SHDLD_FETCHLAYER1, IMXDPUV1_SUB_8 << 8 }, /* _CHAN_28 */{ IMXDPUV1_SHDLD_FETCHECO0, 0 }, /* _CHAN_29 */{ IMXDPUV1_SHDLD_FETCHECO1, 0 }, /* _CHAN_30 */{ IMXDPUV1_SHDLD_FETCHECO2, 0 } }; #ifdef ENABLE_IMXDPUV1_TRACE_REG uint32_t _imxdpuv1_read(struct imxdpuv1_soc *imxdpu, uint32_t offset, char *file, int line) { uint32_t val = 0; val = __raw_readl(imxdpu->base + offset); IMXDPUV1_TRACE_REG("%s:%d R reg 0x%08x --> val 0x%08x\n", file, line, (uint32_t)offset, (uint32_t)val); return val; } void _imxdpuv1_write(struct imxdpuv1_soc *imxdpu, uint32_t offset, uint32_t value, char *file, int line) { __raw_writel(value, imxdpu->base + offset); IMXDPUV1_TRACE_REG("%s:%d W reg 0x%08x <-- val 0x%08x\n", file, line, (uint32_t)offset, (uint32_t)value); } #endif void _imxdpuv1_write_block(struct imxdpuv1_soc *imxdpu, uint32_t offset, void *values, uint32_t cnt, char *file, int line) { int i; uint32_t *dest = (uint32_t *)(imxdpu->base + offset); uint32_t *src = (uint32_t *)values; IMXDPUV1_TRACE_REG("%s:%d W reg 0x%08x <-- cnt 0x%08x\n", file, line, (uint32_t)offset, (uint32_t)cnt); for (i = 0; i < cnt; i++) { dest[i] = src[i]; IMXDPUV1_TRACE_REG("%s:%d WB reg 0x%08x <-- val 0x%08x\n", file, line, (uint32_t) ((uint64_t)(&dest[i])), (uint32_t)(src[i])); } } #ifdef ENABLE_IMXDPUV1_TRACE_IRQ_READ uint32_t _imxdpuv1_read_irq(struct imxdpuv1_soc *imxdpu, uint32_t offset, char *file, int line) { uint32_t val = 0; val = __raw_readl(imxdpu->base + offset); IMXDPUV1_TRACE_IRQ("%s:%d IRQ R reg 0x%08x --> val 0x%08x\n", file, line, (uint32_t)offset, (uint32_t)val); return val; } #endif #ifdef ENABLE_IMXDPUV1_TRACE_IRQ_WRITE void _imxdpuv1_write_irq(struct imxdpuv1_soc *imxdpu, uint32_t offset, uint32_t value, char *file, int line) { __raw_writel(value, imxdpu->base + offset); IMXDPUV1_TRACE_IRQ("%s:%d IRQ W reg 0x%08x <-- val 0x%08x\n", file, line, (uint32_t)offset, (uint32_t)value); } #endif /* static prototypes */ int imxdpuv1_dump_channel(int8_t imxdpuv1_id, imxdpuv1_chan_t chan); static int imxdpuv1_disp_start_shadow_loads(int8_t imxdpuv1_id, int8_t disp); void imxdpuv1_dump_pixencfg_status(int8_t imxdpuv1_id); static bool imxdpuv1_is_yuv(uint32_t fmt); bool imxdpuv1_is_rgb(uint32_t fmt); /*! * Returns IMXDPUV1_TRUE for a valid channel * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int is_chan(imxdpuv1_chan_t chan) { imxdpuv1_chan_idx_t chan_idx = get_channel_idx(chan); if ((chan_idx >= IMXDPUV1_CHAN_IDX_IN_FIRST) && (chan_idx < IMXDPUV1_CHAN_IDX_IN_MAX)) return IMXDPUV1_TRUE; if ((chan_idx >= IMXDPUV1_CHAN_IDX_OUT_FIRST) && (chan_idx < IMXDPUV1_CHAN_IDX_OUT_MAX)) return IMXDPUV1_TRUE; return IMXDPUV1_FALSE; } /*! * Returns IMXDPUV1_TRUE for a valid store channel * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int is_store_chan(imxdpuv1_chan_t chan) { #ifdef IMXDPUV1_VERSION_0 imxdpuv1_id_t blk_id = get_channel_blk(chan); if ((blk_id == IMXDPUV1_ID_STORE4) || (blk_id == IMXDPUV1_ID_STORE4)) return IMXDPUV1_TRUE; #endif return IMXDPUV1_FALSE; } /*! * Returns IMXDPUV1_TRUE for a valid fetch channel * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int is_fetch_eco_chan(imxdpuv1_chan_t chan) { imxdpuv1_id_t blk_id = get_channel_blk(chan); if ((blk_id == IMXDPUV1_ID_FETCHECO0) || (blk_id == IMXDPUV1_ID_FETCHECO1) || (blk_id == IMXDPUV1_ID_FETCHECO2)) return IMXDPUV1_TRUE; return IMXDPUV1_FALSE; } /*! * Returns IMXDPUV1_TRUE for a valid fetch decode channel * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int is_fetch_decode_chan(imxdpuv1_chan_t chan) { imxdpuv1_id_t blk_id = get_channel_blk(chan); if ((blk_id == IMXDPUV1_ID_FETCHDECODE0) || (blk_id == IMXDPUV1_ID_FETCHDECODE1) #ifdef IMXDPUV1_VERSION_0 || (blk_id == IMXDPUV1_ID_FETCHDECODE2) || (blk_id == IMXDPUV1_ID_FETCHDECODE3) #endif ) return IMXDPUV1_TRUE; return IMXDPUV1_FALSE; } /*! * Returns IMXDPUV1_TRUE if a fetch channel has an eco fetch * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int has_fetch_eco_chan(imxdpuv1_chan_t chan) { imxdpuv1_id_t blk_id = get_channel_blk(chan); if ((blk_id == IMXDPUV1_ID_FETCHDECODE0) || (blk_id == IMXDPUV1_ID_FETCHDECODE1) || (blk_id == IMXDPUV1_ID_FETCHWARP2)) return IMXDPUV1_TRUE; return IMXDPUV1_FALSE; } /*! * Returns IMXDPUV1_TRUE for a valid fetch warp channel * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int is_fetch_warp_chan(imxdpuv1_chan_t chan) { imxdpuv1_id_t blk_id = get_channel_blk(chan); if ((blk_id == IMXDPUV1_ID_FETCHWARP2)) return IMXDPUV1_TRUE; return IMXDPUV1_FALSE; } /*! * Returns IMXDPUV1_TRUE for a valid fetch layer channel * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int is_fetch_layer_chan(imxdpuv1_chan_t chan) { imxdpuv1_id_t blk_id = get_channel_blk(chan); if ((blk_id == IMXDPUV1_ID_FETCHLAYER0) #ifdef IMXDPUV1_VERSION_0 || (blk_id == IMXDPUV1_ID_FETCHLAYER1) #endif ) return IMXDPUV1_TRUE; return IMXDPUV1_FALSE; } /*! * Returns IMXDPUV1_TRUE for a valid layer sub1 channel * * @param channel to test * * @return This function returns IMXDPUV1_TRUE on success or * IMXDPUV1_FALSE if the test fails. */ static int is_fetch_layer_sub_chan1(imxdpuv1_chan_t chan) { imxdpuv1_id_t blk_id = get_channel_blk(chan); if ((blk_id == IMXDPUV1_ID_FETCHLAYER0) || #ifdef IMXDPUV1_VERSION_0 (blk_id == IMXDPUV1_ID_FETCHLAYER1) || #endif (blk_id == IMXDPUV1_ID_FETCHWARP2)) if (get_channel_sub(chan) == IMXDPUV1_SUB_1) return IMXDPUV1_TRUE; return IMXDPUV1_FALSE; } /*! * Returns subindex of a channel * * @param channel * * @return returns the subindex of a channel */ static int imxdpuv1_get_channel_subindex(imxdpuv1_chan_t chan) { switch (get_channel_sub(chan)) { case IMXDPUV1_SUB_2: return 1; case IMXDPUV1_SUB_3: return 2; case IMXDPUV1_SUB_4: return 3; case IMXDPUV1_SUB_5: return 4; case IMXDPUV1_SUB_6: return 5; case IMXDPUV1_SUB_7: return 6; case IMXDPUV1_SUB_8: return 7; case IMXDPUV1_SUB_1: case IMXDPUV1_SUBWINDOW_NONE: default: return 0; } } /*! * Returns returns the eco channel for a channel index * * @param chan * * @return returns number of bits per pixel or zero * if the format is not matched. */ imxdpuv1_chan_t imxdpuv1_get_eco(imxdpuv1_chan_t chan) { switch (get_eco_idx(chan)) { case get_channel_idx(IMXDPUV1_CHAN_28): return IMXDPUV1_CHAN_28; case get_channel_idx(IMXDPUV1_CHAN_29): return IMXDPUV1_CHAN_29; case get_channel_idx(IMXDPUV1_CHAN_30): return IMXDPUV1_CHAN_30; default: return 0; } } /*! * Returns the start address offset for a given block ID * * @param block id * * @return This function returns the address offset if the block id * matches a valid block. Otherwise, IMXDPUV1_OFFSET_INVALID * is returned. */ uint32_t id2blockoffset(imxdpuv1_id_t block_id) { switch (block_id) { /*case IMXDPUV1_ID_NONE: return IMXDPUV1_NONE_LOCKUNLOCK; */ case IMXDPUV1_ID_FETCHDECODE9: return IMXDPUV1_FETCHDECODE9_LOCKUNLOCK; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_FETCHPERSP9: return IMXDPUV1_FETCHPERSP9_LOCKUNLOCK; #else case IMXDPUV1_ID_FETCHWARP9: return IMXDPUV1_FETCHWARP9_LOCKUNLOCK; #endif case IMXDPUV1_ID_FETCHECO9: return IMXDPUV1_FETCHECO9_LOCKUNLOCK; case IMXDPUV1_ID_ROP9: return IMXDPUV1_ROP9_LOCKUNLOCK; case IMXDPUV1_ID_CLUT9: return IMXDPUV1_CLUT9_LOCKUNLOCK; case IMXDPUV1_ID_MATRIX9: return IMXDPUV1_MATRIX9_LOCKUNLOCK; case IMXDPUV1_ID_HSCALER9: return IMXDPUV1_HSCALER9_LOCKUNLOCK; case IMXDPUV1_ID_VSCALER9: return IMXDPUV1_VSCALER9_LOCKUNLOCK; case IMXDPUV1_ID_FILTER9: return IMXDPUV1_FILTER9_LOCKUNLOCK; case IMXDPUV1_ID_BLITBLEND9: return IMXDPUV1_BLITBLEND9_LOCKUNLOCK; case IMXDPUV1_ID_STORE9: return IMXDPUV1_STORE9_LOCKUNLOCK; case IMXDPUV1_ID_CONSTFRAME0: return IMXDPUV1_CONSTFRAME0_LOCKUNLOCK; case IMXDPUV1_ID_EXTDST0: return IMXDPUV1_EXTDST0_LOCKUNLOCK; case IMXDPUV1_ID_CONSTFRAME4: return IMXDPUV1_CONSTFRAME4_LOCKUNLOCK; case IMXDPUV1_ID_EXTDST4: return IMXDPUV1_EXTDST4_LOCKUNLOCK; case IMXDPUV1_ID_CONSTFRAME1: return IMXDPUV1_CONSTFRAME1_LOCKUNLOCK; case IMXDPUV1_ID_EXTDST1: return IMXDPUV1_EXTDST1_LOCKUNLOCK; case IMXDPUV1_ID_CONSTFRAME5: return IMXDPUV1_CONSTFRAME5_LOCKUNLOCK; case IMXDPUV1_ID_EXTDST5: return IMXDPUV1_EXTDST5_LOCKUNLOCK; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_EXTSRC4: return IMXDPUV1_EXTSRC4_LOCKUNLOCK; case IMXDPUV1_ID_STORE4: return IMXDPUV1_STORE4_LOCKUNLOCK; case IMXDPUV1_ID_EXTSRC5: return IMXDPUV1_EXTSRC5_LOCKUNLOCK; case IMXDPUV1_ID_STORE5: return IMXDPUV1_STORE5_LOCKUNLOCK; case IMXDPUV1_ID_FETCHDECODE2: return IMXDPUV1_FETCHDECODE2_LOCKUNLOCK; case IMXDPUV1_ID_FETCHDECODE3: return IMXDPUV1_FETCHDECODE3_LOCKUNLOCK; #endif case IMXDPUV1_ID_FETCHWARP2: return IMXDPUV1_FETCHWARP2_LOCKUNLOCK; case IMXDPUV1_ID_FETCHECO2: return IMXDPUV1_FETCHECO2_LOCKUNLOCK; case IMXDPUV1_ID_FETCHDECODE0: return IMXDPUV1_FETCHDECODE0_LOCKUNLOCK; case IMXDPUV1_ID_FETCHECO0: return IMXDPUV1_FETCHECO0_LOCKUNLOCK; case IMXDPUV1_ID_FETCHDECODE1: return IMXDPUV1_FETCHDECODE1_LOCKUNLOCK; case IMXDPUV1_ID_FETCHECO1: return IMXDPUV1_FETCHECO1_LOCKUNLOCK; case IMXDPUV1_ID_FETCHLAYER0: return IMXDPUV1_FETCHLAYER0_LOCKUNLOCK; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_FETCHLAYER1: return IMXDPUV1_FETCHLAYER1_LOCKUNLOCK; case IMXDPUV1_ID_GAMMACOR4: return IMXDPUV1_GAMMACOR4_LOCKUNLOCK; #endif case IMXDPUV1_ID_MATRIX4: return IMXDPUV1_MATRIX4_LOCKUNLOCK; case IMXDPUV1_ID_HSCALER4: return IMXDPUV1_HSCALER4_LOCKUNLOCK; case IMXDPUV1_ID_VSCALER4: return IMXDPUV1_VSCALER4_LOCKUNLOCK; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_HISTOGRAM4: return IMXDPUV1_HISTOGRAM4_CONTROL; case IMXDPUV1_ID_GAMMACOR5: return IMXDPUV1_GAMMACOR5_LOCKUNLOCK; #endif case IMXDPUV1_ID_MATRIX5: return IMXDPUV1_MATRIX5_LOCKUNLOCK; case IMXDPUV1_ID_HSCALER5: return IMXDPUV1_HSCALER5_LOCKUNLOCK; case IMXDPUV1_ID_VSCALER5: return IMXDPUV1_VSCALER5_LOCKUNLOCK; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_HISTOGRAM5: return IMXDPUV1_HISTOGRAM5_CONTROL; #endif case IMXDPUV1_ID_LAYERBLEND0: return IMXDPUV1_LAYERBLEND0_LOCKUNLOCK; case IMXDPUV1_ID_LAYERBLEND1: return IMXDPUV1_LAYERBLEND1_LOCKUNLOCK; case IMXDPUV1_ID_LAYERBLEND2: return IMXDPUV1_LAYERBLEND2_LOCKUNLOCK; case IMXDPUV1_ID_LAYERBLEND3: return IMXDPUV1_LAYERBLEND3_LOCKUNLOCK; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_LAYERBLEND4: return IMXDPUV1_LAYERBLEND4_LOCKUNLOCK; case IMXDPUV1_ID_LAYERBLEND5: return IMXDPUV1_LAYERBLEND5_LOCKUNLOCK; case IMXDPUV1_ID_LAYERBLEND6: return IMXDPUV1_LAYERBLEND6_LOCKUNLOCK; case IMXDPUV1_ID_EXTSRC0: return IMXDPUV1_EXTSRC0_LOCKUNLOCK; case IMXDPUV1_ID_EXTSRC1: return IMXDPUV1_EXTSRC1_LOCKUNLOCK; #endif case IMXDPUV1_ID_DISENGCFG: return IMXDPUV1_DISENGCFG_LOCKUNLOCK0; case IMXDPUV1_ID_FRAMEGEN0: return IMXDPUV1_FRAMEGEN0_LOCKUNLOCK; case IMXDPUV1_ID_MATRIX0: return IMXDPUV1_MATRIX0_LOCKUNLOCK; case IMXDPUV1_ID_GAMMACOR0: return IMXDPUV1_GAMMACOR0_LOCKUNLOCK; case IMXDPUV1_ID_DITHER0: return IMXDPUV1_DITHER0_LOCKUNLOCK; case IMXDPUV1_ID_TCON0: return IMXDPUV1_TCON0_LOCKUNLOCK; case IMXDPUV1_ID_SIG0: return IMXDPUV1_SIG0_LOCKUNLOCK; case IMXDPUV1_ID_FRAMEGEN1: return IMXDPUV1_FRAMEGEN1_LOCKUNLOCK; case IMXDPUV1_ID_MATRIX1: return IMXDPUV1_MATRIX1_LOCKUNLOCK; case IMXDPUV1_ID_GAMMACOR1: return IMXDPUV1_GAMMACOR1_LOCKUNLOCK; case IMXDPUV1_ID_DITHER1: return IMXDPUV1_DITHER1_LOCKUNLOCK; case IMXDPUV1_ID_TCON1: return IMXDPUV1_TCON1_LOCKUNLOCK; case IMXDPUV1_ID_SIG1: return IMXDPUV1_SIG1_LOCKUNLOCK; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_FRAMECAP4: return IMXDPUV1_FRAMECAP4_LOCKUNLOCK; case IMXDPUV1_ID_FRAMECAP5: return IMXDPUV1_FRAMECAP5_LOCKUNLOCK; #endif default: return IMXDPUV1_OFFSET_INVALID; } } /*! * Returns the start address offset for the dynamic configuraiton for * a given block ID * * @param block id * * @return This function returns the address offset if the block id * matches a valid block. Otherwise, IMXDPUV1_OFFSET_INVALID * is returned. */ uint32_t id2dynamicoffset(imxdpuv1_id_t block_id) { switch (block_id) { case IMXDPUV1_ID_FETCHDECODE9: return IMXDPUV1_PIXENGCFG_FETCHDECODE9_DYNAMIC; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_FETCHPERSP9: return IMXDPUV1_PIXENGCFG_FETCHPERSP9_DYNAMIC; #else case IMXDPUV1_ID_FETCHWARP9: return IMXDPUV1_PIXENGCFG_FETCHWARP9_DYNAMIC; #endif case IMXDPUV1_ID_ROP9: return IMXDPUV1_PIXENGCFG_ROP9_DYNAMIC; case IMXDPUV1_ID_CLUT9: return IMXDPUV1_PIXENGCFG_CLUT9_DYNAMIC; case IMXDPUV1_ID_MATRIX9: return IMXDPUV1_PIXENGCFG_MATRIX9_DYNAMIC; case IMXDPUV1_ID_HSCALER9: return IMXDPUV1_PIXENGCFG_HSCALER9_DYNAMIC; case IMXDPUV1_ID_VSCALER9: return IMXDPUV1_PIXENGCFG_VSCALER9_DYNAMIC; case IMXDPUV1_ID_FILTER9: return IMXDPUV1_PIXENGCFG_FILTER9_DYNAMIC; case IMXDPUV1_ID_BLITBLEND9: return IMXDPUV1_PIXENGCFG_BLITBLEND9_DYNAMIC; case IMXDPUV1_ID_STORE9: return IMXDPUV1_PIXENGCFG_STORE9_DYNAMIC; case IMXDPUV1_ID_EXTDST0: return IMXDPUV1_PIXENGCFG_EXTDST0_DYNAMIC; case IMXDPUV1_ID_EXTDST4: return IMXDPUV1_PIXENGCFG_EXTDST4_DYNAMIC; case IMXDPUV1_ID_EXTDST1: return IMXDPUV1_PIXENGCFG_EXTDST1_DYNAMIC; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_EXTDST5: return IMXDPUV1_PIXENGCFG_EXTDST5_DYNAMIC; case IMXDPUV1_ID_STORE4: return IMXDPUV1_PIXENGCFG_STORE4_DYNAMIC; case IMXDPUV1_ID_STORE5: return IMXDPUV1_PIXENGCFG_STORE5_DYNAMIC; case IMXDPUV1_ID_FETCHDECODE2: return IMXDPUV1_PIXENGCFG_FETCHDECODE2_DYNAMIC; case IMXDPUV1_ID_FETCHDECODE3: return IMXDPUV1_PIXENGCFG_FETCHDECODE3_DYNAMIC; #endif case IMXDPUV1_ID_FETCHWARP2: return IMXDPUV1_PIXENGCFG_FETCHWARP2_DYNAMIC; case IMXDPUV1_ID_FETCHDECODE0: return IMXDPUV1_PIXENGCFG_FETCHDECODE0_DYNAMIC; case IMXDPUV1_ID_FETCHDECODE1: return IMXDPUV1_PIXENGCFG_FETCHDECODE1_DYNAMIC; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_GAMMACOR4: return IMXDPUV1_PIXENGCFG_GAMMACOR4_DYNAMIC; #endif case IMXDPUV1_ID_MATRIX4: return IMXDPUV1_PIXENGCFG_MATRIX4_DYNAMIC; case IMXDPUV1_ID_HSCALER4: return IMXDPUV1_PIXENGCFG_HSCALER4_DYNAMIC; case IMXDPUV1_ID_VSCALER4: return IMXDPUV1_PIXENGCFG_VSCALER4_DYNAMIC; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_HISTOGRAM4: return IMXDPUV1_PIXENGCFG_HISTOGRAM4_DYNAMIC; case IMXDPUV1_ID_GAMMACOR5: return IMXDPUV1_PIXENGCFG_GAMMACOR5_DYNAMIC; #endif case IMXDPUV1_ID_MATRIX5: return IMXDPUV1_PIXENGCFG_MATRIX5_DYNAMIC; case IMXDPUV1_ID_HSCALER5: return IMXDPUV1_PIXENGCFG_HSCALER5_DYNAMIC; case IMXDPUV1_ID_VSCALER5: return IMXDPUV1_PIXENGCFG_VSCALER5_DYNAMIC; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_HISTOGRAM5: return IMXDPUV1_PIXENGCFG_HISTOGRAM5_DYNAMIC; #endif case IMXDPUV1_ID_LAYERBLEND0: return IMXDPUV1_PIXENGCFG_LAYERBLEND0_DYNAMIC; case IMXDPUV1_ID_LAYERBLEND1: return IMXDPUV1_PIXENGCFG_LAYERBLEND1_DYNAMIC; case IMXDPUV1_ID_LAYERBLEND2: return IMXDPUV1_PIXENGCFG_LAYERBLEND2_DYNAMIC; case IMXDPUV1_ID_LAYERBLEND3: return IMXDPUV1_PIXENGCFG_LAYERBLEND3_DYNAMIC; #ifdef IMXDPUV1_VERSION_0 case IMXDPUV1_ID_LAYERBLEND4: return IMXDPUV1_PIXENGCFG_LAYERBLEND4_DYNAMIC; case IMXDPUV1_ID_LAYERBLEND5: return IMXDPUV1_PIXENGCFG_LAYERBLEND5_DYNAMIC; case IMXDPUV1_ID_LAYERBLEND6: return IMXDPUV1_PIXENGCFG_LAYERBLEND6_DYNAMIC; #endif default: return IMXDPUV1_OFFSET_INVALID; } } /*! * Returns the start address offset for a given shadow index * * @param block id * * @return This function returns the address offset if the shadow * index matches a valid block. Otherwise, IMXDPUV1_OFFSET_INVALID * is returned. */ imxdpuv1_chan_t shadowindex2channel(imxdpuv1_shadow_load_index_t shadow_index) { switch (shadow_index) { case IMXDPUV1_SHDLD_IDX_CHAN_00: return IMXDPUV1_CHAN_00; case IMXDPUV1_SHDLD_IDX_CHAN_01: return IMXDPUV1_CHAN_01; case IMXDPUV1_SHDLD_IDX_CHAN_02: return IMXDPUV1_CHAN_02; case IMXDPUV1_SHDLD_IDX_CHAN_03: return IMXDPUV1_CHAN_03; case IMXDPUV1_SHDLD_IDX_CHAN_04: return IMXDPUV1_CHAN_04; case IMXDPUV1_SHDLD_IDX_CHAN_05: return IMXDPUV1_CHAN_05; case IMXDPUV1_SHDLD_IDX_CHAN_06: return IMXDPUV1_CHAN_06; case IMXDPUV1_SHDLD_IDX_CHAN_07: return IMXDPUV1_CHAN_07; case IMXDPUV1_SHDLD_IDX_CHAN_08: return IMXDPUV1_CHAN_08; case IMXDPUV1_SHDLD_IDX_CHAN_09: return IMXDPUV1_CHAN_09; case IMXDPUV1_SHDLD_IDX_CHAN_10: return IMXDPUV1_CHAN_10; case IMXDPUV1_SHDLD_IDX_CHAN_11: return IMXDPUV1_CHAN_11; case IMXDPUV1_SHDLD_IDX_CHAN_12: return IMXDPUV1_CHAN_12; case IMXDPUV1_SHDLD_IDX_CHAN_13: return IMXDPUV1_CHAN_13; case IMXDPUV1_SHDLD_IDX_CHAN_14: return IMXDPUV1_CHAN_14; case IMXDPUV1_SHDLD_IDX_CHAN_15: return IMXDPUV1_CHAN_15; case IMXDPUV1_SHDLD_IDX_CHAN_16: return IMXDPUV1_CHAN_16; case IMXDPUV1_SHDLD_IDX_CHAN_17: return IMXDPUV1_CHAN_17; case IMXDPUV1_SHDLD_IDX_CHAN_18: return IMXDPUV1_CHAN_18; case IMXDPUV1_SHDLD_IDX_CHAN_19: return IMXDPUV1_CHAN_19; case IMXDPUV1_SHDLD_IDX_CHAN_20: return IMXDPUV1_CHAN_20; case IMXDPUV1_SHDLD_IDX_CHAN_21: return IMXDPUV1_CHAN_21; case IMXDPUV1_SHDLD_IDX_CHAN_22: return IMXDPUV1_CHAN_22; case IMXDPUV1_SHDLD_IDX_CHAN_23: return IMXDPUV1_CHAN_23; case IMXDPUV1_SHDLD_IDX_CHAN_24: return IMXDPUV1_CHAN_24; case IMXDPUV1_SHDLD_IDX_CHAN_25: return IMXDPUV1_CHAN_25; case IMXDPUV1_SHDLD_IDX_CHAN_26: return IMXDPUV1_CHAN_26; case IMXDPUV1_SHDLD_IDX_CHAN_27: return IMXDPUV1_CHAN_27; case IMXDPUV1_SHDLD_IDX_CHAN_28: return IMXDPUV1_CHAN_28; case IMXDPUV1_SHDLD_IDX_CHAN_29: return IMXDPUV1_CHAN_29; case IMXDPUV1_SHDLD_IDX_CHAN_30: return IMXDPUV1_CHAN_30; default: return IMXDPUV1_CHANNEL_INVALID; } } /*! * This function returns the pointer to the imxdpu structutre * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * * @return This function returns the pointer to the imxdpu structutre * return a NULL pointer for a failure. */ struct imxdpuv1_soc *imxdpuv1_get_soc(int8_t imxdpuv1_id) { /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return NULL; } return &(imxdpuv1_array[imxdpuv1_id]); } /*! * This function enables the interrupt for the specified interrupt line. * The interrupt lines are defined in imxdpuv1_events.h. * * @param imxdpu imxdpu instance * @param irq Interrupt line to enable interrupt for. * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_enable_irq(int8_t imxdpuv1_id, uint32_t irq) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); #ifdef DEBUG_IMXDPUV1_IRQ_ERROR if (irq == 0) panic("Trying to enable irq 0!"); #endif /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpuv1_clear_irq(imxdpuv1_id, irq); if (irq < IMXDPUV1_INTERRUPT_MAX) { if (irq < 32) { imxdpu->enabled_int[0] |= INTSTAT0_BIT(irq); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE0, imxdpu->enabled_int[0]); } else if (irq < 64) { imxdpu->enabled_int[1] |= INTSTAT1_BIT(irq); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE1, imxdpu->enabled_int[1]); #ifdef IMXDPUV1_VERSION_0 } else { imxdpu->enabled_int[2] |= INTSTAT2_BIT(irq); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE2, imxdpu->enabled_int[2]); #endif } } else { return -EINVAL; } return ret; } /*! * This function disables the interrupt for the specified interrupt line.g * The interrupt lines are defined in imxdpuv1_events.h. * * @param imxdpu imxdpu instance * @param irq Interrupt line to disable interrupt for. * */ int imxdpuv1_disable_irq(int8_t imxdpuv1_id, uint32_t irq) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (irq < IMXDPUV1_INTERRUPT_MAX) { if (irq < 32) { imxdpu->enabled_int[0] &= ~INTSTAT0_BIT(irq); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE0, imxdpu->enabled_int[0]); } else if (irq < 64) { imxdpu->enabled_int[1] &= ~INTSTAT1_BIT(irq); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE1, imxdpu->enabled_int[1]); #ifdef IMXDPUV1_VERSION_0 } else { imxdpu->enabled_int[2] &= ~INTSTAT2_BIT(irq); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE2, imxdpu->enabled_int[2]); #endif } } else { return -EINVAL; } return ret; } /*! * This function clears all interrupts. * * @param imxdpu imxdpu instance * */ int imxdpuv1_clear_all_irqs(int8_t imxdpuv1_id) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR0, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR0_USERINTERRUPTCLEAR0_MASK); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR1, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR1_USERINTERRUPTCLEAR1_MASK); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR2, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR2_USERINTERRUPTCLEAR2_MASK); #endif #if 1 imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTCLEAR0, IMXDPUV1_COMCTRL_INTERRUPTCLEAR0_INTERRUPTCLEAR0_MASK); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTCLEAR1, IMXDPUV1_COMCTRL_INTERRUPTCLEAR1_INTERRUPTCLEAR1_MASK); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTCLEAR2, IMXDPUV1_COMCTRL_INTERRUPTCLEAR2_INTERRUPTCLEAR2_MASK); #endif #endif return ret; } /*! * This function disables all interrupts. * * @param imxdpu imxdpu instance * */ int imxdpuv1_disable_all_irqs(int8_t imxdpuv1_id) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE0, 0); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE1, 0); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE2, 0); #endif #if 1 imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTENABLE0, 0); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTENABLE1, 0); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTENABLE2, 0); #endif #endif imxdpu->enabled_int[0] = 0; imxdpu->enabled_int[1] = 0; #ifdef IMXDPUV1_VERSION_0 imxdpu->enabled_int[2] = 0; #endif return ret; } /*! * This function clears the interrupt for the specified interrupt line. * The interrupt lines are defined in ipu_irq_line enum. * * @param imxdpu imxdpu instance * @param irq Interrupt line to clear interrupt for. * */ int imxdpuv1_clear_irq(int8_t imxdpuv1_id, uint32_t irq) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (irq < IMXDPUV1_INTERRUPT_MAX) { if (irq < 32) { imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR0, 1U << irq); } if (irq < 64) { imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR1, 1U << (irq - 32)); #ifdef IMXDPUV1_VERSION_0 } else { imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR2, 1U << (irq - 64)); #endif } } else { return -EINVAL; } return ret; } /*! * This function initializes the imxdpu interrupts * * @param imxdpu imxdpu instance * */ int imxdpuv1_init_irqs(int8_t imxdpuv1_id) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpuv1_disable_all_irqs(imxdpuv1_id); imxdpuv1_clear_all_irqs(imxdpuv1_id); /* Set all irq to user mode */ imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTMASK0, IMXDPUV1_COMCTRL_USERINTERRUPTMASK0_USERINTERRUPTMASK0_MASK); imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTMASK1, IMXDPUV1_COMCTRL_USERINTERRUPTMASK1_USERINTERRUPTMASK1_MASK); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTMASK2, IMXDPUV1_COMCTRL_USERINTERRUPTMASK2_USERINTERRUPTMASK2_MASK); #endif /* enable needed interupts */ imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_EXTDST0_SHDLOAD_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_EXTDST1_SHDLOAD_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_EXTDST0_FRAMECOMPLETE_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_EXTDST1_FRAMECOMPLETE_IRQ); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_STORE4_SHDLOAD_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_STORE5_SHDLOAD_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_STORE4_SEQCOMPLETE_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_STORE5_SEQCOMPLETE_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_STORE4_FRAMECOMPLETE_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_STORE5_FRAMECOMPLETE_IRQ); #endif /* enable the frame interrupts as IMXDPUV1_IRQF_ONESHOT */ imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_FRAMEGEN0_INT0_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_FRAMEGEN1_INT0_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW0_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW1_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_DISENGCFG_SHDLOAD0_IRQ); imxdpuv1_enable_irq(imxdpuv1_id, IMXDPUV1_DISENGCFG_SHDLOAD1_IRQ); IMXDPUV1_TRACE("%s() enabled_int[0] 0x%08x\n", __func__, imxdpu->enabled_int[0]); IMXDPUV1_TRACE("%s() enabled_int[1] 0x%08x\n", __func__, imxdpu->enabled_int[1]); #ifdef IMXDPUV1_VERSION_0 IMXDPUV1_TRACE("%s() enabled_int[2] 0x%08x\n", __func__, imxdpu->enabled_int[2]); #endif return ret; } /*! * This function checks pending shadow loads * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_check_shadow_loads(int8_t imxdpuv1_id, int8_t disp) { int ret = 0; uint32_t addr_extdst = IMXDPUV1_OFFSET_INVALID; /* address for extdst */ uint32_t extdst = 0; uint32_t extdst_stat = 0; uint32_t fgen = 1; uint32_t fgen_stat = 0; uint32_t sub = 0; uint32_t sub_stat = 0; uint32_t stat; int32_t i; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; stat = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTSTATUS0); if (disp == 0) { addr_extdst = IMXDPUV1_PIXENGCFG_EXTDST0_REQUEST; if (stat & IMXDPUV1_DISENGCFG_SHDLOAD0_IRQ) { fgen = 0; } } else if (disp == 1) { addr_extdst = IMXDPUV1_PIXENGCFG_EXTDST1_REQUEST; if (stat & IMXDPUV1_DISENGCFG_SHDLOAD1_IRQ) { fgen = 0; } } else { return -EINVAL; } sub |= (imxdpuv1_read(imxdpu, IMXDPUV1_FETCHLAYER0_TRIGGERENABLE)) & 0xff; #ifdef IMXDPUV1_VERSION_0 sub |= (imxdpuv1_read(imxdpu, IMXDPUV1_FETCHLAYER1_TRIGGERENABLE) << 8) & 0xff00; #endif sub |= (imxdpuv1_read(imxdpu, IMXDPUV1_FETCHWARP2_TRIGGERENABLE) << 16) & 0xff0000; extdst = imxdpuv1_read(imxdpu, addr_extdst); /* this loop may need to be optimized */ for (i = 0; i < IMXDPUV1_SHDLD_IDX_CHAN_00; i++) { if (imxdpu->shadow_load_state[disp][i].state.complete) { if (imxdpu->shadow_load_state[disp][i].state.trys > 0) { IMXDPUV1_TRACE_IRQ ("shadow index complete after retry: index %d trys %d\n", i, imxdpu->shadow_load_state[disp][i]. state.trys); } else { IMXDPUV1_TRACE_IRQ("shadow index complete: index %d\n", i); } imxdpu->shadow_load_state[disp][i].word = 0; } else if (imxdpu->shadow_load_state[disp][i].state.processing) { if (i > IMXDPUV1_SHDLD_IDX_CONST1) { if (!(extdst & trigger_list[i].extdst) && !fgen) { imxdpu->shadow_load_state[disp][i]. state.complete = 1; } else { extdst_stat |= trigger_list[i].extdst; fgen_stat |= 1 << i; } } else if (!(extdst & trigger_list[i].extdst)) { imxdpu->shadow_load_state[disp][i]. state.complete = 1; } else { imxdpu->shadow_load_state[disp][i].state.trys++; extdst |= trigger_list[i].extdst; IMXDPUV1_TRACE_IRQ ("shadow index retry: index %d trys %d\n", i, imxdpu->shadow_load_state[disp][i]. state.trys); } } } for (i = IMXDPUV1_SHDLD_IDX_CHAN_00; i < IMXDPUV1_SHDLD_IDX_MAX; i++) { if (imxdpu->shadow_load_state[disp][i].state.complete) { if (imxdpu->shadow_load_state[disp][i].state.trys > 0) { IMXDPUV1_TRACE_IRQ ("shadow index complete after retry: index %d trys %d\n", i, imxdpu->shadow_load_state[disp][i]. state.trys); } else { IMXDPUV1_TRACE_IRQ("shadow index complete: index %d\n", i); } imxdpu->shadow_load_state[disp][i].word = 0; } else if (imxdpu->shadow_load_state[disp][i].state.processing) { /* fetch layer and fetchwarp */ if ((trigger_list[i].extdst != 0) && (trigger_list[i].sub != 0)) { if (!(extdst & trigger_list[i].extdst) && !(sub & trigger_list[i].sub)) { imxdpu->shadow_load_state[disp][i]. state.complete = 1; } else { extdst_stat |= trigger_list[i].extdst; sub_stat |= trigger_list[i].sub; } } else if (!(extdst & trigger_list[i].extdst)) { imxdpu->shadow_load_state[disp][i]. state.complete = 1; } else { imxdpu->shadow_load_state[disp][i].state.trys++; extdst_stat |= trigger_list[i].extdst; IMXDPUV1_TRACE_IRQ ("shadow index retry: index %d trys %d\n", i, imxdpu->shadow_load_state[disp][i]. state.trys); } } } if ((extdst_stat == 0) && (sub_stat == 0) && (fgen_stat == 0)) { /* clear interrupt */ IMXDPUV1_TRACE_IRQ("shadow requests are complete.\n"); } else { IMXDPUV1_TRACE_IRQ ("shadow requests are not complete: extdst 0x%08x, sub 0x%08x, fgen 0x%08x\n", extdst, sub, fgen); IMXDPUV1_TRACE_IRQ ("shadow requests are not complete: extdst_stat 0x%08x, sub_stat 0x%08x, fgen_stat 0x%08x\n", extdst_stat, sub_stat, fgen_stat); } return ret; } /*! * This function starts pending shadow loads * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * * @return This function returns 0 on success or negative error code on * fail. */ static int imxdpuv1_disp_start_shadow_loads(int8_t imxdpuv1_id, int8_t disp) { int ret = 0; uint32_t addr_extdst; /* address for extdst */ uint32_t addr_fgen; /* address for frame generator */ uint32_t extdst = 0; uint32_t fgen = 0; uint32_t sub = 0; int32_t i; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (disp == 0) { addr_fgen = IMXDPUV1_FRAMEGEN0_FGSLR; addr_extdst = IMXDPUV1_PIXENGCFG_EXTDST0_REQUEST; } else if (disp == 1) { addr_fgen = IMXDPUV1_FRAMEGEN1_FGSLR; addr_extdst = IMXDPUV1_PIXENGCFG_EXTDST1_REQUEST; } else { return -EINVAL; } /* this loop may need to be optimized */ for (i = 0; i < IMXDPUV1_SHDLD_IDX_CHAN_00; i++) { if (imxdpu->shadow_load_state[disp][i].state.request && (imxdpu->shadow_load_state[disp][i].state.processing == 0)) { imxdpu->shadow_load_state[disp][i].state.processing = 1; extdst |= trigger_list[i].extdst; /* only trigger frame generator for const frames*/ if (i >= IMXDPUV1_SHDLD_IDX_CONST0) { fgen |= 1; } } } for (i = IMXDPUV1_SHDLD_IDX_CHAN_00; i < IMXDPUV1_SHDLD_IDX_MAX; i++) { if (imxdpu->shadow_load_state[disp][i].state.request && (imxdpu->shadow_load_state[disp][i].state.processing == 0)) { imxdpu->shadow_load_state[disp][i].state.processing = 1; /*todo: need a completion handler */ extdst |= trigger_list[i].extdst; sub |= trigger_list[i].sub; } } if (sub) { IMXDPUV1_TRACE_IRQ("Fetch layer shadow request 0x%08x\n", sub); if (sub & 0xff) { /* FETCHLAYER0 */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_TRIGGERENABLE, sub & 0xff); } #ifdef IMXDPUV1_VERSION_0 if (sub & 0xff00) { /* FETCHLAYER1 */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_TRIGGERENABLE, (sub >> 8) & 0xff); } #endif if (sub & 0xff0000) { /* FETCHWARP2 */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_TRIGGERENABLE, (sub >> 16) & 0xff); } } if (extdst) { IMXDPUV1_TRACE_IRQ("Extdst shadow request 0x%08x\n", extdst); imxdpuv1_write(imxdpu, addr_extdst, extdst); } if (fgen) { IMXDPUV1_TRACE_IRQ("Fgen shadow request 0x%08x\n", fgen); imxdpuv1_write(imxdpu, addr_fgen, fgen); } return ret; } /*! * This function handles the VYNC interrupt for a display * * @param imxdpu imxdpu instance * @param disp display index * */ static void imxdpuv1_disp_vsync_handler(int8_t imxdpuv1_id, int8_t disp) { IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return; } if (!((disp == 0) || (disp == 1))) return; /* send notifications shadow load finished */ imxdpuv1_disp_start_shadow_loads(imxdpuv1_id, disp); imxdpuv1_disp_update_fgen_status(imxdpuv1_id, disp); return; } /*! * This function calls a register handler for an interrupt * * @param imxdpu imxdpu instance * @param irq interrupt line * */ static void imxdpuv1_handle_registered_irq(int8_t imxdpuv1_id, int8_t irq) { struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if ((irq < 0) || (irq >= IMXDPUV1_INTERRUPT_MAX)) return; if (imxdpu->irq_list[irq].handler == NULL) return; imxdpu->irq_list[irq].handler(irq, imxdpu->irq_list[irq].data); if ((imxdpu->irq_list[irq].flags & IMXDPUV1_IRQF_ONESHOT) != 0) { imxdpuv1_disable_irq(imxdpuv1_id, irq); imxdpuv1_clear_irq(imxdpuv1_id, irq); } return; } /* todo: this irq handler assumes all irq are ORed together. The irqs may be grouped so this function can be optimized if that is the case*/ /*! * This function processes all IRQs for the IMXDPU * * @param data pointer to the imxdpu structure * */ int imxdpuv1_handle_irq(int32_t imxdpuv1_id) { uint32_t int_stat[3]; uint32_t int_temp[3]; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE_IRQ("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { IMXDPUV1_TRACE_IRQ("%s(): invalid imxdpuv1_id\n", __func__); #ifdef DEBUG_IMXDPUV1_IRQ_ERROR panic("wrong imxdpuv1_id"); #endif return IMXDPUV1_FALSE; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpu->irq_count++; #ifdef DEBUG_IMXDPUV1_IRQ_ERROR { uint32_t int_enable0; int_enable0 = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE0); if (int_enable0 & 1) { panic("IRQ0 enabled\n"); } if (imxdpu->enabled_int[0] & 1) { panic("IRQ0 in enabled_int is set\n"); } } #endif /* Get and clear interrupt status */ int_temp[0] = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTSTATUS0); int_stat[0] = imxdpu->enabled_int[0] & int_temp[0]; int_temp[1] = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTSTATUS1); int_stat[1] = imxdpu->enabled_int[1] & int_temp[1]; #ifdef IMXDPUV1_VERSION_0 #ifdef IMXDPUV1_ENABLE_INTSTAT2 /* Enable this (IMXDPUV1_ENABLE_INTSTAT2) if intstat2 interrupts are needed */ int_temp[2] = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTSTATUS2); int_stat[2] = imxdpu->enabled_int[2] & int_temp[2]; #endif #endif /* No interrupts are pending */ if ((int_temp[0] == 0) && (int_temp[1] == 0) #ifdef IMXDPUV1_VERSION_0 #ifdef IMXDPUV1_ENABLE_INTSTAT2 && (int_temp[2] == 0) #endif #endif ) { } /* No enabled interrupts are pending */ if ((int_stat[0] == 0) && (int_stat[1] == 0) #ifdef IMXDPUV1_ENABLE_INTSTAT2 && (int_stat[2] == 0) #endif ) { IMXDPUV1_TRACE_IRQ ("Error: No enabled interrupts, 0x%08x 0x%08x\n", int_temp[0] & ~imxdpu->enabled_int[0], int_temp[1] & ~imxdpu->enabled_int[1]); #ifdef DEBUG_IMXDPUV1_IRQ_ERROR panic("no enabled IMXDPU interrupts"); #endif return IMXDPUV1_FALSE; } /* Clear the enabled interrupts */ if (int_stat[0]) { imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR0, int_stat[0]); } if (int_stat[1]) { imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR1, int_stat[1]); } #ifdef IMXDPUV1_ENABLE_INTSTAT2 if (int_stat[2]) { imxdpuv1_write_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTCLEAR2, int_stat[2]); } #endif #ifdef IMXDPUV1_ENABLE_INTSTAT2 if (int_stat[1] != 0) { /* add int_stat[2] if needed */ } #endif #ifdef IMXDPUV1_VERSION_0 /* now handle the interrupts that are pending */ if (int_stat[0] != 0) { if (int_stat[0] & 0xff) { if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE9_SHDLOAD_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_STORE9_SHDLOAD_IRQ irq\n"); imxdpuv1_be_irq_handler(imxdpuv1_id, IMXDPUV1_STORE9_SHDLOAD_IRQ); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE9_SHDLOAD_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ irq\n"); imxdpuv1_be_irq_handler(imxdpuv1_id, IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE9_SEQCOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_STORE9_SEQCOMPLETE_IRQ irq\n"); imxdpuv1_be_irq_handler(imxdpuv1_id, IMXDPUV1_STORE9_SEQCOMPLETE_IRQ); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE9_SEQCOMPLETE_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_EXTDST0_SHDLOAD_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_EXTDST0_SHDLOAD_IRQ irq\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST0_SHDLOAD_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_EXTDST0_FRAMECOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_EXTDST0_FRAMECOMPLETE_IRQ\n"); /* todo: move */ imxdpuv1_disp_check_shadow_loads(imxdpuv1_id, 0); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST0_FRAMECOMPLETE_IRQ); } } if (int_stat[0] & 0xff00) { if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_EXTDST1_SHDLOAD_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_EXTDST1_SHDLOAD_IRQ irq\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST1_SHDLOAD_IRQ); } if (int_stat[0] & INTSTAT0_BIT( IMXDPUV1_EXTDST1_FRAMECOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_EXTDST1_FRAMECOMPLETE_IRQ\n"); /* todo: move */ imxdpuv1_disp_check_shadow_loads(imxdpuv1_id, 1); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST1_FRAMECOMPLETE_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE4_SHDLOAD_IRQ)) { IMXDPUV1_TRACE_IRQ_CAPTURE("IMXDPUV1_STORE4_SHDLOAD_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE4_SHDLOAD_IRQ); } } if (int_stat[0] & 0xff0000) { if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE4_FRAMECOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ_CAPTURE( "IMXDPUV1_STORE4_FRAMECOMPLETE_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE4_FRAMECOMPLETE_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE4_SEQCOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ_CAPTURE( "IMXDPUV1_STORE4_SEQCOMPLETE_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE4_SEQCOMPLETE_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_HISTOGRAM4_VALID_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_HISTOGRAM4_VALID_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_HISTOGRAM4_VALID_IRQ); } } if (int_stat[0] & 0xff000000) { if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_HISTOGRAM5_VALID_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_HISTOGRAM5_VALID_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_HISTOGRAM5_VALID_IRQ); } if (int_stat[1] & INTSTAT0_BIT(IMXDPUV1_DISENGCFG_SHDLOAD0_IRQ)) { IMXDPUV1_PRINT ("IMXDPUV1_DISENGCFG_SHDLOAD0_IRQ irq\n"); imxdpuv1_disp_check_shadow_loads(imxdpuv1_id, 0); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_DISENGCFG_SHDLOAD0_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_DISENGCFG_FRAMECOMPLETE0_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_DISENGCFG_FRAMECOMPLETE0_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_DISENGCFG_FRAMECOMPLETE0_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_FRAMEGEN0_INT0_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_FRAMEGEN0_INT0_IRQ\n"); imxdpuv1_disp_vsync_handler(imxdpuv1_id, 0); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_FRAMEGEN0_INT0_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_FRAMEGEN0_INT1_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_FRAMEGEN0_INT1_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_FRAMEGEN0_INT1_IRQ); } } } if (int_stat[1] != 0) { if (int_stat[1] & 0xff) { } if (int_stat[1] & 0xff00) { if (int_stat[1] & INTSTAT1_BIT(IMXDPUV1_FRAMEGEN1_INT0_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_FRAMEGEN1_INT0_IRQ\n"); imxdpuv1_disp_vsync_handler(imxdpuv1_id, 1); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_FRAMEGEN1_INT0_IRQ); } } if (int_stat[0] & 0xff0000) { if (int_stat[0] & INTSTAT1_BIT(IMXDPUV1_COMCTRL_SW0_IRQ)) { IMXDPUV1_TRACE_IRQ("IMXDPUV1_COMCTRL_SW0_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW0_IRQ); } if (int_stat[1] & INTSTAT1_BIT(IMXDPUV1_COMCTRL_SW2_IRQ)) { IMXDPUV1_TRACE_IRQ("IMXDPUV1_COMCTRL_SW2_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW2_IRQ); } if (int_stat[1] & INTSTAT1_BIT(IMXDPUV1_COMCTRL_SW3_IRQ)) { IMXDPUV1_TRACE_IRQ("IMXDPUV1_COMCTRL_SW3_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW3_IRQ); } } } #else /* now handle the interrupts that are pending */ if (int_stat[0] != 0) { if (int_stat[0] & 0xff) { if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE9_SHDLOAD_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_STORE9_SHDLOAD_IRQ irq\n"); imxdpuv1_be_irq_handler(imxdpuv1_id, IMXDPUV1_STORE9_SHDLOAD_IRQ); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE9_SHDLOAD_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ irq\n"); imxdpuv1_be_irq_handler(imxdpuv1_id, IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE9_FRAMECOMPLETE_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_STORE9_SEQCOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_STORE9_SEQCOMPLETE_IRQ irq\n"); imxdpuv1_be_irq_handler(imxdpuv1_id, IMXDPUV1_STORE9_SEQCOMPLETE_IRQ); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_STORE9_SEQCOMPLETE_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_EXTDST0_SHDLOAD_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_EXTDST0_SHDLOAD_IRQ irq\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST0_SHDLOAD_IRQ); } if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_EXTDST0_FRAMECOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ ("IMXDPUV1_EXTDST0_FRAMECOMPLETE_IRQ\n"); /* todo: move */ imxdpuv1_disp_check_shadow_loads(imxdpuv1_id, 0); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST0_FRAMECOMPLETE_IRQ); } } if (int_stat[0] & 0xff00) { if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_EXTDST1_SHDLOAD_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_EXTDST1_SHDLOAD_IRQ irq\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST1_SHDLOAD_IRQ); } if (int_stat[0] & INTSTAT0_BIT( IMXDPUV1_EXTDST1_FRAMECOMPLETE_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_EXTDST1_FRAMECOMPLETE_IRQ\n"); /* todo: move */ imxdpuv1_disp_check_shadow_loads(imxdpuv1_id, 1); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_EXTDST1_FRAMECOMPLETE_IRQ); } } if (int_stat[0] & 0xff0000) { if (int_stat[0] & INTSTAT0_BIT(IMXDPUV1_FRAMEGEN0_INT0_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_FRAMEGEN0_INT0_IRQ\n"); imxdpuv1_disp_vsync_handler(imxdpuv1_id, 0); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_FRAMEGEN0_INT0_IRQ); } } if (int_stat[0] & 0xff000000) { if (int_stat[1] & INTSTAT0_BIT(IMXDPUV1_FRAMEGEN1_INT0_IRQ)) { IMXDPUV1_TRACE_IRQ( "IMXDPUV1_FRAMEGEN1_INT0_IRQ\n"); imxdpuv1_disp_vsync_handler(imxdpuv1_id, 1); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_FRAMEGEN1_INT0_IRQ); } } } if (int_stat[1] != 0) { if (int_stat[1] & 0xff) { if (int_stat[0] & INTSTAT1_BIT(IMXDPUV1_COMCTRL_SW0_IRQ)) { IMXDPUV1_TRACE_IRQ("IMXDPUV1_COMCTRL_SW0_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW0_IRQ); } if (int_stat[1] & INTSTAT1_BIT(IMXDPUV1_COMCTRL_SW2_IRQ)) { IMXDPUV1_TRACE_IRQ("IMXDPUV1_COMCTRL_SW2_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW2_IRQ); } } if (int_stat[1] & 0xff00) { if (int_stat[1] & INTSTAT1_BIT(IMXDPUV1_COMCTRL_SW3_IRQ)) { IMXDPUV1_TRACE_IRQ("IMXDPUV1_COMCTRL_SW3_IRQ\n"); imxdpuv1_handle_registered_irq(imxdpuv1_id, IMXDPUV1_COMCTRL_SW3_IRQ); } } if (int_stat[0] & 0xff0000) { /* Reserved for command sequencer debug */ } } #endif return IMXDPUV1_TRUE; } /*! * This function registers an interrupt handler function for the specified * irq line. The interrupt lines are defined in imxdpuv1_events.h * * @param imxdpu imxdpu instance * @param irq Interrupt line to get status for. * * @param handler Input parameter for address of the handler * function. * * @param irq_flags Flags for interrupt mode. Currently not used. * * @param devname Input parameter for string name of driver * registering the handler. * * @param data Input parameter for pointer of data to be * passed to the handler. * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_request_irq(int8_t imxdpuv1_id, uint32_t irq, int (*handler)(int, void *), uint32_t irq_flags, const char *devname, void *data) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (imxdpu->irq_list[irq].handler != NULL) { IMXDPUV1_TRACE("handler already installed on irq %d\n", irq); ret = -EINVAL; goto out; } imxdpu->irq_list[irq].handler = handler; imxdpu->irq_list[irq].flags = irq_flags; imxdpu->irq_list[irq].data = data; imxdpu->irq_list[irq].name = devname; /* Clear and enable the IRQ */ imxdpuv1_clear_irq(imxdpuv1_id, irq); /* Don't enable if a one shot */ if ((imxdpu->irq_list[irq].flags & IMXDPUV1_IRQF_ONESHOT) == 0) imxdpuv1_enable_irq(imxdpuv1_id, irq); out: return ret; } /*! * This function unregisters an interrupt handler for the specified interrupt * line. The interrupt lines are defined in imxdpuv1_events.h * * @param imxdpu imxdpu instance * @param irq Interrupt line to get status for. * * @param data Input parameter for pointer of data to be passed * to the handler. This must match value passed to * ipu_request_irq(). * */ int imxdpuv1_free_irq(int8_t imxdpuv1_id, uint32_t irq, void *data) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpuv1_disable_irq(imxdpuv1_id, irq); imxdpuv1_clear_irq(imxdpuv1_id, irq); if (imxdpu->irq_list[irq].data == data) memset(&imxdpu->irq_list[irq], 0, sizeof(imxdpu->irq_list[irq])); return ret; } /*! * This function un-initializes the imxdpu interrupts * * @param imxdpu imxdpu instance * */ int imxdpuv1_uninit_interrupts(int8_t imxdpuv1_id) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpu->enabled_int[0] = 0; imxdpu->enabled_int[1] = 0; #ifdef IMXDPUV1_VERSION_0 imxdpu->enabled_int[2] = 0; #endif imxdpuv1_clear_all_irqs(imxdpuv1_id); /* Set all interrupt to user mode */ imxdpuv1_write(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTMASK0, IMXDPUV1_COMCTRL_USERINTERRUPTMASK0_USERINTERRUPTMASK0_MASK); imxdpuv1_write(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTMASK1, IMXDPUV1_COMCTRL_USERINTERRUPTMASK1_USERINTERRUPTMASK1_MASK); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTMASK2, IMXDPUV1_COMCTRL_USERINTERRUPTMASK2_USERINTERRUPTMASK2_MASK); #endif /* Set all interrupts to user mode. this will to change to enable panic mode */ imxdpuv1_write(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE0, 0); imxdpuv1_write(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE1, 0); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE2, 0); #endif /* enable needed interupts */ return ret; } /*! * This function initializes the imxdpu and the required data structures * * @param imxdpuv1_id id of the diplay unit * * @return This function returns 0 on success or negative error code on * fail. */ /* todo: replace with probe function or call from probe use device tree as needed */ int imxdpuv1_init(int8_t imxdpuv1_id) { int ret = 0; int i; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); /* todo: add resource mapping for xrdc, layers, blit, display, ... */ /* imxdpuv1_id starts from 0 */ if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } /* Map the channels to display streams todo: make this mapping dynamic add channel features map capture channels */ for (i = IMXDPUV1_CHAN_IDX_IN_FIRST; i < IMXDPUV1_CHAN_IDX_MAX; i++) { if (i <= IMXDPUV1_CHAN_IDX_17) imxdpuv1_array[imxdpuv1_id].chan_data[i].disp_id = 0; else if (i < IMXDPUV1_CHAN_IDX_IN_MAX) imxdpuv1_array[imxdpuv1_id].chan_data[i].disp_id = 1; else if (i < IMXDPUV1_CHAN_IDX_OUT_FIRST) imxdpuv1_array[imxdpuv1_id].chan_data[i].disp_id = 0; else if (i < IMXDPUV1_CHAN_IDX_OUT_MAX) imxdpuv1_array[imxdpuv1_id].chan_data[i].disp_id = 1; else imxdpuv1_array[imxdpuv1_id].chan_data[i].disp_id = 0; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; imxdpu->irq_count = 0; if (imxdpuv1_id == 0) { imxdpu->base = (void __iomem *)IMXDPUV1_REGS_BASE_PHY0; IMXDPUV1_TRACE("%s(): virtual base address is 0x%p (0x%08x physical)\n", __func__, imxdpu->base, IMXDPUV1_REGS_BASE_PHY0); } else if (imxdpuv1_id == 1) { imxdpu->base = (void __iomem *)IMXDPUV1_REGS_BASE_PHY1; IMXDPUV1_TRACE("%s(): virtual base address is 0x%p (0x%08x physical)\n", __func__, imxdpu->base, IMXDPUV1_REGS_BASE_PHY1); } else { return -ENOMEM; } /* todo: may need to check resource allocaiton/ownership for these */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY0, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY0_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY1, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY1_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY2, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY2_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY3, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY3_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY4, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY4_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY5, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY5_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY6, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY6_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY7, IMXDPUV1_FETCHLAYER0_LAYERPROPERTY7_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_TRIGGERENABLE, IMXDPUV1_FETCHLAYER0_TRIGGERENABLE_RESET_VALUE); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY0, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY0_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY1, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY1_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY2, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY2_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY3, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY3_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY4, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY4_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY5, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY5_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY6, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY6_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY7, IMXDPUV1_FETCHLAYER1_LAYERPROPERTY7_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_TRIGGERENABLE, IMXDPUV1_FETCHLAYER1_TRIGGERENABLE_RESET_VALUE); #endif imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY0, IMXDPUV1_FETCHWARP2_LAYERPROPERTY0_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY1, IMXDPUV1_FETCHWARP2_LAYERPROPERTY1_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY2, IMXDPUV1_FETCHWARP2_LAYERPROPERTY2_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY3, IMXDPUV1_FETCHWARP2_LAYERPROPERTY3_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY4, IMXDPUV1_FETCHWARP2_LAYERPROPERTY4_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY5, IMXDPUV1_FETCHWARP2_LAYERPROPERTY5_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY6, IMXDPUV1_FETCHWARP2_LAYERPROPERTY6_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_LAYERPROPERTY7, IMXDPUV1_FETCHWARP2_LAYERPROPERTY7_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_TRIGGERENABLE, IMXDPUV1_FETCHWARP2_TRIGGERENABLE_RESET_VALUE); /* Initial StaticControl configuration - reset values */ /* IMXDPUV1_FETCHDECODE9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE9_STATICCONTROL, IMXDPUV1_FETCHDECODE9_STATICCONTROL_RESET_VALUE); #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_FETCHPERSP9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHPERSP9_STATICCONTROL, IMXDPUV1_FETCHPERSP9_STATICCONTROL_RESET_VALUE); #else /* IMXDPUV1_FETCHPERSP9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP9_STATICCONTROL, IMXDPUV1_FETCHWARP9_STATICCONTROL_RESET_VALUE); #endif /* IMXDPUV1_FETCHECO9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO9_STATICCONTROL, IMXDPUV1_FETCHECO9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_ROP9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_ROP9_STATICCONTROL, IMXDPUV1_ROP9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_CLUT9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_CLUT9_STATICCONTROL, IMXDPUV1_CLUT9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_MATRIX9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_MATRIX9_STATICCONTROL, IMXDPUV1_MATRIX9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_HSCALER9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_HSCALER9_STATICCONTROL, IMXDPUV1_HSCALER9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_VSCALER9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_VSCALER9_STATICCONTROL, IMXDPUV1_VSCALER9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FILTER9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FILTER9_STATICCONTROL, IMXDPUV1_FILTER9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_BLITBLEND9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_BLITBLEND9_STATICCONTROL, IMXDPUV1_BLITBLEND9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_STORE9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_STORE9_STATICCONTROL, IMXDPUV1_STORE9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_CONSTFRAME0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_CONSTFRAME0_STATICCONTROL, IMXDPUV1_CONSTFRAME0_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_EXTDST0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTDST0_STATICCONTROL, IMXDPUV1_EXTDST0_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_EXTDST4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTDST4_STATICCONTROL, IMXDPUV1_EXTDST4_STATICCONTROL_RESET_VALUE); /* todo: IMXDPUV1_CONSTFRAME4_STATICCONTROL */ /* IMXDPUV1_CONSTFRAME1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_CONSTFRAME1_STATICCONTROL, IMXDPUV1_CONSTFRAME1_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_EXTDST1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTDST1_STATICCONTROL, IMXDPUV1_EXTDST1_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_EXTDST5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTDST5_STATICCONTROL, IMXDPUV1_EXTDST5_STATICCONTROL_RESET_VALUE); /* todo: IMXDPUV1_CONSTFRAME5_STATICCONTROL */ #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_EXTSRC4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTSRC4_STATICCONTROL, IMXDPUV1_EXTSRC4_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_STORE4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_STORE4_STATICCONTROL, IMXDPUV1_STORE4_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_EXTSRC5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTSRC5_STATICCONTROL, IMXDPUV1_EXTSRC5_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_STORE5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_STORE5_STATICCONTROL, IMXDPUV1_STORE5_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FETCHDECODE2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE2_STATICCONTROL, IMXDPUV1_FETCHDECODE2_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FETCHDECODE3_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE3_STATICCONTROL, IMXDPUV1_FETCHDECODE3_STATICCONTROL_RESET_VALUE); #endif /* IMXDPUV1_FETCHWARP2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_STATICCONTROL, IMXDPUV1_FETCHWARP2_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FETCHECO2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO9_STATICCONTROL, IMXDPUV1_FETCHECO9_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FETCHDECODE0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE0_STATICCONTROL, IMXDPUV1_FETCHDECODE0_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FETCHECO0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO0_STATICCONTROL, IMXDPUV1_FETCHECO0_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FETCHDECODE1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE1_STATICCONTROL, IMXDPUV1_FETCHDECODE1_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_FETCHECO1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO1_STATICCONTROL, IMXDPUV1_FETCHECO1_STATICCONTROL_RESET_VALUE); /* todo: IMXDPUV1_MATRIX5_STATICCONTROL */ /* todo: IMXDPUV1_HSCALER5_STATICCONTROL */ /* todo: IMXDPUV1_VSCALER5_STATICCONTROL */ /* IMXDPUV1_LAYERBLEND0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND0_STATICCONTROL, IMXDPUV1_LAYERBLEND0_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_LAYERBLEND1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND1_STATICCONTROL, IMXDPUV1_LAYERBLEND1_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_LAYERBLEND2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND2_STATICCONTROL, IMXDPUV1_LAYERBLEND2_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_LAYERBLEND3_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND3_STATICCONTROL, IMXDPUV1_LAYERBLEND3_STATICCONTROL_RESET_VALUE); #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_LAYERBLEND4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND4_STATICCONTROL, IMXDPUV1_LAYERBLEND4_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_LAYERBLEND5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND5_STATICCONTROL, IMXDPUV1_LAYERBLEND5_STATICCONTROL_RESET_VALUE); /* IMXDPUV1_LAYERBLEND6_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND6_STATICCONTROL, IMXDPUV1_LAYERBLEND6_STATICCONTROL_RESET_VALUE); #endif /* Dynamic config */ imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHPERSP9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #else imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHWARP9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #endif imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_ROP9_DYNAMIC, IMXDPUV1_SET_FIELD (IMXDPUV1_PIXENGCFG_ROP9_DYNAMIC_ROP9_PRIM_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD (IMXDPUV1_PIXENGCFG_ROP9_DYNAMIC_ROP9_SEC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD (IMXDPUV1_PIXENGCFG_ROP9_DYNAMIC_ROP9_TERT_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_CLUT9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_MATRIX9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_HSCALER9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_VSCALER9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FILTER9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_BLITBLEND9_DYNAMIC, IMXDPUV1_SET_FIELD (IMXDPUV1_PIXENGCFG_BLITBLEND9_DYNAMIC_BLITBLEND9_PRIM_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD (IMXDPUV1_PIXENGCFG_BLITBLEND9_DYNAMIC_BLITBLEND9_SEC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE9_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE2_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE3_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #endif imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHWARP2_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE0_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE1_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_GAMMACOR4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #endif imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_MATRIX4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_HSCALER4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_VSCALER4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_HISTOGRAM4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_GAMMACOR5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE)); #endif imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_MATRIX5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_HSCALER5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_VSCALER5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_HISTOGRAM5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_SRC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); #endif imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND0_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND1_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND2_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND3_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND4_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND5_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND6_DYNAMIC, IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_PRIM_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL, IMXDPUV1_PIXENGCFG_LAYERBLEND_SEC_SEL__DISABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_CLKEN, IMXDPUV1_PIXENGCFG_CLKEN__AUTOMATIC)); #endif /* Static configuration - reset values */ imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE9_STATIC, IMXDPUV1_PIXENGCFG_STORE9_STATIC_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_STATIC, IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST4_STATIC, IMXDPUV1_PIXENGCFG_EXTDST4_STATIC_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_STATIC, IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST5_STATIC, IMXDPUV1_PIXENGCFG_EXTDST5_STATIC_RESET_VALUE); #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_STATIC, IMXDPUV1_PIXENGCFG_STORE4_STATIC_RESET_VALUE); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE5_STATIC, IMXDPUV1_PIXENGCFG_STORE5_STATIC_RESET_VALUE); #endif /* Static configuration - initial settings */ imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE9_STATIC, IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE9_STATIC_STORE9_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE9_STATIC_STORE9_POWERDOWN, IMXDPUV1_FALSE) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE, IMXDPUV1_PIXENGCFG_STORE9_STATIC_STORE9_SYNC_MODE__SINGLE) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET, IMXDPUV1_PIXENGCFG_STORE9_STATIC_STORE9_SW_RESET__OPERATION) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_STORE9_STATIC_STORE9_DIV, IMXDPUV1_PIXENGCFG_DIVIDER_RESET)); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_STATIC, IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_EXTDST0_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_EXTDST0_POWERDOWN, IMXDPUV1_FALSE) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_EXTDST0_SYNC_MODE, IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_EXTDST0_SYNC_MODE__AUTO) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_EXTDST0_SW_RESET, IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_EXTDST0_SW_RESET__OPERATION) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST0_STATIC_EXTDST0_DIV, IMXDPUV1_PIXENGCFG_DIVIDER_RESET)); /* todo: IMXDPUV1_PIXENGCFG_EXTDST4_STATIC_OFFSET */ imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_STATIC, IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_EXTDST1_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_EXTDST1_POWERDOWN, IMXDPUV1_FALSE) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_EXTDST1_SYNC_MODE, IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_EXTDST1_SYNC_MODE__AUTO) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_EXTDST1_SW_RESET, IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_EXTDST1_SW_RESET__OPERATION) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_EXTDST1_STATIC_EXTDST1_DIV, IMXDPUV1_PIXENGCFG_DIVIDER_RESET)); /* todo: IMXDPUV1_PIXENGCFG_EXTDST5_STATIC_OFFSET */ #ifdef IMXDPUV1_VERSION_0 imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_STATIC, IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE4_STATIC_STORE4_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE4_STATIC_STORE4_POWERDOWN, IMXDPUV1_FALSE) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE4_STATIC_STORE4_SYNC_MODE, IMXDPUV1_PIXENGCFG_STORE4_STATIC_STORE4_SYNC_MODE__SINGLE) | IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_STORE4_STATIC_STORE4_SW_RESET, IMXDPUV1_PIXENGCFG_STORE4_STATIC_STORE4_SW_RESET__OPERATION) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_STORE4_STATIC_STORE4_DIV, IMXDPUV1_PIXENGCFG_DIVIDER_RESET)); #endif /* todo: IMXDPUV1_PIXENGCFG_STORE4_STATIC */ /* Static Control configuration */ /* IMXDPUV1_FETCHDECODE9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE9_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHDECODE9_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_FETCHPERSP9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHPERSP9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHPERSP9_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHPERSP9_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); #else /* IMXDPUV1_FETCHWARP9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHWARP9_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHWARP9_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); #endif /* IMXDPUV1_FETCHECO9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHECO9_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHECO9_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); /* IMXDPUV1_ROP9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_ROP9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_ROP9_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_CLUT9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_CLUT9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_CLUT9_STATICCONTROL_SHDEN, 1)); imxdpuv1_write(imxdpu, IMXDPUV1_CLUT9_UNSHADOWEDCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_CLUT9_UNSHADOWEDCONTROL_B_EN, IMXDPUV1_CLUT9_UNSHADOWEDCONTROL_B_EN__ENABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_CLUT9_UNSHADOWEDCONTROL_G_EN, IMXDPUV1_CLUT9_UNSHADOWEDCONTROL_G_EN__ENABLE) | IMXDPUV1_SET_FIELD(IMXDPUV1_CLUT9_UNSHADOWEDCONTROL_R_EN, IMXDPUV1_CLUT9_UNSHADOWEDCONTROL_R_EN__ENABLE)); /* IMXDPUV1_MATRIX9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_MATRIX9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_MATRIX9_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_HSCALER9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_HSCALER9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_HSCALER9_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_VSCALER9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_VSCALER9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_VSCALER9_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_FILTER9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FILTER9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FILTER9_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_BLITBLEND9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_BLITBLEND9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_BLITBLEND9_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_STORE9_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_STORE9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_STORE9_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_STORE9_STATICCONTROL_BASEADDRESSAUTOUPDATE, 1)); /* IMXDPUV1_CONSTFRAME0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_CONSTFRAME0_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_CONSTFRAME0_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_EXTDST0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTDST0_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTDST0_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_EXTDST0_STATICCONTROL_PERFCOUNTMODE, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTDST0_STATICCONTROL_KICK_MODE, IMXDPUV1_EXTDST0_STATICCONTROL_KICK_MODE__EXTERNAL)); /* todo: IMXDPUV1_CONSTFRAME4_STATICCONTROL */ /* todo: IMXDPUV1_EXTDST4_STATICCONTROL */ /* IMXDPUV1_CONSTFRAME1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_CONSTFRAME1_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_CONSTFRAME1_STATICCONTROL_SHDEN, 1)); /* IMXDPUV1_EXTDST1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTDST1_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTDST1_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_EXTDST1_STATICCONTROL_PERFCOUNTMODE, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTDST1_STATICCONTROL_KICK_MODE, IMXDPUV1_EXTDST1_STATICCONTROL_KICK_MODE__EXTERNAL)); /* todo: IMXDPUV1_CONSTFRAME5_STATICCONTROL */ /* todo: IMXDPUV1_EXTDST5_STATICCONTROL */ #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_EXTSRC4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTSRC4_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_STATICCONTROL_STARTSEL, IMXDPUV1_EXTSRC4_STATICCONTROL_STARTSEL__LOCAL)); /* IMXDPUV1_STORE4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_STORE4_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_STORE4_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_STORE4_STATICCONTROL_BASEADDRESSAUTOUPDATE, 1)); /* IMXDPUV1_EXTSRC5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_EXTSRC5_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC5_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC5_STATICCONTROL_STARTSEL, IMXDPUV1_EXTSRC5_STATICCONTROL_STARTSEL__LOCAL)); /* IMXDPUV1_STORE5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_STORE5_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_STORE5_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_STORE5_STATICCONTROL_BASEADDRESSAUTOUPDATE, 1)); /* IMXDPUV1_FETCHDECODE2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE2_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE2_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHDECODE2_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); /* IMXDPUV1_FETCHDECODE3_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE3_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE3_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHDECODE3_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); #endif /* IMXDPUV1_FETCHWARP2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHWARP2_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHWARP2_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHWARP2_STATICCONTROL_SHDLDREQSTICKY, 0)); /* IMXDPUV1_FETCHECO2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO9_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHECO9_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHECO9_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); /* IMXDPUV1_FETCHDECODE0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE0_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE0_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHDECODE0_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); /* IMXDPUV1_FETCHECO0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO0_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHECO0_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHECO0_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); /* IMXDPUV1_FETCHDECODE1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHDECODE1_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE1_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHDECODE1_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); /* IMXDPUV1_FETCHECO1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHECO1_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHECO1_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHECO1_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0)); /* IMXDPUV1_FETCHLAYER0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHLAYER0_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHLAYER0_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHLAYER0_STATICCONTROL_SHDLDREQSTICKY, 0)); #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_FETCHLAYER1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHLAYER1_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHLAYER1_STATICCONTROL_BASEADDRESSAUTOUPDATE, 0) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHLAYER1_STATICCONTROL_SHDLDREQSTICKY, 0)); /* IMXDPUV1_GAMMACOR4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_GAMMACOR4_STATICCONTROL, IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR4_STATICCONTROL_BLUEWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR4_STATICCONTROL_GREENWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR4_STATICCONTROL_REDWRITEENABLE, 1)); #endif /* todo: IMXDPUV1_MATRIX4_STATICCONTROL */ /* todo: IMXDPUV1_HSCALER4_STATICCONTROL */ /* todo: IMXDPUV1_VSCALER4_STATICCONTROL */ #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_GAMMACOR5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_GAMMACOR5_STATICCONTROL, IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR5_STATICCONTROL_BLUEWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR5_STATICCONTROL_GREENWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR5_STATICCONTROL_REDWRITEENABLE, 1)); #endif /* todo: IMXDPUV1_MATRIX5_STATICCONTROL */ /* todo: IMXDPUV1_HSCALER5_STATICCONTROL */ /* todo: IMXDPUV1_VSCALER5_STATICCONTROL */ /* IMXDPUV1_LAYERBLEND0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND0_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND0_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND0_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND0_STATICCONTROL_SHDTOKSEL__BOTH)); /* IMXDPUV1_LAYERBLEND1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND1_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND1_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND1_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND1_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND1_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND1_STATICCONTROL_SHDTOKSEL__BOTH)); /* IMXDPUV1_LAYERBLEND2_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND2_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND2_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND2_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND2_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND2_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND2_STATICCONTROL_SHDTOKSEL__BOTH)); /* IMXDPUV1_LAYERBLEND3_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND3_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND3_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND3_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND3_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND3_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND3_STATICCONTROL_SHDTOKSEL__BOTH)); #ifdef IMXDPUV1_VERSION_0 /* IMXDPUV1_LAYERBLEND4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND4_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDTOKSEL__BOTH)); /* IMXDPUV1_LAYERBLEND4_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND4_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDEN, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND4_STATICCONTROL_SHDTOKSEL__BOTH)); /* IMXDPUV1_LAYERBLEND5_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND5_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND5_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND5_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND5_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND5_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND5_STATICCONTROL_SHDTOKSEL__BOTH)); /* IMXDPUV1_LAYERBLEND6_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_LAYERBLEND6_STATICCONTROL, IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND6_STATICCONTROL_SHDEN, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND6_STATICCONTROL_SHDLDSEL, IMXDPUV1_LAYERBLEND6_STATICCONTROL_SHDLDSEL__SECONDARY) | IMXDPUV1_SET_FIELD( IMXDPUV1_LAYERBLEND6_STATICCONTROL_SHDTOKSEL, IMXDPUV1_LAYERBLEND6_STATICCONTROL_SHDTOKSEL__BOTH)); #endif /* todo: IMXDPUV1_EXTSRC0_STATICCONTROL */ /* todo: IMXDPUV1_EXTSRC1_STATICCONTROL */ /* todo: IMXDPUV1_MATRIX0_STATICCONTROL */ /* IMXDPUV1_GAMMACOR0_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_GAMMACOR0_STATICCONTROL, IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR1_STATICCONTROL_BLUEWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR1_STATICCONTROL_GREENWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR1_STATICCONTROL_REDWRITEENABLE, 1)); /* todo: IMXDPUV1_SIG0_STATICCONTROL */ /* todo: IMXDPUV1_MATRIX1_STATICCONTROL */ /* IMXDPUV1_GAMMACOR1_STATICCONTROL */ imxdpuv1_write(imxdpu, IMXDPUV1_GAMMACOR1_STATICCONTROL, IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR1_STATICCONTROL_BLUEWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR1_STATICCONTROL_GREENWRITEENABLE, 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_GAMMACOR1_STATICCONTROL_REDWRITEENABLE, 1)); /* IMXDPUV1_SIG1_STATICCONTROL */ imxdpuv1_init_irqs(imxdpuv1_id); return ret; } int imxdpuv1_init_sync_panel(int8_t imxdpuv1_id, int8_t disp, uint32_t pixel_fmt, struct imxdpuv1_videomode mode) { int ret = 0; IMXDPUV1_TRACE("%s()\n", __func__); return ret; } int imxdpuv1_uninit_sync_panel(int8_t imxdpuv1_id, int8_t disp) { int ret = 0; IMXDPUV1_TRACE("%s()\n", __func__); return ret; } int imxdpuv1_reset_disp_panel(int8_t imxdpuv1_id, int8_t disp) { int ret = 0; IMXDPUV1_TRACE("%s()\n", __func__); return ret; } /*! * This function initializes the display * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_init(int8_t imxdpuv1_id, int8_t disp) { int ret = 0; struct imxdpuv1_soc *imxdpu; struct imxdpuv1_videomode *mode; int reg = 0; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; mode = &imxdpu->video_mode[disp]; /*imxdpuv1_disp_dump_mode(&imxdpu->video_mode[disp]);*/ if (disp == 0) { #ifdef IMXDPUV1_TCON0_MAP_24BIT_0_23 /* Static 24-bit TCON bit mapping for FPGA */ imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT7_4, 0x1d1c1b1a); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT3_0, 0x19181716); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT15_12, 0x13121110); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT11_8, 0x0f0e0d0c); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT23_20, 0x09080706); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT19_16, 0x05040302); #else /* tcon mapping * RR RRRR RRRR GGGG GGGG GGBB BBBB BBBB * 98 7654 3210 9876 5432 1098 7654 3210 * bits * 00 0000 0000 1111 1111 1122 2222 2222 * 98 7654 3210 8765 5432 1098 7654 3210 */ /* 30-bit timing controller setup */ imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT31_28, 0x00000908); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT27_24, 0x07060504); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT23_20, 0x03020100); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT19_16, 0x13121110); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT15_12, 0x0f0e0d0c); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT11_8, 0x0b0a1d1c); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT7_4, 0x1b1a1918); imxdpuv1_write(imxdpu, IMXDPUV1_TCON0_MAPBIT3_0, 0x17161514); #endif /* set data enable polarity */ if (mode->flags & IMXDPUV1_MODE_FLAGS_HSYNC_POL) reg = IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLHS0, IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLHS0__HIGH); else reg = IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLHS0, IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLHS0__LOW); if (mode->flags & IMXDPUV1_MODE_FLAGS_VSYNC_POL) reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLVS0, IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLVS0__HIGH); else reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLVS0, IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLVS0__LOW); if (mode->flags & IMXDPUV1_MODE_FLAGS_DE_POL) reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLEN0, IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLEN0__HIGH); else reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLEN0, IMXDPUV1_DISENGCFG_POLARITYCTRL0_POLEN0__LOW); imxdpuv1_write(imxdpu, IMXDPUV1_DISENGCFG_POLARITYCTRL0, reg); /* printf("polreg=0x%x\n", imxdpuv1_read(imxdpu, IMXDPUV1_DISENGCFG_POLARITYCTRL0)); */ } else if (disp == 1) { #ifdef IMXDPUV1_TCON1_MAP_24BIT_0_23 /* Static TCON bit mapping */ imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT7_4, 0x1d1c1b1a); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT3_0, 0x19181716); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT15_12, 0x13121110); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT11_8, 0x0f0e0d0c); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT23_20, 0x09080706); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT19_16, 0x05040302); #else /* tcon mapping * RR RRRR RRRR GGGG GGGG GGBB BBBB BBBB * 98 7654 3210 9876 5432 1098 7654 3210 * bits * 00 0000 0000 1111 1111 1122 2222 2222 * 98 7654 3210 8765 5432 1098 7654 3210 */ /* 30-bit timing controller setup */ imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT31_28, 0x00000908); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT27_24, 0x07060504); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT23_20, 0x03020100); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT19_16, 0x13121110); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT15_12, 0x0f0e0d0c); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT11_8, 0x0b0a1d1c); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT7_4, 0x1b1a1918); imxdpuv1_write(imxdpu, IMXDPUV1_TCON1_MAPBIT3_0, 0x17161514); #endif /* set data enable polarity */ if (mode->flags & IMXDPUV1_MODE_FLAGS_HSYNC_POL) reg = IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLHS1, IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLHS1__HIGH); else reg = IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLHS1, IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLHS1__LOW); if (mode->flags & IMXDPUV1_MODE_FLAGS_VSYNC_POL) reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLVS1, IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLVS1__HIGH); else reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLVS1, IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLVS1__LOW); if (mode->flags & IMXDPUV1_MODE_FLAGS_DE_POL) reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLEN1, IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLEN1__HIGH); else reg |= IMXDPUV1_SET_FIELD( IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLEN1, IMXDPUV1_DISENGCFG_POLARITYCTRL1_POLEN1__LOW); imxdpuv1_write(imxdpu, IMXDPUV1_DISENGCFG_POLARITYCTRL1, reg); /* printf("polreg=0x%x\n", imxdpuv1_read(imxdpu, IMXDPUV1_DISENGCFG_POLARITYCTRL1)); */ } else { return -EINVAL; } /* todo: initialize prefetch */ return ret; } int imxdpuv1_disp_setup_tcon_bypass_mode( int8_t imxdpuv1_id, int8_t disp, const struct imxdpuv1_videomode *mode) { struct imxdpuv1_soc *imxdpu; uint32_t b_off; /* block offset for tcon generator */ IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (disp == 0) { b_off = IMXDPUV1_TCON0_LOCKUNLOCK; } else if (disp == 1) { b_off = IMXDPUV1_TCON1_LOCKUNLOCK; } else { return -EINVAL; } imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_TCON_CTRL_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_TCON_CTRL_LVDS_BALANCE, IMXDPUV1_TCON0_TCON_CTRL_LVDS_BALANCE__BALANCED) | IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_TCON_CTRL_MINILVDS_OPCODE, IMXDPUV1_TCON0_TCON_CTRL_MINILVDS_OPCODE__MODE_4PAIRS) | IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_TCON_CTRL_SPLITPOSITION, 0x140)); /* setup hsync */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG0POSON_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG0POSON_SPGPSON_X0, mode->hlen + mode->hfp)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG0MASKON_OFFSET, 0xffff); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG0POSOFF_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG0POSOFF_SPGPSOFF_X0, mode->hlen + mode->hfp + mode->hsync)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG0MASKOFF_OFFSET, 0xffff); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX0SIGS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SMX0SIGS_SMX0SIGS_S0, 2)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX0FCTTABLE_OFFSET, 1); /* Setup Vsync */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG1POSON_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG1POSON_SPGPSON_X1, mode->hlen + mode->hfp + mode->hsync) | IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG1POSON_SPGPSON_Y1, mode->vlen + mode->vfp - 1)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG1MASKON_OFFSET, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG1POSOFF_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG1POSOFF_SPGPSOFF_X1, mode->hlen + mode->hfp + mode->hsync)| IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG1POSOFF_SPGPSOFF_Y1, mode->vlen + mode->vfp + mode->vsync - 1)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG1MASKOFF_OFFSET, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX1SIGS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SMX1SIGS_SMX1SIGS_S0, 3)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX1FCTTABLE_OFFSET, 1); /* data enable horizontal */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG2POSON_OFFSET, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG2MASKON_OFFSET, 0xffff); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG2POSOFF_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG2POSOFF_SPGPSOFF_X2, mode->hlen)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG2MASKOFF_OFFSET, 0xffff); /* data enable vertical */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG3POSON_OFFSET, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG3MASKON_OFFSET, 0x7fff0000); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG3POSOFF_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG3POSOFF_SPGPSOFF_X3, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG3POSOFF_SPGPSOFF_Y3, mode->vlen)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG3MASKOFF_OFFSET, 0x7fff0000); /* use both SPG2 and SPG3 to generate data enable */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX2SIGS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SMX2SIGS_SMX2SIGS_S0, 4)| IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SMX2SIGS_SMX2SIGS_S1, 5)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX2FCTTABLE_OFFSET, 8); /* shadow load trigger (aka kachunk) */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG4POSON_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG4POSON_SPGPSON_X4, 10) | IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG4POSON_SPGPSON_Y4, mode->vlen)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG4MASKON_OFFSET, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG4POSOFF_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG4POSOFF_SPGPSOFF_X4, 26) | IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SPG4POSOFF_SPGPSOFF_Y4, mode->vlen)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SPG4MASKOFF_OFFSET, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX3SIGS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_TCON0_SMX3SIGS_SMX3SIGS_S0, 6)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_TCON0_SMX3FCTTABLE_OFFSET, 2); return 0; } /*! * This function sets up the frame generator * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * @param enable state to set frame generator to * @param mode to set the display to * @param cc_red constant color red * @param cc_green constant color green * @param cc_blue constant color blue * @param cc_alpha constant color alpha * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_setup_frame_gen( int8_t imxdpuv1_id, int8_t disp, const struct imxdpuv1_videomode *mode, uint16_t cc_red, /* 10 bits */ uint16_t cc_green, /* 10 bits */ uint16_t cc_blue, /* 10 bits */ uint8_t cc_alpha, bool test_mode_enable) { /* 1 bits, yes 1 bit */ int ret = 0; uint32_t b_off; /* block offset for frame generator */ uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (disp == 0) { b_off = IMXDPUV1_FRAMEGEN0_LOCKUNLOCK; } else if (disp == 1) { b_off = IMXDPUV1_FRAMEGEN1_LOCKUNLOCK; } else { return -EINVAL; } /* todo: add video mode sanity check here check if LRSYNC is required */ if (mode->flags & IMXDPUV1_MODE_FLAGS_LRSYNC) { /* todo: here we need to use two outputs to make one */ if (disp == 0) { reg = IMXDPUV1_SET_FIELD( IMXDPUV1_FRAMEGEN0_FGSTCTRL_FGSYNCMODE, IMXDPUV1_FRAMEGEN0_FGSTCTRL_FGSYNCMODE__MASTER); } else { reg = IMXDPUV1_SET_FIELD( IMXDPUV1_FRAMEGEN1_FGSTCTRL_FGSYNCMODE, IMXDPUV1_FRAMEGEN1_FGSTCTRL_FGSYNCMODE__SLAVE_CYC); } } else { reg = IMXDPUV1_SET_FIELD( IMXDPUV1_FRAMEGEN0_FGSTCTRL_FGSYNCMODE, IMXDPUV1_FRAMEGEN0_FGSTCTRL_FGSYNCMODE__OFF); } imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGSTCTRL_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_HTCFG1_HACT, mode->hlen) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_HTCFG1_HTOTAL, (mode->hlen + mode->hfp + mode->hbp + mode->hsync - 1)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_HTCFG1_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_HTCFG2_HSYNC, mode->hsync - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_HTCFG2_HSBP, mode->hbp + mode->hsync - 1) | /* shadow enable */ IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_HTCFG2_HSEN, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_HTCFG2_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_VTCFG1_VACT, mode->vlen) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_VTCFG1_VTOTAL, (mode->vlen + mode->vfp + mode->vbp + mode->vsync - 1)); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_VTCFG1_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_VTCFG2_VSYNC, mode->vsync - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_VTCFG2_VSBP, mode->vbp + mode->vsync - 1) | /* shadow enable */ IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_VTCFG2_VSEN, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_VTCFG2_OFFSET, reg); /* Interupt at position (0, vlen - 3) for end of frame interrupt */ reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT0CONFIG_INT0COL, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT0CONFIG_INT0HSEN, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT0CONFIG_INT0ROW, mode->vlen - 3) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT0CONFIG_INT0EN, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_INT0CONFIG_OFFSET, reg); /* Interupt at position 1, mode->vlen */ reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT1CONFIG_INT1COL, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT1CONFIG_INT1HSEN, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT1CONFIG_INT1ROW, mode->vlen) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT1CONFIG_INT1EN, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_INT1CONFIG_OFFSET, reg); /* Interupt at position 2, mode->vlen */ reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT2CONFIG_INT2COL, 2) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT2CONFIG_INT2HSEN, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT2CONFIG_INT2ROW, mode->vlen) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT2CONFIG_INT2EN, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_INT2CONFIG_OFFSET, reg); /* Interupt at position 3, mode->vlen */ reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT3CONFIG_INT3COL, 3) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT3CONFIG_INT3HSEN, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT3CONFIG_INT3ROW, mode->vlen) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_INT3CONFIG_INT3EN, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_INT3CONFIG_OFFSET, reg); /* todo: these need to be checked _SKICKCOL for verification: =(FW - 40) , for ref driver = 1 ? _SKICKROW for verif. =(FH - 1), ref driver = vlen-2 */ reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_SKICKCONFIG_SKICKCOL, mode->hlen - 40) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_SKICKCONFIG_SKICKINT1EN, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_SKICKCONFIG_SKICKROW, mode->vlen + 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_SKICKCONFIG_SKICKEN, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_SKICKCONFIG_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_PACFG_PSTARTX, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_PACFG_PSTARTY, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_PACFG_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_SACFG_SSTARTX, 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_SACFG_SSTARTY, 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_SACFG_OFFSET, reg); if (IMXDPUV1_ENABLE == test_mode_enable) { reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGINCTRL_FGDM, IMXDPUV1_FRAMEGEN0_FGINCTRL_FGDM__TEST); } else { reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGINCTRL_FGDM, IMXDPUV1_FRAMEGEN0_FGINCTRL_FGDM__SEC) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGINCTRL_ENPRIMALPHA, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGINCTRL_ENSECALPHA, 0); } imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGINCTRL_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGINCTRLPANIC_FGDMPANIC, IMXDPUV1_FRAMEGEN0_FGINCTRLPANIC_FGDMPANIC__CONSTCOL) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGINCTRLPANIC_ENPRIMALPHAPANIC, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGINCTRLPANIC_ENSECALPHAPANIC, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGINCTRLPANIC_OFFSET, reg); /* Set the constant color - ARGB 1-10-10-10 */ reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGCCR_CCRED, cc_red) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGCCR_CCBLUE, cc_blue) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGCCR_CCGREEN, cc_green) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGCCR_CCALPHA, cc_alpha); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGCCR_OFFSET, reg); imxdpuv1_disp_setup_tcon_bypass_mode(imxdpuv1_id, disp, mode); /* save the mode */ imxdpu->video_mode[disp] = *mode; /* imxdpuv1_disp_dump_mode(&imxdpu->video_mode[disp]); */ return ret; } /*! * This function updates the frame generator status * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_update_fgen_status(int8_t imxdpuv1_id, int8_t disp) { int ret = 0; uint32_t b_off; /* block offset for frame generator */ uint32_t reg; uint32_t temp; struct imxdpuv1_soc *imxdpu; static uint32_t fcount[IMXDPUV1_NUM_DI_MAX] = { 0, 0 }; IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (disp == 0) { b_off = IMXDPUV1_FRAMEGEN0_LOCKUNLOCK; } else if (disp == 1) { b_off = IMXDPUV1_FRAMEGEN1_LOCKUNLOCK; } else { return -EINVAL; } /* todo: add video mode sanity check here check if LRSYNC is required */ reg = imxdpuv1_read_irq(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGTIMESTAMP_OFFSET); IMXDPUV1_TRACE_IRQ("DISP %d: findex %d, lindex %d\n", disp, IMXDPUV1_GET_FIELD (IMXDPUV1_FRAMEGEN0_FGTIMESTAMP_FRAMEINDEX, reg), IMXDPUV1_GET_FIELD (IMXDPUV1_FRAMEGEN0_FGTIMESTAMP_LINEINDEX, reg)); temp = IMXDPUV1_GET_FIELD(IMXDPUV1_FRAMEGEN0_FGTIMESTAMP_FRAMEINDEX, reg); if (temp != fcount[disp]) { fcount[disp] = temp; /* Just increment we assume this is called one per frame */ imxdpu->fgen_stats[disp].frame_count++; } reg = imxdpuv1_read_irq(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGCHSTAT_OFFSET); temp = IMXDPUV1_GET_FIELD(IMXDPUV1_FRAMEGEN0_FGCHSTAT_SECSYNCSTAT, reg); /* Sync status bits should be set */ if ((temp != imxdpu->fgen_stats[disp].sec_sync_state) && (temp == 1)) { imxdpu->fgen_stats[disp].sec_sync_count++; IMXDPUV1_TRACE_IRQ("DISP %d: sec in sync\n", disp); } if ((temp != imxdpu->fgen_stats[disp].sec_sync_state) && (temp == 0)) { IMXDPUV1_TRACE_IRQ("DISP %d: sec out of sync\n", disp); } imxdpu->fgen_stats[disp].sec_sync_state = temp; temp = IMXDPUV1_GET_FIELD(IMXDPUV1_FRAMEGEN0_FGCHSTAT_PRIMSYNCSTAT, reg); /* Sync status bits should be set */ if ((temp != imxdpu->fgen_stats[disp].prim_sync_state) && (temp == 1)) { imxdpu->fgen_stats[disp].prim_sync_count++; IMXDPUV1_TRACE_IRQ("DISP %d: prim in sync\n", disp); } if ((temp != imxdpu->fgen_stats[disp].prim_sync_state) && (temp == 0)) { IMXDPUV1_TRACE_IRQ("DISP %d: prim out of sync\n", disp); } imxdpu->fgen_stats[disp].prim_sync_state = temp; /* primary fifo bit should be clear if in use (panic stream) */ if (IMXDPUV1_GET_FIELD(IMXDPUV1_FRAMEGEN0_FGCHSTAT_PFIFOEMPTY, reg)) { IMXDPUV1_TRACE_IRQ("DISP %d: primary fifo empty\n", disp); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGCHSTATCLR_OFFSET, IMXDPUV1_FRAMEGEN0_FGCHSTATCLR_CLRPRIMSTAT_MASK); imxdpu->fgen_stats[disp].prim_fifo_empty_count++; } /* secondary fifo and skew error bits should be clear if in use (content stream) */ if (IMXDPUV1_GET_FIELD(IMXDPUV1_FRAMEGEN0_FGCHSTAT_SFIFOEMPTY, reg) || IMXDPUV1_GET_FIELD(IMXDPUV1_FRAMEGEN0_FGCHSTAT_SKEWRANGEERR, reg)) { if (IMXDPUV1_GET_FIELD(IMXDPUV1_FRAMEGEN0_FGCHSTAT_SFIFOEMPTY, reg)) { IMXDPUV1_TRACE_IRQ("DISP %d: secondary fifo empty\n", disp); imxdpu->fgen_stats[disp].sec_fifo_empty_count++; } if (IMXDPUV1_GET_FIELD (IMXDPUV1_FRAMEGEN0_FGCHSTAT_SKEWRANGEERR, reg)) { IMXDPUV1_TRACE_IRQ("DISP %d: secondary skew error\n", disp); imxdpu->fgen_stats[disp].skew_error_count++; } imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGCHSTATCLR_OFFSET, IMXDPUV1_FRAMEGEN0_FGCHSTATCLR_CLRSECSTAT_MASK); } return ret; } /*! * This function sets up the frame capture * * @param imxdpuv1_id id of the diplay unit * @param src_id id of the capture source block * @param dest_id id of the capture dest block * @param sync_count number of valid required to aquire sync * @param cap_mode mode of the video input * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_cap_setup_frame( int8_t imxdpuv1_id, int8_t src_id, int8_t dest_id, int8_t sync_count, const struct imxdpuv1_videomode *cap_mode) { #ifndef IMXDPUV1_VERSION_0 return -EINVAL; #else int ret = 0; uint32_t b_off_frame; /* block offset for capture source */ uint32_t b_off_extsrc; /* block offset for extsrc */ int8_t cap_id; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (src_id == IMXDPUV1_ID_FRAMECAP4) { cap_id = 0; b_off_frame = IMXDPUV1_FRAMECAP4_LOCKUNLOCK; b_off_extsrc = IMXDPUV1_EXTSRC4_LOCKUNLOCK; } else if (src_id == IMXDPUV1_ID_FRAMECAP5) { cap_id = 1; b_off_frame = IMXDPUV1_FRAMECAP5_LOCKUNLOCK; b_off_extsrc = IMXDPUV1_EXTSRC5_LOCKUNLOCK; } else if (src_id == IMXDPUV1_ID_FRAMEDUMP0) { cap_id = 0; b_off_frame = IMXDPUV1_FRAMEDUMP0_CONTROL; b_off_extsrc = IMXDPUV1_EXTSRC0_LOCKUNLOCK; } else if (src_id == IMXDPUV1_ID_FRAMEDUMP1) { cap_id = 1; b_off_frame = IMXDPUV1_FRAMEDUMP1_CONTROL; b_off_extsrc = IMXDPUV1_EXTSRC4_LOCKUNLOCK; } else { return -EINVAL; } if (dest_id == IMXDPUV1_ID_STORE4) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_DYNAMIC, IMXDPUV1_PIXENGCFG_STORE4_DYNAMIC_STORE4_SRC_SEL__EXTSRC4); } else if (dest_id == IMXDPUV1_ID_STORE5) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE5_DYNAMIC, IMXDPUV1_PIXENGCFG_STORE5_DYNAMIC_STORE5_SRC_SEL__EXTSRC5); } else if (dest_id == IMXDPUV1_ID_EXTDST0) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_DYNAMIC, IMXDPUV1_PIXENGCFG_EXTDST0_DYNAMIC_EXTDST0_SRC_SEL__EXTSRC4); } else if (dest_id == IMXDPUV1_ID_EXTDST1) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_DYNAMIC, IMXDPUV1_PIXENGCFG_EXTDST1_DYNAMIC_EXTDST1_SRC_SEL__EXTSRC5); } else { return -EINVAL; } imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_STATICCONTROL_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_STATICCONTROL_STARTSEL, IMXDPUV1_EXTSRC4_STATICCONTROL_STARTSEL__LOCAL) | IMXDPUV1_EXTSRC4_STATICCONTROL_SHDEN_MASK); imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_CONSTANTCOLOR_OFFSET, 0); if (cap_mode->format == IMXDPUV1_PIX_FMT_BGR24) { imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_COMPONENTBITSRED, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_COMPONENTBITSGREEN, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_COMPONENTBITSBLUE, 0x8)); imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_COMPONENTSHIFTRED, 0x10) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_COMPONENTSHIFTGREEN, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_COMPONENTSHIFTBLUE, 0x00)); /* fixme: handle all cases for control */ imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_CONTROL_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CONTROL_YUVCONVERSIONMODE, IMXDPUV1_EXTSRC4_CONTROL_YUVCONVERSIONMODE__ITU601) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CONTROL_RASTERMODE, IMXDPUV1_EXTSRC4_CONTROL_RASTERMODE__YUV422) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CONTROL_YUV422UPSAMPLINGMODE, IMXDPUV1_EXTSRC4_CONTROL_YUV422UPSAMPLINGMODE__REPLICATE) | IMXDPUV1_EXTSRC4_CONTROL_CLIPWINDOWENABLE_MASK); } else if (cap_mode->format == IMXDPUV1_PIX_FMT_YUYV) { imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_COMPONENTBITSRED, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_COMPONENTBITSGREEN, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTBITS_COMPONENTBITSBLUE, 0x8)); imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_COMPONENTSHIFTRED, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_COMPONENTSHIFTGREEN, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_COLORCOMPONENTSHIFT_COMPONENTSHIFTBLUE, 0x0)); /* fixme: handle all cases for control */ imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_CONTROL_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CONTROL_RASTERMODE, IMXDPUV1_EXTSRC4_CONTROL_RASTERMODE__YUV422) | IMXDPUV1_EXTSRC4_CONTROL_CLIPWINDOWENABLE_MASK); } else { IMXDPUV1_PRINT("%s(): invalid capture interface format\n", __func__); return -EINVAL; } if ((src_id == IMXDPUV1_ID_FRAMECAP4) || (src_id == IMXDPUV1_ID_FRAMECAP5)) { /* setup cature */ uint8_t capture_interface_mode; /* Fixme: change these mode bits to an enumeration */ if ((cap_mode->flags & IMXDPUV1_MODE_FLAGS_32BIT) != 0) { capture_interface_mode = IMXDPUV1_CAPENGCFG_CAPTUREINPUT1_CAPTUREMODE1__ENHSVS_32BIT; } else if ((cap_mode->flags & IMXDPUV1_MODE_FLAGS_BT656_10BIT) != 0) { capture_interface_mode = IMXDPUV1_CAPENGCFG_CAPTUREINPUT1_CAPTUREMODE1__ITU656_10BIT; } else if ((cap_mode->flags & IMXDPUV1_MODE_FLAGS_BT656_8BIT) != 0) { capture_interface_mode = IMXDPUV1_CAPENGCFG_CAPTUREINPUT1_CAPTUREMODE1__ITU656_8BIT; } else { return -EINVAL; } if (cap_id == 0) { imxdpuv1_write(imxdpu, IMXDPUV1_CAPENGCFG_CAPTUREINPUT0, IMXDPUV1_SET_FIELD(IMXDPUV1_CAPENGCFG_CAPTUREINPUT0_CAPTUREMODE0, capture_interface_mode)); } else { imxdpuv1_write(imxdpu, IMXDPUV1_CAPENGCFG_CAPTUREINPUT1, IMXDPUV1_SET_FIELD(IMXDPUV1_CAPENGCFG_CAPTUREINPUT1_CAPTUREMODE1, capture_interface_mode)); } imxdpuv1_write(imxdpu, b_off_frame + IMXDPUV1_FRAMECAP4_FDR_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_FDR_HEIGHT, cap_mode->vlen - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_FDR_WIDTH, cap_mode->hlen - 1)); imxdpuv1_write(imxdpu, b_off_frame + IMXDPUV1_FRAMECAP4_FDR1_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_FDR_HEIGHT, cap_mode->vlen1 - 1)); imxdpuv1_write(imxdpu, b_off_frame + IMXDPUV1_FRAMECAP4_SCR_OFFSET, sync_count); imxdpuv1_write(imxdpu, b_off_frame + IMXDPUV1_FRAMECAP4_KCR_OFFSET, 0); if ((cap_mode->clip_height != 0) && (cap_mode->clip_width != 0)) { imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_CLIPWINDOWDIMENSION_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWDIMENSION_CLIPWINDOWHEIGHT, cap_mode->clip_height - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWDIMENSION_CLIPWINDOWWIDTH, cap_mode->clip_width - 1)); imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_CLIPWINDOWOFFSET_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWOFFSET_CLIPWINDOWXOFFSET, cap_mode->clip_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWOFFSET_CLIPWINDOWYOFFSET, cap_mode->clip_top)); } imxdpuv1_write(imxdpu, b_off_frame + IMXDPUV1_FRAMECAP4_SPR_OFFSET, /* low is active low, high is active high */ IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_SPR_POLHS, ((cap_mode->flags & IMXDPUV1_MODE_FLAGS_HSYNC_POL) != 0)) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_SPR_POLVS, ((cap_mode->flags & IMXDPUV1_MODE_FLAGS_VSYNC_POL) != 0)) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_SPR_POLEN, ((cap_mode->flags & IMXDPUV1_MODE_FLAGS_DE_POL) == 0)) ); /* fixme: may need to move this mapping */ if (src_id == IMXDPUV1_ID_FRAMECAP4) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_DYNAMIC, IMXDPUV1_PIXENGCFG_STORE4_DYNAMIC_STORE4_SRC_SEL__EXTSRC4); } else if (src_id == IMXDPUV1_ID_FRAMECAP5) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE5_DYNAMIC, IMXDPUV1_PIXENGCFG_STORE5_DYNAMIC_STORE5_SRC_SEL__EXTSRC5); } } if ((src_id == IMXDPUV1_ID_FRAMEDUMP0) || (src_id == IMXDPUV1_ID_FRAMEDUMP1)) { /* todo */ } /* save the mode */ imxdpu->capture_mode[cap_id] = *cap_mode; /* imxdpuv1_disp_dump_mode(cap_mode); */ return ret; #endif } /*! * This function sets up the frame capture * * @param imxdpuv1_id id of the diplay unit * @param cap id of the capture inpute * @param sync_count number of valid required to aquire sync * @param cap_mode mode of the video input * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_cap_setup_crop( int8_t imxdpuv1_id, int8_t src_id, int16_t clip_top, int16_t clip_left, uint16_t clip_width, uint16_t clip_height) { #ifndef IMXDPUV1_VERSION_0 return -EINVAL; #else int ret = 0; uint32_t b_off_extsrc; /* block offset for extsrc */ #if 0 uint32_t b_off_dest; /* block offset for destination */ #endif int8_t cap_id; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (src_id == IMXDPUV1_ID_FRAMECAP4) { cap_id = 0; b_off_extsrc = IMXDPUV1_EXTSRC4_LOCKUNLOCK; } else if (src_id == IMXDPUV1_ID_FRAMECAP5) { cap_id = 1; b_off_extsrc = IMXDPUV1_EXTSRC5_LOCKUNLOCK; } else if (src_id == IMXDPUV1_ID_FRAMEDUMP0) { cap_id = 0; b_off_extsrc = IMXDPUV1_EXTSRC0_LOCKUNLOCK; } else if (src_id == IMXDPUV1_ID_FRAMEDUMP1) { cap_id = 1; b_off_extsrc = IMXDPUV1_EXTSRC4_LOCKUNLOCK; } else { return -EINVAL; } if ((src_id == IMXDPUV1_ID_FRAMECAP4) || (src_id == IMXDPUV1_ID_FRAMECAP5)) { if ((clip_height != 0) && (clip_width != 0)) { imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_CLIPWINDOWDIMENSION_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWDIMENSION_CLIPWINDOWHEIGHT, clip_height - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWDIMENSION_CLIPWINDOWWIDTH, clip_width - 1)); imxdpuv1_write(imxdpu, b_off_extsrc + IMXDPUV1_EXTSRC4_CLIPWINDOWOFFSET_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWOFFSET_CLIPWINDOWXOFFSET, clip_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_EXTSRC4_CLIPWINDOWOFFSET_CLIPWINDOWYOFFSET, clip_top)); /* save the clip data */ imxdpu->capture_mode[cap_id].clip_height = clip_height; imxdpu->capture_mode[cap_id].clip_width = clip_width; imxdpu->capture_mode[cap_id].clip_top = clip_top; imxdpu->capture_mode[cap_id].clip_left = clip_left; } } if ((src_id == IMXDPUV1_ID_FRAMEDUMP0) || (src_id == IMXDPUV1_ID_FRAMEDUMP1)) { /* todo */ } /* imxdpuv1_disp_dump_mode(&imxdpu->video_mode[cap_id]); */ return ret; #endif } /*! * This function enables the frame capture * * @param imxdpuv1_id id of the display unit * @param cap id of the capture output pipe * @param enable state to set frame generator to * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_cap_enable(int8_t imxdpuv1_id, int8_t cap, bool enable) { #ifndef IMXDPUV1_VERSION_0 return -EINVAL; #else int ret = 0; uint32_t b_off; uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (cap == 0) { b_off = IMXDPUV1_FRAMECAP4_LOCKUNLOCK; } else { return -EINVAL; } if (enable) { /* imxdpuv1_dump_pixencfg_status(imxdpuv1_id); */ printf("%s(): %s:%d stubbed feature\n", __func__, __FILE__, __LINE__); /* imxdpuv1_dump_pixencfg_status(imxdpuv1_id); */ } reg = enable ? IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_CTR_CEN, 1) : IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMECAP4_CTR_CEN, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMECAP4_CTR_OFFSET, reg); return ret; #endif } /*! * This function triggers a shadow load * * @param imxdpuv1_id id of the diplay unit * @param dest_id id of the capture dest block * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_cap_request_shadow_load(int8_t imxdpuv1_id, int8_t dest_id, uint32_t mask) { #ifndef IMXDPUV1_VERSION_0 return -EINVAL; #else int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; switch (dest_id) { case IMXDPUV1_ID_STORE4: imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_REQUEST, mask); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_TRIGGER, IMXDPUV1_PIXENGCFG_STORE4_TRIGGER_STORE4_SYNC_TRIGGER_MASK); break; case IMXDPUV1_ID_STORE5: imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE5_REQUEST, mask); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_STORE5_TRIGGER, IMXDPUV1_PIXENGCFG_STORE5_TRIGGER_STORE5_SYNC_TRIGGER_MASK); break; default: return -EINVAL; } return ret; #endif } /*! * This function requests a shadow loads * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * @param shadow_load_idx index of the shadow load requested * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_request_shadow_load(int8_t imxdpuv1_id, int8_t disp, imxdpuv1_shadow_load_index_t shadow_load_idx) { int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s(): imxdpuv1_id %d, disp %d, shadow_load_idx %d\n", __func__, imxdpuv1_id, disp, shadow_load_idx); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; /* trigger configuration of the pipeline */ if ((disp == 0) || (disp == 1)) { /* last request was complete or no request in progress, then start a new request */ if (imxdpu->shadow_load_state[disp][shadow_load_idx].word == 0) { imxdpu->shadow_load_state[disp][shadow_load_idx].state. request = IMXDPUV1_TRUE; } else { /* check ifg the request is busy */ IMXDPUV1_TRACE("%s(): shadow load not complete.", __func__); return -EBUSY; } } else { return -EINVAL; } return ret; } /*! * This function force a shadow loads * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * @param shadow_load_idx index of the shadow load requested * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_force_shadow_load(int8_t imxdpuv1_id, int8_t disp, uint64_t mask) { int ret = 0; uint32_t addr_extdst; /* address for extdst */ uint32_t addr_fgen; /* address for frame generator */ uint32_t extdst = 0; uint32_t fgen = 0; uint32_t sub = 0; struct imxdpuv1_soc *imxdpu; int i; uint64_t temp_mask; IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (!((disp == 0) || (disp == 1))) { return -EINVAL; } if (mask == 0) { return -EINVAL; } if (disp == 0) { addr_fgen = IMXDPUV1_FRAMEGEN0_FGSLR; addr_extdst = IMXDPUV1_PIXENGCFG_EXTDST0_REQUEST; } else if (disp == 1) { addr_fgen = IMXDPUV1_FRAMEGEN1_FGSLR; addr_extdst = IMXDPUV1_PIXENGCFG_EXTDST1_REQUEST; } else { return -EINVAL; } for (i = 0; i < IMXDPUV1_SHDLD_IDX_MAX; i++) { temp_mask = 1 << i; if ((mask & temp_mask) == 0) continue; extdst |= trigger_list[i].extdst; sub |= trigger_list[i].sub; if ((i == IMXDPUV1_SHDLD_IDX_CONST0) || (i == IMXDPUV1_SHDLD_IDX_CONST1)) { fgen |= 1; } mask &= ~temp_mask; } if (sub) { IMXDPUV1_TRACE_IRQ("Fetch layer shadow request 0x%08x\n", sub); if (sub & 0xff) { /* FETCHLAYER0 */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER0_TRIGGERENABLE, sub & 0xff); } #ifdef IMXDPUV1_VERSION_0 if (sub & 0xff00) { /* FETCHLAYER1 */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHLAYER1_TRIGGERENABLE, (sub >> 8) & 0xff); } #endif if (sub & 0xff0000) { /* FETCHWARP2 */ imxdpuv1_write(imxdpu, IMXDPUV1_FETCHWARP2_TRIGGERENABLE, (sub >> 16) & 0xff); } } if (extdst) { IMXDPUV1_TRACE_IRQ("Extdst shadow request 0x%08x\n", extdst); imxdpuv1_write(imxdpu, addr_extdst, extdst); } if (fgen) { IMXDPUV1_TRACE_IRQ("Fgen shadow request 0x%08x\n", fgen); imxdpuv1_write(imxdpu, addr_fgen, fgen); } return ret; } /*! * This function shows the frame generators status * * @param imxdpuv1_id id of the diplay unit * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_show_fgen_status(int8_t imxdpuv1_id) { #ifndef ENABLE_IMXDPUV1_TRACE return 0; #else int ret = 0; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; IMXDPUV1_PRINT("IMXDPU %d stat fg0 fg1\n" "prim_sync_state: %10d %10d\n" "sec_sync_state: %10d %10d\n" "prim_sync_count: %10d %10d\n" "sec_sync_count: %10d %10d\n" "skew_error_count: %10d %10d\n" "prim_fifo_empty_count: %10d %10d\n" "sec_fifo_empty_count: %10d %10d\n" "frame_count: %10d %10d\n" "irq_count: %10u\n\n", imxdpuv1_id, imxdpu->fgen_stats[0].prim_sync_state, imxdpu->fgen_stats[1].prim_sync_state, imxdpu->fgen_stats[0].sec_sync_state, imxdpu->fgen_stats[1].sec_sync_state, imxdpu->fgen_stats[0].prim_sync_count, imxdpu->fgen_stats[1].prim_sync_count, imxdpu->fgen_stats[0].sec_sync_count, imxdpu->fgen_stats[1].sec_sync_count, imxdpu->fgen_stats[0].skew_error_count, imxdpu->fgen_stats[1].skew_error_count, imxdpu->fgen_stats[0].prim_fifo_empty_count, imxdpu->fgen_stats[1].prim_fifo_empty_count, imxdpu->fgen_stats[0].sec_fifo_empty_count, imxdpu->fgen_stats[1].sec_fifo_empty_count, imxdpu->fgen_stats[0].frame_count, imxdpu->fgen_stats[1].frame_count, imxdpu->irq_count); return ret; #endif } /*! * This function enables the frame generator * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * @param enable state to set frame generator to * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_enable_frame_gen(int8_t imxdpuv1_id, int8_t disp, bool enable) { int ret = 0; uint32_t b_off; uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (disp == 0) { b_off = IMXDPUV1_FRAMEGEN0_LOCKUNLOCK; } else if (disp == 1) { b_off = IMXDPUV1_FRAMEGEN1_LOCKUNLOCK; } else { return -EINVAL; } imxdpuv1_disp_start_shadow_loads(imxdpuv1_id, disp); reg = enable ? IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGENABLE_FGEN, 1) : IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEGEN0_FGENABLE_FGEN, 0); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FRAMEGEN0_FGENABLE_OFFSET, reg); return ret; } /*! * This function sets up the constframe generator * * @param imxdpuv1_id id of the diplay unit * @param disp id of the diplay output pipe * @param bg_red background red * @param bg_green background green * @param bg_blue background blue * @param bg_alpha background alpha * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_setup_constframe( int8_t imxdpuv1_id, int8_t disp, uint8_t bg_red, uint8_t bg_green, uint8_t bg_blue, uint8_t bg_alpha) { int ret = 0; uint32_t b_off; uint32_t reg; struct imxdpuv1_soc *imxdpu; imxdpuv1_shadow_load_index_t shadow_idx; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; /* todo: add constfram4 and constframe5 */ if (disp == 0) { b_off = IMXDPUV1_CONSTFRAME0_LOCKUNLOCK; shadow_idx = IMXDPUV1_SHDLD_IDX_CONST0; } else if (disp == 1) { b_off = IMXDPUV1_CONSTFRAME1_LOCKUNLOCK; shadow_idx = IMXDPUV1_SHDLD_IDX_CONST1; } else { return -EINVAL; } if (imxdpu->video_mode[disp].flags & IMXDPUV1_MODE_FLAGS_LRSYNC) { /* todo: need to handle sync display case */ } reg = IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEHEIGHT, imxdpu->video_mode[disp].vlen - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEWIDTH, imxdpu->video_mode[disp].hlen - 1); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_CONSTFRAME0_FRAMEDIMENSIONS_OFFSET, reg); /* todo: add linear light correction if needed */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_CONSTFRAME0_CONSTANTCOLOR_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_CONSTRED, bg_red) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_CONSTGREEN, bg_green) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_CONSTBLUE, bg_blue) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_CONSTALPHA, bg_alpha)); imxdpuv1_disp_request_shadow_load(imxdpuv1_id, disp, shadow_idx); /* todo: add linear light correction if needed */ return ret; } /*! * This function sets up a layer * * @param imxdpuv1_id id of the diplay unit * @param layer layer data to use * @param layer_idx layer index to use * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_setup_layer(int8_t imxdpuv1_id, const imxdpuv1_layer_t *layer, imxdpuv1_layer_idx_t layer_idx, bool is_top_layer) { int ret = 0; uint32_t dynamic_offset; uint32_t static_offset; uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; IMXDPUV1_TRACE("%s(): enable %d, primary %d, secondary %d, stream 0x%08x\n", __func__, layer->enable, layer->primary, layer->secondary, layer->stream); imxdpu->blend_layer[layer_idx] = *layer; dynamic_offset = id2dynamicoffset(layer_idx + IMXDPUV1_ID_LAYERBLEND0); if (dynamic_offset == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } static_offset = id2blockoffset(layer_idx + IMXDPUV1_ID_LAYERBLEND0); if (static_offset == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } reg = IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_LAYERBLEND0_DYNAMIC_LAYERBLEND0_PRIM_SEL, imxdpu->blend_layer[layer_idx].primary) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND0_DYNAMIC_LAYERBLEND0_SEC_SEL, imxdpu->blend_layer[layer_idx].secondary) | IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_LAYERBLEND0_DYNAMIC_LAYERBLEND0_CLKEN, IMXDPUV1_PIXENGCFG_LAYERBLEND0_DYNAMIC_LAYERBLEND0_CLKEN__AUTOMATIC); imxdpuv1_write(imxdpu, dynamic_offset, reg); if (imxdpu->blend_layer[layer_idx].stream & IMXDPUV1_DISPLAY_STREAM_0) { IMXDPUV1_TRACE("%s(): IMXDPUV1_DISPLAY_STREAM_0\n", __func__); if (is_top_layer) { reg = IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_EXTDST0_DYNAMIC_EXTDST0_SRC_SEL, layer_idx + IMXDPUV1_ID_LAYERBLEND0); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_DYNAMIC, reg); } /* trigger configuration of the pipeline */ imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_TRIGGER, IMXDPUV1_PIXENGCFG_EXTDST0_TRIGGER_EXTDST0_SYNC_TRIGGER_MASK); imxdpuv1_disp_request_shadow_load(imxdpuv1_id, 0, IMXDPUV1_SHDLD_IDX_DISP0); } if (imxdpu->blend_layer[layer_idx].stream & IMXDPUV1_DISPLAY_STREAM_1) { IMXDPUV1_TRACE_IRQ("%s(): IMXDPUV1_DISPLAY_STREAM_1\n", __func__); if (is_top_layer) { reg = IMXDPUV1_SET_FIELD(IMXDPUV1_PIXENGCFG_EXTDST0_DYNAMIC_EXTDST0_SRC_SEL, layer_idx + IMXDPUV1_ID_LAYERBLEND0); imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_DYNAMIC, reg); } /* trigger configuration of the pipeline */ imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_TRIGGER, IMXDPUV1_PIXENGCFG_EXTDST1_TRIGGER_EXTDST1_SYNC_TRIGGER_MASK); imxdpuv1_disp_request_shadow_load(imxdpuv1_id, 1, IMXDPUV1_SHDLD_IDX_DISP1); } /* todo: add code to disable a layer */ return ret; } /*! * This function sets global alpha for a blend layer * * @param imxdpuv1_id id of the diplay unit * @param layer_idx layer index to use * @param alpha global alpha * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_set_layer_global_alpha(int8_t imxdpuv1_id, imxdpuv1_layer_idx_t layer_idx, uint8_t alpha) { int ret = 0; uint32_t offset; uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; /* update imxdpu */ offset = id2blockoffset(layer_idx + IMXDPUV1_ID_LAYERBLEND0); if (offset == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } reg = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_BLENDCONTROL_BLENDALPHA, alpha) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_BLENDCONTROL_PRIM_C_BLD_FUNC, IMXDPUV1_LAYERBLEND0_BLENDCONTROL_PRIM_C_BLD_FUNC__ONE_MINUS_SEC_ALPHA) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_BLENDCONTROL_SEC_C_BLD_FUNC, IMXDPUV1_LAYERBLEND0_BLENDCONTROL_SEC_C_BLD_FUNC__CONST_ALPHA) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_BLENDCONTROL_PRIM_A_BLD_FUNC, IMXDPUV1_LAYERBLEND0_BLENDCONTROL_PRIM_A_BLD_FUNC__ONE_MINUS_SEC_ALPHA) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_BLENDCONTROL_SEC_A_BLD_FUNC, IMXDPUV1_LAYERBLEND0_BLENDCONTROL_SEC_A_BLD_FUNC__ONE); imxdpuv1_write(imxdpu, offset + IMXDPUV1_LAYERBLEND0_BLENDCONTROL_OFFSET, reg); reg = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_CONTROL_MODE, IMXDPUV1_LAYERBLEND0_CONTROL_MODE__BLEND) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_CONTROL_ALPHAMASKENABLE, IMXDPUV1_DISABLE); imxdpuv1_write(imxdpu, offset + IMXDPUV1_LAYERBLEND0_CONTROL_OFFSET, reg); return ret; } /*! * This function sets the position of the a blend layer secondary input * * @param imxdpuv1_id id of the diplay unit * @param layer_idx layer index to use * @param x x position * @param y y position * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_set_layer_position(int8_t imxdpuv1_id, imxdpuv1_layer_idx_t layer_idx, int16_t x, int16_t y) { int ret = 0; uint32_t offset; uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; /* update imxdpu */ offset = id2blockoffset(layer_idx + IMXDPUV1_ID_LAYERBLEND0); if (offset == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } reg = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_POSITION_XPOS, x) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERBLEND0_POSITION_YPOS, y); imxdpuv1_write(imxdpu, offset + IMXDPUV1_LAYERBLEND0_POSITION_OFFSET, reg); return ret; } /*! * This function sets the position of the a channel (window) layer * * @param imxdpuv1_id id of the diplay unit * @param layer_idx layer index to use * @param x x position * @param y y position * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_set_chan_position(int8_t imxdpuv1_id, imxdpuv1_chan_t chan, int16_t x, int16_t y) { int ret = 0; uint32_t offset; int idx; int sub_idx; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; /* update imxdpu */ offset = id2blockoffset(get_channel_blk(chan)); if (offset == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } idx = get_channel_idx(chan); if ((idx >= IMXDPUV1_CHAN_IDX_IN_MAX) || (idx < 0)) { return -EINVAL; } sub_idx = imxdpuv1_get_channel_subindex(chan); imxdpu->chan_data[idx].dest_top = y; imxdpu->chan_data[idx].dest_left = x; imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0 = IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE0_LAYEROFFSET0_LAYERXOFFSET0, imxdpu->chan_data[idx].dest_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE0_LAYEROFFSET0_LAYERYOFFSET0, imxdpu->chan_data[idx].dest_top); if (is_fetch_layer_chan(chan) || is_fetch_warp_chan(chan)) { IMXDPUV1_TRACE("%s(): fetch layer or warp\n", __func__); imxdpuv1_write(imxdpu, offset + IMXDPUV1_FETCHLAYER0_LAYEROFFSET0_OFFSET + ((IMXDPUV1_SUBCHAN_LAYER_OFFSET * sub_idx)), imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0); } else if (is_fetch_decode_chan(chan)) { if (imxdpu->chan_data[idx].use_eco_fetch) { imxdpuv1_disp_set_chan_position(imxdpuv1_id, imxdpuv1_get_eco(chan), x, y); } imxdpuv1_write(imxdpu, offset + IMXDPUV1_FETCHDECODE0_LAYEROFFSET0_OFFSET, imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0); } else if (is_fetch_eco_chan(chan)) { imxdpuv1_write(imxdpu, offset + IMXDPUV1_FETCHECO0_LAYEROFFSET0_OFFSET, imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0); } else { return -EINVAL; } imxdpuv1_disp_request_shadow_load(imxdpuv1_id, imxdpu->chan_data[idx].disp_id, IMXDPUV1_SHDLD_IDX_CHAN_00 + idx); return ret; } /*! * This function sets the source and destination crop * position of the a channel (window) layer * * @param imxdpuv1_id id of the diplay unit * @param chan chan to use * @param clip_top source y position * @param clip_left source x position * @param clip_width source width * @param clip_height source height * @param dest_top destination y * @param dest_left destination x * @param dest_width destination width * @param dest_height destination height * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_set_chan_crop( int8_t imxdpuv1_id, imxdpuv1_chan_t chan, int16_t clip_top, int16_t clip_left, uint16_t clip_width, uint16_t clip_height, int16_t dest_top, int16_t dest_left, uint16_t dest_width, uint16_t dest_height) { int ret = 0; uint32_t offset; int idx; int sub_idx; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; offset = id2blockoffset(get_channel_blk(chan)); if (offset == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } idx = get_channel_idx(chan); if ((idx >= IMXDPUV1_CHAN_IDX_IN_MAX) || (idx < 0)) { return -EINVAL; } if ((imxdpu->chan_data[idx].clip_height < 0) || (imxdpu->chan_data[idx].clip_width < 0)) { return -EINVAL; } sub_idx = imxdpuv1_get_channel_subindex(chan); imxdpu->chan_data[idx].dest_top = dest_top; imxdpu->chan_data[idx].dest_left = dest_left; imxdpu->chan_data[idx].dest_width = IMXDPUV1_MIN(dest_width, clip_width); imxdpu->chan_data[idx].dest_height = IMXDPUV1_MIN(dest_height, clip_height); imxdpu->chan_data[idx].clip_top = clip_top; imxdpu->chan_data[idx].clip_left = clip_left; imxdpu->chan_data[idx].clip_width = IMXDPUV1_MIN(dest_width, clip_width); imxdpu->chan_data[idx].clip_height = IMXDPUV1_MIN(dest_height, clip_height); /* Need to check more cases here */ if ((imxdpu->chan_data[idx].clip_height != 0) && (imxdpu->chan_data[idx].clip_width != 0)) { imxdpu->chan_data[idx].fetch_layer_prop.layerproperty0 |= IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_CLIPWINDOWENABLE, IMXDPUV1_ENABLE); imxdpu->chan_data[idx].fetch_layer_prop.clipwindowdimensions0 = IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_HEIGHT, imxdpu->chan_data[idx].clip_height - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_WIDTH, imxdpu->chan_data[idx].clip_width - 1); } else { imxdpu->chan_data[idx].fetch_layer_prop.layerproperty0 &= ~IMXDPUV1_LAYERPROPERTY_CLIPWINDOWENABLE_MASK; imxdpu->chan_data[idx].fetch_layer_prop.clipwindowdimensions0 = 0; } imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0 = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYER_XOFFSET, imxdpu->chan_data[idx].dest_left - imxdpu->chan_data[idx].clip_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYER_YOFFSET, imxdpu->chan_data[idx].dest_top - imxdpu->chan_data[idx].clip_top); imxdpu->chan_data[idx].fetch_layer_prop.clipwindowoffset0 = IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_XOFFSET, imxdpu->chan_data[idx].dest_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_YOFFSET, imxdpu->chan_data[idx].dest_top); if (is_fetch_layer_chan(chan) || is_fetch_warp_chan(chan)) { imxdpuv1_write_block(imxdpu, offset + IMXDPUV1_FETCHLAYER0_LAYEROFFSET0_OFFSET + ((IMXDPUV1_SUBCHAN_LAYER_OFFSET * sub_idx)), (void *)&imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0, 5); } else if (is_fetch_decode_chan(chan)) { if (imxdpu->chan_data[idx].use_eco_fetch) { imxdpuv1_disp_set_chan_crop(imxdpuv1_id, imxdpuv1_get_eco(chan), clip_top, clip_left, clip_width, clip_height, dest_top, dest_left, dest_width, dest_height); } imxdpuv1_write_block(imxdpu, offset + IMXDPUV1_FETCHDECODE0_LAYEROFFSET0_OFFSET, (void *)&imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0, 5); } else if (is_fetch_eco_chan(chan)) { imxdpuv1_write_block(imxdpu, offset + IMXDPUV1_FETCHECO0_LAYEROFFSET0_OFFSET, (void *)&imxdpu->chan_data[idx].fetch_layer_prop.layeroffset0, 5); } else { return -EINVAL; } imxdpuv1_disp_request_shadow_load(imxdpuv1_id, imxdpu->chan_data[idx].disp_id, IMXDPUV1_SHDLD_IDX_CHAN_00 + idx); return ret; } /*! * This function sets initializes a channel and buffer * * @param imxdpuv1_id id of the diplay unit * @param chan chan to use * @param src_pixel_fmt source pixel format * @param clip_top source y position * @param clip_left source x position * @param clip_width source width * @param clip_height source height * @param stride stride of the buffer * @param disp_id display id * @param dest_top destination y * @param dest_left destination x * @param dest_width destination width * @param dest_height destination height * @param const_color constant color for clip region * @param disp_addr display buffer physical address * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_disp_setup_channel(int8_t imxdpuv1_id, imxdpuv1_chan_t chan, uint32_t src_pixel_fmt, uint16_t src_width, uint16_t src_height, int16_t clip_top, int16_t clip_left, uint16_t clip_width, uint16_t clip_height, uint16_t stride, uint8_t disp_id, int16_t dest_top, int16_t dest_left, uint16_t dest_width, uint16_t dest_height, uint32_t const_color, bool use_global_alpha, bool use_local_alpha, unsigned int disp_addr) { int ret = 0; imxdpuv1_channel_params_t channel; uint32_t uv_offset = 0; IMXDPUV1_TRACE("%s(): " "imxdpuv1_id %d\n" "chan_t chan %x\n" "src_pixel_fmt 0x%x\n" "src_width %d\n" "src_height %d\n" "clip_top %d\n" "clip_left %d\n" "clip_width %d\n" "clip_height %d\n" "stride %d\n" "disp_id %d\n" "dest_top %d\n" "dest_left %d\n" "dest_width %d\n" "dest_height %d\n" "const_color 0x%x\n" "disp_addr 0x%x\n", __func__, imxdpuv1_id, chan, src_pixel_fmt, src_width, src_height, clip_top, clip_left, clip_width, clip_height, stride, disp_id, dest_top, dest_left, dest_width, dest_height, const_color, disp_addr); channel.common.chan = chan; channel.common.src_pixel_fmt = src_pixel_fmt; channel.common.src_width = src_width; channel.common.src_height = src_height; channel.common.clip_top = clip_top; channel.common.clip_left = clip_left; channel.common.clip_width = clip_width; channel.common.clip_height = clip_height; channel.common.stride = stride; channel.common.disp_id = disp_id; channel.common.dest_top = dest_top; channel.common.dest_left = dest_left; channel.common.dest_width = dest_width; channel.common.dest_height = dest_height; channel.common.const_color = const_color; channel.common.use_global_alpha = use_global_alpha; channel.common.use_local_alpha = use_local_alpha; if (imxdpuv1_get_planes(src_pixel_fmt) == 2) { uv_offset = src_width * src_height; /* works for NV12 and NV16*/ } ret = imxdpuv1_init_channel(imxdpuv1_id, &channel); ret = imxdpuv1_init_channel_buffer(imxdpuv1_id, channel.common.chan, channel.common.stride, IMXDPUV1_ROTATE_NONE, disp_addr, uv_offset, 0); ret = imxdpuv1_disp_set_chan_crop(imxdpuv1_id, channel.common.chan, channel.common.clip_top, channel.common.clip_left, channel.common.clip_width, channel.common.clip_height, channel.common.dest_top, channel.common.dest_left, channel.common.dest_width, channel.common.dest_height); #ifdef DEBUG { imxdpuv1_chan_t eco_chan; imxdpuv1_dump_channel(imxdpuv1_id, channel.common.chan); eco_chan = imxdpuv1_get_eco(channel.common.chan); if (eco_chan != 0) { imxdpuv1_dump_channel(imxdpuv1_id, eco_chan); } } #endif return ret; } /*! * This function prints the video mode passed as a parameter * * @param *mode pointer to video mode struct to show */ void imxdpuv1_disp_dump_mode(const struct imxdpuv1_videomode *mode) { IMXDPUV1_PRINT("%s():\n", __func__); IMXDPUV1_PRINT("\thlen %4d\n", mode->hlen); IMXDPUV1_PRINT("\thfp %4d\n", mode->hfp); IMXDPUV1_PRINT("\thbp %4d\n", mode->hbp); IMXDPUV1_PRINT("\thsync %4d\n", mode->hsync); IMXDPUV1_PRINT("\tvlen %4d\n", mode->vlen); IMXDPUV1_PRINT("\tvfp %4d\n", mode->vfp); IMXDPUV1_PRINT("\tvbp %4d\n", mode->vbp); IMXDPUV1_PRINT("\tvsync %4d\n", mode->vsync); IMXDPUV1_PRINT("\tvlen1 %4d\n", mode->vlen1); IMXDPUV1_PRINT("\tvfp1 %4d\n", mode->vfp1); IMXDPUV1_PRINT("\tvbp1 %4d\n", mode->vbp1); IMXDPUV1_PRINT("\tvsync1 %4d\n", mode->vsync1); IMXDPUV1_PRINT("\tflags 0x%08x:\n", mode->flags); if (mode->flags & IMXDPUV1_MODE_FLAGS_HSYNC_POL) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_HSYNC_POL is high\n"); else IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_HSYNC_POL is low\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_VSYNC_POL) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_VSYNC_POL is high\n"); else IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_VSYNC_POL is low\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_DE_POL) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_DE_POL is high\n"); else IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_DE_POL is low\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_INTERLACED) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_INTERLACED is set\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_LRSYNC) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_LRSYNC is set\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_SPLIT) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_SPLIT is set\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_32BIT) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_32BIT is set\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_BT656_10BIT) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_BT656_10BIT is set\n"); if (mode->flags & IMXDPUV1_MODE_FLAGS_BT656_8BIT) IMXDPUV1_PRINT("\t\tIMXDPUV1_MODE_FLAGS_BT656_8BIT is set\n"); } /*! * Returns the bytes per pixel * * @param pixel format * * @return returns number of bytes per pixel or zero * if the format is not matched. */ int imxdpuv1_bytes_per_pixel(uint32_t fmt) { IMXDPUV1_TRACE("%s():\n", __func__); switch (fmt) { /* todo add NV12, and NV16 */ case IMXDPUV1_PIX_FMT_NV12: return 1; /* luma */ case IMXDPUV1_PIX_FMT_RGB565: case IMXDPUV1_PIX_FMT_YUYV: case IMXDPUV1_PIX_FMT_UYVY: return 2; break; case IMXDPUV1_PIX_FMT_BGR24: case IMXDPUV1_PIX_FMT_RGB24: case IMXDPUV1_PIX_FMT_YUV444: return 3; break; case IMXDPUV1_PIX_FMT_GENERIC_32: case IMXDPUV1_PIX_FMT_BGR32: case IMXDPUV1_PIX_FMT_BGRA32: case IMXDPUV1_PIX_FMT_RGB32: case IMXDPUV1_PIX_FMT_RGBA32: case IMXDPUV1_PIX_FMT_ABGR32: case IMXDPUV1_PIX_FMT_AYUV: return 4; break; default: IMXDPUV1_TRACE("%s(): unsupported pixel format", __func__); return 0; } } /*! * Returns the number of bits per color component for the color * component bits register * * @param pixel format * * @return Returns the number of bits per color component for * the color component bits register. */ uint32_t imxdpuv1_get_colorcomponentbits(uint32_t fmt) { IMXDPUV1_TRACE("%s():\n", __func__); switch (fmt) { /* todo add NV12, NV16, YUYV, and UYVY */ case IMXDPUV1_PIX_FMT_YUYV: case IMXDPUV1_PIX_FMT_UYVY: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSRED0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSGREEN0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSBLUE0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSALPHA0, 0x00); case IMXDPUV1_PIX_FMT_NV12: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSRED0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSGREEN0, 0x00) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSBLUE0, 0x00) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSALPHA0, 0x00); case IMXDPUV1_PIX_FMT_RGB565: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSRED0, 0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSGREEN0, 5) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSBLUE0, 11) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSALPHA0, 0); case IMXDPUV1_PIX_FMT_BGR24: case IMXDPUV1_PIX_FMT_RGB24: case IMXDPUV1_PIX_FMT_YUV444: case IMXDPUV1_PIX_FMT_BGR32: case IMXDPUV1_PIX_FMT_RGB32: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSRED0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSGREEN0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSBLUE0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSALPHA0, 0x0); case IMXDPUV1_PIX_FMT_GENERIC_32: case IMXDPUV1_PIX_FMT_BGRA32: case IMXDPUV1_PIX_FMT_RGBA32: case IMXDPUV1_PIX_FMT_ABGR32: case IMXDPUV1_PIX_FMT_ARGB32: case IMXDPUV1_PIX_FMT_AYUV: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSRED0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSGREEN0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSBLUE0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSALPHA0, 0x08); default: IMXDPUV1_TRACE("%s(): unsupported pixel format 0x%08x", __func__, fmt); return 0; } return 0; } /*! * Returns the number of planes for the pixel format * * @param pixel format * * @return returns number of bytes per pixel or zero * if the format is not matched. */ uint32_t imxdpuv1_get_planes(uint32_t fmt) { IMXDPUV1_TRACE("%s():\n", __func__); switch (fmt) { case IMXDPUV1_PIX_FMT_NV16: case IMXDPUV1_PIX_FMT_NV12: return 2; case IMXDPUV1_PIX_FMT_RGB565: case IMXDPUV1_PIX_FMT_YUYV: case IMXDPUV1_PIX_FMT_UYVY: case IMXDPUV1_PIX_FMT_BGRA32: case IMXDPUV1_PIX_FMT_RGBA32: case IMXDPUV1_PIX_FMT_ABGR32: case IMXDPUV1_PIX_FMT_AYUV: case IMXDPUV1_PIX_FMT_BGR24: case IMXDPUV1_PIX_FMT_RGB24: case IMXDPUV1_PIX_FMT_YUV444: case IMXDPUV1_PIX_FMT_BGR32: case IMXDPUV1_PIX_FMT_RGB32: case IMXDPUV1_PIX_FMT_ARGB32: return 1; default: return 0; IMXDPUV1_TRACE("%s(): unsupported pixel format", __func__); } } /*! * Returns the color component bit position shifts * * @param pixel format * * @return returns the register setting for the * colorcomponentshift register * */ uint32_t imxdpuv1_get_colorcomponentshift(uint32_t fmt) { IMXDPUV1_TRACE("%s():\n", __func__); switch (fmt) { case IMXDPUV1_PIX_FMT_NV12: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x0); case IMXDPUV1_PIX_FMT_RGB565: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 5) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 6) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 5) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0); case IMXDPUV1_PIX_FMT_YUYV: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x0); case IMXDPUV1_PIX_FMT_UYVY: return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x0); case IMXDPUV1_PIX_FMT_BGR24: case IMXDPUV1_PIX_FMT_BGR32: case IMXDPUV1_PIX_FMT_BGRA32: /* 0xaaRRGGBB */ return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x10) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x00) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x18); case IMXDPUV1_PIX_FMT_AYUV: /* 0xVVUUYYAA */ return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x10) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x18) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x00); case IMXDPUV1_PIX_FMT_ABGR32: /* 0xRRGGBBAA */ return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x18) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x10) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x00); case IMXDPUV1_PIX_FMT_ARGB32: /* 0xBBGGRRAA */ return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x10) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x18) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x00); case IMXDPUV1_PIX_FMT_GENERIC_32: case IMXDPUV1_PIX_FMT_RGB24: case IMXDPUV1_PIX_FMT_YUV444: case IMXDPUV1_PIX_FMT_RGB32: case IMXDPUV1_PIX_FMT_RGBA32: /* 0xaaBBGGRR or 0xaaUUVVYY */ return IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x00) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x08) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x10) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x18); default: return 0; IMXDPUV1_TRACE("%s(): unsupported pixel format", __func__); } } /*! * Returns true is the format has local alpha * * @param pixel format * * @return Returns true is the format has local alpha */ uint32_t imxdpuv1_has_localalpha(uint32_t fmt) { IMXDPUV1_TRACE("%s():\n", __func__); switch (fmt) { case IMXDPUV1_PIX_FMT_BGRA32: case IMXDPUV1_PIX_FMT_AYUV: case IMXDPUV1_PIX_FMT_RGBA32: return IMXDPUV1_TRUE; default: return IMXDPUV1_FALSE; } } /*! * Returns the bits per pixel * * @param pixel format * * @return returns number of bits per pixel or zero * if the format is not matched. */ int imxdpuv1_bits_per_pixel(uint32_t fmt) { int ret = 0; switch (fmt) { case IMXDPUV1_PIX_FMT_NV12: ret = 8; break; case IMXDPUV1_PIX_FMT_NV16: case IMXDPUV1_PIX_FMT_RGB565: case IMXDPUV1_PIX_FMT_YUYV: case IMXDPUV1_PIX_FMT_UYVY: case IMXDPUV1_PIX_FMT_YVYU: ret = 16; break; case IMXDPUV1_PIX_FMT_BGR24: case IMXDPUV1_PIX_FMT_RGB24: case IMXDPUV1_PIX_FMT_YUV444: ret = 24; break; case IMXDPUV1_PIX_FMT_GENERIC_32: case IMXDPUV1_PIX_FMT_BGR32: case IMXDPUV1_PIX_FMT_BGRA32: case IMXDPUV1_PIX_FMT_RGB32: case IMXDPUV1_PIX_FMT_RGBA32: case IMXDPUV1_PIX_FMT_ABGR32: case IMXDPUV1_PIX_FMT_ARGB32: case IMXDPUV1_PIX_FMT_AYUV: ret = 32; break; default: IMXDPUV1_TRACE("%s(): unsupported pixel format\n", __func__); ret = 1; break; } IMXDPUV1_TRACE("%s(): fmt 0x%08x, ret %d\n", __func__, fmt, ret); return ret; } /*! * Tests for YUV * * @param pixel format * * @return returns true if the format is YUV. */ static bool imxdpuv1_is_yuv(uint32_t fmt) { int ret = IMXDPUV1_FALSE; switch (fmt) { case IMXDPUV1_PIX_FMT_AYUV: case IMXDPUV1_PIX_FMT_NV12: case IMXDPUV1_PIX_FMT_NV16: case IMXDPUV1_PIX_FMT_YUYV: case IMXDPUV1_PIX_FMT_UYVY: case IMXDPUV1_PIX_FMT_YUV444: ret = IMXDPUV1_TRUE; break; case IMXDPUV1_PIX_FMT_GENERIC_32: case IMXDPUV1_PIX_FMT_BGR32: case IMXDPUV1_PIX_FMT_BGRA32: case IMXDPUV1_PIX_FMT_RGB32: case IMXDPUV1_PIX_FMT_RGBA32: case IMXDPUV1_PIX_FMT_ABGR32: case IMXDPUV1_PIX_FMT_ARGB32: case IMXDPUV1_PIX_FMT_RGB565: case IMXDPUV1_PIX_FMT_BGR24: case IMXDPUV1_PIX_FMT_RGB24: ret = IMXDPUV1_FALSE; break; default: IMXDPUV1_TRACE("%s(): unsupported pixel format", __func__); ret = IMXDPUV1_FALSE; break; } IMXDPUV1_TRACE("%s(): fmt 0x%08x, ret %d\n", __func__, fmt, ret); return ret; } /*! * Tests for RGB formats * * @param pixel format * * @return returns true if the format is any supported RGB */ bool imxdpuv1_is_rgb(uint32_t fmt) { int ret = IMXDPUV1_FALSE; switch (fmt) { case IMXDPUV1_PIX_FMT_AYUV: case IMXDPUV1_PIX_FMT_NV12: case IMXDPUV1_PIX_FMT_NV16: case IMXDPUV1_PIX_FMT_YUYV: case IMXDPUV1_PIX_FMT_UYVY: case IMXDPUV1_PIX_FMT_YUV444: case IMXDPUV1_PIX_FMT_GENERIC_32: ret = IMXDPUV1_FALSE; break; case IMXDPUV1_PIX_FMT_BGR32: case IMXDPUV1_PIX_FMT_BGRA32: case IMXDPUV1_PIX_FMT_RGB32: case IMXDPUV1_PIX_FMT_RGBA32: case IMXDPUV1_PIX_FMT_ABGR32: case IMXDPUV1_PIX_FMT_ARGB32: case IMXDPUV1_PIX_FMT_RGB565: case IMXDPUV1_PIX_FMT_BGR24: case IMXDPUV1_PIX_FMT_RGB24: ret = IMXDPUV1_TRUE; break; default: IMXDPUV1_TRACE("%s(): unsupported pixel format", __func__); ret = IMXDPUV1_FALSE; break; } IMXDPUV1_TRACE("%s(): fmt 0x%08x, ret %d\n", __func__, fmt, ret); return ret; } /*! * Intializes buffers to be used for a channel * * @param imxdpuv1_id id of the diplay unit * @param chan channel to use for this buffer * @param stride total width in the buffer in pixels * @param rot_mode rotatation mode * @param phyaddr_0 buffer 0 address * @param u_offset U offset * @param v_offset V offset * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_init_channel_buffer( int8_t imxdpuv1_id, imxdpuv1_chan_t chan, uint32_t stride, imxdpuv1_rotate_mode_t rot_mode, dma_addr_t phyaddr_0, uint32_t u_offset, uint32_t v_offset) { int ret = 0; uint32_t b_off; struct imxdpuv1_soc *imxdpu; imxdpuv1_chan_idx_t chan_idx = get_channel_idx(chan); int sub_idx = imxdpuv1_get_channel_subindex(chan); bool enable_clip = IMXDPUV1_FALSE; bool enable_buffer = IMXDPUV1_TRUE; uint8_t enable_yuv = IMXDPUV1_LAYERPROPERTY_YUVCONVERSIONMODE__OFF; uint8_t input_select = IMXDPUV1_FETCHDECODE0_CONTROL_INPUTSELECT__INACTIVE; uint32_t fwidth; uint32_t fheight; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (!is_chan(chan)) { return -EINVAL; } b_off = id2blockoffset(get_channel_blk(chan)); if (b_off == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } imxdpu->chan_data[chan_idx].phyaddr_0 = phyaddr_0; imxdpu->chan_data[chan_idx].u_offset = u_offset; imxdpu->chan_data[chan_idx].v_offset = v_offset; /* update stride if provided */ if (stride != 0) { /* todo: check stride range */ imxdpu->chan_data[chan_idx].stride = stride; } /* common fetch setup */ if (!is_store_chan(chan)) { /* default horizontal scan * todo: add support for vertical and warp scans */ if (sub_idx == 0) { imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHDECODE0_BURSTBUFFERMANAGEMENT_OFFSET, IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHDECODE0_BURSTBUFFERMANAGEMENT_SETBURSTLENGTH, burst_param[IMXDPUV1_BURST_HORIZONTAL]. len) | IMXDPUV1_SET_FIELD( IMXDPUV1_FETCHDECODE0_BURSTBUFFERMANAGEMENT_SETNUMBUFFERS, burst_param[IMXDPUV1_BURST_HORIZONTAL].buffers)); } /* todo: Add range checking here */ imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0 = phyaddr_0; imxdpu->chan_data[chan_idx].fetch_layer_prop.sourcebufferattributes0 = IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_ATTR_BITSPERPIXEL, imxdpuv1_bits_per_pixel( imxdpu->chan_data[chan_idx].src_pixel_fmt)) | IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_ATTR_STRIDE, imxdpu->chan_data[chan_idx].stride - 1); imxdpu->chan_data[chan_idx].fetch_layer_prop.sourcebufferdimension0 = IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_DIMEN_LINECOUNT, imxdpu->chan_data[chan_idx].src_height - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_DIMEN_LINEWIDTH, imxdpu->chan_data[chan_idx].src_width - 1); imxdpu->chan_data[chan_idx].fetch_layer_prop.colorcomponentbits0 = imxdpuv1_get_colorcomponentbits( imxdpu->chan_data[chan_idx].src_pixel_fmt); imxdpu->chan_data[chan_idx].fetch_layer_prop.colorcomponentshift0 = imxdpuv1_get_colorcomponentshift( imxdpu->chan_data[chan_idx].src_pixel_fmt); imxdpu->chan_data[chan_idx].fetch_layer_prop.layeroffset0 = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYER_XOFFSET, imxdpu->chan_data[chan_idx].dest_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYER_YOFFSET, imxdpu->chan_data[chan_idx].dest_top); imxdpu->chan_data[chan_idx].fetch_layer_prop.clipwindowoffset0 = IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_XOFFSET, imxdpu->chan_data[chan_idx].clip_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_YOFFSET, imxdpu->chan_data[chan_idx].clip_top); imxdpu->chan_data[chan_idx].fetch_layer_prop.clipwindowdimensions0 = IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_HEIGHT, imxdpu->chan_data[chan_idx].clip_height - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_WIDTH, imxdpu->chan_data[chan_idx].clip_width - 1); if ((imxdpu->chan_data[chan_idx].clip_height != 0) && (imxdpu->chan_data[chan_idx].clip_width != 0)) { imxdpu->chan_data[chan_idx].fetch_layer_prop.clipwindowdimensions0 = IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_HEIGHT, imxdpu->chan_data[chan_idx].clip_height - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_CLIP_WIDTH, imxdpu->chan_data[chan_idx].clip_width - 1); enable_clip = IMXDPUV1_ENABLE; } else { imxdpu->chan_data[chan_idx].fetch_layer_prop.clipwindowdimensions0 = 0; } imxdpu->chan_data[chan_idx].fetch_layer_prop.constantcolor0 = imxdpu->chan_data[chan_idx].const_color; if (imxdpu->chan_data[chan_idx].phyaddr_0 == 0) { enable_buffer = IMXDPUV1_FALSE; } if (imxdpuv1_is_yuv(imxdpu->chan_data[chan_idx].src_pixel_fmt)) { /* TODO: need to get correct encoding range */ enable_yuv = IMXDPUV1_LAYERPROPERTY_YUVCONVERSIONMODE__ITU601; } } if (is_fetch_decode_chan(chan)) { IMXDPUV1_TRACE("%s(): fetch decode channel\n", __func__); if (imxdpu->chan_data[chan_idx].use_eco_fetch) { input_select = IMXDPUV1_FETCHDECODE0_CONTROL_INPUTSELECT__COMPPACK; if (chan == IMXDPUV1_CHAN_01) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE0_DYNAMIC, IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_FETCHDECODE0_DYNAMIC_FETCHDECODE0_SRC_SEL__FETCHECO0)); } else if (chan == IMXDPUV1_CHAN_19) { imxdpuv1_write(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE1_DYNAMIC, IMXDPUV1_SET_FIELD( IMXDPUV1_PIXENGCFG_SRC_SEL, IMXDPUV1_PIXENGCFG_FETCHDECODE1_DYNAMIC_FETCHDECODE1_SRC_SEL__FETCHECO1)); } imxdpuv1_init_channel_buffer(imxdpuv1_id, imxdpuv1_get_eco(chan), stride, rot_mode, phyaddr_0, u_offset, v_offset); imxdpu->chan_data[chan_idx].fetch_layer_prop.colorcomponentbits0 = (0x08 << IMXDPUV1_FETCHDECODE0_COLORCOMPONENTBITS0_COMPONENTBITSRED0_SHIFT); imxdpu->chan_data[chan_idx].fetch_layer_prop.colorcomponentshift0 = (0x00 << IMXDPUV1_FETCHDECODE0_COLORCOMPONENTSHIFT0_COMPONENTSHIFTRED0_SHIFT); } /* else need to handle Alpha, Warp, CLUT ... */ imxdpu->chan_data[chan_idx].fetch_layer_prop.layerproperty0 = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_SOURCEBUFFERENABLE, enable_buffer) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_YUVCONVERSIONMODE, enable_yuv) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_CLIPWINDOWENABLE, enable_clip) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_ALPHACONSTENABLE, imxdpu->chan_data[chan_idx].use_global_alpha) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_ALPHASRCENABLE, imxdpu->chan_data[chan_idx].use_local_alpha); /* todo: handle all cases for control register */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHDECODE0_CONTROL_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE0_CONTROL_YUV422UPSAMPLINGMODE, IMXDPUV1_FETCHDECODE0_CONTROL_YUV422UPSAMPLINGMODE__INTERPOLATE) | IMXDPUV1_FETCHDECODE0_CONTROL_PALETTEIDXWIDTH_MASK | /* needed ?*/ IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE0_CONTROL_CLIPCOLOR, 1) | /*needed for clip */ IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE0_CONTROL_INPUTSELECT, input_select)); /*needed for eco */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHDECODE0_FRAMEDIMENSIONS_OFFSET, IMXDPUV1_SET_FIELD (IMXDPUV1_FETCHDECODE0_FRAMEDIMENSIONS_FRAMEHEIGHT, imxdpu->chan_data[chan_idx].dest_height - 1 /*fheight-1 */) | IMXDPUV1_SET_FIELD (IMXDPUV1_FETCHDECODE0_FRAMEDIMENSIONS_FRAMEWIDTH, imxdpu->chan_data[chan_idx].dest_width - 1 /*fwidth-1 */)); imxdpuv1_write_block(imxdpu, b_off + IMXDPUV1_FETCHDECODE0_BASEADDRESS0_OFFSET, (void *)&imxdpu->chan_data[chan_idx]. fetch_layer_prop, sizeof(fetch_layer_setup_t) / 4); imxdpuv1_disp_request_shadow_load(imxdpuv1_id, imxdpu->chan_data[chan_idx]. disp_id, IMXDPUV1_SHDLD_IDX_CHAN_00 + chan_idx); } else if (is_fetch_layer_chan(chan)) { IMXDPUV1_TRACE("%s(): fetch layer channel\n", __func__); /* here the frame is shared for all sub layers so we use the video mode dimensions. fetch layer sub 1 must be setup first todo: add a check so that any sub layer can set this */ if (is_fetch_layer_sub_chan1(chan)) { IMXDPUV1_TRACE("%s(): fetch layer sub channel 1\n", __func__); fwidth = imxdpuv1_array[imxdpuv1_id]. video_mode[imxdpuv1_array[imxdpuv1_id]. chan_data[chan_idx].disp_id].hlen; fheight = imxdpuv1_array[imxdpuv1_id]. video_mode[imxdpuv1_array[imxdpuv1_id]. chan_data[chan_idx].disp_id].vlen; imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_CONTROL_OFFSET, IMXDPUV1_FETCHDECODE0_CONTROL_PALETTEIDXWIDTH_MASK | /* needed ?*/ IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHDECODE0_CONTROL_CLIPCOLOR, 1) ); /*needed for eco */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_FRAMEDIMENSIONS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEHEIGHT, /*imxdpu->chan_data[chan_idx].dest_height-1 */ fheight - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEWIDTH, /*imxdpu->chan_data[chan_idx].dest_width-1 */ fwidth - 1)); } imxdpu->chan_data[chan_idx].fetch_layer_prop.layerproperty0 = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_SOURCEBUFFERENABLE, enable_buffer) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_YUVCONVERSIONMODE, enable_yuv) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_CLIPWINDOWENABLE, enable_clip) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_ALPHACONSTENABLE, imxdpu->chan_data[chan_idx].use_global_alpha) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_ALPHASRCENABLE, imxdpu->chan_data[chan_idx].use_local_alpha); imxdpuv1_write_block(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_BASEADDRESS0_OFFSET + ((IMXDPUV1_SUBCHAN_LAYER_OFFSET * sub_idx)), (void *)&imxdpu->chan_data[chan_idx]. fetch_layer_prop, sizeof(fetch_layer_setup_t) / 4); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_TRIGGERENABLE_OFFSET, get_channel_sub(chan)); imxdpuv1_disp_request_shadow_load(imxdpuv1_id, imxdpu->chan_data[chan_idx]. disp_id, IMXDPUV1_SHDLD_IDX_CHAN_00 + chan_idx); } else if (is_fetch_warp_chan(chan)) { /* here the frame is shared for all sub layers so we use the video mode dimensions. fetch layer sub 1 must be setup first todo: add a check so that any sub layer can set this */ if (is_fetch_layer_sub_chan1(chan)) { IMXDPUV1_TRACE("%s(): fetch layer sub channel 1\n", __func__); fwidth = imxdpuv1_array[imxdpuv1_id]. video_mode[imxdpuv1_array[imxdpuv1_id]. chan_data[chan_idx].disp_id].hlen; fheight = imxdpuv1_array[imxdpuv1_id]. video_mode[imxdpuv1_array[imxdpuv1_id]. chan_data[chan_idx].disp_id].vlen; imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHWARP2_CONTROL_OFFSET, 0x700); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_FRAMEDIMENSIONS_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEHEIGHT, /*imxdpu->chan_data[chan_idx].dest_height-1 */ fheight - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_FRAMEWIDTH, /*imxdpu->chan_data[chan_idx].dest_width-1 */ fwidth - 1)); } imxdpu->chan_data[chan_idx].fetch_layer_prop.layerproperty0 = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_SOURCEBUFFERENABLE, enable_buffer) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_YUVCONVERSIONMODE, enable_yuv) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_CLIPWINDOWENABLE, enable_clip) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_ALPHACONSTENABLE, imxdpu->chan_data[chan_idx].use_global_alpha) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_ALPHASRCENABLE, imxdpu->chan_data[chan_idx].use_local_alpha); imxdpuv1_write_block(imxdpu, b_off + IMXDPUV1_FETCHWARP2_BASEADDRESS0_OFFSET + (IMXDPUV1_SUBCHAN_LAYER_OFFSET * sub_idx), (void *)&imxdpu->chan_data[chan_idx]. fetch_layer_prop, sizeof(fetch_layer_setup_t) / 4); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHWARP2_TRIGGERENABLE_OFFSET, get_channel_sub(chan)); imxdpuv1_disp_request_shadow_load(imxdpuv1_id, imxdpu->chan_data[chan_idx]. disp_id, IMXDPUV1_SHDLD_IDX_CHAN_00 + chan_idx); } else if (is_fetch_eco_chan(chan)) { IMXDPUV1_TRACE("%s(): fetch eco setup\n", __func__); if (imxdpu->chan_data[chan_idx].src_pixel_fmt == IMXDPUV1_PIX_FMT_NV12) { imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0 = phyaddr_0 + u_offset; imxdpu->chan_data[chan_idx].fetch_layer_prop.sourcebufferattributes0 = IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_ATTR_BITSPERPIXEL, 16) | IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_ATTR_STRIDE, imxdpu->chan_data[chan_idx].stride - 1); /* chroma resolution*/ imxdpu->chan_data[chan_idx].fetch_layer_prop.sourcebufferdimension0 = IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_DIMEN_LINECOUNT, imxdpu->chan_data[chan_idx].src_height / 2 - 1) | IMXDPUV1_SET_FIELD(IMXDPUV1_BUFF_DIMEN_LINEWIDTH, imxdpu->chan_data[chan_idx].src_width / 2 - 1); imxdpu->chan_data[chan_idx].fetch_layer_prop.colorcomponentbits0 = IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSRED0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSGREEN0, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSBLUE0, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_BITSALPHA0, 0x0); imxdpu->chan_data[chan_idx].fetch_layer_prop.colorcomponentshift0 = IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTRED0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTGREEN0, 0x0) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTBLUE0, 0x8) | IMXDPUV1_SET_FIELD(IMXDPUV1_COLOR_SHIFTALPHA0, 0x0); imxdpu->chan_data[chan_idx].fetch_layer_prop.layerproperty0 = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_SOURCEBUFFERENABLE, enable_buffer) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_CLIPWINDOWENABLE, enable_clip); imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHECO0_FRAMERESAMPLING_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHECO0_FRAMERESAMPLING_DELTAX, 0x2) | IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHECO0_FRAMERESAMPLING_DELTAY, 0x2) ); /* todo: handle all cases for control register */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHECO0_CONTROL_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_FETCHECO0_CONTROL_CLIPCOLOR, 1)); /* luma resolution */ imxdpuv1_write(imxdpu, b_off + IMXDPUV1_FETCHECO0_FRAMEDIMENSIONS_OFFSET, IMXDPUV1_SET_FIELD (IMXDPUV1_FETCHECO0_FRAMEDIMENSIONS_FRAMEHEIGHT, imxdpu->chan_data[chan_idx].dest_height - 1 /*fheight-1 */) | IMXDPUV1_SET_FIELD (IMXDPUV1_FETCHECO0_FRAMEDIMENSIONS_FRAMEWIDTH, imxdpu->chan_data[chan_idx].dest_width - 1 /*fwidth-1 */)); } /* else need to handle Alpha, Warp, CLUT ... */ imxdpu->chan_data[chan_idx].fetch_layer_prop.layerproperty0 = IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_SOURCEBUFFERENABLE, enable_buffer) | IMXDPUV1_SET_FIELD(IMXDPUV1_LAYERPROPERTY_CLIPWINDOWENABLE, enable_clip); imxdpuv1_write_block(imxdpu, b_off + IMXDPUV1_FETCHECO0_BASEADDRESS0_OFFSET, (void *)&imxdpu->chan_data[chan_idx]. fetch_layer_prop, sizeof(fetch_layer_setup_t) / 4); imxdpuv1_disp_request_shadow_load(imxdpuv1_id, imxdpu->chan_data[chan_idx]. disp_id, IMXDPUV1_SHDLD_IDX_CHAN_00 + chan_idx); } else if (is_store_chan(chan)) { imxdpu->chan_data[chan_idx].store_layer_prop.baseaddress0 = phyaddr_0; imxdpu->chan_data[chan_idx].store_layer_prop.destbufferattributes0 = IMXDPUV1_SET_FIELD( IMXDPUV1_STORE9_DESTINATIONBUFFERATTRIBUTES_BITSPERPIXEL, imxdpuv1_bits_per_pixel( imxdpu->chan_data[chan_idx].dest_pixel_fmt)) | IMXDPUV1_SET_FIELD( IMXDPUV1_STORE9_DESTINATIONBUFFERATTRIBUTES_STRIDE, imxdpu->chan_data[chan_idx].stride-1); imxdpu->chan_data[chan_idx].store_layer_prop.destbufferdimension0 = IMXDPUV1_SET_FIELD( IMXDPUV1_STORE9_DESTINATIONBUFFERDIMENSION_LINECOUNT, imxdpu->chan_data[chan_idx].dest_height - 1) | IMXDPUV1_SET_FIELD( IMXDPUV1_STORE9_DESTINATIONBUFFERDIMENSION_LINEWIDTH, imxdpu->chan_data[chan_idx].dest_width - 1); imxdpu->chan_data[chan_idx].store_layer_prop.colorcomponentbits0 = imxdpuv1_get_colorcomponentbits( imxdpu->chan_data[chan_idx].dest_pixel_fmt); imxdpu->chan_data[chan_idx].store_layer_prop.colorcomponentshift0 = imxdpuv1_get_colorcomponentshift( imxdpu->chan_data[chan_idx].dest_pixel_fmt); imxdpu->chan_data[chan_idx].store_layer_prop.frameoffset0 = IMXDPUV1_SET_FIELD(IMXDPUV1_STORE9_FRAMEOFFSET_FRAMEXOFFSET, -imxdpu->chan_data[chan_idx].dest_left) | IMXDPUV1_SET_FIELD(IMXDPUV1_STORE9_FRAMEOFFSET_FRAMEYOFFSET, -imxdpu->chan_data[chan_idx].dest_top); imxdpuv1_write_block(imxdpu, b_off + IMXDPUV1_STORE9_BASEADDRESS_OFFSET, (void *)&imxdpu->chan_data[chan_idx]. store_layer_prop, sizeof(store_layer_setup_t) / 4); if ((imxdpu->chan_data[chan_idx].dest_pixel_fmt == IMXDPUV1_PIX_FMT_YUYV) || (imxdpu->chan_data[chan_idx].dest_pixel_fmt == IMXDPUV1_PIX_FMT_YVYU) || (imxdpu->chan_data[chan_idx].dest_pixel_fmt == IMXDPUV1_PIX_FMT_UYVY)) { imxdpuv1_write(imxdpu, b_off + IMXDPUV1_STORE9_CONTROL_OFFSET, IMXDPUV1_SET_FIELD(IMXDPUV1_STORE9_CONTROL_RASTERMODE, IMXDPUV1_STORE9_CONTROL_RASTERMODE__YUV422)); } } /* imxdpuv1_dump_channel(imxdpuv1_id, chan); */ return ret; } /*! * Intializes a channel * * @param imxdpuv1_id id of the diplay unit * @param chan channel to update * @param phyaddr_0 physical address * * @return This function returns 0 on success or negative error code on * fail. */ int32_t imxdpuv1_update_channel_buffer( int8_t imxdpuv1_id, imxdpuv1_chan_t chan, dma_addr_t phyaddr_0) { int ret = 0; uint32_t b_off; /* block offset for frame generator */ struct imxdpuv1_soc *imxdpu; imxdpuv1_chan_idx_t chan_idx = get_channel_idx(chan); IMXDPUV1_TRACE_IRQ("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (!is_chan(chan)) { return -EINVAL; } b_off = id2blockoffset(get_channel_blk(chan)); if (b_off == IMXDPUV1_OFFSET_INVALID) { return -EINVAL; } if (imxdpu->chan_data[chan_idx].use_eco_fetch == IMXDPUV1_FALSE) { imxdpu->chan_data[chan_idx].phyaddr_0 = phyaddr_0; imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0 = phyaddr_0; } #ifdef IMXDPUV1_VERSION_0 if (is_store_chan(chan)) { IMXDPUV1_TRACE_IRQ("%s(): store channel\n", __func__); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_STORE4_BASEADDRESS_OFFSET, imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0); /* fixme: need to handle all pipline elements */ imxdpuv1_write_irq(imxdpu, IMXDPUV1_PIXENGCFG_STORE4_REQUEST, 1); return ret; } #endif if (is_fetch_decode_chan(chan)) { IMXDPUV1_TRACE_IRQ("%s(): fetch decode channel\n", __func__); if (imxdpu->chan_data[chan_idx].use_eco_fetch) { imxdpuv1_update_channel_buffer(imxdpuv1_id, imxdpuv1_get_eco(chan), phyaddr_0); } imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHDECODE0_BASEADDRESS0_OFFSET, imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHDECODE0_CONTROLTRIGGER_OFFSET, IMXDPUV1_FETCHDECODE0_CONTROLTRIGGER_SHDTOKGEN_MASK); } else if (is_fetch_layer_chan(chan)) { IMXDPUV1_TRACE_IRQ("%s(): fetch layer channel\n", __func__); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_BASEADDRESS0_OFFSET, imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_TRIGGERENABLE_OFFSET, get_channel_sub(chan)); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHLAYER0_CONTROLTRIGGER_OFFSET, IMXDPUV1_FETCHLAYER0_CONTROLTRIGGER_SHDTOKGEN_MASK); } else if (is_fetch_warp_chan(chan)) { IMXDPUV1_TRACE_IRQ("%s(): fetch warp channel\n", __func__); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHWARP2_BASEADDRESS0_OFFSET, imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHWARP2_TRIGGERENABLE_OFFSET, get_channel_sub(chan)); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHWARP2_CONTROLTRIGGER_OFFSET, IMXDPUV1_FETCHWARP2_CONTROLTRIGGER_SHDTOKGEN_MASK); } else if (is_fetch_eco_chan(chan)) { IMXDPUV1_TRACE_IRQ("%s(): fetch eco channel\n", __func__); imxdpu->chan_data[chan_idx].phyaddr_0 = phyaddr_0 + imxdpu->chan_data[chan_idx].u_offset; imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0 = imxdpu->chan_data[chan_idx].phyaddr_0; imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHDECODE0_BASEADDRESS0_OFFSET, imxdpu->chan_data[chan_idx].fetch_layer_prop.baseaddress0); imxdpuv1_write_irq(imxdpu, b_off + IMXDPUV1_FETCHECO0_CONTROLTRIGGER_OFFSET, IMXDPUV1_FETCHECO0_CONTROLTRIGGER_SHDTOKGEN_MASK); } return ret; } /*! * Intializes a channel * * @param imxdpuv1_id id of the diplay unit * @param params pointer to channel parameters * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_init_channel(int8_t imxdpuv1_id, imxdpuv1_channel_params_t *params) { int ret = 0; struct imxdpuv1_soc *imxdpu; imxdpuv1_chan_t chan = params->common.chan; imxdpuv1_chan_idx_t chan_idx = get_channel_idx(chan); /* here we use the video mode for channel frame width, todo: we may need to add a paramter for this */ IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (!is_chan(chan)) { return -EINVAL; } imxdpu->chan_data[chan_idx].chan = chan; memset(&imxdpu->chan_data[chan_idx].fetch_layer_prop, 0, sizeof(fetch_layer_setup_t)); imxdpu->chan_data[chan_idx].use_eco_fetch = IMXDPUV1_FALSE; if (is_fetch_decode_chan(chan)) { IMXDPUV1_TRACE("%s(): decode channel setup\n", __func__); imxdpu->chan_data[chan_idx].src_pixel_fmt = params->fetch_decode.src_pixel_fmt; imxdpu->chan_data[chan_idx].src_width = params->fetch_decode.src_width; imxdpu->chan_data[chan_idx].src_height = params->fetch_decode.src_height; imxdpu->chan_data[chan_idx].clip_top = params->fetch_decode.clip_top; imxdpu->chan_data[chan_idx].clip_left = params->fetch_decode.clip_left; imxdpu->chan_data[chan_idx].clip_width = params->fetch_decode.clip_width; imxdpu->chan_data[chan_idx].clip_height = params->fetch_decode.clip_height; imxdpu->chan_data[chan_idx].stride = params->fetch_decode.stride; imxdpu->chan_data[chan_idx].dest_pixel_fmt = params->fetch_decode.dest_pixel_fmt; imxdpu->chan_data[chan_idx].dest_top = params->fetch_decode.dest_top; imxdpu->chan_data[chan_idx].dest_left = params->fetch_decode.dest_left; imxdpu->chan_data[chan_idx].dest_width = params->fetch_decode.dest_width; imxdpu->chan_data[chan_idx].dest_height = params->fetch_decode.dest_height; imxdpu->chan_data[chan_idx].const_color = params->fetch_decode.const_color; imxdpu->chan_data[chan_idx].use_global_alpha = params->fetch_decode.use_global_alpha; imxdpu->chan_data[chan_idx].use_local_alpha = params->fetch_decode.use_local_alpha; imxdpu->chan_data[chan_idx].disp_id = params->fetch_decode.disp_id; if (imxdpu->chan_data[chan_idx].use_video_proc == IMXDPUV1_TRUE) { imxdpu->chan_data[chan_idx].h_scale_factor = params->fetch_decode.h_scale_factor; imxdpu->chan_data[chan_idx].h_phase = params->fetch_decode.h_phase; imxdpu->chan_data[chan_idx].v_scale_factor = params->fetch_decode.v_scale_factor; imxdpu->chan_data[chan_idx].v_phase[0][0] = params->fetch_decode.v_phase[0][0]; imxdpu->chan_data[chan_idx].v_phase[0][1] = params->fetch_decode.v_phase[0][1]; imxdpu->chan_data[chan_idx].v_phase[1][0] = params->fetch_decode.v_phase[1][0]; imxdpu->chan_data[chan_idx].v_phase[1][1] = params->fetch_decode.v_phase[1][1]; } if (imxdpuv1_get_planes(imxdpu->chan_data[chan_idx].src_pixel_fmt) == 2) { if (has_fetch_eco_chan(chan)) { imxdpuv1_channel_params_t temp_params = *params; imxdpu->chan_data[chan_idx].use_eco_fetch = IMXDPUV1_TRUE; temp_params.fetch_decode.chan = imxdpuv1_get_eco(params->fetch_decode.chan); imxdpuv1_init_channel(imxdpuv1_id, &temp_params); } else { return -EINVAL; } } } else if (is_fetch_layer_chan(chan)) { IMXDPUV1_TRACE("%s(): layer channel setup\n", __func__); imxdpu->chan_data[chan_idx].src_pixel_fmt = params->fetch_layer.src_pixel_fmt; imxdpu->chan_data[chan_idx].src_width = params->fetch_layer.src_width; imxdpu->chan_data[chan_idx].src_height = params->fetch_layer.src_height; imxdpu->chan_data[chan_idx].clip_top = params->fetch_layer.clip_top; imxdpu->chan_data[chan_idx].clip_left = params->fetch_layer.clip_left; imxdpu->chan_data[chan_idx].clip_width = params->fetch_layer.clip_width; imxdpu->chan_data[chan_idx].clip_height = params->fetch_layer.clip_height; imxdpu->chan_data[chan_idx].stride = params->fetch_layer.stride; imxdpu->chan_data[chan_idx].dest_pixel_fmt = params->fetch_layer.dest_pixel_fmt; imxdpu->chan_data[chan_idx].dest_top = params->fetch_layer.dest_top; imxdpu->chan_data[chan_idx].dest_left = params->fetch_layer.dest_left; imxdpu->chan_data[chan_idx].dest_width = params->fetch_layer.dest_width; imxdpu->chan_data[chan_idx].dest_height = params->fetch_layer.dest_height; imxdpu->chan_data[chan_idx].const_color = params->fetch_layer.const_color; imxdpu->chan_data[chan_idx].use_global_alpha = params->fetch_layer.use_global_alpha; imxdpu->chan_data[chan_idx].use_local_alpha = params->fetch_layer.use_local_alpha; imxdpu->chan_data[chan_idx].disp_id = params->fetch_layer.disp_id; } else if (is_fetch_warp_chan(chan)) { IMXDPUV1_TRACE("%s(): warp channel setup\n", __func__); imxdpu->chan_data[chan_idx].src_pixel_fmt = params->fetch_warp.src_pixel_fmt; imxdpu->chan_data[chan_idx].src_width = params->fetch_warp.src_width; imxdpu->chan_data[chan_idx].src_height = params->fetch_warp.src_height; imxdpu->chan_data[chan_idx].clip_top = params->fetch_warp.clip_top; imxdpu->chan_data[chan_idx].clip_left = params->fetch_warp.clip_left; imxdpu->chan_data[chan_idx].clip_width = params->fetch_warp.clip_width; imxdpu->chan_data[chan_idx].clip_height = params->fetch_warp.clip_height; imxdpu->chan_data[chan_idx].stride = params->fetch_warp.stride; imxdpu->chan_data[chan_idx].dest_pixel_fmt = params->fetch_warp.dest_pixel_fmt; imxdpu->chan_data[chan_idx].dest_top = params->fetch_warp.dest_top; imxdpu->chan_data[chan_idx].dest_left = params->fetch_warp.dest_left; imxdpu->chan_data[chan_idx].dest_width = params->fetch_warp.dest_width; imxdpu->chan_data[chan_idx].dest_height = params->fetch_warp.dest_height; imxdpu->chan_data[chan_idx].const_color = params->fetch_warp.const_color; imxdpu->chan_data[chan_idx].use_global_alpha = params->fetch_warp.use_global_alpha; imxdpu->chan_data[chan_idx].use_local_alpha = params->fetch_warp.use_local_alpha; imxdpu->chan_data[chan_idx].disp_id = params->fetch_warp.disp_id; } else if (is_fetch_eco_chan(chan)) { IMXDPUV1_TRACE("%s(): fetch eco channel setup\n", __func__); imxdpu->chan_data[chan_idx].src_pixel_fmt = params->fetch_decode.src_pixel_fmt; imxdpu->chan_data[chan_idx].src_width = params->fetch_decode.src_width; imxdpu->chan_data[chan_idx].src_height = params->fetch_decode.src_height; imxdpu->chan_data[chan_idx].clip_top = params->fetch_decode.clip_top; imxdpu->chan_data[chan_idx].clip_left = params->fetch_decode.clip_left; imxdpu->chan_data[chan_idx].clip_width = params->fetch_decode.clip_width; imxdpu->chan_data[chan_idx].clip_height = params->fetch_decode.clip_height; imxdpu->chan_data[chan_idx].stride = params->fetch_decode.stride; imxdpu->chan_data[chan_idx].dest_pixel_fmt = params->fetch_decode.dest_pixel_fmt; imxdpu->chan_data[chan_idx].dest_top = params->fetch_decode.dest_top; imxdpu->chan_data[chan_idx].dest_left = params->fetch_decode.dest_left; imxdpu->chan_data[chan_idx].dest_width = params->fetch_decode.dest_width; imxdpu->chan_data[chan_idx].dest_height = params->fetch_decode.dest_height; imxdpu->chan_data[chan_idx].const_color = params->fetch_decode.const_color; imxdpu->chan_data[chan_idx].use_global_alpha = params->fetch_decode.use_global_alpha; imxdpu->chan_data[chan_idx].use_local_alpha = params->fetch_decode.use_local_alpha; imxdpu->chan_data[chan_idx].disp_id = params->fetch_decode.disp_id; if (imxdpu->chan_data[chan_idx].use_video_proc == IMXDPUV1_TRUE) { imxdpu->chan_data[chan_idx].h_scale_factor = params->fetch_decode.h_scale_factor; imxdpu->chan_data[chan_idx].h_phase = params->fetch_decode.h_phase; imxdpu->chan_data[chan_idx].v_scale_factor = params->fetch_decode.v_scale_factor; imxdpu->chan_data[chan_idx].v_phase[0][0] = params->fetch_decode.v_phase[0][0]; imxdpu->chan_data[chan_idx].v_phase[0][1] = params->fetch_decode.v_phase[0][1]; imxdpu->chan_data[chan_idx].v_phase[1][0] = params->fetch_decode.v_phase[1][0]; imxdpu->chan_data[chan_idx].v_phase[1][1] = params->fetch_decode.v_phase[1][1]; } } else if (is_store_chan(chan)) { IMXDPUV1_TRACE("%s(): store setup\n", __func__); imxdpu->chan_data[chan_idx].src_pixel_fmt = params->store.src_pixel_fmt; imxdpu->chan_data[chan_idx].src_width = params->store.src_width; imxdpu->chan_data[chan_idx].src_height = params->store.src_height; imxdpu->chan_data[chan_idx].clip_top = params->store.clip_top; imxdpu->chan_data[chan_idx].clip_left = params->store.clip_left; imxdpu->chan_data[chan_idx].clip_width = params->store.clip_width; imxdpu->chan_data[chan_idx].clip_height = params->store.clip_height; imxdpu->chan_data[chan_idx].stride = params->store.stride; imxdpu->chan_data[chan_idx].dest_pixel_fmt = params->store.dest_pixel_fmt; imxdpu->chan_data[chan_idx].dest_top = params->store.dest_top; imxdpu->chan_data[chan_idx].dest_left = params->store.dest_left; imxdpu->chan_data[chan_idx].dest_width = params->store.dest_width; imxdpu->chan_data[chan_idx].dest_height = params->store.dest_height; imxdpu->chan_data[chan_idx].const_color = params->store.const_color; imxdpu->chan_data[chan_idx].source_id = params->store.capture_id; if (imxdpu->chan_data[chan_idx].use_video_proc == IMXDPUV1_TRUE) { imxdpu->chan_data[chan_idx].h_scale_factor = params->store.h_scale_factor; imxdpu->chan_data[chan_idx].h_phase = params->store.h_phase; imxdpu->chan_data[chan_idx].v_scale_factor = params->store.v_scale_factor; imxdpu->chan_data[chan_idx].v_phase[0][0] = params->store.v_phase[0][0]; imxdpu->chan_data[chan_idx].v_phase[0][1] = params->store.v_phase[0][1]; imxdpu->chan_data[chan_idx].v_phase[1][0] = params->store.v_phase[1][0]; imxdpu->chan_data[chan_idx].v_phase[1][1] = params->store.v_phase[1][1]; } } else { IMXDPUV1_TRACE("%s(): ERROR, invalid channel type!\n", __func__); return -EINVAL; } /* imxdpuv1_dump_channel(imxdpuv1_id, chan); */ return ret; } /*! * Dumps the fetch layer properties structure for a channel. * * @param layer id of the diplay unit * * @return This function returns 0 on success or negative error code on * fail. */ void imxdpuv1_dump_fetch_layer(fetch_layer_setup_t *layer) { IMXDPUV1_PRINT("baseaddress 0x%08x\n" "sourcebufferattributes 0x%08x\n" "sourcebufferdimension h %d w %d\n" "colorcomponentbits 0x%08x\n" "colorcomponentshift 0x%08x\n" "layeroffset y(top) %d x(left) %d\n" "clipwindowoffset y(top) %d x(left) %d\n" "clipwindowdimensions h %d w %d\n" "constantcolor 0x%08x\n" "layerproperty 0x%08x\n", layer->baseaddress0, layer->sourcebufferattributes0, layer->sourcebufferdimension0 >> 16, layer->sourcebufferdimension0 & 0x3fff, layer->colorcomponentbits0, layer->colorcomponentshift0, layer->layeroffset0 >> 16, layer->layeroffset0 & 0x3fff, layer->clipwindowoffset0 >> 16, layer->clipwindowoffset0 & 0x3fff, layer->clipwindowdimensions0 >> 16, layer->clipwindowdimensions0 & 0x3fff, layer->constantcolor0, layer->layerproperty0); return; } /*! * Dumps the store layer properties structure for a channel. * * @param layer id of the diplay unit * * @return This function returns 0 on success or negative error code on * fail. */ void imxdpuv1_dump_store_layer(store_layer_setup_t *layer) { IMXDPUV1_TRACE( "baseaddress0 0x%08x\n" "destbufferattributes0 0x%08x\n" "destbufferdimension0 h %d w %d\n" "frameoffset0 %d\n" "colorcomponentbits0 0x%08x\n" "colorcomponentshift0 0x%08x\n", layer->baseaddress0, layer->destbufferattributes0, layer->destbufferdimension0 >> 16, layer->destbufferdimension0 & 0x3fff, layer->frameoffset0, layer->colorcomponentbits0, layer->colorcomponentshift0); return; } /*! * Dumps the pixel engine configuration status * * @param imxdpuv1_id id of the diplay unit * * @return This function returns 0 on success or negative error code on * fail. */ void imxdpuv1_dump_layerblend(int8_t imxdpuv1_id) { uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND0_STATUS); IMXDPUV1_TRACE("LAYERBLEND0_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND0_LOCKSTATUS); IMXDPUV1_PRINT("LAYERBLEND0_LOCKSTATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND1_STATUS); IMXDPUV1_PRINT("LAYERBLEND1_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND1_LOCKSTATUS); IMXDPUV1_PRINT("LAYERBLEND1_LOCKSTATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND2_STATUS); IMXDPUV1_PRINT("LAYERBLEND2_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND2_LOCKSTATUS); IMXDPUV1_PRINT("LAYERBLEND2_LOCKSTATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND3_STATUS); IMXDPUV1_PRINT("LAYERBLEND3_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND3_LOCKSTATUS); IMXDPUV1_PRINT("LAYERBLEND3_LOCKSTATUS: 0x%08x\n", reg); #ifdef IMXDPUV1_VERSION_0 reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND4_STATUS); IMXDPUV1_PRINT("LAYERBLEND4_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND4_LOCKSTATUS); IMXDPUV1_PRINT("LAYERBLEND4_LOCKSTATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND5_STATUS); IMXDPUV1_PRINT("LAYERBLEND5_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND5_LOCKSTATUS); IMXDPUV1_PRINT("LAYERBLEND5_LOCKSTATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND6_STATUS); IMXDPUV1_PRINT("LAYERBLEND6_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_LAYERBLEND6_LOCKSTATUS); IMXDPUV1_PRINT("LAYERBLEND6_LOCKSTATUS: 0x%08x\n", reg); #endif return; } /*! * Dumps the pixel engine configuration status * * @param imxdpuv1_id id of the diplay unit * * @return This function returns 0 on success or negative error code on * fail. */ void imxdpuv1_dump_pixencfg_status(int8_t imxdpuv1_id) { uint32_t reg; struct imxdpuv1_soc *imxdpu; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_REQUEST); IMXDPUV1_PRINT("EXTDST0_REQUEST: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_REQUEST); IMXDPUV1_PRINT("EXTDST1_REQUEST: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST4_REQUEST); IMXDPUV1_PRINT("EXTDST4_REQUEST: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST5_REQUEST); IMXDPUV1_PRINT("EXTDST5_REQUEST: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST0_STATUS); IMXDPUV1_PRINT("EXTDST0_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST1_STATUS); IMXDPUV1_PRINT("EXTDST1_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST4_STATUS); IMXDPUV1_PRINT("EXTDST4_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_EXTDST5_STATUS); IMXDPUV1_PRINT("EXTDST5_STATUS: 0x%08x\n", reg); #ifdef IMXDPUV1_VERSION_0 reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE2_STATUS); IMXDPUV1_PRINT("FETCHDECODE2_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE3_STATUS); IMXDPUV1_PRINT("FETCHDECODE3_STATUS: 0x%08x\n", reg); #endif reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHWARP2_STATUS); IMXDPUV1_PRINT("FETCHWARP2_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHECO2_STATUS); IMXDPUV1_PRINT("FETCHECO2_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE0_STATUS); IMXDPUV1_PRINT("FETCHDECODE0_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHECO0_STATUS); IMXDPUV1_PRINT("FETCHECO0_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHDECODE1_STATUS); IMXDPUV1_PRINT("FETCHDECODE1_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHECO1_STATUS); IMXDPUV1_PRINT("FETCHECO1_STATUS: 0x%08x\n", reg); reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHLAYER0_STATUS); IMXDPUV1_PRINT("FETCHLAYER0_STATUS: 0x%08x\n", reg); #ifdef IMXDPUV1_VERSION_0 reg = imxdpuv1_read(imxdpu, IMXDPUV1_PIXENGCFG_FETCHLAYER1_STATUS); IMXDPUV1_PRINT("FETCHLAYER1_STATUS: 0x%08x\n", reg); #endif return; } /*! * Dumps the channel data * * @param imxdpuv1_id id of the diplay unit * @param chan channel to dump * * @return This function returns 0 on success or negative error code on * fail. */ int imxdpuv1_dump_channel(int8_t imxdpuv1_id, imxdpuv1_chan_t chan) { int ret = 0; struct imxdpuv1_soc *imxdpu; imxdpuv1_chan_idx_t chan_idx = get_channel_idx(chan); IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return -EINVAL; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; if (!is_chan(chan)) { return -EINVAL; } if (is_store_chan(chan)) { IMXDPUV1_PRINT("chan_id 0x%x\n" "src_pixel_fmt 0x%08x\n" "src_width %d\n" "src_height %d\n" "clip_top %d(0x%04x)\n" "clip_left %d(0x%04x)\n" "clip_width %d\n" "clip_height %d\n" "stride %d\n" "dest_pixel_fmt 0x%08x\n" "dest_top %d(0x%04x)\n" "dest_left %d(0x%04x)\n" "dest_width %d\n" "dest_height %d\n", (uint32_t)imxdpu->chan_data[chan_idx].chan, imxdpu->chan_data[chan_idx].src_pixel_fmt, imxdpu->chan_data[chan_idx].src_width, imxdpu->chan_data[chan_idx].src_height, imxdpu->chan_data[chan_idx].clip_top, imxdpu->chan_data[chan_idx].clip_top, imxdpu->chan_data[chan_idx].clip_left, imxdpu->chan_data[chan_idx].clip_left, imxdpu->chan_data[chan_idx].clip_width, imxdpu->chan_data[chan_idx].clip_height, imxdpu->chan_data[chan_idx].stride, imxdpu->chan_data[chan_idx].dest_pixel_fmt, imxdpu->chan_data[chan_idx].dest_top, imxdpu->chan_data[chan_idx].dest_top, imxdpu->chan_data[chan_idx].dest_left, imxdpu->chan_data[chan_idx].dest_left, imxdpu->chan_data[chan_idx].dest_width, imxdpu->chan_data[chan_idx].dest_height); IMXDPUV1_PRINT( "use_video_proc %d\n" "use_eco_fetch %d\n" "interlaced %d\n" "phyaddr_0 0x%08x\n" "rot_mode %d\n" "in_use %d\n" "use_global_alpha %d\n" "use_local_alpha %d\n", imxdpu->chan_data[chan_idx].use_video_proc, imxdpu->chan_data[chan_idx].use_eco_fetch, imxdpu->chan_data[chan_idx].interlaced, ptr_to_uint32(imxdpu->chan_data[chan_idx].phyaddr_0), imxdpu->chan_data[chan_idx].rot_mode, imxdpu->chan_data[chan_idx].in_use, imxdpu->chan_data[chan_idx].use_global_alpha, imxdpu->chan_data[chan_idx].use_local_alpha ); imxdpuv1_dump_store_layer(&imxdpu->chan_data[chan_idx].store_layer_prop); } else { IMXDPUV1_PRINT("chan_id 0x%x\n" "src_pixel_fmt 0x%08x\n" "src_width %d\n" "src_height %d\n" "clip_top %d(0x%04x)\n" "clip_left %d(0x%04x)\n" "clip_width %d\n" "clip_height %d\n" "stride %d\n" "dest_pixel_fmt 0x%08x\n" "dest_top %d(0x%04x)\n" "dest_left %d(0x%04x)\n" "dest_width %d\n" "dest_height %d\n", (uint32_t)imxdpu->chan_data[chan_idx].chan, imxdpu->chan_data[chan_idx].src_pixel_fmt, imxdpu->chan_data[chan_idx].src_width, imxdpu->chan_data[chan_idx].src_height, imxdpu->chan_data[chan_idx].clip_top, imxdpu->chan_data[chan_idx].clip_top, imxdpu->chan_data[chan_idx].clip_left, imxdpu->chan_data[chan_idx].clip_left, imxdpu->chan_data[chan_idx].clip_width, imxdpu->chan_data[chan_idx].clip_height, imxdpu->chan_data[chan_idx].stride, imxdpu->chan_data[chan_idx].dest_pixel_fmt, imxdpu->chan_data[chan_idx].dest_top, imxdpu->chan_data[chan_idx].dest_top, imxdpu->chan_data[chan_idx].dest_left, imxdpu->chan_data[chan_idx].dest_left, imxdpu->chan_data[chan_idx].dest_width, imxdpu->chan_data[chan_idx].dest_height); IMXDPUV1_PRINT( "use_video_proc %d\n" "use_eco_fetch %d\n" "interlaced %d\n" "phyaddr_0 0x%08x\n" "u_offset 0x%08x\n" "v_offset 0x%08x\n" "rot_mode %d\n" "in_use %d\n" "use_global_alpha %d\n" "use_local_alpha %d\n", imxdpu->chan_data[chan_idx].use_video_proc, imxdpu->chan_data[chan_idx].use_eco_fetch, imxdpu->chan_data[chan_idx].interlaced, ptr_to_uint32(imxdpu->chan_data[chan_idx].phyaddr_0), imxdpu->chan_data[chan_idx].u_offset, imxdpu->chan_data[chan_idx].v_offset, imxdpu->chan_data[chan_idx].rot_mode, imxdpu->chan_data[chan_idx].in_use, imxdpu->chan_data[chan_idx].use_global_alpha, imxdpu->chan_data[chan_idx].use_local_alpha ); imxdpuv1_dump_fetch_layer(&imxdpu->chan_data[chan_idx].fetch_layer_prop); } return ret; } /*! * Shows the interrupt status registers * * @param id of the diplay unit * */ void imxdpuv1_dump_int_stat(int8_t imxdpuv1_id) { int i; struct imxdpuv1_soc *imxdpu; uint32_t reg; IMXDPUV1_TRACE("%s()\n", __func__); if (!((imxdpuv1_id >= 0) && (imxdpuv1_id < IMXDPUV1_MAX_NUM))) { return; } imxdpu = &imxdpuv1_array[imxdpuv1_id]; for (i = 0; i < 3; i++) { reg = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTMASK0 + (i * 4)); IMXDPUV1_PRINT("USERINTERRUPTMASK%d: 0x%08x\n", i, reg); } for (i = 0; i < 3; i++) { reg = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTENABLE0 + (i * 4)); IMXDPUV1_PRINT("USERINTERRUPTENABLE%d: 0x%08x\n", i, reg); } for (i = 0; i < 3; i++) { reg = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_USERINTERRUPTSTATUS0 + (i * 4)); IMXDPUV1_PRINT("USERINTERRUPTSTATUS%d: 0x%08x\n", i, reg); } for (i = 0; i < 3; i++) { reg = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTENABLE0 + (i * 4)); IMXDPUV1_PRINT("INTERRUPTENABLE%i: 0x%08x\n", i, reg); } for (i = 0; i < 3; i++) { reg = imxdpuv1_read_irq(imxdpu, IMXDPUV1_COMCTRL_INTERRUPTSTATUS0 + (i * 4)); IMXDPUV1_PRINT("INTERRUPTSTATUS%i: 0x%08x\n", i, reg); } }