Path: blob/master/arch/arm/mach-orion5x/terastation_pro2-setup.c
26292 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Buffalo Terastation Pro II/Live Board Setup3*4* Maintainer: Sylver Bruneau <[email protected]>5*/6#include <linux/gpio.h>7#include <linux/kernel.h>8#include <linux/init.h>9#include <linux/platform_device.h>10#include <linux/pci.h>11#include <linux/irq.h>12#include <linux/delay.h>13#include <linux/mtd/physmap.h>14#include <linux/mv643xx_eth.h>15#include <linux/i2c.h>16#include <linux/serial_reg.h>17#include <asm/mach-types.h>18#include <asm/mach/arch.h>19#include <asm/mach/pci.h>20#include "common.h"21#include "mpp.h"22#include "orion5x.h"2324/*****************************************************************************25* Terastation Pro 2/Live Info26****************************************************************************/2728/*29* Terastation Pro 2 hardware :30* - Marvell 88F5281-D031* - Marvell 88SX6042 SATA controller (PCI)32* - Marvell 88E1118 Gigabit Ethernet PHY33* - 256KB NOR flash34* - 128MB of DDR RAM35* - PCIe port (not equipped)36*/3738/*39* 256K NOR flash Device bus boot chip select40*/4142#define TSP2_NOR_BOOT_BASE 0xf400000043#define TSP2_NOR_BOOT_SIZE SZ_256K4445/*****************************************************************************46* 256KB NOR Flash on BOOT Device47****************************************************************************/4849static struct physmap_flash_data tsp2_nor_flash_data = {50.width = 1,51};5253static struct resource tsp2_nor_flash_resource = {54.flags = IORESOURCE_MEM,55.start = TSP2_NOR_BOOT_BASE,56.end = TSP2_NOR_BOOT_BASE + TSP2_NOR_BOOT_SIZE - 1,57};5859static struct platform_device tsp2_nor_flash = {60.name = "physmap-flash",61.id = 0,62.dev = {63.platform_data = &tsp2_nor_flash_data,64},65.num_resources = 1,66.resource = &tsp2_nor_flash_resource,67};6869/*****************************************************************************70* PCI71****************************************************************************/72#define TSP2_PCI_SLOT0_OFFS 773#define TSP2_PCI_SLOT0_IRQ_PIN 117475static void __init tsp2_pci_preinit(void)76{77int pin;7879/*80* Configure PCI GPIO IRQ pins81*/82pin = TSP2_PCI_SLOT0_IRQ_PIN;83if (gpio_request(pin, "PCI Int1") == 0) {84if (gpio_direction_input(pin) == 0) {85irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);86} else {87printk(KERN_ERR "tsp2_pci_preinit failed "88"to set_irq_type pin %d\n", pin);89gpio_free(pin);90}91} else {92printk(KERN_ERR "tsp2_pci_preinit failed to "93"gpio_request %d\n", pin);94}95}9697static int __init tsp2_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)98{99int irq;100101/*102* Check for devices with hard-wired IRQs.103*/104irq = orion5x_pci_map_irq(dev, slot, pin);105if (irq != -1)106return irq;107108/*109* PCI IRQs are connected via GPIOs.110*/111if (slot == TSP2_PCI_SLOT0_OFFS)112return gpio_to_irq(TSP2_PCI_SLOT0_IRQ_PIN);113114return -1;115}116117static struct hw_pci tsp2_pci __initdata = {118.nr_controllers = 2,119.preinit = tsp2_pci_preinit,120.setup = orion5x_pci_sys_setup,121.scan = orion5x_pci_sys_scan_bus,122.map_irq = tsp2_pci_map_irq,123};124125static int __init tsp2_pci_init(void)126{127if (machine_is_terastation_pro2())128pci_common_init(&tsp2_pci);129130return 0;131}132133subsys_initcall(tsp2_pci_init);134135/*****************************************************************************136* Ethernet137****************************************************************************/138139static struct mv643xx_eth_platform_data tsp2_eth_data = {140.phy_addr = 0,141};142143/*****************************************************************************144* RTC 5C372a on I2C bus145****************************************************************************/146147#define TSP2_RTC_GPIO 9148149static struct i2c_board_info __initdata tsp2_i2c_rtc = {150I2C_BOARD_INFO("rs5c372a", 0x32),151};152153/*****************************************************************************154* Terastation Pro II specific power off method via UART1-attached155* microcontroller156****************************************************************************/157158#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))159160static int tsp2_miconread(unsigned char *buf, int count)161{162int i;163int timeout;164165for (i = 0; i < count; i++) {166timeout = 10;167168while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {169if (--timeout == 0)170break;171udelay(1000);172}173174if (timeout == 0)175break;176buf[i] = readl(UART1_REG(RX));177}178179/* return read bytes */180return i;181}182183static int tsp2_miconwrite(const unsigned char *buf, int count)184{185int i = 0;186187while (count--) {188while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))189barrier();190writel(buf[i++], UART1_REG(TX));191}192193return 0;194}195196static int tsp2_miconsend(const unsigned char *data, int count)197{198int i;199unsigned char checksum = 0;200unsigned char recv_buf[40];201unsigned char send_buf[40];202unsigned char correct_ack[3];203int retry = 2;204205/* Generate checksum */206for (i = 0; i < count; i++)207checksum -= data[i];208209do {210/* Send data */211tsp2_miconwrite(data, count);212213/* send checksum */214tsp2_miconwrite(&checksum, 1);215216if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) {217printk(KERN_ERR ">%s: receive failed.\n", __func__);218219/* send preamble to clear the receive buffer */220memset(&send_buf, 0xff, sizeof(send_buf));221tsp2_miconwrite(send_buf, sizeof(send_buf));222223/* make dummy reads */224mdelay(100);225tsp2_miconread(recv_buf, sizeof(recv_buf));226} else {227/* Generate expected ack */228correct_ack[0] = 0x01;229correct_ack[1] = data[1];230correct_ack[2] = 0x00;231232/* checksum Check */233if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +234recv_buf[3]) & 0xFF) {235printk(KERN_ERR ">%s: Checksum Error : "236"Received data[%02x, %02x, %02x, %02x]"237"\n", __func__, recv_buf[0],238recv_buf[1], recv_buf[2], recv_buf[3]);239} else {240/* Check Received Data */241if (correct_ack[0] == recv_buf[0] &&242correct_ack[1] == recv_buf[1] &&243correct_ack[2] == recv_buf[2]) {244/* Interval for next command */245mdelay(10);246247/* Receive ACK */248return 0;249}250}251/* Received NAK or illegal Data */252printk(KERN_ERR ">%s: Error : NAK or Illegal Data "253"Received\n", __func__);254}255} while (retry--);256257/* Interval for next command */258mdelay(10);259260return -1;261}262263static void tsp2_power_off(void)264{265const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};266const unsigned char shutdownwait[] = {0x00, 0x0c};267const unsigned char poweroff[] = {0x00, 0x06};268/* 38400 baud divisor */269const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));270271pr_info("%s: triggering power-off...\n", __func__);272273/* hijack uart1 and reset into sane state (38400,8n1,even parity) */274writel(0x83, UART1_REG(LCR));275writel(divisor & 0xff, UART1_REG(DLL));276writel((divisor >> 8) & 0xff, UART1_REG(DLM));277writel(0x1b, UART1_REG(LCR));278writel(0x00, UART1_REG(IER));279writel(0x07, UART1_REG(FCR));280writel(0x00, UART1_REG(MCR));281282/* Send the commands to shutdown the Terastation Pro II */283tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ;284tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ;285tsp2_miconsend(poweroff, sizeof(poweroff));286}287288/*****************************************************************************289* General Setup290****************************************************************************/291static unsigned int tsp2_mpp_modes[] __initdata = {292MPP0_PCIE_RST_OUTn,293MPP1_UNUSED,294MPP2_UNUSED,295MPP3_UNUSED,296MPP4_NAND, /* BOOT NAND Flash REn */297MPP5_NAND, /* BOOT NAND Flash WEn */298MPP6_NAND, /* BOOT NAND Flash HREn[0] */299MPP7_NAND, /* BOOT NAND Flash WEn[0] */300MPP8_GPIO, /* MICON int */301MPP9_GPIO, /* RTC int */302MPP10_UNUSED,303MPP11_GPIO, /* PCI Int A */304MPP12_UNUSED,305MPP13_GPIO, /* UPS on UART0 enable */306MPP14_GPIO, /* UPS low battery detection */307MPP15_UNUSED,308MPP16_UART, /* UART1 RXD */309MPP17_UART, /* UART1 TXD */310MPP18_UART, /* UART1 CTSn */311MPP19_UART, /* UART1 RTSn */3120,313};314315static void __init tsp2_init(void)316{317/*318* Setup basic Orion functions. Need to be called early.319*/320orion5x_init();321322orion5x_mpp_conf(tsp2_mpp_modes);323324/*325* Configure peripherals.326*/327mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,328ORION_MBUS_DEVBUS_BOOT_ATTR,329TSP2_NOR_BOOT_BASE,330TSP2_NOR_BOOT_SIZE);331platform_device_register(&tsp2_nor_flash);332333orion5x_ehci0_init();334orion5x_eth_init(&tsp2_eth_data);335orion5x_i2c_init();336orion5x_uart0_init();337orion5x_uart1_init();338339/* Get RTC IRQ and register the chip */340if (gpio_request(TSP2_RTC_GPIO, "rtc") == 0) {341if (gpio_direction_input(TSP2_RTC_GPIO) == 0)342tsp2_i2c_rtc.irq = gpio_to_irq(TSP2_RTC_GPIO);343else344gpio_free(TSP2_RTC_GPIO);345}346if (tsp2_i2c_rtc.irq == 0)347pr_warn("tsp2_init: failed to get RTC IRQ\n");348i2c_register_board_info(0, &tsp2_i2c_rtc, 1);349350/* register Terastation Pro II specific power-off method */351register_platform_power_off(tsp2_power_off);352}353354MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")355/* Maintainer: Sylver Bruneau <[email protected]> */356.atag_offset = 0x100,357.nr_irqs = ORION5X_NR_IRQS,358.init_machine = tsp2_init,359.map_io = orion5x_map_io,360.init_early = orion5x_init_early,361.init_irq = orion5x_init_irq,362.init_time = orion5x_timer_init,363.fixup = tag_fixup_mem32,364.restart = orion5x_restart,365MACHINE_END366367368