linux/arch/sh/boards/mach-ap325rxa/setup.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Renesas - AP-325RXA
   4 * (Compatible with Algo System ., LTD. - AP-320A)
   5 *
   6 * Copyright (C) 2008 Renesas Solutions Corp.
   7 * Author : Yusuke Goda <goda.yuske@renesas.com>
   8 */
   9
  10#include <asm/clock.h>
  11#include <asm/io.h>
  12#include <asm/suspend.h>
  13
  14#include <cpu/sh7723.h>
  15
  16#include <linux/clkdev.h>
  17#include <linux/delay.h>
  18#include <linux/device.h>
  19#include <linux/gpio.h>
  20#include <linux/gpio/machine.h>
  21#include <linux/i2c.h>
  22#include <linux/init.h>
  23#include <linux/interrupt.h>
  24#include <linux/memblock.h>
  25#include <linux/mfd/tmio.h>
  26#include <linux/mmc/host.h>
  27#include <linux/mtd/physmap.h>
  28#include <linux/mtd/sh_flctl.h>
  29#include <linux/platform_device.h>
  30#include <linux/regulator/fixed.h>
  31#include <linux/regulator/machine.h>
  32#include <linux/sh_intc.h>
  33#include <linux/smsc911x.h>
  34#include <linux/videodev2.h>
  35
  36#include <media/drv-intf/renesas-ceu.h>
  37#include <media/i2c/ov772x.h>
  38
  39#include <video/sh_mobile_lcdc.h>
  40
  41#define CEU_BUFFER_MEMORY_SIZE          (4 << 20)
  42static phys_addr_t ceu_dma_membase;
  43
  44/* Dummy supplies, where voltage doesn't matter */
  45static struct regulator_consumer_supply dummy_supplies[] = {
  46        REGULATOR_SUPPLY("vddvario", "smsc911x"),
  47        REGULATOR_SUPPLY("vdd33a", "smsc911x"),
  48};
  49
  50static struct smsc911x_platform_config smsc911x_config = {
  51        .phy_interface  = PHY_INTERFACE_MODE_MII,
  52        .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
  53        .irq_type       = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
  54        .flags          = SMSC911X_USE_32BIT,
  55};
  56
  57static struct resource smsc9118_resources[] = {
  58        [0] = {
  59                .start  = 0xb6080000,
  60                .end    = 0xb60fffff,
  61                .flags  = IORESOURCE_MEM,
  62        },
  63        [1] = {
  64                .start  = evt2irq(0x660),
  65                .end    = evt2irq(0x660),
  66                .flags  = IORESOURCE_IRQ,
  67        }
  68};
  69
  70static struct platform_device smsc9118_device = {
  71        .name           = "smsc911x",
  72        .id             = -1,
  73        .num_resources  = ARRAY_SIZE(smsc9118_resources),
  74        .resource       = smsc9118_resources,
  75        .dev            = {
  76                .platform_data = &smsc911x_config,
  77        },
  78};
  79
  80/*
  81 * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
  82 * If this area erased, this board can not boot.
  83 */
  84static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
  85        {
  86                .name = "uboot",
  87                .offset = 0,
  88                .size = (1 * 1024 * 1024),
  89                .mask_flags = MTD_WRITEABLE,    /* Read-only */
  90        }, {
  91                .name = "kernel",
  92                .offset = MTDPART_OFS_APPEND,
  93                .size = (2 * 1024 * 1024),
  94        }, {
  95                .name = "free-area0",
  96                .offset = MTDPART_OFS_APPEND,
  97                .size = ((7 * 1024 * 1024) + (512 * 1024)),
  98        }, {
  99                .name = "CPLD-Data",
 100                .offset = MTDPART_OFS_APPEND,
 101                .mask_flags = MTD_WRITEABLE,    /* Read-only */
 102                .size = (1024 * 128 * 2),
 103        }, {
 104                .name = "free-area1",
 105                .offset = MTDPART_OFS_APPEND,
 106                .size = MTDPART_SIZ_FULL,
 107        },
 108};
 109
 110static struct physmap_flash_data ap325rxa_nor_flash_data = {
 111        .width          = 2,
 112        .parts          = ap325rxa_nor_flash_partitions,
 113        .nr_parts       = ARRAY_SIZE(ap325rxa_nor_flash_partitions),
 114};
 115
 116static struct resource ap325rxa_nor_flash_resources[] = {
 117        [0] = {
 118                .name   = "NOR Flash",
 119                .start  = 0x00000000,
 120                .end    = 0x00ffffff,
 121                .flags  = IORESOURCE_MEM,
 122        }
 123};
 124
 125static struct platform_device ap325rxa_nor_flash_device = {
 126        .name           = "physmap-flash",
 127        .resource       = ap325rxa_nor_flash_resources,
 128        .num_resources  = ARRAY_SIZE(ap325rxa_nor_flash_resources),
 129        .dev            = {
 130                .platform_data = &ap325rxa_nor_flash_data,
 131        },
 132};
 133
 134static struct mtd_partition nand_partition_info[] = {
 135        {
 136                .name   = "nand_data",
 137                .offset = 0,
 138                .size   = MTDPART_SIZ_FULL,
 139        },
 140};
 141
 142static struct resource nand_flash_resources[] = {
 143        [0] = {
 144                .start  = 0xa4530000,
 145                .end    = 0xa45300ff,
 146                .flags  = IORESOURCE_MEM,
 147        }
 148};
 149
 150static struct sh_flctl_platform_data nand_flash_data = {
 151        .parts          = nand_partition_info,
 152        .nr_parts       = ARRAY_SIZE(nand_partition_info),
 153        .flcmncr_val    = FCKSEL_E | TYPESEL_SET | NANWF_E,
 154        .has_hwecc      = 1,
 155};
 156
 157static struct platform_device nand_flash_device = {
 158        .name           = "sh_flctl",
 159        .resource       = nand_flash_resources,
 160        .num_resources  = ARRAY_SIZE(nand_flash_resources),
 161        .dev            = {
 162                .platform_data = &nand_flash_data,
 163        },
 164};
 165
 166#define FPGA_LCDREG     0xB4100180
 167#define FPGA_BKLREG     0xB4100212
 168#define FPGA_LCDREG_VAL 0x0018
 169#define PORT_MSELCRB    0xA4050182
 170#define PORT_HIZCRC     0xA405015C
 171#define PORT_DRVCRA     0xA405018A
 172#define PORT_DRVCRB     0xA405018C
 173
 174static int ap320_wvga_set_brightness(int brightness)
 175{
 176        if (brightness) {
 177                gpio_set_value(GPIO_PTS3, 0);
 178                __raw_writew(0x100, FPGA_BKLREG);
 179        } else {
 180                __raw_writew(0, FPGA_BKLREG);
 181                gpio_set_value(GPIO_PTS3, 1);
 182        }
 183
 184        return 0;
 185}
 186
 187static void ap320_wvga_power_on(void)
 188{
 189        msleep(100);
 190
 191        /* ASD AP-320/325 LCD ON */
 192        __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
 193}
 194
 195static void ap320_wvga_power_off(void)
 196{
 197        /* ASD AP-320/325 LCD OFF */
 198        __raw_writew(0, FPGA_LCDREG);
 199}
 200
 201static const struct fb_videomode ap325rxa_lcdc_modes[] = {
 202        {
 203                .name = "LB070WV1",
 204                .xres = 800,
 205                .yres = 480,
 206                .left_margin = 32,
 207                .right_margin = 160,
 208                .hsync_len = 8,
 209                .upper_margin = 63,
 210                .lower_margin = 80,
 211                .vsync_len = 1,
 212                .sync = 0, /* hsync and vsync are active low */
 213        },
 214};
 215
 216static struct sh_mobile_lcdc_info lcdc_info = {
 217        .clock_source = LCDC_CLK_EXTERNAL,
 218        .ch[0] = {
 219                .chan = LCDC_CHAN_MAINLCD,
 220                .fourcc = V4L2_PIX_FMT_RGB565,
 221                .interface_type = RGB18,
 222                .clock_divider = 1,
 223                .lcd_modes = ap325rxa_lcdc_modes,
 224                .num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
 225                .panel_cfg = {
 226                        .width = 152,   /* 7.0 inch */
 227                        .height = 91,
 228                        .display_on = ap320_wvga_power_on,
 229                        .display_off = ap320_wvga_power_off,
 230                },
 231                .bl_info = {
 232                        .name = "sh_mobile_lcdc_bl",
 233                        .max_brightness = 1,
 234                        .set_brightness = ap320_wvga_set_brightness,
 235                },
 236        }
 237};
 238
 239static struct resource lcdc_resources[] = {
 240        [0] = {
 241                .name   = "LCDC",
 242                .start  = 0xfe940000, /* P4-only space */
 243                .end    = 0xfe942fff,
 244                .flags  = IORESOURCE_MEM,
 245        },
 246        [1] = {
 247                .start  = evt2irq(0x580),
 248                .flags  = IORESOURCE_IRQ,
 249        },
 250};
 251
 252static struct platform_device lcdc_device = {
 253        .name           = "sh_mobile_lcdc_fb",
 254        .num_resources  = ARRAY_SIZE(lcdc_resources),
 255        .resource       = lcdc_resources,
 256        .dev            = {
 257                .platform_data  = &lcdc_info,
 258        },
 259};
 260
 261/* Powerdown/reset gpios for CEU image sensors */
 262static struct gpiod_lookup_table ov7725_gpios = {
 263        .dev_id         = "0-0021",
 264        .table          = {
 265                GPIO_LOOKUP("sh7723_pfc", GPIO_PTZ5, "reset", GPIO_ACTIVE_LOW),
 266        },
 267};
 268
 269static struct ceu_platform_data ceu0_pdata = {
 270        .num_subdevs                    = 1,
 271        .subdevs = {
 272                { /* [0] = ov7725  */
 273                        .flags          = 0,
 274                        .bus_width      = 8,
 275                        .bus_shift      = 0,
 276                        .i2c_adapter_id = 0,
 277                        .i2c_address    = 0x21,
 278                },
 279        },
 280};
 281
 282static struct resource ceu_resources[] = {
 283        [0] = {
 284                .name   = "CEU",
 285                .start  = 0xfe910000,
 286                .end    = 0xfe91009f,
 287                .flags  = IORESOURCE_MEM,
 288        },
 289        [1] = {
 290                .start  = evt2irq(0x880),
 291                .flags  = IORESOURCE_IRQ,
 292        },
 293};
 294
 295static struct platform_device ap325rxa_ceu_device = {
 296        .name           = "renesas-ceu",
 297        .id             = 0, /* "ceu.0" clock */
 298        .num_resources  = ARRAY_SIZE(ceu_resources),
 299        .resource       = ceu_resources,
 300        .dev            = {
 301                .platform_data  = &ceu0_pdata,
 302        },
 303};
 304
 305/* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */
 306static struct regulator_consumer_supply fixed3v3_power_consumers[] =
 307{
 308        REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
 309        REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
 310        REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
 311        REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
 312};
 313
 314static struct resource sdhi0_cn3_resources[] = {
 315        [0] = {
 316                .name   = "SDHI0",
 317                .start  = 0x04ce0000,
 318                .end    = 0x04ce00ff,
 319                .flags  = IORESOURCE_MEM,
 320        },
 321        [1] = {
 322                .start  = evt2irq(0xe80),
 323                .flags  = IORESOURCE_IRQ,
 324        },
 325};
 326
 327static struct tmio_mmc_data sdhi0_cn3_data = {
 328        .capabilities   = MMC_CAP_SDIO_IRQ,
 329};
 330
 331static struct platform_device sdhi0_cn3_device = {
 332        .name           = "sh_mobile_sdhi",
 333        .id             = 0, /* "sdhi0" clock */
 334        .num_resources  = ARRAY_SIZE(sdhi0_cn3_resources),
 335        .resource       = sdhi0_cn3_resources,
 336        .dev = {
 337                .platform_data = &sdhi0_cn3_data,
 338        },
 339};
 340
 341static struct resource sdhi1_cn7_resources[] = {
 342        [0] = {
 343                .name   = "SDHI1",
 344                .start  = 0x04cf0000,
 345                .end    = 0x04cf00ff,
 346                .flags  = IORESOURCE_MEM,
 347        },
 348        [1] = {
 349                .start  = evt2irq(0x4e0),
 350                .flags  = IORESOURCE_IRQ,
 351        },
 352};
 353
 354static struct tmio_mmc_data sdhi1_cn7_data = {
 355        .capabilities   = MMC_CAP_SDIO_IRQ,
 356};
 357
 358static struct platform_device sdhi1_cn7_device = {
 359        .name           = "sh_mobile_sdhi",
 360        .id             = 1, /* "sdhi1" clock */
 361        .num_resources  = ARRAY_SIZE(sdhi1_cn7_resources),
 362        .resource       = sdhi1_cn7_resources,
 363        .dev = {
 364                .platform_data = &sdhi1_cn7_data,
 365        },
 366};
 367
 368static struct ov772x_camera_info ov7725_info = {
 369        .flags          = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
 370        .edgectrl       = OV772X_AUTO_EDGECTRL(0xf, 0),
 371};
 372
 373static struct i2c_board_info ap325rxa_i2c_devices[] __initdata = {
 374        {
 375                I2C_BOARD_INFO("pcf8563", 0x51),
 376        },
 377        {
 378                I2C_BOARD_INFO("ov772x", 0x21),
 379                .platform_data = &ov7725_info,
 380        },
 381};
 382
 383static struct platform_device *ap325rxa_devices[] __initdata = {
 384        &smsc9118_device,
 385        &ap325rxa_nor_flash_device,
 386        &lcdc_device,
 387        &nand_flash_device,
 388        &sdhi0_cn3_device,
 389        &sdhi1_cn7_device,
 390};
 391
 392extern char ap325rxa_sdram_enter_start;
 393extern char ap325rxa_sdram_enter_end;
 394extern char ap325rxa_sdram_leave_start;
 395extern char ap325rxa_sdram_leave_end;
 396
 397static int __init ap325rxa_devices_setup(void)
 398{
 399        /* register board specific self-refresh code */
 400        sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
 401                                        &ap325rxa_sdram_enter_start,
 402                                        &ap325rxa_sdram_enter_end,
 403                                        &ap325rxa_sdram_leave_start,
 404                                        &ap325rxa_sdram_leave_end);
 405
 406        regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
 407                                     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
 408        regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies));
 409
 410        /* LD3 and LD4 LEDs */
 411        gpio_request(GPIO_PTX5, NULL); /* RUN */
 412        gpio_direction_output(GPIO_PTX5, 1);
 413        gpio_export(GPIO_PTX5, 0);
 414
 415        gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
 416        gpio_direction_output(GPIO_PTX4, 0);
 417        gpio_export(GPIO_PTX4, 0);
 418
 419        /* SW1 input */
 420        gpio_request(GPIO_PTF7, NULL); /* MODE */
 421        gpio_direction_input(GPIO_PTF7);
 422        gpio_export(GPIO_PTF7, 0);
 423
 424        /* LCDC */
 425        gpio_request(GPIO_FN_LCDD15, NULL);
 426        gpio_request(GPIO_FN_LCDD14, NULL);
 427        gpio_request(GPIO_FN_LCDD13, NULL);
 428        gpio_request(GPIO_FN_LCDD12, NULL);
 429        gpio_request(GPIO_FN_LCDD11, NULL);
 430        gpio_request(GPIO_FN_LCDD10, NULL);
 431        gpio_request(GPIO_FN_LCDD9, NULL);
 432        gpio_request(GPIO_FN_LCDD8, NULL);
 433        gpio_request(GPIO_FN_LCDD7, NULL);
 434        gpio_request(GPIO_FN_LCDD6, NULL);
 435        gpio_request(GPIO_FN_LCDD5, NULL);
 436        gpio_request(GPIO_FN_LCDD4, NULL);
 437        gpio_request(GPIO_FN_LCDD3, NULL);
 438        gpio_request(GPIO_FN_LCDD2, NULL);
 439        gpio_request(GPIO_FN_LCDD1, NULL);
 440        gpio_request(GPIO_FN_LCDD0, NULL);
 441        gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
 442        gpio_request(GPIO_FN_LCDDCK, NULL);
 443        gpio_request(GPIO_FN_LCDVEPWC, NULL);
 444        gpio_request(GPIO_FN_LCDVCPWC, NULL);
 445        gpio_request(GPIO_FN_LCDVSYN, NULL);
 446        gpio_request(GPIO_FN_LCDHSYN, NULL);
 447        gpio_request(GPIO_FN_LCDDISP, NULL);
 448        gpio_request(GPIO_FN_LCDDON, NULL);
 449
 450        /* LCD backlight */
 451        gpio_request(GPIO_PTS3, NULL);
 452        gpio_direction_output(GPIO_PTS3, 1);
 453
 454        /* CEU */
 455        gpio_request(GPIO_FN_VIO_CLK2, NULL);
 456        gpio_request(GPIO_FN_VIO_VD2, NULL);
 457        gpio_request(GPIO_FN_VIO_HD2, NULL);
 458        gpio_request(GPIO_FN_VIO_FLD, NULL);
 459        gpio_request(GPIO_FN_VIO_CKO, NULL);
 460        gpio_request(GPIO_FN_VIO_D15, NULL);
 461        gpio_request(GPIO_FN_VIO_D14, NULL);
 462        gpio_request(GPIO_FN_VIO_D13, NULL);
 463        gpio_request(GPIO_FN_VIO_D12, NULL);
 464        gpio_request(GPIO_FN_VIO_D11, NULL);
 465        gpio_request(GPIO_FN_VIO_D10, NULL);
 466        gpio_request(GPIO_FN_VIO_D9, NULL);
 467        gpio_request(GPIO_FN_VIO_D8, NULL);
 468
 469        gpio_request(GPIO_PTZ7, NULL);
 470        gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
 471        gpio_request(GPIO_PTZ6, NULL);
 472        gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
 473        gpio_request(GPIO_PTZ5, NULL);
 474        gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
 475        gpio_request(GPIO_PTZ4, NULL);
 476        gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
 477
 478        __raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
 479
 480        /* FLCTL */
 481        gpio_request(GPIO_FN_FCE, NULL);
 482        gpio_request(GPIO_FN_NAF7, NULL);
 483        gpio_request(GPIO_FN_NAF6, NULL);
 484        gpio_request(GPIO_FN_NAF5, NULL);
 485        gpio_request(GPIO_FN_NAF4, NULL);
 486        gpio_request(GPIO_FN_NAF3, NULL);
 487        gpio_request(GPIO_FN_NAF2, NULL);
 488        gpio_request(GPIO_FN_NAF1, NULL);
 489        gpio_request(GPIO_FN_NAF0, NULL);
 490        gpio_request(GPIO_FN_FCDE, NULL);
 491        gpio_request(GPIO_FN_FOE, NULL);
 492        gpio_request(GPIO_FN_FSC, NULL);
 493        gpio_request(GPIO_FN_FWE, NULL);
 494        gpio_request(GPIO_FN_FRB, NULL);
 495
 496        __raw_writew(0, PORT_HIZCRC);
 497        __raw_writew(0xFFFF, PORT_DRVCRA);
 498        __raw_writew(0xFFFF, PORT_DRVCRB);
 499
 500        /* SDHI0 - CN3 - SD CARD */
 501        gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
 502        gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
 503        gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
 504        gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
 505        gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
 506        gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
 507        gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
 508        gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
 509
 510        /* SDHI1 - CN7 - MICRO SD CARD */
 511        gpio_request(GPIO_FN_SDHI1CD, NULL);
 512        gpio_request(GPIO_FN_SDHI1D3, NULL);
 513        gpio_request(GPIO_FN_SDHI1D2, NULL);
 514        gpio_request(GPIO_FN_SDHI1D1, NULL);
 515        gpio_request(GPIO_FN_SDHI1D0, NULL);
 516        gpio_request(GPIO_FN_SDHI1CMD, NULL);
 517        gpio_request(GPIO_FN_SDHI1CLK, NULL);
 518
 519        /* Add a clock alias for ov7725 xclk source. */
 520        clk_add_alias(NULL, "0-0021", "video_clk", NULL);
 521
 522        /* Register RSTB gpio for ov7725 camera sensor. */
 523        gpiod_add_lookup_table(&ov7725_gpios);
 524
 525        i2c_register_board_info(0, ap325rxa_i2c_devices,
 526                                ARRAY_SIZE(ap325rxa_i2c_devices));
 527
 528        /* Initialize CEU platform device separately to map memory first */
 529        device_initialize(&ap325rxa_ceu_device.dev);
 530        dma_declare_coherent_memory(&ap325rxa_ceu_device.dev,
 531                        ceu_dma_membase, ceu_dma_membase,
 532                        ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
 533
 534        platform_device_add(&ap325rxa_ceu_device);
 535
 536        return platform_add_devices(ap325rxa_devices,
 537                                ARRAY_SIZE(ap325rxa_devices));
 538}
 539arch_initcall(ap325rxa_devices_setup);
 540
 541/* Return the board specific boot mode pin configuration */
 542static int ap325rxa_mode_pins(void)
 543{
 544        /* MD0=0, MD1=0, MD2=0: Clock Mode 0
 545         * MD3=0: 16-bit Area0 Bus Width
 546         * MD5=1: Little Endian
 547         * TSTMD=1, MD8=1: Test Mode Disabled
 548         */
 549        return MODE_PIN5 | MODE_PIN8;
 550}
 551
 552/* Reserve a portion of memory for CEU buffers */
 553static void __init ap325rxa_mv_mem_reserve(void)
 554{
 555        phys_addr_t phys;
 556        phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
 557
 558        phys = memblock_phys_alloc(size, PAGE_SIZE);
 559        if (!phys)
 560                panic("Failed to allocate CEU memory\n");
 561
 562        memblock_free(phys, size);
 563        memblock_remove(phys, size);
 564
 565        ceu_dma_membase = phys;
 566}
 567
 568static struct sh_machine_vector mv_ap325rxa __initmv = {
 569        .mv_name = "AP-325RXA",
 570        .mv_mode_pins = ap325rxa_mode_pins,
 571        .mv_mem_reserve = ap325rxa_mv_mem_reserve,
 572};
 573