linux/arch/mips/alchemy/devboards/db1000.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * DBAu1000/1500/1100 PBAu1100/1500 board support
   4 *
   5 * Copyright 2000, 2008 MontaVista Software Inc.
   6 * Author: MontaVista Software, Inc. <source@mvista.com>
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/dma-mapping.h>
  11#include <linux/gpio.h>
  12#include <linux/gpio/machine.h>
  13#include <linux/init.h>
  14#include <linux/interrupt.h>
  15#include <linux/leds.h>
  16#include <linux/mmc/host.h>
  17#include <linux/module.h>
  18#include <linux/platform_device.h>
  19#include <linux/pm.h>
  20#include <linux/spi/spi.h>
  21#include <linux/spi/spi_gpio.h>
  22#include <linux/spi/ads7846.h>
  23#include <asm/mach-au1x00/au1000.h>
  24#include <asm/mach-au1x00/gpio-au1000.h>
  25#include <asm/mach-au1x00/au1000_dma.h>
  26#include <asm/mach-au1x00/au1100_mmc.h>
  27#include <asm/mach-db1x00/bcsr.h>
  28#include <asm/reboot.h>
  29#include <prom.h>
  30#include "platform.h"
  31
  32#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
  33
  34const char *get_system_type(void);
  35
  36int __init db1000_board_setup(void)
  37{
  38        /* initialize board register space */
  39        bcsr_init(DB1000_BCSR_PHYS_ADDR,
  40                  DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
  41
  42        switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
  43        case BCSR_WHOAMI_DB1000:
  44        case BCSR_WHOAMI_DB1500:
  45        case BCSR_WHOAMI_DB1100:
  46        case BCSR_WHOAMI_PB1500:
  47        case BCSR_WHOAMI_PB1500R2:
  48        case BCSR_WHOAMI_PB1100:
  49                pr_info("AMD Alchemy %s Board\n", get_system_type());
  50                return 0;
  51        }
  52        return -ENODEV;
  53}
  54
  55static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
  56{
  57        if ((slot < 12) || (slot > 13) || pin == 0)
  58                return -1;
  59        if (slot == 12)
  60                return (pin == 1) ? AU1500_PCI_INTA : 0xff;
  61        if (slot == 13) {
  62                switch (pin) {
  63                case 1: return AU1500_PCI_INTA;
  64                case 2: return AU1500_PCI_INTB;
  65                case 3: return AU1500_PCI_INTC;
  66                case 4: return AU1500_PCI_INTD;
  67                }
  68        }
  69        return -1;
  70}
  71
  72static u64 au1xxx_all_dmamask = DMA_BIT_MASK(32);
  73
  74static struct resource alchemy_pci_host_res[] = {
  75        [0] = {
  76                .start  = AU1500_PCI_PHYS_ADDR,
  77                .end    = AU1500_PCI_PHYS_ADDR + 0xfff,
  78                .flags  = IORESOURCE_MEM,
  79        },
  80};
  81
  82static struct alchemy_pci_platdata db1500_pci_pd = {
  83        .board_map_irq  = db1500_map_pci_irq,
  84};
  85
  86static struct platform_device db1500_pci_host_dev = {
  87        .dev.platform_data = &db1500_pci_pd,
  88        .name           = "alchemy-pci",
  89        .id             = 0,
  90        .num_resources  = ARRAY_SIZE(alchemy_pci_host_res),
  91        .resource       = alchemy_pci_host_res,
  92};
  93
  94int __init db1500_pci_setup(void)
  95{
  96        return platform_device_register(&db1500_pci_host_dev);
  97}
  98
  99static struct resource au1100_lcd_resources[] = {
 100        [0] = {
 101                .start  = AU1100_LCD_PHYS_ADDR,
 102                .end    = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
 103                .flags  = IORESOURCE_MEM,
 104        },
 105        [1] = {
 106                .start  = AU1100_LCD_INT,
 107                .end    = AU1100_LCD_INT,
 108                .flags  = IORESOURCE_IRQ,
 109        }
 110};
 111
 112static struct platform_device au1100_lcd_device = {
 113        .name           = "au1100-lcd",
 114        .id             = 0,
 115        .dev = {
 116                .dma_mask               = &au1xxx_all_dmamask,
 117                .coherent_dma_mask      = DMA_BIT_MASK(32),
 118        },
 119        .num_resources  = ARRAY_SIZE(au1100_lcd_resources),
 120        .resource       = au1100_lcd_resources,
 121};
 122
 123static struct resource alchemy_ac97c_res[] = {
 124        [0] = {
 125                .start  = AU1000_AC97_PHYS_ADDR,
 126                .end    = AU1000_AC97_PHYS_ADDR + 0xfff,
 127                .flags  = IORESOURCE_MEM,
 128        },
 129        [1] = {
 130                .start  = DMA_ID_AC97C_TX,
 131                .end    = DMA_ID_AC97C_TX,
 132                .flags  = IORESOURCE_DMA,
 133        },
 134        [2] = {
 135                .start  = DMA_ID_AC97C_RX,
 136                .end    = DMA_ID_AC97C_RX,
 137                .flags  = IORESOURCE_DMA,
 138        },
 139};
 140
 141static struct platform_device alchemy_ac97c_dev = {
 142        .name           = "alchemy-ac97c",
 143        .id             = -1,
 144        .resource       = alchemy_ac97c_res,
 145        .num_resources  = ARRAY_SIZE(alchemy_ac97c_res),
 146};
 147
 148static struct platform_device alchemy_ac97c_dma_dev = {
 149        .name           = "alchemy-pcm-dma",
 150        .id             = 0,
 151};
 152
 153static struct platform_device db1x00_codec_dev = {
 154        .name           = "ac97-codec",
 155        .id             = -1,
 156};
 157
 158static struct platform_device db1x00_audio_dev = {
 159        .name           = "db1000-audio",
 160        .dev = {
 161                .dma_mask               = &au1xxx_all_dmamask,
 162                .coherent_dma_mask      = DMA_BIT_MASK(32),
 163        },
 164};
 165
 166/******************************************************************************/
 167
 168static irqreturn_t db1100_mmc_cd(int irq, void *ptr)
 169{
 170        void (*mmc_cd)(struct mmc_host *, unsigned long);
 171        /* link against CONFIG_MMC=m */
 172        mmc_cd = symbol_get(mmc_detect_change);
 173        mmc_cd(ptr, msecs_to_jiffies(500));
 174        symbol_put(mmc_detect_change);
 175
 176        return IRQ_HANDLED;
 177}
 178
 179static int db1100_mmc_cd_setup(void *mmc_host, int en)
 180{
 181        int ret = 0, irq;
 182
 183        if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
 184                irq = AU1100_GPIO19_INT;
 185        else
 186                irq = AU1100_GPIO14_INT;        /* PB1100 SD0 CD# */
 187
 188        if (en) {
 189                irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
 190                ret = request_irq(irq, db1100_mmc_cd, 0,
 191                                  "sd0_cd", mmc_host);
 192        } else
 193                free_irq(irq, mmc_host);
 194        return ret;
 195}
 196
 197static int db1100_mmc1_cd_setup(void *mmc_host, int en)
 198{
 199        int ret = 0, irq;
 200
 201        if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
 202                irq = AU1100_GPIO20_INT;
 203        else
 204                irq = AU1100_GPIO15_INT;        /* PB1100 SD1 CD# */
 205
 206        if (en) {
 207                irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
 208                ret = request_irq(irq, db1100_mmc_cd, 0,
 209                                  "sd1_cd", mmc_host);
 210        } else
 211                free_irq(irq, mmc_host);
 212        return ret;
 213}
 214
 215static int db1100_mmc_card_readonly(void *mmc_host)
 216{
 217        /* testing suggests that this bit is inverted */
 218        return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1;
 219}
 220
 221static int db1100_mmc_card_inserted(void *mmc_host)
 222{
 223        return !alchemy_gpio_get_value(19);
 224}
 225
 226static void db1100_mmc_set_power(void *mmc_host, int state)
 227{
 228        int bit;
 229
 230        if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
 231                bit = BCSR_BOARD_SD0PWR;
 232        else
 233                bit = BCSR_BOARD_PB1100_SD0PWR;
 234
 235        if (state) {
 236                bcsr_mod(BCSR_BOARD, 0, bit);
 237                msleep(400);    /* stabilization time */
 238        } else
 239                bcsr_mod(BCSR_BOARD, bit, 0);
 240}
 241
 242static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b)
 243{
 244        if (b != LED_OFF)
 245                bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
 246        else
 247                bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
 248}
 249
 250static struct led_classdev db1100_mmc_led = {
 251        .brightness_set = db1100_mmcled_set,
 252};
 253
 254static int db1100_mmc1_card_readonly(void *mmc_host)
 255{
 256        return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0;
 257}
 258
 259static int db1100_mmc1_card_inserted(void *mmc_host)
 260{
 261        return !alchemy_gpio_get_value(20);
 262}
 263
 264static void db1100_mmc1_set_power(void *mmc_host, int state)
 265{
 266        int bit;
 267
 268        if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
 269                bit = BCSR_BOARD_SD1PWR;
 270        else
 271                bit = BCSR_BOARD_PB1100_SD1PWR;
 272
 273        if (state) {
 274                bcsr_mod(BCSR_BOARD, 0, bit);
 275                msleep(400);    /* stabilization time */
 276        } else
 277                bcsr_mod(BCSR_BOARD, bit, 0);
 278}
 279
 280static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b)
 281{
 282        if (b != LED_OFF)
 283                bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
 284        else
 285                bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
 286}
 287
 288static struct led_classdev db1100_mmc1_led = {
 289        .brightness_set = db1100_mmc1led_set,
 290};
 291
 292static struct au1xmmc_platform_data db1100_mmc_platdata[2] = {
 293        [0] = {
 294                .cd_setup       = db1100_mmc_cd_setup,
 295                .set_power      = db1100_mmc_set_power,
 296                .card_inserted  = db1100_mmc_card_inserted,
 297                .card_readonly  = db1100_mmc_card_readonly,
 298                .led            = &db1100_mmc_led,
 299        },
 300        [1] = {
 301                .cd_setup       = db1100_mmc1_cd_setup,
 302                .set_power      = db1100_mmc1_set_power,
 303                .card_inserted  = db1100_mmc1_card_inserted,
 304                .card_readonly  = db1100_mmc1_card_readonly,
 305                .led            = &db1100_mmc1_led,
 306        },
 307};
 308
 309static struct resource au1100_mmc0_resources[] = {
 310        [0] = {
 311                .start  = AU1100_SD0_PHYS_ADDR,
 312                .end    = AU1100_SD0_PHYS_ADDR + 0xfff,
 313                .flags  = IORESOURCE_MEM,
 314        },
 315        [1] = {
 316                .start  = AU1100_SD_INT,
 317                .end    = AU1100_SD_INT,
 318                .flags  = IORESOURCE_IRQ,
 319        },
 320        [2] = {
 321                .start  = DMA_ID_SD0_TX,
 322                .end    = DMA_ID_SD0_TX,
 323                .flags  = IORESOURCE_DMA,
 324        },
 325        [3] = {
 326                .start  = DMA_ID_SD0_RX,
 327                .end    = DMA_ID_SD0_RX,
 328                .flags  = IORESOURCE_DMA,
 329        }
 330};
 331
 332static struct platform_device db1100_mmc0_dev = {
 333        .name           = "au1xxx-mmc",
 334        .id             = 0,
 335        .dev = {
 336                .dma_mask               = &au1xxx_all_dmamask,
 337                .coherent_dma_mask      = DMA_BIT_MASK(32),
 338                .platform_data          = &db1100_mmc_platdata[0],
 339        },
 340        .num_resources  = ARRAY_SIZE(au1100_mmc0_resources),
 341        .resource       = au1100_mmc0_resources,
 342};
 343
 344static struct resource au1100_mmc1_res[] = {
 345        [0] = {
 346                .start  = AU1100_SD1_PHYS_ADDR,
 347                .end    = AU1100_SD1_PHYS_ADDR + 0xfff,
 348                .flags  = IORESOURCE_MEM,
 349        },
 350        [1] = {
 351                .start  = AU1100_SD_INT,
 352                .end    = AU1100_SD_INT,
 353                .flags  = IORESOURCE_IRQ,
 354        },
 355        [2] = {
 356                .start  = DMA_ID_SD1_TX,
 357                .end    = DMA_ID_SD1_TX,
 358                .flags  = IORESOURCE_DMA,
 359        },
 360        [3] = {
 361                .start  = DMA_ID_SD1_RX,
 362                .end    = DMA_ID_SD1_RX,
 363                .flags  = IORESOURCE_DMA,
 364        }
 365};
 366
 367static struct platform_device db1100_mmc1_dev = {
 368        .name           = "au1xxx-mmc",
 369        .id             = 1,
 370        .dev = {
 371                .dma_mask               = &au1xxx_all_dmamask,
 372                .coherent_dma_mask      = DMA_BIT_MASK(32),
 373                .platform_data          = &db1100_mmc_platdata[1],
 374        },
 375        .num_resources  = ARRAY_SIZE(au1100_mmc1_res),
 376        .resource       = au1100_mmc1_res,
 377};
 378
 379/******************************************************************************/
 380
 381static struct ads7846_platform_data db1100_touch_pd = {
 382        .model          = 7846,
 383        .vref_mv        = 3300,
 384        .gpio_pendown   = 21,
 385};
 386
 387static struct spi_gpio_platform_data db1100_spictl_pd = {
 388        .num_chipselect = 1,
 389};
 390
 391static struct spi_board_info db1100_spi_info[] __initdata = {
 392        [0] = {
 393                .modalias        = "ads7846",
 394                .max_speed_hz    = 3250000,
 395                .bus_num         = 0,
 396                .chip_select     = 0,
 397                .mode            = 0,
 398                .irq             = AU1100_GPIO21_INT,
 399                .platform_data   = &db1100_touch_pd,
 400        },
 401};
 402
 403static struct platform_device db1100_spi_dev = {
 404        .name           = "spi_gpio",
 405        .id             = 0,
 406        .dev            = {
 407                .platform_data  = &db1100_spictl_pd,
 408                .dma_mask               = &au1xxx_all_dmamask,
 409                .coherent_dma_mask      = DMA_BIT_MASK(32),
 410        },
 411};
 412
 413/*
 414 * Alchemy GPIO 2 has its base at 200 so the GPIO lines
 415 * 207 thru 210 are GPIOs at offset 7 thru 10 at this chip.
 416 */
 417static struct gpiod_lookup_table db1100_spi_gpiod_table = {
 418        .dev_id         = "spi_gpio",
 419        .table          = {
 420                GPIO_LOOKUP("alchemy-gpio2", 9,
 421                            "sck", GPIO_ACTIVE_HIGH),
 422                GPIO_LOOKUP("alchemy-gpio2", 8,
 423                            "mosi", GPIO_ACTIVE_HIGH),
 424                GPIO_LOOKUP("alchemy-gpio2", 7,
 425                            "miso", GPIO_ACTIVE_HIGH),
 426                GPIO_LOOKUP("alchemy-gpio2", 10,
 427                            "cs", GPIO_ACTIVE_HIGH),
 428                { },
 429        },
 430};
 431
 432static struct platform_device *db1x00_devs[] = {
 433        &db1x00_codec_dev,
 434        &alchemy_ac97c_dma_dev,
 435        &alchemy_ac97c_dev,
 436        &db1x00_audio_dev,
 437};
 438
 439static struct platform_device *db1100_devs[] = {
 440        &au1100_lcd_device,
 441        &db1100_mmc0_dev,
 442        &db1100_mmc1_dev,
 443};
 444
 445int __init db1000_dev_setup(void)
 446{
 447        int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
 448        int c0, c1, d0, d1, s0, s1, flashsize = 32,  twosocks = 1;
 449        unsigned long pfc;
 450        struct clk *c, *p;
 451
 452        if (board == BCSR_WHOAMI_DB1500) {
 453                c0 = AU1500_GPIO2_INT;
 454                c1 = AU1500_GPIO5_INT;
 455                d0 = 0; /* GPIO number, NOT irq! */
 456                d1 = 3; /* GPIO number, NOT irq! */
 457                s0 = AU1500_GPIO1_INT;
 458                s1 = AU1500_GPIO4_INT;
 459        } else if (board == BCSR_WHOAMI_DB1100) {
 460                c0 = AU1100_GPIO2_INT;
 461                c1 = AU1100_GPIO5_INT;
 462                d0 = 0; /* GPIO number, NOT irq! */
 463                d1 = 3; /* GPIO number, NOT irq! */
 464                s0 = AU1100_GPIO1_INT;
 465                s1 = AU1100_GPIO4_INT;
 466
 467                gpio_request(19, "sd0_cd");
 468                gpio_request(20, "sd1_cd");
 469                gpio_direction_input(19);       /* sd0 cd# */
 470                gpio_direction_input(20);       /* sd1 cd# */
 471
 472                /* spi_gpio on SSI0 pins */
 473                pfc = alchemy_rdsys(AU1000_SYS_PINFUNC);
 474                pfc |= (1 << 0);        /* SSI0 pins as GPIOs */
 475                alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);
 476
 477                spi_register_board_info(db1100_spi_info,
 478                                        ARRAY_SIZE(db1100_spi_info));
 479
 480                /* link LCD clock to AUXPLL */
 481                p = clk_get(NULL, "auxpll_clk");
 482                c = clk_get(NULL, "lcd_intclk");
 483                if (!IS_ERR(c) && !IS_ERR(p)) {
 484                        clk_set_parent(c, p);
 485                        clk_set_rate(c, clk_get_rate(p));
 486                }
 487                if (!IS_ERR(c))
 488                        clk_put(c);
 489                if (!IS_ERR(p))
 490                        clk_put(p);
 491
 492                platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
 493                gpiod_add_lookup_table(&db1100_spi_gpiod_table);
 494                platform_device_register(&db1100_spi_dev);
 495        } else if (board == BCSR_WHOAMI_DB1000) {
 496                c0 = AU1000_GPIO2_INT;
 497                c1 = AU1000_GPIO5_INT;
 498                d0 = 0; /* GPIO number, NOT irq! */
 499                d1 = 3; /* GPIO number, NOT irq! */
 500                s0 = AU1000_GPIO1_INT;
 501                s1 = AU1000_GPIO4_INT;
 502        } else if ((board == BCSR_WHOAMI_PB1500) ||
 503                   (board == BCSR_WHOAMI_PB1500R2)) {
 504                c0 = AU1500_GPIO203_INT;
 505                d0 = 1; /* GPIO number, NOT irq! */
 506                s0 = AU1500_GPIO202_INT;
 507                twosocks = 0;
 508                flashsize = 64;
 509                /* RTC and daughtercard irqs */
 510                irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_LOW);
 511                irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
 512                /* EPSON S1D13806 0x1b000000
 513                 * SRAM 1MB/2MB   0x1a000000
 514                 * DS1693 RTC     0x0c000000
 515                 */
 516        } else if (board == BCSR_WHOAMI_PB1100) {
 517                c0 = AU1100_GPIO11_INT;
 518                d0 = 9; /* GPIO number, NOT irq! */
 519                s0 = AU1100_GPIO10_INT;
 520                twosocks = 0;
 521                flashsize = 64;
 522                /* pendown, rtc, daughtercard irqs */
 523                irq_set_irq_type(AU1100_GPIO8_INT, IRQ_TYPE_LEVEL_LOW);
 524                irq_set_irq_type(AU1100_GPIO12_INT, IRQ_TYPE_LEVEL_LOW);
 525                irq_set_irq_type(AU1100_GPIO13_INT, IRQ_TYPE_LEVEL_LOW);
 526                /* EPSON S1D13806 0x1b000000
 527                 * SRAM 1MB/2MB   0x1a000000
 528                 * DiskOnChip     0x0d000000
 529                 * DS1693 RTC     0x0c000000
 530                 */
 531                platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
 532        } else
 533                return 0; /* unknown board, no further dev setup to do */
 534
 535        irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW);
 536        irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW);
 537
 538        db1x_register_pcmcia_socket(
 539                AU1000_PCMCIA_ATTR_PHYS_ADDR,
 540                AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
 541                AU1000_PCMCIA_MEM_PHYS_ADDR,
 542                AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x000400000 - 1,
 543                AU1000_PCMCIA_IO_PHYS_ADDR,
 544                AU1000_PCMCIA_IO_PHYS_ADDR   + 0x000010000 - 1,
 545                c0, d0, /*s0*/0, 0, 0);
 546
 547        if (twosocks) {
 548                irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
 549                irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
 550
 551                db1x_register_pcmcia_socket(
 552                        AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
 553                        AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
 554                        AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x004000000,
 555                        AU1000_PCMCIA_MEM_PHYS_ADDR  + 0x004400000 - 1,
 556                        AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004000000,
 557                        AU1000_PCMCIA_IO_PHYS_ADDR   + 0x004010000 - 1,
 558                        c1, d1, /*s1*/0, 0, 1);
 559        }
 560
 561        platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs));
 562        db1x_register_norflash(flashsize << 20, 4 /* 32bit */, F_SWAPPED);
 563        return 0;
 564}
 565