ARM: LPC32xx: Remove SLC controller initialization from platform init
[deliverable/linux.git] / arch / arm / mach-lpc32xx / phy3250.c
CommitLineData
19d95e1a 1/*
f5c42271 2 * Platform support for LPC32xx SoC
19d95e1a
KW
3 *
4 * Author: Kevin Wells <kevin.wells@nxp.com>
5 *
f5c42271 6 * Copyright (C) 2012 Roland Stigge <stigge@antcom.de>
19d95e1a
KW
7 * Copyright (C) 2010 NXP Semiconductors
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/init.h>
21#include <linux/platform_device.h>
edbaa603 22#include <linux/device.h>
19d95e1a
KW
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/dma-mapping.h>
26#include <linux/device.h>
27#include <linux/spi/spi.h>
28#include <linux/spi/eeprom.h>
19d95e1a
KW
29#include <linux/gpio.h>
30#include <linux/amba/bus.h>
31#include <linux/amba/clcd.h>
32#include <linux/amba/pl022.h>
f5c42271
RS
33#include <linux/of.h>
34#include <linux/of_address.h>
35#include <linux/of_irq.h>
36#include <linux/of_platform.h>
37#include <linux/clk.h>
38#include <linux/amba/pl08x.h>
19d95e1a
KW
39
40#include <asm/setup.h>
41#include <asm/mach-types.h>
42#include <asm/mach/arch.h>
43
44#include <mach/hardware.h>
45#include <mach/platform.h>
c20b909b 46#include <mach/board.h>
9c587c05 47#include <mach/gpio-lpc32xx.h>
19d95e1a
KW
48#include "common.h"
49
50/*
51 * Mapped GPIOLIB GPIOs
52 */
53#define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
54#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0)
55#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4)
19d95e1a
KW
56
57/*
58 * AMBA LCD controller
59 */
60static struct clcd_panel conn_lcd_panel = {
61 .mode = {
62 .name = "QVGA portrait",
63 .refresh = 60,
64 .xres = 240,
65 .yres = 320,
66 .pixclock = 191828,
67 .left_margin = 22,
68 .right_margin = 11,
69 .upper_margin = 2,
70 .lower_margin = 1,
71 .hsync_len = 5,
72 .vsync_len = 2,
73 .sync = 0,
74 .vmode = FB_VMODE_NONINTERLACED,
75 },
76 .width = -1,
77 .height = -1,
78 .tim2 = (TIM2_IVS | TIM2_IHS),
79 .cntl = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) |
80 CNTL_LCDBPP16_565),
81 .bpp = 16,
82};
83#define PANEL_SIZE (3 * SZ_64K)
84
85static int lpc32xx_clcd_setup(struct clcd_fb *fb)
86{
87 dma_addr_t dma;
88
89 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev,
90 PANEL_SIZE, &dma, GFP_KERNEL);
91 if (!fb->fb.screen_base) {
92 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
93 return -ENOMEM;
94 }
95
96 fb->fb.fix.smem_start = dma;
97 fb->fb.fix.smem_len = PANEL_SIZE;
98 fb->panel = &conn_lcd_panel;
99
100 if (gpio_request(LCD_POWER_GPIO, "LCD power"))
101 printk(KERN_ERR "Error requesting gpio %u",
102 LCD_POWER_GPIO);
103 else if (gpio_direction_output(LCD_POWER_GPIO, 1))
104 printk(KERN_ERR "Error setting gpio %u to output",
105 LCD_POWER_GPIO);
106
107 if (gpio_request(BKL_POWER_GPIO, "LCD backlight power"))
108 printk(KERN_ERR "Error requesting gpio %u",
109 BKL_POWER_GPIO);
110 else if (gpio_direction_output(BKL_POWER_GPIO, 1))
111 printk(KERN_ERR "Error setting gpio %u to output",
112 BKL_POWER_GPIO);
113
114 return 0;
115}
116
117static int lpc32xx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
118{
119 return dma_mmap_writecombine(&fb->dev->dev, vma,
120 fb->fb.screen_base, fb->fb.fix.smem_start,
121 fb->fb.fix.smem_len);
122}
123
124static void lpc32xx_clcd_remove(struct clcd_fb *fb)
125{
126 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
127 fb->fb.screen_base, fb->fb.fix.smem_start);
128}
129
130/*
131 * On some early LCD modules (1307.0), the backlight logic is inverted.
132 * For those board variants, swap the disable and enable states for
133 * BKL_POWER_GPIO.
134*/
135static void clcd_disable(struct clcd_fb *fb)
136{
137 gpio_set_value(BKL_POWER_GPIO, 0);
138 gpio_set_value(LCD_POWER_GPIO, 0);
139}
140
141static void clcd_enable(struct clcd_fb *fb)
142{
143 gpio_set_value(BKL_POWER_GPIO, 1);
144 gpio_set_value(LCD_POWER_GPIO, 1);
145}
146
147static struct clcd_board lpc32xx_clcd_data = {
148 .name = "Phytec LCD",
149 .check = clcdfb_check,
150 .decode = clcdfb_decode,
151 .disable = clcd_disable,
152 .enable = clcd_enable,
153 .setup = lpc32xx_clcd_setup,
154 .mmap = lpc32xx_clcd_mmap,
155 .remove = lpc32xx_clcd_remove,
156};
157
19d95e1a
KW
158/*
159 * AMBA SSP (SPI)
160 */
161static void phy3250_spi_cs_set(u32 control)
162{
163 gpio_set_value(SPI0_CS_GPIO, (int) control);
164}
165
166static struct pl022_config_chip spi0_chip_info = {
19d95e1a
KW
167 .com_mode = INTERRUPT_TRANSFER,
168 .iface = SSP_INTERFACE_MOTOROLA_SPI,
169 .hierarchy = SSP_MASTER,
170 .slave_tx_disable = 0,
19d95e1a
KW
171 .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
172 .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
19d95e1a
KW
173 .ctrl_len = SSP_BITS_8,
174 .wait_state = SSP_MWIRE_WAIT_ZERO,
175 .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
176 .cs_control = phy3250_spi_cs_set,
177};
178
179static struct pl022_ssp_controller lpc32xx_ssp0_data = {
180 .bus_id = 0,
181 .num_chipselect = 1,
182 .enable_dma = 0,
183};
184
f5c42271
RS
185static struct pl022_ssp_controller lpc32xx_ssp1_data = {
186 .bus_id = 1,
187 .num_chipselect = 1,
188 .enable_dma = 0,
189};
19d95e1a
KW
190
191/* AT25 driver registration */
192static int __init phy3250_spi_board_register(void)
193{
194#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
195 static struct spi_board_info info[] = {
196 {
197 .modalias = "spidev",
198 .max_speed_hz = 5000000,
199 .bus_num = 0,
200 .chip_select = 0,
201 .controller_data = &spi0_chip_info,
202 },
203 };
204
205#else
206 static struct spi_eeprom eeprom = {
207 .name = "at25256a",
208 .byte_len = 0x8000,
209 .page_size = 64,
210 .flags = EE_ADDR2,
211 };
212
213 static struct spi_board_info info[] = {
214 {
215 .modalias = "at25",
216 .max_speed_hz = 5000000,
217 .bus_num = 0,
218 .chip_select = 0,
bde435a9 219 .mode = SPI_MODE_0,
19d95e1a
KW
220 .platform_data = &eeprom,
221 .controller_data = &spi0_chip_info,
222 },
223 };
224#endif
225 return spi_register_board_info(info, ARRAY_SIZE(info));
226}
227arch_initcall(phy3250_spi_board_register);
228
f5c42271 229static struct pl08x_platform_data pl08x_pd = {
19d95e1a
KW
230};
231
f5c42271
RS
232static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = {
233 OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", &lpc32xx_ssp0_data),
234 OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", &lpc32xx_ssp1_data),
235 OF_DEV_AUXDATA("arm,pl110", 0x31040000, "dev:clcd", &lpc32xx_clcd_data),
236 OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd),
237 { }
19d95e1a
KW
238};
239
f5c42271 240static void __init lpc3250_machine_init(void)
19d95e1a
KW
241{
242 u32 tmp;
19d95e1a 243
19d95e1a
KW
244 /* Setup LCD muxing to RGB565 */
245 tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) &
246 ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK |
247 LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK);
248 tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16;
249 __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL);
250
f5c42271
RS
251 /* Set up USB power */
252 tmp = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
253 tmp |= LPC32XX_CLKPWR_USBCTRL_HCLK_EN |
254 LPC32XX_CLKPWR_USBCTRL_USBI2C_EN;
255 __raw_writel(tmp, LPC32XX_CLKPWR_USB_CTRL);
256
19d95e1a
KW
257 /* Set up I2C pull levels */
258 tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
259 tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE |
260 LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE;
261 __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
262
263 /* Disable IrDA pulsing support on UART6 */
264 tmp = __raw_readl(LPC32XX_UARTCTL_CTRL);
265 tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS;
266 __raw_writel(tmp, LPC32XX_UARTCTL_CTRL);
267
268 /* Enable DMA for I2S1 channel */
269 tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL);
270 tmp = LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA;
271 __raw_writel(tmp, LPC32XX_CLKPWR_I2S_CLK_CTRL);
272
273 lpc32xx_serial_init();
274
275 /*
276 * AMBA peripheral clocks need to be enabled prior to AMBA device
277 * detection or a data fault will occur, so enable the clocks
f5c42271 278 * here.
19d95e1a 279 */
19d95e1a
KW
280 tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
281 __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN),
282 LPC32XX_CLKPWR_LCDCLK_CTRL);
f5c42271 283
19d95e1a
KW
284 tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL);
285 __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN),
286 LPC32XX_CLKPWR_SSP_CLK_CTRL);
19d95e1a 287
f5c42271
RS
288 tmp = __raw_readl(LPC32XX_CLKPWR_DMA_CLK_CTRL);
289 __raw_writel((tmp | LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN),
290 LPC32XX_CLKPWR_DMA_CLK_CTRL);
19d95e1a
KW
291
292 /* Test clock needed for UDA1380 initial init */
293 __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC |
294 LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN,
295 LPC32XX_CLKPWR_TEST_CLK_SEL);
296
f5c42271
RS
297 of_platform_populate(NULL, of_default_bus_match_table,
298 lpc32xx_auxdata_lookup, NULL);
299
300 /* Register GPIOs used on this board */
301 if (gpio_request(SPI0_CS_GPIO, "spi0 cs"))
302 printk(KERN_ERR "Error requesting gpio %u",
303 SPI0_CS_GPIO);
304 else if (gpio_direction_output(SPI0_CS_GPIO, 1))
305 printk(KERN_ERR "Error setting gpio %u to output",
306 SPI0_CS_GPIO);
19d95e1a
KW
307}
308
f5c42271
RS
309static char const *lpc32xx_dt_compat[] __initdata = {
310 "nxp,lpc3220",
311 "nxp,lpc3230",
312 "nxp,lpc3240",
313 "nxp,lpc3250",
314 NULL
315};
316
317DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
bdec5ddd 318 .atag_offset = 0x100,
19d95e1a
KW
319 .map_io = lpc32xx_map_io,
320 .init_irq = lpc32xx_init_irq,
321 .timer = &lpc32xx_timer,
f5c42271
RS
322 .init_machine = lpc3250_machine_init,
323 .dt_compat = lpc32xx_dt_compat,
b23fcd90 324 .restart = lpc23xx_restart,
19d95e1a 325MACHINE_END
This page took 0.129357 seconds and 5 git commands to generate.