]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/arm/mach-lpc32xx/phy3250.c
Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux
[mv-sheeva.git] / arch / arm / mach-lpc32xx / phy3250.c
1 /*
2  * arch/arm/mach-lpc32xx/phy3250.c
3  *
4  * Author: Kevin Wells <kevin.wells@nxp.com>
5  *
6  * Copyright (C) 2010 NXP Semiconductors
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 #include <linux/init.h>
20 #include <linux/platform_device.h>
21 #include <linux/sysdev.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/dma-mapping.h>
25 #include <linux/device.h>
26 #include <linux/spi/spi.h>
27 #include <linux/spi/eeprom.h>
28 #include <linux/leds.h>
29 #include <linux/gpio.h>
30 #include <linux/amba/bus.h>
31 #include <linux/amba/clcd.h>
32 #include <linux/amba/pl022.h>
33
34 #include <asm/setup.h>
35 #include <asm/mach-types.h>
36 #include <asm/mach/arch.h>
37
38 #include <mach/hardware.h>
39 #include <mach/platform.h>
40 #include "common.h"
41
42 /*
43  * Mapped GPIOLIB GPIOs
44  */
45 #define SPI0_CS_GPIO    LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
46 #define LCD_POWER_GPIO  LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0)
47 #define BKL_POWER_GPIO  LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4)
48 #define LED_GPIO        LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 1)
49
50 /*
51  * AMBA LCD controller
52  */
53 static struct clcd_panel conn_lcd_panel = {
54         .mode           = {
55                 .name           = "QVGA portrait",
56                 .refresh        = 60,
57                 .xres           = 240,
58                 .yres           = 320,
59                 .pixclock       = 191828,
60                 .left_margin    = 22,
61                 .right_margin   = 11,
62                 .upper_margin   = 2,
63                 .lower_margin   = 1,
64                 .hsync_len      = 5,
65                 .vsync_len      = 2,
66                 .sync           = 0,
67                 .vmode          = FB_VMODE_NONINTERLACED,
68         },
69         .width          = -1,
70         .height         = -1,
71         .tim2           = (TIM2_IVS | TIM2_IHS),
72         .cntl           = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) |
73                                 CNTL_LCDBPP16_565),
74         .bpp            = 16,
75 };
76 #define PANEL_SIZE (3 * SZ_64K)
77
78 static int lpc32xx_clcd_setup(struct clcd_fb *fb)
79 {
80         dma_addr_t dma;
81
82         fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev,
83                 PANEL_SIZE, &dma, GFP_KERNEL);
84         if (!fb->fb.screen_base) {
85                 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
86                 return -ENOMEM;
87         }
88
89         fb->fb.fix.smem_start = dma;
90         fb->fb.fix.smem_len = PANEL_SIZE;
91         fb->panel = &conn_lcd_panel;
92
93         if (gpio_request(LCD_POWER_GPIO, "LCD power"))
94                 printk(KERN_ERR "Error requesting gpio %u",
95                         LCD_POWER_GPIO);
96         else if (gpio_direction_output(LCD_POWER_GPIO, 1))
97                 printk(KERN_ERR "Error setting gpio %u to output",
98                         LCD_POWER_GPIO);
99
100         if (gpio_request(BKL_POWER_GPIO, "LCD backlight power"))
101                 printk(KERN_ERR "Error requesting gpio %u",
102                         BKL_POWER_GPIO);
103         else if (gpio_direction_output(BKL_POWER_GPIO, 1))
104                 printk(KERN_ERR "Error setting gpio %u to output",
105                         BKL_POWER_GPIO);
106
107         return 0;
108 }
109
110 static int lpc32xx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
111 {
112         return dma_mmap_writecombine(&fb->dev->dev, vma,
113                 fb->fb.screen_base, fb->fb.fix.smem_start,
114                 fb->fb.fix.smem_len);
115 }
116
117 static void lpc32xx_clcd_remove(struct clcd_fb *fb)
118 {
119         dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
120                 fb->fb.screen_base, fb->fb.fix.smem_start);
121 }
122
123 /*
124  * On some early LCD modules (1307.0), the backlight logic is inverted.
125  * For those board variants, swap the disable and enable states for
126  * BKL_POWER_GPIO.
127 */
128 static void clcd_disable(struct clcd_fb *fb)
129 {
130         gpio_set_value(BKL_POWER_GPIO, 0);
131         gpio_set_value(LCD_POWER_GPIO, 0);
132 }
133
134 static void clcd_enable(struct clcd_fb *fb)
135 {
136         gpio_set_value(BKL_POWER_GPIO, 1);
137         gpio_set_value(LCD_POWER_GPIO, 1);
138 }
139
140 static struct clcd_board lpc32xx_clcd_data = {
141         .name           = "Phytec LCD",
142         .check          = clcdfb_check,
143         .decode         = clcdfb_decode,
144         .disable        = clcd_disable,
145         .enable         = clcd_enable,
146         .setup          = lpc32xx_clcd_setup,
147         .mmap           = lpc32xx_clcd_mmap,
148         .remove         = lpc32xx_clcd_remove,
149 };
150
151 static struct amba_device lpc32xx_clcd_device = {
152         .dev                            = {
153                 .coherent_dma_mask      = ~0,
154                 .init_name              = "dev:clcd",
155                 .platform_data          = &lpc32xx_clcd_data,
156         },
157         .res                            = {
158                 .start                  = LPC32XX_LCD_BASE,
159                 .end                    = (LPC32XX_LCD_BASE + SZ_4K - 1),
160                 .flags                  = IORESOURCE_MEM,
161         },
162         .dma_mask                       = ~0,
163         .irq                            = {IRQ_LPC32XX_LCD, NO_IRQ},
164 };
165
166 /*
167  * AMBA SSP (SPI)
168  */
169 static void phy3250_spi_cs_set(u32 control)
170 {
171         gpio_set_value(SPI0_CS_GPIO, (int) control);
172 }
173
174 static struct pl022_config_chip spi0_chip_info = {
175         .com_mode               = INTERRUPT_TRANSFER,
176         .iface                  = SSP_INTERFACE_MOTOROLA_SPI,
177         .hierarchy              = SSP_MASTER,
178         .slave_tx_disable       = 0,
179         .rx_lev_trig            = SSP_RX_4_OR_MORE_ELEM,
180         .tx_lev_trig            = SSP_TX_4_OR_MORE_EMPTY_LOC,
181         .ctrl_len               = SSP_BITS_8,
182         .wait_state             = SSP_MWIRE_WAIT_ZERO,
183         .duplex                 = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
184         .cs_control             = phy3250_spi_cs_set,
185 };
186
187 static struct pl022_ssp_controller lpc32xx_ssp0_data = {
188         .bus_id                 = 0,
189         .num_chipselect         = 1,
190         .enable_dma             = 0,
191 };
192
193 static struct amba_device lpc32xx_ssp0_device = {
194         .dev                            = {
195                 .coherent_dma_mask      = ~0,
196                 .init_name              = "dev:ssp0",
197                 .platform_data          = &lpc32xx_ssp0_data,
198         },
199         .res                            = {
200                 .start                  = LPC32XX_SSP0_BASE,
201                 .end                    = (LPC32XX_SSP0_BASE + SZ_4K - 1),
202                 .flags                  = IORESOURCE_MEM,
203         },
204         .dma_mask                       = ~0,
205         .irq                            = {IRQ_LPC32XX_SSP0, NO_IRQ},
206 };
207
208 /* AT25 driver registration */
209 static int __init phy3250_spi_board_register(void)
210 {
211 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
212         static struct spi_board_info info[] = {
213                 {
214                         .modalias = "spidev",
215                         .max_speed_hz = 5000000,
216                         .bus_num = 0,
217                         .chip_select = 0,
218                         .controller_data = &spi0_chip_info,
219                 },
220         };
221
222 #else
223         static struct spi_eeprom eeprom = {
224                 .name = "at25256a",
225                 .byte_len = 0x8000,
226                 .page_size = 64,
227                 .flags = EE_ADDR2,
228         };
229
230         static struct spi_board_info info[] = {
231                 {
232                         .modalias = "at25",
233                         .max_speed_hz = 5000000,
234                         .bus_num = 0,
235                         .chip_select = 0,
236                         .mode = SPI_MODE_0,
237                         .platform_data = &eeprom,
238                         .controller_data = &spi0_chip_info,
239                 },
240         };
241 #endif
242         return spi_register_board_info(info, ARRAY_SIZE(info));
243 }
244 arch_initcall(phy3250_spi_board_register);
245
246 static struct i2c_board_info __initdata phy3250_i2c_board_info[] = {
247         {
248                 I2C_BOARD_INFO("pcf8563", 0x51),
249         },
250 };
251
252 static struct gpio_led phy_leds[] = {
253         {
254                 .name                   = "led0",
255                 .gpio                   = LED_GPIO,
256                 .active_low             = 1,
257                 .default_trigger        = "heartbeat",
258         },
259 };
260
261 static struct gpio_led_platform_data led_data = {
262         .leds = phy_leds,
263         .num_leds = ARRAY_SIZE(phy_leds),
264 };
265
266 static struct platform_device lpc32xx_gpio_led_device = {
267         .name                   = "leds-gpio",
268         .id                     = -1,
269         .dev.platform_data      = &led_data,
270 };
271
272 static struct platform_device *phy3250_devs[] __initdata = {
273         &lpc32xx_i2c0_device,
274         &lpc32xx_i2c1_device,
275         &lpc32xx_i2c2_device,
276         &lpc32xx_watchdog_device,
277         &lpc32xx_gpio_led_device,
278 };
279
280 static struct amba_device *amba_devs[] __initdata = {
281         &lpc32xx_clcd_device,
282         &lpc32xx_ssp0_device,
283 };
284
285 /*
286  * Board specific functions
287  */
288 static void __init phy3250_board_init(void)
289 {
290         u32 tmp;
291         int i;
292
293         lpc32xx_gpio_init();
294
295         /* Register GPIOs used on this board */
296         if (gpio_request(SPI0_CS_GPIO, "spi0 cs"))
297                 printk(KERN_ERR "Error requesting gpio %u",
298                         SPI0_CS_GPIO);
299         else if (gpio_direction_output(SPI0_CS_GPIO, 1))
300                 printk(KERN_ERR "Error setting gpio %u to output",
301                         SPI0_CS_GPIO);
302
303         /* Setup network interface for RMII mode */
304         tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
305         tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
306         tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
307         __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
308
309         /* Setup SLC NAND controller muxing */
310         __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC,
311                 LPC32XX_CLKPWR_NAND_CLK_CTRL);
312
313         /* Setup LCD muxing to RGB565 */
314         tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) &
315                 ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK |
316                 LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK);
317         tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16;
318         __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL);
319
320         /* Set up I2C pull levels */
321         tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
322         tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE |
323                 LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE;
324         __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
325
326         /* Disable IrDA pulsing support on UART6 */
327         tmp = __raw_readl(LPC32XX_UARTCTL_CTRL);
328         tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS;
329         __raw_writel(tmp, LPC32XX_UARTCTL_CTRL);
330
331         /* Enable DMA for I2S1 channel */
332         tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL);
333         tmp = LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA;
334         __raw_writel(tmp, LPC32XX_CLKPWR_I2S_CLK_CTRL);
335
336         lpc32xx_serial_init();
337
338         /*
339          * AMBA peripheral clocks need to be enabled prior to AMBA device
340          * detection or a data fault will occur, so enable the clocks
341          * here. However, we don't want to enable them if the peripheral
342          * isn't included in the image
343          */
344 #ifdef CONFIG_FB_ARMCLCD
345         tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
346         __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN),
347                 LPC32XX_CLKPWR_LCDCLK_CTRL);
348 #endif
349 #ifdef CONFIG_SPI_PL022
350         tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL);
351         __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN),
352                 LPC32XX_CLKPWR_SSP_CLK_CTRL);
353 #endif
354
355         platform_add_devices(phy3250_devs, ARRAY_SIZE(phy3250_devs));
356         for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
357                 struct amba_device *d = amba_devs[i];
358                 amba_device_register(d, &iomem_resource);
359         }
360
361         /* Test clock needed for UDA1380 initial init */
362         __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC |
363                 LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN,
364                 LPC32XX_CLKPWR_TEST_CLK_SEL);
365
366         i2c_register_board_info(0, phy3250_i2c_board_info,
367                 ARRAY_SIZE(phy3250_i2c_board_info));
368 }
369
370 static int __init lpc32xx_display_uid(void)
371 {
372         u32 uid[4];
373
374         lpc32xx_get_uid(uid);
375
376         printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n",
377                 uid[3], uid[2], uid[1], uid[0]);
378
379         return 1;
380 }
381 arch_initcall(lpc32xx_display_uid);
382
383 MACHINE_START(PHY3250, "Phytec 3250 board with the LPC3250 Microcontroller")
384         /* Maintainer: Kevin Wells, NXP Semiconductors */
385         .boot_params    = 0x80000100,
386         .map_io         = lpc32xx_map_io,
387         .init_irq       = lpc32xx_init_irq,
388         .timer          = &lpc32xx_timer,
389         .init_machine   = phy3250_board_init,
390 MACHINE_END