1/* 2 * Copyright (C) 2000 Deep Blue Solutions Ltd 3 * Copyright (C) 2002 Shane Nay (shane@minirl.com) 4 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17#include <linux/platform_device.h> 18#include <linux/mtd/mtd.h> 19#include <linux/mtd/map.h> 20#include <linux/mtd/partitions.h> 21#include <linux/mtd/physmap.h> 22#include <linux/i2c.h> 23#include <linux/irq.h> 24#include <mach/common.h> 25#include <mach/hardware.h> 26#include <asm/mach-types.h> 27#include <asm/mach/arch.h> 28#include <asm/mach/time.h> 29#include <asm/mach/map.h> 30#include <mach/gpio.h> 31#include <mach/iomux-mx27.h> 32#include <mach/mxc_nand.h> 33#include <mach/imxfb.h> 34#include <mach/mmc.h> 35 36#include "devices-imx27.h" 37#include "devices.h" 38 39/* 40 * Base address of PBC controller, CS4 41 */ 42#define PBC_BASE_ADDRESS 0xf4300000 43#define PBC_REG_ADDR(offset) (void __force __iomem *) \ 44 (PBC_BASE_ADDRESS + (offset)) 45 46/* When the PBC address connection is fixed in h/w, defined as 1 */ 47#define PBC_ADDR_SH 0 48 49/* Offsets for the PBC Controller register */ 50/* 51 * PBC Board version register offset 52 */ 53#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH) 54/* 55 * PBC Board control register 1 set address. 56 */ 57#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH) 58/* 59 * PBC Board control register 1 clear address. 60 */ 61#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH) 62 63/* PBC Board Control Register 1 bit definitions */ 64#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */ 65 66/* to determine the correct external crystal reference */ 67#define CKIH_27MHZ_BIT_SET (1 << 3) 68 69static unsigned int mx27ads_pins[] = { 70 /* UART0 */ 71 PE12_PF_UART1_TXD, 72 PE13_PF_UART1_RXD, 73 PE14_PF_UART1_CTS, 74 PE15_PF_UART1_RTS, 75 /* UART1 */ 76 PE3_PF_UART2_CTS, 77 PE4_PF_UART2_RTS, 78 PE6_PF_UART2_TXD, 79 PE7_PF_UART2_RXD, 80 /* UART2 */ 81 PE8_PF_UART3_TXD, 82 PE9_PF_UART3_RXD, 83 PE10_PF_UART3_CTS, 84 PE11_PF_UART3_RTS, 85 /* UART3 */ 86 PB26_AF_UART4_RTS, 87 PB28_AF_UART4_TXD, 88 PB29_AF_UART4_CTS, 89 PB31_AF_UART4_RXD, 90 /* UART4 */ 91 PB18_AF_UART5_TXD, 92 PB19_AF_UART5_RXD, 93 PB20_AF_UART5_CTS, 94 PB21_AF_UART5_RTS, 95 /* UART5 */ 96 PB10_AF_UART6_TXD, 97 PB12_AF_UART6_CTS, 98 PB11_AF_UART6_RXD, 99 PB13_AF_UART6_RTS, 100 /* FEC */ 101 PD0_AIN_FEC_TXD0, 102 PD1_AIN_FEC_TXD1, 103 PD2_AIN_FEC_TXD2, 104 PD3_AIN_FEC_TXD3, 105 PD4_AOUT_FEC_RX_ER, 106 PD5_AOUT_FEC_RXD1, 107 PD6_AOUT_FEC_RXD2, 108 PD7_AOUT_FEC_RXD3, 109 PD8_AF_FEC_MDIO, 110 PD9_AIN_FEC_MDC, 111 PD10_AOUT_FEC_CRS, 112 PD11_AOUT_FEC_TX_CLK, 113 PD12_AOUT_FEC_RXD0, 114 PD13_AOUT_FEC_RX_DV, 115 PD14_AOUT_FEC_RX_CLK, 116 PD15_AOUT_FEC_COL, 117 PD16_AIN_FEC_TX_ER, 118 PF23_AIN_FEC_TX_EN, 119 /* I2C2 */ 120 PC5_PF_I2C2_SDA, 121 PC6_PF_I2C2_SCL, 122 /* FB */ 123 PA5_PF_LSCLK, 124 PA6_PF_LD0, 125 PA7_PF_LD1, 126 PA8_PF_LD2, 127 PA9_PF_LD3, 128 PA10_PF_LD4, 129 PA11_PF_LD5, 130 PA12_PF_LD6, 131 PA13_PF_LD7, 132 PA14_PF_LD8, 133 PA15_PF_LD9, 134 PA16_PF_LD10, 135 PA17_PF_LD11, 136 PA18_PF_LD12, 137 PA19_PF_LD13, 138 PA20_PF_LD14, 139 PA21_PF_LD15, 140 PA22_PF_LD16, 141 PA23_PF_LD17, 142 PA24_PF_REV, 143 PA25_PF_CLS, 144 PA26_PF_PS, 145 PA27_PF_SPL_SPR, 146 PA28_PF_HSYNC, 147 PA29_PF_VSYNC, 148 PA30_PF_CONTRAST, 149 PA31_PF_OE_ACD, 150 /* OWIRE */ 151 PE16_AF_OWIRE, 152 /* SDHC1*/ 153 PE18_PF_SD1_D0, 154 PE19_PF_SD1_D1, 155 PE20_PF_SD1_D2, 156 PE21_PF_SD1_D3, 157 PE22_PF_SD1_CMD, 158 PE23_PF_SD1_CLK, 159 /* SDHC2*/ 160 PB4_PF_SD2_D0, 161 PB5_PF_SD2_D1, 162 PB6_PF_SD2_D2, 163 PB7_PF_SD2_D3, 164 PB8_PF_SD2_CMD, 165 PB9_PF_SD2_CLK, 166}; 167 168static const struct mxc_nand_platform_data 169mx27ads_nand_board_info __initconst = { 170 .width = 1, 171 .hw_ecc = 1, 172}; 173 174/* ADS's NOR flash */ 175static struct physmap_flash_data mx27ads_flash_data = { 176 .width = 2, 177}; 178 179static struct resource mx27ads_flash_resource = { 180 .start = 0xc0000000, 181 .end = 0xc0000000 + 0x02000000 - 1, 182 .flags = IORESOURCE_MEM, 183 184}; 185 186static struct platform_device mx27ads_nor_mtd_device = { 187 .name = "physmap-flash", 188 .id = 0, 189 .dev = { 190 .platform_data = &mx27ads_flash_data, 191 }, 192 .num_resources = 1, 193 .resource = &mx27ads_flash_resource, 194}; 195 196static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = { 197 .bitrate = 100000, 198}; 199 200static struct i2c_board_info mx27ads_i2c_devices[] = { 201}; 202 203void lcd_power(int on) 204{ 205 if (on) 206 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); 207 else 208 __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); 209} 210 211static struct imx_fb_videomode mx27ads_modes[] = { 212 { 213 .mode = { 214 .name = "Sharp-LQ035Q7", 215 .refresh = 60, 216 .xres = 240, 217 .yres = 320, 218 .pixclock = 188679, /* in ps (5.3MHz) */ 219 .hsync_len = 1, 220 .left_margin = 9, 221 .right_margin = 16, 222 .vsync_len = 1, 223 .upper_margin = 7, 224 .lower_margin = 9, 225 }, 226 .bpp = 16, 227 .pcr = 0xFB008BC0, 228 }, 229}; 230 231static struct imx_fb_platform_data mx27ads_fb_data = { 232 .mode = mx27ads_modes, 233 .num_modes = ARRAY_SIZE(mx27ads_modes), 234 235 /* 236 * - HSYNC active high 237 * - VSYNC active high 238 * - clk notenabled while idle 239 * - clock inverted 240 * - data not inverted 241 * - data enable low active 242 * - enable sharp mode 243 */ 244 .pwmr = 0x00A903FF, 245 .lscr1 = 0x00120300, 246 .dmacr = 0x00020010, 247 248 .lcd_power = lcd_power, 249}; 250 251static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq, 252 void *data) 253{ 254 return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING, 255 "sdhc1-card-detect", data); 256} 257 258static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq, 259 void *data) 260{ 261 return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING, 262 "sdhc2-card-detect", data); 263} 264 265static void mx27ads_sdhc1_exit(struct device *dev, void *data) 266{ 267 free_irq(IRQ_GPIOE(21), data); 268} 269 270static void mx27ads_sdhc2_exit(struct device *dev, void *data) 271{ 272 free_irq(IRQ_GPIOB(7), data); 273} 274 275static struct imxmmc_platform_data sdhc1_pdata = { 276 .init = mx27ads_sdhc1_init, 277 .exit = mx27ads_sdhc1_exit, 278}; 279 280static struct imxmmc_platform_data sdhc2_pdata = { 281 .init = mx27ads_sdhc2_init, 282 .exit = mx27ads_sdhc2_exit, 283}; 284 285static struct platform_device *platform_devices[] __initdata = { 286 &mx27ads_nor_mtd_device, 287 &mxc_fec_device, 288 &mxc_w1_master_device, 289}; 290 291static const struct imxuart_platform_data uart_pdata __initconst = { 292 .flags = IMXUART_HAVE_RTSCTS, 293}; 294 295static void __init mx27ads_board_init(void) 296{ 297 mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins), 298 "mx27ads"); 299 300 imx27_add_imx_uart0(&uart_pdata); 301 imx27_add_imx_uart1(&uart_pdata); 302 imx27_add_imx_uart2(&uart_pdata); 303 imx27_add_imx_uart3(&uart_pdata); 304 imx27_add_imx_uart4(&uart_pdata); 305 imx27_add_imx_uart5(&uart_pdata); 306 imx27_add_mxc_nand(&mx27ads_nand_board_info); 307 308 /* only the i2c master 1 is used on this CPU card */ 309 i2c_register_board_info(1, mx27ads_i2c_devices, 310 ARRAY_SIZE(mx27ads_i2c_devices)); 311 imx27_add_i2c_imx1(&mx27ads_i2c1_data); 312 mxc_register_device(&mxc_fb_device, &mx27ads_fb_data); 313 mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata); 314 mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata); 315 316 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); 317} 318 319static void __init mx27ads_timer_init(void) 320{ 321 unsigned long fref = 26000000; 322 323 if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) 324 fref = 27000000; 325 326 mx27_clocks_init(fref); 327} 328 329static struct sys_timer mx27ads_timer = { 330 .init = mx27ads_timer_init, 331}; 332 333static struct map_desc mx27ads_io_desc[] __initdata = { 334 { 335 .virtual = PBC_BASE_ADDRESS, 336 .pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR), 337 .length = SZ_1M, 338 .type = MT_DEVICE, 339 }, 340}; 341 342static void __init mx27ads_map_io(void) 343{ 344 mx27_map_io(); 345 iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc)); 346} 347 348MACHINE_START(MX27ADS, "Freescale i.MX27ADS") 349 /* maintainer: Freescale Semiconductor, Inc. */ 350 .phys_io = MX27_AIPI_BASE_ADDR, 351 .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, 352 .boot_params = MX27_PHYS_OFFSET + 0x100, 353 .map_io = mx27ads_map_io, 354 .init_irq = mx27_init_irq, 355 .init_machine = mx27ads_board_init, 356 .timer = &mx27ads_timer, 357MACHINE_END 358