Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * MTX-1 platform devices registration (Au1500)
0004  *
0005  * Copyright (C) 2007-2009, Florian Fainelli <florian@openwrt.org>
0006  */
0007 
0008 #include <linux/init.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/kernel.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/leds.h>
0013 #include <linux/gpio.h>
0014 #include <linux/gpio/machine.h>
0015 #include <linux/gpio_keys.h>
0016 #include <linux/input.h>
0017 #include <linux/mtd/partitions.h>
0018 #include <linux/mtd/physmap.h>
0019 #include <mtd/mtd-abi.h>
0020 #include <asm/bootinfo.h>
0021 #include <asm/reboot.h>
0022 #include <asm/setup.h>
0023 #include <asm/mach-au1x00/au1000.h>
0024 #include <asm/mach-au1x00/gpio-au1000.h>
0025 #include <asm/mach-au1x00/au1xxx_eth.h>
0026 #include <prom.h>
0027 
0028 const char *get_system_type(void)
0029 {
0030     return "MTX-1";
0031 }
0032 
0033 void prom_putchar(char c)
0034 {
0035     alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
0036 }
0037 
0038 static void mtx1_reset(char *c)
0039 {
0040     /* Jump to the reset vector */
0041     __asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000));
0042 }
0043 
0044 static void mtx1_power_off(void)
0045 {
0046     while (1)
0047         asm volatile (
0048         "   .set    mips32                  \n"
0049         "   wait                        \n"
0050         "   .set    mips0                   \n");
0051 }
0052 
0053 void __init board_setup(void)
0054 {
0055 #if IS_ENABLED(CONFIG_USB_OHCI_HCD)
0056     /* Enable USB power switch */
0057     alchemy_gpio_direction_output(204, 0);
0058 #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
0059 
0060     /* Initialize sys_pinfunc */
0061     alchemy_wrsys(SYS_PF_NI2, AU1000_SYS_PINFUNC);
0062 
0063     /* Initialize GPIO */
0064     alchemy_wrsys(~0, AU1000_SYS_TRIOUTCLR);
0065     alchemy_gpio_direction_output(0, 0);    /* Disable M66EN (PCI 66MHz) */
0066     alchemy_gpio_direction_output(3, 1);    /* Disable PCI CLKRUN# */
0067     alchemy_gpio_direction_output(1, 1);    /* Enable EXT_IO3 */
0068     alchemy_gpio_direction_output(5, 0);    /* Disable eth PHY TX_ER */
0069 
0070     /* Enable LED and set it to green */
0071     alchemy_gpio_direction_output(211, 1);  /* green on */
0072     alchemy_gpio_direction_output(212, 0);  /* red off */
0073 
0074     pm_power_off = mtx1_power_off;
0075     _machine_halt = mtx1_power_off;
0076     _machine_restart = mtx1_reset;
0077 
0078     printk(KERN_INFO "4G Systems MTX-1 Board\n");
0079 }
0080 
0081 /******************************************************************************/
0082 
0083 static struct gpio_keys_button mtx1_gpio_button[] = {
0084     {
0085         .gpio = 207,
0086         .code = BTN_0,
0087         .desc = "System button",
0088     }
0089 };
0090 
0091 static struct gpio_keys_platform_data mtx1_buttons_data = {
0092     .buttons = mtx1_gpio_button,
0093     .nbuttons = ARRAY_SIZE(mtx1_gpio_button),
0094 };
0095 
0096 static struct platform_device mtx1_button = {
0097     .name = "gpio-keys",
0098     .id = -1,
0099     .dev = {
0100         .platform_data = &mtx1_buttons_data,
0101     }
0102 };
0103 
0104 static struct gpiod_lookup_table mtx1_wdt_gpio_table = {
0105     .dev_id = "mtx1-wdt.0",
0106     .table = {
0107         /* Global number 215 is offset 15 on Alchemy GPIO 2 */
0108         GPIO_LOOKUP("alchemy-gpio2", 15, NULL, GPIO_ACTIVE_HIGH),
0109         { },
0110     },
0111 };
0112 
0113 static struct platform_device mtx1_wdt = {
0114     .name = "mtx1-wdt",
0115     .id = 0,
0116 };
0117 
0118 static const struct gpio_led default_leds[] = {
0119     {
0120         .name   = "mtx1:green",
0121         .gpio = 211,
0122     }, {
0123         .name = "mtx1:red",
0124         .gpio = 212,
0125     },
0126 };
0127 
0128 static struct gpio_led_platform_data mtx1_led_data = {
0129     .num_leds = ARRAY_SIZE(default_leds),
0130     .leds = default_leds,
0131 };
0132 
0133 static struct platform_device mtx1_gpio_leds = {
0134     .name = "leds-gpio",
0135     .id = -1,
0136     .dev = {
0137         .platform_data = &mtx1_led_data,
0138     }
0139 };
0140 
0141 static struct mtd_partition mtx1_mtd_partitions[] = {
0142     {
0143         .name   = "filesystem",
0144         .size   = 0x01C00000,
0145         .offset = 0,
0146     },
0147     {
0148         .name   = "yamon",
0149         .size   = 0x00100000,
0150         .offset = MTDPART_OFS_APPEND,
0151         .mask_flags = MTD_WRITEABLE,
0152     },
0153     {
0154         .name   = "kernel",
0155         .size   = 0x002c0000,
0156         .offset = MTDPART_OFS_APPEND,
0157     },
0158     {
0159         .name   = "yamon env",
0160         .size   = 0x00040000,
0161         .offset = MTDPART_OFS_APPEND,
0162     },
0163 };
0164 
0165 static struct physmap_flash_data mtx1_flash_data = {
0166     .width      = 4,
0167     .nr_parts   = 4,
0168     .parts      = mtx1_mtd_partitions,
0169 };
0170 
0171 static struct resource mtx1_mtd_resource = {
0172     .start  = 0x1e000000,
0173     .end    = 0x1fffffff,
0174     .flags  = IORESOURCE_MEM,
0175 };
0176 
0177 static struct platform_device mtx1_mtd = {
0178     .name       = "physmap-flash",
0179     .dev        = {
0180         .platform_data  = &mtx1_flash_data,
0181     },
0182     .num_resources  = 1,
0183     .resource   = &mtx1_mtd_resource,
0184 };
0185 
0186 static struct resource alchemy_pci_host_res[] = {
0187     [0] = {
0188         .start  = AU1500_PCI_PHYS_ADDR,
0189         .end    = AU1500_PCI_PHYS_ADDR + 0xfff,
0190         .flags  = IORESOURCE_MEM,
0191     },
0192 };
0193 
0194 static int mtx1_pci_idsel(unsigned int devsel, int assert)
0195 {
0196     /* This function is only necessary to support a proprietary Cardbus
0197      * adapter on the mtx-1 "singleboard" variant. It triggers a custom
0198      * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
0199      */
0200     udelay(1);
0201 
0202     if (assert && devsel != 0)
0203         /* Suppress signal to Cardbus */
0204         alchemy_gpio_set_value(1, 0);   /* set EXT_IO3 OFF */
0205     else
0206         alchemy_gpio_set_value(1, 1);   /* set EXT_IO3 ON */
0207 
0208     udelay(1);
0209     return 1;
0210 }
0211 
0212 static const char mtx1_irqtab[][5] = {
0213     [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
0214     [1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
0215     [2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
0216     [3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
0217     [4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
0218     [5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
0219     [6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
0220     [7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
0221 };
0222 
0223 static int mtx1_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
0224 {
0225     return mtx1_irqtab[slot][pin];
0226 }
0227 
0228 static struct alchemy_pci_platdata mtx1_pci_pd = {
0229     .board_map_irq   = mtx1_map_pci_irq,
0230     .board_pci_idsel = mtx1_pci_idsel,
0231     .pci_cfg_set     = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
0232                PCI_CONFIG_CH |
0233 #if defined(__MIPSEB__)
0234                PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
0235 #else
0236                0,
0237 #endif
0238 };
0239 
0240 static struct platform_device mtx1_pci_host = {
0241     .dev.platform_data = &mtx1_pci_pd,
0242     .name       = "alchemy-pci",
0243     .id     = 0,
0244     .num_resources  = ARRAY_SIZE(alchemy_pci_host_res),
0245     .resource   = alchemy_pci_host_res,
0246 };
0247 
0248 static struct platform_device *mtx1_devs[] __initdata = {
0249     &mtx1_pci_host,
0250     &mtx1_gpio_leds,
0251     &mtx1_wdt,
0252     &mtx1_button,
0253     &mtx1_mtd,
0254 };
0255 
0256 static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = {
0257     .phy_search_highest_addr    = 1,
0258     .phy1_search_mac0       = 1,
0259 };
0260 
0261 static int __init mtx1_register_devices(void)
0262 {
0263     int rc;
0264 
0265     irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH);
0266     irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW);
0267     irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW);
0268     irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW);
0269     irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
0270 
0271     au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
0272 
0273     rc = gpio_request(mtx1_gpio_button[0].gpio,
0274                     mtx1_gpio_button[0].desc);
0275     if (rc < 0) {
0276         printk(KERN_INFO "mtx1: failed to request %d\n",
0277                     mtx1_gpio_button[0].gpio);
0278         goto out;
0279     }
0280     gpio_direction_input(mtx1_gpio_button[0].gpio);
0281 out:
0282     gpiod_add_lookup_table(&mtx1_wdt_gpio_table);
0283     return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
0284 }
0285 arch_initcall(mtx1_register_devices);