(g_ipu_hw_rev >= 2));
}
+/*
+ * We usually use IDMAC 23 as full plane and IDMAC 27 as partial
+ * plane.
+ * IDMAC 23/24/28/41 can drive a display respectively - primary
+ * IDMAC 27 depends on IDMAC 23 - nonprimary
+ */
+static inline int _ipu_is_primary_disp_chan(uint32_t dma_chan)
+{
+ return ((dma_chan == 23) || (dma_chan == 24) ||
+ (dma_chan == 28) || (dma_chan == 41));
+}
+
#define idma_is_valid(ch) (ch != NO_DMA)
#define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0)
#define idma_is_set(ipu, reg, dma) (ipu_idmac_read(ipu, reg(dma)) & idma_mask(dma))
uint32_t reg;
uint32_t in_dma, out_dma = 0;
uint32_t ipu_conf;
+ uint32_t dc_chan = 0;
_ipu_lock(ipu);
_ipu_ic_uninit_rotate_pp(ipu);
break;
case MEM_DC_SYNC:
+ dc_chan = 1;
_ipu_dc_uninit(ipu, 1);
ipu->di_use_count[ipu->dc_di_assignment[1]]--;
ipu->dc_use_count--;
ipu->dmfc_use_count--;
break;
case MEM_BG_SYNC:
+ dc_chan = 5;
_ipu_dp_uninit(ipu, channel);
_ipu_dc_uninit(ipu, 5);
ipu->di_use_count[ipu->dc_di_assignment[5]]--;
ipu->dmfc_use_count--;
break;
case DIRECT_ASYNC0:
+ dc_chan = 8;
_ipu_dc_uninit(ipu, 8);
ipu->di_use_count[ipu->dc_di_assignment[8]]--;
ipu->dc_use_count--;
break;
case DIRECT_ASYNC1:
+ dc_chan = 9;
_ipu_dc_uninit(ipu, 9);
ipu->di_use_count[ipu->dc_di_assignment[9]]--;
ipu->dc_use_count--;
ipu->channel_init_mask &= ~(1L << IPU_CHAN_ID(channel));
+ /*
+ * Disable pixel clk and its parent clock(if the parent clock
+ * usecount is 1) after clearing DC/DP/DI bits in IPU_CONF
+ * register to prevent LVDS display channel starvation.
+ */
+ if (_ipu_is_primary_disp_chan(in_dma))
+ clk_disable(&ipu->pixel_clk[ipu->dc_di_assignment[dc_chan]]);
+
_ipu_unlock(ipu);
_ipu_put(ipu);
reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
reg ^= DC_WR_CH_CONF_PROG_DI_ID;
ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
- } else
- /* Clock is already off because it must be done quickly, but
- we need to fix the ref count */
- clk_disable(&ipu->pixel_clk[ipu->dc_di_assignment[dc_chan]]);
+ }
}
void _ipu_init_dc_mappings(struct ipu_soc *ipu)