1/* 2 * Author: MontaVista Software, Inc. 3 * <source@mvista.com> 4 * 5 * Based on the OMAP devices.c 6 * 7 * 2005 (c) MontaVista Software, Inc. This file is licensed under the 8 * terms of the GNU General Public License version 2. This program is 9 * licensed "as is" without any warranty of any kind, whether express 10 * or implied. 11 * 12 * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. 13 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 14 * Copyright 2008 Sascha Hauer, kernel@pengutronix.de 15 * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> 16 * Copyright (c) 2008 Darius Augulis <darius.augulis@teltonika.lt> 17 * 18 * This program is free software; you can redistribute it and/or 19 * modify it under the terms of the GNU General Public License 20 * as published by the Free Software Foundation; either version 2 21 * of the License, or (at your option) any later version. 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 30 * MA 02110-1301, USA. 31 */ 32#include <linux/module.h> 33#include <linux/kernel.h> 34#include <linux/init.h> 35#include <linux/platform_device.h> 36#include <linux/gpio.h> 37#include <linux/dma-mapping.h> 38#include <linux/serial.h> 39 40#include <mach/irqs.h> 41#include <mach/hardware.h> 42#include <mach/common.h> 43#include <mach/mmc.h> 44 45#include "devices.h" 46 47#if defined(CONFIG_ARCH_MX1) 48static struct resource imx1_camera_resources[] = { 49 { 50 .start = 0x00224000, 51 .end = 0x00224010, 52 .flags = IORESOURCE_MEM, 53 }, { 54 .start = MX1_CSI_INT, 55 .end = MX1_CSI_INT, 56 .flags = IORESOURCE_IRQ, 57 }, 58}; 59 60static u64 imx1_camera_dmamask = DMA_BIT_MASK(32); 61 62struct platform_device imx1_camera_device = { 63 .name = "mx1-camera", 64 .id = 0, /* This is used to put cameras on this interface */ 65 .dev = { 66 .dma_mask = &imx1_camera_dmamask, 67 .coherent_dma_mask = DMA_BIT_MASK(32), 68 }, 69 .resource = imx1_camera_resources, 70 .num_resources = ARRAY_SIZE(imx1_camera_resources), 71}; 72 73static struct resource imx_rtc_resources[] = { 74 { 75 .start = 0x00204000, 76 .end = 0x00204024, 77 .flags = IORESOURCE_MEM, 78 }, { 79 .start = MX1_RTC_INT, 80 .end = MX1_RTC_INT, 81 .flags = IORESOURCE_IRQ, 82 }, { 83 .start = MX1_RTC_SAMINT, 84 .end = MX1_RTC_SAMINT, 85 .flags = IORESOURCE_IRQ, 86 }, 87}; 88 89struct platform_device imx_rtc_device = { 90 .name = "rtc-imx", 91 .id = 0, 92 .resource = imx_rtc_resources, 93 .num_resources = ARRAY_SIZE(imx_rtc_resources), 94}; 95 96static struct resource imx_wdt_resources[] = { 97 { 98 .start = 0x00201000, 99 .end = 0x00201008, 100 .flags = IORESOURCE_MEM, 101 }, { 102 .start = MX1_WDT_INT, 103 .end = MX1_WDT_INT, 104 .flags = IORESOURCE_IRQ, 105 }, 106}; 107 108struct platform_device imx_wdt_device = { 109 .name = "imx-wdt", 110 .id = 0, 111 .resource = imx_wdt_resources, 112 .num_resources = ARRAY_SIZE(imx_wdt_resources), 113}; 114 115static struct resource imx_usb_resources[] = { 116 { 117 .start = 0x00212000, 118 .end = 0x00212148, 119 .flags = IORESOURCE_MEM, 120 }, { 121 .start = MX1_USBD_INT0, 122 .end = MX1_USBD_INT0, 123 .flags = IORESOURCE_IRQ, 124 }, { 125 .start = MX1_USBD_INT1, 126 .end = MX1_USBD_INT1, 127 .flags = IORESOURCE_IRQ, 128 }, { 129 .start = MX1_USBD_INT2, 130 .end = MX1_USBD_INT2, 131 .flags = IORESOURCE_IRQ, 132 }, { 133 .start = MX1_USBD_INT3, 134 .end = MX1_USBD_INT3, 135 .flags = IORESOURCE_IRQ, 136 }, { 137 .start = MX1_USBD_INT4, 138 .end = MX1_USBD_INT4, 139 .flags = IORESOURCE_IRQ, 140 }, { 141 .start = MX1_USBD_INT5, 142 .end = MX1_USBD_INT5, 143 .flags = IORESOURCE_IRQ, 144 }, { 145 .start = MX1_USBD_INT6, 146 .end = MX1_USBD_INT6, 147 .flags = IORESOURCE_IRQ, 148 }, 149}; 150 151struct platform_device imx_usb_device = { 152 .name = "imx_udc", 153 .id = 0, 154 .num_resources = ARRAY_SIZE(imx_usb_resources), 155 .resource = imx_usb_resources, 156}; 157 158/* GPIO port description */ 159static struct mxc_gpio_port imx_gpio_ports[] = { 160 { 161 .chip.label = "gpio-0", 162 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR), 163 .irq = MX1_GPIO_INT_PORTA, 164 .virtual_irq_start = MXC_GPIO_IRQ_START, 165 }, { 166 .chip.label = "gpio-1", 167 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x100), 168 .irq = MX1_GPIO_INT_PORTB, 169 .virtual_irq_start = MXC_GPIO_IRQ_START + 32, 170 }, { 171 .chip.label = "gpio-2", 172 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x200), 173 .irq = MX1_GPIO_INT_PORTC, 174 .virtual_irq_start = MXC_GPIO_IRQ_START + 64, 175 }, { 176 .chip.label = "gpio-3", 177 .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x300), 178 .irq = MX1_GPIO_INT_PORTD, 179 .virtual_irq_start = MXC_GPIO_IRQ_START + 96, 180 } 181}; 182 183int __init imx1_register_gpios(void) 184{ 185 return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); 186} 187#endif 188 189#if defined(CONFIG_MACH_MX21) || defined(CONFIG_MACH_MX27) 190 191#ifdef CONFIG_MACH_MX27 192static struct resource mx27_camera_resources[] = { 193 { 194 .start = MX27_CSI_BASE_ADDR, 195 .end = MX27_CSI_BASE_ADDR + 0x1f, 196 .flags = IORESOURCE_MEM, 197 }, { 198 .start = MX27_EMMA_PRP_BASE_ADDR, 199 .end = MX27_EMMA_PRP_BASE_ADDR + 0x1f, 200 .flags = IORESOURCE_MEM, 201 }, { 202 .start = MX27_INT_CSI, 203 .end = MX27_INT_CSI, 204 .flags = IORESOURCE_IRQ, 205 },{ 206 .start = MX27_INT_EMMAPRP, 207 .end = MX27_INT_EMMAPRP, 208 .flags = IORESOURCE_IRQ, 209 }, 210}; 211struct platform_device mx27_camera_device = { 212 .name = "mx2-camera", 213 .id = 0, 214 .num_resources = ARRAY_SIZE(mx27_camera_resources), 215 .resource = mx27_camera_resources, 216 .dev = { 217 .coherent_dma_mask = 0xffffffff, 218 }, 219}; 220#endif 221 222/* 223 * General Purpose Timer 224 * - i.MX21: 3 timers 225 * - i.MX27: 6 timers 226 */ 227#define DEFINE_IMX_GPT_DEVICE(n, baseaddr, irq) \ 228 static struct resource timer ## n ##_resources[] = { \ 229 { \ 230 .start = baseaddr, \ 231 .end = baseaddr + SZ_4K - 1, \ 232 .flags = IORESOURCE_MEM, \ 233 }, { \ 234 .start = irq, \ 235 .end = irq, \ 236 .flags = IORESOURCE_IRQ, \ 237 } \ 238 }; \ 239 \ 240 struct platform_device mxc_gpt ## n = { \ 241 .name = "imx_gpt", \ 242 .id = n, \ 243 .num_resources = ARRAY_SIZE(timer ## n ## _resources), \ 244 .resource = timer ## n ## _resources, \ 245 } 246 247/* We use gpt1 as system timer, so do not add a device for this one */ 248DEFINE_IMX_GPT_DEVICE(1, MX2x_GPT2_BASE_ADDR, MX2x_INT_GPT2); 249DEFINE_IMX_GPT_DEVICE(2, MX2x_GPT3_BASE_ADDR, MX2x_INT_GPT3); 250 251#ifdef CONFIG_MACH_MX27 252DEFINE_IMX_GPT_DEVICE(3, MX27_GPT4_BASE_ADDR, MX27_INT_GPT4); 253DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5); 254DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6); 255#endif 256 257/* Watchdog: i.MX1 has seperate driver, i.MX21 and i.MX27 are equal */ 258static struct resource mxc_wdt_resources[] = { 259 { 260 .start = MX2x_WDOG_BASE_ADDR, 261 .end = MX2x_WDOG_BASE_ADDR + SZ_4K - 1, 262 .flags = IORESOURCE_MEM, 263 }, 264}; 265 266struct platform_device mxc_wdt = { 267 .name = "imx2-wdt", 268 .id = 0, 269 .num_resources = ARRAY_SIZE(mxc_wdt_resources), 270 .resource = mxc_wdt_resources, 271}; 272 273static struct resource mxc_w1_master_resources[] = { 274 { 275 .start = MX2x_OWIRE_BASE_ADDR, 276 .end = MX2x_OWIRE_BASE_ADDR + SZ_4K - 1, 277 .flags = IORESOURCE_MEM, 278 }, 279}; 280 281struct platform_device mxc_w1_master_device = { 282 .name = "mxc_w1", 283 .id = 0, 284 .num_resources = ARRAY_SIZE(mxc_w1_master_resources), 285 .resource = mxc_w1_master_resources, 286}; 287 288/* 289 * lcdc: 290 * - i.MX1: the basic controller 291 * - i.MX21: to be checked 292 * - i.MX27: like i.MX1, with slightly variations 293 */ 294static struct resource mxc_fb[] = { 295 { 296 .start = MX2x_LCDC_BASE_ADDR, 297 .end = MX2x_LCDC_BASE_ADDR + SZ_4K - 1, 298 .flags = IORESOURCE_MEM, 299 }, { 300 .start = MX2x_INT_LCDC, 301 .end = MX2x_INT_LCDC, 302 .flags = IORESOURCE_IRQ, 303 } 304}; 305 306/* mxc lcd driver */ 307struct platform_device mxc_fb_device = { 308 .name = "imx-fb", 309 .id = 0, 310 .num_resources = ARRAY_SIZE(mxc_fb), 311 .resource = mxc_fb, 312 .dev = { 313 .coherent_dma_mask = DMA_BIT_MASK(32), 314 }, 315}; 316 317#ifdef CONFIG_MACH_MX27 318static struct resource mxc_fec_resources[] = { 319 { 320 .start = MX27_FEC_BASE_ADDR, 321 .end = MX27_FEC_BASE_ADDR + SZ_4K - 1, 322 .flags = IORESOURCE_MEM, 323 }, { 324 .start = MX27_INT_FEC, 325 .end = MX27_INT_FEC, 326 .flags = IORESOURCE_IRQ, 327 }, 328}; 329 330struct platform_device mxc_fec_device = { 331 .name = "fec", 332 .id = 0, 333 .num_resources = ARRAY_SIZE(mxc_fec_resources), 334 .resource = mxc_fec_resources, 335}; 336#endif 337 338static struct resource mxc_pwm_resources[] = { 339 { 340 .start = MX2x_PWM_BASE_ADDR, 341 .end = MX2x_PWM_BASE_ADDR + SZ_4K - 1, 342 .flags = IORESOURCE_MEM, 343 }, { 344 .start = MX2x_INT_PWM, 345 .end = MX2x_INT_PWM, 346 .flags = IORESOURCE_IRQ, 347 } 348}; 349 350struct platform_device mxc_pwm_device = { 351 .name = "mxc_pwm", 352 .id = 0, 353 .num_resources = ARRAY_SIZE(mxc_pwm_resources), 354 .resource = mxc_pwm_resources, 355}; 356 357#define DEFINE_MXC_MMC_DEVICE(n, baseaddr, irq, dmareq) \ 358 static struct resource mxc_sdhc_resources ## n[] = { \ 359 { \ 360 .start = baseaddr, \ 361 .end = baseaddr + SZ_4K - 1, \ 362 .flags = IORESOURCE_MEM, \ 363 }, { \ 364 .start = irq, \ 365 .end = irq, \ 366 .flags = IORESOURCE_IRQ, \ 367 }, { \ 368 .start = dmareq, \ 369 .end = dmareq, \ 370 .flags = IORESOURCE_DMA, \ 371 }, \ 372 }; \ 373 \ 374 static u64 mxc_sdhc ## n ## _dmamask = DMA_BIT_MASK(32); \ 375 \ 376 struct platform_device mxc_sdhc_device ## n = { \ 377 .name = "mxc-mmc", \ 378 .id = n, \ 379 .dev = { \ 380 .dma_mask = &mxc_sdhc ## n ## _dmamask, \ 381 .coherent_dma_mask = DMA_BIT_MASK(32), \ 382 }, \ 383 .num_resources = ARRAY_SIZE(mxc_sdhc_resources ## n), \ 384 .resource = mxc_sdhc_resources ## n, \ 385 } 386 387DEFINE_MXC_MMC_DEVICE(0, MX2x_SDHC1_BASE_ADDR, MX2x_INT_SDHC1, MX2x_DMA_REQ_SDHC1); 388DEFINE_MXC_MMC_DEVICE(1, MX2x_SDHC2_BASE_ADDR, MX2x_INT_SDHC2, MX2x_DMA_REQ_SDHC2); 389 390#ifdef CONFIG_MACH_MX27 391static struct resource otg_resources[] = { 392 { 393 .start = MX27_USBOTG_BASE_ADDR, 394 .end = MX27_USBOTG_BASE_ADDR + 0x1ff, 395 .flags = IORESOURCE_MEM, 396 }, { 397 .start = MX27_INT_USB3, 398 .end = MX27_INT_USB3, 399 .flags = IORESOURCE_IRQ, 400 }, 401}; 402 403static u64 otg_dmamask = DMA_BIT_MASK(32); 404 405/* OTG gadget device */ 406struct platform_device mxc_otg_udc_device = { 407 .name = "fsl-usb2-udc", 408 .id = -1, 409 .dev = { 410 .dma_mask = &otg_dmamask, 411 .coherent_dma_mask = DMA_BIT_MASK(32), 412 }, 413 .resource = otg_resources, 414 .num_resources = ARRAY_SIZE(otg_resources), 415}; 416 417/* OTG host */ 418struct platform_device mxc_otg_host = { 419 .name = "mxc-ehci", 420 .id = 0, 421 .dev = { 422 .coherent_dma_mask = DMA_BIT_MASK(32), 423 .dma_mask = &otg_dmamask, 424 }, 425 .resource = otg_resources, 426 .num_resources = ARRAY_SIZE(otg_resources), 427}; 428 429/* USB host 1 */ 430 431static u64 usbh1_dmamask = DMA_BIT_MASK(32); 432 433static struct resource mxc_usbh1_resources[] = { 434 { 435 .start = MX27_USBOTG_BASE_ADDR + 0x200, 436 .end = MX27_USBOTG_BASE_ADDR + 0x3ff, 437 .flags = IORESOURCE_MEM, 438 }, { 439 .start = MX27_INT_USB1, 440 .end = MX27_INT_USB1, 441 .flags = IORESOURCE_IRQ, 442 }, 443}; 444 445struct platform_device mxc_usbh1 = { 446 .name = "mxc-ehci", 447 .id = 1, 448 .dev = { 449 .coherent_dma_mask = DMA_BIT_MASK(32), 450 .dma_mask = &usbh1_dmamask, 451 }, 452 .resource = mxc_usbh1_resources, 453 .num_resources = ARRAY_SIZE(mxc_usbh1_resources), 454}; 455 456/* USB host 2 */ 457static u64 usbh2_dmamask = DMA_BIT_MASK(32); 458 459static struct resource mxc_usbh2_resources[] = { 460 { 461 .start = MX27_USBOTG_BASE_ADDR + 0x400, 462 .end = MX27_USBOTG_BASE_ADDR + 0x5ff, 463 .flags = IORESOURCE_MEM, 464 }, { 465 .start = MX27_INT_USB2, 466 .end = MX27_INT_USB2, 467 .flags = IORESOURCE_IRQ, 468 }, 469}; 470 471struct platform_device mxc_usbh2 = { 472 .name = "mxc-ehci", 473 .id = 2, 474 .dev = { 475 .coherent_dma_mask = DMA_BIT_MASK(32), 476 .dma_mask = &usbh2_dmamask, 477 }, 478 .resource = mxc_usbh2_resources, 479 .num_resources = ARRAY_SIZE(mxc_usbh2_resources), 480}; 481#endif 482 483#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \ 484 { \ 485 .name = _name, \ 486 .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \ 487 .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \ 488 .flags = IORESOURCE_DMA, \ 489 } 490 491#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \ 492 static struct resource imx_ssi_resources ## n[] = { \ 493 { \ 494 .start = MX2x_SSI ## ssin ## _BASE_ADDR, \ 495 .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \ 496 .flags = IORESOURCE_MEM, \ 497 }, { \ 498 .start = MX2x_INT_SSI1, \ 499 .end = MX2x_INT_SSI1, \ 500 .flags = IORESOURCE_IRQ, \ 501 }, \ 502 DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \ 503 DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \ 504 DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \ 505 DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \ 506 }; \ 507 \ 508 struct platform_device imx_ssi_device ## n = { \ 509 .name = "imx-ssi", \ 510 .id = n, \ 511 .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \ 512 .resource = imx_ssi_resources ## n, \ 513 } 514 515DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1); 516DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1); 517 518/* GPIO port description */ 519#define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \ 520 { \ 521 .chip.label = "gpio-" #n, \ 522 .irq = _irq, \ 523 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \ 524 n * 0x100), \ 525 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \ 526 } 527 528#define DEFINE_MXC_GPIO_PORT(SOC, n) \ 529 { \ 530 .chip.label = "gpio-" #n, \ 531 .base = SOC ## _IO_ADDRESS(MX2x_GPIO_BASE_ADDR + \ 532 n * 0x100), \ 533 .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \ 534 } 535 536#define DEFINE_MXC_GPIO_PORTS(SOC, pfx) \ 537 static struct mxc_gpio_port pfx ## _gpio_ports[] = { \ 538 DEFINE_MXC_GPIO_PORT_IRQ(SOC, 0, SOC ## _INT_GPIO), \ 539 DEFINE_MXC_GPIO_PORT(SOC, 1), \ 540 DEFINE_MXC_GPIO_PORT(SOC, 2), \ 541 DEFINE_MXC_GPIO_PORT(SOC, 3), \ 542 DEFINE_MXC_GPIO_PORT(SOC, 4), \ 543 DEFINE_MXC_GPIO_PORT(SOC, 5), \ 544 } 545 546#ifdef CONFIG_MACH_MX21 547DEFINE_MXC_GPIO_PORTS(MX21, imx21); 548 549int __init imx21_register_gpios(void) 550{ 551 return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports)); 552} 553#endif 554 555#ifdef CONFIG_MACH_MX27 556DEFINE_MXC_GPIO_PORTS(MX27, imx27); 557 558int __init imx27_register_gpios(void) 559{ 560 return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports)); 561} 562#endif 563 564#ifdef CONFIG_MACH_MX21 565static struct resource mx21_usbhc_resources[] = { 566 { 567 .start = MX21_USBOTG_BASE_ADDR, 568 .end = MX21_USBOTG_BASE_ADDR + SZ_8K - 1, 569 .flags = IORESOURCE_MEM, 570 }, 571 { 572 .start = MX21_INT_USBHOST, 573 .end = MX21_INT_USBHOST, 574 .flags = IORESOURCE_IRQ, 575 }, 576}; 577 578struct platform_device mx21_usbhc_device = { 579 .name = "imx21-hcd", 580 .id = 0, 581 .dev = { 582 .dma_mask = &mx21_usbhc_device.dev.coherent_dma_mask, 583 .coherent_dma_mask = DMA_BIT_MASK(32), 584 }, 585 .num_resources = ARRAY_SIZE(mx21_usbhc_resources), 586 .resource = mx21_usbhc_resources, 587}; 588#endif 589 590static struct resource imx_kpp_resources[] = { 591 { 592 .start = MX2x_KPP_BASE_ADDR, 593 .end = MX2x_KPP_BASE_ADDR + 0xf, 594 .flags = IORESOURCE_MEM 595 }, { 596 .start = MX2x_INT_KPP, 597 .end = MX2x_INT_KPP, 598 .flags = IORESOURCE_IRQ, 599 }, 600}; 601 602struct platform_device imx_kpp_device = { 603 .name = "imx-keypad", 604 .id = -1, 605 .num_resources = ARRAY_SIZE(imx_kpp_resources), 606 .resource = imx_kpp_resources, 607}; 608 609#endif 610