blob: 02e47377df5a209f5f5a85a0b581b8fdb7a9a826 [file] [log] [blame]
Dhaval Patelf9986272013-10-18 19:06:05 -07001/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
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
89int target_backlight_ctrl(uint8_t enable)
90{
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 };
99 if (enable) {
100 pm8x41_gpio_config(7, &pwmgpio_param);
101
102 /* lpg channel 2 */
103 pm8x41_lpg_write(3, 0x41, 0x33); /* LPG_PWM_SIZE_CLK, */
104 pm8x41_lpg_write(3, 0x42, 0x01); /* LPG_PWM_FREQ_PREDIV */
105 pm8x41_lpg_write(3, 0x43, 0x20); /* LPG_PWM_TYPE_CONFIG */
106 pm8x41_lpg_write(3, 0x44, 0xcc); /* LPG_VALUE_LSB */
107 pm8x41_lpg_write(3, 0x45, 0x00); /* LPG_VALUE_MSB */
108 pm8x41_lpg_write(3, 0x46, 0xe4); /* LPG_ENABLE_CONTROL */
109 } else {
110 pm8x41_lpg_write(3, 0x46, 0x0); /* LPG_ENABLE_CONTROL */
111 }
112
113 return NO_ERROR;
114}
115
116int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
117{
118 struct mdss_dsi_pll_config *pll_data;
119 uint32_t dual_dsi = pinfo->mipi.dual_dsi;
120 dprintf(SPEW, "target_panel_clock\n");
121
122 pll_data = pinfo->mipi.dsi_pll_config;
123 if (enable) {
124 mdp_gdsc_ctrl(enable);
125 mmss_bus_clock_enable();
126 mdp_clock_enable();
127 mdss_dsi_auto_pll_config(MIPI_DSI0_BASE, pll_data);
128 dsi_pll_enable_seq(MIPI_DSI0_BASE);
129 if (pinfo->mipi.dual_dsi &&
130 !(pinfo->mipi.broadcast)) {
131 mdss_dsi_auto_pll_config(MIPI_DSI1_BASE, pll_data);
132 dsi_pll_enable_seq(MIPI_DSI1_BASE);
133 }
134 mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, dual_dsi,
135 pll_data->pclk_m,
136 pll_data->pclk_n,
137 pll_data->pclk_d);
138 } else if(!target_cont_splash_screen()) {
139 /* Disable clocks if continuous splash off */
140 mmss_dsi_clock_enable(dual_dsi);
141 mdp_clock_disable();
142 mmss_bus_clock_disable();
143 mdp_gdsc_ctrl(enable);
144 }
145
146 return NO_ERROR;
147}
148
149/* Pull DISP_RST_N high to get panel out of reset */
150int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
151 struct msm_panel_info *pinfo)
152{
153 uint32_t i = 0;
154
155 if (enable) {
156 gpio_tlmm_config(reset_gpio.pin_id, 0,
157 reset_gpio.pin_direction, reset_gpio.pin_pull,
158 reset_gpio.pin_strength, reset_gpio.pin_state);
159
160 gpio_tlmm_config(enable_gpio.pin_id, 0,
161 enable_gpio.pin_direction, enable_gpio.pin_pull,
162 enable_gpio.pin_strength, enable_gpio.pin_state);
163
164 gpio_tlmm_config(bkl_gpio.pin_id, 0,
165 bkl_gpio.pin_direction, bkl_gpio.pin_pull,
166 bkl_gpio.pin_strength, bkl_gpio.pin_state);
167
168 gpio_set(enable_gpio.pin_id, 2);
169 gpio_set(bkl_gpio.pin_id, 2);
170 /* reset */
171 for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
172 if (resetseq->pin_state[i] == GPIO_STATE_LOW)
173 gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
174 else
175 gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
176 mdelay(resetseq->sleep[i]);
177 }
178 } else {
179 gpio_set(reset_gpio.pin_id, 0);
180 gpio_set(enable_gpio.pin_id, 0);
181 gpio_set(bkl_gpio.pin_id, 0);
182 }
183
184 return NO_ERROR;
185}
186
187int target_ldo_ctrl(uint8_t enable)
188{
189 uint32_t ldocounter = 0;
190 uint32_t pm8x41_ldo_base = 0x13F00;
191
192 while (ldocounter < TOTAL_LDO_DEFINED) {
193 struct pm8x41_ldo ldo_entry = LDO((pm8x41_ldo_base +
194 0x100 * ldo_entry_array[ldocounter].ldo_id),
195 ldo_entry_array[ldocounter].ldo_type);
196
197 dprintf(SPEW, "Setting %s\n",
198 ldo_entry_array[ldocounter].ldo_id);
199
200 /* Set voltage during power on */
201 if (enable) {
202 pm8x41_ldo_set_voltage(&ldo_entry,
203 ldo_entry_array[ldocounter].ldo_voltage);
204 pm8x41_ldo_control(&ldo_entry, enable);
205 } else if(ldo_entry_array[ldocounter].ldo_id != HFPLL_LDO_ID) {
206 pm8x41_ldo_control(&ldo_entry, enable);
207 }
208 ldocounter++;
209 }
210
211 return NO_ERROR;
212}
213
214void display_init(void)
215{
216 uint32_t ret = 0;
217 ret = gcdb_display_init(MDP_REV_50, MIPI_FB_ADDR);
218 if (ret) {
219 msm_display_off();
220 }
221}
222
223void display_shutdown(void)
224{
225 gcdb_display_shutdown();
226}