Path: blob/master/arch/arm/mach-orion5x/kurobox_pro-setup.c
10817 views
/*1* arch/arm/mach-orion5x/kurobox_pro-setup.c2*3* Maintainer: Ronen Shitrit <[email protected]>4*5* This file is licensed under the terms of the GNU General Public6* License version 2. This program is licensed "as is" without any7* warranty of any kind, whether express or implied.8*/910#include <linux/kernel.h>11#include <linux/init.h>12#include <linux/platform_device.h>13#include <linux/pci.h>14#include <linux/irq.h>15#include <linux/delay.h>16#include <linux/mtd/physmap.h>17#include <linux/mtd/nand.h>18#include <linux/mv643xx_eth.h>19#include <linux/i2c.h>20#include <linux/serial_reg.h>21#include <linux/ata_platform.h>22#include <asm/mach-types.h>23#include <asm/gpio.h>24#include <asm/mach/arch.h>25#include <asm/mach/pci.h>26#include <mach/orion5x.h>27#include <plat/orion_nand.h>28#include "common.h"29#include "mpp.h"3031/*****************************************************************************32* KUROBOX-PRO Info33****************************************************************************/3435/*36* 256K NOR flash Device bus boot chip select37*/3839#define KUROBOX_PRO_NOR_BOOT_BASE 0xf400000040#define KUROBOX_PRO_NOR_BOOT_SIZE SZ_256K4142/*43* 256M NAND flash on Device bus chip select 144*/4546#define KUROBOX_PRO_NAND_BASE 0xfc00000047#define KUROBOX_PRO_NAND_SIZE SZ_2M4849/*****************************************************************************50* 256MB NAND Flash on Device bus CS051****************************************************************************/5253static struct mtd_partition kurobox_pro_nand_parts[] = {54{55.name = "uImage",56.offset = 0,57.size = SZ_4M,58}, {59.name = "rootfs",60.offset = SZ_4M,61.size = SZ_64M,62}, {63.name = "extra",64.offset = SZ_4M + SZ_64M,65.size = SZ_256M - (SZ_4M + SZ_64M),66},67};6869static struct resource kurobox_pro_nand_resource = {70.flags = IORESOURCE_MEM,71.start = KUROBOX_PRO_NAND_BASE,72.end = KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1,73};7475static struct orion_nand_data kurobox_pro_nand_data = {76.parts = kurobox_pro_nand_parts,77.nr_parts = ARRAY_SIZE(kurobox_pro_nand_parts),78.cle = 0,79.ale = 1,80.width = 8,81};8283static struct platform_device kurobox_pro_nand_flash = {84.name = "orion_nand",85.id = -1,86.dev = {87.platform_data = &kurobox_pro_nand_data,88},89.resource = &kurobox_pro_nand_resource,90.num_resources = 1,91};9293/*****************************************************************************94* 256KB NOR Flash on BOOT Device95****************************************************************************/9697static struct physmap_flash_data kurobox_pro_nor_flash_data = {98.width = 1,99};100101static struct resource kurobox_pro_nor_flash_resource = {102.flags = IORESOURCE_MEM,103.start = KUROBOX_PRO_NOR_BOOT_BASE,104.end = KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1,105};106107static struct platform_device kurobox_pro_nor_flash = {108.name = "physmap-flash",109.id = 0,110.dev = {111.platform_data = &kurobox_pro_nor_flash_data,112},113.num_resources = 1,114.resource = &kurobox_pro_nor_flash_resource,115};116117/*****************************************************************************118* PCI119****************************************************************************/120121static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)122{123int irq;124125/*126* Check for devices with hard-wired IRQs.127*/128irq = orion5x_pci_map_irq(dev, slot, pin);129if (irq != -1)130return irq;131132/*133* PCI isn't used on the Kuro134*/135return -1;136}137138static struct hw_pci kurobox_pro_pci __initdata = {139.nr_controllers = 2,140.swizzle = pci_std_swizzle,141.setup = orion5x_pci_sys_setup,142.scan = orion5x_pci_sys_scan_bus,143.map_irq = kurobox_pro_pci_map_irq,144};145146static int __init kurobox_pro_pci_init(void)147{148if (machine_is_kurobox_pro()) {149orion5x_pci_disable();150pci_common_init(&kurobox_pro_pci);151}152153return 0;154}155156subsys_initcall(kurobox_pro_pci_init);157158/*****************************************************************************159* Ethernet160****************************************************************************/161162static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {163.phy_addr = MV643XX_ETH_PHY_ADDR(8),164};165166/*****************************************************************************167* RTC 5C372a on I2C bus168****************************************************************************/169static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {170I2C_BOARD_INFO("rs5c372a", 0x32),171};172173/*****************************************************************************174* SATA175****************************************************************************/176static struct mv_sata_platform_data kurobox_pro_sata_data = {177.n_ports = 2,178};179180/*****************************************************************************181* Kurobox Pro specific power off method via UART1-attached microcontroller182****************************************************************************/183184#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))185186static int kurobox_pro_miconread(unsigned char *buf, int count)187{188int i;189int timeout;190191for (i = 0; i < count; i++) {192timeout = 10;193194while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {195if (--timeout == 0)196break;197udelay(1000);198}199200if (timeout == 0)201break;202buf[i] = readl(UART1_REG(RX));203}204205/* return read bytes */206return i;207}208209static int kurobox_pro_miconwrite(const unsigned char *buf, int count)210{211int i = 0;212213while (count--) {214while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))215barrier();216writel(buf[i++], UART1_REG(TX));217}218219return 0;220}221222static int kurobox_pro_miconsend(const unsigned char *data, int count)223{224int i;225unsigned char checksum = 0;226unsigned char recv_buf[40];227unsigned char send_buf[40];228unsigned char correct_ack[3];229int retry = 2;230231/* Generate checksum */232for (i = 0; i < count; i++)233checksum -= data[i];234235do {236/* Send data */237kurobox_pro_miconwrite(data, count);238239/* send checksum */240kurobox_pro_miconwrite(&checksum, 1);241242if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) {243printk(KERN_ERR ">%s: receive failed.\n", __func__);244245/* send preamble to clear the receive buffer */246memset(&send_buf, 0xff, sizeof(send_buf));247kurobox_pro_miconwrite(send_buf, sizeof(send_buf));248249/* make dummy reads */250mdelay(100);251kurobox_pro_miconread(recv_buf, sizeof(recv_buf));252} else {253/* Generate expected ack */254correct_ack[0] = 0x01;255correct_ack[1] = data[1];256correct_ack[2] = 0x00;257258/* checksum Check */259if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +260recv_buf[3]) & 0xFF) {261printk(KERN_ERR ">%s: Checksum Error : "262"Received data[%02x, %02x, %02x, %02x]"263"\n", __func__, recv_buf[0],264recv_buf[1], recv_buf[2], recv_buf[3]);265} else {266/* Check Received Data */267if (correct_ack[0] == recv_buf[0] &&268correct_ack[1] == recv_buf[1] &&269correct_ack[2] == recv_buf[2]) {270/* Interval for next command */271mdelay(10);272273/* Receive ACK */274return 0;275}276}277/* Received NAK or illegal Data */278printk(KERN_ERR ">%s: Error : NAK or Illegal Data "279"Received\n", __func__);280}281} while (retry--);282283/* Interval for next command */284mdelay(10);285286return -1;287}288289static void kurobox_pro_power_off(void)290{291const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};292const unsigned char shutdownwait[] = {0x00, 0x0c};293const unsigned char poweroff[] = {0x00, 0x06};294/* 38400 baud divisor */295const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));296297pr_info("%s: triggering power-off...\n", __func__);298299/* hijack uart1 and reset into sane state (38400,8n1,even parity) */300writel(0x83, UART1_REG(LCR));301writel(divisor & 0xff, UART1_REG(DLL));302writel((divisor >> 8) & 0xff, UART1_REG(DLM));303writel(0x1b, UART1_REG(LCR));304writel(0x00, UART1_REG(IER));305writel(0x07, UART1_REG(FCR));306writel(0x00, UART1_REG(MCR));307308/* Send the commands to shutdown the Kurobox Pro */309kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ;310kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ;311kurobox_pro_miconsend(poweroff, sizeof(poweroff));312}313314/*****************************************************************************315* General Setup316****************************************************************************/317static unsigned int kurobox_pro_mpp_modes[] __initdata = {318MPP0_UNUSED,319MPP1_UNUSED,320MPP2_GPIO, /* GPIO Micon */321MPP3_GPIO, /* GPIO Rtc */322MPP4_UNUSED,323MPP5_UNUSED,324MPP6_NAND, /* NAND Flash REn */325MPP7_NAND, /* NAND Flash WEn */326MPP8_UNUSED,327MPP9_UNUSED,328MPP10_UNUSED,329MPP11_UNUSED,330MPP12_SATA_LED, /* SATA 0 presence */331MPP13_SATA_LED, /* SATA 1 presence */332MPP14_SATA_LED, /* SATA 0 active */333MPP15_SATA_LED, /* SATA 1 active */334MPP16_UART, /* UART1 RXD */335MPP17_UART, /* UART1 TXD */336MPP18_UART, /* UART1 CTSn */337MPP19_UART, /* UART1 RTSn */3380,339};340341static void __init kurobox_pro_init(void)342{343/*344* Setup basic Orion functions. Need to be called early.345*/346orion5x_init();347348orion5x_mpp_conf(kurobox_pro_mpp_modes);349350/*351* Configure peripherals.352*/353orion5x_ehci0_init();354orion5x_ehci1_init();355orion5x_eth_init(&kurobox_pro_eth_data);356orion5x_i2c_init();357orion5x_sata_init(&kurobox_pro_sata_data);358orion5x_uart0_init();359orion5x_uart1_init();360orion5x_xor_init();361362orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE,363KUROBOX_PRO_NOR_BOOT_SIZE);364platform_device_register(&kurobox_pro_nor_flash);365366if (machine_is_kurobox_pro()) {367orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE,368KUROBOX_PRO_NAND_SIZE);369platform_device_register(&kurobox_pro_nand_flash);370}371372i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);373374/* register Kurobox Pro specific power-off method */375pm_power_off = kurobox_pro_power_off;376}377378#ifdef CONFIG_MACH_KUROBOX_PRO379MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")380/* Maintainer: Ronen Shitrit <[email protected]> */381.boot_params = 0x00000100,382.init_machine = kurobox_pro_init,383.map_io = orion5x_map_io,384.init_early = orion5x_init_early,385.init_irq = orion5x_init_irq,386.timer = &orion5x_timer,387.fixup = tag_fixup_mem32,388MACHINE_END389#endif390391#ifdef CONFIG_MACH_LINKSTATION_PRO392MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")393/* Maintainer: Byron Bradley <[email protected]> */394.boot_params = 0x00000100,395.init_machine = kurobox_pro_init,396.map_io = orion5x_map_io,397.init_early = orion5x_init_early,398.init_irq = orion5x_init_irq,399.timer = &orion5x_timer,400.fixup = tag_fixup_mem32,401MACHINE_END402#endif403404405