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