Merge "pm8x41: diff clock control api"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index af03c6c..1e9dacd 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -687,7 +687,7 @@
device.is_unlocked,
device.is_tampered);
- if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_tampered))
+ if(target_use_signed_kernel() && (!device.is_unlocked))
{
offset = 0;
@@ -697,7 +697,7 @@
dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
- if (check_aboot_addr_range_overlap(hdr->tags_addr, hdr->dt_size))
+ if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_actual))
{
dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
return -1;
@@ -710,6 +710,12 @@
dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
bs_set_timestamp(BS_KERNEL_LOAD_START);
+ if (check_aboot_addr_range_overlap(image_addr, imagesize_actual))
+ {
+ dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
+ return -1;
+ }
+
/* Read image without signature */
if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
{
@@ -721,6 +727,13 @@
bs_set_timestamp(BS_KERNEL_LOAD_DONE);
offset = imagesize_actual;
+
+ if (check_aboot_addr_range_overlap(image_addr + offset, page_size))
+ {
+ dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
+ return -1;
+ }
+
/* Read signature */
if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
{
@@ -767,7 +780,8 @@
*/
void *dtb;
dtb = dev_tree_appended((void*) hdr->kernel_addr,
- (void *)hdr->tags_addr, hdr->kernel_size);
+ hdr->kernel_size,
+ (void *)hdr->tags_addr);
if (!dtb) {
dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
return -1;
@@ -858,7 +872,8 @@
*/
void *dtb;
dtb = dev_tree_appended((void*) hdr->kernel_addr,
- (void *)hdr->tags_addr, hdr->kernel_size);
+ kernel_actual,
+ (void *)hdr->tags_addr);
if (!dtb) {
dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
return -1;
@@ -975,7 +990,7 @@
#endif
/* Authenticate Kernel */
- if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_tampered))
+ if(target_use_signed_kernel() && (!device.is_unlocked))
{
image_addr = (unsigned char *)target_get_scratch_address();
offset = 0;
@@ -1423,7 +1438,8 @@
*/
if (!dtb_copied) {
void *dtb;
- dtb = dev_tree_appended((void *)hdr->kernel_addr, (void *)hdr->tags_addr, hdr->kernel_size);
+ dtb = dev_tree_appended((void *)hdr->kernel_addr, hdr->kernel_size,
+ (void *)hdr->tags_addr);
if (!dtb) {
fastboot_fail("dtb not found");
return;
diff --git a/dev/gcdb/display/panel_display.c b/dev/gcdb/display/panel_display.c
old mode 100755
new mode 100644
index 7f78122..da69f20
--- a/dev/gcdb/display/panel_display.c
+++ b/dev/gcdb/display/panel_display.c
@@ -184,21 +184,14 @@
if (pinfo->mipi.dual_dsi)
panel_width = panel_width / 2;
- switch (pinfo->mipi.num_of_lanes) {
- case 1:
- lane_enable = 0x1; /*1 lane only */
- break;
- case 2:
- lane_enable = 0x3; /* 2 lanes only */
- break;
- case 3:
- lane_enable = 0x7; /* 3 lanes only */
- break;
- case 4:
- default:
- lane_enable = 0xf; /* 4 lanes */
- break;
- }
+ if (pinfo->mipi.data_lane0)
+ lane_enable |= (1 << 0);
+ if (pinfo->mipi.data_lane1)
+ lane_enable |= (1 << 1);
+ if (pinfo->mipi.data_lane2)
+ lane_enable |= (1 << 2);
+ if (pinfo->mipi.data_lane3)
+ lane_enable |= (1 << 3);
ret = mdss_dsi_video_mode_config((panel_width + plcdc->xres_pad),
(pinfo->yres + plcdc->yres_pad),
@@ -245,11 +238,24 @@
struct lcdc_panel_info *plcdc)
{
int ret = NO_ERROR;
+ uint8_t lane_en = 0;
+ uint8_t ystride = pinfo->bpp / 8;
+
+ if (pinfo->mipi.data_lane0)
+ lane_en |= (1 << 0);
+ if (pinfo->mipi.data_lane1)
+ lane_en |= (1 << 1);
+ if (pinfo->mipi.data_lane2)
+ lane_en |= (1 << 2);
+ if (pinfo->mipi.data_lane3)
+ lane_en |= (1 << 3);
ret = mdss_dsi_cmd_mode_config((pinfo->xres + plcdc->xres_pad),
(pinfo->yres + plcdc->yres_pad),
(pinfo->xres), (pinfo->yres),
- pinfo->mipi.dst_format, pinfo->mipi.traffic_mode);
+ pinfo->mipi.dst_format,
+ ystride, lane_en,
+ pinfo->mipi.interleave_mode);
return ret;
}
diff --git a/dev/panel/msm/edp_auo_1080p.c b/dev/panel/msm/edp_auo_1080p.c
new file mode 100644
index 0000000..42aa021
--- /dev/null
+++ b/dev/panel/msm/edp_auo_1080p.c
@@ -0,0 +1,87 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 <edp.h>
+#include <msm_panel.h>
+
+static void edp_auo_1080p_init_edid_data(struct edp_edid *edid)
+{
+ edid->id_name[0] = 'A';
+ edid->id_name[0] = 'U';
+ edid->id_name[0] = 'O';
+ edid->id_name[0] = 0;
+ edid->id_product = 0x305D;
+ edid->version = 1;
+ edid->revision = 4;
+ edid->ext_block_cnt = 0;
+ edid->video_digital = 0x5;
+ edid->color_depth = 6;
+ edid->dpm = 0;
+ edid->color_format = 0;
+ edid->timing[0].pclk = 138500000;
+ edid->timing[0].h_addressable = 1920;
+ edid->timing[0].h_blank = 160;
+ edid->timing[0].v_addressable = 1080;
+ edid->timing[0].v_blank = 30;
+ edid->timing[0].h_fporch = 48;
+ edid->timing[0].h_sync_pulse = 32;
+ edid->timing[0].v_sync_pulse = 14;
+ edid->timing[0].v_fporch = 8;
+ edid->timing[0].width_mm = 256;
+ edid->timing[0].height_mm = 144;
+ edid->timing[0].h_border = 0;
+ edid->timing[0].v_border = 0;
+ edid->timing[0].interlaced = 0;
+ edid->timing[0].stereo = 0;
+ edid->timing[0].sync_type = 1;
+ edid->timing[0].sync_separate = 1;
+ edid->timing[0].vsync_pol = 0;
+ edid->timing[0].hsync_pol = 0;
+
+}
+
+static void edp_auo_1080p_init_dpcd_data(struct dpcd_cap *cap)
+{
+ cap->max_lane_count = 2;
+ cap->max_link_clk = 270;
+}
+
+void edp_auo_1080p_init(struct edp_panel_data *edp_panel)
+{
+ if (!edp_panel->panel_data) {
+ dprintf(CRITICAL, "%s(), panel_data is null", __func__);
+ return;
+ }
+
+ edp_auo_1080p_init_edid_data(&(edp_panel->edid));
+ edp_auo_1080p_init_dpcd_data(&(edp_panel->dpcd));
+ edp_edid2pinfo(edp_panel);
+
+ edp_panel->panel_data->panel_info.on = edp_on;
+ edp_panel->panel_data->panel_info.off = edp_off;
+}
diff --git a/dev/panel/msm/mipi_nt35590_cmd_720p.c b/dev/panel/msm/mipi_nt35590_cmd_720p.c
index 41c6220..6629aa6 100644
--- a/dev/panel/msm/mipi_nt35590_cmd_720p.c
+++ b/dev/panel/msm/mipi_nt35590_cmd_720p.c
@@ -2385,7 +2385,9 @@
(pinfo->xres),
(pinfo->yres),
pinfo->mipi.dst_format,
- pinfo->mipi.traffic_mode);
+ pinfo->bpp / 8,
+ 0xf,
+ pinfo->mipi.interleave_mode);
return ret;
}
diff --git a/dev/panel/msm/mipi_truly_cmd_wvga.c b/dev/panel/msm/mipi_truly_cmd_wvga.c
new file mode 100644
index 0000000..b1f6c31
--- /dev/null
+++ b/dev/panel/msm/mipi_truly_cmd_wvga.c
@@ -0,0 +1,314 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. 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 The Linux Foundation 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 <msm_panel.h>
+#include <mipi_dsi.h>
+#include <sys/types.h>
+#include <err.h>
+#include <reg.h>
+#include <debug.h>
+#include <target/display.h>
+#include <platform/iomap.h>
+
+#define WVGA_MIPI_FB_WIDTH 480
+#define WVGA_MIPI_FB_HEIGHT 800
+
+#define TRULY_PANEL_FRAME_RATE 60
+#define TRULY_PANEL_NUM_OF_LANES 2
+#define TRULY_PANEL_LANE_SWAP 0
+#define TRULY_PANEL_T_CLK_PRE 0x41b
+#define TRULY_PANEL_T_CLK_POST 0x0
+#define TRULY_PANEL_BPP 24
+#define TRULY_PANEL_CLK_RATE 499000000
+
+static char disp_on0[4] = {
+ 0x01, 0x00, 0x05, 0x80
+};
+static char disp_on1[4] = {
+ 0xB0, 0x04, 0x23, 0x80
+};
+static char disp_on2[8] = {
+ 0x03, 0x00, 0x29, 0xC0,
+ 0xB3, 0x02, 0x00, 0xFF
+};
+static char disp_on3[4] = {
+ 0xBD, 0x00, 0x23, 0x80
+};
+static char disp_on4[8] = {
+ 0x03, 0x00, 0x29, 0xC0,
+ 0xC0, 0x18, 0x66, 0xFF
+};
+static char disp_on5[20] = {
+ 0x10, 0x00, 0x29, 0xC0,
+ 0xC1, 0x23, 0x31, 0x99,
+ 0x21, 0x20, 0x00, 0x30,
+ 0x28, 0x0C, 0x0C, 0x00,
+ 0x00, 0x00, 0x21, 0x01
+};
+static char disp_on6[12] = {
+ 0x07, 0x00, 0x29, 0xC0,
+ 0xC2, 0x00, 0x06, 0x06,
+ 0x01, 0x03, 0x00, 0xFF
+};
+static char disp_on7[32] = {
+ 0x19, 0x00, 0x29, 0xC0,
+ 0xC8, 0x04, 0x10, 0x18,
+ 0x20, 0x2E, 0x46, 0x3C,
+ 0x28, 0x1F, 0x18, 0x10,
+ 0x04, 0x04, 0x10, 0x18,
+ 0x20, 0x2E, 0x46, 0x3C,
+ 0x28, 0x1F, 0x18, 0x10,
+ 0x04, 0xFF, 0xFF, 0xFF
+};
+static char disp_on8[32] = {
+ 0x19, 0x00, 0x29, 0xC0,
+ 0xC9, 0x04, 0x10, 0x18,
+ 0x20, 0x2E, 0x46, 0x3C,
+ 0x28, 0x1F, 0x18, 0x10,
+ 0x04, 0x04, 0x10, 0x18,
+ 0x20, 0x2E, 0x46, 0x3C,
+ 0x28, 0x1F, 0x18, 0x10,
+ 0x04, 0xFF, 0xFF, 0xFF
+};
+static char disp_on9[32] = {
+ 0x19, 0x00, 0x29, 0xC0,
+ 0xCA, 0x04, 0x10, 0x18,
+ 0x20, 0x2E, 0x46, 0x3C,
+ 0x28, 0x1F, 0x18, 0x10,
+ 0x04, 0x04, 0x10, 0x18,
+ 0x20, 0x2E, 0x46, 0x3C,
+ 0x28, 0x1F, 0x18, 0x10,
+ 0x04, 0xFF, 0xFF, 0xFF
+};
+static char disp_on10[24] = {
+ 0x11, 0x00, 0x29, 0xC0,
+ 0xD0, 0x29, 0x03, 0xce,
+ 0xa6, 0x00, 0x43, 0x20,
+ 0x10, 0x01, 0x00, 0x01,
+ 0x01, 0x00, 0x03, 0x01,
+ 0x00, 0xFF, 0xFF, 0xFF
+};
+static char disp_on11[12] = {
+ 0x08, 0x00, 0x29, 0xC0,
+ 0xD1, 0x18, 0x0C, 0x23,
+ 0x03, 0x75, 0x02, 0x50
+};
+static char disp_on12[4] = {
+ 0xD3, 0x11, 0x23, 0x80
+};
+static char disp_on13[8] = {
+ 0x03, 0x00, 0x29, 0xC0,
+ 0xD5, 0x2A, 0x2A, 0xFF
+};
+static char disp_on14[8] = {
+ 0x03, 0x00, 0x29, 0xC0,
+ 0xDE, 0x01, 0x51, 0xFF
+};
+static char disp_on15[4] = {
+ 0xE6, 0x51, 0x23, 0x80
+};
+static char disp_on16[4] = {
+ 0xFA, 0x03, 0x23, 0x80
+};
+static char disp_on17[4] = {
+ 0xD6, 0x28, 0x23, 0x80
+};
+static char disp_on18[4] = {
+ 0x36, 0x41, 0x15, 0x80
+};
+static char disp_on19[12] = {
+ 0x05, 0x00, 0x39, 0xC0,
+ 0x2A, 0x00, 0x00, 0x01,
+ 0xDF, 0xFF, 0xFF, 0xFF
+};
+static char disp_on20[12] = {
+ 0x05, 0x00, 0x39, 0xC0,
+ 0x2B, 0x00, 0x00, 0x03,
+ 0x1F, 0xFF, 0xFF, 0xFF
+};
+static char disp_on21[4] = {
+ 0x35, 0x00, 0x15, 0x80
+};
+static char disp_on22[8] = {
+ 0x03, 0x00, 0x39, 0xc0,
+ 0x44, 0x00, 0x50, 0xFF
+};
+static char disp_on23[4] = {
+ 0x3A, 0x77, 0x15, 0x80
+};
+static char disp_on24[4] = {
+ 0x11, 0x00, 0x05, 0x80
+};
+static char disp_on25[4] = {
+ 0x29, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd truly_wvga_panel_cmd_mode_cmds[] = {
+ {sizeof(disp_on0), (char *)disp_on0},
+ {sizeof(disp_on1), (char *)disp_on1},
+ {sizeof(disp_on2), (char *)disp_on2},
+ {sizeof(disp_on3), (char *)disp_on3},
+ {sizeof(disp_on4), (char *)disp_on4},
+ {sizeof(disp_on5), (char *)disp_on5},
+ {sizeof(disp_on6), (char *)disp_on6},
+ {sizeof(disp_on7), (char *)disp_on7},
+ {sizeof(disp_on8), (char *)disp_on8},
+ {sizeof(disp_on9), (char *)disp_on9},
+ {sizeof(disp_on10), (char *)disp_on10},
+ {sizeof(disp_on11), (char *)disp_on11},
+ {sizeof(disp_on12), (char *)disp_on12},
+ {sizeof(disp_on13), (char *)disp_on13},
+ {sizeof(disp_on14), (char *)disp_on14},
+ {sizeof(disp_on15), (char *)disp_on15},
+ {sizeof(disp_on16), (char *)disp_on16},
+ {sizeof(disp_on17), (char *)disp_on17},
+ {sizeof(disp_on18), (char *)disp_on18},
+ {sizeof(disp_on19), (char *)disp_on19},
+ {sizeof(disp_on20), (char *)disp_on20},
+ {sizeof(disp_on21), (char *)disp_on21},
+ {sizeof(disp_on22), (char *)disp_on22},
+ {sizeof(disp_on23), (char *)disp_on23},
+ {sizeof(disp_on24), (char *)disp_on24},
+ {sizeof(disp_on25), (char *)disp_on25},
+};
+
+int mipi_truly_cmd_wvga_config(void *pdata)
+{
+ int ret = NO_ERROR;
+ /* 2 Lanes -- Enables Data Lane0, 1 */
+ unsigned char lane_en = 0x3;
+ unsigned long low_pwr_stop_mode = 0;
+
+ /* Needed or else will have blank line at top of display */
+ unsigned char eof_bllp_pwr = 0x9;
+
+ unsigned char interleav = 0;
+ struct lcdc_panel_info *lcdc = NULL;
+ struct msm_panel_info *pinfo = (struct msm_panel_info *) pdata;
+
+ if (pinfo == NULL)
+ return ERR_INVALID_ARGS;
+
+ lcdc = &(pinfo->lcdc);
+ if (lcdc == NULL)
+ return ERR_INVALID_ARGS;
+
+ ret = mdss_dsi_cmd_mode_config((pinfo->xres + lcdc->xres_pad),
+ (pinfo->yres + lcdc->yres_pad),
+ (pinfo->xres),
+ (pinfo->yres),
+ pinfo->mipi.dst_format,
+ pinfo->bpp / 8,
+ lane_en,
+ 0);
+
+ return ret;
+}
+
+int mipi_truly_cmd_wvga_on()
+{
+ int ret = NO_ERROR;
+ return ret;
+}
+
+int mipi_truly_cmd_wvga_off()
+{
+ int ret = NO_ERROR;
+ return ret;
+}
+
+static struct mdss_dsi_phy_ctrl dsi_video_mode_phy_db = {
+ /* regulator */
+ {0x02, 0x08, 0x05, 0x00, 0x20, 0x03},
+ /* timing */
+ {0x5d, 0x12, 0x0c, 0x00, 0x33, 0x38,
+ 0x10, 0x16, 0x1e, 0x03, 0x04, 0x00},
+ /* phy ctrl */
+ {0x7f, 0x00, 0x00, 0x00},
+ /* strength */
+ {0xff, 0x06},
+ /* bist */
+ {0x03, 0x03, 0x00, 0x00, 0x0f, 0x00},
+ /* lane config */
+ {0x80, 0x45, 0x00, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00,
+ 0x80, 0x45, 0x00, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00,
+ 0x80, 0x45, 0x00, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00,
+ 0x80, 0x45, 0x00, 0x00, 0x00, 0x01, 0x66, 0x00, 0x00,
+ 0x40, 0x67, 0x00, 0x00, 0x00, 0x01, 0x88, 0x00, 0x00},
+};
+
+void mipi_truly_cmd_wvga_init(struct msm_panel_info *pinfo)
+{
+ if (!pinfo)
+ return;
+
+ pinfo->xres = WVGA_MIPI_FB_WIDTH;
+ pinfo->yres = WVGA_MIPI_FB_HEIGHT;
+ pinfo->lcdc.h_back_porch = MIPI_HSYNC_BACK_PORCH_DCLK;
+ pinfo->lcdc.h_front_porch = MIPI_HSYNC_FRONT_PORCH_DCLK;
+ pinfo->lcdc.h_pulse_width = MIPI_HSYNC_PULSE_WIDTH;
+ pinfo->lcdc.v_back_porch = MIPI_VSYNC_BACK_PORCH_LINES;
+ pinfo->lcdc.v_front_porch = MIPI_VSYNC_FRONT_PORCH_LINES;
+ pinfo->lcdc.v_pulse_width = MIPI_VSYNC_PULSE_WIDTH;
+ pinfo->mipi.num_of_lanes = TRULY_PANEL_NUM_OF_LANES;
+ pinfo->mipi.frame_rate = TRULY_PANEL_FRAME_RATE;
+
+ pinfo->type = MIPI_CMD_PANEL;
+ pinfo->wait_cycle = 0;
+ pinfo->bpp = TRULY_PANEL_BPP;
+ pinfo->clk_rate = TRULY_PANEL_CLK_RATE;
+
+ pinfo->mipi.mode = DSI_CMD_MODE;
+ pinfo->mipi.traffic_mode = 1;
+ pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+ pinfo->mipi.vc = 0;
+ pinfo->mipi.lane_swap = TRULY_PANEL_LANE_SWAP;
+ pinfo->mipi.data_lane0 = TRUE;
+ pinfo->mipi.data_lane1 = TRUE;
+ pinfo->mipi.data_lane2 = FALSE;
+ pinfo->mipi.data_lane3 = FALSE;
+ pinfo->mipi.t_clk_post = TRULY_PANEL_T_CLK_POST;
+ pinfo->mipi.t_clk_pre = TRULY_PANEL_T_CLK_PRE;
+ pinfo->mipi.stream = 0;
+ pinfo->mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+ pinfo->mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+
+ pinfo->mipi.mdss_dsi_phy_db = &dsi_video_mode_phy_db;
+ pinfo->mipi.tx_eot_append = TRUE;
+
+ pinfo->mipi.panel_cmds = truly_wvga_panel_cmd_mode_cmds;
+ pinfo->mipi.num_of_panel_cmds = ARRAY_SIZE(truly_wvga_panel_cmd_mode_cmds);
+
+ pinfo->on = mipi_truly_cmd_wvga_on;
+ pinfo->off = mipi_truly_cmd_wvga_off;
+ pinfo->config = mipi_truly_cmd_wvga_config;
+
+ return;
+}
diff --git a/dev/panel/msm/rules.mk b/dev/panel/msm/rules.mk
index b3bdac3..56e6815 100644
--- a/dev/panel/msm/rules.mk
+++ b/dev/panel/msm/rules.mk
@@ -24,7 +24,8 @@
ifeq ($(PLATFORM),msm8974)
OBJS += \
$(LOCAL_DIR)/mipi_toshiba_video_720p.o \
- $(LOCAL_DIR)/mipi_sharp_video_qhd.o
+ $(LOCAL_DIR)/mipi_sharp_video_qhd.o \
+ $(LOCAL_DIR)/edp_auo_1080p.o
endif
ifeq ($(PLATFORM),msm8226)
@@ -35,5 +36,6 @@
ifeq ($(PLATFORM),msm8610)
OBJS += \
- $(LOCAL_DIR)/mipi_truly_video_wvga.o
+ $(LOCAL_DIR)/mipi_truly_video_wvga.o \
+ $(LOCAL_DIR)/mipi_truly_cmd_wvga.o
endif
diff --git a/dev/pmic/pm8921/pm8921.c b/dev/pmic/pm8921/pm8921.c
index cafa6a8..9cf5e91 100644
--- a/dev/pmic/pm8921/pm8921.c
+++ b/dev/pmic/pm8921/pm8921.c
@@ -747,3 +747,23 @@
return 0;
}
+
+int pm8921_configure_wled(void)
+{
+ pm8921_masked_write(WLED_BOOST_CFG_REG, 0xFF, 0x47);
+ pm8921_masked_write(WLED_HIGH_POLE_CAP_REG, 0xFF, 0x2c);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(2), 0xFF, 0x19);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(3), 0xFF, 0x59);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(4), 0xFF, 0x59);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(5), 0xFF, 0x66);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(6), 0xFF, 0x66);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(7), 0xFF, 0x0f);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(8), 0xFF, 0xff);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(9), 0xFF, 0x0f);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(10), 0xFF, 0xff);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(12), 0xFF, 0x16);
+ pm8921_masked_write(SSBI_REG_ADDR_WLED_CTRL(13), 0xFF, 0x55);
+ pm8921_masked_write(WLED_MOD_CTRL_REG, 0xFF, 0x7f);
+ pm8921_masked_write(WLED_SYNC_REG, WLED_SYNC_MASK, WLED_SYNC_VAL);
+ pm8921_masked_write(WLED_SYNC_REG, WLED_SYNC_MASK, WLED_SYNC_RESET_VAL);
+}
diff --git a/dev/pmic/pm8921/pm8921_hw.h b/dev/pmic/pm8921/pm8921_hw.h
index ea3046f..02771ce 100644
--- a/dev/pmic/pm8921/pm8921_hw.h
+++ b/dev/pmic/pm8921/pm8921_hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -154,6 +154,18 @@
#define PLDO_TYPE 0
#define NLDO_TYPE 1
+#define SSBI_REG_ADDR_WLED_CTRL_BASE 0x25A
+#define SSBI_REG_ADDR_WLED_CTRL(n) (SSBI_REG_ADDR_WLED_CTRL_BASE + (n) - 1)
+
+/* wled control registers */
+#define WLED_MOD_CTRL_REG SSBI_REG_ADDR_WLED_CTRL(1)
+#define WLED_SYNC_REG SSBI_REG_ADDR_WLED_CTRL(11)
+#define WLED_BOOST_CFG_REG SSBI_REG_ADDR_WLED_CTRL(14)
+#define WLED_HIGH_POLE_CAP_REG SSBI_REG_ADDR_WLED_CTRL(16)
+#define WLED_SYNC_VAL 0x07
+#define WLED_SYNC_RESET_VAL 0x00
+#define WLED_SYNC_MASK 0xF8
+
#define PM8921_MVS_5V_HDMI_SWITCH 0x70
#define LDO(_name, _type, _test_reg, _ctrl_reg) \
diff --git a/platform/msm8974/include/platform/clock.h b/platform/msm8974/include/platform/clock.h
index e9f8d08..c96763a 100644
--- a/platform/msm8974/include/platform/clock.h
+++ b/platform/msm8974/include/platform/clock.h
@@ -81,6 +81,16 @@
#define DSI_PIXEL1_CFG_RCGR REG_MM(0x2024)
#define DSI_PIXEL1_CBCR REG_MM(0x2318)
+#define MDSS_EDPPIXEL_CBCR REG_MM(0x232C)
+#define MDSS_EDPLINK_CBCR REG_MM(0x2330)
+#define EDPPIXEL_M REG_MM(0x20A8)
+#define EDPPIXEL_N REG_MM(0x20AC)
+#define EDPPIXEL_D REG_MM(0x20B0)
+#define EDPPIXEL_CFG_RCGR REG_MM(0x20A4)
+#define EDPPIXEL_CMD_RCGR REG_MM(0x20A0)
+#define EDPLINK_CFG_RCGR REG_MM(0x20C4)
+#define EDPLINK_CMD_RCGR REG_MM(0x20C0)
+
void platform_clock_init(void);
void clock_init_mmc(uint32_t interface);
@@ -90,6 +100,7 @@
void clock_config_ce(uint8_t instance);
void mdp_clock_init(void);
void mdp_gdsc_ctrl(uint8_t enable);
+void edp_clk_enable(void);
void clock_ce_enable(uint8_t instance);
void clock_ce_disable(uint8_t instance);
diff --git a/platform/msm8974/include/platform/iomap.h b/platform/msm8974/include/platform/iomap.h
index 3e27c3b..b3edca9 100644
--- a/platform/msm8974/include/platform/iomap.h
+++ b/platform/msm8974/include/platform/iomap.h
@@ -182,6 +182,8 @@
#define MIPI_DSI1_BASE (0xFD922E00)
#define REG_DSI(off) (MIPI_DSI_BASE + 0x04 + (off))
+#define EDP_BASE (0xFD923400)
+
#define MDP_BASE (0xfd900000)
#define REG_MDP(off) (MDP_BASE + (off))
diff --git a/platform/msm8974/msm8974-clock.c b/platform/msm8974/msm8974-clock.c
index dbba8c4..991fe17 100644
--- a/platform/msm8974/msm8974-clock.c
+++ b/platform/msm8974/msm8974-clock.c
@@ -44,6 +44,8 @@
#define mmpll1_mm_source_val 2
#define mmpll3_mm_source_val 3
#define gpll0_mm_source_val 5
+#define edppll_270_mm_source_val 4
+#define edppll_350_mm_source_val 4
struct clk_freq_tbl rcg_dummy_freq = F_END;
@@ -624,6 +626,60 @@
},
};
+static struct clk_freq_tbl ftbl_mdss_edplink_clk[] = {
+ F_MDSS(162000000, edppll_270, 2, 0, 0),
+ F_MDSS(270000000, edppll_270, 11, 0, 0),
+ F_END
+};
+
+static struct rcg_clk edplink_clk_src = {
+ .cmd_reg = (uint32_t *)EDPLINK_CMD_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mdss_edplink_clk,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "edplink_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdss_edppixel_clk[] = {
+ F_MDSS(138500000, edppll_350, 2, 0, 0),
+ F_MDSS(350000000, edppll_350, 11, 0, 0),
+ F_END
+};
+
+static struct rcg_clk edppixel_clk_src = {
+ .cmd_reg = (uint32_t *)EDPPIXEL_CMD_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_mnd,
+ .freq_tbl = ftbl_mdss_edppixel_clk,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "edppixel_clk_src",
+ .ops = &clk_ops_rcg_mnd,
+ },
+};
+
+static struct branch_clk mdss_edplink_clk = {
+ .cbcr_reg = (uint32_t *)MDSS_EDPLINK_CBCR,
+ .has_sibling = 0,
+ .parent = &edplink_clk_src.c,
+ .c = {
+ .dbg_name = "mdss_edplink_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk mdss_edppixel_clk = {
+ .cbcr_reg = (uint32_t *)MDSS_EDPPIXEL_CBCR,
+ .has_sibling = 0,
+ .parent = &edppixel_clk_src.c,
+ .c = {
+ .dbg_name = "mdss_edppixel_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
/* Clock lookup table */
static struct clk_lookup msm_clocks_8974[] =
{
@@ -663,6 +719,9 @@
CLK_LOOKUP("mdss_mdp_clk_src", mdss_mdp_clk_src.c),
CLK_LOOKUP("mdss_mdp_clk", mdss_mdp_clk.c),
CLK_LOOKUP("mdss_mdp_lut_clk", mdss_mdp_lut_clk.c),
+
+ CLK_LOOKUP("edp_pixel_clk", mdss_edppixel_clk.c),
+ CLK_LOOKUP("edp_link_clk", mdss_edplink_clk.c),
};
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index ee0582d..6b596fa 100644
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -52,6 +52,75 @@
*/
extern int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
+struct msm_id
+{
+ uint32_t platform_id;
+ uint32_t hardware_id;
+ uint32_t soc_rev;
+};
+
+/* Returns soc version if platform id and hardware id matches
+ otherwise return 0xFFFFFFFF */
+#define INVALID_SOC_REV_ID 0XFFFFFFFF
+static uint32_t dev_tree_compatible(void *dtb)
+{
+ int root_offset;
+ const void *prop;
+ char model[128];
+ struct msm_id msm_id;
+ int len;
+
+ root_offset = fdt_path_offset(dtb, "/");
+ if (root_offset < 0)
+ return false;
+
+ prop = fdt_getprop(dtb, root_offset, "model", &len);
+ if (prop && len > 0) {
+ memcpy(model, prop, MIN((int)sizeof(model), len));
+ model[sizeof(model) - 1] = '\0';
+ } else {
+ model[0] = '\0';
+ }
+
+ prop = fdt_getprop(dtb, root_offset, "qcom,msm-id", &len);
+ if (!prop || len <= 0) {
+ dprintf(INFO, "qcom,msm-id entry not found\n");
+ return false;
+ } else if (len < (int)sizeof(struct msm_id)) {
+ dprintf(INFO, "qcom,msm-id entry size mismatch (%d != %d)\n",
+ len, sizeof(struct msm_id));
+ return false;
+ }
+ msm_id.platform_id = fdt32_to_cpu(((const struct msm_id *)prop)->platform_id);
+ msm_id.hardware_id = fdt32_to_cpu(((const struct msm_id *)prop)->hardware_id);
+ msm_id.soc_rev = fdt32_to_cpu(((const struct msm_id *)prop)->soc_rev);
+
+ dprintf(INFO, "Found an appended flattened device tree (%s - %d %d 0x%x)\n",
+ *model ? model : "unknown",
+ msm_id.platform_id, msm_id.hardware_id, msm_id.soc_rev);
+
+ if (msm_id.platform_id != board_platform_id() ||
+ msm_id.hardware_id != board_hardware_id()) {
+ dprintf(INFO, "Device tree's msm_id doesn't match the board: <%d %d 0x%x> != <%d %d 0x%x>\n",
+ msm_id.platform_id,
+ msm_id.hardware_id,
+ msm_id.soc_rev,
+ board_platform_id(),
+ board_hardware_id(),
+ board_soc_version());
+ return INVALID_SOC_REV_ID;
+ }
+
+ dprintf(INFO, "Device tree's msm_id matchs the board: <%d %d 0x%x> != <%d %d 0x%x>\n",
+ msm_id.platform_id,
+ msm_id.hardware_id,
+ msm_id.soc_rev,
+ board_platform_id(),
+ board_hardware_id(),
+ board_soc_version());
+ return msm_id.soc_rev;
+}
+
/*
* Will relocate the DTB to the tags addr if the device tree is found and return
* its address
@@ -63,46 +132,66 @@
* Return Value: DTB address : If appended device tree is found
* 'NULL' : Otherwise
*/
-void *dev_tree_appended(void *kernel, void *tags, uint32_t kernel_size)
+void *dev_tree_appended(void *kernel, uint32_t kernel_size, void *tags)
{
+ void *kernel_end = kernel + kernel_size;
uint32_t app_dtb_offset = 0;
- uint32_t size;
+ void *dtb;
+ void *bestmatch_tag = NULL;
+ uint32_t bestmatch_tag_size;
+ uint32_t bestmatch_soc_rev_id = INVALID_SOC_REV_ID;
memcpy((void*) &app_dtb_offset, (void*) (kernel + DTB_OFFSET), sizeof(uint32_t));
- /*
- * Check if we have valid offset for the DTB, if not return error.
- * If the kernel image does not have appeneded device tree, DTB offset
- * might contain some random address which is not accessible & cause
- * data abort. If kernel start + dtb offset address exceed the total
- * size of the kernel, then we dont have an appeneded DTB.
- */
- if (app_dtb_offset < kernel_size)
- {
- if (!fdt_check_header((void*) (kernel + app_dtb_offset)))
- {
- void *dtb;
- int rc;
+ dtb = kernel + app_dtb_offset;
+ while (dtb + sizeof(struct fdt_header) < kernel_end) {
+ uint32_t dtb_soc_rev_id;
+ struct fdt_header dtb_hdr;
+ uint32_t dtb_size;
- dprintf(INFO, "Found Appeneded Flattened Device tree\n");
- dtb = kernel + app_dtb_offset;
- size = fdt_totalsize(dtb);
- if (check_aboot_addr_range_overlap(tags, size))
- {
- dprintf(CRITICAL, "Appended dtb aboot overlap check failed.\n");
- return NULL;
- }
- rc = fdt_open_into(dtb, tags, size);
- if (rc == 0)
- {
- /* clear out the old DTB magic so kernel doesn't find it */
- *((uint32_t *)dtb) = 0;
- return tags;
+ /* the DTB could be unaligned, so extract the header,
+ * and operate on it separately */
+ memcpy(&dtb_hdr, dtb, sizeof(struct fdt_header));
+ if (fdt_check_header((const void *)&dtb_hdr) != 0 ||
+ (dtb + fdt_totalsize((const void *)&dtb_hdr) > kernel_end))
+ break;
+ dtb_size = fdt_totalsize(&dtb_hdr);
+
+ /* now that we know we have a valid DTB, we need to copy
+ * it somewhere aligned, like tags */
+ memcpy(tags, dtb, dtb_size);
+
+ dtb_soc_rev_id = dev_tree_compatible(tags);
+ if (dtb_soc_rev_id == board_soc_version()) {
+ /* clear out the old DTB magic so kernel doesn't find it */
+ *((uint32_t *)(kernel + app_dtb_offset)) = 0;
+ return tags;
+ } else if ((dtb_soc_rev_id != INVALID_SOC_REV_ID) &&
+ (dtb_soc_rev_id < board_soc_version())) {
+ /* if current bestmatch is less than new dtb_soc_rev_id then update
+ bestmatch_tag */
+ if((bestmatch_soc_rev_id == INVALID_SOC_REV_ID) ||
+ (bestmatch_soc_rev_id < dtb_soc_rev_id)) {
+ bestmatch_tag = dtb;
+ bestmatch_tag_size = dtb_size;
+ bestmatch_soc_rev_id = dtb_soc_rev_id;
}
}
+
+ /* goto the next device tree if any */
+ dtb += dtb_size;
}
- else
- dprintf(CRITICAL, "DTB offset is incorrect, kernel image does not have appended DTB\n");
+
+ if(bestmatch_tag) {
+ dprintf(INFO,"DTB found with bestmatch soc rev id 0x%x.Board soc rev id 0x%x\n",
+ bestmatch_soc_rev_id, board_soc_version());
+ memcpy(tags, bestmatch_tag, bestmatch_tag_size);
+ /* clear out the old DTB magic so kernel doesn't find it */
+ *((uint32_t *)(kernel + app_dtb_offset)) = 0;
+ return tags;
+ }
+
+ dprintf(CRITICAL, "DTB offset is incorrect, kernel image does not have appended DTB\n");
return NULL;
}
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
old mode 100755
new mode 100644
index 9254a78..3768ca8
--- a/platform/msm_shared/display.c
+++ b/platform/msm_shared/display.c
@@ -112,8 +112,8 @@
break;
case MIPI_CMD_PANEL:
dprintf(INFO, "Config MIPI_CMD_PANEL.\n");
-
- if (mdp_get_revision() == MDP_REV_50)
+ mdp_rev = mdp_get_revision();
+ if (mdp_rev == MDP_REV_50 || mdp_rev == MDP_REV_304)
ret = mdss_dsi_config(panel);
else
ret = mipi_config(panel);
@@ -150,6 +150,7 @@
int msm_display_on()
{
int ret = NO_ERROR;
+ int mdp_rev;
struct msm_panel_info *pinfo;
if (!panel)
@@ -183,7 +184,8 @@
ret = mdp_dma_on();
if (ret)
goto msm_display_on_out;
- if (mdp_get_revision() != MDP_REV_50) {
+ mdp_rev = mdp_get_revision();
+ if (mdp_rev != MDP_REV_50 && mdp_rev != MDP_REV_304) {
ret = mipi_cmd_trigger();
if (ret)
goto msm_display_on_out;
diff --git a/platform/msm_shared/edp.c b/platform/msm_shared/edp.c
new file mode 100644
index 0000000..d170f19
--- /dev/null
+++ b/platform/msm_shared/edp.c
@@ -0,0 +1,163 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE 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 "edp.h"
+#include "mdp5.h"
+
+#define RGB_COMPONENTS 3
+#define MAX_NUMBER_EDP_LANES 4
+
+static void edp_config_sync(void)
+{
+ int ret = 0;
+
+ ret = edp_read(EDP_BASE + 0xc); /* EDP_CONFIGURATION_CTRL */
+ ret &= ~0x733;
+ ret |= (0x55 & 0x733);
+ edp_write(EDP_BASE + 0xc, ret);
+ edp_write(EDP_BASE + 0xc, 0x55); /* EDP_CONFIGURATION_CTRL */
+}
+
+static void edp_config_sw_div(void)
+{
+ edp_write(EDP_BASE + 0x14, 0x13b); /* EDP_SOFTWARE_MVID */
+ edp_write(EDP_BASE + 0x18, 0x266); /* EDP_SOFTWARE_NVID */
+}
+
+static void edp_config_static_mdiv(void)
+{
+ int ret = 0;
+
+ ret = edp_read(EDP_BASE + 0xc); /* EDP_CONFIGURATION_CTRL */
+ edp_write(EDP_BASE + 0xc, ret | 0x2); /* EDP_CONFIGURATION_CTRL */
+ edp_write(EDP_BASE + 0xc, 0x57); /* EDP_CONFIGURATION_CTRL */
+}
+
+static void edp_config_timing(void)
+{
+ edp_write(EDP_BASE + 0x98, 0);
+ edp_write(EDP_BASE + 0x9C, 0x8200020); /* EDP_HSYNC_CTL */
+ edp_write(EDP_BASE + 0x100, 0x233AC0); /* EDP_VSYNC_PERIOD_F0 */
+ edp_write(EDP_BASE + 0x104, 0x0);
+ edp_write(EDP_BASE + 0x10C, 0x0);
+ edp_write(EDP_BASE + 0x130, 0x7ef0070); /* EDP_DISPLAY_HCTL */
+ edp_write(EDP_BASE + 0x134, 0x0); /* EDP_ACTIVE_HCTL */
+ edp_write(EDP_BASE + 0x110, 0xB330); /* EDP_DISPLAY_V_START_F0 */
+ edp_write(EDP_BASE + 0x118, 0x22f98f); /* EDP_DISPLAY_V_END_F0 */
+ edp_write(EDP_BASE + 0x114, 0x0);
+ edp_write(EDP_BASE + 0x11C, 0x0);
+ edp_write(EDP_BASE + 0x120, 0x0); /* EDP_ACTIVE_V_START_F0 */
+ edp_write(EDP_BASE + 0x128, 0x0); /* EDP_ACTIVE_V_END_F0 */
+ edp_write(EDP_BASE + 0x124, 0x0);
+ edp_write(EDP_BASE + 0x12C, 0x0);
+}
+
+static void edp_enable(int enable)
+{
+ edp_write(EDP_BASE + 0x8, 0x0); /* EDP_STATE_CTRL */
+ edp_write(EDP_BASE + 0x8, 0x40); /* EDP_STATE_CTRL */
+ edp_write(EDP_BASE + 0x94, enable); /* EDP_TIMING_ENGINE_EN */
+ edp_write(EDP_BASE + 0x4, enable); /* EDP_MAINLINK_CTRL */
+}
+
+/*
+ * Converts from EDID struct to msm_panel_info
+ */
+void edp_edid2pinfo(struct edp_panel_data *edp_panel)
+{
+ struct display_timing_desc *dp;
+ struct msm_panel_info *pinfo;
+
+ dp = &edp_panel->edid.timing[0];
+ pinfo = &edp_panel->panel_data->panel_info;
+
+ pinfo->clk_rate = dp->pclk;
+
+ pinfo->xres = dp->h_addressable + dp->h_border * 2;
+ pinfo->yres = dp->v_addressable + dp->v_border * 2;
+
+ pinfo->lcdc.h_back_porch = dp->h_blank - dp->h_fporch \
+ - dp->h_sync_pulse;
+ pinfo->lcdc.h_front_porch = dp->h_fporch;
+ pinfo->lcdc.h_pulse_width = dp->h_sync_pulse;
+
+ pinfo->lcdc.v_back_porch = dp->v_blank - dp->v_fporch \
+ - dp->v_sync_pulse;
+ pinfo->lcdc.v_front_porch = dp->v_fporch;
+ pinfo->lcdc.v_pulse_width = dp->v_sync_pulse;
+
+ pinfo->type = EDP_PANEL;
+ pinfo->wait_cycle = 0;
+ pinfo->bpp = 24;
+
+ pinfo->lcdc.border_clr = 0; /* black */
+ pinfo->lcdc.underflow_clr = 0xff; /* blue */
+ pinfo->lcdc.hsync_skew = 0;
+}
+
+int edp_on(void)
+{
+ int i;
+
+ edp_phy_sw_reset();
+ edp_pll_configure();
+ edp_config_clk();
+ edp_phy_misc_cfg();
+ edp_config_sync();
+ edp_config_sw_div();
+ edp_config_static_mdiv();
+ edp_config_timing();
+
+ edp_hw_powerup(1);
+
+ for (i = 0; i < MAX_NUMBER_EDP_LANES; ++i)
+ edp_enable_lane_bist(i, 1);
+
+ edp_enable_mainlink(1);
+ edp_enable(1);
+
+ return 0;
+}
+
+int edp_off(void)
+{
+ int i;
+
+ mdp_edp_off();
+ edp_enable(0);
+ edp_unconfig_clk();
+ edp_enable_mainlink(0);
+
+ for (i = 0; i < MAX_NUMBER_EDP_LANES; ++i)
+ edp_enable_lane_bist(i, 0);
+
+ edp_hw_powerup(0);
+
+ return 0;
+}
diff --git a/platform/msm_shared/edp_phy.c b/platform/msm_shared/edp_phy.c
new file mode 100644
index 0000000..32ca68e
--- /dev/null
+++ b/platform/msm_shared/edp_phy.c
@@ -0,0 +1,197 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE 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 "edp.h"
+#include <platform/timer.h>
+
+/* EDP phy configuration settings */
+void edp_phy_sw_reset(void)
+{
+ /* phy sw reset */
+ edp_write(EDP_BASE + 0x74, 0x100); /* EDP_PHY_CTRL */
+ dmb();
+ udelay(1);
+ edp_write(EDP_BASE + 0x74, 0x000); /* EDP_PHY_CTRL */
+ dmb();
+ udelay(1);
+
+ /* phy PLL sw reset */
+ edp_write(EDP_BASE + 0x74, 0x001); /* EDP_PHY_CTRL */
+ dmb();
+ udelay(1);
+ edp_write(EDP_BASE + 0x74, 0x000); /* EDP_PHY_CTRL */
+ dmb();
+ udelay(1);
+}
+
+void edp_hw_powerup(int enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ /* EDP_PHY_EDPPHY_GLB_PD_CTL */
+ edp_write(EDP_BASE + 0x52c, 0x3f);
+ /* EDP_PHY_EDPPHY_GLB_CFG */
+ edp_write(EDP_BASE + 0x528, 0x1);
+ /* EDP_PHY_PLL_UNIPHY_PLL_GLB_CFG */
+ edp_write(EDP_BASE + 0x620, 0xf);
+ /* EDP_AUX_CTRL */
+ ret = edp_read(EDP_BASE + 0x300);
+ edp_write(EDP_BASE + 0x300, ret | 0x1);
+ } else {
+ /* EDP_PHY_EDPPHY_GLB_PD_CTL */
+ edp_write(EDP_BASE + 0x52c, 0xc0);
+ }
+}
+
+void edp_pll_configure(void)
+{
+ edp_write(EDP_BASE + 0x664, 0x5); /* UNIPHY_PLL_LKDET_CFG2 */
+ edp_write(EDP_BASE + 0x600, 0x1); /* UNIPHY_PLL_REFCLK_CFG */
+ edp_write(EDP_BASE + 0x638, 0x36); /* UNIPHY_PLL_SDM_CFG0 */
+ edp_write(EDP_BASE + 0x63c, 0x62); /* UNIPHY_PLL_SDM_CFG1 */
+ edp_write(EDP_BASE + 0x640, 0x0); /* UNIPHY_PLL_SDM_CFG2 */
+ edp_write(EDP_BASE + 0x644, 0x28); /* UNIPHY_PLL_SDM_CFG3 */
+ edp_write(EDP_BASE + 0x648, 0x0); /* UNIPHY_PLL_SDM_CFG4 */
+ edp_write(EDP_BASE + 0x64c, 0x80); /* UNIPHY_PLL_SSC_CFG0 */
+ edp_write(EDP_BASE + 0x650, 0x0); /* UNIPHY_PLL_SSC_CFG1 */
+ edp_write(EDP_BASE + 0x654, 0x0); /* UNIPHY_PLL_SSC_CFG2 */
+ edp_write(EDP_BASE + 0x658, 0x0); /* UNIPHY_PLL_SSC_CFG3 */
+ edp_write(EDP_BASE + 0x66c, 0xa); /* UNIPHY_PLL_CAL_CFG0 */
+ edp_write(EDP_BASE + 0x674, 0x1); /* UNIPHY_PLL_CAL_CFG2 */
+ edp_write(EDP_BASE + 0x684, 0x5a); /* UNIPHY_PLL_CAL_CFG6 */
+ edp_write(EDP_BASE + 0x688, 0x0); /* UNIPHY_PLL_CAL_CFG7 */
+ edp_write(EDP_BASE + 0x68c, 0x60); /* UNIPHY_PLL_CAL_CFG8 */
+ edp_write(EDP_BASE + 0x690, 0x0); /* UNIPHY_PLL_CAL_CFG9 */
+ edp_write(EDP_BASE + 0x694, 0x46); /* UNIPHY_PLL_CAL_CFG10 */
+ edp_write(EDP_BASE + 0x698, 0x5); /* UNIPHY_PLL_CAL_CFG11 */
+ edp_write(EDP_BASE + 0x65c, 0x10); /* UNIPHY_PLL_LKDET_CFG0 */
+ edp_write(EDP_BASE + 0x660, 0x1a); /* UNIPHY_PLL_LKDET_CFG1 */
+ edp_write(EDP_BASE + 0x604, 0x0); /* UNIPHY_PLL_POSTDIV1_CFG */
+ edp_write(EDP_BASE + 0x624, 0x0); /* UNIPHY_PLL_POSTDIV2_CFG */
+ edp_write(EDP_BASE + 0x628, 0x0); /* UNIPHY_PLL_POSTDIV3_CFG */
+
+ edp_write(EDP_BASE + 0x620, 0x1); /* UNIPHY_PLL_GLB_CFG */
+ edp_write(EDP_BASE + 0x620, 0x5); /* UNIPHY_PLL_GLB_CFG */
+ edp_write(EDP_BASE + 0x620, 0x7); /* UNIPHY_PLL_GLB_CFG */
+ edp_write(EDP_BASE + 0x620, 0xf); /* UNIPHY_PLL_GLB_CFG */
+}
+
+void edp_enable_mainlink(int enable)
+{
+ uint32_t data;
+
+ data = edp_read(EDP_BASE + 0x004);
+ data &= ~BIT(0);
+
+ if (enable) {
+ data |= 0x1;
+ edp_write(EDP_BASE + 0x004, data);
+ edp_write(EDP_BASE + 0x004, 0x1);
+ } else {
+ data |= 0x0;
+ edp_write(EDP_BASE + 0x004, data);
+ }
+}
+
+void edp_enable_lane_bist(int lane, int enable)
+{
+ unsigned char *addr_ln_bist_cfg, *addr_ln_pd_ctrl;
+
+ /* EDP_PHY_EDPPHY_LNn_PD_CTL */
+ addr_ln_pd_ctrl = (unsigned char *)(EDP_BASE + 0x404 + (0x40 * lane));
+ /* EDP_PHY_EDPPHY_LNn_BIST_CFG0 */
+ addr_ln_bist_cfg = (unsigned char *)(EDP_BASE + 0x408 + (0x40 * lane));
+
+ if (enable) {
+ edp_write(addr_ln_pd_ctrl, 0x0);
+ edp_write(addr_ln_bist_cfg, 0x10);
+
+ } else {
+ edp_write(addr_ln_pd_ctrl, 0xf);
+ edp_write(addr_ln_bist_cfg, 0x10);
+ }
+}
+
+void edp_enable_pixel_clk(int enable)
+{
+ if (!enable) {
+ edp_write(MDSS_EDPPIXEL_CBCR, 0); /* CBCR */
+ return;
+ }
+
+ edp_write(EDP_BASE + 0x624, 0x1); /* PostDiv2 */
+
+ /* Configuring MND for Pixel */
+ edp_write(EDPPIXEL_M, 0x3f); /* M value */
+ edp_write(EDPPIXEL_N, 0xb); /* N value */
+ edp_write(EDPPIXEL_D, 0x0); /* D value */
+
+ /* CFG RCGR */
+ edp_write(EDPPIXEL_CFG_RCGR, (5 << 8) | (2 << 12));
+ edp_write(EDPPIXEL_CMD_RCGR, 3); /* CMD RCGR */
+
+ edp_write(MDSS_EDPPIXEL_CBCR, 1); /* CBCR */
+}
+
+void edp_enable_link_clk(int enable)
+{
+ if (!enable) {
+ edp_write(MDSS_EDPLINK_CBCR, 0); /* CBCR */
+ return;
+ }
+
+ edp_write(EDPLINK_CFG_RCGR, (4 << 8)); /* CFG RCGR */
+ edp_write(EDPLINK_CMD_RCGR, 3); /* CMD RCGR */
+
+ edp_write(MDSS_EDPLINK_CBCR, 1); /* CBCR */
+}
+
+void edp_config_clk(void)
+{
+ edp_enable_link_clk(1);
+ edp_enable_pixel_clk(1);
+}
+
+void edp_unconfig_clk(void)
+{
+ edp_enable_link_clk(0);
+ edp_enable_pixel_clk(0);
+}
+
+void edp_phy_misc_cfg(void)
+{
+ /* EDP_PHY_EDPPHY_GLB_VM_CFG0 */
+ edp_write(EDP_BASE + 0x510, 0x3);
+ /* EDP_PHY_EDPPHY_GLB_VM_CFG1 */
+ edp_write(EDP_BASE + 0x514, 0x64);
+ /* EDP_PHY_EDPPHY_GLB_MISC9 */
+ edp_write(EDP_BASE + 0x518, 0x6c);
+ /* EDP_MISC1_MISC0 */
+ edp_write(EDP_BASE + 0x2c, 0x1);
+}
diff --git a/platform/msm_shared/include/clock_lib2.h b/platform/msm_shared/include/clock_lib2.h
index a7606bc..008d5fa 100644
--- a/platform/msm_shared/include/clock_lib2.h
+++ b/platform/msm_shared/include/clock_lib2.h
@@ -70,6 +70,16 @@
| BVAL(10, 8, s##_mm_source_val), \
}
+#define F_MDSS(f, s, div, m, n) \
+ { \
+ .freq_hz = (f), \
+ .m_val = (m), \
+ .n_val = ~((n)-(m)) * !!(n), \
+ .d_val = ~(n),\
+ .div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
+ | BVAL(10, 8, s##_mm_source_val), \
+ }
+
/* Branch Clock Bits */
#define CBCR_BRANCH_ENABLE_BIT BIT(0)
#define CBCR_BRANCH_OFF_BIT BIT(31)
diff --git a/platform/msm_shared/include/dev_tree.h b/platform/msm_shared/include/dev_tree.h
index d0b0ca8..2a8ee01 100644
--- a/platform/msm_shared/include/dev_tree.h
+++ b/platform/msm_shared/include/dev_tree.h
@@ -70,5 +70,5 @@
int dev_tree_get_entry_info(struct dt_table *table, struct dt_entry *dt_entry_info);
int update_device_tree(void *, const char *, void *, unsigned);
int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint32_t size, uint32_t addr);
-void *dev_tree_appended(void *kernel, void *tags, uint32_t kernel_size);
+void *dev_tree_appended(void *kernel, uint32_t kernel_size, void *tags);
#endif
diff --git a/platform/msm_shared/include/edp.h b/platform/msm_shared/include/edp.h
new file mode 100644
index 0000000..04a3e49
--- /dev/null
+++ b/platform/msm_shared/include/edp.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE 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 EDP_H
+#define EDP_H
+
+#include "msm_panel.h"
+#include <reg.h>
+#include <debug.h>
+#include <err.h>
+#include <platform/iomap.h>
+#include <platform/clock.h>
+
+#define edp_read(offset) readl_relaxed((offset))
+#define edp_write(offset, data) writel_relaxed((data), (offset))
+
+void edp_phy_sw_reset(void);
+void edp_pll_configure(void);
+void edp_enable_lane_bist(int lane, int enable);
+void edp_enable_mainlink(int enable);
+void edp_hw_powerup(int enable);
+void edp_config_clk(void);
+void edp_unconfig_clk(void);
+void edp_phy_misc_cfg(void);
+void edp_edid2pinfo(struct edp_panel_data *edp_panel);
+int edp_on(void);
+int edp_off(void);
+int edp_config(void *pdata);
+
+#endif /* EDP_H */
diff --git a/platform/msm_shared/include/mdp3.h b/platform/msm_shared/include/mdp3.h
index 813b4ba..8dff686 100644
--- a/platform/msm_shared/include/mdp3.h
+++ b/platform/msm_shared/include/mdp3.h
@@ -28,6 +28,8 @@
*/
#include <dev/fbcon.h>
+#include <msm_panel.h>
+
//TODO: Make a global PASS / FAIL define
#define PASS 0
#define FAIL 1
@@ -51,3 +53,8 @@
void mdp_shutdown(void);
void mdp_set_revision(int rev);
int mdp_get_revision();
+
+/* defining no-op functions that are implemented only for mdp5 */
+int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
+int mdp_edp_on(void);
+int mdp_edp_off(void);
diff --git a/platform/msm_shared/include/mdp4.h b/platform/msm_shared/include/mdp4.h
index e0fc2c7..c988dee 100644
--- a/platform/msm_shared/include/mdp4.h
+++ b/platform/msm_shared/include/mdp4.h
@@ -111,4 +111,10 @@
int mdp_lcdc_off();
void mdp_set_revision(int rev);
int mdp_get_revision();
+
+/* defining no-op functions that are implemented only for mdp5 */
+int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
+int mdp_edp_on(void);
+int mdp_edp_off(void);
+
#endif
diff --git a/platform/msm_shared/include/mdp5.h b/platform/msm_shared/include/mdp5.h
index 994d54e..75e4e0d 100644
--- a/platform/msm_shared/include/mdp5.h
+++ b/platform/msm_shared/include/mdp5.h
@@ -76,6 +76,7 @@
#define MDP_UPPER_NEW_ROI_PRIOR_RO_START REG_MDP(0x02EC)
#define MDP_LOWER_NEW_ROI_PRIOR_TO_START REG_MDP(0x04F8)
+#define MDP_INTF_0_TIMING_ENGINE_EN REG_MDP(0x12500)
#define MDP_INTF_1_TIMING_ENGINE_EN REG_MDP(0x12700)
#define MDP_CTL_0_BASE REG_MDP(0x600)
@@ -91,6 +92,7 @@
#define MDP_REG_SPLIT_DISPLAY_EN REG_MDP(0x3F4)
#define MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL REG_MDP(0x3F8)
+#define MDP_INTF_0_BASE REG_MDP(0x12500)
#define MDP_INTF_1_BASE REG_MDP(0x12700)
#define MDP_INTF_2_BASE REG_MDP(0x12900)
@@ -156,6 +158,9 @@
unsigned short num_of_lanes);
int mdp_dsi_video_on(void);
int mdp_dma_on(void);
+int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
+int mdp_edp_on(void);
+int mdp_edp_off(void);
void mdp_disable(void);
#endif
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index 22a47ad..42f2b47 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -49,6 +49,7 @@
#define MIPI_CMD_PANEL 9 /* MIPI */
#define WRITEBACK_PANEL 10 /* Wifi display */
#define LVDS_PANEL 11 /* LVDS */
+#define EDP_PANEL 12 /* EDP */
enum msm_mdp_hw_revision {
MDP_REV_20 = 1,
@@ -207,6 +208,56 @@
int (*pll_clk_func) (int enable, struct msm_panel_info *);
};
+struct display_timing_desc {
+ uint32_t pclk;
+ uint32_t h_addressable; /* addressable + boder = active */
+ uint32_t h_border;
+ uint32_t h_blank; /* fporch + bporch + sync_pulse = blank */
+ uint32_t h_fporch;
+ uint32_t h_sync_pulse;
+ uint32_t v_addressable; /* addressable + boder = active */
+ uint32_t v_border;
+ uint32_t v_blank; /* fporch + bporch + sync_pulse = blank */
+ uint32_t v_fporch;
+ uint32_t v_sync_pulse;
+ uint32_t width_mm;
+ uint32_t height_mm;
+ uint32_t interlaced;
+ uint32_t stereo;
+ uint32_t sync_type;
+ uint32_t sync_separate;
+ uint32_t vsync_pol;
+ uint32_t hsync_pol;
+};
+
+struct edp_edid {
+ char id_name[4];
+ short id_product;
+ char version;
+ char revision;
+ char video_digital;
+ char color_depth; /* 6, 8, 10, 12 and 14 bits */
+ char color_format; /* RGB 4:4:4, YCrCb 4:4:4, Ycrcb 4:2:2 */
+ char dpm; /* display power management */
+ char sync_digital; /* 1 = digital */
+ char sync_separate; /* 1 = separate */
+ char vsync_pol; /* 0 = negative, 1 = positive */
+ char hsync_pol; /* 0 = negative, 1 = positive */
+ char ext_block_cnt;
+ struct display_timing_desc timing[4];
+};
+
+struct dpcd_cap {
+ char max_lane_count;
+ uint32_t max_link_clk; /* 162, 270 and 540 Mb, divided by 10 */
+};
+
+struct edp_panel_data {
+ struct msm_fb_panel_data *panel_data;
+ struct edp_edid edid;
+ struct dpcd_cap dpcd;
+};
+
int msm_display_init(struct msm_fb_panel_data *pdata);
#endif
diff --git a/platform/msm_shared/mdp3.c b/platform/msm_shared/mdp3.c
index 0629b8e..169dce5 100644
--- a/platform/msm_shared/mdp3.c
+++ b/platform/msm_shared/mdp3.c
@@ -165,7 +165,7 @@
int mdp_dma_on()
{
int ret = 0;
-
+ mdelay(100);
writel(0x00000001, MDP_DMA_P_START);
return ret;
@@ -180,3 +180,18 @@
return ret;
}
+
+int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb)
+{
+ return NO_ERROR;
+}
+
+int mdp_edp_on(void)
+{
+ return NO_ERROR;
+}
+
+int mdp_edp_off(void)
+{
+ return NO_ERROR;
+}
diff --git a/platform/msm_shared/mdp4.c b/platform/msm_shared/mdp4.c
index e347438..b3ade80 100644
--- a/platform/msm_shared/mdp4.c
+++ b/platform/msm_shared/mdp4.c
@@ -408,3 +408,18 @@
{
return mdp_rev;
}
+
+int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb)
+{
+ return NO_ERROR;
+}
+
+int mdp_edp_on(void)
+{
+ return NO_ERROR;
+}
+
+int mdp_edp_off(void)
+{
+ return NO_ERROR;
+}
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index e86c8df..1a190ab 100644
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -253,6 +253,11 @@
display_vend = ((vsync_period - lcdc->v_front_porch) * hsync_period)
+lcdc->hsync_skew - 1;
+ if (intf_base == MDP_INTF_0_BASE) { /* eDP */
+ display_vstart += lcdc->h_pulse_width + lcdc->h_back_porch;
+ display_vend -= lcdc->h_front_porch;
+ }
+
hsync_ctl = (hsync_period << 16) | lcdc->h_pulse_width;
display_hctl = (hsync_end_x << 16) | hsync_start_x;
@@ -278,8 +283,10 @@
writel(0x00, MDP_ACTIVE_V_END_F1 + mdss_mdp_intf_off);
writel(0xFF, MDP_UNDERFFLOW_COLOR + mdss_mdp_intf_off);
- writel(0x213F, MDP_PANEL_FORMAT + mdss_mdp_intf_off);
-
+ if (intf_base == MDP_INTF_0_BASE) /* eDP */
+ writel(0x212A, MDP_PANEL_FORMAT + mdss_mdp_intf_off);
+ else
+ writel(0x213F, MDP_PANEL_FORMAT + mdss_mdp_intf_off);
}
void mdss_layer_mixer_setup(struct fbcon_config *fb, struct msm_panel_info
@@ -368,6 +375,33 @@
return 0;
}
+int mdp_edp_config(struct msm_panel_info *pinfo, struct fbcon_config *fb)
+{
+ int ret = NO_ERROR;
+ struct lcdc_panel_info *lcdc = NULL;
+
+ mdss_intf_tg_setup(pinfo, MDP_INTF_0_BASE);
+
+ mdp_clk_gating_ctrl();
+
+ mdss_vbif_setup();
+ mdss_smp_setup(pinfo);
+
+ writel(0x0E9, MDP_QOS_REMAPPER_CLASS_0);
+
+ mdss_rgb_pipe_config(fb, pinfo, MDP_VP_0_RGB_0_BASE);
+
+ mdss_layer_mixer_setup(fb, pinfo);
+
+ writel(0x1F10, MDP_CTL_0_BASE + CTL_TOP);
+ writel(0x9, MDP_DISP_INTF_SEL);
+ writel(0x1111, MDP_VIDEO_INTF_UNDERFLOW_CTL);
+ writel(0x01, MDP_UPPER_NEW_ROI_PRIOR_RO_START);
+ writel(0x01, MDP_LOWER_NEW_ROI_PRIOR_TO_START);
+
+ return 0;
+}
+
int mdp_dsi_cmd_config(struct msm_panel_info *pinfo,
struct fbcon_config *fb)
{
@@ -452,3 +486,26 @@
{
}
+
+int mdp_edp_on(void)
+{
+ writel(0x32048, MDP_CTL_0_BASE + CTL_FLUSH);
+ writel(0x01, MDP_INTF_0_TIMING_ENGINE_EN + mdss_mdp_intf_offset());
+ return NO_ERROR;
+}
+
+int mdp_edp_off(void)
+{
+ if (!target_cont_splash_screen()) {
+
+ writel(0x00000000, MDP_INTF_0_TIMING_ENGINE_EN +
+ mdss_mdp_intf_offset());
+ mdelay(60);
+ /* Ping-Pong done Tear Check Read/Write */
+ /* Underrun(Interface 0/1/2/3) VSYNC Interrupt Enable */
+ writel(0xFF777713, MDP_INTR_CLEAR);
+ writel(0x00000000, MDP_INTR_EN);
+ }
+
+ return NO_ERROR;
+}
diff --git a/platform/msm_shared/mipi_dsi.c b/platform/msm_shared/mipi_dsi.c
index 43559eb..6b6e6c6 100644
--- a/platform/msm_shared/mipi_dsi.c
+++ b/platform/msm_shared/mipi_dsi.c
@@ -951,7 +951,6 @@
unsigned char eof_bllp_pwr,
unsigned char interleav)
{
-
int status = 0;
/* disable mdp first */
@@ -1033,16 +1032,27 @@
uint16_t img_width,
uint16_t img_height,
uint16_t dst_format,
- uint16_t traffic_mode)
+ uint8_t ystride,
+ uint8_t lane_en,
+ uint8_t interleav)
{
- uint8_t DST_FORMAT;
- uint8_t TRAFIC_MODE;
- uint8_t DLNx_EN;
- // video mode data ctrl
- int status = 0;
- uint8_t interleav = 0;
- uint8_t ystride = 0x03;
- // disable mdp first
+ uint16_t dst_fmt = 0;
+
+ switch (dst_format) {
+ case DSI_VIDEO_DST_FORMAT_RGB565:
+ dst_fmt = DSI_CMD_DST_FORMAT_RGB565;
+ break;
+ case DSI_VIDEO_DST_FORMAT_RGB666:
+ case DSI_VIDEO_DST_FORMAT_RGB666_LOOSE:
+ dst_fmt = DSI_CMD_DST_FORMAT_RGB666;
+ break;
+ case DSI_VIDEO_DST_FORMAT_RGB888:
+ dst_fmt = DSI_CMD_DST_FORMAT_RGB888;
+ break;
+ default:
+ dprintf(CRITICAL, "unsupported dst format\n");
+ return ERROR;
+ }
#if (DISPLAY_TYPE_MDSS == 1)
writel(0x00000000, DSI_CLK_CTRL);
@@ -1061,16 +1071,7 @@
writel(0x02020202, DSI_INT_CTRL);
- DST_FORMAT = 8; // RGB888
- dprintf(SPEW, "DSI_Cmd_Mode - Dst Format: RGB888\n");
-
- DLNx_EN = 0xf; // 4 lane with clk programming
- dprintf(SPEW, "Data Lane: 4 lane\n");
-
- TRAFIC_MODE = 0; // non burst mode with sync pulses
- dprintf(SPEW, "Traffic mode: non burst mode with sync pulses\n");
-
- writel(DST_FORMAT, DSI_COMMAND_MODE_MDP_CTRL);
+ writel(dst_fmt, DSI_COMMAND_MODE_MDP_CTRL);
writel((img_width * ystride + 1) << 16 | 0x0039,
DSI_COMMAND_MODE_MDP_STREAM0_CTRL);
writel((img_width * ystride + 1) << 16 | 0x0039,
@@ -1080,13 +1081,13 @@
writel(img_height << 16 | img_width,
DSI_COMMAND_MODE_MDP_STREAM1_TOTAL);
writel(0x13c2c, DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL);
- writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4 | 0x105,
+ writel(interleav << 30 | 0 << 24 | 0 << 20 | lane_en << 4 | 0x105,
DSI_CTRL);
writel(0x10000000, DSI_COMMAND_MODE_DMA_CTRL);
writel(0x10000000, DSI_MISR_CMD_CTRL);
#endif
- return NO_ERROR;
+ return 0;
}
int mipi_dsi_cmd_mode_config(unsigned short disp_width,
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index cb00a3c..8dae760 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -287,7 +287,7 @@
mmc_cid.pnm[6] = 0;
mmc_cid.prv = UNPACK_BITS(raw_cid, 56, 8, mmc_sizeof);
- mmc_cid.psn = UNPACK_BITS(raw_cid, 24, 31, mmc_sizeof);
+ mmc_cid.psn = UNPACK_BITS(raw_cid, 24, 32, mmc_sizeof);
mmc_cid.month = UNPACK_BITS(raw_cid, 8, 4, mmc_sizeof);
mmc_cid.year = UNPACK_BITS(raw_cid, 12, 8, mmc_sizeof);
mmc_cid.year += 2000;
@@ -302,7 +302,7 @@
mmc_cid.pnm[6] = 0;
mmc_cid.prv = UNPACK_BITS(raw_cid, 48, 8, mmc_sizeof);
- mmc_cid.psn = UNPACK_BITS(raw_cid, 16, 31, mmc_sizeof);
+ mmc_cid.psn = UNPACK_BITS(raw_cid, 16, 32, mmc_sizeof);
mmc_cid.month = UNPACK_BITS(raw_cid, 8, 4, mmc_sizeof);
mmc_cid.year = UNPACK_BITS(raw_cid, 12, 4, mmc_sizeof);
mmc_cid.year += 1997;
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index 5cca931..6c0ae6c 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -227,7 +227,10 @@
/* Print out the GPT first */
ret = mmc_read(PROTECTIVE_MBR_SIZE, (unsigned int *)data, BLOCK_SIZE);
if (ret)
+ {
dprintf(CRITICAL, "GPT: Could not read primary gpt from mmc\n");
+ return ret;
+ }
ret = partition_parse_gpt_header(data, &first_usable_lba,
&partition_entry_size, &header_size,
@@ -441,7 +444,7 @@
{
int byte_length = 8; /*length of unit (i.e. byte) */
int msb = 0;
- int polynomial = 0x104C11DB7; /* IEEE 32bit polynomial */
+ int polynomial = 0x04C11DB7; /* IEEE 32bit polynomial */
unsigned int regs = 0xFFFFFFFF; /* init to all ones */
int regs_mask = 0xFFFFFFFF; /* ensure only 32 bit answer */
int regs_msb = 0;
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index f43f1f6..0ffa27c 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -98,7 +98,9 @@
$(LOCAL_DIR)/crypto5_wrapper.o \
$(LOCAL_DIR)/i2c_qup.o \
$(LOCAL_DIR)/gpio.o \
- $(LOCAL_DIR)/dload_util.o
+ $(LOCAL_DIR)/dload_util.o \
+ $(LOCAL_DIR)/edp.o \
+ $(LOCAL_DIR)/edp_phy.o
endif
ifeq ($(PLATFORM),msm8226)
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index adeecc8..26e203e 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -308,10 +308,11 @@
if(parse_rsp.status == SSD_PMD_ENCRYPTED)
{
*ctx_id = parse_rsp.md_ctx_id;
- *img_len_ptr = *img_len_ptr - (parse_rsp.md_end_ptr - *img_ptr);
+ *img_len_ptr = *img_len_ptr - ((uint8_t*)parse_rsp.md_end_ptr - (uint8_t*)*img_ptr);
*img_ptr = (uint32_t*)parse_rsp.md_end_ptr;
- ret = 1;
}
+
+ ret = parse_rsp.status;
}
else
{
@@ -330,43 +331,62 @@
ssd_decrypt_img_frag_req decrypt_req;
ssd_decrypt_img_frag_rsp decrypt_rsp;
- if(ssd_image_is_encrypted(img_ptr,img_len_ptr,&ctx_id))
+ ret = ssd_image_is_encrypted(img_ptr,img_len_ptr,&ctx_id);
+ switch(ret)
{
+ case SSD_PMD_ENCRYPTED:
+ /* Image data is operated upon by TZ, which accesses only the main memory.
+ * It must be flushed/invalidated before and after TZ call.
+ */
- /* Image data is operated upon by TZ, which accesses only the main memory.
- * It must be flushed/invalidated before and after TZ call.
- */
+ arch_clean_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr);
- arch_clean_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr);
+ /*decrypt the image here*/
- /*decrypt the image here*/
+ decrypt_req.md_ctx_id = ctx_id;
+ decrypt_req.last_frag = 1;
+ decrypt_req.frag_len = *img_len_ptr;
+ decrypt_req.frag = *img_ptr;
- decrypt_req.md_ctx_id = ctx_id;
- decrypt_req.last_frag = 1;
- decrypt_req.frag_len = *img_len_ptr;
- decrypt_req.frag = *img_ptr;
+ ret = scm_call(SCM_SVC_SSD,
+ SSD_DECRYPT_IMG_FRAG_ID,
+ &decrypt_req,
+ sizeof(decrypt_req),
+ &decrypt_rsp,
+ sizeof(decrypt_rsp));
- ret = scm_call(SCM_SVC_SSD,
- SSD_DECRYPT_IMG_FRAG_ID,
- &decrypt_req,
- sizeof(decrypt_req),
- &decrypt_rsp,
- sizeof(decrypt_rsp));
+ if(!ret){
+ ret = decrypt_rsp.status;
+ }
- if(!ret){
- ret = decrypt_rsp.status;
- }
+ /* Values at img_ptr and img_len_ptr are updated by TZ. Must be invalidated
+ * before we use them.
+ */
+ arch_invalidate_cache_range((addr_t) img_ptr, sizeof(img_ptr));
+ arch_invalidate_cache_range((addr_t) img_len_ptr, sizeof(img_len_ptr));
- /* Values at img_ptr and img_len_ptr are updated by TZ. Must be invalidated
- * before we use them.
- */
- arch_invalidate_cache_range((addr_t) img_ptr, sizeof(img_ptr));
- arch_invalidate_cache_range((addr_t) img_len_ptr, sizeof(img_len_ptr));
+ /* Invalidate the updated image data */
+ arch_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr);
- /* Invalidate the updated image data */
- arch_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr);
+ break;
+
+ case SSD_PMD_NOT_ENCRYPTED:
+ case SSD_PMD_NO_MD_FOUND:
+ ret = 0;
+ break;
+
+ case SSD_PMD_BUSY:
+ case SSD_PMD_BAD_MD_PTR_OR_LEN:
+ case SSD_PMD_PARSING_INCOMPLETE:
+ case SSD_PMD_PARSING_FAILED:
+ case SSD_PMD_SETUP_CIPHER_FAILED:
+ dprintf(CRITICAL,"decrypt_scm_v2: failed status %d\n",ret);
+ break;
+
+ default:
+ dprintf(CRITICAL,"decrypt_scm_v2: case default: failed status %d\n",ret);
+ break;
}
-
return ret;
}
diff --git a/scripts/aboot_test.py b/scripts/aboot_test.py
new file mode 100755
index 0000000..c43364c
--- /dev/null
+++ b/scripts/aboot_test.py
@@ -0,0 +1,189 @@
+# Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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.
+#
+
+#!/usr/bin/python
+
+import os
+import sys
+import time
+import re
+import subprocess
+import getopt
+
+#
+# Erase routine, erase a parition & print the time taken for erase
+#
+def fastboot_erase(partition):
+ start_time = time.time()
+ exe = subprocess.Popen(['fastboot', 'erase', partition], stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
+ print exe
+ print "Time Taken for erase:", partition, ":", time.time() - start_time, "seconds"
+ print("")
+ return
+
+#
+# Flash routine, flash a parition & print the time taken to flash the image
+#
+def fastboot_flash(image_name, partition):
+ start_time = time.time()
+ exe = subprocess.Popen(['fastboot', 'flash', partition, image_name], stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
+ print exe
+ print "Time Taken for flashing:", partition, ":", time.time() - start_time, "seconds"
+ print("")
+ return
+
+#
+# Execute any other fasboot command & print the time taken
+#
+def fastboot_exec(command):
+ start_time = time.time()
+ exe = subprocess.Popen(['fastboot', command], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read()
+ print exe
+ print "Time Taken for fastboot:", command, time.time() - start_time, "seconds"
+ print("")
+ return
+
+#
+# Aboot test, Test aboot with different use cases
+#
+def test_aboot(iteration, input_path):
+ system=''
+ userdata=''
+ boot=''
+
+ print ("ABOOT TEST START")
+ t0 = time.clock()
+
+ boot = os.path.join(input_path, 'boot.img')
+ system = os.path.join(input_path, 'system.img')
+ userdata = os.path.join(input_path, 'userdata.img')
+
+ print("")
+ getstate = subprocess.Popen(["fastboot", "devices"], stdout=subprocess.PIPE).communicate()[0]
+ if(re.search("fastboot",getstate) == None):
+ print("Device is not in fastboot, please make sure device is in fastboot mode ... [FAIL]")
+ sys.exit(-1)
+ else:
+ print ("fastboot devices ... [OKAY]")
+ print ("Executing other fastboot tests ...")
+ print("")
+
+ fastboot_erase("boot")
+ time.sleep(2)
+
+ fastboot_exec("reboot")
+ time.sleep(2)
+ fastboot_exec("devices")
+ time.sleep(2)
+ getstate = subprocess.Popen(["fastboot", "devices"], stdout=subprocess.PIPE).communicate()[0]
+ if(re.search("fastboot",getstate) == None):
+ print("fastboot reboot ... [FAIL]")
+ sys.exit(-1)
+
+ iteration = int(iteration)
+
+ # Flash images in a loop
+ i = 0
+ while i < iteration:
+ print "Iteration ", i
+ print ("fastboot flash boot boot.img...")
+ fastboot_flash(boot, 'boot')
+ print("")
+ print ("fastboot flash system system.img ...")
+ fastboot_flash(system, 'system')
+ print("")
+ print ("fastboot flash userdata userdata.img ...")
+ fastboot_flash(userdata, 'userdata')
+ print("")
+ i+=1
+
+ fastboot_exec("reboot")
+ print ("fastboot reboot ... [OKAY]")
+ print("")
+ time.sleep(1)
+ print("Waiting for adb to come up ...")
+ print("")
+ i = 0
+ while i < 10:
+ getstate = subprocess.Popen(["adb", "get-state"], stdout=subprocess.PIPE).communicate()[0]
+ if(re.search("device",getstate) == None):
+ i+=1
+ time.sleep(2)
+ else:
+ print("Device Online")
+ print("")
+ break
+
+ os.system("adb reboot-bootloader")
+ time.sleep(4)
+ getstate = subprocess.Popen(["fastboot", "devices"], stdout=subprocess.PIPE).communicate()[0]
+ if(re.search("fastboot",getstate) == None):
+ print ("adb reboot-bootloader ... [FAIL]")
+ sys.exit(-1)
+ else:
+ print ("adb reboot-bootloader ... [PASS]")
+
+ print("")
+ fastboot_exec("devices")
+ print ("fastboot devices ... [OKAY]")
+ print("")
+
+ fastboot_erase("system")
+ fastboot_erase("userdata")
+
+ fastboot_exec("continue")
+ print ("fastboot continue ... [OKAY]")
+ print("")
+
+ print ("ABOOT TEST DONE")
+ return
+
+# Main function to parse i/p args
+def main(argv):
+ input_path = ''
+ iteration = ''
+ if len(sys.argv) < 2:
+ print "aboot_test.py -i <iterations> -p <Binary Image Path>"
+ sys.exit(2)
+ try:
+ opts, args = getopt.getopt(argv, "hi:p:",["iter=","opath="])
+ except getopt.GetoptError:
+ print "aboot_test.py -i <iterations> -p <Binary Image Path>"
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt == '-h':
+ print "aboot_test.py -i <iterations> -o <Binary Image Path>"
+ sys.exit(2)
+ elif opt in ("-i", "--iter"):
+ iteration = arg
+ elif opt in ("-p", "--opath"):
+ input_path = arg
+ test_aboot(iteration, input_path)
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/target/msm8226/target_display.c b/target/msm8226/target_display.c
index 2da792e..a30b568 100755
--- a/target/msm8226/target_display.c
+++ b/target/msm8226/target_display.c
@@ -43,12 +43,10 @@
#include "include/display_resource.h"
static struct pm8x41_wled_data wled_ctrl = {
- .mod_scheme = 0xC3,
+ .mod_scheme = 0x00,
.led1_brightness = (0x0F << 8) | 0xEF,
- .led2_brightness = (0x0F << 8) | 0xEF,
- .led3_brightness = (0x0F << 8) | 0xEF,
.max_duty_cycle = 0x01,
- .ovp = 0x2,
+ .ovp = 0x0,
.full_current_scale = 0x19
};
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index d612015..2329965 100644
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -48,7 +48,7 @@
extern int mdss_sharp_dsi_uniphy_pll_config(uint32_t ctl_base);
static struct pm8x41_wled_data wled_ctrl = {
- .mod_scheme = 0xC3,
+ .mod_scheme = 0x00,
.led1_brightness = (0x0F << 8) | 0xEF,
.led2_brightness = (0x0F << 8) | 0xEF,
.led3_brightness = (0x0F << 8) | 0xEF,