root/arch/mips/alchemy/board-mtx1.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_system_type
  2. prom_init
  3. prom_putchar
  4. mtx1_reset
  5. mtx1_power_off
  6. board_setup
  7. mtx1_pci_idsel
  8. mtx1_map_pci_irq
  9. mtx1_register_devices

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * MTX-1 platform devices registration (Au1500)
   4  *
   5  * Copyright (C) 2007-2009, Florian Fainelli <florian@openwrt.org>
   6  */
   7 
   8 #include <linux/init.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/kernel.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/leds.h>
  13 #include <linux/gpio.h>
  14 #include <linux/gpio/machine.h>
  15 #include <linux/gpio_keys.h>
  16 #include <linux/input.h>
  17 #include <linux/mtd/partitions.h>
  18 #include <linux/mtd/physmap.h>
  19 #include <mtd/mtd-abi.h>
  20 #include <asm/bootinfo.h>
  21 #include <asm/reboot.h>
  22 #include <asm/setup.h>
  23 #include <asm/mach-au1x00/au1000.h>
  24 #include <asm/mach-au1x00/gpio-au1000.h>
  25 #include <asm/mach-au1x00/au1xxx_eth.h>
  26 #include <prom.h>
  27 
  28 const char *get_system_type(void)
  29 {
  30         return "MTX-1";
  31 }
  32 
  33 void __init prom_init(void)
  34 {
  35         unsigned char *memsize_str;
  36         unsigned long memsize;
  37 
  38         prom_argc = fw_arg0;
  39         prom_argv = (char **)fw_arg1;
  40         prom_envp = (char **)fw_arg2;
  41 
  42         prom_init_cmdline();
  43 
  44         memsize_str = prom_getenv("memsize");
  45         if (!memsize_str || kstrtoul(memsize_str, 0, &memsize))
  46                 memsize = 0x04000000;
  47         add_memory_region(0, memsize, BOOT_MEM_RAM);
  48 }
  49 
  50 void prom_putchar(char c)
  51 {
  52         alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
  53 }
  54 
  55 static void mtx1_reset(char *c)
  56 {
  57         /* Jump to the reset vector */
  58         __asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000));
  59 }
  60 
  61 static void mtx1_power_off(void)
  62 {
  63         while (1)
  64                 asm volatile (
  65                 "       .set    mips32                                  \n"
  66                 "       wait                                            \n"
  67                 "       .set    mips0                                   \n");
  68 }
  69 
  70 void __init board_setup(void)
  71 {
  72 #if IS_ENABLED(CONFIG_USB_OHCI_HCD)
  73         /* Enable USB power switch */
  74         alchemy_gpio_direction_output(204, 0);
  75 #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
  76 
  77         /* Initialize sys_pinfunc */
  78         alchemy_wrsys(SYS_PF_NI2, AU1000_SYS_PINFUNC);
  79 
  80         /* Initialize GPIO */
  81         alchemy_wrsys(~0, AU1000_SYS_TRIOUTCLR);
  82         alchemy_gpio_direction_output(0, 0);    /* Disable M66EN (PCI 66MHz) */
  83         alchemy_gpio_direction_output(3, 1);    /* Disable PCI CLKRUN# */
  84         alchemy_gpio_direction_output(1, 1);    /* Enable EXT_IO3 */
  85         alchemy_gpio_direction_output(5, 0);    /* Disable eth PHY TX_ER */
  86 
  87         /* Enable LED and set it to green */
  88         alchemy_gpio_direction_output(211, 1);  /* green on */
  89         alchemy_gpio_direction_output(212, 0);  /* red off */
  90 
  91         pm_power_off = mtx1_power_off;
  92         _machine_halt = mtx1_power_off;
  93         _machine_restart = mtx1_reset;
  94 
  95         printk(KERN_INFO "4G Systems MTX-1 Board\n");
  96 }
  97 
  98 /******************************************************************************/
  99 
 100 static struct gpio_keys_button mtx1_gpio_button[] = {
 101         {
 102                 .gpio = 207,
 103                 .code = BTN_0,
 104                 .desc = "System button",
 105         }
 106 };
 107 
 108 static struct gpio_keys_platform_data mtx1_buttons_data = {
 109         .buttons = mtx1_gpio_button,
 110         .nbuttons = ARRAY_SIZE(mtx1_gpio_button),
 111 };
 112 
 113 static struct platform_device mtx1_button = {
 114         .name = "gpio-keys",
 115         .id = -1,
 116         .dev = {
 117                 .platform_data = &mtx1_buttons_data,
 118         }
 119 };
 120 
 121 static struct gpiod_lookup_table mtx1_wdt_gpio_table = {
 122         .dev_id = "mtx1-wdt.0",
 123         .table = {
 124                 /* Global number 215 is offset 15 on Alchemy GPIO 2 */
 125                 GPIO_LOOKUP("alchemy-gpio2", 15, NULL, GPIO_ACTIVE_HIGH),
 126                 { },
 127         },
 128 };
 129 
 130 static struct platform_device mtx1_wdt = {
 131         .name = "mtx1-wdt",
 132         .id = 0,
 133 };
 134 
 135 static const struct gpio_led default_leds[] = {
 136         {
 137                 .name   = "mtx1:green",
 138                 .gpio = 211,
 139         }, {
 140                 .name = "mtx1:red",
 141                 .gpio = 212,
 142         },
 143 };
 144 
 145 static struct gpio_led_platform_data mtx1_led_data = {
 146         .num_leds = ARRAY_SIZE(default_leds),
 147         .leds = default_leds,
 148 };
 149 
 150 static struct platform_device mtx1_gpio_leds = {
 151         .name = "leds-gpio",
 152         .id = -1,
 153         .dev = {
 154                 .platform_data = &mtx1_led_data,
 155         }
 156 };
 157 
 158 static struct mtd_partition mtx1_mtd_partitions[] = {
 159         {
 160                 .name   = "filesystem",
 161                 .size   = 0x01C00000,
 162                 .offset = 0,
 163         },
 164         {
 165                 .name   = "yamon",
 166                 .size   = 0x00100000,
 167                 .offset = MTDPART_OFS_APPEND,
 168                 .mask_flags = MTD_WRITEABLE,
 169         },
 170         {
 171                 .name   = "kernel",
 172                 .size   = 0x002c0000,
 173                 .offset = MTDPART_OFS_APPEND,
 174         },
 175         {
 176                 .name   = "yamon env",
 177                 .size   = 0x00040000,
 178                 .offset = MTDPART_OFS_APPEND,
 179         },
 180 };
 181 
 182 static struct physmap_flash_data mtx1_flash_data = {
 183         .width          = 4,
 184         .nr_parts       = 4,
 185         .parts          = mtx1_mtd_partitions,
 186 };
 187 
 188 static struct resource mtx1_mtd_resource = {
 189         .start  = 0x1e000000,
 190         .end    = 0x1fffffff,
 191         .flags  = IORESOURCE_MEM,
 192 };
 193 
 194 static struct platform_device mtx1_mtd = {
 195         .name           = "physmap-flash",
 196         .dev            = {
 197                 .platform_data  = &mtx1_flash_data,
 198         },
 199         .num_resources  = 1,
 200         .resource       = &mtx1_mtd_resource,
 201 };
 202 
 203 static struct resource alchemy_pci_host_res[] = {
 204         [0] = {
 205                 .start  = AU1500_PCI_PHYS_ADDR,
 206                 .end    = AU1500_PCI_PHYS_ADDR + 0xfff,
 207                 .flags  = IORESOURCE_MEM,
 208         },
 209 };
 210 
 211 static int mtx1_pci_idsel(unsigned int devsel, int assert)
 212 {
 213         /* This function is only necessary to support a proprietary Cardbus
 214          * adapter on the mtx-1 "singleboard" variant. It triggers a custom
 215          * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
 216          */
 217         udelay(1);
 218 
 219         if (assert && devsel != 0)
 220                 /* Suppress signal to Cardbus */
 221                 alchemy_gpio_set_value(1, 0);   /* set EXT_IO3 OFF */
 222         else
 223                 alchemy_gpio_set_value(1, 1);   /* set EXT_IO3 ON */
 224 
 225         udelay(1);
 226         return 1;
 227 }
 228 
 229 static const char mtx1_irqtab[][5] = {
 230         [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
 231         [1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
 232         [2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
 233         [3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
 234         [4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
 235         [5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
 236         [6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
 237         [7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
 238 };
 239 
 240 static int mtx1_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
 241 {
 242         return mtx1_irqtab[slot][pin];
 243 }
 244 
 245 static struct alchemy_pci_platdata mtx1_pci_pd = {
 246         .board_map_irq   = mtx1_map_pci_irq,
 247         .board_pci_idsel = mtx1_pci_idsel,
 248         .pci_cfg_set     = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
 249                            PCI_CONFIG_CH |
 250 #if defined(__MIPSEB__)
 251                            PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
 252 #else
 253                            0,
 254 #endif
 255 };
 256 
 257 static struct platform_device mtx1_pci_host = {
 258         .dev.platform_data = &mtx1_pci_pd,
 259         .name           = "alchemy-pci",
 260         .id             = 0,
 261         .num_resources  = ARRAY_SIZE(alchemy_pci_host_res),
 262         .resource       = alchemy_pci_host_res,
 263 };
 264 
 265 static struct platform_device *mtx1_devs[] __initdata = {
 266         &mtx1_pci_host,
 267         &mtx1_gpio_leds,
 268         &mtx1_wdt,
 269         &mtx1_button,
 270         &mtx1_mtd,
 271 };
 272 
 273 static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = {
 274         .phy_search_highest_addr        = 1,
 275         .phy1_search_mac0               = 1,
 276 };
 277 
 278 static int __init mtx1_register_devices(void)
 279 {
 280         int rc;
 281 
 282         irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH);
 283         irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW);
 284         irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW);
 285         irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW);
 286         irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
 287 
 288         au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
 289 
 290         rc = gpio_request(mtx1_gpio_button[0].gpio,
 291                                         mtx1_gpio_button[0].desc);
 292         if (rc < 0) {
 293                 printk(KERN_INFO "mtx1: failed to request %d\n",
 294                                         mtx1_gpio_button[0].gpio);
 295                 goto out;
 296         }
 297         gpio_direction_input(mtx1_gpio_button[0].gpio);
 298 out:
 299         gpiod_add_lookup_table(&mtx1_wdt_gpio_table);
 300         return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
 301 }
 302 arch_initcall(mtx1_register_devices);

/* [<][>][^][v][top][bottom][index][help] */