Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Buffalo Terastation Pro II/Live Board Setup
0004  *
0005  * Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com>
0006  */
0007 #include <linux/gpio.h>
0008 #include <linux/kernel.h>
0009 #include <linux/init.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/pci.h>
0012 #include <linux/irq.h>
0013 #include <linux/delay.h>
0014 #include <linux/mtd/physmap.h>
0015 #include <linux/mv643xx_eth.h>
0016 #include <linux/i2c.h>
0017 #include <linux/serial_reg.h>
0018 #include <asm/mach-types.h>
0019 #include <asm/mach/arch.h>
0020 #include <asm/mach/pci.h>
0021 #include "common.h"
0022 #include "mpp.h"
0023 #include "orion5x.h"
0024 
0025 /*****************************************************************************
0026  * Terastation Pro 2/Live Info
0027  ****************************************************************************/
0028 
0029 /*
0030  * Terastation Pro 2 hardware :
0031  * - Marvell 88F5281-D0
0032  * - Marvell 88SX6042 SATA controller (PCI)
0033  * - Marvell 88E1118 Gigabit Ethernet PHY
0034  * - 256KB NOR flash
0035  * - 128MB of DDR RAM
0036  * - PCIe port (not equipped)
0037  */
0038 
0039 /*
0040  * 256K NOR flash Device bus boot chip select
0041  */
0042 
0043 #define TSP2_NOR_BOOT_BASE  0xf4000000
0044 #define TSP2_NOR_BOOT_SIZE  SZ_256K
0045 
0046 /*****************************************************************************
0047  * 256KB NOR Flash on BOOT Device
0048  ****************************************************************************/
0049 
0050 static struct physmap_flash_data tsp2_nor_flash_data = {
0051     .width    = 1,
0052 };
0053 
0054 static struct resource tsp2_nor_flash_resource = {
0055     .flags = IORESOURCE_MEM,
0056     .start = TSP2_NOR_BOOT_BASE,
0057     .end   = TSP2_NOR_BOOT_BASE + TSP2_NOR_BOOT_SIZE - 1,
0058 };
0059 
0060 static struct platform_device tsp2_nor_flash = {
0061     .name          = "physmap-flash",
0062     .id            = 0,
0063     .dev           = {
0064         .platform_data  = &tsp2_nor_flash_data,
0065     },
0066     .num_resources = 1,
0067     .resource      = &tsp2_nor_flash_resource,
0068 };
0069 
0070 /*****************************************************************************
0071  * PCI
0072  ****************************************************************************/
0073 #define TSP2_PCI_SLOT0_OFFS     7
0074 #define TSP2_PCI_SLOT0_IRQ_PIN      11
0075 
0076 static void __init tsp2_pci_preinit(void)
0077 {
0078     int pin;
0079 
0080     /*
0081      * Configure PCI GPIO IRQ pins
0082      */
0083     pin = TSP2_PCI_SLOT0_IRQ_PIN;
0084     if (gpio_request(pin, "PCI Int1") == 0) {
0085         if (gpio_direction_input(pin) == 0) {
0086             irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
0087         } else {
0088             printk(KERN_ERR "tsp2_pci_preinit failed "
0089                     "to set_irq_type pin %d\n", pin);
0090             gpio_free(pin);
0091         }
0092     } else {
0093         printk(KERN_ERR "tsp2_pci_preinit failed to "
0094                 "gpio_request %d\n", pin);
0095     }
0096 }
0097 
0098 static int __init tsp2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
0099 {
0100     int irq;
0101 
0102     /*
0103      * Check for devices with hard-wired IRQs.
0104      */
0105     irq = orion5x_pci_map_irq(dev, slot, pin);
0106     if (irq != -1)
0107         return irq;
0108 
0109     /*
0110      * PCI IRQs are connected via GPIOs.
0111      */
0112     if (slot == TSP2_PCI_SLOT0_OFFS)
0113         return gpio_to_irq(TSP2_PCI_SLOT0_IRQ_PIN);
0114 
0115     return -1;
0116 }
0117 
0118 static struct hw_pci tsp2_pci __initdata = {
0119     .nr_controllers = 2,
0120     .preinit        = tsp2_pci_preinit,
0121     .setup          = orion5x_pci_sys_setup,
0122     .scan           = orion5x_pci_sys_scan_bus,
0123     .map_irq        = tsp2_pci_map_irq,
0124 };
0125 
0126 static int __init tsp2_pci_init(void)
0127 {
0128     if (machine_is_terastation_pro2())
0129         pci_common_init(&tsp2_pci);
0130 
0131     return 0;
0132 }
0133 
0134 subsys_initcall(tsp2_pci_init);
0135 
0136 /*****************************************************************************
0137  * Ethernet
0138  ****************************************************************************/
0139 
0140 static struct mv643xx_eth_platform_data tsp2_eth_data = {
0141     .phy_addr   = 0,
0142 };
0143 
0144 /*****************************************************************************
0145  * RTC 5C372a on I2C bus
0146  ****************************************************************************/
0147 
0148 #define TSP2_RTC_GPIO   9
0149 
0150 static struct i2c_board_info __initdata tsp2_i2c_rtc = {
0151     I2C_BOARD_INFO("rs5c372a", 0x32),
0152 };
0153 
0154 /*****************************************************************************
0155  * Terastation Pro II specific power off method via UART1-attached
0156  * microcontroller
0157  ****************************************************************************/
0158 
0159 #define UART1_REG(x)    (UART1_VIRT_BASE + ((UART_##x) << 2))
0160 
0161 static int tsp2_miconread(unsigned char *buf, int count)
0162 {
0163     int i;
0164     int timeout;
0165 
0166     for (i = 0; i < count; i++) {
0167         timeout = 10;
0168 
0169         while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
0170             if (--timeout == 0)
0171                 break;
0172             udelay(1000);
0173         }
0174 
0175         if (timeout == 0)
0176             break;
0177         buf[i] = readl(UART1_REG(RX));
0178     }
0179 
0180     /* return read bytes */
0181     return i;
0182 }
0183 
0184 static int tsp2_miconwrite(const unsigned char *buf, int count)
0185 {
0186     int i = 0;
0187 
0188     while (count--) {
0189         while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
0190             barrier();
0191         writel(buf[i++], UART1_REG(TX));
0192     }
0193 
0194     return 0;
0195 }
0196 
0197 static int tsp2_miconsend(const unsigned char *data, int count)
0198 {
0199     int i;
0200     unsigned char checksum = 0;
0201     unsigned char recv_buf[40];
0202     unsigned char send_buf[40];
0203     unsigned char correct_ack[3];
0204     int retry = 2;
0205 
0206     /* Generate checksum */
0207     for (i = 0; i < count; i++)
0208         checksum -=  data[i];
0209 
0210     do {
0211         /* Send data */
0212         tsp2_miconwrite(data, count);
0213 
0214         /* send checksum */
0215         tsp2_miconwrite(&checksum, 1);
0216 
0217         if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
0218             printk(KERN_ERR ">%s: receive failed.\n", __func__);
0219 
0220             /* send preamble to clear the receive buffer */
0221             memset(&send_buf, 0xff, sizeof(send_buf));
0222             tsp2_miconwrite(send_buf, sizeof(send_buf));
0223 
0224             /* make dummy reads */
0225             mdelay(100);
0226             tsp2_miconread(recv_buf, sizeof(recv_buf));
0227         } else {
0228             /* Generate expected ack */
0229             correct_ack[0] = 0x01;
0230             correct_ack[1] = data[1];
0231             correct_ack[2] = 0x00;
0232 
0233             /* checksum Check */
0234             if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
0235                  recv_buf[3]) & 0xFF) {
0236                 printk(KERN_ERR ">%s: Checksum Error : "
0237                     "Received data[%02x, %02x, %02x, %02x]"
0238                     "\n", __func__, recv_buf[0],
0239                     recv_buf[1], recv_buf[2], recv_buf[3]);
0240             } else {
0241                 /* Check Received Data */
0242                 if (correct_ack[0] == recv_buf[0] &&
0243                     correct_ack[1] == recv_buf[1] &&
0244                     correct_ack[2] == recv_buf[2]) {
0245                     /* Interval for next command */
0246                     mdelay(10);
0247 
0248                     /* Receive ACK */
0249                     return 0;
0250                 }
0251             }
0252             /* Received NAK or illegal Data */
0253             printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
0254                     "Received\n", __func__);
0255         }
0256     } while (retry--);
0257 
0258     /* Interval for next command */
0259     mdelay(10);
0260 
0261     return -1;
0262 }
0263 
0264 static void tsp2_power_off(void)
0265 {
0266     const unsigned char watchdogkill[]  = {0x01, 0x35, 0x00};
0267     const unsigned char shutdownwait[]  = {0x00, 0x0c};
0268     const unsigned char poweroff[]      = {0x00, 0x06};
0269     /* 38400 baud divisor */
0270     const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
0271 
0272     pr_info("%s: triggering power-off...\n", __func__);
0273 
0274     /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
0275     writel(0x83, UART1_REG(LCR));
0276     writel(divisor & 0xff, UART1_REG(DLL));
0277     writel((divisor >> 8) & 0xff, UART1_REG(DLM));
0278     writel(0x1b, UART1_REG(LCR));
0279     writel(0x00, UART1_REG(IER));
0280     writel(0x07, UART1_REG(FCR));
0281     writel(0x00, UART1_REG(MCR));
0282 
0283     /* Send the commands to shutdown the Terastation Pro II */
0284     tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ;
0285     tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ;
0286     tsp2_miconsend(poweroff, sizeof(poweroff));
0287 }
0288 
0289 /*****************************************************************************
0290  * General Setup
0291  ****************************************************************************/
0292 static unsigned int tsp2_mpp_modes[] __initdata = {
0293     MPP0_PCIE_RST_OUTn,
0294     MPP1_UNUSED,
0295     MPP2_UNUSED,
0296     MPP3_UNUSED,
0297     MPP4_NAND,      /* BOOT NAND Flash REn */
0298     MPP5_NAND,      /* BOOT NAND Flash WEn */
0299     MPP6_NAND,      /* BOOT NAND Flash HREn[0] */
0300     MPP7_NAND,      /* BOOT NAND Flash WEn[0] */
0301     MPP8_GPIO,      /* MICON int */
0302     MPP9_GPIO,      /* RTC int */
0303     MPP10_UNUSED,
0304     MPP11_GPIO,     /* PCI Int A */
0305     MPP12_UNUSED,
0306     MPP13_GPIO,     /* UPS on UART0 enable */
0307     MPP14_GPIO,     /* UPS low battery detection */
0308     MPP15_UNUSED,
0309     MPP16_UART,     /* UART1 RXD */
0310     MPP17_UART,     /* UART1 TXD */
0311     MPP18_UART,     /* UART1 CTSn */
0312     MPP19_UART,     /* UART1 RTSn */
0313     0,
0314 };
0315 
0316 static void __init tsp2_init(void)
0317 {
0318     /*
0319      * Setup basic Orion functions. Need to be called early.
0320      */
0321     orion5x_init();
0322 
0323     orion5x_mpp_conf(tsp2_mpp_modes);
0324 
0325     /*
0326      * Configure peripherals.
0327      */
0328     mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
0329                     ORION_MBUS_DEVBUS_BOOT_ATTR,
0330                     TSP2_NOR_BOOT_BASE,
0331                     TSP2_NOR_BOOT_SIZE);
0332     platform_device_register(&tsp2_nor_flash);
0333 
0334     orion5x_ehci0_init();
0335     orion5x_eth_init(&tsp2_eth_data);
0336     orion5x_i2c_init();
0337     orion5x_uart0_init();
0338     orion5x_uart1_init();
0339 
0340     /* Get RTC IRQ and register the chip */
0341     if (gpio_request(TSP2_RTC_GPIO, "rtc") == 0) {
0342         if (gpio_direction_input(TSP2_RTC_GPIO) == 0)
0343             tsp2_i2c_rtc.irq = gpio_to_irq(TSP2_RTC_GPIO);
0344         else
0345             gpio_free(TSP2_RTC_GPIO);
0346     }
0347     if (tsp2_i2c_rtc.irq == 0)
0348         pr_warn("tsp2_init: failed to get RTC IRQ\n");
0349     i2c_register_board_info(0, &tsp2_i2c_rtc, 1);
0350 
0351     /* register Terastation Pro II specific power-off method */
0352     pm_power_off = tsp2_power_off;
0353 }
0354 
0355 MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
0356     /* Maintainer:  Sylver Bruneau <sylver.bruneau@googlemail.com> */
0357     .atag_offset    = 0x100,
0358     .nr_irqs    = ORION5X_NR_IRQS,
0359     .init_machine   = tsp2_init,
0360     .map_io     = orion5x_map_io,
0361     .init_early = orion5x_init_early,
0362     .init_irq   = orion5x_init_irq,
0363     .init_time  = orion5x_timer_init,
0364     .fixup      = tag_fixup_mem32,
0365     .restart    = orion5x_restart,
0366 MACHINE_END