blob: 8af6d1b4ae78124c1f3b795694947e6f31920bfd [file] [log] [blame]
Kuogee Hsieh7c3982a2013-12-18 14:13:45 -08001/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
Dhaval Patel25f686e2013-10-18 19:06:05 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in
10 * the documentation and/or other materials provided with the
11 * distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <debug.h>
31#include <smem.h>
32#include <err.h>
33#include <msm_panel.h>
34#include <mipi_dsi.h>
35#include <pm8x41.h>
36#include <pm8x41_wled.h>
37#include <board.h>
38#include <mdp5.h>
39#include <endian.h>
40#include <platform/gpio.h>
41#include <platform/clock.h>
42#include <platform/iomap.h>
43#include <target/display.h>
44#include "include/panel.h"
45#include "include/display_resource.h"
46
47#define HFPLL_LDO_ID 12
48
49#define GPIO_STATE_LOW 0
50#define GPIO_STATE_HIGH 2
51#define RESET_GPIO_SEQ_LEN 3
52
53static uint32_t dsi_pll_enable_seq(uint32_t ctl_base)
54{
55 uint32_t rc = 0;
56
57 mdss_dsi_uniphy_pll_sw_reset(ctl_base);
58
59 writel(0x01, ctl_base + 0x0220); /* GLB CFG */
60 mdelay(1);
61 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
62 mdelay(1);
63 writel(0x07, ctl_base + 0x0220); /* GLB CFG */
64 mdelay(1);
65 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
66 mdelay(1);
67
68 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
69
70 while (!(readl(ctl_base + 0x02c0) & 0x01)) {
71 mdss_dsi_uniphy_pll_sw_reset(ctl_base);
72 writel(0x01, ctl_base + 0x0220); /* GLB CFG */
73 mdelay(1);
74 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
75 mdelay(1);
76 writel(0x07, ctl_base + 0x0220); /* GLB CFG */
77 mdelay(1);
78 writel(0x05, ctl_base + 0x0220); /* GLB CFG */
79 mdelay(1);
80 writel(0x07, ctl_base + 0x0220); /* GLB CFG */
81 mdelay(1);
82 writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
83 mdelay(2);
84 mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
85 }
86 return rc;
87}
88
Kuogee Hsieh7c3982a2013-12-18 14:13:45 -080089int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
Dhaval Patel25f686e2013-10-18 19:06:05 -070090{
91 struct pm8x41_gpio pwmgpio_param = {
92 .direction = PM_GPIO_DIR_OUT,
93 .function = PM_GPIO_FUNC_1,
94 .vin_sel = 2, /* VIN_2 */
95 .pull = PM_GPIO_PULL_UP_1_5 | PM_GPIO_PULLDOWN_10,
96 .output_buffer = PM_GPIO_OUT_CMOS,
97 .out_strength = 0x03,
98 };
Kuogee Hsieh7c3982a2013-12-18 14:13:45 -080099
Dhaval Patel25f686e2013-10-18 19:06:05 -0700100 if (enable) {
Dhaval Patel18bf4c62014-01-07 21:57:30 -0800101 pm8x41_gpio_config(pwm_gpio.pin_id, &pwmgpio_param);
Dhaval Patel25f686e2013-10-18 19:06:05 -0700102
103 /* lpg channel 2 */
Dhaval Patel18bf4c62014-01-07 21:57:30 -0800104 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x41, 0x33); /* LPG_PWM_SIZE_CLK, */
105 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x42, 0x01); /* LPG_PWM_FREQ_PREDIV */
106 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x43, 0x20); /* LPG_PWM_TYPE_CONFIG */
107 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x44, 0xcc); /* LPG_VALUE_LSB */
108 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x45, 0x00); /* LPG_VALUE_MSB */
109 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x46, 0xe4); /* LPG_ENABLE_CONTROL */
Dhaval Patel25f686e2013-10-18 19:06:05 -0700110 } else {
Dhaval Patel18bf4c62014-01-07 21:57:30 -0800111 pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x46, 0x0); /* LPG_ENABLE_CONTROL */
Dhaval Patel25f686e2013-10-18 19:06:05 -0700112 }
113
114 return NO_ERROR;
115}
116
117int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
118{
119 struct mdss_dsi_pll_config *pll_data;
120 uint32_t dual_dsi = pinfo->mipi.dual_dsi;
121 dprintf(SPEW, "target_panel_clock\n");
122
123 pll_data = pinfo->mipi.dsi_pll_config;
124 if (enable) {
125 mdp_gdsc_ctrl(enable);
126 mmss_bus_clock_enable();
127 mdp_clock_enable();
128 mdss_dsi_auto_pll_config(MIPI_DSI0_BASE, pll_data);
129 dsi_pll_enable_seq(MIPI_DSI0_BASE);
130 if (pinfo->mipi.dual_dsi &&
131 !(pinfo->mipi.broadcast)) {
132 mdss_dsi_auto_pll_config(MIPI_DSI1_BASE, pll_data);
133 dsi_pll_enable_seq(MIPI_DSI1_BASE);
134 }
135 mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, dual_dsi,
136 pll_data->pclk_m,
137 pll_data->pclk_n,
138 pll_data->pclk_d);
139 } else if(!target_cont_splash_screen()) {
140 /* Disable clocks if continuous splash off */
Dhaval Patelaff93af2013-10-29 12:48:41 -0700141 mmss_dsi_clock_disable(dual_dsi);
Dhaval Patel25f686e2013-10-18 19:06:05 -0700142 mdp_clock_disable();
143 mmss_bus_clock_disable();
144 mdp_gdsc_ctrl(enable);
145 }
146
147 return NO_ERROR;
148}
149
150/* Pull DISP_RST_N high to get panel out of reset */
151int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
152 struct msm_panel_info *pinfo)
153{
154 uint32_t i = 0;
155
156 if (enable) {
157 gpio_tlmm_config(reset_gpio.pin_id, 0,
158 reset_gpio.pin_direction, reset_gpio.pin_pull,
159 reset_gpio.pin_strength, reset_gpio.pin_state);
160
161 gpio_tlmm_config(enable_gpio.pin_id, 0,
162 enable_gpio.pin_direction, enable_gpio.pin_pull,
163 enable_gpio.pin_strength, enable_gpio.pin_state);
164
165 gpio_tlmm_config(bkl_gpio.pin_id, 0,
166 bkl_gpio.pin_direction, bkl_gpio.pin_pull,
167 bkl_gpio.pin_strength, bkl_gpio.pin_state);
168
169 gpio_set(enable_gpio.pin_id, 2);
170 gpio_set(bkl_gpio.pin_id, 2);
171 /* reset */
172 for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
173 if (resetseq->pin_state[i] == GPIO_STATE_LOW)
174 gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
175 else
176 gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
177 mdelay(resetseq->sleep[i]);
178 }
179 } else {
180 gpio_set(reset_gpio.pin_id, 0);
181 gpio_set(enable_gpio.pin_id, 0);
182 gpio_set(bkl_gpio.pin_id, 0);
183 }
184
185 return NO_ERROR;
186}
187
188int target_ldo_ctrl(uint8_t enable)
189{
190 uint32_t ldocounter = 0;
191 uint32_t pm8x41_ldo_base = 0x13F00;
192
193 while (ldocounter < TOTAL_LDO_DEFINED) {
194 struct pm8x41_ldo ldo_entry = LDO((pm8x41_ldo_base +
195 0x100 * ldo_entry_array[ldocounter].ldo_id),
196 ldo_entry_array[ldocounter].ldo_type);
197
198 dprintf(SPEW, "Setting %s\n",
199 ldo_entry_array[ldocounter].ldo_id);
200
201 /* Set voltage during power on */
202 if (enable) {
203 pm8x41_ldo_set_voltage(&ldo_entry,
204 ldo_entry_array[ldocounter].ldo_voltage);
205 pm8x41_ldo_control(&ldo_entry, enable);
206 } else if(ldo_entry_array[ldocounter].ldo_id != HFPLL_LDO_ID) {
207 pm8x41_ldo_control(&ldo_entry, enable);
208 }
209 ldocounter++;
210 }
211
212 return NO_ERROR;
213}
214
Dhaval Patel83b08bc2013-10-25 10:40:58 -0700215int target_display_pre_on()
216{
217 writel(0x000000FA, MDP_QOS_REMAPPER_CLASS_0);
218 writel(0x00000055, MDP_QOS_REMAPPER_CLASS_1);
219 writel(0xC0000CCD, MDP_CLK_CTRL0);
220 writel(0xD0000CCC, MDP_CLK_CTRL1);
221 writel(0x00CCCCCC, MDP_CLK_CTRL2);
222 writel(0x000000CC, MDP_CLK_CTRL6);
223 writel(0x0CCCC0C0, MDP_CLK_CTRL3);
224 writel(0xCCCCC0C0, MDP_CLK_CTRL4);
225 writel(0xCCCCC0C0, MDP_CLK_CTRL5);
226 writel(0x00CCC000, MDP_CLK_CTRL7);
227
228 writel(0x00000001, VBIF_VBIF_DDR_FORCE_CLK_ON);
229 writel(0x00080808, VBIF_VBIF_IN_RD_LIM_CONF0);
230 writel(0x08000808, VBIF_VBIF_IN_RD_LIM_CONF1);
231 writel(0x00080808, VBIF_VBIF_IN_RD_LIM_CONF2);
232 writel(0x00000808, VBIF_VBIF_IN_RD_LIM_CONF3);
233 writel(0x10000000, VBIF_VBIF_IN_WR_LIM_CONF0);
234 writel(0x00100000, VBIF_VBIF_IN_WR_LIM_CONF1);
235 writel(0x10000000, VBIF_VBIF_IN_WR_LIM_CONF2);
236 writel(0x00000000, VBIF_VBIF_IN_WR_LIM_CONF3);
237 writel(0x00013fff, VBIF_VBIF_ABIT_SHORT);
238 writel(0x000000A4, VBIF_VBIF_ABIT_SHORT_CONF);
239 writel(0x00003FFF, VBIF_VBIF_GATE_OFF_WRREQ_EN);
240 writel(0x00000003, VBIF_VBIF_DDR_RND_RBN_QOS_ARB);
241
242 return NO_ERROR;
243}
244
Aravind Venkateswaran35d110b2014-02-25 16:45:11 -0800245void target_display_init(const char *panel_name)
Dhaval Patel25f686e2013-10-18 19:06:05 -0700246{
247 uint32_t ret = 0;
Aravind Venkateswaran927e9102014-02-25 17:16:49 -0800248 ret = gcdb_display_init(panel_name, MDP_REV_50, MIPI_FB_ADDR);
Dhaval Patel25f686e2013-10-18 19:06:05 -0700249 if (ret) {
Justin Philipd4b293a2014-09-17 12:26:49 +0530250 target_force_cont_splash_disable(true);
Dhaval Patel25f686e2013-10-18 19:06:05 -0700251 msm_display_off();
252 }
253}
254
Aravind Venkateswaran497653f2014-02-25 14:42:43 -0800255void target_display_shutdown(void)
Dhaval Patel25f686e2013-10-18 19:06:05 -0700256{
257 gcdb_display_shutdown();
258}