FP2-15: create Product ID for FP2 project
Change-Id: Ia7290f1516b3397590be838f6311a902fbe323b8
diff --git a/target/fairphone/target_display.c b/target/fairphone/target_display.c
new file mode 100755
index 0000000..56a03c1
--- /dev/null
+++ b/target/fairphone/target_display.c
@@ -0,0 +1,413 @@
+/* Copyright (c) 2012-2014, 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 <debug.h>
+#include <smem.h>
+#include <err.h>
+#include <msm_panel.h>
+#include <mipi_dsi.h>
+#include <pm8x41.h>
+#include <pm8x41_wled.h>
+#include <board.h>
+#include <mdp5.h>
+#include <platform/gpio.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+#include <target/display.h>
+#include "include/panel.h"
+#include "include/display_resource.h"
+
+static struct msm_fb_panel_data panel;
+static uint8_t edp_enable;
+
+#define HFPLL_LDO_ID 12
+
+static struct pm8x41_wled_data wled_ctrl = {
+ .mod_scheme = 0x00,
+ .led1_brightness = (0x0F << 8) | 0xEF,
+ .led2_brightness = (0x0F << 8) | 0xEF,
+ .led3_brightness = (0x0F << 8) | 0xEF,
+ .max_duty_cycle = 0x01,
+ .ovp = 0x2,
+ .full_current_scale = 0x19
+};
+
+static uint32_t dsi_pll_lock_status(uint32_t ctl_base)
+{
+ uint32_t counter, status;
+
+ udelay(100);
+ mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
+
+ status = readl(ctl_base + 0x02c0) & 0x01;
+ for (counter = 0; counter < 5 && !status; counter++) {
+ udelay(100);
+ status = readl(ctl_base + 0x02c0) & 0x01;
+ }
+
+ return status;
+}
+
+static uint32_t dsi_pll_enable_seq_b(uint32_t ctl_base)
+{
+ mdss_dsi_uniphy_pll_sw_reset(ctl_base);
+
+ writel(0x01, ctl_base + 0x0220); /* GLB CFG */
+ udelay(1);
+ writel(0x05, ctl_base + 0x0220); /* GLB CFG */
+ udelay(200);
+ writel(0x07, ctl_base + 0x0220); /* GLB CFG */
+ udelay(500);
+ writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
+ udelay(500);
+
+ return dsi_pll_lock_status(ctl_base);
+}
+
+static uint32_t dsi_pll_enable_seq_d(uint32_t ctl_base)
+{
+ mdss_dsi_uniphy_pll_sw_reset(ctl_base);
+
+ writel(0x01, ctl_base + 0x0220); /* GLB CFG */
+ udelay(1);
+ writel(0x05, ctl_base + 0x0220); /* GLB CFG */
+ udelay(200);
+ writel(0x07, ctl_base + 0x0220); /* GLB CFG */
+ udelay(250);
+ writel(0x05, ctl_base + 0x0220); /* GLB CFG */
+ udelay(200);
+ writel(0x07, ctl_base + 0x0220); /* GLB CFG */
+ udelay(500);
+ writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
+ udelay(500);
+
+ return dsi_pll_lock_status(ctl_base);
+}
+
+static void dsi_pll_enable_seq(uint32_t ctl_base)
+{
+ uint32_t counter, status;
+
+ for (counter = 0; counter < 3; counter++) {
+ status = dsi_pll_enable_seq_b(ctl_base);
+ if (status)
+ break;
+ status = dsi_pll_enable_seq_d(ctl_base);
+ if (status)
+ break;
+ status = dsi_pll_enable_seq_d(ctl_base);
+ if(status)
+ break;
+ }
+
+ if (!status)
+ dprintf(CRITICAL, "Pll lock sequence failed\n");
+}
+
+static int msm8974_wled_backlight_ctrl(uint8_t enable)
+{
+ uint32_t platform_id = board_platform_id();
+ uint32_t hardware_id = board_hardware_id();
+ uint8_t slave_id = 1;
+
+ if (enable) {
+ if (platform_id == MSM8974AC)
+ if ((hardware_id == HW_PLATFORM_MTP)
+ || (hardware_id == HW_PLATFORM_LIQUID))
+ slave_id = 3;
+
+ pm8x41_wled_config_slave_id(slave_id);
+ pm8x41_wled_config(&wled_ctrl);
+ pm8x41_wled_sink_control(enable);
+ pm8x41_wled_iled_sync_control(enable);
+ pm8x41_wled_led_mod_enable(enable);
+ }
+ pm8x41_wled_enable(enable);
+
+ return NO_ERROR;
+}
+
+static int msm8974_pwm_backlight_ctrl(int gpio_num, int lpg_chan, int enable)
+{
+ struct pm8x41_gpio gpio_param = {
+ .direction = PM_GPIO_DIR_OUT,
+ .function = PM_GPIO_FUNC_2,
+ .vin_sel = 2, /* VIN_2 */
+ .pull = PM_GPIO_PULL_UP_1_5 | PM_GPIO_PULLDOWN_10,
+ .output_buffer = PM_GPIO_OUT_CMOS,
+ .out_strength = PM_GPIO_OUT_DRIVE_HIGH,
+ };
+
+ dprintf(SPEW, "%s: gpio=%d lpg=%d enable=%d\n", __func__,
+ gpio_num, lpg_chan, enable);
+
+ if (enable) {
+ pm8x41_gpio_config(gpio_num, &gpio_param);
+ pm8x41_lpg_write(lpg_chan, 0x41, 0x33); /* LPG_PWM_SIZE_CLK, */
+ pm8x41_lpg_write(lpg_chan, 0x42, 0x01); /* LPG_PWM_FREQ_PREDIV */
+ pm8x41_lpg_write(lpg_chan, 0x43, 0x20); /* LPG_PWM_TYPE_CONFIG */
+ pm8x41_lpg_write(lpg_chan, 0x44, 0xb2); /* LPG_VALUE_LSB */
+ pm8x41_lpg_write(lpg_chan, 0x45, 0x01); /* LPG_VALUE_MSB */
+ pm8x41_lpg_write(lpg_chan, 0x46, 0xe4); /* LPG_ENABLE_CONTROL */
+ } else {
+ pm8x41_lpg_write(lpg_chan, 0x46, 0x00);
+ }
+
+ return NO_ERROR;
+}
+
+int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
+{
+ uint32_t ret = NO_ERROR;
+
+ if (!bl) {
+ dprintf(CRITICAL, "backlight structure is not available\n");
+ return ERR_INVALID_ARGS;
+ }
+
+ switch (bl->bl_interface_type) {
+ case BL_WLED:
+ ret = msm8974_wled_backlight_ctrl(enable);
+ break;
+ case BL_PWM:
+ ret = msm8974_pwm_backlight_ctrl(pwm_gpio.pin_id,
+ PWM_BL_LPG_CHAN_ID,
+ enable);
+ break;
+ default:
+ dprintf(CRITICAL, "backlight type:%d not supported\n",
+ bl->bl_interface_type);
+ return ERR_NOT_SUPPORTED;
+ }
+
+ return ret;
+}
+
+int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
+{
+ struct mdss_dsi_pll_config *pll_data;
+ uint32_t dual_dsi = pinfo->mipi.dual_dsi;
+ dprintf(SPEW, "target_panel_clock\n");
+
+ pll_data = pinfo->mipi.dsi_pll_config;
+ if (enable) {
+ mdp_gdsc_ctrl(enable);
+ mdp_clock_init();
+ mdss_dsi_auto_pll_config(MIPI_DSI0_BASE, pll_data);
+ dsi_pll_enable_seq(MIPI_DSI0_BASE);
+ mmss_clock_auto_pll_init(DSI0_PHY_PLL_OUT, dual_dsi,
+ pll_data->pclk_m,
+ pll_data->pclk_n,
+ pll_data->pclk_d);
+ } else if(!target_cont_splash_screen()) {
+ // * Add here for continuous splash *
+ mmss_clock_disable(dual_dsi);
+ mdp_clock_disable(dual_dsi);
+ }
+
+ return NO_ERROR;
+}
+
+/* Pull DISP_RST_N high to get panel out of reset */
+int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
+ struct msm_panel_info *pinfo)
+{
+ uint32_t rst_gpio = reset_gpio.pin_id;
+ uint32_t platform_id = board_platform_id();
+ uint32_t hardware_id = board_hardware_id();
+
+ struct pm8x41_gpio resetgpio_param = {
+ .direction = PM_GPIO_DIR_OUT,
+ .output_buffer = PM_GPIO_OUT_CMOS,
+ .out_strength = PM_GPIO_OUT_DRIVE_MED,
+ };
+
+ if (platform_id == MSM8974AC)
+ if ((hardware_id == HW_PLATFORM_MTP)
+ || (hardware_id == HW_PLATFORM_LIQUID))
+ rst_gpio = 20;
+
+ dprintf(SPEW, "platform_id: %u, rst_gpio: %u\n",
+ platform_id, rst_gpio);
+
+ pm8x41_gpio_config(rst_gpio, &resetgpio_param);
+ if (enable) {
+ gpio_tlmm_config(enable_gpio.pin_id, 0,
+ enable_gpio.pin_direction, enable_gpio.pin_pull,
+ enable_gpio.pin_strength, enable_gpio.pin_state);
+
+ gpio_set(enable_gpio.pin_id, resetseq->pin_direction);
+ pm8x41_gpio_set(rst_gpio, resetseq->pin_state[0]);
+ mdelay(resetseq->sleep[0]);
+ pm8x41_gpio_set(rst_gpio, resetseq->pin_state[1]);
+ mdelay(resetseq->sleep[1]);
+ pm8x41_gpio_set(rst_gpio, resetseq->pin_state[2]);
+ mdelay(resetseq->sleep[2]);
+ } else {
+ resetgpio_param.out_strength = PM_GPIO_OUT_DRIVE_LOW;
+ pm8x41_gpio_config(rst_gpio, &resetgpio_param);
+ pm8x41_gpio_set(rst_gpio, PM_GPIO_FUNC_LOW);
+ gpio_set(enable_gpio.pin_id, resetseq->pin_direction);
+ }
+ return NO_ERROR;
+}
+
+int target_ldo_ctrl(uint8_t enable)
+{
+ uint32_t ldocounter = 0;
+ uint32_t pm8x41_ldo_base = 0x13F00;
+
+ while (ldocounter < TOTAL_LDO_DEFINED) {
+ struct pm8x41_ldo ldo_entry = LDO((pm8x41_ldo_base +
+ 0x100 * ldo_entry_array[ldocounter].ldo_id),
+ ldo_entry_array[ldocounter].ldo_type);
+
+ dprintf(SPEW, "Setting %s\n",
+ ldo_entry_array[ldocounter].ldo_id);
+
+ /* Set voltage during power on */
+ if (enable) {
+ pm8x41_ldo_set_voltage(&ldo_entry,
+ ldo_entry_array[ldocounter].ldo_voltage);
+ pm8x41_ldo_control(&ldo_entry, enable);
+ } else if(ldo_entry_array[ldocounter].ldo_id != HFPLL_LDO_ID) {
+ pm8x41_ldo_control(&ldo_entry, enable);
+ }
+ ldocounter++;
+ }
+
+ return NO_ERROR;
+}
+
+static int msm8974_mdss_edp_panel_clock(int enable)
+{
+ if (enable) {
+ mdp_gdsc_ctrl(enable);
+ mdp_clock_init();
+ edp_clk_enable();
+ } else if (!target_cont_splash_screen()) {
+ /* Add here for continuous splash */
+ edp_clk_disable();
+ mdp_clock_disable();
+ mdp_gdsc_ctrl(enable);
+ }
+
+ return 0;
+}
+
+static int msm8974_edp_panel_power(int enable)
+{
+ struct pm8x41_gpio gpio36_param = {
+ .direction = PM_GPIO_DIR_OUT,
+ .function = PM_GPIO_FUNC_2,
+ .vin_sel = 2, /* VIN_2 */
+ .pull = PM_GPIO_PULL_UP_1_5 | PM_GPIO_PULLDOWN_10,
+ .output_buffer = PM_GPIO_OUT_CMOS,
+ .out_strength = PM_GPIO_OUT_DRIVE_HIGH,
+ };
+
+ struct pm8x41_ldo ldo12 = LDO(PM8x41_LDO12, PLDO_TYPE);
+
+ if (enable) {
+ /* Enable backlight */
+ dprintf(SPEW, "Enable Backlight\n");
+ msm8974_pwm_backlight_ctrl(36, 8, 1);
+ dprintf(SPEW, "Enable Backlight Done\n");
+
+ /* Turn on LDO12 for edp vdda */
+ dprintf(SPEW, "Setting LDO12 n");
+ pm8x41_ldo_set_voltage(&ldo12, 1800000);
+ pm8x41_ldo_control(&ldo12, enable);
+ dprintf(SPEW, "Setting LDO12 Done\n");
+
+ /* Panel Enable */
+ dprintf(SPEW, "Panel Enable\n");
+ gpio_tlmm_config(58, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA,
+ GPIO_DISABLE);
+ gpio_set(58, 2);
+ dprintf(SPEW, "Panel Enable Done\n");
+ } else {
+ /* Keep LDO12 on, otherwise kernel will not boot */
+ gpio_set(58, 0);
+ msm8974_pwm_backlight_ctrl(36, 8, 0);
+ }
+
+ return 0;
+}
+
+void target_display_init(const char *panel_name)
+{
+ uint32_t hw_id = board_hardware_id();
+ uint32_t panel_loop = 0;
+ uint32_t ret = 0;
+ switch (hw_id) {
+ case HW_PLATFORM_LIQUID:
+ edp_panel_init(&(panel.panel_info));
+ panel.clk_func = msm8974_mdss_edp_panel_clock;
+ panel.power_func = msm8974_edp_panel_power;
+ panel.fb.base = (void *)EDP_FB_ADDR;
+ panel.fb.format = FB_FORMAT_RGB888;
+ panel.mdp_rev = MDP_REV_50;
+
+ if (msm_display_init(&panel)) {
+ dprintf(CRITICAL, "edp init failed!\n");
+ return;
+ }
+
+ edp_enable = 1;
+ break;
+ default:
+ do {
+ target_force_cont_splash_disable(false);
+ ret = gcdb_display_init(panel_name, MDP_REV_50,
+ MIPI_FB_ADDR);
+ if (!ret || ret == ERR_NOT_SUPPORTED) {
+ break;
+ } else {
+ target_force_cont_splash_disable(true);
+ msm_display_off();
+ }
+ } while (++panel_loop <= oem_panel_max_auto_detect_panels());
+ break;
+ }
+}
+
+void target_display_shutdown(void)
+{
+ uint32_t hw_id = board_hardware_id();
+ switch (hw_id) {
+ case HW_PLATFORM_LIQUID:
+ if (edp_enable)
+ msm_display_off();
+ break;
+ default:
+ gcdb_display_shutdown();
+ break;
+ }
+}