aboutsummaryrefslogtreecommitdiff
path: root/drivers/video/mcde/mcde_hw.c
diff options
context:
space:
mode:
authorJimmy Rubin <jimmy.rubin@stericsson.com>2010-10-12 14:21:00 +0200
committerJonas ABERG <jonas.aberg@stericsson.com>2010-12-08 08:32:38 +0100
commitbffb8da32a433b0b67ba8e81194c1ceb81499b3c (patch)
tree40110029c9bde0d6dcbd35bc22118b8bf2da156e /drivers/video/mcde/mcde_hw.c
parent9fc85f544d2cbf50386df1f5da5848f663104f7c (diff)
MCDE: Add maja support
This patch does the following: * Adds support for maja hw * Enables HW MEM for Maja ST Ericsson ID: WP 279382 Change-Id: I21e9841359f06ca00c75d36cbc6a5a29059b0a11 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/9963 Tested-by: Jimmy RUBIN <jimmy.rubin@stericsson.com> Reviewed-by: Dan JOHANSSON <dan.johansson@stericsson.com>
Diffstat (limited to 'drivers/video/mcde/mcde_hw.c')
-rw-r--r--drivers/video/mcde/mcde_hw.c170
1 files changed, 132 insertions, 38 deletions
diff --git a/drivers/video/mcde/mcde_hw.c b/drivers/video/mcde/mcde_hw.c
index a09e31e3747..8f80e3e9ac3 100644
--- a/drivers/video/mcde/mcde_hw.c
+++ b/drivers/video/mcde/mcde_hw.c
@@ -53,9 +53,11 @@ static u8 num_channels;
static u8 num_overlays;
static u8 hardware_version;
+#ifdef CONFIG_REGULATOR
static struct regulator *regulator_vana;
static struct regulator *regulator_mcde_epod;
static struct regulator *regulator_esram_epod;
+#endif
static struct clk *clock_dpi;
static struct clk *clock_dsi;
static struct clk *clock_mcde;
@@ -350,6 +352,7 @@ static int enable_clocks_and_power(struct platform_device *pdev)
dev_vdbg(&mcde_dev->dev, "%s\n", __func__);
+#ifdef CONFIG_REGULATOR
if (regulator_mcde_epod) {
ret = regulator_enable(regulator_mcde_epod);
if (ret < 0) {
@@ -387,6 +390,7 @@ static int enable_clocks_and_power(struct platform_device *pdev)
, __func__);
goto regulator_vana_err;
}
+#endif
ret = pdata->platform_enable();
if (ret < 0) {
@@ -432,6 +436,7 @@ clk_dsi_err:
clk_dpi_err:
pdata->platform_disable();
prcmu_err:
+#ifdef CONFIG_REGULATOR
if (regulator_vana)
regulator_disable(regulator_vana);
regulator_vana_err:
@@ -440,6 +445,7 @@ regulator_vana_err:
regulator_esram_err:
if (regulator_mcde_epod)
regulator_disable(regulator_mcde_epod);
+#endif
return ret;
}
@@ -457,6 +463,7 @@ static int disable_clocks_and_power(struct platform_device *pdev)
pdata->platform_disable();
+#ifdef CONFIG_REGULATOR
if (regulator_vana) {
ret = regulator_disable(regulator_vana);
if (ret < 0) {
@@ -494,8 +501,8 @@ static int disable_clocks_and_power(struct platform_device *pdev)
dev_warn(&pdev->dev, "%s: esram_epod regulator is null\n"
, __func__);
}
-
return ret;
+
regulator_esram_epod_err:
regulator_enable(regulator_mcde_epod);
regulator_mcde_epod_err:
@@ -505,6 +512,7 @@ regulator_vana_err:
clk_enable(clock_dsi_lp);
clk_enable(clock_mcde);
clk_enable(clock_dsi);
+#endif
return ret;
}
@@ -512,33 +520,46 @@ static void update_mcde_registers(void)
{
struct mcde_platform_data *pdata = mcde_dev->dev.platform_data;
- /* Setup output muxing */
- mcde_wreg(MCDE_CONF0,
- MCDE_CONF0_IFIFOCTRLWTRMRKLVL(7) |
- MCDE_CONF0_OUTMUX0(pdata->outmux[0]) |
- MCDE_CONF0_OUTMUX1(pdata->outmux[1]) |
- MCDE_CONF0_OUTMUX2(pdata->outmux[2]) |
- MCDE_CONF0_OUTMUX3(pdata->outmux[3]) |
- MCDE_CONF0_OUTMUX4(pdata->outmux[4]) |
- pdata->syncmux);
-
- mcde_wfld(MCDE_RISOVL, OVLFDRIS, 1);
- mcde_wfld(MCDE_RISPP, VCMPARIS, 1);
- mcde_wfld(MCDE_RISPP, VCMPBRIS, 1);
- mcde_wfld(MCDE_RISPP, VCMPC0RIS, 1);
- mcde_wfld(MCDE_RISPP, VCMPC1RIS, 1);
-
- /* Enable channel VCMP interrupts */
- mcde_wreg(MCDE_IMSCPP,
- MCDE_IMSCPP_VCMPAIM(true) |
- MCDE_IMSCPP_VCMPBIM(true) |
- MCDE_IMSCPP_VCMPC0IM(true) |
- MCDE_IMSCPP_VCMPC1IM(true));
+ if (hardware_version == MCDE_CHIP_VERSION_1_0_4) {
+ /* Setup output muxing */
+ mcde_wreg(MCDE_CONF0,
+ MCDE_CONF0_IFIFOCTRLWTRMRKLVL(7));
- /* Enable overlay fetch done interrupts */
- mcde_wfld(MCDE_IMSCOVL, OVLFDIM, 0x3f);
+ mcde_wfld(MCDE_RISOVL, OVLFDRIS, 1);
+ mcde_wfld(MCDE_RISPP, VCMPARIS, 1);
+ mcde_wfld(MCDE_RISPP, VCMPBRIS, 1);
+ /* Enable channel VCMP interrupts */
+ mcde_wreg(MCDE_IMSCPP,
+ MCDE_IMSCPP_VCMPAIM(true) |
+ MCDE_IMSCPP_VCMPBIM(true));
+ } else {
+ /* Setup output muxing */
+ mcde_wreg(MCDE_CONF0,
+ MCDE_CONF0_IFIFOCTRLWTRMRKLVL(7) |
+ MCDE_CONF0_OUTMUX0(pdata->outmux[0]) |
+ MCDE_CONF0_OUTMUX1(pdata->outmux[1]) |
+ MCDE_CONF0_OUTMUX2(pdata->outmux[2]) |
+ MCDE_CONF0_OUTMUX3(pdata->outmux[3]) |
+ MCDE_CONF0_OUTMUX4(pdata->outmux[4]) |
+ pdata->syncmux);
+
+ mcde_wfld(MCDE_RISOVL, OVLFDRIS, 1);
+ mcde_wfld(MCDE_RISPP, VCMPARIS, 1);
+ mcde_wfld(MCDE_RISPP, VCMPBRIS, 1);
+ mcde_wfld(MCDE_RISPP, VCMPC0RIS, 1);
+ mcde_wfld(MCDE_RISPP, VCMPC1RIS, 1);
+
+ /* Enable channel VCMP interrupts */
+ mcde_wreg(MCDE_IMSCPP,
+ MCDE_IMSCPP_VCMPAIM(true) |
+ MCDE_IMSCPP_VCMPBIM(true) |
+ MCDE_IMSCPP_VCMPC0IM(true) |
+ MCDE_IMSCPP_VCMPC1IM(true));
+ }
+ /* Enable overlay fetch done interrupts */
+ mcde_wfld(MCDE_IMSCOVL, OVLFDIM, 0x3f);
/* Setup sync pulse length */
mcde_wreg(MCDE_VSCRC0,
@@ -859,7 +880,10 @@ static u32 get_output_fifo_size(enum mcde_fifo fifo)
switch (fifo) {
case MCDE_FIFO_A:
case MCDE_FIFO_B:
- ret = MCDE_FIFO_AB_SIZE;
+ if (hardware_version == MCDE_CHIP_VERSION_1_0_4)
+ ret = MCDE_FIFO_AB_SIZE / 2;
+ else
+ ret = MCDE_FIFO_AB_SIZE;
break;
case MCDE_FIFO_C0:
case MCDE_FIFO_C1:
@@ -1194,6 +1218,46 @@ static int update_channel_static_registers(struct mcde_chnl_state *chnl)
default:
return -EINVAL;
}
+ } else if (hardware_version == MCDE_CHIP_VERSION_1_0_4) {
+ switch (chnl->fifo) {
+ case MCDE_FIFO_A:
+ /* only channel A is supported */
+ if (chnl->id != 0)
+ return -EINVAL;
+
+ if (port->type == MCDE_PORTTYPE_DSI) {
+ if (port->link == 1 && port->ifc == 0)
+ return -EINVAL;
+ if (port->link == 0 && port->ifc == 1)
+ return -EINVAL;
+ mcde_wfld(MCDE_CR, DSI0_EN_V3, true);
+
+ } else if (port->type == MCDE_PORTTYPE_DPI) {
+ mcde_wfld(MCDE_CR, DPI_EN_V3, true);
+ }
+ mcde_wfld(MCDE_CTRLA, FIFOWTRMRK,
+ get_output_fifo_size(MCDE_FIFO_A));
+ break;
+ case MCDE_FIFO_B:
+ if (port->type != MCDE_PORTTYPE_DSI)
+ return -EINVAL;
+ /* only channel B is supported */
+ if (chnl->id != 1)
+ return -EINVAL;
+
+ if (port->link == 0 && port->ifc == 0)
+ return -EINVAL;
+ if (port->link == 1 && port->ifc == 0)
+ return -EINVAL;
+
+ mcde_wfld(MCDE_CR, DSI1_EN_V3, true);
+ mcde_wfld(MCDE_CTRLB, FIFOWTRMRK,
+ get_output_fifo_size(MCDE_FIFO_B));
+
+ break;
+ default:
+ return -EINVAL;
+ }
}
/* Formatter */
@@ -1202,7 +1266,10 @@ static int update_channel_static_registers(struct mcde_chnl_state *chnl)
u8 idx;
u8 lnk = port->link;
- idx = 2 * port->link + port->ifc;
+ if (hardware_version == MCDE_CHIP_VERSION_1_0_4)
+ idx = chnl->id;
+ else
+ idx = 2 * port->link + port->ifc;
dsi_wfld(lnk, DSI_MCTL_MAIN_DATA_CTL, LINK_EN, true);
dsi_wfld(lnk, DSI_MCTL_MAIN_DATA_CTL, BTA_EN, true);
@@ -1743,7 +1810,10 @@ void update_channel_registers(enum mcde_chnl chnl_id, struct chnl_regs *regs,
u32 dsi_delay0 = 0;
u32 screen_ppl, screen_lpf;
- fidx = 2 * port->link + port->ifc;
+ if (hardware_version == MCDE_CHIP_VERSION_1_0_4)
+ fidx = chnl_id;
+ else
+ fidx = 2 * port->link + port->ifc;
screen_ppl = video_mode->xres;
screen_lpf = video_mode->yres;
@@ -1824,6 +1894,8 @@ int mcde_dsi_dcs_write(struct mcde_chnl_state *chnl, u8 cmd, u8* data, int len)
u32 settings;
u8 link = chnl->port.link;
u8 virt_id = chnl->port.phy.dsi.virt_id;
+ u32 ok;
+ u32 error;
/* REVIEW: One command at a time */
/* REVIEW: Allow read/write on unreserved ports */
@@ -1869,6 +1941,11 @@ int mcde_dsi_dcs_write(struct mcde_chnl_state *chnl, u8 cmd, u8* data, int len)
/* TODO: irq wait and error check */
mdelay(10);
+
+ ok = dsi_rreg(link, DSI_DIRECT_CMD_STS);
+ error = dsi_rreg(link, DSI_CMD_MODE_STS);
+ dev_vdbg(&mcde_dev->dev, "DSI Write ok %x error %x\n", ok, error);
+
dsi_wreg(link, DSI_CMD_MODE_STS_CLR, ~0);
dsi_wreg(link, DSI_DIRECT_CMD_STS_CLR, ~0);
@@ -1924,7 +2001,7 @@ int mcde_dsi_dcs_read(struct mcde_chnl_state *chnl, u8 cmd, u8* data, int *len)
rdsize = dsi_rfld(link, DSI_DIRECT_CMD_RD_PROPERTY, RD_SIZE);
rddat = dsi_rreg(link, DSI_DIRECT_CMD_RDDAT);
if (rdsize < *len)
- pr_debug("DCS incomplete read %d<%d (%.8X)\n",
+ pr_err("DCS incomplete read %d<%d (%.8X)\n",
rdsize, *len, rddat);/* REVIEW: dev_dbg */
*len = min(*len, rdsize);
memcpy(data, &rddat, *len);
@@ -2707,6 +2784,7 @@ static int init_clocks_and_power(struct platform_device *pdev)
int ret = 0;
struct mcde_platform_data *pdata = pdev->dev.platform_data;
+#ifdef CONFIG_REGULATOR
if (pdata->regulator_mcde_epod_id) {
regulator_mcde_epod = regulator_get(&pdev->dev,
pdata->regulator_mcde_epod_id);
@@ -2757,6 +2835,7 @@ static int init_clocks_and_power(struct platform_device *pdev)
ret = -EINVAL;
goto regulator_vana_err;
}
+#endif
clock_dsi = clk_get(&pdev->dev, pdata->clock_dsi_id);
if (IS_ERR(clock_dsi)) {
@@ -2799,6 +2878,7 @@ clk_dpi_err:
clk_dsi_lp_err:
clk_put(clock_dsi);
clk_dsi_err:
+#ifdef CONFIG_REGULATOR
if (regulator_vana)
regulator_put(regulator_vana);
regulator_vana_err:
@@ -2807,6 +2887,7 @@ regulator_vana_err:
regulator_esram_err:
if (regulator_mcde_epod)
regulator_put(regulator_mcde_epod);
+#endif
return ret;
}
@@ -2818,13 +2899,14 @@ static void remove_clocks_and_power(struct platform_device *pdev)
clk_put(clock_dsi_lp);
clk_put(clock_dsi);
clk_put(clock_mcde);
-
+#ifdef CONFIG_REGULATOR
if (regulator_vana)
regulator_put(regulator_vana);
if (regulator_mcde_epod)
regulator_put(regulator_mcde_epod);
if (regulator_esram_epod)
regulator_put(regulator_esram_epod);
+#endif
}
static int __devinit mcde_probe(struct platform_device *pdev)
@@ -2948,6 +3030,11 @@ static int __devinit mcde_probe(struct platform_device *pdev)
development_version >= 5) {
hardware_version = MCDE_CHIP_VERSION_3_0_5;
dev_info(&mcde_dev->dev, "V1 HW\n");
+ } else if (major_version == 1 && minor_version == 0 &&
+ development_version >= 4) {
+ hardware_version = MCDE_CHIP_VERSION_1_0_4;
+ mcde_dynamic_power_management = false;
+ dev_info(&mcde_dev->dev, "V1_U5500 HW\n");
} else {
dev_err(&mcde_dev->dev, "Unsupported HW version\n");
ret = -ENOTSUPP;
@@ -2958,14 +3045,21 @@ static int __devinit mcde_probe(struct platform_device *pdev)
for (i = 0; i < num_overlays; i++)
overlays[i].idx = i;
- channels[0].ovly0 = &overlays[0];
- channels[0].ovly1 = &overlays[1];
- channels[1].ovly0 = &overlays[2];
- channels[1].ovly1 = &overlays[3];
- channels[2].ovly0 = &overlays[4];
- channels[2].ovly1 = NULL;
- channels[3].ovly0 = &overlays[5];
- channels[3].ovly1 = NULL;
+ if (hardware_version == MCDE_CHIP_VERSION_1_0_4) {
+ channels[0].ovly0 = &overlays[0];
+ channels[0].ovly1 = &overlays[1];
+ channels[1].ovly0 = &overlays[2];
+ channels[1].ovly1 = NULL;
+ } else {
+ channels[0].ovly0 = &overlays[0];
+ channels[0].ovly1 = &overlays[1];
+ channels[1].ovly0 = &overlays[2];
+ channels[1].ovly1 = &overlays[3];
+ channels[2].ovly0 = &overlays[4];
+ channels[2].ovly1 = NULL;
+ channels[3].ovly0 = &overlays[5];
+ channels[3].ovly1 = NULL;
+ }
for (i = 0; i < num_channels; i++) {
channels[i].id = i;