2 * Copyright (C) 2014 Spreadtrum Communications Inc.
4 * modules/DISPC/usc28c_dsi_init.c
6 * Author: Haibing.Yang <haibing.yang@spreadtrum.com>
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.
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.
20 #include <asm/arch/sprd_reg.h>
23 #define CTL_BASE_GPIO 0x40280000
26 #define CTL_BASE_ENABLE_USC28C_DSI 0x403f0008
28 #define pr_info printf
30 #define CHIP_GPIO_BASE CTL_BASE_GPIO
31 #define ARM_GPIO_BASE_CNT (192)
33 #define SPI_USC28C_SCK_GPIO_PIN (200)
34 #define SPI_USC28C_SEN_GPIO_PIN (201)
35 #define SPI_USC28C_DAT_GPIO_PIN (202)
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
43 #define GPIO_CHIP_USC28C_OFFSET (CHIP_GPIO_BASE + 0x600)
45 #define DSI_SCAN_MODE_0 252
46 #define DSI_SCAN_MODE_1 394
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 */
61 static void gpio_set_dir(u8 port, u8 dir)
63 volatile struct gpio_ctrl_reg *reg;
65 reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
67 reg->dir |= 1 << ((u32) (port - ARM_GPIO_BASE_CNT)); // OUTPUT MODE.
69 reg->dir &= ~((u32)(1 << ((u32) (port - ARM_GPIO_BASE_CNT)))); // INPUT MODE.
71 reg->msk |= (1 << (u32)(port - ARM_GPIO_BASE_CNT)); // OUTPUT MODE.
74 static void gpio_out(u8 port, u8 data)
76 volatile struct gpio_ctrl_reg *reg;
78 reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
80 reg->data |= (1 << (u32)(port - ARM_GPIO_BASE_CNT)); // set 1.
82 reg->data &= ~(1 << (u32)(port - ARM_GPIO_BASE_CNT)); // set 0.
86 static void gpio_out_combo(u32 sclk, u32 sen, u32 dat)
88 volatile struct gpio_ctrl_reg *reg;
92 reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
95 reg_set |= SPI_USC28C_SCK_GPIO_MASK;
98 reg_set |= SPI_USC28C_SEN_GPIO_MASK;
101 reg_set |= SPI_USC28C_DAT_GPIO_MASK;
103 read_dat = reg->data;
104 read_dat &= ~(SPI_USC28C_SCK_GPIO_MASK | SPI_USC28C_SEN_GPIO_MASK
105 | SPI_USC28C_DAT_GPIO_MASK);
107 reg->data = read_dat;
110 static u8 gpio_in(u8 port)
112 volatile struct gpio_ctrl_reg *reg;
115 reg = (volatile struct gpio_ctrl_reg *)(GPIO_CHIP_USC28C_OFFSET);
118 if (data & (1 << (port - ARM_GPIO_BASE_CNT))) {
124 static void __usc28c_spi_init(void)
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);
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);
135 static void __spi_reg_w(u16 reg, u16 val)
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);
144 gpio_out_combo(0, 1, 0);
145 udelay(SPI_CLK_DELAY);
146 if (val & (1 << 15)) {
147 gpio_out_combo(0, 0, 1);
149 gpio_out_combo(0, 0, 0);
151 udelay(SPI_CLK_DELAY);
152 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
153 udelay(SPI_CLK_DELAY);
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);
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);
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);
175 udelay(SPI_CLK_DELAY);
176 gpio_out_combo(0, 1, 1);
179 static u16 __spi_reg_r(u16 reg)
184 __spi_reg_w(SPI_READ_REG, reg);
185 gpio_set_dir(SPI_USC28C_DAT_GPIO_PIN, 0);
187 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
188 udelay(SPI_CLK_DELAY);
189 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 0);
191 for (i = 15; i >= 0; i--) {
192 udelay(SPI_CLK_DELAY);
193 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 1);
195 udelay(SPI_CLK_DELAY);
196 recv |= gpio_in(SPI_USC28C_DAT_GPIO_PIN);
197 gpio_out(SPI_USC28C_SCK_GPIO_PIN, 0);
203 void usc28c_dsi_init(void)
207 writel(0x2880, CTL_BASE_ENABLE_USC28C_DSI);
211 __spi_reg_w(0x00, 0x01);
212 __spi_reg_w(0x10, 0x02);
215 __spi_reg_w(0x00, 0x07);
216 __spi_reg_w(0x10, 0x03);
219 pr_info("%s: chip usc28c dsi mode is chosen\n", __func__);
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));
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)));
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)));
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));
242 void __usc28c_usb_init(void)
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));
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));