Merge "target: msm8996: add support for HDMI regulators"
diff --git a/platform/msm8996/acpuclock.c b/platform/msm8996/acpuclock.c
index 5d2e7eb..ff0b55c 100644
--- a/platform/msm8996/acpuclock.c
+++ b/platform/msm8996/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -687,4 +687,37 @@
dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
return;
}
-}
\ No newline at end of file
+}
+
+void hdmi_clk_enable(void)
+{
+ int ret;
+
+ /* Configure hdmi ahb clock */
+ ret = clk_get_set_enable("hdmi_ahb_clk", 0, 1);
+ if(ret) {
+ dprintf(CRITICAL, "failed to set hdmi_ahb_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ /* Configure hdmi core clock */
+ ret = clk_get_set_enable("hdmi_core_clk", 19200000, 1);
+ if(ret) {
+ dprintf(CRITICAL, "failed to set hdmi_core_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ /* Configure hdmi pixel clock */
+ ret = clk_get_set_enable("hdmi_extp_clk", 148500000, 1);
+ if(ret) {
+ dprintf(CRITICAL, "failed to set hdmi_extp_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+}
+
+void hdmi_clk_disable(void)
+{
+ clk_disable(clk_get("hdmi_extp_clk"));
+ clk_disable(clk_get("hdmi_core_clk"));
+ clk_disable(clk_get("hdmi_ahb_clk"));
+}
diff --git a/platform/msm8996/include/platform/clock.h b/platform/msm8996/include/platform/clock.h
index 6ff55e2..25e6ea9 100644
--- a/platform/msm8996/include/platform/clock.h
+++ b/platform/msm8996/include/platform/clock.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -58,6 +58,13 @@
#define MMSS_MMAGIC_AHB_CBCR REG_MM(0x5024)
#define SMMU_MDP_AHB_CBCR REG_MM(0x2454)
#define MDSS_AHB_CBCR REG_MM(0x2308)
+#define MDSS_HDMI_AHB_CBCR REG_MM(0x230C)
+#define MDSS_HDMI_CBCR REG_MM(0x2338)
+#define MDSS_EXTPCLK_CBCR REG_MM(0x2324)
+#define EXTPCLK_CMD_RCGR REG_MM(0x2060)
+#define EXTPCLK_CFG_RCGR REG_MM(0x2064)
+#define HDMI_CMD_RCGR REG_MM(0x2100)
+#define HDMI_CFG_RCGR REG_MM(0x2104)
#define AXI_CMD_RCGR REG_MM(0x5040)
#define AXI_CFG_RCGR REG_MM(0x5044)
@@ -126,4 +133,7 @@
void video_gdsc_disable();
void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
+void hdmi_clk_enable(void);
+void hdmi_clk_disable(void);
+
#endif
diff --git a/platform/msm8996/msm8996-clock.c b/platform/msm8996/msm8996-clock.c
index 8a02900..9074bd6 100644
--- a/platform/msm8996/msm8996-clock.c
+++ b/platform/msm8996/msm8996-clock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -46,6 +46,7 @@
#define mmpll1_mm_source_val 2
#define mmpll3_mm_source_val 3
#define gpll0_mm_source_val 5
+#define hdmipll_mm_source_val 3
struct clk_freq_tbl rcg_dummy_freq = F_END;
@@ -813,6 +814,77 @@
},
};
+static struct branch_clk mdss_hdmi_ahb_clk = {
+ .cbcr_reg = (uint32_t *) MDSS_HDMI_AHB_CBCR,
+ .has_sibling = 1,
+ .c = {
+ .dbg_name = "mdss_hdmi_ahb_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdss_hdmi_clk[] = {
+ F_MM( 19200000, cxo, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk hdmi_clk_src = {
+ .cmd_reg = (uint32_t *) HDMI_CMD_RCGR,
+ .cfg_reg = (uint32_t *) HDMI_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mdss_hdmi_clk,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "hdmi_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct branch_clk mdss_hdmi_clk = {
+ .cbcr_reg = (uint32_t *) MDSS_HDMI_CBCR,
+ .has_sibling = 0,
+ .parent = &hdmi_clk_src.c,
+ .c = {
+ .dbg_name = "mdss_hdmi_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct clk_freq_tbl ftbl_mdss_extpclk_clk[] = {
+ F_MDSS( 74250000, hdmipll, 1, 0, 0),
+ F_MDSS( 25200000, hdmipll, 1, 0, 0),
+ F_MDSS( 27000000, hdmipll, 1, 0, 0),
+ F_MDSS( 27030000, hdmipll, 1, 0, 0),
+ F_MDSS( 27070000, hdmipll, 1, 0, 0),
+ F_MDSS( 65000000, hdmipll, 1, 0, 0),
+ F_MDSS(108000000, hdmipll, 1, 0, 0),
+ F_MDSS(148500000, hdmipll, 1, 0, 0),
+ F_MDSS(268500000, hdmipll, 1, 0, 0),
+ F_MDSS(297000000, hdmipll, 1, 0, 0),
+ F_END
+};
+
+static struct rcg_clk extpclk_clk_src = {
+ .cmd_reg = (uint32_t *) EXTPCLK_CMD_RCGR,
+ .cfg_reg = (uint32_t *) EXTPCLK_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_mdss_extpclk_clk,
+ .current_freq = &rcg_dummy_freq,
+ .c = {
+ .dbg_name = "extpclk_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct branch_clk mdss_extpclk_clk = {
+ .cbcr_reg = (uint32_t *) MDSS_EXTPCLK_CBCR,
+ .has_sibling = 0,
+ .parent = &extpclk_clk_src.c,
+ .c = {
+ .dbg_name = "mdss_extpclk_clk",
+ .ops = &clk_ops_branch,
+ },
+};
/* Clock lookup table */
static struct clk_lookup msm_msm8996_clocks[] =
@@ -863,6 +935,11 @@
gcc_blsp2_qup2_i2c_apps_clk_src.c),
CLK_LOOKUP("gcc_blsp2_qup2_i2c_apps_clk",
gcc_blsp2_qup2_i2c_apps_clk.c),
+
+ /* HDMI clocks*/
+ CLK_LOOKUP("hdmi_ahb_clk", mdss_hdmi_ahb_clk.c),
+ CLK_LOOKUP("hdmi_core_clk", mdss_hdmi_clk.c),
+ CLK_LOOKUP("hdmi_extp_clk", mdss_extpclk_clk.c),
};
void platform_clock_init(void)
diff --git a/platform/msm_shared/include/mdp5.h b/platform/msm_shared/include/mdp5.h
index b8deb6d..935e7a6 100644
--- a/platform/msm_shared/include/mdp5.h
+++ b/platform/msm_shared/include/mdp5.h
@@ -265,9 +265,11 @@
int target_edp_panel_disable(void);
int target_edp_bl_ctrl(int enable);
int mdss_hdmi_init(void);
+void mdss_hdmi_display_init(uint32_t rev, void *base);
int mdss_hdmi_on(struct msm_panel_info *pinfo);
int mdss_hdmi_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
void mdss_hdmi_get_vic(char *buf);
+void hdmi_phy_init(void);
int msm_display_off();
void display_shutdown(void);
diff --git a/platform/msm_shared/mdss_hdmi.c b/platform/msm_shared/mdss_hdmi.c
index 0741308..4908c19 100644
--- a/platform/msm_shared/mdss_hdmi.c
+++ b/platform/msm_shared/mdss_hdmi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2016, 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
@@ -101,6 +101,8 @@
{10240, 247500}, {18816, 247500}, {20480, 247500} }),
};
+extern int msm_display_init(struct msm_fb_panel_data *pdata);
+
/* AVI INFOFRAME DATA */
#define NUM_MODES_AVI 20
#define AVI_MAX_DATA_BYTES 13
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index f426e93..be1a5f1 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -582,7 +582,8 @@
$(LOCAL_DIR)/mipi_dsi_autopll_thulium.o \
$(LOCAL_DIR)/shutdown_detect.o \
$(LOCAL_DIR)/i2c_qup.o \
- $(LOCAL_DIR)/mipi_dsi_i2c.o
+ $(LOCAL_DIR)/mipi_dsi_i2c.o \
+ $(LOCAL_DIR)/mdss_hdmi.o
endif
ifeq ($(ENABLE_UFS_SUPPORT), 1)
diff --git a/target/msm8996/include/target/display.h b/target/msm8996/include/target/display.h
index 5b21a1f..9ee5ec3 100644
--- a/target/msm8996/include/target/display.h
+++ b/target/msm8996/include/target/display.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -33,6 +33,7 @@
/* HEADER files */
/*---------------------------------------------------------------------------*/
#include <display_resource.h>
+#include <msm_panel.h>
/*---------------------------------------------------------------------------*/
/* Target Physical configuration */
@@ -67,6 +68,7 @@
#define DISPLAY_CMDLINE_PREFIX " mdss_mdp.panel="
#define MIPI_FB_ADDR 0x83400000
+#define HDMI_FB_ADDR 0xB1C00000
#define MIPI_HSYNC_PULSE_WIDTH 16
#define MIPI_HSYNC_BACK_PORCH_DCLK 32
@@ -79,7 +81,8 @@
#define PWM_BL_LPG_CHAN_ID 4 /* lpg_out<3> */
#define HDMI_PANEL_NAME "hdmi"
-#define HDMI_CONTROLLER_STRING "hdmi:0"
+#define HDMI_CONTROLLER_STRING "hdmi:"
+#define HDMI_VIC_LEN 5
/*---------------------------------------------------------------------------*/
/* Functions */
@@ -93,5 +96,9 @@
void target_force_cont_splash_disable(uint8_t override);
uint8_t target_panel_auto_detect_enabled();
void target_set_switch_gpio(int enable_dsi2hdmibridge);
+int target_hdmi_pll_clock(uint8_t enable, struct msm_panel_info *pinfo);
+int target_hdmi_panel_clock(uint8_t enable, struct msm_panel_info *pinfo);
+int target_hdmi_regulator_ctrl(uint8_t enable);
+int target_hdmi_gpio_ctrl(uint8_t enable);
#endif
diff --git a/target/msm8996/regulator.c b/target/msm8996/regulator.c
index 909082d..a95a42f 100644
--- a/target/msm8996/regulator.c
+++ b/target/msm8996/regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -48,6 +48,23 @@
},
};
+static uint32_t ldo12[][11]=
+{
+ {
+ LDOA_RES_TYPE, 12,
+ KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+ KEY_MICRO_VOLT, 4, 0,
+ KEY_CURRENT, 4, 0,
+ },
+
+ {
+ LDOA_RES_TYPE, 12,
+ KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+ KEY_MICRO_VOLT, 4, 1800000,
+ KEY_CURRENT, 4, 11,
+ },
+};
+
static uint32_t ldo14[][11]=
{
{
@@ -88,6 +105,9 @@
if (enable & REG_LDO2)
rpm_send_data(&ldo2[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+ if (enable & REG_LDO12)
+ rpm_send_data(&ldo12[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+
if (enable & REG_LDO14)
rpm_send_data(&ldo14[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
@@ -100,6 +120,9 @@
if (enable & REG_LDO2)
rpm_send_data(&ldo2[GENERIC_DISABLE][0], 36, RPM_REQUEST_TYPE);
+ if (enable & REG_LDO12)
+ rpm_send_data(&ldo12[GENERIC_DISABLE][0], 36, RPM_REQUEST_TYPE);
+
if (enable & REG_LDO14)
rpm_send_data(&ldo14[GENERIC_DISABLE][0], 36, RPM_REQUEST_TYPE);
diff --git a/target/msm8996/target_display.c b/target/msm8996/target_display.c
index 5086451..3709094 100644
--- a/target/msm8996/target_display.c
+++ b/target/msm8996/target_display.c
@@ -92,6 +92,88 @@
"msmgpio", 105, 3, 1, 0, 1
};
+/* gpio name, id, strength, direction, pull, state. */
+static struct gpio_pin hdmi_cec_gpio = { /* CEC */
+ "msmgpio", 31, 0, 2, 3, 1
+};
+
+static struct gpio_pin hdmi_ddc_clk_gpio = { /* DDC CLK */
+ "msmgpio", 32, 0, 2, 3, 1
+};
+
+static struct gpio_pin hdmi_ddc_data_gpio = { /* DDC DATA */
+ "msmgpio", 33, 0, 2, 3, 1
+};
+
+static struct gpio_pin hdmi_hpd_gpio = { /* HPD, input */
+ "msmgpio", 34, 7, 0, 1, 1
+};
+
+static void target_hdmi_ldo_enable(uint8_t enable)
+{
+ if (enable)
+ regulator_enable(REG_LDO12);
+ else
+ regulator_disable(REG_LDO12);
+}
+
+static void target_hdmi_mpp4_enable(uint8_t enable)
+{
+ struct pm8x41_mpp mpp;
+
+ /* Enable MPP4 */
+ pmi8994_config_mpp_slave_id(0);
+
+ mpp.base = PM8x41_MMP4_BASE;
+ mpp.vin = MPP_VIN2;
+ mpp.mode = MPP_HIGH;;
+ if (enable) {
+ pm8x41_config_output_mpp(&mpp);
+ pm8x41_enable_mpp(&mpp, MPP_ENABLE);
+ } else {
+ pm8x41_enable_mpp(&mpp, MPP_DISABLE);
+ }
+
+ /* Need delay before power on regulators */
+ mdelay(20);
+}
+
+int target_hdmi_regulator_ctrl(uint8_t enable)
+{
+ target_hdmi_ldo_enable(enable);
+
+ target_hdmi_mpp4_enable(enable);
+
+ return 0;
+}
+
+int target_hdmi_gpio_ctrl(uint8_t enable)
+{
+ gpio_tlmm_config(hdmi_cec_gpio.pin_id, 1, /* gpio 31, CEC */
+ hdmi_cec_gpio.pin_direction, hdmi_cec_gpio.pin_pull,
+ hdmi_cec_gpio.pin_strength, hdmi_cec_gpio.pin_state);
+
+ gpio_tlmm_config(hdmi_ddc_clk_gpio.pin_id, 1, /* gpio 32, DDC CLK */
+ hdmi_ddc_clk_gpio.pin_direction, hdmi_ddc_clk_gpio.pin_pull,
+ hdmi_ddc_clk_gpio.pin_strength, hdmi_ddc_clk_gpio.pin_state);
+
+
+ gpio_tlmm_config(hdmi_ddc_data_gpio.pin_id, 1, /* gpio 33, DDC DATA */
+ hdmi_ddc_data_gpio.pin_direction, hdmi_ddc_data_gpio.pin_pull,
+ hdmi_ddc_data_gpio.pin_strength, hdmi_ddc_data_gpio.pin_state);
+
+ gpio_tlmm_config(hdmi_hpd_gpio.pin_id, 1, /* gpio 34, HPD */
+ hdmi_hpd_gpio.pin_direction, hdmi_hpd_gpio.pin_pull,
+ hdmi_hpd_gpio.pin_strength, hdmi_hpd_gpio.pin_state);
+
+ gpio_set(hdmi_cec_gpio.pin_id, hdmi_cec_gpio.pin_direction);
+ gpio_set(hdmi_ddc_clk_gpio.pin_id, hdmi_ddc_clk_gpio.pin_direction);
+ gpio_set(hdmi_ddc_data_gpio.pin_id, hdmi_ddc_data_gpio.pin_direction);
+ gpio_set(hdmi_hpd_gpio.pin_id, hdmi_hpd_gpio.pin_direction);
+
+ return NO_ERROR;
+}
+
static uint32_t thulium_dsi_pll_lock_status(uint32_t pll_base, uint32_t off,
uint32_t bit)
{
@@ -579,6 +661,7 @@
int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
bool ret = true;
struct oem_panel_data oem = mdss_dsi_get_oem_data();
+ char vic_buf[HDMI_VIC_LEN] = "0";
if (!strcmp(oem.panel, HDMI_PANEL_NAME)) {
if (buf_size < (prefix_string_len + LK_OVERRIDE_PANEL_LEN +
@@ -592,6 +675,9 @@
strlcat(pbuf, LK_OVERRIDE_PANEL, buf_size);
buf_size -= LK_OVERRIDE_PANEL_LEN;
strlcat(pbuf, HDMI_CONTROLLER_STRING, buf_size);
+ buf_size -= strlen(HDMI_CONTROLLER_STRING);
+ mdss_hdmi_get_vic(vic_buf);
+ strlcat(pbuf, vic_buf, buf_size);
} else {
ret = gcdb_display_cmdline_arg(pbuf, buf_size);
}
@@ -629,6 +715,8 @@
oem.panel);
return;
} else if (!strcmp(oem.panel, HDMI_PANEL_NAME)) {
+ dprintf(INFO, "%s: HDMI is primary\n", __func__);
+ mdss_hdmi_display_init(MDP_REV_50, (void *) HDMI_FB_ADDR);
return;
}