diff options
author | James <> | 2013-03-17 12:16:37 +0000 |
---|---|---|
committer | James <> | 2013-03-17 12:16:37 +0000 |
commit | 27b76ab0671089c47506615a796a261e993896a7 (patch) | |
tree | 61213d67e7fa87b20356b23798558e2c4212c42f /target/linux/adm8668/files | |
download | trunk-36060-master.tar.gz trunk-36060-master.tar.bz2 trunk-36060-master.zip |
Diffstat (limited to 'target/linux/adm8668/files')
52 files changed, 3869 insertions, 0 deletions
diff --git a/target/linux/adm8668/files/.svn/entries b/target/linux/adm8668/files/.svn/entries new file mode 100644 index 0000000..50f18d6 --- /dev/null +++ b/target/linux/adm8668/files/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +arch +dir + +drivers +dir + diff --git a/target/linux/adm8668/files/arch/.svn/entries b/target/linux/adm8668/files/arch/.svn/entries new file mode 100644 index 0000000..fb433a8 --- /dev/null +++ b/target/linux/adm8668/files/arch/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +mips +dir + diff --git a/target/linux/adm8668/files/arch/mips/.svn/entries b/target/linux/adm8668/files/arch/mips/.svn/entries new file mode 100644 index 0000000..7872a45 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/.svn/entries @@ -0,0 +1,37 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch/mips +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +include +dir + +pci +dir + +adm8668 +dir + diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/entries b/target/linux/adm8668/files/arch/mips/adm8668/.svn/entries new file mode 100644 index 0000000..5c87afe --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/entries @@ -0,0 +1,436 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch/mips/adm8668 +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +gpio.c +file + + + + +2013-03-17T12:12:21.000000Z +5bf76f5f2c1114dd70d3bbb7d9556b4c +2012-12-06T22:41:04.955973Z +34564 +florian + + + + + + + + + + + + + + + + + + + + + +2757 + +time.c +file + + + + +2013-03-17T12:12:21.000000Z +b8269fe3ba3ebdc5fc5aead3ca4164d2 +2012-12-06T22:39:52.691056Z +34550 +florian + + + + + + + + + + + + + + + + + + + + + +350 + +Kconfig +file + + + + +2013-03-17T12:12:21.000000Z +9d2ca6eb366d16a53eac61b6a87f46fd +2012-12-06T22:39:43.120900Z +34548 +florian + + + + + + + + + + + + + + + + + + + + + +28 + +setup.c +file + + + + +2013-03-17T12:12:21.000000Z +c085b7fa51628d884884f4f6a2435020 +2012-12-06T22:40:58.805103Z +34563 +florian + + + + + + + + + + + + + + + + + + + + + +642 + +Platform +file + + + + +2013-03-17T12:12:21.000000Z +22655d9d742459b827367c8ba37a2a54 +2010-11-06T18:54:20.513313Z +23900 +florian + + + + + + + + + + + + + + + + + + + + + +193 + +early_printk.c +file + + + + +2013-03-17T12:12:21.000000Z +d5712bf86a75d96434c10b230a600f09 +2012-12-06T22:39:47.932769Z +34549 +florian + + + + + + + + + + + + + + + + + + + + + +387 + +platform.c +file + + + + +2013-03-17T12:12:21.000000Z +f911ba0a1e4fd095ab3262bd809017fb +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + + + + + + + + +4870 + +u-boot.h +file + + + + +2013-03-17T12:12:21.000000Z +c40428c4a9fd4edc52578af459b98c1a +2010-11-06T18:54:20.513313Z +23900 +florian + + + + + + + + + + + + + + + + + + + + + +2017 + +clock.c +file + + + + +2013-03-17T12:12:21.000000Z +ecbae188690818acf20199b807b2d745 +2012-12-06T22:40:26.530602Z +34556 +florian +has-props + + + + + + + + + + + + + + + + + + + + +1307 + +irq.c +file + + + + +2013-03-17T12:12:21.000000Z +ceae2774e545542eb6605566d6657d23 +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + + + + + + + + +2566 + +Makefile +file + + + + +2013-03-17T12:12:21.000000Z +fa5f9fa564e18b4ab8b398aa6eca0f3f +2012-12-06T22:41:09.830841Z +34565 +florian + + + + + + + + + + + + + + + + + + + + + +128 + +prom.c +file + + + + +2013-03-17T12:12:21.000000Z +8187f7213a344bca0092390629362e18 +2012-12-06T22:39:33.611231Z +34547 +florian + + + + + + + + + + + + + + + + + + + + + +2268 + diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/prop-base/clock.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/prop-base/clock.c.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/prop-base/clock.c.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Kconfig.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Kconfig.svn-base new file mode 100644 index 0000000..2e7281f --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Kconfig.svn-base @@ -0,0 +1,2 @@ +config ARM_AMBA + def_bool y diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Makefile.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..515c3a4 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Makefile.svn-base @@ -0,0 +1,6 @@ +# +# something witty --neutronscott +# + +obj-y := irq.o prom.o platform.o gpio.o \ + setup.o clock.o time.o early_printk.o \ diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Platform.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Platform.svn-base new file mode 100644 index 0000000..c70cd27 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/Platform.svn-base @@ -0,0 +1,6 @@ +# +# Infineon ADM8668 WildPass +# +platform-$(CONFIG_ADM8668) += adm8668/ +cflags-$(CONFIG_ADM8668) += -I$(srctree)/arch/mips/include/asm/mach-adm8668 +load-$(CONFIG_ADM8668) += 0xffffffff80002000 diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/clock.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/clock.c.svn-base new file mode 100644 index 0000000..1e010fc --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/clock.c.svn-base @@ -0,0 +1,76 @@ +/* + * ADM8668 minimal clock support + * + * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org> + * + * Licensed under the terms of the GPLv2 + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/clk.h> + +#include <adm8668.h> + +struct clk { + unsigned long rate; +}; + +static struct clk uart_clk = { + .rate = 62500000, +}; + +static struct clk sys_clk; + +struct clk *clk_get(struct device *dev, const char *id) +{ + const char *lookup = id; + + if (dev) + lookup = dev_name(dev); + + if (!strcmp(lookup, "apb:uart0")) + return &uart_clk; + if (!strcmp(lookup, "sys")) + return &sys_clk; + + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +void __init adm8668_init_clocks(void) +{ + u32 adj; + + /* adjustable clock selection + * CR3 bit 14~11, 0000 -> 175MHz, 0001 -> 180MHz, etc... + */ + adj = (ADM8668_CONFIG_REG(ADM8668_CR3) >> 11) & 0xf; + sys_clk.rate = 175000000 + (adj * 5000000); + + pr_info("ADM8668 CPU clock: %lu MHz\n", sys_clk.rate / 1000000); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/early_printk.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/early_printk.c.svn-base new file mode 100644 index 0000000..03dd72a --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/early_printk.c.svn-base @@ -0,0 +1,16 @@ +#include <linux/io.h> +#include <linux/amba/serial.h> +#include <adm8668.h> + +#define UART_READ(r) \ + __raw_readl((void __iomem *)(KSEG1ADDR(ADM8668_UART0_BASE) + (r))) + +#define UART_WRITE(v, r) \ + __raw_writel((v), (void __iomem *)(KSEG1ADDR(ADM8668_UART0_BASE) + (r))) + +void prom_putchar(char c) +{ + UART_WRITE(c, UART01x_DR); + while ((UART_READ(UART01x_FR) & UART01x_FR_TXFF) != 0) + ; +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/gpio.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/gpio.c.svn-base new file mode 100644 index 0000000..fb39f7f --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/gpio.c.svn-base @@ -0,0 +1,123 @@ +/* + * Infineon/ADMTek ADM8668 WildPass GPIO support + * + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * Licensed under the terms of GPLv2. + * + */ +#include <linux/kernel.h> +#include <linux/gpio.h> +#include <linux/io.h> + +#include <adm8668.h> + +#define GPIO_MASK 0x3f + +#define GPIO_IN_OFS 0 +#define GPIO_OUT_OFS 6 +#define GPIO_OE_OFS 12 + +struct adm8668_gpio_chip { + void __iomem *base; + struct gpio_chip chip; +}; + +static int adm8668_gpio_dir_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 mask; + + /* clear input, set output enable and output value */ + mask = __raw_readl(c->base); + mask &= ~(1 << offset); + mask |= (1 << (offset + GPIO_OE_OFS)); + if (value) + mask |= (1 << (offset + GPIO_OUT_OFS)); + else + mask &= ~(1 << (offset + GPIO_OUT_OFS)); + __raw_writel(mask, c->base); + + return 0; +} + +static int adm8668_gpio_dir_in(struct gpio_chip *chip, + unsigned offset) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 mask; + + mask = __raw_readl(c->base); + mask &= ~(((1 << (offset + GPIO_OE_OFS)) | (1 << (offset + GPIO_OUT_OFS)))); + mask |= (1 << offset); + __raw_writel(mask, c->base); + + return 0; +} + +static void adm8668_gpio_set(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 mask; + + mask = __raw_readl(c->base); + if (value) + mask |= (1 << (offset + GPIO_OUT_OFS)); + else + mask &= ~(1 << (offset + GPIO_OUT_OFS)); + __raw_writel(mask, c->base); +} + +static int adm8668_gpio_get(struct gpio_chip *chip, + unsigned offset) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 value; + + value = __raw_readl(c->base) & GPIO_MASK; + + return value & (1 << offset); +} + +static struct adm8668_gpio_chip adm8668_gpio_cpu = { + .base = (void __iomem *)KSEG1ADDR(ADM8668_CONFIG_BASE + CRGPIO_REG), + .chip = { + .label = "adm8668-cpu-gpio", + .direction_output = adm8668_gpio_dir_out, + .direction_input = adm8668_gpio_dir_in, + .set = adm8668_gpio_set, + .get = adm8668_gpio_get, + .ngpio = 6, + }, +}; + +static struct adm8668_gpio_chip adm8668_gpio_wlan = { + .base = (void __iomem *)KSEG1ADDR(ADM8668_WLAN_BASE + GPIO_REG), + .chip = { + .label = "adm8668-wlan-gpio", + .direction_output = adm8668_gpio_dir_out, + .direction_input = adm8668_gpio_dir_in, + .set = adm8668_gpio_set, + .get = adm8668_gpio_get, + .ngpio = 6, + .base = 6, + }, +}; + +static int __init adm8668_gpio_init(void) +{ + int ret; + + ret = gpiochip_add(&adm8668_gpio_cpu.chip); + if (ret) + return ret; + + return gpiochip_add(&adm8668_gpio_wlan.chip); +} +arch_initcall(adm8668_gpio_init); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/irq.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/irq.c.svn-base new file mode 100644 index 0000000..9d3b2b9 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/irq.c.svn-base @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/pm.h> +#include <linux/irq.h> +#include <asm/mipsregs.h> +#include <asm/irq_cpu.h> +#include <asm/irq.h> +#include <adm8668.h> + +/* interrupt controller */ +#define IRQ_STATUS_REG 0x00 /* Read */ +#define IRQ_ENABLE_REG 0x08 /* Read/Write */ +#define IRQ_DISABLE_REG 0x0C /* Write */ + +#define IRQ_MASK 0xffff + +static inline void intc_write_reg(u32 val, unsigned int reg) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(ADM8668_INTC_BASE); + + __raw_writel(val, base + reg); +} + +static inline u32 intc_read_reg(unsigned int reg) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(ADM8668_INTC_BASE); + + return __raw_readl(base + reg); +} + +static void adm8668_irq_cascade(void) +{ + int irq; + u32 intsrc; + + intsrc = intc_read_reg(IRQ_STATUS_REG) & IRQ_MASK; + if (intsrc) { + irq = fls(intsrc) - 1; + do_IRQ(irq); + } else + spurious_interrupt(); +} + +/* + * System irq dispatch + */ +void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + /* timer interrupt, that we renumbered */ + if (pending & STATUSF_IP7) + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + else if (pending & STATUSF_IP2) + adm8668_irq_cascade(); + else + spurious_interrupt(); +} + +/* + * enable 8668 irq + */ +static void enable_adm8668_irq(struct irq_data *d) +{ + intc_write_reg((1 << d->irq), IRQ_ENABLE_REG); +} + + +static void ack_adm8668_irq(struct irq_data *d) +{ + intc_write_reg((1 << d->irq), IRQ_DISABLE_REG); +} + +/* + * system irq type + */ + +static struct irq_chip adm8668_irq_type = { + .name = "adm8668", + .irq_ack = ack_adm8668_irq, + .irq_mask = ack_adm8668_irq, + .irq_unmask = enable_adm8668_irq +}; + +/* + * irq init + */ +static void __init init_adm8668_irqs(void) +{ + int i; + + /* disable all interrupts for the moment */ + intc_write_reg(IRQ_MASK, IRQ_DISABLE_REG); + + for (i = 0; i <= ADM8668_IRQ_MAX; i++) + irq_set_chip_and_handler(i, &adm8668_irq_type, + handle_level_irq); + + /* hw0 is where our interrupts are uh.. interrupted at. */ + set_c0_status(IE_IRQ0); +} + +/* + * system init + */ +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); + init_adm8668_irqs(); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/platform.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/platform.c.svn-base new file mode 100644 index 0000000..7cd56b7 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/platform.c.svn-base @@ -0,0 +1,224 @@ +/* + * Infineon/ADMTek 8668 (WildPass) platform devices support + * + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/platform_data/tulip.h> +#include <linux/usb/ehci_pdriver.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/partitions.h> +#include <linux/pci.h> +#include <linux/slab.h> +#include <linux/ioport.h> +#include <linux/amba/bus.h> +#include <linux/amba/serial.h> + +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <adm8668.h> + +#define ADM8868_UBOOT_ENV 0x20000 +#define ADM8868_UBOOT_WAN_MAC 0x5ac +#define ADM8868_UBOOT_LAN_MAC 0x404 + +static void adm8668_uart_set_mctrl(struct amba_device *dev, + void __iomem *base, + unsigned int mcrtl) +{ +} + +static struct amba_pl010_data adm8668_uart0_data = { + .set_mctrl = adm8668_uart_set_mctrl, +}; + +static struct amba_device adm8668_uart0_device = { + .dev = { + .init_name = "apb:uart0", + .platform_data = &adm8668_uart0_data, + }, + .res = { + .start = ADM8668_UART0_BASE, + .end = ADM8668_UART0_BASE + 0xF, + .flags = IORESOURCE_MEM, + }, + .irq = { + ADM8668_UART0_IRQ, + -1 + }, + .periphid = 0x0041010, +}; + +static struct resource eth0_resources[] = { + { + .start = ADM8668_LAN_BASE, + .end = ADM8668_LAN_BASE + 256, + .flags = IORESOURCE_MEM, + }, + { + .start = ADM8668_LAN_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct tulip_platform_data eth0_pdata = { + .chip_id = ADM8668, +}; + +static struct platform_device adm8668_eth0_device = { + .name = "tulip", + .id = 0, + .resource = eth0_resources, + .num_resources = ARRAY_SIZE(eth0_resources), + .dev.platform_data = ð0_pdata, +}; + +static struct resource eth1_resources[] = { + { + .start = ADM8668_WAN_BASE, + .end = ADM8668_WAN_BASE + 256, + .flags = IORESOURCE_MEM, + }, + { + .start = ADM8668_WAN_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct tulip_platform_data eth1_pdata = { + .chip_id = ADM8668, +}; + +static struct platform_device adm8668_eth1_device = { + .name = "tulip", + .id = 1, + .resource = eth1_resources, + .num_resources = ARRAY_SIZE(eth1_resources), + .dev.platform_data = ð1_pdata, +}; + +static const char *nor_probe_types[] = { "adm8668part", NULL }; + +static struct physmap_flash_data nor_flash_data = { + .width = 2, + .part_probe_types = nor_probe_types, +}; + +static struct resource nor_resources[] = { + { + .start = ADM8668_SMEM1_BASE, + .end = ADM8668_SMEM1_BASE + 0x800000 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device adm8668_nor_device = { + .name = "physmap-flash", + .id = -1, + .resource = nor_resources, + .num_resources = ARRAY_SIZE(nor_resources), + .dev.platform_data = &nor_flash_data, +}; + +static struct resource usb_resources[] = { + { + .start = ADM8668_USB_BASE, + .end = ADM8668_USB_BASE + 0x1FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .start = ADM8668_USB_IRQ, + .end = ADM8668_USB_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct usb_ehci_pdata usb_pdata = { + .caps_offset = 0x100, + .has_tt = 1, + .port_power_off = 1, +}; + +static struct platform_device adm8668_usb_device = { + .name = "ehci-platform", + .id = -1, + .resource = usb_resources, + .num_resources = ARRAY_SIZE(usb_resources), + .dev.platform_data = &usb_pdata, +}; + +static struct platform_device *adm8668_devs[] = { + &adm8668_eth0_device, + &adm8668_eth1_device, + &adm8668_nor_device, + &adm8668_usb_device, +}; + +static void adm8668_fetch_mac(int unit) +{ + u8 *mac; + u32 offset; + struct tulip_platform_data *pdata; + + switch (unit) { + case -1: + case 0: + offset = ADM8868_UBOOT_LAN_MAC; + pdata = ð0_pdata; + break; + case 1: + offset = ADM8868_UBOOT_WAN_MAC; + pdata = ð1_pdata; + break; + default: + pr_err("unsupported ethernet unit: %d\n", unit); + return; + } + + mac = (u8 *)(KSEG1ADDR(ADM8668_SMEM1_BASE) + ADM8868_UBOOT_ENV + offset); + + memcpy(pdata->mac, mac, sizeof(pdata->mac)); +} + +static void adm8668_ehci_workaround(void) +{ + u32 chipid; + + chipid = ADM8668_CONFIG_REG(ADM8668_CR0); + ADM8668_CONFIG_REG(ADM8668_CR66) = 0x0C1600D9; + + if (chipid == 0x86880001) + return; + + ADM8668_CONFIG_REG(ADM8668_CR66) &= ~(3 << 20); + ADM8668_CONFIG_REG(ADM8668_CR66) |= (1 << 20); + pr_info("ADM8668: applied USB workaround\n"); +} + + +int __devinit adm8668_devs_register(void) +{ + int ret; + + ret = amba_device_register(&adm8668_uart0_device, &iomem_resource); + if (ret) + panic("failed to register AMBA UART"); + + adm8668_fetch_mac(0); + adm8668_fetch_mac(1); + adm8668_ehci_workaround(); + + return platform_add_devices(adm8668_devs, ARRAY_SIZE(adm8668_devs)); +} +arch_initcall(adm8668_devs_register); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/prom.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/prom.c.svn-base new file mode 100644 index 0000000..24b77f8 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/prom.c.svn-base @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * + * based on work of rb532 prom.c + * Copyright (C) 2003, Peter Sadik <peter.sadik@idt.com> + * Copyright (C) 2005-2006, P.Christeas <p_christ@hol.gr> + * Copyright (C) 2007, Gabor Juhos <juhosg@openwrt.org> + * Felix Fietkau <nbd@openwrt.org> + * Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/string.h> +#include <linux/serial_core.h> +#include <asm/bootinfo.h> +#include <adm8668.h> +#include "u-boot.h" + +register volatile struct global_data *gd asm ("k0"); + +void __init prom_free_prom_memory(void) +{ + /* No prom memory to free */ +} + +static inline int match_tag(char *arg, const char *tag) +{ + return strncmp(arg, tag, strlen(tag)) == 0; +} + +static inline unsigned long tag2ul(char *arg, const char *tag) +{ + char *num; + + num = arg + strlen(tag); + return simple_strtoul(num, 0, 10); +} + +void __init prom_setup_cmdline(void) +{ + char *cp; + int prom_argc; + char **prom_argv; + int i; + + prom_argc = fw_arg0; + prom_argv = (char **)KSEG0ADDR(fw_arg1); + + cp = &(arcs_cmdline[0]); + for (i = 1; i < prom_argc; i++) { + prom_argv[i] = (char *)KSEG0ADDR(prom_argv[i]); + + /* default bootargs has "console=/dev/ttyS0" yet console won't + * show up at all if you include the '/dev/' nowadays ... */ + if (match_tag(prom_argv[i], "console=/dev/")) { + char *ptr = prom_argv[i] + strlen("console=/dev/"); + + strcpy(cp, "console="); + cp += strlen("console="); + strcpy(cp, ptr); + cp += strlen(ptr); + *cp++ = ' '; + continue; + } + strcpy(cp, prom_argv[i]); + cp += strlen(prom_argv[i]); + *cp++ = ' '; + } + if (prom_argc > 1) + --cp; /* trailing space */ + + *cp = '\0'; +} + +void __init prom_init(void) +{ + bd_t *bd = gd->bd; + int memsize; + + memsize = bd->bi_memsize; + printk("Board info:\n"); + printk(" RAM size: %d MB\n", (int)memsize/(1024*1024)); + printk(" NOR start: %#lx\n", bd->bi_flashstart); + printk(" NOR size: %#lx\n", bd->bi_flashsize); + + prom_setup_cmdline(); + add_memory_region(0, memsize, BOOT_MEM_RAM); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/setup.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/setup.c.svn-base new file mode 100644 index 0000000..b33c483 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/setup.c.svn-base @@ -0,0 +1,36 @@ +#include <linux/init.h> +#include <linux/reboot.h> + +#include <asm/reboot.h> +#include <adm8668.h> + +static void adm8668_restart(char *cmd) +{ + int i; + + /* the real deal */ + for (i = 0; i < 1000; i++) + ; + ADM8668_CONFIG_REG(ADM8668_CR1) = 1; +} + +void __init plat_mem_setup(void) +{ + _machine_restart = adm8668_restart; +} + +const char *get_system_type(void) +{ + unsigned long chipid = ADM8668_CONFIG_REG(ADM8668_CR0); + int product, revision; + static char ret[32]; + + product = chipid >> 16; + revision = chipid & 0xffff; + + /* i getting fancy :\ */ + snprintf(ret, sizeof(ret), "ADM%xr%x", product, revision); + + return ret; +} + diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/time.c.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/time.c.svn-base new file mode 100644 index 0000000..87bdd66 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/time.c.svn-base @@ -0,0 +1,20 @@ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/clk.h> + +#include <asm/time.h> +#include <adm8668.h> + +void __init plat_time_init(void) +{ + struct clk *sys_clk; + + adm8668_init_clocks(); + + sys_clk = clk_get(NULL, "sys"); + if (IS_ERR(sys_clk)) + panic("unable to get system clock\n"); + + mips_hpt_frequency = clk_get_rate(sys_clk) / 2; +} + diff --git a/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/u-boot.h.svn-base b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/u-boot.h.svn-base new file mode 100644 index 0000000..d9d2268 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/.svn/text-base/u-boot.h.svn-base @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +typedef struct bd_info { + int bi_baudrate; /* serial console baudrate */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned long bi_arch_number; /* unique id for this board */ + unsigned long bi_boot_params; /* where this board expects params */ + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ +} bd_t; + +struct global_data { + bd_t *bd; /* board data... */ + unsigned long flags; + unsigned long baudrate; + unsigned long have_console; /* serial_init() was called */ + unsigned long ram_size; /* RAM size */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + void **jt; /* jump table */ +}; + +#endif /* _U_BOOT_H_ */ diff --git a/target/linux/adm8668/files/arch/mips/adm8668/Kconfig b/target/linux/adm8668/files/arch/mips/adm8668/Kconfig new file mode 100644 index 0000000..2e7281f --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/Kconfig @@ -0,0 +1,2 @@ +config ARM_AMBA + def_bool y diff --git a/target/linux/adm8668/files/arch/mips/adm8668/Makefile b/target/linux/adm8668/files/arch/mips/adm8668/Makefile new file mode 100644 index 0000000..515c3a4 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/Makefile @@ -0,0 +1,6 @@ +# +# something witty --neutronscott +# + +obj-y := irq.o prom.o platform.o gpio.o \ + setup.o clock.o time.o early_printk.o \ diff --git a/target/linux/adm8668/files/arch/mips/adm8668/Platform b/target/linux/adm8668/files/arch/mips/adm8668/Platform new file mode 100644 index 0000000..c70cd27 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/Platform @@ -0,0 +1,6 @@ +# +# Infineon ADM8668 WildPass +# +platform-$(CONFIG_ADM8668) += adm8668/ +cflags-$(CONFIG_ADM8668) += -I$(srctree)/arch/mips/include/asm/mach-adm8668 +load-$(CONFIG_ADM8668) += 0xffffffff80002000 diff --git a/target/linux/adm8668/files/arch/mips/adm8668/clock.c b/target/linux/adm8668/files/arch/mips/adm8668/clock.c new file mode 100644 index 0000000..1e010fc --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/clock.c @@ -0,0 +1,76 @@ +/* + * ADM8668 minimal clock support + * + * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org> + * + * Licensed under the terms of the GPLv2 + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/clk.h> + +#include <adm8668.h> + +struct clk { + unsigned long rate; +}; + +static struct clk uart_clk = { + .rate = 62500000, +}; + +static struct clk sys_clk; + +struct clk *clk_get(struct device *dev, const char *id) +{ + const char *lookup = id; + + if (dev) + lookup = dev_name(dev); + + if (!strcmp(lookup, "apb:uart0")) + return &uart_clk; + if (!strcmp(lookup, "sys")) + return &sys_clk; + + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +void __init adm8668_init_clocks(void) +{ + u32 adj; + + /* adjustable clock selection + * CR3 bit 14~11, 0000 -> 175MHz, 0001 -> 180MHz, etc... + */ + adj = (ADM8668_CONFIG_REG(ADM8668_CR3) >> 11) & 0xf; + sys_clk.rate = 175000000 + (adj * 5000000); + + pr_info("ADM8668 CPU clock: %lu MHz\n", sys_clk.rate / 1000000); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/early_printk.c b/target/linux/adm8668/files/arch/mips/adm8668/early_printk.c new file mode 100644 index 0000000..03dd72a --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/early_printk.c @@ -0,0 +1,16 @@ +#include <linux/io.h> +#include <linux/amba/serial.h> +#include <adm8668.h> + +#define UART_READ(r) \ + __raw_readl((void __iomem *)(KSEG1ADDR(ADM8668_UART0_BASE) + (r))) + +#define UART_WRITE(v, r) \ + __raw_writel((v), (void __iomem *)(KSEG1ADDR(ADM8668_UART0_BASE) + (r))) + +void prom_putchar(char c) +{ + UART_WRITE(c, UART01x_DR); + while ((UART_READ(UART01x_FR) & UART01x_FR_TXFF) != 0) + ; +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/gpio.c b/target/linux/adm8668/files/arch/mips/adm8668/gpio.c new file mode 100644 index 0000000..fb39f7f --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/gpio.c @@ -0,0 +1,123 @@ +/* + * Infineon/ADMTek ADM8668 WildPass GPIO support + * + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * Licensed under the terms of GPLv2. + * + */ +#include <linux/kernel.h> +#include <linux/gpio.h> +#include <linux/io.h> + +#include <adm8668.h> + +#define GPIO_MASK 0x3f + +#define GPIO_IN_OFS 0 +#define GPIO_OUT_OFS 6 +#define GPIO_OE_OFS 12 + +struct adm8668_gpio_chip { + void __iomem *base; + struct gpio_chip chip; +}; + +static int adm8668_gpio_dir_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 mask; + + /* clear input, set output enable and output value */ + mask = __raw_readl(c->base); + mask &= ~(1 << offset); + mask |= (1 << (offset + GPIO_OE_OFS)); + if (value) + mask |= (1 << (offset + GPIO_OUT_OFS)); + else + mask &= ~(1 << (offset + GPIO_OUT_OFS)); + __raw_writel(mask, c->base); + + return 0; +} + +static int adm8668_gpio_dir_in(struct gpio_chip *chip, + unsigned offset) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 mask; + + mask = __raw_readl(c->base); + mask &= ~(((1 << (offset + GPIO_OE_OFS)) | (1 << (offset + GPIO_OUT_OFS)))); + mask |= (1 << offset); + __raw_writel(mask, c->base); + + return 0; +} + +static void adm8668_gpio_set(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 mask; + + mask = __raw_readl(c->base); + if (value) + mask |= (1 << (offset + GPIO_OUT_OFS)); + else + mask &= ~(1 << (offset + GPIO_OUT_OFS)); + __raw_writel(mask, c->base); +} + +static int adm8668_gpio_get(struct gpio_chip *chip, + unsigned offset) +{ + struct adm8668_gpio_chip *c = + container_of(chip, struct adm8668_gpio_chip, chip); + u32 value; + + value = __raw_readl(c->base) & GPIO_MASK; + + return value & (1 << offset); +} + +static struct adm8668_gpio_chip adm8668_gpio_cpu = { + .base = (void __iomem *)KSEG1ADDR(ADM8668_CONFIG_BASE + CRGPIO_REG), + .chip = { + .label = "adm8668-cpu-gpio", + .direction_output = adm8668_gpio_dir_out, + .direction_input = adm8668_gpio_dir_in, + .set = adm8668_gpio_set, + .get = adm8668_gpio_get, + .ngpio = 6, + }, +}; + +static struct adm8668_gpio_chip adm8668_gpio_wlan = { + .base = (void __iomem *)KSEG1ADDR(ADM8668_WLAN_BASE + GPIO_REG), + .chip = { + .label = "adm8668-wlan-gpio", + .direction_output = adm8668_gpio_dir_out, + .direction_input = adm8668_gpio_dir_in, + .set = adm8668_gpio_set, + .get = adm8668_gpio_get, + .ngpio = 6, + .base = 6, + }, +}; + +static int __init adm8668_gpio_init(void) +{ + int ret; + + ret = gpiochip_add(&adm8668_gpio_cpu.chip); + if (ret) + return ret; + + return gpiochip_add(&adm8668_gpio_wlan.chip); +} +arch_initcall(adm8668_gpio_init); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/irq.c b/target/linux/adm8668/files/arch/mips/adm8668/irq.c new file mode 100644 index 0000000..9d3b2b9 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/irq.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/pm.h> +#include <linux/irq.h> +#include <asm/mipsregs.h> +#include <asm/irq_cpu.h> +#include <asm/irq.h> +#include <adm8668.h> + +/* interrupt controller */ +#define IRQ_STATUS_REG 0x00 /* Read */ +#define IRQ_ENABLE_REG 0x08 /* Read/Write */ +#define IRQ_DISABLE_REG 0x0C /* Write */ + +#define IRQ_MASK 0xffff + +static inline void intc_write_reg(u32 val, unsigned int reg) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(ADM8668_INTC_BASE); + + __raw_writel(val, base + reg); +} + +static inline u32 intc_read_reg(unsigned int reg) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(ADM8668_INTC_BASE); + + return __raw_readl(base + reg); +} + +static void adm8668_irq_cascade(void) +{ + int irq; + u32 intsrc; + + intsrc = intc_read_reg(IRQ_STATUS_REG) & IRQ_MASK; + if (intsrc) { + irq = fls(intsrc) - 1; + do_IRQ(irq); + } else + spurious_interrupt(); +} + +/* + * System irq dispatch + */ +void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + /* timer interrupt, that we renumbered */ + if (pending & STATUSF_IP7) + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + else if (pending & STATUSF_IP2) + adm8668_irq_cascade(); + else + spurious_interrupt(); +} + +/* + * enable 8668 irq + */ +static void enable_adm8668_irq(struct irq_data *d) +{ + intc_write_reg((1 << d->irq), IRQ_ENABLE_REG); +} + + +static void ack_adm8668_irq(struct irq_data *d) +{ + intc_write_reg((1 << d->irq), IRQ_DISABLE_REG); +} + +/* + * system irq type + */ + +static struct irq_chip adm8668_irq_type = { + .name = "adm8668", + .irq_ack = ack_adm8668_irq, + .irq_mask = ack_adm8668_irq, + .irq_unmask = enable_adm8668_irq +}; + +/* + * irq init + */ +static void __init init_adm8668_irqs(void) +{ + int i; + + /* disable all interrupts for the moment */ + intc_write_reg(IRQ_MASK, IRQ_DISABLE_REG); + + for (i = 0; i <= ADM8668_IRQ_MAX; i++) + irq_set_chip_and_handler(i, &adm8668_irq_type, + handle_level_irq); + + /* hw0 is where our interrupts are uh.. interrupted at. */ + set_c0_status(IE_IRQ0); +} + +/* + * system init + */ +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); + init_adm8668_irqs(); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/platform.c b/target/linux/adm8668/files/arch/mips/adm8668/platform.c new file mode 100644 index 0000000..7cd56b7 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/platform.c @@ -0,0 +1,224 @@ +/* + * Infineon/ADMTek 8668 (WildPass) platform devices support + * + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/platform_data/tulip.h> +#include <linux/usb/ehci_pdriver.h> +#include <linux/mtd/physmap.h> +#include <linux/mtd/partitions.h> +#include <linux/pci.h> +#include <linux/slab.h> +#include <linux/ioport.h> +#include <linux/amba/bus.h> +#include <linux/amba/serial.h> + +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <adm8668.h> + +#define ADM8868_UBOOT_ENV 0x20000 +#define ADM8868_UBOOT_WAN_MAC 0x5ac +#define ADM8868_UBOOT_LAN_MAC 0x404 + +static void adm8668_uart_set_mctrl(struct amba_device *dev, + void __iomem *base, + unsigned int mcrtl) +{ +} + +static struct amba_pl010_data adm8668_uart0_data = { + .set_mctrl = adm8668_uart_set_mctrl, +}; + +static struct amba_device adm8668_uart0_device = { + .dev = { + .init_name = "apb:uart0", + .platform_data = &adm8668_uart0_data, + }, + .res = { + .start = ADM8668_UART0_BASE, + .end = ADM8668_UART0_BASE + 0xF, + .flags = IORESOURCE_MEM, + }, + .irq = { + ADM8668_UART0_IRQ, + -1 + }, + .periphid = 0x0041010, +}; + +static struct resource eth0_resources[] = { + { + .start = ADM8668_LAN_BASE, + .end = ADM8668_LAN_BASE + 256, + .flags = IORESOURCE_MEM, + }, + { + .start = ADM8668_LAN_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct tulip_platform_data eth0_pdata = { + .chip_id = ADM8668, +}; + +static struct platform_device adm8668_eth0_device = { + .name = "tulip", + .id = 0, + .resource = eth0_resources, + .num_resources = ARRAY_SIZE(eth0_resources), + .dev.platform_data = ð0_pdata, +}; + +static struct resource eth1_resources[] = { + { + .start = ADM8668_WAN_BASE, + .end = ADM8668_WAN_BASE + 256, + .flags = IORESOURCE_MEM, + }, + { + .start = ADM8668_WAN_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct tulip_platform_data eth1_pdata = { + .chip_id = ADM8668, +}; + +static struct platform_device adm8668_eth1_device = { + .name = "tulip", + .id = 1, + .resource = eth1_resources, + .num_resources = ARRAY_SIZE(eth1_resources), + .dev.platform_data = ð1_pdata, +}; + +static const char *nor_probe_types[] = { "adm8668part", NULL }; + +static struct physmap_flash_data nor_flash_data = { + .width = 2, + .part_probe_types = nor_probe_types, +}; + +static struct resource nor_resources[] = { + { + .start = ADM8668_SMEM1_BASE, + .end = ADM8668_SMEM1_BASE + 0x800000 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device adm8668_nor_device = { + .name = "physmap-flash", + .id = -1, + .resource = nor_resources, + .num_resources = ARRAY_SIZE(nor_resources), + .dev.platform_data = &nor_flash_data, +}; + +static struct resource usb_resources[] = { + { + .start = ADM8668_USB_BASE, + .end = ADM8668_USB_BASE + 0x1FFFFF, + .flags = IORESOURCE_MEM, + }, + { + .start = ADM8668_USB_IRQ, + .end = ADM8668_USB_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct usb_ehci_pdata usb_pdata = { + .caps_offset = 0x100, + .has_tt = 1, + .port_power_off = 1, +}; + +static struct platform_device adm8668_usb_device = { + .name = "ehci-platform", + .id = -1, + .resource = usb_resources, + .num_resources = ARRAY_SIZE(usb_resources), + .dev.platform_data = &usb_pdata, +}; + +static struct platform_device *adm8668_devs[] = { + &adm8668_eth0_device, + &adm8668_eth1_device, + &adm8668_nor_device, + &adm8668_usb_device, +}; + +static void adm8668_fetch_mac(int unit) +{ + u8 *mac; + u32 offset; + struct tulip_platform_data *pdata; + + switch (unit) { + case -1: + case 0: + offset = ADM8868_UBOOT_LAN_MAC; + pdata = ð0_pdata; + break; + case 1: + offset = ADM8868_UBOOT_WAN_MAC; + pdata = ð1_pdata; + break; + default: + pr_err("unsupported ethernet unit: %d\n", unit); + return; + } + + mac = (u8 *)(KSEG1ADDR(ADM8668_SMEM1_BASE) + ADM8868_UBOOT_ENV + offset); + + memcpy(pdata->mac, mac, sizeof(pdata->mac)); +} + +static void adm8668_ehci_workaround(void) +{ + u32 chipid; + + chipid = ADM8668_CONFIG_REG(ADM8668_CR0); + ADM8668_CONFIG_REG(ADM8668_CR66) = 0x0C1600D9; + + if (chipid == 0x86880001) + return; + + ADM8668_CONFIG_REG(ADM8668_CR66) &= ~(3 << 20); + ADM8668_CONFIG_REG(ADM8668_CR66) |= (1 << 20); + pr_info("ADM8668: applied USB workaround\n"); +} + + +int __devinit adm8668_devs_register(void) +{ + int ret; + + ret = amba_device_register(&adm8668_uart0_device, &iomem_resource); + if (ret) + panic("failed to register AMBA UART"); + + adm8668_fetch_mac(0); + adm8668_fetch_mac(1); + adm8668_ehci_workaround(); + + return platform_add_devices(adm8668_devs, ARRAY_SIZE(adm8668_devs)); +} +arch_initcall(adm8668_devs_register); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/prom.c b/target/linux/adm8668/files/arch/mips/adm8668/prom.c new file mode 100644 index 0000000..24b77f8 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/prom.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * + * based on work of rb532 prom.c + * Copyright (C) 2003, Peter Sadik <peter.sadik@idt.com> + * Copyright (C) 2005-2006, P.Christeas <p_christ@hol.gr> + * Copyright (C) 2007, Gabor Juhos <juhosg@openwrt.org> + * Felix Fietkau <nbd@openwrt.org> + * Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/string.h> +#include <linux/serial_core.h> +#include <asm/bootinfo.h> +#include <adm8668.h> +#include "u-boot.h" + +register volatile struct global_data *gd asm ("k0"); + +void __init prom_free_prom_memory(void) +{ + /* No prom memory to free */ +} + +static inline int match_tag(char *arg, const char *tag) +{ + return strncmp(arg, tag, strlen(tag)) == 0; +} + +static inline unsigned long tag2ul(char *arg, const char *tag) +{ + char *num; + + num = arg + strlen(tag); + return simple_strtoul(num, 0, 10); +} + +void __init prom_setup_cmdline(void) +{ + char *cp; + int prom_argc; + char **prom_argv; + int i; + + prom_argc = fw_arg0; + prom_argv = (char **)KSEG0ADDR(fw_arg1); + + cp = &(arcs_cmdline[0]); + for (i = 1; i < prom_argc; i++) { + prom_argv[i] = (char *)KSEG0ADDR(prom_argv[i]); + + /* default bootargs has "console=/dev/ttyS0" yet console won't + * show up at all if you include the '/dev/' nowadays ... */ + if (match_tag(prom_argv[i], "console=/dev/")) { + char *ptr = prom_argv[i] + strlen("console=/dev/"); + + strcpy(cp, "console="); + cp += strlen("console="); + strcpy(cp, ptr); + cp += strlen(ptr); + *cp++ = ' '; + continue; + } + strcpy(cp, prom_argv[i]); + cp += strlen(prom_argv[i]); + *cp++ = ' '; + } + if (prom_argc > 1) + --cp; /* trailing space */ + + *cp = '\0'; +} + +void __init prom_init(void) +{ + bd_t *bd = gd->bd; + int memsize; + + memsize = bd->bi_memsize; + printk("Board info:\n"); + printk(" RAM size: %d MB\n", (int)memsize/(1024*1024)); + printk(" NOR start: %#lx\n", bd->bi_flashstart); + printk(" NOR size: %#lx\n", bd->bi_flashsize); + + prom_setup_cmdline(); + add_memory_region(0, memsize, BOOT_MEM_RAM); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/setup.c b/target/linux/adm8668/files/arch/mips/adm8668/setup.c new file mode 100644 index 0000000..b33c483 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/setup.c @@ -0,0 +1,36 @@ +#include <linux/init.h> +#include <linux/reboot.h> + +#include <asm/reboot.h> +#include <adm8668.h> + +static void adm8668_restart(char *cmd) +{ + int i; + + /* the real deal */ + for (i = 0; i < 1000; i++) + ; + ADM8668_CONFIG_REG(ADM8668_CR1) = 1; +} + +void __init plat_mem_setup(void) +{ + _machine_restart = adm8668_restart; +} + +const char *get_system_type(void) +{ + unsigned long chipid = ADM8668_CONFIG_REG(ADM8668_CR0); + int product, revision; + static char ret[32]; + + product = chipid >> 16; + revision = chipid & 0xffff; + + /* i getting fancy :\ */ + snprintf(ret, sizeof(ret), "ADM%xr%x", product, revision); + + return ret; +} + diff --git a/target/linux/adm8668/files/arch/mips/adm8668/time.c b/target/linux/adm8668/files/arch/mips/adm8668/time.c new file mode 100644 index 0000000..87bdd66 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/time.c @@ -0,0 +1,20 @@ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/clk.h> + +#include <asm/time.h> +#include <adm8668.h> + +void __init plat_time_init(void) +{ + struct clk *sys_clk; + + adm8668_init_clocks(); + + sys_clk = clk_get(NULL, "sys"); + if (IS_ERR(sys_clk)) + panic("unable to get system clock\n"); + + mips_hpt_frequency = clk_get_rate(sys_clk) / 2; +} + diff --git a/target/linux/adm8668/files/arch/mips/adm8668/u-boot.h b/target/linux/adm8668/files/arch/mips/adm8668/u-boot.h new file mode 100644 index 0000000..d9d2268 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/u-boot.h @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +typedef struct bd_info { + int bi_baudrate; /* serial console baudrate */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned long bi_arch_number; /* unique id for this board */ + unsigned long bi_boot_params; /* where this board expects params */ + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ +} bd_t; + +struct global_data { + bd_t *bd; /* board data... */ + unsigned long flags; + unsigned long baudrate; + unsigned long have_console; /* serial_init() was called */ + unsigned long ram_size; /* RAM size */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + void **jt; /* jump table */ +}; + +#endif /* _U_BOOT_H_ */ diff --git a/target/linux/adm8668/files/arch/mips/include/.svn/entries b/target/linux/adm8668/files/arch/mips/include/.svn/entries new file mode 100644 index 0000000..6caecf6 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch/mips/include +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +asm +dir + diff --git a/target/linux/adm8668/files/arch/mips/include/asm/.svn/entries b/target/linux/adm8668/files/arch/mips/include/asm/.svn/entries new file mode 100644 index 0000000..65b6c38 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch/mips/include/asm +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +mach-adm8668 +dir + diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/entries b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/entries new file mode 100644 index 0000000..8d81bcf --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/entries @@ -0,0 +1,167 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668 +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +war.h +file + + + + +2013-03-17T12:12:21.000000Z +555e422f2f7419fd8ebe8d15490fc7ca +2010-11-06T18:54:20.513313Z +23900 +florian + + + + + + + + + + + + + + + + + + + + + +812 + +asm +dir + +irq.h +file + + + + +2013-03-17T12:12:21.000000Z +4ae36a3ee4780ca6b0f3c6477dfc84b9 +2012-12-06T22:40:02.290820Z +34552 +florian + + + + + + + + + + + + + + + + + + + + + +377 + +adm8668.h +file + + + + +2013-03-17T12:12:21.000000Z +10cb9f9df6674d6d7586a94b37a1aad8 +2012-12-06T22:41:14.865616Z +34566 +florian + + + + + + + + + + + + + + + + + + + + + +1975 + +gpio.h +file + + + + +2013-03-17T12:12:21.000000Z +ab9e4f57ac547937aafb036c601de62e +2012-12-06T22:41:04.955973Z +34564 +florian + + + + + + + + + + + + + + + + + + + + + +249 + diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/adm8668.h.svn-base b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/adm8668.h.svn-base new file mode 100644 index 0000000..8a16863 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/adm8668.h.svn-base @@ -0,0 +1,69 @@ +/************************************************************************ + * + * Copyright (c) 2005 + * Infineon Technologies AG + * St. Martin Strasse 53; 81669 Muenchen; Germany + * + ************************************************************************/ + +#ifndef __ADM8668_H__ +#define __ADM8668_H__ + +/*======================= Physical Memory Map ============================*/ +#define ADM8668_SDRAM_BASE 0 +#define ADM8668_SMEM1_BASE 0x10000000 +#define ADM8668_MPMC_BASE 0x11000000 +#define ADM8668_USB_BASE 0x11200000 +#define ADM8668_CONFIG_BASE 0x11400000 +#define ADM8668_WAN_BASE 0x11600000 +#define ADM8668_WLAN_BASE 0x11800000 +#define ADM8668_LAN_BASE 0x11A00000 +#define ADM8668_INTC_BASE 0x1E000000 +#define ADM8668_TMR_BASE 0x1E200000 +#define ADM8668_UART0_BASE 0x1E400000 +#define ADM8668_SMEM0_BASE 0x1FC00000 +#define ADM8668_NAND_BASE 0x1FFFFF00 + +#define ADM8668_PCICFG_BASE 0x12200000 +#define ADM8668_PCIDAT_BASE 0x12400000 + +/* interrupt levels */ +#define ADM8668_SWI_IRQ 1 +#define ADM8668_COMMS_RX_IRQ 2 +#define ADM8668_COMMS_TX_IRQ 3 +#define ADM8668_TIMER0_IRQ 4 +#define ADM8668_TIMER1_IRQ 5 +#define ADM8668_UART0_IRQ 6 +#define ADM8668_LAN_IRQ 7 +#define ADM8668_WAN_IRQ 8 +#define ADM8668_WLAN_IRQ 9 +#define ADM8668_GPIO_IRQ 10 +#define ADM8668_IDE_IRQ 11 +#define ADM8668_PCI2_IRQ 12 +#define ADM8668_PCI1_IRQ 13 +#define ADM8668_PCI0_IRQ 14 +#define ADM8668_USB_IRQ 15 +#define ADM8668_IRQ_MAX ADM8668_USB_IRQ + +/* register access macros */ +#define ADM8668_CONFIG_REG(_reg) \ + (*((volatile unsigned int *)(KSEG1ADDR(ADM8668_CONFIG_BASE + (_reg))))) + +/* lan registers */ +#define NETCSR6 0x30 +#define NETCSR7 0x38 +#define NETCSR37 0xF8 + +/* known/used CPU configuration registers */ +#define ADM8668_CR0 0x00 +#define ADM8668_CR1 0x04 +#define ADM8668_CR3 0x0C +#define ADM8668_CR66 0x108 + +/** For GPIO control **/ +#define GPIO_REG 0x5C /* on WLAN */ +#define CRGPIO_REG 0x20 /* on CPU */ + +void adm8668_init_clocks(void); + +#endif /* __ADM8668_H__ */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/gpio.h.svn-base b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/gpio.h.svn-base new file mode 100644 index 0000000..b0473fc --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/gpio.h.svn-base @@ -0,0 +1,13 @@ +#ifndef __ADM8668_GPIO_H__ +#define __ADM8668_GPIO_H__ + +#define gpio_to_irq(gpio) -1 + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value + +#define gpio_cansleep __gpio_cansleep + +#include <asm-generic/gpio.h> + +#endif diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/irq.h.svn-base b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/irq.h.svn-base new file mode 100644 index 0000000..ea859f0 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/irq.h.svn-base @@ -0,0 +1,14 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 by Ralf Baechle + */ +#ifndef __ASM_MACH_ADM8668_IRQ_H +#define __ASM_MACH_ADM8668_IRQ_H + +#define NR_IRQS 32 +#define MIPS_CPU_IRQ_BASE 16 + +#endif /* __ASM_MACH_ADM8668_IRQ_H */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/war.h.svn-base b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/war.h.svn-base new file mode 100644 index 0000000..7180043 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/.svn/text-base/war.h.svn-base @@ -0,0 +1,25 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> + */ +#ifndef __ASM_MIPS_MACH_ADM8668_WAR_H +#define __ASM_MIPS_MACH_ADM8668_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_ADM8668_WAR_H */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h new file mode 100644 index 0000000..8a16863 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h @@ -0,0 +1,69 @@ +/************************************************************************ + * + * Copyright (c) 2005 + * Infineon Technologies AG + * St. Martin Strasse 53; 81669 Muenchen; Germany + * + ************************************************************************/ + +#ifndef __ADM8668_H__ +#define __ADM8668_H__ + +/*======================= Physical Memory Map ============================*/ +#define ADM8668_SDRAM_BASE 0 +#define ADM8668_SMEM1_BASE 0x10000000 +#define ADM8668_MPMC_BASE 0x11000000 +#define ADM8668_USB_BASE 0x11200000 +#define ADM8668_CONFIG_BASE 0x11400000 +#define ADM8668_WAN_BASE 0x11600000 +#define ADM8668_WLAN_BASE 0x11800000 +#define ADM8668_LAN_BASE 0x11A00000 +#define ADM8668_INTC_BASE 0x1E000000 +#define ADM8668_TMR_BASE 0x1E200000 +#define ADM8668_UART0_BASE 0x1E400000 +#define ADM8668_SMEM0_BASE 0x1FC00000 +#define ADM8668_NAND_BASE 0x1FFFFF00 + +#define ADM8668_PCICFG_BASE 0x12200000 +#define ADM8668_PCIDAT_BASE 0x12400000 + +/* interrupt levels */ +#define ADM8668_SWI_IRQ 1 +#define ADM8668_COMMS_RX_IRQ 2 +#define ADM8668_COMMS_TX_IRQ 3 +#define ADM8668_TIMER0_IRQ 4 +#define ADM8668_TIMER1_IRQ 5 +#define ADM8668_UART0_IRQ 6 +#define ADM8668_LAN_IRQ 7 +#define ADM8668_WAN_IRQ 8 +#define ADM8668_WLAN_IRQ 9 +#define ADM8668_GPIO_IRQ 10 +#define ADM8668_IDE_IRQ 11 +#define ADM8668_PCI2_IRQ 12 +#define ADM8668_PCI1_IRQ 13 +#define ADM8668_PCI0_IRQ 14 +#define ADM8668_USB_IRQ 15 +#define ADM8668_IRQ_MAX ADM8668_USB_IRQ + +/* register access macros */ +#define ADM8668_CONFIG_REG(_reg) \ + (*((volatile unsigned int *)(KSEG1ADDR(ADM8668_CONFIG_BASE + (_reg))))) + +/* lan registers */ +#define NETCSR6 0x30 +#define NETCSR7 0x38 +#define NETCSR37 0xF8 + +/* known/used CPU configuration registers */ +#define ADM8668_CR0 0x00 +#define ADM8668_CR1 0x04 +#define ADM8668_CR3 0x0C +#define ADM8668_CR66 0x108 + +/** For GPIO control **/ +#define GPIO_REG 0x5C /* on WLAN */ +#define CRGPIO_REG 0x20 /* on CPU */ + +void adm8668_init_clocks(void); + +#endif /* __ADM8668_H__ */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/entries b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/entries new file mode 100644 index 0000000..0c5d2e5 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:39:43.120900Z +34548 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +sizes.h +file + + + + +2013-03-17T12:12:21.000000Z +3bede0704cba7e7a951edbbaaac16260 +2012-12-06T22:39:43.120900Z +34548 +florian +has-props + + + + + + + + + + + + + + + + + + + + +2125 + diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/prop-base/sizes.h.svn-base b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/prop-base/sizes.h.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/prop-base/sizes.h.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/text-base/sizes.h.svn-base b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/text-base/sizes.h.svn-base new file mode 100644 index 0000000..503843d --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/.svn/text-base/sizes.h.svn-base @@ -0,0 +1,56 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* DO NOT EDIT!! - this file automatically generated + * from .s file by awk -f s2h.awk + */ +/* Size definitions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h 1 + +/* handy sizes */ +#define SZ_16 0x00000010 +#define SZ_256 0x00000100 +#define SZ_512 0x00000200 + +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif + +/* END */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/sizes.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/sizes.h new file mode 100644 index 0000000..503843d --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/asm/sizes.h @@ -0,0 +1,56 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* DO NOT EDIT!! - this file automatically generated + * from .s file by awk -f s2h.awk + */ +/* Size definitions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h 1 + +/* handy sizes */ +#define SZ_16 0x00000010 +#define SZ_256 0x00000100 +#define SZ_512 0x00000200 + +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif + +/* END */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/gpio.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/gpio.h new file mode 100644 index 0000000..b0473fc --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/gpio.h @@ -0,0 +1,13 @@ +#ifndef __ADM8668_GPIO_H__ +#define __ADM8668_GPIO_H__ + +#define gpio_to_irq(gpio) -1 + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value + +#define gpio_cansleep __gpio_cansleep + +#include <asm-generic/gpio.h> + +#endif diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/irq.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/irq.h new file mode 100644 index 0000000..ea859f0 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/irq.h @@ -0,0 +1,14 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 by Ralf Baechle + */ +#ifndef __ASM_MACH_ADM8668_IRQ_H +#define __ASM_MACH_ADM8668_IRQ_H + +#define NR_IRQS 32 +#define MIPS_CPU_IRQ_BASE 16 + +#endif /* __ASM_MACH_ADM8668_IRQ_H */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/war.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/war.h new file mode 100644 index 0000000..7180043 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/war.h @@ -0,0 +1,25 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> + */ +#ifndef __ASM_MIPS_MACH_ADM8668_WAR_H +#define __ASM_MIPS_MACH_ADM8668_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_ADM8668_WAR_H */ diff --git a/target/linux/adm8668/files/arch/mips/pci/.svn/entries b/target/linux/adm8668/files/arch/mips/pci/.svn/entries new file mode 100644 index 0000000..0246bb2 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/pci/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/arch/mips/pci +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:40:12.205377Z +34553 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +pci-adm8668.c +file + + + + +2013-03-17T12:12:21.000000Z +61448a32a3d9242b13e980144661e39f +2012-12-06T22:40:12.205377Z +34553 +florian + + + + + + + + + + + + + + + + + + + + + +4259 + diff --git a/target/linux/adm8668/files/arch/mips/pci/.svn/text-base/pci-adm8668.c.svn-base b/target/linux/adm8668/files/arch/mips/pci/.svn/text-base/pci-adm8668.c.svn-base new file mode 100644 index 0000000..5cfa546 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/pci/.svn/text-base/pci-adm8668.c.svn-base @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Note that this controller is identical to the ADM5120 one + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <linux/spinlock.h> + +#include <asm/byteorder.h> +#include <asm/pci.h> +#include <adm8668.h> + +static DEFINE_SPINLOCK(pci_lock); + +#define PCI_ENABLE 0x80000000 +#define ADMPCI_IO_BASE 0x12600000 +#define ADMPCI_IO_SIZE 0x1fffff +#define ADMPCI_MEM_BASE 0x16000000 +#define ADMPCI_MEM_SIZE 0x7ffffff + +static inline void write_cfgaddr(u32 addr) +{ + __raw_writel((addr | PCI_ENABLE), + (void __iomem *)KSEG1ADDR(ADM8668_PCICFG_BASE)); +} + +static inline void write_cfgdata(u32 data) +{ + __raw_writel(data, (void __iomem *)KSEG1ADDR(ADM8668_PCIDAT_BASE)); +} + +static inline u32 read_cfgdata(void) +{ + return __raw_readl((void __iomem *)KSEG1ADDR(ADM8668_PCIDAT_BASE)); +} + +static inline u32 mkaddr(struct pci_bus *bus, unsigned int devfn, int where) +{ + return ((bus->number & 0xff) << 16) | ((devfn & 0xff) << 8) | + (where & 0xfc); +} + +static int pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + unsigned long flags; + u32 data; + + spin_lock_irqsave(&pci_lock, flags); + write_cfgaddr(mkaddr(bus, devfn, where)); + data = read_cfgdata(); + + switch (size) { + case 1: + if (where & 1) + data >>= 8; + if (where & 2) + data >>= 16; + data &= 0xff; + break; + case 2: + if (where & 2) + data >>= 16; + data &= 0xffff; + break; + } + + *val = data; + + spin_unlock_irqrestore(&pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + unsigned long flags; + u32 data; + int s; + + spin_lock_irqsave(&pci_lock, flags); + + write_cfgaddr(mkaddr(bus, devfn, where)); + data = read_cfgdata(); + + switch (size) { + case 1: + s = ((where & 3) << 3); + data &= ~(0xff << s); + data |= ((val & 0xff) << s); + break; + case 2: + s = ((where & 2) << 4); + data &= ~(0xffff << s); + data |= ((val & 0xffff) << s); + break; + case 4: + data = val; + break; + } + + write_cfgdata(data); + + spin_unlock_irqrestore(&pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops adm8668_pci_ops = { + .read = pci_read_config, + .write = pci_write_config +}; + + +struct resource pciioport_resource = { + .name = "adm8668_pci", + .start = ADMPCI_IO_BASE, + .end = ADMPCI_IO_BASE + ADMPCI_IO_SIZE, + .flags = IORESOURCE_IO +}; + +struct resource pciiomem_resource = { + .name = "adm8668_pci", + .start = ADMPCI_MEM_BASE, + .end = ADMPCI_MEM_BASE + ADMPCI_MEM_SIZE, + .flags = IORESOURCE_MEM +}; + +struct pci_controller adm8668_pci_controller = { + .pci_ops = &adm8668_pci_ops, + .io_resource = &pciioport_resource, + .mem_resource = &pciiomem_resource, +}; + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { + case 1: + return 14; + case 2: + return 13; + case 3: + return 12; + default: + return dev->irq; + } +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static void adm8668_pci_fixup(struct pci_dev *dev) +{ + if (dev->devfn != 0) + return; + + pr_info("PCI: fixing up ADM8668 controller\n"); + + /* setup COMMAND register */ + pci_write_config_word(dev, PCI_COMMAND, + (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); + + /* setup CACHE_LINE_SIZE register */ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); + + /* setup BARS */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); +} +DECLARE_PCI_FIXUP_HEADER(0x1317, 0x8688, adm8668_pci_fixup); + +static int __init adm8668_pci_init(void) +{ + void __iomem *io_map_base; + + ioport_resource.start = ADMPCI_IO_BASE; + ioport_resource.end = ADMPCI_IO_BASE + ADMPCI_IO_SIZE; + + io_map_base = ioremap(ADMPCI_IO_BASE, ADMPCI_IO_SIZE); + if (!io_map_base) + printk("io_map_base didn't work.\n"); + + adm8668_pci_controller.io_map_base = (unsigned long)io_map_base; + register_pci_controller(&adm8668_pci_controller); + + return 0; +} +arch_initcall(adm8668_pci_init); diff --git a/target/linux/adm8668/files/arch/mips/pci/pci-adm8668.c b/target/linux/adm8668/files/arch/mips/pci/pci-adm8668.c new file mode 100644 index 0000000..5cfa546 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/pci/pci-adm8668.c @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Note that this controller is identical to the ADM5120 one + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <linux/spinlock.h> + +#include <asm/byteorder.h> +#include <asm/pci.h> +#include <adm8668.h> + +static DEFINE_SPINLOCK(pci_lock); + +#define PCI_ENABLE 0x80000000 +#define ADMPCI_IO_BASE 0x12600000 +#define ADMPCI_IO_SIZE 0x1fffff +#define ADMPCI_MEM_BASE 0x16000000 +#define ADMPCI_MEM_SIZE 0x7ffffff + +static inline void write_cfgaddr(u32 addr) +{ + __raw_writel((addr | PCI_ENABLE), + (void __iomem *)KSEG1ADDR(ADM8668_PCICFG_BASE)); +} + +static inline void write_cfgdata(u32 data) +{ + __raw_writel(data, (void __iomem *)KSEG1ADDR(ADM8668_PCIDAT_BASE)); +} + +static inline u32 read_cfgdata(void) +{ + return __raw_readl((void __iomem *)KSEG1ADDR(ADM8668_PCIDAT_BASE)); +} + +static inline u32 mkaddr(struct pci_bus *bus, unsigned int devfn, int where) +{ + return ((bus->number & 0xff) << 16) | ((devfn & 0xff) << 8) | + (where & 0xfc); +} + +static int pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + unsigned long flags; + u32 data; + + spin_lock_irqsave(&pci_lock, flags); + write_cfgaddr(mkaddr(bus, devfn, where)); + data = read_cfgdata(); + + switch (size) { + case 1: + if (where & 1) + data >>= 8; + if (where & 2) + data >>= 16; + data &= 0xff; + break; + case 2: + if (where & 2) + data >>= 16; + data &= 0xffff; + break; + } + + *val = data; + + spin_unlock_irqrestore(&pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + unsigned long flags; + u32 data; + int s; + + spin_lock_irqsave(&pci_lock, flags); + + write_cfgaddr(mkaddr(bus, devfn, where)); + data = read_cfgdata(); + + switch (size) { + case 1: + s = ((where & 3) << 3); + data &= ~(0xff << s); + data |= ((val & 0xff) << s); + break; + case 2: + s = ((where & 2) << 4); + data &= ~(0xffff << s); + data |= ((val & 0xffff) << s); + break; + case 4: + data = val; + break; + } + + write_cfgdata(data); + + spin_unlock_irqrestore(&pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops adm8668_pci_ops = { + .read = pci_read_config, + .write = pci_write_config +}; + + +struct resource pciioport_resource = { + .name = "adm8668_pci", + .start = ADMPCI_IO_BASE, + .end = ADMPCI_IO_BASE + ADMPCI_IO_SIZE, + .flags = IORESOURCE_IO +}; + +struct resource pciiomem_resource = { + .name = "adm8668_pci", + .start = ADMPCI_MEM_BASE, + .end = ADMPCI_MEM_BASE + ADMPCI_MEM_SIZE, + .flags = IORESOURCE_MEM +}; + +struct pci_controller adm8668_pci_controller = { + .pci_ops = &adm8668_pci_ops, + .io_resource = &pciioport_resource, + .mem_resource = &pciiomem_resource, +}; + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { + case 1: + return 14; + case 2: + return 13; + case 3: + return 12; + default: + return dev->irq; + } +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static void adm8668_pci_fixup(struct pci_dev *dev) +{ + if (dev->devfn != 0) + return; + + pr_info("PCI: fixing up ADM8668 controller\n"); + + /* setup COMMAND register */ + pci_write_config_word(dev, PCI_COMMAND, + (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); + + /* setup CACHE_LINE_SIZE register */ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); + + /* setup BARS */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); +} +DECLARE_PCI_FIXUP_HEADER(0x1317, 0x8688, adm8668_pci_fixup); + +static int __init adm8668_pci_init(void) +{ + void __iomem *io_map_base; + + ioport_resource.start = ADMPCI_IO_BASE; + ioport_resource.end = ADMPCI_IO_BASE + ADMPCI_IO_SIZE; + + io_map_base = ioremap(ADMPCI_IO_BASE, ADMPCI_IO_SIZE); + if (!io_map_base) + printk("io_map_base didn't work.\n"); + + adm8668_pci_controller.io_map_base = (unsigned long)io_map_base; + register_pci_controller(&adm8668_pci_controller); + + return 0; +} +arch_initcall(adm8668_pci_init); diff --git a/target/linux/adm8668/files/drivers/.svn/entries b/target/linux/adm8668/files/drivers/.svn/entries new file mode 100644 index 0000000..3a64176 --- /dev/null +++ b/target/linux/adm8668/files/drivers/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/drivers +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:40:17.135311Z +34554 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +mtd +dir + diff --git a/target/linux/adm8668/files/drivers/mtd/.svn/entries b/target/linux/adm8668/files/drivers/mtd/.svn/entries new file mode 100644 index 0000000..d7e59d4 --- /dev/null +++ b/target/linux/adm8668/files/drivers/mtd/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/drivers/mtd +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:40:17.135311Z +34554 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +maps +dir + diff --git a/target/linux/adm8668/files/drivers/mtd/maps/.svn/entries b/target/linux/adm8668/files/drivers/mtd/maps/.svn/entries new file mode 100644 index 0000000..f4aabda --- /dev/null +++ b/target/linux/adm8668/files/drivers/mtd/maps/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/target/linux/adm8668/files/drivers/mtd/maps +svn://svn.openwrt.org/openwrt + + + +2012-12-06T22:40:17.135311Z +34554 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +adm8668.c +file + + + + +2013-03-17T12:12:21.000000Z +81273563c0bdd2580da032a511f374e7 +2012-12-06T22:40:17.135311Z +34554 +florian + + + + + + + + + + + + + + + + + + + + + +8203 + diff --git a/target/linux/adm8668/files/drivers/mtd/maps/.svn/text-base/adm8668.c.svn-base b/target/linux/adm8668/files/drivers/mtd/maps/.svn/text-base/adm8668.c.svn-base new file mode 100644 index 0000000..7ef0ada --- /dev/null +++ b/target/linux/adm8668/files/drivers/mtd/maps/.svn/text-base/adm8668.c.svn-base @@ -0,0 +1,263 @@ +/* + * Infineon/ADMTek ADM8668 (WildPass) partition parser support + * + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * original functions for finding root filesystem from Mike Baker + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * Copyright 2004, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/wait.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/crc32.h> +#include <linux/magic.h> + +#define PFX "adm8668-part: " + +/* first a little bit about the headers i need.. */ + +/* just interested in part of the full struct */ +struct squashfs_super_block { + __le32 s_magic; + __le32 pad0[9]; /* it's not really padding */ + __le64 bytes_used; +}; + +#define IH_MAGIC 0x56190527 /* Image Magic Number */ +struct uboot_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + char ih_name[32]; /* image name */ +}; + +/* in case i wanna change stuff later, and to clarify the math section... */ +#define PART_LINUX 0 +#define PART_ROOTFS 1 +#define PART_UBOOT_ENV 2 +#define NR_PARTS 3 + +static int adm8668_parse_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + int ret; + struct uboot_header uhdr; + int off, blocksize; + size_t len, linux_len; + struct squashfs_super_block shdr; + struct erase_info erase_info; + struct mtd_partition *adm8668_parts; + + memset(&erase_info, 0, sizeof(erase_info)); + + blocksize = master->erasesize; + + if (blocksize < 0x10000) + blocksize = 0x10000; + + adm8668_parts = kzalloc(sizeof(*adm8668_parts) * NR_PARTS, GFP_KERNEL); + if (!adm8668_parts) + return -ENOMEM; + + adm8668_parts[PART_LINUX].name = kstrdup("linux", GFP_KERNEL); + adm8668_parts[PART_LINUX].offset = 0x40000; + adm8668_parts[PART_LINUX].size = master->size - 0x40000; + adm8668_parts[PART_ROOTFS].name = kstrdup("rootfs", GFP_KERNEL); + adm8668_parts[PART_ROOTFS].offset = 0xe0000; + adm8668_parts[PART_ROOTFS].size = 0x140000; + adm8668_parts[PART_UBOOT_ENV].name = kstrdup("uboot_env", GFP_KERNEL); + adm8668_parts[PART_UBOOT_ENV].offset = 0x20000; + adm8668_parts[PART_UBOOT_ENV].size = 0x20000; + + /* now find squashfs */ + memset(&shdr, 0xe5, sizeof(shdr)); + + for (off = 0x40000; off < master->size; off += blocksize) { + /* + * Read into buffer + */ + if (mtd_read(master, off, sizeof(shdr), &len, (char *)&shdr) || + len != sizeof(shdr)) + continue; + + if (shdr.s_magic == SQUASHFS_MAGIC) { + uint32_t fs_size = (uint32_t)shdr.bytes_used; + + pr_info(PFX "filesystem type: squashfs, size=%dkB\n", + fs_size >> 10); + + /* + * Update rootfs based on the superblock info, and + * stretch to end of MTD. rootfs_split will split it + */ + adm8668_parts[PART_ROOTFS].offset = off; + adm8668_parts[PART_ROOTFS].size = master->size - + adm8668_parts[PART_ROOTFS].offset; + + /* + * kernel ends where rootfs starts + * but we'll keep it full-length for upgrades + */ + linux_len = adm8668_parts[PART_LINUX + 1].offset - + adm8668_parts[PART_LINUX].offset; + + adm8668_parts[PART_LINUX].size = master->size - + adm8668_parts[PART_LINUX].offset; + goto found; + } + } + + pr_err(PFX "could't find root filesystem\n"); + return NR_PARTS; + +found: + if (mtd_read(master, adm8668_parts[PART_LINUX].offset, sizeof(uhdr), &len, (char *)&uhdr) || + len != sizeof(uhdr)) { + pr_err(PFX "failed to read u-boot header\n"); + return NR_PARTS; + } + + if (uhdr.ih_magic != IH_MAGIC) { + pr_info(PFX "invalid u-boot magic detected?!?!\n"); + return NR_PARTS; + } + + if (be32_to_cpu(uhdr.ih_size) != (linux_len - sizeof(uhdr))) { + u32 data; + size_t data_len = 0; + unsigned char *block; + unsigned int offset; + + offset = adm8668_parts[PART_LINUX].offset + + sizeof(struct uboot_header); + + pr_info(PFX "Updating U-boot image:\n"); + pr_info(PFX " old: [size: %8d crc32: 0x%08x]\n", + be32_to_cpu(uhdr.ih_size), be32_to_cpu(uhdr.ih_dcrc)); + + if (mtd_read(master, offset, sizeof(data), &data_len, (char *)&data)) { + pr_err(PFX "failed to read data\n"); + goto out; + } + + /* Update the data length & crc32 */ + uhdr.ih_size = cpu_to_be32(linux_len - sizeof(uhdr)); + uhdr.ih_dcrc = crc32_le(~0, (char *)&data, linux_len - sizeof(uhdr)) ^ (~0); + uhdr.ih_dcrc = cpu_to_be32(uhdr.ih_dcrc); + + pr_info(PFX " new: [size: %8d crc32: 0x%08x]\n", + be32_to_cpu(uhdr.ih_size), be32_to_cpu(uhdr.ih_dcrc)); + + /* update header's crc... */ + uhdr.ih_hcrc = 0; + uhdr.ih_hcrc = crc32_le(~0, (unsigned char *)&uhdr, + sizeof(uhdr)) ^ (~0); + uhdr.ih_hcrc = cpu_to_be32(uhdr.ih_hcrc); + + /* read first eraseblock from the image */ + block = vmalloc(master->erasesize); + if (!block) + return -ENOMEM; + + if (mtd_read(master, adm8668_parts[PART_LINUX].offset, master->erasesize, &len, block) + || len != master->erasesize) { + pr_err(PFX "error copying first eraseblock\n"); + return 0; + } + + /* Write updated header to the flash */ + memcpy(block, &uhdr, sizeof(uhdr)); + if (master->unlock) + master->unlock(master, off, master->erasesize); + + erase_info.mtd = master; + erase_info.addr = (uint64_t)adm8668_parts[PART_LINUX].offset; + erase_info.len = master->erasesize; + ret = mtd_erase(master, &erase_info); + if (!ret) { + if (mtd_write(master, adm8668_parts[PART_LINUX].offset, master->erasesize, + &len, block)) + pr_err(PFX "write failed"); + } else + pr_err(PFX "erase failed"); + + mtd_sync(master); +out: + if (block) + vfree(block); + pr_info(PFX "done\n"); + } + + *pparts = adm8668_parts; + + return NR_PARTS; +} + +static struct mtd_part_parser adm8668_parser = { + .owner = THIS_MODULE, + .parse_fn = adm8668_parse_partitions, + .name = "adm8668part", +}; + +static int __init adm8668_parser_init(void) +{ + return register_mtd_parser(&adm8668_parser); +} + +static void __exit adm8668_parser_exit(void) +{ + deregister_mtd_parser(&adm8668_parser); +} + +module_init(adm8668_parser_init); +module_exit(adm8668_parser_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Scott Nicholas <neutronscott@scottn.us>"); +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); +MODULE_DESCRIPTION("MTD partition parser for ADM8668"); diff --git a/target/linux/adm8668/files/drivers/mtd/maps/adm8668.c b/target/linux/adm8668/files/drivers/mtd/maps/adm8668.c new file mode 100644 index 0000000..7ef0ada --- /dev/null +++ b/target/linux/adm8668/files/drivers/mtd/maps/adm8668.c @@ -0,0 +1,263 @@ +/* + * Infineon/ADMTek ADM8668 (WildPass) partition parser support + * + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * original functions for finding root filesystem from Mike Baker + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * Copyright 2004, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/wait.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/crc32.h> +#include <linux/magic.h> + +#define PFX "adm8668-part: " + +/* first a little bit about the headers i need.. */ + +/* just interested in part of the full struct */ +struct squashfs_super_block { + __le32 s_magic; + __le32 pad0[9]; /* it's not really padding */ + __le64 bytes_used; +}; + +#define IH_MAGIC 0x56190527 /* Image Magic Number */ +struct uboot_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + char ih_name[32]; /* image name */ +}; + +/* in case i wanna change stuff later, and to clarify the math section... */ +#define PART_LINUX 0 +#define PART_ROOTFS 1 +#define PART_UBOOT_ENV 2 +#define NR_PARTS 3 + +static int adm8668_parse_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + int ret; + struct uboot_header uhdr; + int off, blocksize; + size_t len, linux_len; + struct squashfs_super_block shdr; + struct erase_info erase_info; + struct mtd_partition *adm8668_parts; + + memset(&erase_info, 0, sizeof(erase_info)); + + blocksize = master->erasesize; + + if (blocksize < 0x10000) + blocksize = 0x10000; + + adm8668_parts = kzalloc(sizeof(*adm8668_parts) * NR_PARTS, GFP_KERNEL); + if (!adm8668_parts) + return -ENOMEM; + + adm8668_parts[PART_LINUX].name = kstrdup("linux", GFP_KERNEL); + adm8668_parts[PART_LINUX].offset = 0x40000; + adm8668_parts[PART_LINUX].size = master->size - 0x40000; + adm8668_parts[PART_ROOTFS].name = kstrdup("rootfs", GFP_KERNEL); + adm8668_parts[PART_ROOTFS].offset = 0xe0000; + adm8668_parts[PART_ROOTFS].size = 0x140000; + adm8668_parts[PART_UBOOT_ENV].name = kstrdup("uboot_env", GFP_KERNEL); + adm8668_parts[PART_UBOOT_ENV].offset = 0x20000; + adm8668_parts[PART_UBOOT_ENV].size = 0x20000; + + /* now find squashfs */ + memset(&shdr, 0xe5, sizeof(shdr)); + + for (off = 0x40000; off < master->size; off += blocksize) { + /* + * Read into buffer + */ + if (mtd_read(master, off, sizeof(shdr), &len, (char *)&shdr) || + len != sizeof(shdr)) + continue; + + if (shdr.s_magic == SQUASHFS_MAGIC) { + uint32_t fs_size = (uint32_t)shdr.bytes_used; + + pr_info(PFX "filesystem type: squashfs, size=%dkB\n", + fs_size >> 10); + + /* + * Update rootfs based on the superblock info, and + * stretch to end of MTD. rootfs_split will split it + */ + adm8668_parts[PART_ROOTFS].offset = off; + adm8668_parts[PART_ROOTFS].size = master->size - + adm8668_parts[PART_ROOTFS].offset; + + /* + * kernel ends where rootfs starts + * but we'll keep it full-length for upgrades + */ + linux_len = adm8668_parts[PART_LINUX + 1].offset - + adm8668_parts[PART_LINUX].offset; + + adm8668_parts[PART_LINUX].size = master->size - + adm8668_parts[PART_LINUX].offset; + goto found; + } + } + + pr_err(PFX "could't find root filesystem\n"); + return NR_PARTS; + +found: + if (mtd_read(master, adm8668_parts[PART_LINUX].offset, sizeof(uhdr), &len, (char *)&uhdr) || + len != sizeof(uhdr)) { + pr_err(PFX "failed to read u-boot header\n"); + return NR_PARTS; + } + + if (uhdr.ih_magic != IH_MAGIC) { + pr_info(PFX "invalid u-boot magic detected?!?!\n"); + return NR_PARTS; + } + + if (be32_to_cpu(uhdr.ih_size) != (linux_len - sizeof(uhdr))) { + u32 data; + size_t data_len = 0; + unsigned char *block; + unsigned int offset; + + offset = adm8668_parts[PART_LINUX].offset + + sizeof(struct uboot_header); + + pr_info(PFX "Updating U-boot image:\n"); + pr_info(PFX " old: [size: %8d crc32: 0x%08x]\n", + be32_to_cpu(uhdr.ih_size), be32_to_cpu(uhdr.ih_dcrc)); + + if (mtd_read(master, offset, sizeof(data), &data_len, (char *)&data)) { + pr_err(PFX "failed to read data\n"); + goto out; + } + + /* Update the data length & crc32 */ + uhdr.ih_size = cpu_to_be32(linux_len - sizeof(uhdr)); + uhdr.ih_dcrc = crc32_le(~0, (char *)&data, linux_len - sizeof(uhdr)) ^ (~0); + uhdr.ih_dcrc = cpu_to_be32(uhdr.ih_dcrc); + + pr_info(PFX " new: [size: %8d crc32: 0x%08x]\n", + be32_to_cpu(uhdr.ih_size), be32_to_cpu(uhdr.ih_dcrc)); + + /* update header's crc... */ + uhdr.ih_hcrc = 0; + uhdr.ih_hcrc = crc32_le(~0, (unsigned char *)&uhdr, + sizeof(uhdr)) ^ (~0); + uhdr.ih_hcrc = cpu_to_be32(uhdr.ih_hcrc); + + /* read first eraseblock from the image */ + block = vmalloc(master->erasesize); + if (!block) + return -ENOMEM; + + if (mtd_read(master, adm8668_parts[PART_LINUX].offset, master->erasesize, &len, block) + || len != master->erasesize) { + pr_err(PFX "error copying first eraseblock\n"); + return 0; + } + + /* Write updated header to the flash */ + memcpy(block, &uhdr, sizeof(uhdr)); + if (master->unlock) + master->unlock(master, off, master->erasesize); + + erase_info.mtd = master; + erase_info.addr = (uint64_t)adm8668_parts[PART_LINUX].offset; + erase_info.len = master->erasesize; + ret = mtd_erase(master, &erase_info); + if (!ret) { + if (mtd_write(master, adm8668_parts[PART_LINUX].offset, master->erasesize, + &len, block)) + pr_err(PFX "write failed"); + } else + pr_err(PFX "erase failed"); + + mtd_sync(master); +out: + if (block) + vfree(block); + pr_info(PFX "done\n"); + } + + *pparts = adm8668_parts; + + return NR_PARTS; +} + +static struct mtd_part_parser adm8668_parser = { + .owner = THIS_MODULE, + .parse_fn = adm8668_parse_partitions, + .name = "adm8668part", +}; + +static int __init adm8668_parser_init(void) +{ + return register_mtd_parser(&adm8668_parser); +} + +static void __exit adm8668_parser_exit(void) +{ + deregister_mtd_parser(&adm8668_parser); +} + +module_init(adm8668_parser_init); +module_exit(adm8668_parser_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Scott Nicholas <neutronscott@scottn.us>"); +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); +MODULE_DESCRIPTION("MTD partition parser for ADM8668"); |