msm8960: apq8064: Inital display clean up.
-- Clean up display code.
-- Add support for LVDS display.
CRs-Fixed: 348219
Change-Id: I6583234b931b9617a8b9f29d598875bd94e31d3d
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
new file mode 100644
index 0000000..2438820
--- /dev/null
+++ b/platform/msm_shared/display.c
@@ -0,0 +1,220 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <err.h>
+#include <msm_panel.h>
+#include <mdp4.h>
+#include <mipi_dsi.h>
+
+static struct msm_fb_panel_data *panel;
+
+extern int lvds_on(struct msm_fb_panel_data *pdata);
+
+static int msm_fb_alloc(struct fbcon_config *fb)
+{
+ if (fb == NULL)
+ return ERROR;
+
+ if (fb->base == NULL)
+ fb->base = memalign(4096, fb->width
+ * fb->height
+ * (fb->bpp / 8));
+
+ if (fb->base == NULL)
+ return ERROR;
+
+ return NO_ERROR;
+}
+
+int msm_display_config()
+{
+ int ret = NO_ERROR;
+ struct msm_panel_info *pinfo;
+
+ if (!panel)
+ return ERR_INVALID_ARGS;
+
+ pinfo = &(panel->panel_info);
+
+ /* Set MDP revision */
+ mdp_set_revision(panel->mdp_rev);
+
+ switch (pinfo->type) {
+ case LVDS_PANEL:
+ dprintf(INFO, "Config LVDS_PANEL.\n");
+ ret = mdp_lcdc_config(pinfo, &(panel->fb));
+ if (ret)
+ goto msm_display_config_out;
+ break;
+ case MIPI_VIDEO_PANEL:
+ dprintf(INFO, "Config MIPI_VIDEO_PANEL.\n");
+ ret = mipi_config(panel);
+ if (ret)
+ goto msm_display_config_out;
+ ret = mdp_dsi_video_config(pinfo, &(panel->fb));
+ if (ret)
+ goto msm_display_config_out;
+ break;
+ default:
+ return ERR_INVALID_ARGS;
+ };
+
+ if (pinfo->config)
+ ret = pinfo->config((void *)pinfo);
+
+msm_display_config_out:
+ return ret;
+}
+
+int msm_display_on()
+{
+ int ret = NO_ERROR;
+ struct msm_panel_info *pinfo;
+
+ if (!panel)
+ return ERR_INVALID_ARGS;
+
+ pinfo = &(panel->panel_info);
+
+ switch (pinfo->type) {
+ case LVDS_PANEL:
+ dprintf(INFO, "Turn on LVDS PANEL.\n");
+ ret = mdp_lcdc_on(panel);
+ if (ret)
+ goto msm_display_on_out;
+ ret = lvds_on(panel);
+ if (ret)
+ goto msm_display_on_out;
+ break;
+ case MIPI_VIDEO_PANEL:
+ dprintf(INFO, "Turn on MIPI_VIDEO_PANEL.\n");
+ ret = mdp_dsi_video_on();
+ if (ret)
+ goto msm_display_on_out;
+ ret = mipi_dsi_on();
+ if (ret)
+ goto msm_display_on_out;
+ break;
+ default:
+ return ERR_INVALID_ARGS;
+ };
+
+ if (pinfo->on)
+ ret = pinfo->on();
+
+msm_display_on_out:
+ return ret;
+}
+
+int msm_display_init(struct msm_fb_panel_data *pdata)
+{
+ int ret = NO_ERROR;
+
+ panel = pdata;
+ if (!panel) {
+ ret = ERR_INVALID_ARGS;
+ goto msm_display_init_out;
+ }
+
+ /* Enable clock */
+ if (pdata->clk_func)
+ ret = pdata->clk_func(1);
+
+ if (ret)
+ goto msm_display_init_out;
+
+ /* Turn on panel */
+ if (pdata->power_func)
+ ret = pdata->power_func(1);
+
+ if (ret)
+ goto msm_display_init_out;
+
+ ret = msm_fb_alloc(&(panel->fb));
+ if (ret)
+ goto msm_display_init_out;
+
+ fbcon_setup(&(panel->fb));
+ ret = msm_display_config();
+ if (ret)
+ goto msm_display_init_out;
+
+ ret = msm_display_on();
+ if (ret)
+ goto msm_display_init_out;
+
+msm_display_init_out:
+ return ret;
+}
+
+int msm_display_off()
+{
+ int ret = NO_ERROR;
+ struct msm_panel_info *pinfo;
+
+ if (!panel)
+ return ERR_INVALID_ARGS;
+
+ pinfo = &(panel->panel_info);
+
+ switch (pinfo->type) {
+ case LVDS_PANEL:
+ dprintf(INFO, "Turn off LVDS PANEL.\n");
+ mdp_lcdc_off();
+ break;
+ case MIPI_VIDEO_PANEL:
+ dprintf(INFO, "Turn off MIPI_VIDEO_PANEL.\n");
+ ret = mdp_dsi_video_off();
+ if (ret)
+ goto msm_display_off_out;
+ ret = mipi_dsi_off();
+ if (ret)
+ goto msm_display_off_out;
+ break;
+ default:
+ return ERR_INVALID_ARGS;
+ };
+
+ if (pinfo->off)
+ ret = pinfo->off();
+
+ /* Disable clock */
+ if (panel->clk_func)
+ ret = panel->clk_func(0);
+
+ if (ret)
+ goto msm_display_off_out;
+
+ /* Disable panel */
+ if (panel->power_func)
+ ret = panel->power_func(0);
+
+msm_display_off_out:
+ return ret;
+}
diff --git a/platform/msm_shared/include/mdp3.h b/platform/msm_shared/include/mdp3.h
index 9d690c6..d4a3081 100644
--- a/platform/msm_shared/include/mdp3.h
+++ b/platform/msm_shared/include/mdp3.h
@@ -49,3 +49,5 @@
void mdp_disable(void);
void mdp_shutdown(void);
+void mdp_set_revision(int rev);
+int mdp_get_revision();
diff --git a/platform/msm_shared/include/mdp4.h b/platform/msm_shared/include/mdp4.h
index 3ee82b3..df7cbb0 100644
--- a/platform/msm_shared/include/mdp4.h
+++ b/platform/msm_shared/include/mdp4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -26,7 +26,11 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
+#ifndef _PLATFORM_MSM_SHARED_MDP_4_H_
+#define _PLATFORM_MSM_SHARED_MDP_4_H_
+
#include <dev/fbcon.h>
+#include <msm_panel.h>
//TODO: Make a global PASS / FAIL define
#define PASS 0
@@ -43,12 +47,47 @@
#define MDP_DSI_CMD_MODE_ID_MAP REG_MDP(0x000A0)
#define MDP_DSI_CMD_MODE_TRIGGER_EN REG_MDP(0x000A4)
#define MDP_OVERLAYPROC0_CFG REG_MDP(0x10004)
+#define MDP_OVERLAYPROC0_OPMODE REG_MDP(0x10014)
+#define MDP_LAYERMIXER_IN_CFG REG_MDP(0x10100)
+#define MDP_OVERLAY_REG_FLUSH REG_MDP(0x18000)
+
+#define MDP_RGB1_SRC_SIZE REG_MDP(0x40000)
+#define MDP_RGB1_SRC_XY REG_MDP(0x40004)
+#define MDP_RGB1_OUT_SIZE REG_MDP(0x40008)
+#define MDP_RGB1_OUT_XY REG_MDP(0x4000C)
+#define MDP_RGB1_SRCP0_ADDR REG_MDP(0x40010)
+#define MDP_RGB1_SRCP0_ADDR_1 REG_MDP(0x40014)
+#define MDP_RGB1_SRCP0_ADDR_2 REG_MDP(0x40018)
+#define MDP_RGB1_SRC_YSTRIDE1 REG_MDP(0x40040)
+#define MDP_RGB1_SRC_FORMAT REG_MDP(0x40050)
+#define MDP_RGB1_CONSTANT_COLOR REG_MDP(0x41008)
+
#define MDP_DMA_P_CONFIG REG_MDP(0x90000)
#define MDP_DMA_P_OUT_XY REG_MDP(0x90010)
#define MDP_DMA_P_SIZE REG_MDP(0x90004)
#define MDP_DMA_P_BUF_ADDR REG_MDP(0x90008)
#define MDP_DMA_P_BUF_Y_STRIDE REG_MDP(0x9000C)
#define MDP_DMA_P_OP_MODE REG_MDP(0x90070)
+
+#define MDP_LCDC_EN REG_MDP(0xC0000)
+#define MDP_LCDC_HSYNC_CTL REG_MDP(0xC0004)
+#define MDP_LCDC_VSYNC_PERIOD REG_MDP(0xC0008)
+#define MDP_LCDC_VSYNC_PULSE_WIDTH REG_MDP(0xC000C)
+#define MDP_LCDC_DISPLAY_HCTL REG_MDP(0xC0010)
+#define MDP_LCDC_DISPLAY_V_START REG_MDP(0xC0014)
+#define MDP_LCDC_DISPLAY_V_END REG_MDP(0xC0018)
+#define MDP_LCDC_ACTIVE_HCTL REG_MDP(0xC001C)
+#define MDP_LCDC_ACTIVE_V_START REG_MDP(0xC0020)
+#define MDP_LCDC_ACTIVE_V_END REG_MDP(0xC0024)
+#define MDP_LCDC_BORDER_CLR REG_MDP(0xC0028)
+#define MDP_LCDC_UNDERFLOW_CTL REG_MDP(0xC002C)
+#define MDP_LCDC_HSYNC_SKEW REG_MDP(0xC0030)
+#define MDP_LCDC_TEST_CTL REG_MDP(0xC0034)
+#define MDP_LCDC_CTL_POLARITY REG_MDP(0xC0038)
+#define MDP_LCDC_TEST_COL_VAR1 REG_MDP(0xC003C)
+#define MDP_LCDC_UNDERFLOW_HIDING_CTL REG_MDP(0xC0044)
+#define MDP_LCDC_LOST_PIXEL_CNT_VALUE REG_MDP(0xC0048)
+
#define MDP_DSI_VIDEO_EN REG_MDP(0xE0000)
#define MDP_DSI_VIDEO_HSYNC_CTL REG_MDP(0xE0004)
#define MDP_DSI_VIDEO_VSYNC_PERIOD REG_MDP(0xE0008)
@@ -65,28 +104,61 @@
#define MDP_TEST_MODE_CLK REG_MDP(0xF0000)
#define MDP_INTR_STATUS REG_MDP(0x00054)
+#define DMA_DSTC0G_8BITS (BIT(1)|BIT(0))
+#define DMA_DSTC1B_8BITS (BIT(3)|BIT(2))
+#define DMA_DSTC2R_8BITS (BIT(5)|BIT(4))
+#define CLR_G 0x0
+#define CLR_B 0x1
+#define CLR_R 0x2
+#define MDP_GET_PACK_PATTERN(a, x, y, z, bit) \
+ (((a)<<(bit*3))|((x)<<(bit*2))|((y)<<bit)|(z))
+#define DMA_PACK_ALIGN_LSB 0
+#define DMA_PACK_PATTERN_RGB \
+ (MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
+#define DMA_DITHER_EN BIT(24)
+#define DMA_OUT_SEL_LCDC BIT(20)
+#define DMA_IBUF_FORMAT_RGB888 (0 << 25)
+#define DMA_IBUF_FORMAT_RGB565 (1 << 25)
+#define MDP_RGB_888_FORMAT \
+ (BIT(17) | (1<<14) | (2<<9) | \
+ (0<<8) | (0<<6) | (3<<4) | \
+ (3<<2) | (3<<0))
+#define MDP_RGB_565_FORMAT \
+ (BIT(17) | (1<<14) | (1<<9) | \
+ (0<<8) | (0<<6) | (1<<4) | \
+ (1<<2) | (2<<0))
+
void mdp_setup_dma_p_video_config(unsigned short pack_pattern,
- unsigned short img_width,
- unsigned short img_height,
- unsigned long input_img_addr,
- unsigned short img_width_full_size,
- unsigned char ystride);
+ unsigned short img_width,
+ unsigned short img_height,
+ unsigned long input_img_addr,
+ unsigned short img_width_full_size,
+ unsigned char ystride);
int mdp_setup_dma_p_video_mode(unsigned short disp_width,
- unsigned short disp_height,
- unsigned short img_width,
- unsigned short img_height,
- unsigned short hsync_porch0_fp,
- unsigned short hsync_porch0_bp,
- unsigned short vsync_porch0_fp,
- unsigned short vsync_porch0_bp,
- unsigned short hsync_width,
- unsigned short vsync_width,
- unsigned long input_img_addr,
- unsigned short img_width_full_size,
- unsigned short pack_pattern,
- unsigned char ystride);
+ unsigned short disp_height,
+ unsigned short img_width,
+ unsigned short img_height,
+ unsigned short hsync_porch0_fp,
+ unsigned short hsync_porch0_bp,
+ unsigned short vsync_porch0_fp,
+ unsigned short vsync_porch0_bp,
+ unsigned short hsync_width,
+ unsigned short vsync_width,
+ unsigned long input_img_addr,
+ unsigned short img_width_full_size,
+ unsigned short pack_pattern,
+ unsigned char ystride);
int mipi_dsi_cmd_config(struct fbcon_config mipi_fb_cfg,
unsigned short num_of_lanes);
void mdp_shutdown(void);
void mdp_disable(void);
void mdp_start_dma(void);
+int mdp_dsi_video_off();
+int mdp_dsi_video_on();
+int mdp_dsi_video_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
+int mdp_lcdc_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
+int mdp_lcdc_on();
+int mdp_lcdc_off();
+void mdp_set_revision(int rev);
+int mdp_get_revision();
+#endif
diff --git a/platform/msm_shared/include/mipi_dsi.h b/platform/msm_shared/include/mipi_dsi.h
index b8a55fd..9f83129 100644
--- a/platform/msm_shared/include/mipi_dsi.h
+++ b/platform/msm_shared/include/mipi_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,6 +30,8 @@
#ifndef _PLATFORM_MSM_SHARED_MIPI_DSI_H_
#define _PLATFORM_MSM_SHARED_MIPI_DSI_H_
+#include <msm_panel.h>
+
#define PASS 0
#define FAIL 1
@@ -1781,4 +1783,56 @@
0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
};
+enum { /* mipi dsi panel */
+ DSI_VIDEO_MODE,
+ DSI_CMD_MODE,
+};
+#define DSI_NON_BURST_SYNCH_PULSE 0
+#define DSI_NON_BURST_SYNCH_EVENT 1
+#define DSI_BURST_MODE 2
+
+#define DSI_RGB_SWAP_RGB 0
+#define DSI_RGB_SWAP_RBG 1
+#define DSI_RGB_SWAP_BGR 2
+#define DSI_RGB_SWAP_BRG 3
+#define DSI_RGB_SWAP_GRB 4
+#define DSI_RGB_SWAP_GBR 5
+
+#define DSI_VIDEO_DST_FORMAT_RGB565 0
+#define DSI_VIDEO_DST_FORMAT_RGB666 1
+#define DSI_VIDEO_DST_FORMAT_RGB666_LOOSE 2
+#define DSI_VIDEO_DST_FORMAT_RGB888 3
+
+#define DSI_CMD_DST_FORMAT_RGB111 0
+#define DSI_CMD_DST_FORMAT_RGB332 3
+#define DSI_CMD_DST_FORMAT_RGB444 4
+#define DSI_CMD_DST_FORMAT_RGB565 6
+#define DSI_CMD_DST_FORMAT_RGB666 7
+#define DSI_CMD_DST_FORMAT_RGB888 8
+
+#define DSI_CMD_TRIGGER_NONE 0x0 /* mdp trigger */
+#define DSI_CMD_TRIGGER_TE 0x02
+#define DSI_CMD_TRIGGER_SW 0x04
+#define DSI_CMD_TRIGGER_SW_SEOF 0x05 /* cmd dma only */
+#define DSI_CMD_TRIGGER_SW_TE 0x06
+
+int mipi_config(struct msm_fb_panel_data *panel);
+int mipi_dsi_video_mode_config(unsigned short disp_width,
+ unsigned short disp_height,
+ unsigned short img_width,
+ unsigned short img_height,
+ unsigned short hsync_porch0_fp,
+ unsigned short hsync_porch0_bp,
+ unsigned short vsync_porch0_fp,
+ unsigned short vsync_porch0_bp,
+ unsigned short hsync_width,
+ unsigned short vsync_width,
+ unsigned short dst_format,
+ unsigned short traffic_mode,
+ unsigned char lane_en,
+ unsigned low_pwr_stop_mode,
+ unsigned char eof_bllp_pwr,
+ unsigned char interleav);
+int mipi_dsi_on();
+int mipi_dsi_off();
#endif
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
new file mode 100644
index 0000000..a65cbe0
--- /dev/null
+++ b/platform/msm_shared/include/msm_panel.h
@@ -0,0 +1,184 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _PLATFORM_MSM_SHARED_MSM_PANEL_H_
+#define _PLATFORM_MSM_SHARED_MSM_PANEL_H_
+
+#include <stdint.h>
+#include <dev/fbcon.h>
+
+#define TRUE 1
+#define FALSE 0
+
+/* panel type list */
+#define NO_PANEL 0xffff /* No Panel */
+#define MDDI_PANEL 1 /* MDDI */
+#define EBI2_PANEL 2 /* EBI2 */
+#define LCDC_PANEL 3 /* internal LCDC type */
+#define EXT_MDDI_PANEL 4 /* Ext.MDDI */
+#define TV_PANEL 5 /* TV */
+#define HDMI_PANEL 6 /* HDMI TV */
+#define DTV_PANEL 7 /* DTV */
+#define MIPI_VIDEO_PANEL 8 /* MIPI */
+#define MIPI_CMD_PANEL 9 /* MIPI */
+#define WRITEBACK_PANEL 10 /* Wifi display */
+#define LVDS_PANEL 11 /* LVDS */
+
+enum msm_mdp_hw_revision {
+ MDP_REV_20 = 1,
+ MDP_REV_22,
+ MDP_REV_30,
+ MDP_REV_303,
+ MDP_REV_31,
+ MDP_REV_40,
+ MDP_REV_41,
+ MDP_REV_42,
+ MDP_REV_43,
+ MDP_REV_44,
+};
+
+/* panel info type */
+struct lcd_panel_info {
+ uint32_t vsync_enable;
+ uint32_t refx100;
+ uint32_t v_back_porch;
+ uint32_t v_front_porch;
+ uint32_t v_pulse_width;
+ uint32_t hw_vsync_mode;
+ uint32_t vsync_notifier_period;
+ uint32_t rev;
+};
+
+struct lcdc_panel_info {
+ uint32_t h_back_porch;
+ uint32_t h_front_porch;
+ uint32_t h_pulse_width;
+ uint32_t v_back_porch;
+ uint32_t v_front_porch;
+ uint32_t v_pulse_width;
+ uint32_t border_clr;
+ uint32_t underflow_clr;
+ uint32_t hsync_skew;
+ /* Pad width */
+ uint32_t xres_pad;
+ /* Pad height */
+ uint32_t yres_pad;
+};
+
+struct mipi_panel_info {
+ char mode; /* video/cmd */
+ char interleave_mode;
+ char crc_check;
+ char ecc_check;
+ char dst_format; /* shared by video and command */
+ char num_of_lanes;
+ char data_lane0;
+ char data_lane1;
+ char data_lane2;
+ char data_lane3;
+ char dlane_swap; /* data lane swap */
+ char rgb_swap;
+ char b_sel;
+ char g_sel;
+ char r_sel;
+ char rx_eot_ignore;
+ char tx_eot_append;
+ char t_clk_post; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
+ char t_clk_pre; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
+ char vc; /* virtual channel */
+ struct mipi_dsi_phy_ctrl *dsi_phy_db;
+ struct mipi_dsi_cmd *panel_cmds;
+ int num_of_panel_cmds;
+ /* video mode */
+ char pulse_mode_hsa_he;
+ char hfp_power_stop;
+ char hbp_power_stop;
+ char hsa_power_stop;
+ char eof_bllp_power_stop;
+ char bllp_power_stop;
+ char traffic_mode;
+ char frame_rate;
+ /* command mode */
+ char interleave_max;
+ char insert_dcs_cmd;
+ char wr_mem_continue;
+ char wr_mem_start;
+ char te_sel;
+ char stream; /* 0 or 1 */
+ char mdp_trigger;
+ char dma_trigger;
+ uint32_t dsi_pclk_rate;
+ /* The packet-size should not bet changed */
+ char no_max_pkt_size;
+ /* Clock required during LP commands */
+ char force_clk_lane_hs;
+};
+
+enum lvds_mode {
+ LVDS_SINGLE_CHANNEL_MODE,
+ LVDS_DUAL_CHANNEL_MODE,
+};
+
+struct lvds_panel_info {
+ enum lvds_mode channel_mode;
+ /* Channel swap in dual mode */
+ char channel_swap;
+};
+
+struct msm_panel_info {
+ uint32_t xres;
+ uint32_t yres;
+ uint32_t bpp;
+ uint32_t type;
+ uint32_t wait_cycle;
+ uint32_t clk_rate;
+
+ struct lcd_panel_info lcd;
+ struct lcdc_panel_info lcdc;
+ struct mipi_panel_info mipi;
+ struct lvds_panel_info lvds;
+
+ int (*on) (void);
+ int (*off) (void);
+ int (*config) (void *pdata);
+};
+
+struct msm_fb_panel_data {
+ struct msm_panel_info panel_info;
+ struct fbcon_config fb;
+ int mdp_rev;
+
+ /* function entry chain */
+ int (*power_func) (int enable);
+ int (*clk_func) (int enable);
+};
+
+
+int msm_display_init(struct msm_fb_panel_data *pdata);
+#endif
diff --git a/platform/msm_shared/lvds.c b/platform/msm_shared/lvds.c
new file mode 100644
index 0000000..b9a5813
--- /dev/null
+++ b/platform/msm_shared/lvds.c
@@ -0,0 +1,177 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <reg.h>
+#include <err.h>
+#include <bits.h>
+#include <platform/iomap.h>
+#include <platform/clock.h>
+#include <dev/fbcon.h>
+#include <dev/lcdc.h>
+
+#include <msm_panel.h>
+#define MDP_OUTP(addr, val) writel(val, addr);
+
+void lvds_init(struct msm_panel_info *pinfo)
+{
+ unsigned int lvds_intf, lvds_phy_cfg0;
+ MDP_OUTP(MDP_BASE + 0xc2034, 0x33);
+ udelay(1000);
+
+ /*1. Configure LVDS PHY PLL through MDP_LVDSPHY_PLL_CTRL_* registers*/
+ /* LVDS PHY PLL configuration */
+ MDP_OUTP(MDP_BASE + 0xc3000, 0x08);
+ MDP_OUTP(MDP_BASE + 0xc3004, 0x87);
+ MDP_OUTP(MDP_BASE + 0xc3008, 0x30);
+ MDP_OUTP(MDP_BASE + 0xc300c, 0x06);
+ MDP_OUTP(MDP_BASE + 0xc3014, 0x20);
+ MDP_OUTP(MDP_BASE + 0xc3018, 0x0F);
+ MDP_OUTP(MDP_BASE + 0xc301c, 0x01);
+ MDP_OUTP(MDP_BASE + 0xc3020, 0x41);
+ MDP_OUTP(MDP_BASE + 0xc3024, 0x0d);
+ MDP_OUTP(MDP_BASE + 0xc3028, 0x07);
+ MDP_OUTP(MDP_BASE + 0xc302c, 0x00);
+ MDP_OUTP(MDP_BASE + 0xc3030, 0x1c);
+ MDP_OUTP(MDP_BASE + 0xc3034, 0x01);
+ MDP_OUTP(MDP_BASE + 0xc3038, 0x00);
+ MDP_OUTP(MDP_BASE + 0xc3040, 0xC0);
+ MDP_OUTP(MDP_BASE + 0xc3044, 0x00);
+ MDP_OUTP(MDP_BASE + 0xc3048, 0x30);
+ MDP_OUTP(MDP_BASE + 0xc304c, 0x00);
+
+ MDP_OUTP(MDP_BASE + 0xc3000, 0x11);
+ MDP_OUTP(MDP_BASE + 0xc3064, 0x05);
+ MDP_OUTP(MDP_BASE + 0xc3050, 0x20);
+
+ /*2. Enable LVDS PHY PLL in MDP_LVDSPHY_PLL_CTRL_0*/
+ MDP_OUTP(MDP_BASE + 0xc3000, 0x01);
+
+ /*3. Poll the MDP_LVDSPHY_PLL_RDY register until it is 1*/
+ /* Wait until LVDS PLL is locked and ready */
+ while (!readl(MDP_BASE + 0xc3080))
+ udelay(1);
+
+ /*4. Enable dsi2_pixel domain clocks*/
+ writel(0x00, REG_MM(0x0264));
+ writel(0x00, REG_MM(0x0094));
+
+ writel(0x02, REG_MM(0x00E4));
+
+ writel((0x80 | readl(REG_MM(0x00E4))),
+ REG_MM(0x00E4));
+ udelay(1000);
+ writel((~0x80 & readl(REG_MM(0x00E4))),
+ REG_MM(0x00E4));
+
+ writel(0x05, REG_MM(0x0094));
+ writel(0x02, REG_MM(0x0264));
+ /* Wait until LVDS pixel clock output is enabled */
+ dsb();
+ if (pinfo->bpp == 24) {
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2024, 0x151a191a);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc202c, 0x1706071b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2030, 0x000e0f16);
+
+ if (pinfo->lvds.channel_mode ==
+ LVDS_DUAL_CHANNEL_MODE) {
+ lvds_intf = 0x0001ff80;
+ lvds_phy_cfg0 = BIT(6) | BIT(7);
+ if (pinfo->lvds.channel_swap)
+ lvds_intf |= BIT(4);
+ } else {
+ lvds_intf = 0x00010f84;
+ lvds_phy_cfg0 = BIT(6);
+ }
+ } else if (pinfo->bpp == 18) {
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+ MDP_OUTP(MDP_BASE + 0xc2024, 0x1518191a);
+ /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+ MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
+
+ if (pinfo->lvds.channel_mode ==
+ LVDS_DUAL_CHANNEL_MODE) {
+ lvds_intf = 0x00017788;
+ lvds_phy_cfg0 = BIT(6) | BIT(7);
+ if (pinfo->lvds.channel_swap)
+ lvds_intf |= BIT(4);
+ } else {
+ lvds_intf = 0x0001078c;
+ lvds_phy_cfg0 = BIT(6);
+ }
+ }
+
+ /* MDP_LVDSPHY_CFG0 */
+ MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
+ /* MDP_LCDC_LVDS_INTF_CTL */
+ MDP_OUTP(MDP_BASE + 0xc2000, lvds_intf);
+ MDP_OUTP(MDP_BASE + 0xc3108, 0x30);
+ lvds_phy_cfg0 |= BIT(4);
+
+ /* Wait until LVDS PHY registers are configured */
+ dsb();
+ udelay(1);
+ /* MDP_LVDSPHY_CFG0, enable serialization */
+ MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
+}
+
+int lvds_on(struct msm_fb_panel_data *pdata)
+{
+ int ret = 0;
+ if (pdata == NULL) {
+ ret = ERR_INVALID_ARGS;
+ goto out;
+ }
+
+ lvds_init(&(pdata->panel_info));
+out:
+ return ret;
+}
+
diff --git a/platform/msm_shared/mdp3.c b/platform/msm_shared/mdp3.c
index 396ab6a..847e5cb 100644
--- a/platform/msm_shared/mdp3.c
+++ b/platform/msm_shared/mdp3.c
@@ -33,6 +33,8 @@
#include <platform/timer.h>
#include <platform/iomap.h>
+static int mdp_rev;
+
int
mdp_setup_dma_p_video_mode(unsigned short disp_width,
unsigned short disp_height,
@@ -99,3 +101,13 @@
writel(0x00000000, MDP_INTR_ENABLE);
writel(0x01ffffff, MDP_INTR_CLEAR);
}
+
+void mdp_set_revision(int rev)
+{
+ mdp_rev = rev;
+}
+
+int mdp_get_revision(void)
+{
+ return mdp_rev;
+}
diff --git a/platform/msm_shared/mdp4.c b/platform/msm_shared/mdp4.c
index 21fad3d..361193c 100644
--- a/platform/msm_shared/mdp4.c
+++ b/platform/msm_shared/mdp4.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,6 +32,14 @@
#include <target/display.h>
#include <platform/timer.h>
#include <platform/iomap.h>
+#include <dev/lcdc.h>
+#include <dev/fbcon.h>
+#include <bits.h>
+#include <msm_panel.h>
+#include <mipi_dsi.h>
+#include <err.h>
+
+static int mdp_rev;
void
mdp_setup_dma_p_video_config(unsigned short pack_pattern,
@@ -188,3 +196,290 @@
{
writel(0x00000001, MDP_DMA_P_START);
}
+
+int mdp_lcdc_config(struct msm_panel_info *pinfo,
+ struct fbcon_config *fb)
+{
+ unsigned mdp_rgb_size;
+ unsigned mdp_rgb_size_src;
+ int hsync_period, vsync_period;
+ int hsync_start_x, hsync_end_x;
+ int display_hctl, display_vstart, display_vend;
+ unsigned mdp_rgb_format = 0;
+
+ int active_x, active_y;
+ int active_hstart_x, active_hend_x;
+ int active_vstart, active_vend;
+
+ struct lcdc_panel_info *lcdc = NULL;
+
+ if (pinfo == NULL)
+ return;
+
+ lcdc = &(pinfo->lcdc);
+ if (lcdc == NULL)
+ return;
+
+ mdp_rgb_size = (pinfo->yres << 16) + pinfo->xres;
+ mdp_rgb_size_src = (fb->height << 16) + fb->width;
+
+ dprintf(INFO, "Panel is %d x %d\n",
+ pinfo->xres + lcdc->xres_pad,
+ pinfo->yres + lcdc->yres_pad);
+
+ /* write fb addr in MDP_DMA_P_BUF_ADDR */
+ writel(fb->base, MDP_DMA_P_BUF_ADDR);
+
+ /* write active region size*/
+ writel(mdp_rgb_size, MDP_DMA_P_SIZE);
+
+ /* set Y-stride value in bytes */
+ /* Y-stride is defined as the number of bytes
+ in a line.
+ */
+ writel((pinfo->xres * pinfo->bpp/8), MDP_DMA_P_BUF_Y_STRIDE);
+
+ /* Start XY coordinates */
+ writel(0, MDP_DMA_P_OUT_XY);
+
+ if (fb->bpp == 16) {
+ writel(DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB |
+ DMA_DITHER_EN | DMA_OUT_SEL_LCDC |
+ DMA_IBUF_FORMAT_RGB565 | DMA_DSTC0G_8BITS |
+ DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS,
+ MDP_DMA_P_CONFIG);
+ mdp_rgb_format = MDP_RGB_565_FORMAT;
+ } else if (fb->bpp == 24) {
+ writel(DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB |
+ DMA_DITHER_EN | DMA_OUT_SEL_LCDC |
+ DMA_IBUF_FORMAT_RGB888 | DMA_DSTC0G_8BITS |
+ DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS,
+ MDP_DMA_P_CONFIG);
+ mdp_rgb_format = MDP_RGB_888_FORMAT;
+ } else {
+ dprintf(CRITICAL, "Unsupported bpp detected!\n");
+ return ERR_INVALID_ARGS;
+ }
+
+ hsync_period = lcdc->h_pulse_width +
+ lcdc->h_back_porch +
+ pinfo->xres + lcdc->h_front_porch;
+ vsync_period = (lcdc->v_pulse_width +
+ lcdc->v_back_porch +
+ pinfo->yres +
+ lcdc->v_front_porch) *
+ hsync_period;
+ hsync_start_x =
+ lcdc->h_pulse_width +
+ lcdc->h_back_porch;
+ hsync_end_x =
+ hsync_period - lcdc->h_front_porch - 1;
+ display_hctl = (hsync_end_x << 16) | hsync_start_x;
+ display_vstart = (lcdc->v_pulse_width +
+ lcdc->v_back_porch)
+ * hsync_period + lcdc->hsync_skew;
+ display_vend = vsync_period -
+ (lcdc->v_front_porch * hsync_period)
+ +lcdc->hsync_skew - 1;
+
+ active_x = (pinfo->xres - fb->width)/2;
+ active_y = (pinfo->yres - fb->height)/2;
+
+ active_hstart_x = lcdc->h_pulse_width + lcdc->h_back_porch
+ + active_x;
+ active_hend_x = active_hstart_x + fb->width - 1;
+
+ active_vstart = (lcdc->v_pulse_width + lcdc->v_back_porch
+ + active_y) * hsync_period
+ + lcdc->hsync_skew;
+ active_vend = active_vstart + (fb->height * hsync_period) - 1;
+
+
+ /* LCDC specific initalizations */
+ writel((hsync_period << 16) | lcdc->h_pulse_width,
+ MDP_LCDC_HSYNC_CTL);
+ writel(vsync_period, MDP_LCDC_VSYNC_PERIOD);
+ writel(lcdc->v_pulse_width * hsync_period,
+ MDP_LCDC_VSYNC_PULSE_WIDTH);
+ writel(display_hctl, MDP_LCDC_DISPLAY_HCTL);
+ writel(display_vstart, MDP_LCDC_DISPLAY_V_START);
+ writel(display_vend, MDP_LCDC_DISPLAY_V_END);
+
+ writel(BIT(31) | (active_hend_x << 16) | active_hstart_x,
+ MDP_LCDC_ACTIVE_HCTL);
+
+ writel(BIT(31) | active_vstart, MDP_LCDC_ACTIVE_V_START);
+ writel(active_vend, MDP_LCDC_ACTIVE_V_END);
+
+ writel(0xf, MDP_LCDC_BORDER_CLR);
+ writel(0xff, MDP_LCDC_UNDERFLOW_CTL);
+ writel(lcdc->hsync_skew,
+ MDP_LCDC_HSYNC_SKEW);
+ writel(0x3, MDP_LCDC_CTL_POLARITY);
+ writel(0, MDP_LCDC_ACTIVE_HCTL);
+ writel(0, MDP_LCDC_ACTIVE_V_START);
+ writel(0, MDP_LCDC_ACTIVE_V_END);
+
+ /* setting for single layer direct out mode for rgb565 source */
+ writel(0x100, MDP_LAYERMIXER_IN_CFG);
+ writel(mdp_rgb_size_src, MDP_RGB1_SRC_SIZE);
+ writel(mdp_rgb_size, MDP_RGB1_OUT_SIZE);
+ writel((int)fb->base, MDP_RGB1_SRCP0_ADDR);
+ writel((fb->stride * fb->bpp / 8), MDP_RGB1_SRC_YSTRIDE1);
+ writel(0x00, MDP_RGB1_CONSTANT_COLOR);
+ writel(mdp_rgb_format, MDP_RGB1_SRC_FORMAT);
+ writel(0x1, MDP_OVERLAYPROC0_CFG);
+ if (fb->bpp == 16)
+ writel(0x1, MDP_OVERLAYPROC0_OPMODE);
+ else if (fb->bpp == 24)
+ writel(0x0, MDP_OVERLAYPROC0_OPMODE);
+
+ /* register flush and enable LCDC */
+ writel(0x11, MDP_OVERLAY_REG_FLUSH);
+ return NO_ERROR;
+}
+
+int mdp_lcdc_on()
+{
+ writel(0x1, MDP_LCDC_EN);
+ return NO_ERROR;
+}
+
+int mdp_lcdc_off()
+{
+ writel(0x0, MDP_LCDC_EN);
+ return NO_ERROR;
+}
+
+int mdp_dsi_video_config(struct msm_panel_info *pinfo,
+ struct fbcon_config *fb)
+{
+ int ret = NO_ERROR;
+ int hsync_period, vsync_period;
+ int hsync_start_x, hsync_end_x;
+ int display_hctl, display_vstart, display_vend;
+ struct lcdc_panel_info *lcdc = NULL;
+ unsigned mdp_rgb_size;
+
+ if (pinfo == NULL)
+ return ERR_INVALID_ARGS;
+
+ lcdc = &(pinfo->lcdc);
+ if (lcdc == NULL)
+ return ERR_INVALID_ARGS;
+
+ hsync_period = lcdc->h_pulse_width +
+ lcdc->h_back_porch +
+ pinfo->xres + lcdc->xres_pad + lcdc->h_front_porch;
+ vsync_period = (lcdc->v_pulse_width +
+ lcdc->v_back_porch +
+ pinfo->yres + lcdc->yres_pad +
+ lcdc->v_front_porch) * hsync_period;
+ hsync_start_x =
+ lcdc->h_pulse_width +
+ lcdc->h_back_porch;
+ hsync_end_x =
+ hsync_period - lcdc->h_front_porch - 1;
+ display_hctl = (hsync_end_x << 16) | hsync_start_x;
+ display_vstart = (lcdc->v_pulse_width +
+ lcdc->v_back_porch)
+ * hsync_period + lcdc->hsync_skew;
+ display_vend = vsync_period -
+ (lcdc->v_front_porch * hsync_period)
+ +lcdc->hsync_skew - 1;
+
+ /* MDP_AXI_RDMASTER_CONFIG set all master to read from
+ AXI port 0, that's the only port connected */
+ writel(0x00290000, MDP_AXI_RDMASTER_CONFIG);
+ writel(0x00000004, MDP_AXI_WRMASTER_CONFIG);
+ writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG);
+
+ /* Set up CMD_INTF_SEL, VIDEO_INTF_SEL,
+ EXT_INTF_SEL, SEC_INTF_SEL, PRIM_INTF_SEL */
+ writel(0x00000049, MDP_DISP_INTF_SEL);
+
+ /* DMA P */
+ writel(0x0000000b, MDP_OVERLAYPROC0_CFG);
+
+ /* write fb addr in MDP_DMA_P_BUF_ADDR */
+ writel(fb->base, MDP_DMA_P_BUF_ADDR);
+
+ /* write active region size*/
+ mdp_rgb_size = (fb->height << 16) + fb->width;
+ writel(mdp_rgb_size, MDP_DMA_P_SIZE);
+
+ /* set Y-stride value in bytes */
+ /* Y-stride is defined as the number of bytes
+ in a line.
+ */
+ writel((fb->stride * fb->bpp/8), MDP_DMA_P_BUF_Y_STRIDE);
+
+ /* Start XY coordinates */
+ writel(0, MDP_DMA_P_OUT_XY);
+
+ if (fb->bpp == 16) {
+ writel(DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB |
+ DMA_DITHER_EN | DMA_OUT_SEL_LCDC |
+ DMA_IBUF_FORMAT_RGB565 | DMA_DSTC0G_8BITS |
+ DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS,
+ MDP_DMA_P_CONFIG);
+ } else if (fb->bpp == 24) {
+ writel(DMA_PACK_ALIGN_LSB | DMA_PACK_PATTERN_RGB |
+ DMA_DITHER_EN | DMA_OUT_SEL_LCDC |
+ DMA_IBUF_FORMAT_RGB888 | DMA_DSTC0G_8BITS |
+ DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS,
+ MDP_DMA_P_CONFIG);
+ } else {
+ dprintf(CRITICAL, "Unsupported bpp detected!\n");
+ return ERR_INVALID_ARGS;
+ }
+
+ writel(hsync_period << 16 | lcdc->h_pulse_width,
+ MDP_DSI_VIDEO_HSYNC_CTL);
+ writel(vsync_period, MDP_DSI_VIDEO_VSYNC_PERIOD);
+ writel(lcdc->v_pulse_width * hsync_period,
+ MDP_DSI_VIDEO_VSYNC_PULSE_WIDTH);
+ writel(display_hctl,
+ MDP_DSI_VIDEO_DISPLAY_HCTL);
+ writel(display_vstart, MDP_DSI_VIDEO_DISPLAY_V_START);
+ writel(display_vend, MDP_DSI_VIDEO_DISPLAY_V_END);
+
+ if (lcdc->xres_pad) {
+ writel((1 << 31) |
+ (lcdc->h_back_porch + lcdc->h_pulse_width +
+ fb->width - 1) << 16 | lcdc->h_pulse_width +
+ lcdc->h_back_porch, MDP_DSI_VIDEO_ACTIVE_HCTL);
+ }
+
+ return ret;
+}
+
+int mdp_dsi_video_on()
+{
+ int ret = NO_ERROR;
+
+ writel(0x00000001, MDP_DSI_VIDEO_EN);
+
+ return ret;
+}
+
+int mdp_dsi_video_off()
+{
+#if (!CONT_SPLASH_SCREEN)
+ writel(0x00000000, MDP_DSI_VIDEO_EN);
+ mdelay(60);
+ writel(0x00000000, MDP_INTR_ENABLE);
+ writel(0x00000003, MDP_OVERLAYPROC0_CFG);
+#endif
+ return NO_ERROR;
+}
+
+void mdp_set_revision(int rev)
+{
+ mdp_rev = rev;
+}
+
+int mdp_get_revision()
+{
+ return mdp_rev;
+}
diff --git a/platform/msm_shared/mipi_dsi.c b/platform/msm_shared/mipi_dsi.c
index 3b09510..51fe36b 100644
--- a/platform/msm_shared/mipi_dsi.c
+++ b/platform/msm_shared/mipi_dsi.c
@@ -38,6 +38,8 @@
#include <platform/iomap.h>
#include <platform/clock.h>
#include <platform/timer.h>
+#include <err.h>
+#include <msm_panel.h>
extern void mdp_disable(void);
extern int mipi_dsi_cmd_config(struct fbcon_config mipi_fb_cfg,
@@ -82,24 +84,6 @@
.panel_cmds = novatek_panel_cmd_mode_cmds,
.num_of_panel_cmds = ARRAY_SIZE(novatek_panel_cmd_mode_cmds),
};
-#elif DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
-static struct fbcon_config mipi_fb_cfg = {
- .height = TSH_MDT61_MIPI_FB_HEIGHT,
- .width = TSH_MDT61_MIPI_FB_WIDTH,
- .stride = TSH_MDT61_MIPI_FB_WIDTH,
- .format = FB_FORMAT_RGB888,
- .bpp = 24,
- .update_start = NULL,
- .update_done = NULL,
-};
-
-struct mipi_dsi_panel_config toshiba_mdt61_panel_info = {
- .mode = MIPI_VIDEO_MODE,
- .num_of_lanes = 3,
- .dsi_phy_config = &mipi_dsi_toshiba_mdt61_panel_phy_ctrl,
- .panel_cmds = toshiba_mdt61_video_mode_cmds,
- .num_of_panel_cmds = ARRAY_SIZE(toshiba_mdt61_video_mode_cmds),
-};
#elif DISPLAY_MIPI_PANEL_RENESAS
static struct fbcon_config mipi_fb_cfg = {
.height = REN_MIPI_FB_HEIGHT,
@@ -200,8 +184,6 @@
return &toshiba_panel_info;
#elif DISPLAY_MIPI_PANEL_NOVATEK_BLUE
return &novatek_panel_info;
-#elif DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
- return &toshiba_mdt61_panel_info;
#elif DISPLAY_MIPI_PANEL_RENESAS
if (machine_is_7x25a()) {
renesas_panel_info.num_of_lanes = 1;
@@ -574,7 +556,6 @@
// or lp mode
unsigned short image_wd = mipi_fb_cfg.width;
unsigned short image_ht = mipi_fb_cfg.height;
-#if !DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
unsigned short display_wd = mipi_fb_cfg.width;
unsigned short display_ht = mipi_fb_cfg.height;
unsigned short hsync_porch_fp = MIPI_HSYNC_FRONT_PORCH_DCLK;
@@ -585,7 +566,6 @@
unsigned short vsync_width = MIPI_VSYNC_PULSE_WIDTH;
unsigned short dst_format = 0;
unsigned short traffic_mode = 0;
-#endif
unsigned short pack_pattern = 0x12; //BGR
unsigned char ystride = 3;
@@ -595,15 +575,7 @@
eof_bllp_pwr = 0x9; // low power stop mode or let cmd mode eng send
// packets in hs or lp mode
-#if DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
- pack_pattern = 0x21; //RGB
- config_mdt61_dsi_video_mode();
-
- /* Two functions make up mdp_setup_dma_p_video_mode with mdt61 panel functions */
- mdp_setup_dma_p_video_config(pack_pattern, image_wd, image_ht,
- MIPI_FB_ADDR, image_wd, ystride);
- mdp_setup_mdt61_video_dsi_config();
-#elif DISPLAY_MIPI_PANEL_RENESAS
+#if DISPLAY_MIPI_PANEL_RENESAS
if (machine_is_7x25a()) {
display_wd = REN_MIPI_FB_WIDTH_HVGA;
display_ht = REN_MIPI_FB_HEIGHT_HVGA;
@@ -687,14 +659,9 @@
mdp_shutdown();
writel(0x01010101, DSI_INT_CTRL);
writel(0x13FF3BFF, DSI_ERR_INT_MASK0);
-#if DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
- /* Disable branch clocks */
- writel(0x0, DSI1_BYTE_CC_REG);
- writel(0x0, DSI_PIXEL_CC_REG);
- writel(0x0, DSI1_ESC_CC_REG);
- /* Disable root clock */
- writel(0x0, DSI_CC_REG);
-#elif (!DISPLAY_MIPI_PANEL_RENESAS)
+
+#if (DISPLAY_MIPI_PANEL_NOVATEK_BLUE \
+ || DISPLAY_MIPI_PANEL_TOSHIBA)
secure_writel(0x0, DSI_CC_REG);
secure_writel(0x0, DSI_PIXEL_CC_REG);
#endif
@@ -741,3 +708,155 @@
return &mipi_fb_cfg;
}
+
+int mipi_config(struct msm_fb_panel_data *panel)
+{
+ int ret = NO_ERROR;
+ struct msm_panel_info *pinfo;
+ struct mipi_dsi_panel_config mipi_pinfo;
+
+ if (!panel)
+ return ERR_INVALID_ARGS;
+
+ pinfo = &(panel->panel_info);
+ mipi_pinfo.mode = pinfo->mipi.mode;
+ mipi_pinfo.num_of_lanes = pinfo->mipi.num_of_lanes;
+ mipi_pinfo.dsi_phy_config = pinfo->mipi.dsi_phy_db;
+ mipi_pinfo.panel_cmds = pinfo->mipi.panel_cmds;
+ mipi_pinfo.num_of_panel_cmds = pinfo->mipi.num_of_panel_cmds;
+
+ /* Enable MMSS_AHB_ARB_MATER_PORT_E for
+ arbiter master0 and master 1 request */
+#if (!DISPLAY_MIPI_PANEL_RENESAS)
+ writel(0x00001800, MMSS_SFPB_GPREG);
+#endif
+
+ mipi_dsi_phy_init(&mipi_pinfo);
+
+ ret += mipi_dsi_panel_initialize(&mipi_pinfo);
+
+ return ret;
+}
+
+int mipi_dsi_video_mode_config(unsigned short disp_width,
+ unsigned short disp_height,
+ unsigned short img_width,
+ unsigned short img_height,
+ unsigned short hsync_porch0_fp,
+ unsigned short hsync_porch0_bp,
+ unsigned short vsync_porch0_fp,
+ unsigned short vsync_porch0_bp,
+ unsigned short hsync_width,
+ unsigned short vsync_width,
+ unsigned short dst_format,
+ unsigned short traffic_mode,
+ unsigned char lane_en,
+ unsigned low_pwr_stop_mode,
+ unsigned char eof_bllp_pwr,
+ unsigned char interleav)
+{
+
+ int status = 0;
+
+ /* disable mdp first */
+ mdp_disable();
+
+ writel(0x00000000, DSI_CLK_CTRL);
+ writel(0x00000000, DSI_CLK_CTRL);
+ writel(0x00000000, DSI_CLK_CTRL);
+ writel(0x00000000, DSI_CLK_CTRL);
+ writel(0x00000002, DSI_CLK_CTRL);
+ writel(0x00000006, DSI_CLK_CTRL);
+ writel(0x0000000e, DSI_CLK_CTRL);
+ writel(0x0000001e, DSI_CLK_CTRL);
+ writel(0x0000003e, DSI_CLK_CTRL);
+
+ writel(0, DSI_CTRL);
+
+ writel(0, DSI_ERR_INT_MASK0);
+
+ writel(0x02020202, DSI_INT_CTRL);
+
+ writel(((disp_width + hsync_porch0_bp) << 16) | hsync_porch0_bp,
+ DSI_VIDEO_MODE_ACTIVE_H);
+
+ writel(((disp_height + vsync_porch0_bp) << 16) | (vsync_porch0_bp),
+ DSI_VIDEO_MODE_ACTIVE_V);
+
+ if (mdp_get_revision() >= MDP_REV_41) {
+ writel(((disp_height + vsync_porch0_fp
+ + vsync_porch0_bp - 1) << 16)
+ | (disp_width + hsync_porch0_fp
+ + hsync_porch0_bp - 1),
+ DSI_VIDEO_MODE_TOTAL);
+ } else {
+ writel(((disp_height + vsync_porch0_fp
+ + vsync_porch0_bp) << 16)
+ | (disp_width + hsync_porch0_fp
+ + hsync_porch0_bp),
+ DSI_VIDEO_MODE_TOTAL);
+ }
+
+ writel((hsync_width << 16) | 0, DSI_VIDEO_MODE_HSYNC);
+
+ writel(0 << 16 | 0, DSI_VIDEO_MODE_VSYNC);
+
+ writel(vsync_width << 16 | 0, DSI_VIDEO_MODE_VSYNC_VPOS);
+
+ writel(1, DSI_EOT_PACKET_CTRL);
+
+ writel(0x00000100, DSI_MISR_VIDEO_CTRL);
+
+ writel(low_pwr_stop_mode << 16 | eof_bllp_pwr << 12 | traffic_mode << 8
+ | dst_format << 4 | 0x0, DSI_VIDEO_MODE_CTRL);
+
+ writel(0x67, DSI_CAL_STRENGTH_CTRL);
+ writel(0x80006711, DSI_CAL_CTRL);
+ writel(0x00010100, DSI_MISR_VIDEO_CTRL);
+
+ writel(0x00010100, DSI_INT_CTRL);
+ writel(0x02010202, DSI_INT_CTRL);
+ writel(0x02030303, DSI_INT_CTRL);
+
+ writel(interleav << 30 | 0 << 24 | 0 << 20 | lane_en << 4
+ | 0x103, DSI_CTRL);
+
+ return status;
+}
+
+int mipi_dsi_on()
+{
+ int ret = NO_ERROR;
+ unsigned long ReadValue;
+ unsigned long count = 0;
+
+ ReadValue = readl(DSI_INT_CTRL) & 0x00010000;
+
+ mdelay(10);
+
+ while (ReadValue != 0x00010000) {
+ ReadValue = readl(DSI_INT_CTRL) & 0x00010000;
+ count++;
+ if (count > 0xffff) {
+ dprintf(CRITICAL, "Video lane test failed\n");
+ return ERROR;
+ }
+ }
+
+ dprintf(SPEW, "Video lane tested successfully\n");
+ return ret;
+}
+
+int mipi_dsi_off()
+{
+ writel(0x01010101, DSI_INT_CTRL);
+ writel(0x13FF3BFF, DSI_ERR_INT_MASK0);
+
+#if (!CONT_SPLASH_SCREEN)
+ writel(0, DSI_CLK_CTRL);
+ writel(0, DSI_CTRL);
+ writel(0, DSIPHY_PLL_CTRL(0));
+#endif
+
+ return NO_ERROR;
+}
diff --git a/platform/msm_shared/mipi_dsi_phy.c b/platform/msm_shared/mipi_dsi_phy.c
new file mode 100644
index 0000000..57b9ff1
--- /dev/null
+++ b/platform/msm_shared/mipi_dsi_phy.c
@@ -0,0 +1,129 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <debug.h>
+#include <reg.h>
+#include <mipi_dsi.h>
+#include <mdp4.h>
+#include <platform/iomap.h>
+
+static void mipi_dsi_calibration(void)
+{
+ uint32_t i = 0;
+ uint32_t term_cnt = 5000;
+ int32_t cal_busy = readl(MIPI_DSI_BASE + 0x550);
+
+ /* DSI1_DSIPHY_REGULATOR_CAL_PWR_CFG */
+ writel(0x01, MIPI_DSI_BASE + 0x0518);
+
+ /* DSI1_DSIPHY_CAL_SW_CFG2 */
+ writel(0x0, MIPI_DSI_BASE + 0x0534);
+ /* DSI1_DSIPHY_CAL_HW_CFG1 */
+ writel(0x5a, MIPI_DSI_BASE + 0x053c);
+ /* DSI1_DSIPHY_CAL_HW_CFG3 */
+ writel(0x10, MIPI_DSI_BASE + 0x0544);
+ /* DSI1_DSIPHY_CAL_HW_CFG4 */
+ writel(0x01, MIPI_DSI_BASE + 0x0548);
+ /* DSI1_DSIPHY_CAL_HW_CFG0 */
+ writel(0x01, MIPI_DSI_BASE + 0x0538);
+
+ /* DSI1_DSIPHY_CAL_HW_TRIGGER */
+ writel(0x01, MIPI_DSI_BASE + 0x0528);
+
+ /* DSI1_DSIPHY_CAL_HW_TRIGGER */
+ writel(0x00, MIPI_DSI_BASE + 0x0528);
+
+ cal_busy = readl(MIPI_DSI_BASE + 0x550);
+ while (cal_busy & 0x10) {
+ i++;
+ if (i > term_cnt) {
+ dprintf(CRITICAL, "DSI1 PHY REGULATOR NOT READY,"
+ "exceeded polling TIMEOUT!\n");
+ break;
+ }
+ cal_busy = readl(MIPI_DSI_BASE + 0x550);
+ }
+}
+
+int mipi_dsi_phy_init(struct mipi_dsi_panel_config *pinfo)
+{
+ struct mipi_dsi_phy_ctrl *pd;
+ uint32_t i, off = 0;
+
+ writel(0x0001, MIPI_DSI_BASE + 0x128); /* start phy sw reset */
+ writel(0x0000, MIPI_DSI_BASE + 0x128); /* end phy w reset */
+ writel(0x0003, MIPI_DSI_BASE + 0x500); /* regulator_ctrl_0 */
+ writel(0x0001, MIPI_DSI_BASE + 0x504); /* regulator_ctrl_1 */
+ writel(0x0001, MIPI_DSI_BASE + 0x508); /* regulator_ctrl_2 */
+ writel(0x0000, MIPI_DSI_BASE + 0x50c); /* regulator_ctrl_3 */
+ writel(0x0100, MIPI_DSI_BASE + 0x510); /* regulator_ctrl_4 */
+
+ pd = (pinfo->dsi_phy_config);
+
+ off = 0x0480; /* strength 0 - 2 */
+ for (i = 0; i < 3; i++) {
+ writel(pd->strength[i], MIPI_DSI_BASE + off);
+ off += 4;
+ }
+
+ off = 0x0470; /* ctrl 0 - 3 */
+ for (i = 0; i < 4; i++) {
+ writel(pd->ctrl[i], MIPI_DSI_BASE + off);
+ off += 4;
+ }
+
+ off = 0x0500; /* regulator ctrl 0 - 4 */
+ for (i = 0; i < 5; i++) {
+ writel(pd->regulator[i], MIPI_DSI_BASE + off);
+ off += 4;
+ }
+ mipi_dsi_calibration();
+
+ off = 0x0204; /* pll ctrl 1 - 19, skip 0 */
+ for (i = 1; i < 20; i++) {
+ writel(pd->pll[i], MIPI_DSI_BASE + off);
+ off += 4;
+ }
+
+ /* pll ctrl 0 */
+ writel(pd->pll[0], MIPI_DSI_BASE + 0x200);
+ writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200);
+
+ /* Check that PHY is ready */
+ while (!(readl(DSIPHY_PLL_RDY) & 0x01))
+ udelay(1);
+
+ writel(0x202D, DSI_CLKOUT_TIMING_CTRL);
+
+ off = 0x0440; /* phy timing ctrl 0 - 11 */
+ for (i = 0; i < 12; i++) {
+ writel(pd->timing[i], MIPI_DSI_BASE + off);
+ off += 4;
+ }
+ return 0;
+}
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 91e6371..6f75995 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -49,7 +49,10 @@
$(LOCAL_DIR)/interrupts.o \
$(LOCAL_DIR)/clock-local.o \
$(LOCAL_DIR)/clock.o \
- $(LOCAL_DIR)/board.o
+ $(LOCAL_DIR)/board.o \
+ $(LOCAL_DIR)/display.o \
+ $(LOCAL_DIR)/lvds.o \
+ $(LOCAL_DIR)/mipi_dsi_phy.o
endif
ifeq ($(PLATFORM),msm7x27a)