linux/arch/arm/mach-imx/mach-mx27ads.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  Copyright (C) 2000 Deep Blue Solutions Ltd
   4 *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
   5 *  Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
   6 */
   7#include <linux/gpio/driver.h>
   8/* Needed for gpio_to_irq() */
   9#include <linux/gpio.h>
  10#include <linux/gpio/machine.h>
  11#include <linux/platform_device.h>
  12#include <linux/mtd/mtd.h>
  13#include <linux/mtd/map.h>
  14#include <linux/mtd/partitions.h>
  15#include <linux/mtd/physmap.h>
  16#include <linux/i2c.h>
  17#include <linux/irq.h>
  18
  19#include <linux/regulator/fixed.h>
  20#include <linux/regulator/machine.h>
  21
  22#include <asm/mach-types.h>
  23#include <asm/mach/arch.h>
  24#include <asm/mach/time.h>
  25#include <asm/mach/map.h>
  26
  27#include "common.h"
  28#include "devices-imx27.h"
  29#include "hardware.h"
  30#include "iomux-mx27.h"
  31
  32/*
  33 * Base address of PBC controller, CS4
  34 */
  35#define PBC_BASE_ADDRESS        0xf4300000
  36#define PBC_REG_ADDR(offset)    (void __force __iomem *) \
  37                (PBC_BASE_ADDRESS + (offset))
  38
  39/* When the PBC address connection is fixed in h/w, defined as 1 */
  40#define PBC_ADDR_SH             0
  41
  42/* Offsets for the PBC Controller register */
  43/*
  44 * PBC Board version register offset
  45 */
  46#define PBC_VERSION_REG         PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH)
  47/*
  48 * PBC Board control register 1 set address.
  49 */
  50#define PBC_BCTRL1_SET_REG      PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH)
  51/*
  52 * PBC Board control register 1 clear address.
  53 */
  54#define PBC_BCTRL1_CLEAR_REG    PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH)
  55
  56/* PBC Board Control Register 1 bit definitions */
  57#define PBC_BCTRL1_LCDON        0x0800  /* Enable the LCD */
  58
  59/* to determine the correct external crystal reference */
  60#define CKIH_27MHZ_BIT_SET      (1 << 3)
  61
  62static const int mx27ads_pins[] __initconst = {
  63        /* UART0 */
  64        PE12_PF_UART1_TXD,
  65        PE13_PF_UART1_RXD,
  66        PE14_PF_UART1_CTS,
  67        PE15_PF_UART1_RTS,
  68        /* UART1 */
  69        PE3_PF_UART2_CTS,
  70        PE4_PF_UART2_RTS,
  71        PE6_PF_UART2_TXD,
  72        PE7_PF_UART2_RXD,
  73        /* UART2 */
  74        PE8_PF_UART3_TXD,
  75        PE9_PF_UART3_RXD,
  76        PE10_PF_UART3_CTS,
  77        PE11_PF_UART3_RTS,
  78        /* UART3 */
  79        PB26_AF_UART4_RTS,
  80        PB28_AF_UART4_TXD,
  81        PB29_AF_UART4_CTS,
  82        PB31_AF_UART4_RXD,
  83        /* UART4 */
  84        PB18_AF_UART5_TXD,
  85        PB19_AF_UART5_RXD,
  86        PB20_AF_UART5_CTS,
  87        PB21_AF_UART5_RTS,
  88        /* UART5 */
  89        PB10_AF_UART6_TXD,
  90        PB12_AF_UART6_CTS,
  91        PB11_AF_UART6_RXD,
  92        PB13_AF_UART6_RTS,
  93        /* FEC */
  94        PD0_AIN_FEC_TXD0,
  95        PD1_AIN_FEC_TXD1,
  96        PD2_AIN_FEC_TXD2,
  97        PD3_AIN_FEC_TXD3,
  98        PD4_AOUT_FEC_RX_ER,
  99        PD5_AOUT_FEC_RXD1,
 100        PD6_AOUT_FEC_RXD2,
 101        PD7_AOUT_FEC_RXD3,
 102        PD8_AF_FEC_MDIO,
 103        PD9_AIN_FEC_MDC,
 104        PD10_AOUT_FEC_CRS,
 105        PD11_AOUT_FEC_TX_CLK,
 106        PD12_AOUT_FEC_RXD0,
 107        PD13_AOUT_FEC_RX_DV,
 108        PD14_AOUT_FEC_RX_CLK,
 109        PD15_AOUT_FEC_COL,
 110        PD16_AIN_FEC_TX_ER,
 111        PF23_AIN_FEC_TX_EN,
 112        /* I2C2 */
 113        PC5_PF_I2C2_SDA,
 114        PC6_PF_I2C2_SCL,
 115        /* FB */
 116        PA5_PF_LSCLK,
 117        PA6_PF_LD0,
 118        PA7_PF_LD1,
 119        PA8_PF_LD2,
 120        PA9_PF_LD3,
 121        PA10_PF_LD4,
 122        PA11_PF_LD5,
 123        PA12_PF_LD6,
 124        PA13_PF_LD7,
 125        PA14_PF_LD8,
 126        PA15_PF_LD9,
 127        PA16_PF_LD10,
 128        PA17_PF_LD11,
 129        PA18_PF_LD12,
 130        PA19_PF_LD13,
 131        PA20_PF_LD14,
 132        PA21_PF_LD15,
 133        PA22_PF_LD16,
 134        PA23_PF_LD17,
 135        PA24_PF_REV,
 136        PA25_PF_CLS,
 137        PA26_PF_PS,
 138        PA27_PF_SPL_SPR,
 139        PA28_PF_HSYNC,
 140        PA29_PF_VSYNC,
 141        PA30_PF_CONTRAST,
 142        PA31_PF_OE_ACD,
 143        /* OWIRE */
 144        PE16_AF_OWIRE,
 145        /* SDHC1*/
 146        PE18_PF_SD1_D0,
 147        PE19_PF_SD1_D1,
 148        PE20_PF_SD1_D2,
 149        PE21_PF_SD1_D3,
 150        PE22_PF_SD1_CMD,
 151        PE23_PF_SD1_CLK,
 152        /* SDHC2*/
 153        PB4_PF_SD2_D0,
 154        PB5_PF_SD2_D1,
 155        PB6_PF_SD2_D2,
 156        PB7_PF_SD2_D3,
 157        PB8_PF_SD2_CMD,
 158        PB9_PF_SD2_CLK,
 159};
 160
 161static const struct mxc_nand_platform_data
 162mx27ads_nand_board_info __initconst = {
 163        .width = 1,
 164        .hw_ecc = 1,
 165};
 166
 167/* ADS's NOR flash */
 168static struct physmap_flash_data mx27ads_flash_data = {
 169        .width = 2,
 170};
 171
 172static struct resource mx27ads_flash_resource = {
 173        .start = 0xc0000000,
 174        .end = 0xc0000000 + 0x02000000 - 1,
 175        .flags = IORESOURCE_MEM,
 176
 177};
 178
 179static struct platform_device mx27ads_nor_mtd_device = {
 180        .name = "physmap-flash",
 181        .id = 0,
 182        .dev = {
 183                .platform_data = &mx27ads_flash_data,
 184        },
 185        .num_resources = 1,
 186        .resource = &mx27ads_flash_resource,
 187};
 188
 189static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = {
 190        .bitrate = 100000,
 191};
 192
 193static struct i2c_board_info mx27ads_i2c_devices[] = {
 194};
 195
 196static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value)
 197{
 198        if (value)
 199                imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
 200        else
 201                imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
 202}
 203
 204static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
 205{
 206        return 0;
 207}
 208
 209#define MX27ADS_LCD_GPIO        (6 * 32)
 210
 211static struct regulator_consumer_supply mx27ads_lcd_regulator_consumer =
 212        REGULATOR_SUPPLY("lcd", "imx-fb.0");
 213
 214static struct regulator_init_data mx27ads_lcd_regulator_init_data = {
 215        .constraints    = {
 216                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
 217},
 218        .consumer_supplies      = &mx27ads_lcd_regulator_consumer,
 219        .num_consumer_supplies  = 1,
 220};
 221
 222static struct fixed_voltage_config mx27ads_lcd_regulator_pdata = {
 223        .supply_name    = "LCD",
 224        .microvolts     = 3300000,
 225        .init_data      = &mx27ads_lcd_regulator_init_data,
 226};
 227
 228static struct gpiod_lookup_table mx27ads_lcd_regulator_gpiod_table = {
 229        .dev_id = "reg-fixed-voltage.0", /* Let's hope ID 0 is what we get */
 230        .table = {
 231                GPIO_LOOKUP("LCD", 0, NULL, GPIO_ACTIVE_LOW),
 232                { },
 233        },
 234};
 235
 236static void __init mx27ads_regulator_init(void)
 237{
 238        struct gpio_chip *vchip;
 239
 240        vchip = kzalloc(sizeof(*vchip), GFP_KERNEL);
 241        vchip->owner            = THIS_MODULE;
 242        vchip->label            = "LCD";
 243        vchip->base             = MX27ADS_LCD_GPIO;
 244        vchip->ngpio            = 1;
 245        vchip->direction_output = vgpio_dir_out;
 246        vchip->set              = vgpio_set;
 247        gpiochip_add_data(vchip, NULL);
 248
 249        gpiod_add_lookup_table(&mx27ads_lcd_regulator_gpiod_table);
 250
 251        platform_device_register_data(NULL, "reg-fixed-voltage",
 252                                      PLATFORM_DEVID_AUTO,
 253                                      &mx27ads_lcd_regulator_pdata,
 254                                      sizeof(mx27ads_lcd_regulator_pdata));
 255}
 256
 257static struct imx_fb_videomode mx27ads_modes[] = {
 258        {
 259                .mode = {
 260                        .name           = "Sharp-LQ035Q7",
 261                        .refresh        = 60,
 262                        .xres           = 240,
 263                        .yres           = 320,
 264                        .pixclock       = 188679, /* in ps (5.3MHz) */
 265                        .hsync_len      = 1,
 266                        .left_margin    = 9,
 267                        .right_margin   = 16,
 268                        .vsync_len      = 1,
 269                        .upper_margin   = 7,
 270                        .lower_margin   = 9,
 271                },
 272                .bpp            = 16,
 273                .pcr            = 0xFB008BC0,
 274        },
 275};
 276
 277static const struct imx_fb_platform_data mx27ads_fb_data __initconst = {
 278        .mode = mx27ads_modes,
 279        .num_modes = ARRAY_SIZE(mx27ads_modes),
 280
 281        /*
 282         * - HSYNC active high
 283         * - VSYNC active high
 284         * - clk notenabled while idle
 285         * - clock inverted
 286         * - data not inverted
 287         * - data enable low active
 288         * - enable sharp mode
 289         */
 290        .pwmr           = 0x00A903FF,
 291        .lscr1          = 0x00120300,
 292        .dmacr          = 0x00020010,
 293};
 294
 295static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
 296                              void *data)
 297{
 298        return request_irq(gpio_to_irq(IMX_GPIO_NR(5, 21)), detect_irq,
 299                           IRQF_TRIGGER_RISING, "sdhc1-card-detect", data);
 300}
 301
 302static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
 303                              void *data)
 304{
 305        return request_irq(gpio_to_irq(IMX_GPIO_NR(2, 7)), detect_irq,
 306                           IRQF_TRIGGER_RISING, "sdhc2-card-detect", data);
 307}
 308
 309static void mx27ads_sdhc1_exit(struct device *dev, void *data)
 310{
 311        free_irq(gpio_to_irq(IMX_GPIO_NR(5, 21)), data);
 312}
 313
 314static void mx27ads_sdhc2_exit(struct device *dev, void *data)
 315{
 316        free_irq(gpio_to_irq(IMX_GPIO_NR(2, 7)), data);
 317}
 318
 319static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
 320        .init = mx27ads_sdhc1_init,
 321        .exit = mx27ads_sdhc1_exit,
 322};
 323
 324static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
 325        .init = mx27ads_sdhc2_init,
 326        .exit = mx27ads_sdhc2_exit,
 327};
 328
 329static struct platform_device *platform_devices[] __initdata = {
 330        &mx27ads_nor_mtd_device,
 331};
 332
 333static const struct imxuart_platform_data uart_pdata __initconst = {
 334        .flags = IMXUART_HAVE_RTSCTS,
 335};
 336
 337static void __init mx27ads_board_init(void)
 338{
 339        imx27_soc_init();
 340
 341        mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
 342                        "mx27ads");
 343
 344        imx27_add_imx_uart0(&uart_pdata);
 345        imx27_add_imx_uart1(&uart_pdata);
 346        imx27_add_imx_uart2(&uart_pdata);
 347        imx27_add_imx_uart3(&uart_pdata);
 348        imx27_add_imx_uart4(&uart_pdata);
 349        imx27_add_imx_uart5(&uart_pdata);
 350        imx27_add_mxc_nand(&mx27ads_nand_board_info);
 351
 352        /* only the i2c master 1 is used on this CPU card */
 353        i2c_register_board_info(1, mx27ads_i2c_devices,
 354                                ARRAY_SIZE(mx27ads_i2c_devices));
 355        imx27_add_imx_i2c(1, &mx27ads_i2c1_data);
 356        imx27_add_imx_fb(&mx27ads_fb_data);
 357
 358        imx27_add_fec(NULL);
 359        imx27_add_mxc_w1();
 360}
 361
 362static void __init mx27ads_late_init(void)
 363{
 364        mx27ads_regulator_init();
 365
 366        imx27_add_mxc_mmc(0, &sdhc1_pdata);
 367        imx27_add_mxc_mmc(1, &sdhc2_pdata);
 368
 369        platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 370}
 371
 372static void __init mx27ads_timer_init(void)
 373{
 374        unsigned long fref = 26000000;
 375
 376        if ((imx_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
 377                fref = 27000000;
 378
 379        mx27_clocks_init(fref);
 380}
 381
 382static struct map_desc mx27ads_io_desc[] __initdata = {
 383        {
 384                .virtual = PBC_BASE_ADDRESS,
 385                .pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR),
 386                .length = SZ_1M,
 387                .type = MT_DEVICE,
 388        },
 389};
 390
 391static void __init mx27ads_map_io(void)
 392{
 393        mx27_map_io();
 394        iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
 395}
 396
 397MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
 398        /* maintainer: Freescale Semiconductor, Inc. */
 399        .atag_offset = 0x100,
 400        .map_io = mx27ads_map_io,
 401        .init_early = imx27_init_early,
 402        .init_irq = mx27_init_irq,
 403        .init_time      = mx27ads_timer_init,
 404        .init_machine = mx27ads_board_init,
 405        .init_late      = mx27ads_late_init,
 406        .restart        = mxc_restart,
 407MACHINE_END
 408