aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2011-07-21 21:03:10 -0500
committerZiyan <jaraidaniel@gmail.com>2015-04-18 01:24:20 +0200
commit5731d74f3f7ed15625e83d96cc470b62b5714f60 (patch)
tree55b85c0aaccfc32d4c230ffda0eb114a1404dde4 /drivers/video
parentaa3055605bea9d4277225b722546c19af9d364f6 (diff)
downloadkernel_samsung_tuna-5731d74f3f7ed15625e83d96cc470b62b5714f60.zip
kernel_samsung_tuna-5731d74f3f7ed15625e83d96cc470b62b5714f60.tar.gz
kernel_samsung_tuna-5731d74f3f7ed15625e83d96cc470b62b5714f60.tar.bz2
[Tablet] DSI Changes for tablet2
Modify the DSI layer for the tablet2 panel Change-Id: I00b430755c1776819de773e389b7d2814c24dd01 Signed-off-by: Dan Murphy <dmurphy@ti.com>
Diffstat (limited to 'drivers/video')
-rwxr-xr-xdrivers/video/omap2/dss/dsi.c351
1 files changed, 299 insertions, 52 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 09e35fc..6d281ab 100755
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -204,6 +204,8 @@ struct dsi_reg { u16 idx; };
#define DSI_DT_SET_MAX_RET_PKG_SIZE 0x37
#define DSI_DT_NULL_PACKET 0x09
#define DSI_DT_DCS_LONG_WRITE 0x39
+#define DSI_DT_GENERIC_READ_2 0x24
+#define DSI_DT_GENERIC_LONG_WRITE 0x29
#define DSI_DT_RX_ACK_WITH_ERR 0x02
#define DSI_DT_RX_LONG_READ 0x1a
@@ -742,9 +744,7 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
vcstatus[i] = 0;
continue;
}
-
vcstatus[i] = dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
-
dsi_write_reg(dsidev, DSI_VC_IRQSTATUS(i), vcstatus[i]);
/* flush posted write */
dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
@@ -2787,12 +2787,9 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH))
- r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */
-/* TODO: This breaks DSI on Blaze: figure out what is the righ fix */
-#if 0
+ r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */
if (channel == 0)
- r = FLD_MOD(r, 1, 11, 10); /* OCP_WIDTH = 32 bit */
-#endif
+ r = FLD_MOD(r, 1, 11, 10); /* OCP_WIDTH = 32 bit */
r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
@@ -2956,10 +2953,6 @@ static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev,
} else if (dt == DSI_DT_RX_SHORT_READ_2) {
DSSERR("\tDCS short response, 2 byte: %#x\n",
FLD_GET(val, 23, 8));
- } else if (dt == DSI_DT_RX_LONG_READ) {
- DSSERR("\tlong response, len %d\n",
- FLD_GET(val, 23, 8));
- dsi_vc_flush_long_data(dsidev, channel);
} else if (dt == DSI_DT_RX_DCS_LONG_READ) {
DSSERR("\tDCS long response, len %d\n",
FLD_GET(val, 23, 8));
@@ -2995,14 +2988,9 @@ int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
DECLARE_COMPLETION_ONSTACK(completion);
- int r = 0;
+ int r = 0, i = 0;
u32 err;
- r = dsi_register_isr_vc(dsidev, channel, dsi_completion_handler,
- &completion, DSI_VC_IRQ_BTA);
- if (r)
- goto err0;
-
r = dsi_register_isr(dsidev, dsi_completion_handler, &completion,
DSI_IRQ_ERROR_MASK);
if (r)
@@ -3010,29 +2998,32 @@ int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
r = dsi_vc_send_bta(dsidev, channel);
if (r)
- goto err2;
+ goto err1;
- if (wait_for_completion_timeout(&completion,
- msecs_to_jiffies(500)) == 0) {
- DSSERR("Failed to receive BTA\n");
- r = -EIO;
- goto err2;
+ /* wait for BTA ACK */
+ while (i < 500) {
+ if (REG_GET(dsidev, DSI_VC_IRQSTATUS(channel), 5, 5)) {
+ DSSDBG("BTA recieved\n");
+ REG_FLD_MOD(dsidev, DSI_VC_IRQSTATUS(channel), 1, 5, 5);
+ break;
+ }
+ i++;
+ mdelay(1);
}
+ if (i >= 500)
+ DSSERR("sending BTA failed\n");
+
err = dsi_get_errors(dsidev);
if (err) {
DSSERR("Error while sending BTA: %x\n", err);
r = -EIO;
- goto err2;
}
-err2:
+
+err1:
dsi_unregister_isr(dsidev, dsi_completion_handler, &completion,
DSI_IRQ_ERROR_MASK);
-err1:
- dsi_unregister_isr_vc(dsidev, channel, dsi_completion_handler,
- &completion, DSI_VC_IRQ_BTA);
-err0:
- return r;
+ return 0;
}
@@ -3053,6 +3044,8 @@ static inline void dsi_vc_write_long_header(struct platform_device *dsidev,
val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
FLD_VAL(ecc, 31, 24);
+ DSSDBG("writing header %x\n", val);
+
dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_HEADER(channel), val);
}
@@ -3066,6 +3059,7 @@ static inline void dsi_vc_write_long_payload(struct platform_device *dsidev,
/* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
b1, b2, b3, b4, val); */
+ DSSDBG("sending payload %x\n", val);
dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
}
@@ -3079,8 +3073,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
int r = 0;
u8 b1, b2, b3, b4;
- if (dsi->debug_write)
- DSSDBG("dsi_vc_send_long, %d bytes\n", len);
+ DSSDBG("dsi_vc_send_long, %d bytes\n", len);
/* len + header */
if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) {
@@ -3094,8 +3087,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
p = data;
for (i = 0; i < len >> 2; i++) {
- if (dsi->debug_write)
- DSSDBG("\tsending full packet %d\n", i);
+ DSSDBG("\tsending full packet %d\n", i);
b1 = *p++;
b2 = *p++;
@@ -3109,8 +3101,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
if (i) {
b1 = 0; b2 = 0; b3 = 0;
- if (dsi->debug_write)
- DSSDBG("\tsending remainder bytes %d\n", i);
+ DSSDBG("\tsending remainder bytes %d\n", i);
switch (i) {
case 3:
@@ -3130,6 +3121,20 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, 0);
}
+ /* wait for IRQ for long packet transmission confirmation */
+ for (i = 0; i < 1000; i++) {
+ u32 val;
+ val = dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(channel));
+ if (val & 0x4) {
+ DSSDBG("long packet success\n");
+ REG_FLD_MOD(dsidev, DSI_VC_IRQSTATUS(channel), 1, 2, 2);
+ return 0;
+ }
+ udelay(1);
+ }
+
+ DSSERR("long packet send failed\n");
+
return r;
}
@@ -3307,7 +3312,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
buf[1] = (data >> 8) & 0xff;
return 2;
- } else if (dt == DSI_DT_RX_DCS_LONG_READ || dt == DSI_DT_RX_LONG_READ) {
+ } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
int w;
int len = FLD_GET(val, 23, 8);
if (dsi->debug_read)
@@ -3392,6 +3397,174 @@ int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
}
EXPORT_SYMBOL(dsi_vc_dcs_read_2);
+
+int dsi_vc_gen_write_nosync(struct omap_dss_device *dssdev, int channel,
+ u8 *data, int len)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ int r;
+
+ BUG_ON(len == 0);
+
+ if (len == 1) {
+ BUG();
+ r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_0,
+ data[0], 0);
+ } else if (len == 2) {
+ BUG();
+ r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_1,
+ data[0] | (data[1] << 8), 0);
+ } else {
+ r = dsi_vc_send_long(dsidev, channel, DSI_DT_GENERIC_LONG_WRITE,
+ data, len, 0);
+ }
+
+ return r;
+}
+EXPORT_SYMBOL(dsi_vc_gen_write_nosync);
+
+int dsi_vc_gen_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+ int len)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ int r;
+
+ r = dsi_vc_gen_write_nosync(dssdev, channel, data, len);
+ if (r)
+ goto err;
+
+ r = dsi_vc_send_bta_sync(dssdev, channel);
+ if (r)
+ goto err;
+
+ /* RX_FIFO_NOT_EMPTY */
+ if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
+ DSSERR("rx fifo not empty after write, dumping data:\n");
+ dsi_vc_flush_receive_data(dsidev, channel);
+ r = -EIO;
+ goto err;
+ }
+
+ return 0;
+err:
+ DSSERR("dsi_vc_gen_write(ch %d, len %d) failed\n",
+ channel, len);
+ return r;
+}
+EXPORT_SYMBOL(dsi_vc_gen_write);
+
+int dsi_vc_gen_read_2(struct omap_dss_device *dssdev, int channel, u16 cmd,
+ u8 *buf, int buflen)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ u32 val;
+ u8 dt;
+ int r;
+
+ if (dsi->debug_read)
+ DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, cmd);
+
+ r = dsi_vc_send_short(dsidev, channel, DSI_DT_GENERIC_READ_2, cmd, 0);
+ if (r)
+ goto err;
+
+ r = dsi_vc_send_bta_sync(dssdev, channel);
+ if (r)
+ goto err;
+
+ /* RX_FIFO_NOT_EMPTY */
+ if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) {
+ DSSERR("RX fifo empty when trying to read.\n");
+ r = -EIO;
+ goto err;
+ }
+
+ val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
+ if (dsi->debug_read)
+ DSSDBG("\theader: %08x\n", val);
+ dt = FLD_GET(val, 5, 0);
+ if (dt == DSI_DT_RX_ACK_WITH_ERR) {
+ u16 err = FLD_GET(val, 23, 8);
+ dsi_show_rx_ack_with_err(err);
+ r = -EIO;
+ goto err;
+
+ } else if (dt == DSI_DT_RX_SHORT_READ_1) {
+ u8 data = FLD_GET(val, 15, 8);
+ if (dsi->debug_read)
+ DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
+
+ if (buflen < 1) {
+ r = -EIO;
+ goto err;
+ }
+
+ buf[0] = data;
+
+ return 1;
+ } else if (dt == DSI_DT_RX_SHORT_READ_2) {
+ u16 data = FLD_GET(val, 23, 8);
+ if (dsi->debug_read)
+ DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
+
+ if (buflen < 2) {
+ r = -EIO;
+ goto err;
+ }
+
+ buf[0] = data & 0xff;
+ buf[1] = (data >> 8) & 0xff;
+
+ return 2;
+ } else if (dt == DSI_DT_RX_LONG_READ) {
+ int w;
+ int len = FLD_GET(val, 23, 8);
+ if (dsi->debug_read)
+ DSSDBG("\tDCS long response, len %d\n", len);
+
+ if (len > buflen) {
+ r = -EIO;
+ goto err;
+ }
+
+ /* two byte checksum ends the packet, not included in len */
+ for (w = 0; w < len + 2;) {
+ int b;
+ val = dsi_read_reg(dsidev,
+ DSI_VC_SHORT_PACKET_HEADER(channel));
+ if (dsi->debug_read)
+ DSSDBG("\t\t%02x %02x %02x %02x\n",
+ (val >> 0) & 0xff,
+ (val >> 8) & 0xff,
+ (val >> 16) & 0xff,
+ (val >> 24) & 0xff);
+
+ for (b = 0; b < 4; ++b) {
+ if (w < len)
+ buf[w] = (val >> (b * 8)) & 0xff;
+ /* we discard the 2 byte checksum */
+ ++w;
+ }
+ }
+
+ return len;
+ } else {
+ DSSERR("\tunknown datatype 0x%02x\n", dt);
+ r = -EIO;
+ goto err;
+ }
+
+ BUG();
+err:
+ DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
+ channel, cmd);
+ return r;
+
+}
+EXPORT_SYMBOL(dsi_vc_gen_read_2);
+
+
int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
u16 len)
{
@@ -3522,7 +3695,7 @@ static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks,
fck = dsi_fclk_rate(dsidev);
r = dsi_read_reg(dsidev, DSI_TIMING1);
- r = FLD_MOD(r, to ? 1 : 0, 31, 31); /* TA_TO */
+ r = FLD_MOD(r, 0, 31, 31); /* TA_TO */
r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */
r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */
r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */
@@ -3777,13 +3950,12 @@ int dsi_video_mode_enable(struct omap_dss_device *dssdev, u8 data_type)
u32 r;
u32 header;
- dsi_if_enable(dsidev, 0);
- dsi_vc_enable(dsidev, 1, 0);
- dsi_vc_enable(dsidev, 0, 0);
+ dsi_if_enable(dsidev, false);
+ dsi_vc_enable(dsidev, 1, false);
+ dsi_vc_enable(dsidev, 0, false);
- r = dsi_read_reg(dsidev, DSI_TIMING1);
- r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
- dsi_write_reg(dsidev, DSI_TIMING1, r);
+ /* FORCE_TX_STOP_MODE_IO */
+ /* REG_FLD_MOD(dsidev, DSI_TIMING1, 1, 15, 15); */
if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 15, 0) != 0)
BUG();
@@ -3792,11 +3964,7 @@ int dsi_video_mode_enable(struct omap_dss_device *dssdev, u8 data_type)
r = FLD_MOD(r, 1, 4, 4);
r = FLD_MOD(r, 1, 9, 9);
dsi_write_reg(dsidev, DSI_VC_CTRL(0), r);
-
- r = dsi_read_reg(dsidev, DSI_VC_CTRL(1));
- r = FLD_MOD(r, 0, 4, 4);
- r = FLD_MOD(r, 1, 9, 9);
- dsi_write_reg(dsidev, DSI_VC_CTRL(1), r);
+ dsi_write_reg(dsidev, DSI_VC_CTRL(0) , 0x20800790);
word_count = dssdev->panel.timings.x_res * 3;
header = FLD_VAL(0, 31, 24) | /* ECC */
@@ -3805,12 +3973,27 @@ int dsi_video_mode_enable(struct omap_dss_device *dssdev, u8 data_type)
FLD_VAL(data_type, 5, 0);
dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_HEADER(0), header);
- dsi_vc_enable(dsidev, 1, 1);
- dsi_vc_enable(dsidev, 0, 1);
- dsi_if_enable(dsidev, 1);
+ dsi_vc_enable(dsidev, 0, true);
+ dsi_if_enable(dsidev, true);
+
+ msleep(2);
+
+ dssdev->manager->enable(dssdev->manager);
+
+ /* FORCE_TX_STOP_MODE_IO */
+ REG_FLD_MOD(dsidev, DSI_TIMING1, 0, 15, 15);
+
+ msleep(2);
return 0;
}
+EXPORT_SYMBOL(dsi_video_mode_enable);
+
+void dsi_video_mode_disable(struct omap_dss_device *dssdev)
+{
+ dssdev->manager->disable(dssdev->manager);
+}
+EXPORT_SYMBOL(dsi_video_mode_disable);
static void dsi_proto_timings(struct omap_dss_device *dssdev)
{
@@ -4483,6 +4666,21 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
dsi_pll_uninit(dsidev, disconnect_lanes);
}
+static int _dsi_wait_reset(struct platform_device *dsidev)
+{
+ int t = 0;
+
+ while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) {
+ if (++t > 5) {
+ DSSERR("soft reset failed\n");
+ return -ENODEV;
+ }
+ udelay(1);
+ }
+
+ return 0;
+}
+
int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4508,6 +4706,11 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
if(!dssdev->skip_init)
dsi_enable_pll_clock(dsidev, 1);
+ /* Soft reset */
+ REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1);
+ _dsi_wait_reset(dsidev);
+
+
_dsi_initialize_irq(dsidev);
if(!dssdev->skip_init){
@@ -4907,3 +5110,47 @@ void dsi_uninit_platform_driver(void)
{
return platform_driver_unregister(&omap_dsi1hw_driver);
}
+
+
+
+
+/* set extra register hardcoding values for now (according to kozio) */
+void dsi_videomode_panel_preinit(struct omap_dss_device *dssdev)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+
+ dsi_vc_enable(dsidev, 0, false);
+ dsi_vc_enable(dsidev, 1, false);
+ dsi_if_enable(dsidev, false);
+
+ /* configure timings */
+ dsi_write_reg(dsidev, DSI_VM_TIMING1, 0x010D301A); /* HSA=1, HFP=211, HBP=26 */
+ dsi_write_reg(dsidev, DSI_VM_TIMING2, 0x04080F0F); /* WINDOW_SIZE=4, VSA=8, VFP=15, VBP=15 */
+ dsi_write_reg(dsidev, DSI_VM_TIMING3, 0x04B00320); /* TL(31:16)=1200, VACT(15:0)=800 */
+
+ dsi_write_reg(dsidev, DSI_VM_TIMING4, 0x00487296); /* HSA_HS_INTERLEAVING(23:16)=72, HFP_HS_INTERLEAVING(15:8)=114, HBP_HS_INTERLEAVING(7:0)=150 */
+ dsi_write_reg(dsidev, DSI_VM_TIMING5, 0x0082DF3B); /* VC3_FIFO_EMPTINESS, VC2_FIFO_EMPTINESS, VC1_FIFO_EMPTINESS, VC0_FIFO_EMPTINESS */
+ dsi_write_reg(dsidev, DSI_VM_TIMING6, 0x7A6731D1); /* HSA_LP_INTERLEAVING(23:16)=103, HFP_HS_INTERLEAVING(15:8)=49, HBP_HS_INTERLEAVING(7:0)=209 */
+ dsi_write_reg(dsidev, DSI_VM_TIMING7, 0x000E0013); /* BL_HS_INTERLEAVING(23:16)=14, BL_LP_INTERLEAVING(15:0)=19 */
+
+
+ /* set TA_TO_COUNTER accordignly to kozio value(???) */
+ /* enable TA_TO and set it to max */
+ /* disable stop_mode but set it to max */
+ /* dsi_write_reg(dsidev, DSI_TIMING1, 0xFFFF7FFF) */
+
+ /* set TA_TO_COUNTER accordignly to kozio value(???) */
+ /* disable LP_RX_TO but set it to max */
+ /* enable HS_TX_TO and set it to max */
+ /* dsi_write_reg(dsidev, DSI_TIMING2, 0xFFFF7FFF) */
+
+ dsi_vc_enable(dsidev, 1, true);
+ dsi_vc_enable(dsidev, 0, true);
+ dsi_if_enable(dsidev, true);
+
+ /* Send null packet to start DDR clock */
+ dsi_write_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(0), 0);
+ msleep(1);
+}
+EXPORT_SYMBOL(dsi_videomode_panel_preinit);
+