linux/arch/arm/mach-orion5x/ts409-setup.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * QNAP TS-409 Board Setup
   4 *
   5 * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com>
   6 *
   7 * Copyright (C) 2008  Sylver Bruneau <sylver.bruneau@gmail.com>
   8 * Copyright (C) 2008  Martin Michlmayr <tbm@cyrius.com>
   9 */
  10#include <linux/gpio.h>
  11#include <linux/kernel.h>
  12#include <linux/init.h>
  13#include <linux/platform_device.h>
  14#include <linux/pci.h>
  15#include <linux/irq.h>
  16#include <linux/mtd/physmap.h>
  17#include <linux/mv643xx_eth.h>
  18#include <linux/leds.h>
  19#include <linux/gpio_keys.h>
  20#include <linux/input.h>
  21#include <linux/i2c.h>
  22#include <linux/serial_reg.h>
  23#include <asm/mach-types.h>
  24#include <asm/mach/arch.h>
  25#include <asm/mach/pci.h>
  26#include "common.h"
  27#include "mpp.h"
  28#include "orion5x.h"
  29#include "tsx09-common.h"
  30
  31/*****************************************************************************
  32 * QNAP TS-409 Info
  33 ****************************************************************************/
  34
  35/*
  36 * QNAP TS-409 hardware :
  37 * - Marvell 88F5281-D0
  38 * - Marvell 88SX7042 SATA controller (PCIe)
  39 * - Marvell 88E1118 Gigabit Ethernet PHY
  40 * - RTC S35390A (@0x30) on I2C bus
  41 * - 8MB NOR flash
  42 * - 256MB of DDR-2 RAM
  43 */
  44
  45/*
  46 * 8MB NOR flash Device bus boot chip select
  47 */
  48
  49#define QNAP_TS409_NOR_BOOT_BASE 0xff800000
  50#define QNAP_TS409_NOR_BOOT_SIZE SZ_8M
  51
  52/****************************************************************************
  53 * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
  54 *     partitions on the device because we want to keep compatibility with
  55 *     existing QNAP firmware.
  56 *
  57 * Layout as used by QNAP:
  58 *  [2] 0x00000000-0x00200000 : "Kernel"
  59 *  [3] 0x00200000-0x00600000 : "RootFS1"
  60 *  [4] 0x00600000-0x00700000 : "RootFS2"
  61 *  [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
  62 *  [5] 0x00760000-0x00780000 : "U-Boot Config"
  63 *  [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
  64 ***************************************************************************/
  65static struct mtd_partition qnap_ts409_partitions[] = {
  66        {
  67                .name           = "U-Boot",
  68                .size           = 0x00080000,
  69                .offset         = 0x00780000,
  70                .mask_flags     = MTD_WRITEABLE,
  71        }, {
  72                .name           = "Kernel",
  73                .size           = 0x00200000,
  74                .offset         = 0,
  75        }, {
  76                .name           = "RootFS1",
  77                .size           = 0x00400000,
  78                .offset         = 0x00200000,
  79        }, {
  80                .name           = "RootFS2",
  81                .size           = 0x00100000,
  82                .offset         = 0x00600000,
  83        }, {
  84                .name           = "U-Boot Config",
  85                .size           = 0x00020000,
  86                .offset         = 0x00760000,
  87        }, {
  88                .name           = "NAS Config",
  89                .size           = 0x00060000,
  90                .offset         = 0x00700000,
  91                .mask_flags     = MTD_WRITEABLE,
  92        },
  93};
  94
  95static struct physmap_flash_data qnap_ts409_nor_flash_data = {
  96        .width          = 1,
  97        .parts          = qnap_ts409_partitions,
  98        .nr_parts       = ARRAY_SIZE(qnap_ts409_partitions)
  99};
 100
 101static struct resource qnap_ts409_nor_flash_resource = {
 102        .flags  = IORESOURCE_MEM,
 103        .start  = QNAP_TS409_NOR_BOOT_BASE,
 104        .end    = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1,
 105};
 106
 107static struct platform_device qnap_ts409_nor_flash = {
 108        .name           = "physmap-flash",
 109        .id             = 0,
 110        .dev            = { .platform_data = &qnap_ts409_nor_flash_data, },
 111        .num_resources  = 1,
 112        .resource       = &qnap_ts409_nor_flash_resource,
 113};
 114
 115/*****************************************************************************
 116 * PCI
 117 ****************************************************************************/
 118
 119static int __init qnap_ts409_pci_map_irq(const struct pci_dev *dev, u8 slot,
 120        u8 pin)
 121{
 122        int irq;
 123
 124        /*
 125         * Check for devices with hard-wired IRQs.
 126         */
 127        irq = orion5x_pci_map_irq(dev, slot, pin);
 128        if (irq != -1)
 129                return irq;
 130
 131        /*
 132         * PCI isn't used on the TS-409
 133         */
 134        return -1;
 135}
 136
 137static struct hw_pci qnap_ts409_pci __initdata = {
 138        .nr_controllers = 2,
 139        .setup          = orion5x_pci_sys_setup,
 140        .scan           = orion5x_pci_sys_scan_bus,
 141        .map_irq        = qnap_ts409_pci_map_irq,
 142};
 143
 144static int __init qnap_ts409_pci_init(void)
 145{
 146        if (machine_is_ts409())
 147                pci_common_init(&qnap_ts409_pci);
 148
 149        return 0;
 150}
 151
 152subsys_initcall(qnap_ts409_pci_init);
 153
 154/*****************************************************************************
 155 * RTC S35390A on I2C bus
 156 ****************************************************************************/
 157
 158#define TS409_RTC_GPIO  10
 159
 160static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = {
 161        I2C_BOARD_INFO("s35390a", 0x30),
 162};
 163
 164/*****************************************************************************
 165 * LEDs attached to GPIO
 166 ****************************************************************************/
 167
 168static struct gpio_led ts409_led_pins[] = {
 169        {
 170                .name           = "ts409:red:sata1",
 171                .gpio           = 4,
 172                .active_low     = 1,
 173        }, {
 174                .name           = "ts409:red:sata2",
 175                .gpio           = 5,
 176                .active_low     = 1,
 177        }, {
 178                .name           = "ts409:red:sata3",
 179                .gpio           = 6,
 180                .active_low     = 1,
 181        }, {
 182                .name           = "ts409:red:sata4",
 183                .gpio           = 7,
 184                .active_low     = 1,
 185        },
 186};
 187
 188static struct gpio_led_platform_data ts409_led_data = {
 189        .leds           = ts409_led_pins,
 190        .num_leds       = ARRAY_SIZE(ts409_led_pins),
 191};
 192
 193static struct platform_device ts409_leds = {
 194        .name   = "leds-gpio",
 195        .id     = -1,
 196        .dev    = {
 197                .platform_data  = &ts409_led_data,
 198        },
 199};
 200
 201/****************************************************************************
 202 * GPIO Attached Keys
 203 *     Power button is attached to the PIC microcontroller
 204 ****************************************************************************/
 205
 206#define QNAP_TS409_GPIO_KEY_RESET       14
 207#define QNAP_TS409_GPIO_KEY_MEDIA       15
 208
 209static struct gpio_keys_button qnap_ts409_buttons[] = {
 210        {
 211                .code           = KEY_RESTART,
 212                .gpio           = QNAP_TS409_GPIO_KEY_RESET,
 213                .desc           = "Reset Button",
 214                .active_low     = 1,
 215        }, {
 216                .code           = KEY_COPY,
 217                .gpio           = QNAP_TS409_GPIO_KEY_MEDIA,
 218                .desc           = "USB Copy Button",
 219                .active_low     = 1,
 220        },
 221};
 222
 223static struct gpio_keys_platform_data qnap_ts409_button_data = {
 224        .buttons        = qnap_ts409_buttons,
 225        .nbuttons       = ARRAY_SIZE(qnap_ts409_buttons),
 226};
 227
 228static struct platform_device qnap_ts409_button_device = {
 229        .name           = "gpio-keys",
 230        .id             = -1,
 231        .num_resources  = 0,
 232        .dev            = {
 233                .platform_data  = &qnap_ts409_button_data,
 234        },
 235};
 236
 237/*****************************************************************************
 238 * General Setup
 239 ****************************************************************************/
 240static unsigned int ts409_mpp_modes[] __initdata = {
 241        MPP0_UNUSED,
 242        MPP1_UNUSED,
 243        MPP2_UNUSED,
 244        MPP3_UNUSED,
 245        MPP4_GPIO,              /* HDD 1 status */
 246        MPP5_GPIO,              /* HDD 2 status */
 247        MPP6_GPIO,              /* HDD 3 status */
 248        MPP7_GPIO,              /* HDD 4 status */
 249        MPP8_UNUSED,
 250        MPP9_UNUSED,
 251        MPP10_GPIO,             /* RTC int */
 252        MPP11_UNUSED,
 253        MPP12_UNUSED,
 254        MPP13_UNUSED,
 255        MPP14_GPIO,             /* SW_RST */
 256        MPP15_GPIO,             /* USB copy button */
 257        MPP16_UART,             /* UART1 RXD */
 258        MPP17_UART,             /* UART1 TXD */
 259        MPP18_UNUSED,
 260        MPP19_UNUSED,
 261        0,
 262};
 263
 264static void __init qnap_ts409_init(void)
 265{
 266        /*
 267         * Setup basic Orion functions. Need to be called early.
 268         */
 269        orion5x_init();
 270
 271        orion5x_mpp_conf(ts409_mpp_modes);
 272
 273        /*
 274         * Configure peripherals.
 275         */
 276        mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
 277                                    ORION_MBUS_DEVBUS_BOOT_ATTR,
 278                                    QNAP_TS409_NOR_BOOT_BASE,
 279                                    QNAP_TS409_NOR_BOOT_SIZE);
 280        platform_device_register(&qnap_ts409_nor_flash);
 281
 282        orion5x_ehci0_init();
 283        qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE +
 284                                 qnap_ts409_partitions[5].offset,
 285                                 qnap_ts409_partitions[5].size);
 286        orion5x_eth_init(&qnap_tsx09_eth_data);
 287        orion5x_i2c_init();
 288        orion5x_uart0_init();
 289        orion5x_uart1_init();
 290
 291        platform_device_register(&qnap_ts409_button_device);
 292
 293        /* Get RTC IRQ and register the chip */
 294        if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) {
 295                if (gpio_direction_input(TS409_RTC_GPIO) == 0)
 296                        qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO);
 297                else
 298                        gpio_free(TS409_RTC_GPIO);
 299        }
 300        if (qnap_ts409_i2c_rtc.irq == 0)
 301                pr_warn("qnap_ts409_init: failed to get RTC IRQ\n");
 302        i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1);
 303        platform_device_register(&ts409_leds);
 304
 305        /* register tsx09 specific power-off method */
 306        pm_power_off = qnap_tsx09_power_off;
 307}
 308
 309MACHINE_START(TS409, "QNAP TS-409")
 310        /* Maintainer:  Sylver Bruneau <sylver.bruneau@gmail.com> */
 311        .atag_offset    = 0x100,
 312        .nr_irqs        = ORION5X_NR_IRQS,
 313        .init_machine   = qnap_ts409_init,
 314        .map_io         = orion5x_map_io,
 315        .init_early     = orion5x_init_early,
 316        .init_irq       = orion5x_init_irq,
 317        .init_time      = orion5x_timer_init,
 318        .fixup          = tag_fixup_mem32,
 319        .restart        = orion5x_restart,
 320MACHINE_END
 321