summaryrefslogtreecommitdiff
path: root/drivers/mxc/ipu3/ipu_disp.c
diff options
context:
space:
mode:
authorJason Chen <b02280@freescale.com>2009-12-16 15:32:32 +0800
committerJustin Waters <justin.waters@timesys.com>2010-03-25 14:01:46 -0400
commit4b4cc7389a84a3e6c79586a7b65a218a5401d11a (patch)
treed98af9307e47a1c65bbf6e9877a9397ee167eb45 /drivers/mxc/ipu3/ipu_disp.c
parentacc41cfb94eece13a5d2b9dca2543885f6211a8f (diff)
ENGR00119275 ipuv3: dmfc size control
add dmfc size control for dynamic change and _setup. DMFC_NORMAL: segment 0,1 for DC, 4,5 for DP-BG, 6,7 for DP-FG. DMFC_HIGH_RESOLUTION_DC: segment 0~3 for DC, 4,5 for DP-BG, 6,7 for DP-FG. DMFC_HIGH_RESOLUTION_DP: segment 0,1 for DC, 2~5 for DP-BG, 6,7 for DP-FG. DMFC_HIGH_RESOLUTION_ONLY_DP: segment 0~3 for DP-BG, 4~7 for DP-FG. IPU diplay driver will try to enlarge its related DMFC segment size when it meet high resolution condition, but if dmfc is already in high resolution setting, dmfc will not change.That said, first request wins. For cmdline setting, "dmfc=1" is DMFC_HIGH_RESOLUTION_DC, "dmfc=2" is DMFC_HIGH_RESOLUTION_DP, "dmfc=3" is DMFC_HIGH_RESOLUTION_ONLY_DP. NOTE: DMFC_HIGH_RESOLUTION_ONLY_DP only can be set by cmdline. Signed-off-by: Jason Chen <b02280@freescale.com>
Diffstat (limited to 'drivers/mxc/ipu3/ipu_disp.c')
-rw-r--r--drivers/mxc/ipu3/ipu_disp.c120
1 files changed, 99 insertions, 21 deletions
diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c
index 505d3f7d84d7..035d0c9e4519 100644
--- a/drivers/mxc/ipu3/ipu_disp.c
+++ b/drivers/mxc/ipu3/ipu_disp.c
@@ -54,54 +54,132 @@ struct dp_csc_param_t {
#define DC_DISP_ID_SERIAL 2
#define DC_DISP_ID_ASYNC 3
+int dmfc_type_setup;
+static int dmfc_size_28, dmfc_size_29, dmfc_size_24, dmfc_size_27, dmfc_size_23;
-/* all value below is determined by fix reg setting in _ipu_dmfc_init*/
-#define DMFC_FIFO_SIZE_28 (128*4)
-#define DMFC_FIFO_SIZE_29 (64*4)
-#define DMFC_FIFO_SIZE_24 (64*4)
-#define DMFC_FIFO_SIZE_27 (128*4)
-#define DMFC_FIFO_SIZE_23 (128*4)
-
-void _ipu_dmfc_init(void)
+void _ipu_dmfc_init(int dmfc_type, int first)
{
- /* disable DMFC-IC channel*/
- __raw_writel(0x2, DMFC_IC_CTRL);
- /* 1 - segment 0 and 1; 2, 1C and 2C unused */
- __raw_writel(0x00000088, DMFC_WR_CHAN);
+ u32 dmfc_wr_chan, dmfc_dp_chan;
+
+ if (first) {
+ if (dmfc_type_setup > dmfc_type)
+ dmfc_type = dmfc_type_setup;
+ else
+ dmfc_type_setup = dmfc_type;
+
+ /* disable DMFC-IC channel*/
+ __raw_writel(0x2, DMFC_IC_CTRL);
+ } else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) {
+ printk(KERN_DEBUG "DMFC high resolution has set, will not change\n");
+ return;
+ } else
+ dmfc_type_setup = dmfc_type;
+
+ if (dmfc_type == DMFC_HIGH_RESOLUTION_DC) {
+ /* 1 - segment 0~3;
+ * 5B - segement 4, 5;
+ * 5F - segement 6, 7;
+ * 1C, 2C and 6B, 6F unused;
+ */
+ printk(KERN_INFO "IPU DMFC DC HIGH RESOLUTION: 1(0~3), 5B(4,5), 5F(6,7)\n");
+ dmfc_wr_chan = 0x00000088;
+ dmfc_dp_chan = 0x00009694;
+ dmfc_size_28 = 256*4;
+ dmfc_size_29 = 0;
+ dmfc_size_24 = 0;
+ dmfc_size_27 = 128*4;
+ dmfc_size_23 = 128*4;
+ } else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) {
+ /* 1 - segment 0, 1;
+ * 5B - segement 2~5;
+ * 5F - segement 6,7;
+ * 1C, 2C and 6B, 6F unused;
+ */
+ printk(KERN_INFO "IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)\n");
+ dmfc_wr_chan = 0x00000090;
+ dmfc_dp_chan = 0x0000968a;
+ dmfc_size_28 = 128*4;
+ dmfc_size_29 = 0;
+ dmfc_size_24 = 0;
+ dmfc_size_27 = 128*4;
+ dmfc_size_23 = 256*4;
+ } else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) {
+ /* 5B - segement 0~3;
+ * 5F - segement 4~7;
+ * 1, 1C, 2C and 6B, 6F unused;
+ */
+ printk(KERN_INFO "IPU DMFC ONLY-DP HIGH RESOLUTION: 5B(0~3), 5F(4~7)\n");
+ dmfc_wr_chan = 0x00000000;
+ dmfc_dp_chan = 0x00008c88;
+ dmfc_size_28 = 0;
+ dmfc_size_29 = 0;
+ dmfc_size_24 = 0;
+ dmfc_size_27 = 256*4;
+ dmfc_size_23 = 256*4;
+ } else {
+ /* 1 - segment 0, 1;
+ * 5B - segement 4, 5;
+ * 5F - segement 6, 7;
+ * 1C, 2C and 6B, 6F unused;
+ */
+ printk(KERN_INFO "IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n");
+ dmfc_wr_chan = 0x00000090;
+ dmfc_dp_chan = 0x00009694;
+ dmfc_size_28 = 128*4;
+ dmfc_size_29 = 0;
+ dmfc_size_24 = 0;
+ dmfc_size_27 = 128*4;
+ dmfc_size_23 = 128*4;
+ }
+ __raw_writel(dmfc_wr_chan, DMFC_WR_CHAN);
__raw_writel(0x202020F6, DMFC_WR_CHAN_DEF);
- /* 5B - segment 2 and 3; 5F - segment 4 and 5; */
- /* 6B - segment 6; 6F - segment 7 */
- __raw_writel(0x1F1E9694, DMFC_DP_CHAN);
+ __raw_writel(dmfc_dp_chan, DMFC_DP_CHAN);
/* Enable chan 5 watermark set at 5 bursts and clear at 7 bursts */
__raw_writel(0x2020F6F6, DMFC_DP_CHAN_DEF);
}
+static int __init dmfc_setup(char *options)
+{
+ get_option(&options, &dmfc_type_setup);
+ if (dmfc_type_setup > DMFC_HIGH_RESOLUTION_ONLY_DP)
+ dmfc_type_setup = DMFC_HIGH_RESOLUTION_ONLY_DP;
+ return 1;
+}
+__setup("dmfc=", dmfc_setup);
+
void _ipu_dmfc_set_wait4eot(int dma_chan, int width)
{
u32 dmfc_gen1 = __raw_readl(DMFC_GENERAL1);
+ if (width >= HIGH_RESOLUTION_WIDTH) {
+ if (dma_chan == 23)
+ _ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DP, 0);
+ else if (dma_chan == 28)
+ _ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DC, 0);
+ }
+
if (dma_chan == 23) { /*5B*/
- if (DMFC_FIFO_SIZE_23/width > 3)
+ if (dmfc_size_23/width > 3)
dmfc_gen1 |= 1UL << 20;
else
dmfc_gen1 &= ~(1UL << 20);
} else if (dma_chan == 24) { /*6B*/
- if (DMFC_FIFO_SIZE_24/width > 1)
+ if (dmfc_size_24/width > 1)
dmfc_gen1 |= 1UL << 22;
else
dmfc_gen1 &= ~(1UL << 22);
} else if (dma_chan == 27) { /*5F*/
- if (DMFC_FIFO_SIZE_27/width > 2)
+ if (dmfc_size_27/width > 2)
dmfc_gen1 |= 1UL << 21;
else
dmfc_gen1 &= ~(1UL << 21);
} else if (dma_chan == 28) { /*1*/
- if (DMFC_FIFO_SIZE_28/width > 2)
+ if (dmfc_size_28/width > 2)
dmfc_gen1 |= 1UL << 16;
else
dmfc_gen1 &= ~(1UL << 16);
} else if (dma_chan == 29) { /*6F*/
- if (DMFC_FIFO_SIZE_29/width > 1)
+ if (dmfc_size_29/width > 1)
dmfc_gen1 |= 1UL << 23;
else
dmfc_gen1 &= ~(1UL << 23);
@@ -1531,8 +1609,8 @@ int32_t ipu_disp_set_gamma_correction(ipu_channel_t channel, bool enable, int co
__raw_writel((slopek[4*i] & 0xff) | ((slopek[4*i+1] & 0xff) << 8) |
((slopek[4*i+2] & 0xff) << 16) | ((slopek[4*i+3] & 0xff) << 24), DP_GAMMA_S(flow, i));
+ reg = __raw_readl(DP_COM_CONF(flow));
if (enable) {
- reg = __raw_readl(DP_COM_CONF(flow));
if ((bg_csc_type == RGB2YUV) || (bg_csc_type == YUV2YUV))
reg |= DP_COM_CONF_GAMMA_YUV_EN;
else