blob: b9a5813a2b4fb8b58567f5bbdb523251c0bd2768 [file] [log] [blame]
Shashank Mittal4bfb2e32012-04-16 10:56:27 -07001/* Copyright (c) 2012, Code Aurora Forum. 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 are
5 * 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
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. 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 "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#include <stdint.h>
31#include <reg.h>
32#include <err.h>
33#include <bits.h>
34#include <platform/iomap.h>
35#include <platform/clock.h>
36#include <dev/fbcon.h>
37#include <dev/lcdc.h>
38
39#include <msm_panel.h>
40#define MDP_OUTP(addr, val) writel(val, addr);
41
42void lvds_init(struct msm_panel_info *pinfo)
43{
44 unsigned int lvds_intf, lvds_phy_cfg0;
45 MDP_OUTP(MDP_BASE + 0xc2034, 0x33);
46 udelay(1000);
47
48 /*1. Configure LVDS PHY PLL through MDP_LVDSPHY_PLL_CTRL_* registers*/
49 /* LVDS PHY PLL configuration */
50 MDP_OUTP(MDP_BASE + 0xc3000, 0x08);
51 MDP_OUTP(MDP_BASE + 0xc3004, 0x87);
52 MDP_OUTP(MDP_BASE + 0xc3008, 0x30);
53 MDP_OUTP(MDP_BASE + 0xc300c, 0x06);
54 MDP_OUTP(MDP_BASE + 0xc3014, 0x20);
55 MDP_OUTP(MDP_BASE + 0xc3018, 0x0F);
56 MDP_OUTP(MDP_BASE + 0xc301c, 0x01);
57 MDP_OUTP(MDP_BASE + 0xc3020, 0x41);
58 MDP_OUTP(MDP_BASE + 0xc3024, 0x0d);
59 MDP_OUTP(MDP_BASE + 0xc3028, 0x07);
60 MDP_OUTP(MDP_BASE + 0xc302c, 0x00);
61 MDP_OUTP(MDP_BASE + 0xc3030, 0x1c);
62 MDP_OUTP(MDP_BASE + 0xc3034, 0x01);
63 MDP_OUTP(MDP_BASE + 0xc3038, 0x00);
64 MDP_OUTP(MDP_BASE + 0xc3040, 0xC0);
65 MDP_OUTP(MDP_BASE + 0xc3044, 0x00);
66 MDP_OUTP(MDP_BASE + 0xc3048, 0x30);
67 MDP_OUTP(MDP_BASE + 0xc304c, 0x00);
68
69 MDP_OUTP(MDP_BASE + 0xc3000, 0x11);
70 MDP_OUTP(MDP_BASE + 0xc3064, 0x05);
71 MDP_OUTP(MDP_BASE + 0xc3050, 0x20);
72
73 /*2. Enable LVDS PHY PLL in MDP_LVDSPHY_PLL_CTRL_0*/
74 MDP_OUTP(MDP_BASE + 0xc3000, 0x01);
75
76 /*3. Poll the MDP_LVDSPHY_PLL_RDY register until it is 1*/
77 /* Wait until LVDS PLL is locked and ready */
78 while (!readl(MDP_BASE + 0xc3080))
79 udelay(1);
80
81 /*4. Enable dsi2_pixel domain clocks*/
82 writel(0x00, REG_MM(0x0264));
83 writel(0x00, REG_MM(0x0094));
84
85 writel(0x02, REG_MM(0x00E4));
86
87 writel((0x80 | readl(REG_MM(0x00E4))),
88 REG_MM(0x00E4));
89 udelay(1000);
90 writel((~0x80 & readl(REG_MM(0x00E4))),
91 REG_MM(0x00E4));
92
93 writel(0x05, REG_MM(0x0094));
94 writel(0x02, REG_MM(0x0264));
95 /* Wait until LVDS pixel clock output is enabled */
96 dsb();
97 if (pinfo->bpp == 24) {
98 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
99 MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
100 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
101 MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
102 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
103 MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
104 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
105 MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
106 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
107 MDP_OUTP(MDP_BASE + 0xc2024, 0x151a191a);
108 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
109 MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
110 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
111 MDP_OUTP(MDP_BASE + 0xc202c, 0x1706071b);
112 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
113 MDP_OUTP(MDP_BASE + 0xc2030, 0x000e0f16);
114
115 if (pinfo->lvds.channel_mode ==
116 LVDS_DUAL_CHANNEL_MODE) {
117 lvds_intf = 0x0001ff80;
118 lvds_phy_cfg0 = BIT(6) | BIT(7);
119 if (pinfo->lvds.channel_swap)
120 lvds_intf |= BIT(4);
121 } else {
122 lvds_intf = 0x00010f84;
123 lvds_phy_cfg0 = BIT(6);
124 }
125 } else if (pinfo->bpp == 18) {
126 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
127 MDP_OUTP(MDP_BASE + 0xc2014, 0x03040508);
128 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
129 MDP_OUTP(MDP_BASE + 0xc2018, 0x00000102);
130 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
131 MDP_OUTP(MDP_BASE + 0xc201c, 0x0c0d1011);
132 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
133 MDP_OUTP(MDP_BASE + 0xc2020, 0x00090a0b);
134 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
135 MDP_OUTP(MDP_BASE + 0xc2024, 0x1518191a);
136 /* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
137 MDP_OUTP(MDP_BASE + 0xc2028, 0x00121314);
138
139 if (pinfo->lvds.channel_mode ==
140 LVDS_DUAL_CHANNEL_MODE) {
141 lvds_intf = 0x00017788;
142 lvds_phy_cfg0 = BIT(6) | BIT(7);
143 if (pinfo->lvds.channel_swap)
144 lvds_intf |= BIT(4);
145 } else {
146 lvds_intf = 0x0001078c;
147 lvds_phy_cfg0 = BIT(6);
148 }
149 }
150
151 /* MDP_LVDSPHY_CFG0 */
152 MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
153 /* MDP_LCDC_LVDS_INTF_CTL */
154 MDP_OUTP(MDP_BASE + 0xc2000, lvds_intf);
155 MDP_OUTP(MDP_BASE + 0xc3108, 0x30);
156 lvds_phy_cfg0 |= BIT(4);
157
158 /* Wait until LVDS PHY registers are configured */
159 dsb();
160 udelay(1);
161 /* MDP_LVDSPHY_CFG0, enable serialization */
162 MDP_OUTP(MDP_BASE + 0xc3100, lvds_phy_cfg0);
163}
164
165int lvds_on(struct msm_fb_panel_data *pdata)
166{
167 int ret = 0;
168 if (pdata == NULL) {
169 ret = ERR_INVALID_ARGS;
170 goto out;
171 }
172
173 lvds_init(&(pdata->panel_info));
174out:
175 return ret;
176}
177