tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sprdfb / sprdfb_usc28c_init.c
1 /*
2  * Copyright (C) 2014 Spreadtrum Communications Inc.
3  *
4  * modules/DISPC/usc28c_dsi_init.c
5  *
6  * Author: Haibing.Yang <haibing.yang@spreadtrum.com>
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <common.h>
19 #include <asm/io.h>
20 #include <asm/arch/sprd_reg.h>
21
22 #ifndef CTL_BASE_GPIO
23 #define CTL_BASE_GPIO 0x40280000
24 #endif
25
26 #define CTL_BASE_ENABLE_USC28C_DSI 0x403f0008
27
28 #define pr_info printf
29
30 #define CHIP_GPIO_BASE                  CTL_BASE_GPIO
31 #define ARM_GPIO_BASE_CNT              (192)
32
33 #define SPI_USC28C_SCK_GPIO_PIN        (200)
34 #define SPI_USC28C_SEN_GPIO_PIN        (201)
35 #define SPI_USC28C_DAT_GPIO_PIN        (202)
36
37 #define SPI_USC28C_SCK_GPIO_MASK       (1<<(SPI_USC28C_SCK_GPIO_PIN-ARM_GPIO_BASE_CNT))
38 #define SPI_USC28C_SEN_GPIO_MASK       (1<<(SPI_USC28C_SEN_GPIO_PIN-ARM_GPIO_BASE_CNT))
39 #define SPI_USC28C_DAT_GPIO_MASK       (1<<(SPI_USC28C_DAT_GPIO_PIN-ARM_GPIO_BASE_CNT))
40 #define SPI_CLK_DELAY                                   0
41 #define SPI_READ_REG                                    0x3F
42
43 #define GPIO_CHIP_USC28C_OFFSET                 (CHIP_GPIO_BASE + 0x600)
44
45 #define DSI_SCAN_MODE_0                                 252
46 #define DSI_SCAN_MODE_1                                 394
47
48 struct gpio_ctrl_reg {
49         volatile u32 data; /* bits data */
50         volatile u32 msk; /* bits data mask */
51         volatile u32 dir; /* bits data direction */
52         volatile u32 is; /* bits interrupt sense */
53         volatile u32 ibe; /* bits both edges interrupt */
54         volatile u32 iev; /* bits interrupt event */
55         volatile u32 ie; /* bits interrupt enable */
56         volatile u32 ris; /* bits raw interrupt status */
57         volatile u32 mis; /* bits masked interrupt status */
58         volatile u32 inen; /* input enable */
59 };
60
61 static void gpio_set_dir(u8 port, u8 dir)
62 {
63         volatile struct gpio_ctrl_reg *reg;
64
65         reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
66         if (dir) {
67                 reg->dir |= 1 << ((u32) (port - ARM_GPIO_BASE_CNT)); // OUTPUT MODE.
68         } else {
69                 reg->dir &= ~((u32)(1 << ((u32) (port - ARM_GPIO_BASE_CNT)))); // INPUT MODE.
70         }
71         reg->msk |= (1 << (u32)(port - ARM_GPIO_BASE_CNT)); // OUTPUT MODE.
72 }
73
74 static void gpio_out(u8 port, u8 data)
75 {
76         volatile struct gpio_ctrl_reg *reg;
77
78         reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
79         if (data) {
80                 reg->data |= (1 << (u32)(port - ARM_GPIO_BASE_CNT)); // set 1.
81         } else {
82                 reg->data &= ~(1 << (u32)(port - ARM_GPIO_BASE_CNT)); // set 0.
83         }
84 }
85
86 static void gpio_out_combo(u32 sclk, u32 sen, u32 dat)
87 {
88         volatile struct gpio_ctrl_reg *reg;
89         u32 read_dat;
90         u32 reg_set = 0;
91
92         reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
93
94         if (sclk) {
95                 reg_set |= SPI_USC28C_SCK_GPIO_MASK;
96         }
97         if (sen) {
98                 reg_set |= SPI_USC28C_SEN_GPIO_MASK;
99         }
100         if (dat) {
101                 reg_set |= SPI_USC28C_DAT_GPIO_MASK;
102         }
103         read_dat = reg->data;
104         read_dat &= ~(SPI_USC28C_SCK_GPIO_MASK | SPI_USC28C_SEN_GPIO_MASK
105                         | SPI_USC28C_DAT_GPIO_MASK);
106         read_dat |= reg_set;
107         reg->data = read_dat;
108 }
109
110 static u8 gpio_in(u8 port)
111 {
112         volatile struct gpio_ctrl_reg *reg;
113         u32 data;
114
115         reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
116
117         data = reg->data;
118         if (data & (1 << (port - ARM_GPIO_BASE_CNT))) {
119                 return 1;
120         }
121         return 0;
122 }
123
124 static void __usc28c_spi_init(void)
125 {
126         gpio_set_dir(SPI_USC28C_SCK_GPIO_PIN, 1);
127         gpio_set_dir(SPI_USC28C_SEN_GPIO_PIN, 1);
128         gpio_set_dir(SPI_USC28C_DAT_GPIO_PIN, 1);
129
130         gpio_out(SPI_USC28C_SCK_GPIO_PIN, 0);
131         gpio_out(SPI_USC28C_SEN_GPIO_PIN, 1);
132         gpio_out(SPI_USC28C_DAT_GPIO_PIN, 0);
133 }
134
135 static void __spi_reg_w(u16 reg, u16 val)
136 {
137         s8 i;
138         u8 temp = 0;
139
140         gpio_set_dir(SPI_USC28C_SCK_GPIO_PIN, 1);
141         gpio_set_dir(SPI_USC28C_SEN_GPIO_PIN, 1);
142         gpio_set_dir(SPI_USC28C_DAT_GPIO_PIN, 1);
143
144         gpio_out_combo(0, 1, 0);
145         udelay(SPI_CLK_DELAY);
146         if (val & (1 << 15)) {
147                 gpio_out_combo(0, 0, 1);
148         } else {
149                 gpio_out_combo(0, 0, 0);
150         }
151         udelay(SPI_CLK_DELAY);
152         gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
153         udelay(SPI_CLK_DELAY);
154
155         for (i = 14; i >= 0; i--) {
156                 gpio_out_combo(0, 0, val & (1 << i));
157                 udelay(SPI_CLK_DELAY);
158                 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
159                 udelay(SPI_CLK_DELAY);
160         }
161
162         for (i = 1; i >= 0; i--) {
163                 gpio_out_combo(0, 0, temp & (1 << i));
164                 udelay(SPI_CLK_DELAY);
165                 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
166                 udelay(SPI_CLK_DELAY);
167         }
168
169         for (i = 15; i >= 0; i--) {
170                 gpio_out_combo(0, 0, reg & (1 << i));
171                 udelay(SPI_CLK_DELAY);
172                 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
173                 udelay(SPI_CLK_DELAY);
174         }
175         udelay(SPI_CLK_DELAY);
176         gpio_out_combo(0, 1, 1);
177 }
178
179 static u16 __spi_reg_r(u16 reg)
180 {
181         s8 i;
182         u16 recv = 0;
183
184         __spi_reg_w(SPI_READ_REG, reg);
185         gpio_set_dir(SPI_USC28C_DAT_GPIO_PIN, 0);
186
187         gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
188         udelay(SPI_CLK_DELAY);
189         gpio_out(SPI_USC28C_SCK_GPIO_PIN, 0);
190
191         for (i = 15; i >= 0; i--) {
192                 udelay(SPI_CLK_DELAY);
193                 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
194                 recv <<= 1;
195                 udelay(SPI_CLK_DELAY);
196                 recv |= gpio_in(SPI_USC28C_DAT_GPIO_PIN);
197                 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 0);
198         }
199
200         return recv;
201 }
202
203 void usc28c_dsi_init(void)
204 {
205         u16 phy_regs;
206
207         writel(0x2880, CTL_BASE_ENABLE_USC28C_DSI);
208
209         __usc28c_spi_init();
210         /* DSI */
211         __spi_reg_w(0x00, 0x01);
212         __spi_reg_w(0x10, 0x02);
213 /*
214  * choose CSI
215         __spi_reg_w(0x00, 0x07);
216         __spi_reg_w(0x10, 0x03);
217  * choose CSI
218  */
219         pr_info("%s: chip usc28c dsi mode is chosen\n", __func__);
220
221         /* scan mode config: d252 and d394 bit[6] = 1 */
222         __spi_reg_w(DSI_SCAN_MODE_0, __spi_reg_r(DSI_SCAN_MODE_0) | BIT(6));
223         __spi_reg_w(DSI_SCAN_MODE_1, __spi_reg_r(DSI_SCAN_MODE_1) | BIT(6));
224
225 #ifdef CONFIG_IMPROVE_PHY_DRIVE_CAPAILITY
226         for (phy_regs = 64; phy_regs <= 484; ++phy_regs)
227                 __spi_reg_w(phy_regs, __spi_reg_r(phy_regs) |
228                                 BIT(15) | BIT(14) & ~(BIT(5) | BIT(4)));
229
230         for (phy_regs = 493; phy_regs <= 497; ++phy_regs)
231                 __spi_reg_w(phy_regs, __spi_reg_r(phy_regs) |
232                                 BIT(15) | BIT(14) & ~(BIT(5) | BIT(4)));
233 #endif
234
235         pr_info("Reg0x%04x, value: 0x%04x and Reg0x%04x, value: 0x%04x\n",
236                         0x0, __spi_reg_r(0x0), 0x10, __spi_reg_r(0x10));
237         pr_info("Reg0x%04x, value: 0x%04x and Reg0x%04x, value: 0x%04x\n",
238                         DSI_SCAN_MODE_0, __spi_reg_r(DSI_SCAN_MODE_0),
239                         DSI_SCAN_MODE_1, __spi_reg_r(DSI_SCAN_MODE_1));
240 }
241
242 void __usc28c_usb_init(void)
243 {
244         u16 reg_addr;
245
246         for (reg_addr = 64; reg_addr <= 484; reg_addr++) {
247                 __spi_reg_w(reg_addr, (__spi_reg_r(reg_addr) & (~BIT(5))) | BIT(4));
248         }
249
250         for (reg_addr = 493; reg_addr <= 497; reg_addr++) {
251                 __spi_reg_w(reg_addr, (__spi_reg_r(reg_addr) & (~BIT(5))) | BIT(4));
252         }
253 }
254