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