From e1df057df814a4a70a8711c0226a1d178c33edaa Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 16 May 2010 15:25:30 +0200 Subject: MIPS: AR7: Fix typo in ar7.h This fixes a typo on the AR7_RESET_PERIPHERAL define. Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1247/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-ar7/ar7.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/mips/include/asm') diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h index f1cf3894349..483ffea9ecb 100644 --- a/arch/mips/include/asm/mach-ar7/ar7.h +++ b/arch/mips/include/asm/mach-ar7/ar7.h @@ -50,7 +50,7 @@ #define UR8_REGS_WDT (AR7_REGS_BASE + 0x0b00) #define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00) -#define AR7_RESET_PEREPHERIAL 0x0 +#define AR7_RESET_PERIPHERAL 0x0 #define AR7_RESET_SOFTWARE 0x4 #define AR7_RESET_STATUS 0x8 @@ -128,7 +128,7 @@ static inline int ar7_has_high_cpmac(void) static inline void ar7_device_enable(u32 bit) { void *reset_reg = - (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); + (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL); writel(readl(reset_reg) | (1 << bit), reset_reg); msleep(20); } @@ -136,7 +136,7 @@ static inline void ar7_device_enable(u32 bit) static inline void ar7_device_disable(u32 bit) { void *reset_reg = - (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); + (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL); writel(readl(reset_reg) & ~(1 << bit), reset_reg); msleep(20); } -- cgit v1.2.3-70-g09d2 From cdf22a4e90ea3ea8e6a7dd9d2fa810b4a3cdfaed Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 24 May 2010 17:36:24 +0900 Subject: MIPS: AR7, BCM63xx: fix gpio_to_irq() return value The return value of gpio_to_irq() is not a pointer but an integer. Signed-off-by: Yoichi Yuasa Cc: linux-mips Patchwork: http://patchwork.linux-mips.org/patch/1280/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-ar7/gpio.h | 2 +- arch/mips/include/asm/mach-bcm63xx/gpio.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/include/asm') diff --git a/arch/mips/include/asm/mach-ar7/gpio.h b/arch/mips/include/asm/mach-ar7/gpio.h index 73f9b162c97..abc317c0372 100644 --- a/arch/mips/include/asm/mach-ar7/gpio.h +++ b/arch/mips/include/asm/mach-ar7/gpio.h @@ -24,7 +24,7 @@ #define AR7_GPIO_MAX 32 #define NR_BUILTIN_GPIO AR7_GPIO_MAX -#define gpio_to_irq(gpio) NULL +#define gpio_to_irq(gpio) -1 #define gpio_get_value __gpio_get_value #define gpio_set_value __gpio_set_value diff --git a/arch/mips/include/asm/mach-bcm63xx/gpio.h b/arch/mips/include/asm/mach-bcm63xx/gpio.h index 7cda8c0a397..1eb534de8e3 100644 --- a/arch/mips/include/asm/mach-bcm63xx/gpio.h +++ b/arch/mips/include/asm/mach-bcm63xx/gpio.h @@ -3,7 +3,7 @@ #include -#define gpio_to_irq(gpio) NULL +#define gpio_to_irq(gpio) -1 #define gpio_get_value __gpio_get_value #define gpio_set_value __gpio_set_value -- cgit v1.2.3-70-g09d2 From 2e93d1ec080e4b21a34869129bda73f24ebb8950 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Mon, 24 May 2010 19:42:52 +0200 Subject: MIPS: Alchemy: sleepcode without compile-time cputype dependencies Split the low-level sleepcode into per-cpu functions instead of relying on compile-time-defined cpu type. Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: http://patchwork.linux-mips.org/patch/1281/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/power.c | 12 +++-- arch/mips/alchemy/common/sleeper.S | 81 +++++++++++++++++++----------- arch/mips/include/asm/mach-au1x00/au1000.h | 3 +- 3 files changed, 64 insertions(+), 32 deletions(-) (limited to 'arch/mips/include/asm') diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 14eb8c492da..5ef06a164a8 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c @@ -193,9 +193,15 @@ static void restore_core_regs(void) void au_sleep(void) { - save_core_regs(); - au1xxx_save_and_sleep(); - restore_core_regs(); + int cpuid = alchemy_get_cputype(); + if (cpuid != ALCHEMY_CPU_UNKNOWN) { + save_core_regs(); + if (cpuid <= ALCHEMY_CPU_AU1500) + alchemy_sleep_au1000(); + else if (cpuid <= ALCHEMY_CPU_AU1200) + alchemy_sleep_au1550(); + restore_core_regs(); + } } #endif /* CONFIG_PM */ diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S index 4f4b16741d1..77f3c743b71 100644 --- a/arch/mips/alchemy/common/sleeper.S +++ b/arch/mips/alchemy/common/sleeper.S @@ -22,10 +22,9 @@ .set noat .align 5 -/* Save all of the processor general registers and go to sleep. - * A wakeup condition will get us back here to restore the registers. - */ -LEAF(au1xxx_save_and_sleep) + +/* preparatory stuff */ +.macro SETUP_SLEEP subu sp, PT_SIZE sw $1, PT_R1(sp) sw $2, PT_R2(sp) @@ -69,12 +68,32 @@ LEAF(au1xxx_save_and_sleep) */ lui t3, 0xb190 /* sys_xxx */ sw sp, 0x0018(t3) - la k0, 3f /* resume path */ + la k0, alchemy_sleep_wakeup /* resume path */ sw k0, 0x001c(t3) +.endm - /* Put SDRAM into self refresh: Preload instructions into cache, - * issue a precharge, auto/self refresh, then sleep commands to it. - */ +.macro DO_SLEEP + /* put power supply and processor to sleep */ + sw zero, 0x0078(t3) /* sys_slppwr */ + sync + sw zero, 0x007c(t3) /* sys_sleep */ + sync + nop + nop + nop + nop + nop + nop + nop + nop +.endm + +/* sleep code for Au1000/Au1100/Au1500 memory controller type */ +LEAF(alchemy_sleep_au1000) + + SETUP_SLEEP + + /* cache following instructions, as memory gets put to sleep */ la t0, 1f .set mips3 cache 0x14, 0(t0) @@ -84,17 +103,32 @@ LEAF(au1xxx_save_and_sleep) .set mips0 1: lui a0, 0xb400 /* mem_xxx */ -#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || \ - defined(CONFIG_SOC_AU1500) sw zero, 0x001c(a0) /* Precharge */ sync sw zero, 0x0020(a0) /* Auto Refresh */ sync sw zero, 0x0030(a0) /* Sleep */ sync -#endif -#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) + DO_SLEEP + +END(alchemy_sleep_au1000) + +/* sleep code for Au1550/Au1200 memory controller type */ +LEAF(alchemy_sleep_au1550) + + SETUP_SLEEP + + /* cache following instructions, as memory gets put to sleep */ + la t0, 1f + .set mips3 + cache 0x14, 0(t0) + cache 0x14, 32(t0) + cache 0x14, 64(t0) + cache 0x14, 96(t0) + .set mips0 + +1: lui a0, 0xb400 /* mem_xxx */ sw zero, 0x08c0(a0) /* Precharge */ sync sw zero, 0x08d0(a0) /* Self Refresh */ @@ -114,26 +148,17 @@ LEAF(au1xxx_save_and_sleep) and t1, t0, t1 /* clear CE[1:0] */ sw t1, 0x0840(a0) /* mem_sdconfiga */ sync -#endif - /* put power supply and processor to sleep */ - sw zero, 0x0078(t3) /* sys_slppwr */ - sync - sw zero, 0x007c(t3) /* sys_sleep */ - sync - nop - nop - nop - nop - nop - nop - nop - nop + DO_SLEEP + +END(alchemy_sleep_au1550) + /* This is where we return upon wakeup. * Reload all of the registers and return. */ -3: lw k0, 0x20(sp) +LEAF(alchemy_sleep_wakeup) + lw k0, 0x20(sp) mtc0 k0, CP0_STATUS lw k0, 0x1c(sp) mtc0 k0, CP0_CONTEXT @@ -169,4 +194,4 @@ LEAF(au1xxx_save_and_sleep) lw $31, PT_R31(sp) jr ra addiu sp, PT_SIZE -END(au1xxx_save_and_sleep) +END(alchemy_sleep_wakeup) diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index e76941db231..a6976619160 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h @@ -188,7 +188,8 @@ extern unsigned long get_au1x00_uart_baud_base(void); extern unsigned long au1xxx_calc_clock(void); /* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */ -void au1xxx_save_and_sleep(void); +void alchemy_sleep_au1000(void); +void alchemy_sleep_au1550(void); void au_sleep(void); -- cgit v1.2.3-70-g09d2 From 121915c4ee0812a14bc8d752bc210d0238d755c1 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 8 Jun 2010 19:06:01 +0200 Subject: MIPS: BCM47xx: Add NVRAM support devices When trying to netboot a Linksys WRT54GS WLAN router, the bootup fails, because of following error message: ... [ 0.424000] b44: b44.c:v2.0 [ 0.424000] b44: Invalid MAC address found in EEPROM [ 0.432000] b44 ssb0:1: Problem fetching invariants of chip,aborting [ 0.436000] b44: probe of ssb0:1 failed with error -22 ... The router uses a CFE bootloader, but most of the needed environment variables for network card initialization, are not available from CFE via printenv and even though not via cfe_getenv(). The required environment variables are saved in a special partition in flash memory. The attached patch implement nvram_getenv and enables bootup via NFS root on my router. Most of the patch is extracted from the OpenWrt subversion repository and stripped down and cleaned up to just fix this issue. [Ralf: sorted out header file inclusions. Lots of unneded headers and such that should have been included.] Signed-off-by: Waldemar Brodkorb Reviewed-by: Phil Sutter To: linux-mips@linux-mips.org Cc: Hauke Mehrtens Patchwork: http://patchwork.linux-mips.org/patch/1359/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/Makefile | 2 +- arch/mips/bcm47xx/nvram.c | 94 ++++++++++++++++++++++++++++++ arch/mips/bcm47xx/setup.c | 39 +++++++++---- arch/mips/include/asm/mach-bcm47xx/nvram.h | 36 ++++++++++++ 4 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 arch/mips/bcm47xx/nvram.c create mode 100644 arch/mips/include/asm/mach-bcm47xx/nvram.h (limited to 'arch/mips/include/asm') diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index 35294b12d63..7465e8a72d9 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile @@ -3,4 +3,4 @@ # under Linux. # -obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o +obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c new file mode 100644 index 00000000000..06e03b222f6 --- /dev/null +++ b/arch/mips/bcm47xx/nvram.c @@ -0,0 +1,94 @@ +/* + * BCM947xx nvram variable access + * + * Copyright (C) 2005 Broadcom Corporation + * Copyright (C) 2006 Felix Fietkau + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char nvram_buf[NVRAM_SPACE]; + +/* Probe for NVRAM header */ +static void __init early_nvram_init(void) +{ + struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; + struct nvram_header *header; + int i; + u32 base, lim, off; + u32 *src, *dst; + + base = mcore->flash_window; + lim = mcore->flash_window_size; + + off = FLASH_MIN; + while (off <= lim) { + /* Windowed flash access */ + header = (struct nvram_header *) + KSEG1ADDR(base + off - NVRAM_SPACE); + if (header->magic == NVRAM_HEADER) + goto found; + off <<= 1; + } + + /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ + header = (struct nvram_header *) KSEG1ADDR(base + 4096); + if (header->magic == NVRAM_HEADER) + goto found; + + header = (struct nvram_header *) KSEG1ADDR(base + 1024); + if (header->magic == NVRAM_HEADER) + goto found; + + return; + +found: + src = (u32 *) header; + dst = (u32 *) nvram_buf; + for (i = 0; i < sizeof(struct nvram_header); i += 4) + *dst++ = *src++; + for (; i < header->len && i < NVRAM_SPACE; i += 4) + *dst++ = le32_to_cpu(*src++); +} + +int nvram_getenv(char *name, char *val, size_t val_len) +{ + char *var, *value, *end, *eq; + + if (!name) + return 1; + + if (!nvram_buf[0]) + early_nvram_init(); + + /* Look for name=value and return value */ + var = &nvram_buf[sizeof(struct nvram_header)]; + end = nvram_buf + sizeof(nvram_buf) - 2; + end[0] = end[1] = '\0'; + for (; *var; var = value + strlen(value) + 1) { + eq = strchr(var, '='); + if (!eq) + break; + value = eq + 1; + if ((eq - var) == strlen(name) && + strncmp(var, name, (eq - var)) == 0) { + snprintf(val, val_len, "%s", value); + return 0; + } + } + return 1; +} +EXPORT_SYMBOL(nvram_getenv); diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index d442e11625f..b1aee33efd1 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -1,8 +1,8 @@ /* * Copyright (C) 2004 Florian Schirmer - * Copyright (C) 2005 Waldemar Brodkorb * Copyright (C) 2006 Felix Fietkau * Copyright (C) 2006 Michael Buesch + * Copyright (C) 2010 Waldemar Brodkorb * * 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 @@ -33,6 +33,7 @@ #include #include #include +#include struct ssb_bus ssb_bcm47xx; EXPORT_SYMBOL(ssb_bcm47xx); @@ -81,28 +82,42 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, /* Fill boardinfo structure */ memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); - if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0) + if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 || + nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); - if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0) + if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 || + nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); - if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0) + if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 || + nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); /* Fill sprom structure */ memset(&(iv->sprom), 0, sizeof(struct ssb_sprom)); iv->sprom.revision = 3; - if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0) + if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 || + nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) str2eaddr(buf, iv->sprom.et0mac); - if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0) + + if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 || + nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) str2eaddr(buf, iv->sprom.et1mac); - if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) - iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10); - if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) - iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10); - if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0) + + if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 || + nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) + iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0); + + if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 || + nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) + iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0); + + if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 || + nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0) iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10); - if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0) + + if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 || + nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0) iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10); return 0; diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h new file mode 100644 index 00000000000..0d8cc146f7a --- /dev/null +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2005, Broadcom Corporation + * Copyright (C) 2006, Felix Fietkau + * + * 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. + */ + +#ifndef __NVRAM_H +#define __NVRAM_H + +#include + +struct nvram_header { + u32 magic; + u32 len; + u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ + u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ + u32 config_ncdl; /* ncdl values for memc */ +}; + +#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */ +#define NVRAM_VERSION 1 +#define NVRAM_HEADER_SIZE 20 +#define NVRAM_SPACE 0x8000 + +#define FLASH_MIN 0x00020000 /* Minimum flash size */ + +#define NVRAM_MAX_VALUE_LEN 255 +#define NVRAM_MAX_PARAM_LEN 64 + +extern int nvram_getenv(char *name, char *val, size_t val_len); + +#endif -- cgit v1.2.3-70-g09d2