Pull MIPS updates from Ralf Baechle: "This is the main pull request for 3.17. It contains: - misc Cavium Octeon, BCM47xx, BCM63xx and Alchemy updates - MIPS ptrace updates and cleanups - various fixes that will also go to -stable - a number of cleanups and small non-critical fixes. - NUMA support for the Loongson 3. - more support for MSA - support for MAAR - various FP enhancements and fixes" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits) MIPS: jz4740: remove unnecessary null test before debugfs_remove MIPS: Octeon: remove unnecessary null test before debugfs_remove_recursive MIPS: ZBOOT: implement stack protector in compressed boot phase MIPS: mipsreg: remove duplicate MIPS_CONF4_FTLBSETS_SHIFT MIPS: Bonito64: remove a duplicate define MIPS: Malta: initialise MAARs MIPS: Initialise MAARs MIPS: detect presence of MAARs MIPS: define MAAR register accessors & bits MIPS: mark MSA experimental MIPS: Don't build MSA support unless it can be used MIPS: consistently clear MSA flags when starting & copying threads MIPS: 16 byte align MSA vector context MIPS: disable preemption whilst initialising MSA MIPS: ensure MSA gets disabled during boot MIPS: fix read_msa_* & write_msa_* functions on non-MSA toolchains MIPS: fix MSA context for tasks which don't use FP first MIPS: init upper 64b of vector registers when MSA is first used MIPS: save/disable MSA in lose_fpu MIPS: preserve scalar FP CSR when switching vector context ...
Unified · Split
| @@ -571,6 +571,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. · 570 unmodified lines | ||
| 571 | 571 | trust validation. |
| 572 | 572 | format: { id:<keyid> | builtin } |
| 573 | 573 | |
| 574 | + cca= [MIPS] Override the kernel pages' cache coherency | |
| 575 | + algorithm. Accepted values range from 0 to 7 | |
| 576 | + inclusive. See arch/mips/include/asm/pgtable-bits.h | |
| 577 | + for platform specific values (SB1, Loongson3 and | |
| 578 | + others). | |
| 579 | + | |
| 574 | 580 | ccw_timeout_log [S390] |
| 575 | 581 | See Documentation/s390/CommonIO for details. |
| 576 | 582 | |
| @@ -71,6 +71,7 @@ config MIPS_ALCHEMY · 70 unmodified lines | ||
| 71 | 71 | select SYS_SUPPORTS_APM_EMULATION |
| 72 | 72 | select ARCH_REQUIRE_GPIOLIB |
| 73 | 73 | select SYS_SUPPORTS_ZBOOT |
| 74 | + select COMMON_CLK | |
| 74 | 75 | |
| 75 | 76 | config AR7 |
| 76 | 77 | bool "Texas Instruments AR7" |
| @@ -129,6 +130,8 @@ config BCM47XX · 52 unmodified lines | ||
| 129 | 130 | select SYS_SUPPORTS_MIPS16 |
| 130 | 131 | select SYS_HAS_EARLY_PRINTK |
| 131 | 132 | select USE_GENERIC_EARLY_PRINTK_8250 |
| 133 | + select GPIOLIB | |
| 134 | + select LEDS_GPIO_REGISTER | |
| 132 | 135 | help |
| 133 | 136 | Support for BCM47XX based boards |
| 134 | 137 | |
| @@ -137,6 +140,7 @@ config BCM63XX · 2 unmodified lines | ||
| 137 | 140 | select BOOT_RAW |
| 138 | 141 | select CEVT_R4K |
| 139 | 142 | select CSRC_R4K |
| 143 | + select SYNC_R4K | |
| 140 | 144 | select DMA_NONCOHERENT |
| 141 | 145 | select IRQ_CPU |
| 142 | 146 | select SYS_SUPPORTS_32BIT_KERNEL |
| @@ -2056,6 +2060,7 @@ config MIPS_CPS · 1913 unmodified lines | ||
| 2056 | 2060 | support is unavailable. |
| 2057 | 2061 | |
| 2058 | 2062 | config MIPS_CPS_PM |
| 2063 | + select MIPS_CPC | |
| 2059 | 2064 | bool |
| 2060 | 2065 | |
| 2061 | 2066 | config MIPS_GIC_IPI |
| @@ -2109,9 +2114,9 @@ config CPU_MICROMIPS · 47 unmodified lines | ||
| 2109 | 2114 | microMIPS ISA |
| 2110 | 2115 | |
| 2111 | 2116 | config CPU_HAS_MSA |
| 2112 | − bool "Support for the MIPS SIMD Architecture" | |
| 2117 | + bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)" | |
| 2113 | 2118 | depends on CPU_SUPPORTS_MSA |
| 2114 | − default y | |
| 2119 | + depends on 64BIT || MIPS_O32_FP64_SUPPORT | |
| 2115 | 2120 | help |
| 2116 | 2121 | MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers |
| 2117 | 2122 | and a set of SIMD instructions to operate on them. When this option |
| @@ -151,8 +151,10 @@ cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ · 150 unmodified lines | ||
| 151 | 151 | -Wa,--trap |
| 152 | 152 | cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ |
| 153 | 153 | -Wa,--trap |
| 154 | −cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1 -mno-mdmx -mno-mips3d,-march=r5000) \ | |
| 154 | +cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \ | |
| 155 | 155 | -Wa,--trap |
| 156 | +cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx) | |
| 157 | +cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d) | |
| 156 | 158 | cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap |
| 157 | 159 | cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \ |
| 158 | 160 | -Wa,--trap |
| @@ -85,10 +85,10 @@ void __init board_setup(void) · 84 unmodified lines | ||
| 85 | 85 | #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */ |
| 86 | 86 | |
| 87 | 87 | /* Initialize sys_pinfunc */ |
| 88 | − au_writel(SYS_PF_NI2, SYS_PINFUNC); | |
| 88 | + alchemy_wrsys(SYS_PF_NI2, AU1000_SYS_PINFUNC); | |
| 89 | 89 | |
| 90 | 90 | /* Initialize GPIO */ |
| 91 | − au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR); | |
| 91 | + alchemy_wrsys(~0, AU1000_SYS_TRIOUTCLR); | |
| 92 | 92 | alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */ |
| 93 | 93 | alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */ |
| 94 | 94 | alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */ |
| @@ -87,9 +87,9 @@ void __init board_setup(void) · 86 unmodified lines | ||
| 87 | 87 | alchemy_gpio2_enable(); |
| 88 | 88 | |
| 89 | 89 | /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */ |
| 90 | − pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3; | |
| 90 | + pin_func = alchemy_rdsys(AU1000_SYS_PINFUNC) & ~SYS_PF_UR3; | |
| 91 | 91 | pin_func |= SYS_PF_UR3; |
| 92 | − au_writel(pin_func, SYS_PINFUNC); | |
| 92 | + alchemy_wrsys(pin_func, AU1000_SYS_PINFUNC); | |
| 93 | 93 | |
| 94 | 94 | /* Enable UART */ |
| 95 | 95 | alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); |
| @@ -5,8 +5,8 @@ · 4 unmodified lines | ||
| 5 | 5 | # Makefile for the Alchemy Au1xx0 CPUs, generic files. |
| 6 | 6 | # |
| 7 | 7 | |
| 8 | −obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ | |
| 9 | − sleeper.o dma.o dbdma.o vss.o irq.o usb.o | |
| 8 | +obj-y += prom.o time.o clock.o platform.o power.o \ | |
| 9 | + setup.o sleeper.o dma.o dbdma.o vss.o irq.o usb.o | |
| 10 | 10 | |
| 11 | 11 | # optional gpiolib support |
| 12 | 12 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) |
| @@ -0,0 +1,1094 @@ | ||
| 1 | +/* | |
| 2 | + * Alchemy clocks. | |
| 3 | + * | |
| 4 | + * Exposes all configurable internal clock sources to the clk framework. | |
| 5 | + * | |
| 6 | + * We have: | |
| 7 | + * - Root source, usually 12MHz supplied by an external crystal | |
| 8 | + * - 3 PLLs which generate multiples of root rate [AUX, CPU, AUX2] | |
| 9 | + * | |
| 10 | + * Dividers: | |
| 11 | + * - 6 clock dividers with: | |
| 12 | + * * selectable source [one of the PLLs], | |
| 13 | + * * output divided between [2 .. 512 in steps of 2] (!Au1300) | |
| 14 | + * or [1 .. 256 in steps of 1] (Au1300), | |
| 15 | + * * can be enabled individually. | |
| 16 | + * | |
| 17 | + * - up to 6 "internal" (fixed) consumers which: | |
| 18 | + * * take either AUXPLL or one of the above 6 dividers as input, | |
| 19 | + * * divide this input by 1, 2, or 4 (and 3 on Au1300). | |
| 20 | + * * can be disabled separately. | |
| 21 | + * | |
| 22 | + * Misc clocks: | |
| 23 | + * - sysbus clock: CPU core clock (CPUPLL) divided by 2, 3 or 4. | |
| 24 | + * depends on board design and should be set by bootloader, read-only. | |
| 25 | + * - peripheral clock: half the rate of sysbus clock, source for a lot | |
| 26 | + * of peripheral blocks, read-only. | |
| 27 | + * - memory clock: clk rate to main memory chips, depends on board | |
| 28 | + * design and is read-only, | |
| 29 | + * - lrclk: the static bus clock signal for synchronous operation. | |
| 30 | + * depends on board design, must be set by bootloader, | |
| 31 | + * but may be required to correctly configure devices attached to | |
| 32 | + * the static bus. The Au1000/1500/1100 manuals call it LCLK, on | |
| 33 | + * later models it's called RCLK. | |
| 34 | + */ | |
| 35 | + | |
| 36 | +#include <linux/init.h> | |
| 37 | +#include <linux/io.h> | |
| 38 | +#include <linux/clk-provider.h> | |
| 39 | +#include <linux/clkdev.h> | |
| 40 | +#include <linux/clk-private.h> | |
| 41 | +#include <linux/slab.h> | |
| 42 | +#include <linux/spinlock.h> | |
| 43 | +#include <linux/types.h> | |
| 44 | +#include <asm/mach-au1x00/au1000.h> | |
| 45 | + | |
| 46 | +/* Base clock: 12MHz is the default in all databooks, and I haven't | |
| 47 | + * found any board yet which uses a different rate. | |
| 48 | + */ | |
| 49 | +#define ALCHEMY_ROOTCLK_RATE 12000000 | |
| 50 | + | |
| 51 | +/* | |
| 52 | + * the internal sources which can be driven by the PLLs and dividers. | |
| 53 | + * Names taken from the databooks, refer to them for more information, | |
| 54 | + * especially which ones are share a clock line. | |
| 55 | + */ | |
| 56 | +static const char * const alchemy_au1300_intclknames[] = { | |
| 57 | + "lcd_intclk", "gpemgp_clk", "maempe_clk", "maebsa_clk", | |
| 58 | + "EXTCLK0", "EXTCLK1" | |
| 59 | +}; | |
| 60 | + | |
| 61 | +static const char * const alchemy_au1200_intclknames[] = { | |
| 62 | + "lcd_intclk", NULL, NULL, NULL, "EXTCLK0", "EXTCLK1" | |
| 63 | +}; | |
| 64 | + | |
| 65 | +static const char * const alchemy_au1550_intclknames[] = { | |
| 66 | + "usb_clk", "psc0_intclk", "psc1_intclk", "pci_clko", | |
| 67 | + "EXTCLK0", "EXTCLK1" | |
| 68 | +}; | |
| 69 | + | |
| 70 | +static const char * const alchemy_au1100_intclknames[] = { | |
| 71 | + "usb_clk", "lcd_intclk", NULL, "i2s_clk", "EXTCLK0", "EXTCLK1" | |
| 72 | +}; | |
| 73 | + | |
| 74 | +static const char * const alchemy_au1500_intclknames[] = { | |
| 75 | + NULL, "usbd_clk", "usbh_clk", "pci_clko", "EXTCLK0", "EXTCLK1" | |
| 76 | +}; | |
| 77 | + | |
| 78 | +static const char * const alchemy_au1000_intclknames[] = { | |
| 79 | + "irda_clk", "usbd_clk", "usbh_clk", "i2s_clk", "EXTCLK0", | |
| 80 | + "EXTCLK1" | |
| 81 | +}; | |
| 82 | + | |
| 83 | +/* aliases for a few on-chip sources which are either shared | |
| 84 | + * or have gone through name changes. | |
| 85 | + */ | |
| 86 | +static struct clk_aliastable { | |
| 87 | + char *alias; | |
| 88 | + char *base; | |
| 89 | + int cputype; | |
| 90 | +} alchemy_clk_aliases[] __initdata = { | |
| 91 | + { "usbh_clk", "usb_clk", ALCHEMY_CPU_AU1100 }, | |
| 92 | + { "usbd_clk", "usb_clk", ALCHEMY_CPU_AU1100 }, | |
| 93 | + { "irda_clk", "usb_clk", ALCHEMY_CPU_AU1100 }, | |
| 94 | + { "usbh_clk", "usb_clk", ALCHEMY_CPU_AU1550 }, | |
| 95 | + { "usbd_clk", "usb_clk", ALCHEMY_CPU_AU1550 }, | |
| 96 | + { "psc2_intclk", "usb_clk", ALCHEMY_CPU_AU1550 }, | |
| 97 | + { "psc3_intclk", "EXTCLK0", ALCHEMY_CPU_AU1550 }, | |
| 98 | + { "psc0_intclk", "EXTCLK0", ALCHEMY_CPU_AU1200 }, | |
| 99 | + { "psc1_intclk", "EXTCLK1", ALCHEMY_CPU_AU1200 }, | |
| 100 | + { "psc0_intclk", "EXTCLK0", ALCHEMY_CPU_AU1300 }, | |
| 101 | + { "psc2_intclk", "EXTCLK0", ALCHEMY_CPU_AU1300 }, | |
| 102 | + { "psc1_intclk", "EXTCLK1", ALCHEMY_CPU_AU1300 }, | |
| 103 | + { "psc3_intclk", "EXTCLK1", ALCHEMY_CPU_AU1300 }, | |
| 104 | + | |
| 105 | + { NULL, NULL, 0 }, | |
| 106 | +}; | |
| 107 | + | |
| 108 | +#define IOMEM(x) ((void __iomem *)(KSEG1ADDR(CPHYSADDR(x)))) | |
| 109 | + | |
| 110 | +/* access locks to SYS_FREQCTRL0/1 and SYS_CLKSRC registers */ | |
| 111 | +static spinlock_t alchemy_clk_fg0_lock; | |
| 112 | +static spinlock_t alchemy_clk_fg1_lock; | |
| 113 | +static spinlock_t alchemy_clk_csrc_lock; | |
| 114 | + | |
| 115 | +/* CPU Core clock *****************************************************/ | |
| 116 | + | |
| 117 | +static unsigned long alchemy_clk_cpu_recalc(struct clk_hw *hw, | |
| 118 | + unsigned long parent_rate) | |
| 119 | +{ | |
| 120 | + unsigned long t; | |
| 121 | + | |
| 122 | + /* | |
| 123 | + * On early Au1000, sys_cpupll was write-only. Since these | |
| 124 | + * silicon versions of Au1000 are not sold, we don't bend | |
| 125 | + * over backwards trying to determine the frequency. | |
| 126 | + */ | |
| 127 | + if (unlikely(au1xxx_cpu_has_pll_wo())) | |
| 128 | + t = 396000000; | |
| 129 | + else { | |
| 130 | + t = alchemy_rdsys(AU1000_SYS_CPUPLL) & 0x7f; | |
| 131 | + t *= parent_rate; | |
| 132 | + } | |
| 133 | + | |
| 134 | + return t; | |
| 135 | +} | |
| 136 | + | |
| 137 | +static struct clk_ops alchemy_clkops_cpu = { | |
| 138 | + .recalc_rate = alchemy_clk_cpu_recalc, | |
| 139 | +}; | |
| 140 | + | |
| 141 | +static struct clk __init *alchemy_clk_setup_cpu(const char *parent_name, | |
| 142 | + int ctype) | |
| 143 | +{ | |
| 144 | + struct clk_init_data id; | |
| 145 | + struct clk_hw *h; | |
| 146 | + | |
| 147 | + h = kzalloc(sizeof(*h), GFP_KERNEL); | |
| 148 | + if (!h) | |
| 149 | + return ERR_PTR(-ENOMEM); | |
| 150 | + | |
| 151 | + id.name = ALCHEMY_CPU_CLK; | |
| 152 | + id.parent_names = &parent_name; | |
| 153 | + id.num_parents = 1; | |
| 154 | + id.flags = CLK_IS_BASIC; | |
| 155 | + id.ops = &alchemy_clkops_cpu; | |
| 156 | + h->init = &id; | |
| 157 | + | |
| 158 | + return clk_register(NULL, h); | |
| 159 | +} | |
| 160 | + | |
| 161 | +/* AUXPLLs ************************************************************/ | |
| 162 | + | |
| 163 | +struct alchemy_auxpll_clk { | |
| 164 | + struct clk_hw hw; | |
| 165 | + unsigned long reg; /* au1300 has also AUXPLL2 */ | |
| 166 | + int maxmult; /* max multiplier */ | |
| 167 | +}; | |
| 168 | +#define to_auxpll_clk(x) container_of(x, struct alchemy_auxpll_clk, hw) | |
| 169 | + | |
| 170 | +static unsigned long alchemy_clk_aux_recalc(struct clk_hw *hw, | |
| 171 | + unsigned long parent_rate) | |
| 172 | +{ | |
| 173 | + struct alchemy_auxpll_clk *a = to_auxpll_clk(hw); | |
| 174 | + | |
| 175 | + return (alchemy_rdsys(a->reg) & 0xff) * parent_rate; | |
| 176 | +} | |
| 177 | + | |
| 178 | +static int alchemy_clk_aux_setr(struct clk_hw *hw, | |
| 179 | + unsigned long rate, | |
| 180 | + unsigned long parent_rate) | |
| 181 | +{ | |
| 182 | + struct alchemy_auxpll_clk *a = to_auxpll_clk(hw); | |
| 183 | + unsigned long d = rate; | |
| 184 | + | |
| 185 | + if (rate) | |
| 186 | + d /= parent_rate; | |
| 187 | + else | |
| 188 | + d = 0; | |
| 189 | + | |
| 190 | + /* minimum is 84MHz, max is 756-1032 depending on variant */ | |
| 191 | + if (((d < 7) && (d != 0)) || (d > a->maxmult)) | |
| 192 | + return -EINVAL; | |
| 193 | + | |
| 194 | + alchemy_wrsys(d, a->reg); | |
| 195 | + return 0; | |
| 196 | +} | |
| 197 | + | |
| 198 | +static long alchemy_clk_aux_roundr(struct clk_hw *hw, | |
| 199 | + unsigned long rate, | |
| 200 | + unsigned long *parent_rate) | |
| 201 | +{ | |
| 202 | + struct alchemy_auxpll_clk *a = to_auxpll_clk(hw); | |
| 203 | + unsigned long mult; | |
| 204 | + | |
| 205 | + if (!rate || !*parent_rate) | |
| 206 | + return 0; | |
| 207 | + | |
| 208 | + mult = rate / (*parent_rate); | |
| 209 | + | |
| 210 | + if (mult && (mult < 7)) | |
| 211 | + mult = 7; | |
| 212 | + if (mult > a->maxmult) | |
| 213 | + mult = a->maxmult; | |
| 214 | + | |
| 215 | + return (*parent_rate) * mult; | |
| 216 | +} | |
| 217 | + | |
| 218 | +static struct clk_ops alchemy_clkops_aux = { | |
| 219 | + .recalc_rate = alchemy_clk_aux_recalc, | |
| 220 | + .set_rate = alchemy_clk_aux_setr, | |
| 221 | + .round_rate = alchemy_clk_aux_roundr, | |
| 222 | +}; | |
| 223 | + | |
| 224 | +static struct clk __init *alchemy_clk_setup_aux(const char *parent_name, | |
| 225 | + char *name, int maxmult, | |
| 226 | + unsigned long reg) | |
| 227 | +{ | |
| 228 | + struct clk_init_data id; | |
| 229 | + struct clk *c; | |
| 230 | + struct alchemy_auxpll_clk *a; | |
| 231 | + | |
| 232 | + a = kzalloc(sizeof(*a), GFP_KERNEL); | |
| 233 | + if (!a) | |
| 234 | + return ERR_PTR(-ENOMEM); | |
| 235 | + | |
| 236 | + id.name = name; | |
| 237 | + id.parent_names = &parent_name; | |
| 238 | + id.num_parents = 1; | |
| 239 | + id.flags = CLK_GET_RATE_NOCACHE; | |
| 240 | + id.ops = &alchemy_clkops_aux; | |
| 241 | + | |
| 242 | + a->reg = reg; | |
| 243 | + a->maxmult = maxmult; | |
| 244 | + a->hw.init = &id; | |
| 245 | + | |
| 246 | + c = clk_register(NULL, &a->hw); | |
| 247 | + if (!IS_ERR(c)) | |
| 248 | + clk_register_clkdev(c, name, NULL); | |
| 249 | + else | |
| 250 | + kfree(a); | |
| 251 | + | |
| 252 | + return c; | |
| 253 | +} | |
| 254 | + | |
| 255 | +/* sysbus_clk *********************************************************/ | |
| 256 | + | |
| 257 | +static struct clk __init *alchemy_clk_setup_sysbus(const char *pn) | |
| 258 | +{ | |
| 259 | + unsigned long v = (alchemy_rdsys(AU1000_SYS_POWERCTRL) & 3) + 2; | |
| 260 | + struct clk *c; | |
| 261 | + | |
| 262 | + c = clk_register_fixed_factor(NULL, ALCHEMY_SYSBUS_CLK, | |
| 263 | + pn, 0, 1, v); | |
| 264 | + if (!IS_ERR(c)) | |
| 265 | + clk_register_clkdev(c, ALCHEMY_SYSBUS_CLK, NULL); | |
| 266 | + return c; | |
| 267 | +} | |
| 268 | + | |
| 269 | +/* Peripheral Clock ***************************************************/ | |
| 270 | + | |
| 271 | +static struct clk __init *alchemy_clk_setup_periph(const char *pn) | |
| 272 | +{ | |
| 273 | + /* Peripheral clock runs at half the rate of sysbus clk */ | |
| 274 | + struct clk *c; | |
| 275 | + | |
| 276 | + c = clk_register_fixed_factor(NULL, ALCHEMY_PERIPH_CLK, | |
| 277 | + pn, 0, 1, 2); | |
| 278 | + if (!IS_ERR(c)) | |
| 279 | + clk_register_clkdev(c, ALCHEMY_PERIPH_CLK, NULL); | |
| 280 | + return c; | |
| 281 | +} | |
| 282 | + | |
| 283 | +/* mem clock **********************************************************/ | |
| 284 | + | |
| 285 | +static struct clk __init *alchemy_clk_setup_mem(const char *pn, int ct) | |
| 286 | +{ | |
| 287 | + void __iomem *addr = IOMEM(AU1000_MEM_PHYS_ADDR); | |
| 288 | + unsigned long v; | |
| 289 | + struct clk *c; | |
| 290 | + int div; | |
| 291 | + | |
| 292 | + switch (ct) { | |
| 293 | + case ALCHEMY_CPU_AU1550: | |
| 294 | + case ALCHEMY_CPU_AU1200: | |
| 295 | + v = __raw_readl(addr + AU1550_MEM_SDCONFIGB); | |
| 296 | + div = (v & (1 << 15)) ? 1 : 2; | |
| 297 | + break; | |
| 298 | + case ALCHEMY_CPU_AU1300: | |
| 299 | + v = __raw_readl(addr + AU1550_MEM_SDCONFIGB); | |
| 300 | + div = (v & (1 << 31)) ? 1 : 2; | |
| 301 | + break; | |
| 302 | + case ALCHEMY_CPU_AU1000: | |
| 303 | + case ALCHEMY_CPU_AU1500: | |
| 304 | + case ALCHEMY_CPU_AU1100: | |
| 305 | + default: | |
| 306 | + div = 2; | |
| 307 | + break; | |
| 308 | + } | |
| 309 | + | |
| 310 | + c = clk_register_fixed_factor(NULL, ALCHEMY_MEM_CLK, pn, | |
| 311 | + 0, 1, div); | |
| 312 | + if (!IS_ERR(c)) | |
| 313 | + clk_register_clkdev(c, ALCHEMY_MEM_CLK, NULL); | |
| 314 | + return c; | |
| 315 | +} | |
| 316 | + | |
| 317 | +/* lrclk: external synchronous static bus clock ***********************/ | |
| 318 | + | |
| 319 | +static struct clk __init *alchemy_clk_setup_lrclk(const char *pn) | |
| 320 | +{ | |
| 321 | + /* MEM_STCFG0[15:13] = divisor. | |
| 322 | + * L/RCLK = periph_clk / (divisor + 1) | |
| 323 | + * On Au1000, Au1500, Au1100 it's called LCLK, | |
| 324 | + * on later models it's called RCLK, but it's the same thing. | |
| 325 | + */ | |
| 326 | + struct clk *c; | |
| 327 | + unsigned long v = alchemy_rdsmem(AU1000_MEM_STCFG0) >> 13; | |
| 328 | + | |
| 329 | + v = (v & 7) + 1; | |
| 330 | + c = clk_register_fixed_factor(NULL, ALCHEMY_LR_CLK, | |
| 331 | + pn, 0, 1, v); | |
| 332 | + if (!IS_ERR(c)) | |
| 333 | + clk_register_clkdev(c, ALCHEMY_LR_CLK, NULL); | |
| 334 | + return c; | |
| 335 | +} | |
| 336 | + | |
| 337 | +/* Clock dividers and muxes *******************************************/ | |
| 338 | + | |
| 339 | +/* data for fgen and csrc mux-dividers */ | |
| 340 | +struct alchemy_fgcs_clk { | |
| 341 | + struct clk_hw hw; | |
| 342 | + spinlock_t *reglock; /* register lock */ | |
| 343 | + unsigned long reg; /* SYS_FREQCTRL0/1 */ | |
| 344 | + int shift; /* offset in register */ | |
| 345 | + int parent; /* parent before disable [Au1300] */ | |
| 346 | + int isen; /* is it enabled? */ | |
| 347 | + int *dt; /* dividertable for csrc */ | |
| 348 | +}; | |
| 349 | +#define to_fgcs_clk(x) container_of(x, struct alchemy_fgcs_clk, hw) | |
| 350 | + | |
| 351 | +static long alchemy_calc_div(unsigned long rate, unsigned long prate, | |
| 352 | + int scale, int maxdiv, unsigned long *rv) | |
| 353 | +{ | |
| 354 | + long div1, div2; | |
| 355 | + | |
| 356 | + div1 = prate / rate; | |
| 357 | + if ((prate / div1) > rate) | |
| 358 | + div1++; | |
| 359 | + | |
| 360 | + if (scale == 2) { /* only div-by-multiple-of-2 possible */ | |
| 361 | + if (div1 & 1) | |
| 362 | + div1++; /* stay <=prate */ | |
| 363 | + } | |
| 364 | + | |
| 365 | + div2 = (div1 / scale) - 1; /* value to write to register */ | |
| 366 | + | |
| 367 | + if (div2 > maxdiv) | |
| 368 | + div2 = maxdiv; | |
| 369 | + if (rv) | |
| 370 | + *rv = div2; | |
| 371 | + | |
| 372 | + div1 = ((div2 + 1) * scale); | |
| 373 | + return div1; | |
| 374 | +} | |
| 375 | + | |
| 376 | +static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate, | |
| 377 | + unsigned long *best_parent_rate, | |
| 378 | + struct clk **best_parent_clk, | |
| 379 | + int scale, int maxdiv) | |
| 380 | +{ | |
| 381 | + struct clk *pc, *bpc, *free; | |
| 382 | + long tdv, tpr, pr, nr, br, bpr, diff, lastdiff; | |
| 383 | + int j; | |
| 384 | + | |
| 385 | + lastdiff = INT_MAX; | |
| 386 | + bpr = 0; | |
| 387 | + bpc = NULL; | |
| 388 | + br = -EINVAL; | |
| 389 | + free = NULL; | |
| 390 | + | |
| 391 | + /* look at the rates each enabled parent supplies and select | |
| 392 | + * the one that gets closest to but not over the requested rate. | |
| 393 | + */ | |
| 394 | + for (j = 0; j < 7; j++) { | |
| 395 | + pc = clk_get_parent_by_index(hw->clk, j); | |
| 396 | + if (!pc) | |
| 397 | + break; | |
| 398 | + | |
| 399 | + /* if this parent is currently unused, remember it. | |
| 400 | + * XXX: I know it's a layering violation, but it works | |
| 401 | + * so well.. (if (!clk_has_active_children(pc)) ) | |
| 402 | + */ | |
| 403 | + if (pc->prepare_count == 0) { | |
| 404 | + if (!free) | |
| 405 | + free = pc; | |
| 406 | + } | |
| 407 | + | |
| 408 | + pr = clk_get_rate(pc); | |
| 409 | + if (pr < rate) | |
| 410 | + continue; | |
| 411 | + | |
| 412 | + /* what can hardware actually provide */ | |
| 413 | + tdv = alchemy_calc_div(rate, pr, scale, maxdiv, NULL); | |
| 414 | + nr = pr / tdv; | |
| 415 | + diff = rate - nr; | |
| 416 | + if (nr > rate) | |
| 417 | + continue; | |
| 418 | + | |
| 419 | + if (diff < lastdiff) { | |
| 420 | + lastdiff = diff; | |
| 421 | + bpr = pr; | |
| 422 | + bpc = pc; | |
| 423 | + br = nr; | |
| 424 | + } | |
| 425 | + if (diff == 0) | |
| 426 | + break; | |
| 427 | + } | |
| 428 | + | |
| 429 | + /* if we couldn't get the exact rate we wanted from the enabled | |
| 430 | + * parents, maybe we can tell an available disabled/inactive one | |
| 431 | + * to give us a rate we can divide down to the requested rate. | |
| 432 | + */ | |
| 433 | + if (lastdiff && free) { | |
| 434 | + for (j = (maxdiv == 4) ? 1 : scale; j <= maxdiv; j += scale) { | |
| 435 | + tpr = rate * j; | |
| 436 | + if (tpr < 0) | |
| 437 | + break; | |
| 438 | + pr = clk_round_rate(free, tpr); | |
| 439 | + | |
| 440 | + tdv = alchemy_calc_div(rate, pr, scale, maxdiv, NULL); | |
| 441 | + nr = pr / tdv; | |
| 442 | + diff = rate - nr; | |
| 443 | + if (nr > rate) | |
| 444 | + continue; | |
| 445 | + if (diff < lastdiff) { | |
| 446 | + lastdiff = diff; | |
| 447 | + bpr = pr; | |
| 448 | + bpc = free; | |
| 449 | + br = nr; | |
| 450 | + } | |
| 451 | + if (diff == 0) | |
| 452 | + break; | |
| 453 | + } | |
| 454 | + } | |
| 455 | + | |
| 456 | + *best_parent_rate = bpr; | |
| 457 | + *best_parent_clk = bpc; | |
| 458 | + return br; | |
| 459 | +} | |
| 460 | + | |
| 461 | +static int alchemy_clk_fgv1_en(struct clk_hw *hw) | |
| 462 | +{ | |
| 463 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 464 | + unsigned long v, flags; | |
| 465 | + | |
| 466 | + spin_lock_irqsave(c->reglock, flags); | |
| 467 | + v = alchemy_rdsys(c->reg); | |
| 468 | + v |= (1 << 1) << c->shift; | |
| 469 | + alchemy_wrsys(v, c->reg); | |
| 470 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 471 | + | |
| 472 | + return 0; | |
| 473 | +} | |
| 474 | + | |
| 475 | +static int alchemy_clk_fgv1_isen(struct clk_hw *hw) | |
| 476 | +{ | |
| 477 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 478 | + unsigned long v = alchemy_rdsys(c->reg) >> (c->shift + 1); | |
| 479 | + | |
| 480 | + return v & 1; | |
| 481 | +} | |
| 482 | + | |
| 483 | +static void alchemy_clk_fgv1_dis(struct clk_hw *hw) | |
| 484 | +{ | |
| 485 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 486 | + unsigned long v, flags; | |
| 487 | + | |
| 488 | + spin_lock_irqsave(c->reglock, flags); | |
| 489 | + v = alchemy_rdsys(c->reg); | |
| 490 | + v &= ~((1 << 1) << c->shift); | |
| 491 | + alchemy_wrsys(v, c->reg); | |
| 492 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 493 | +} | |
| 494 | + | |
| 495 | +static int alchemy_clk_fgv1_setp(struct clk_hw *hw, u8 index) | |
| 496 | +{ | |
| 497 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 498 | + unsigned long v, flags; | |
| 499 | + | |
| 500 | + spin_lock_irqsave(c->reglock, flags); | |
| 501 | + v = alchemy_rdsys(c->reg); | |
| 502 | + if (index) | |
| 503 | + v |= (1 << c->shift); | |
| 504 | + else | |
| 505 | + v &= ~(1 << c->shift); | |
| 506 | + alchemy_wrsys(v, c->reg); | |
| 507 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 508 | + | |
| 509 | + return 0; | |
| 510 | +} | |
| 511 | + | |
| 512 | +static u8 alchemy_clk_fgv1_getp(struct clk_hw *hw) | |
| 513 | +{ | |
| 514 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 515 | + | |
| 516 | + return (alchemy_rdsys(c->reg) >> c->shift) & 1; | |
| 517 | +} | |
| 518 | + | |
| 519 | +static int alchemy_clk_fgv1_setr(struct clk_hw *hw, unsigned long rate, | |
| 520 | + unsigned long parent_rate) | |
| 521 | +{ | |
| 522 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 523 | + unsigned long div, v, flags, ret; | |
| 524 | + int sh = c->shift + 2; | |
| 525 | + | |
| 526 | + if (!rate || !parent_rate || rate > (parent_rate / 2)) | |
| 527 | + return -EINVAL; | |
| 528 | + ret = alchemy_calc_div(rate, parent_rate, 2, 512, &div); | |
| 529 | + spin_lock_irqsave(c->reglock, flags); | |
| 530 | + v = alchemy_rdsys(c->reg); | |
| 531 | + v &= ~(0xff << sh); | |
| 532 | + v |= div << sh; | |
| 533 | + alchemy_wrsys(v, c->reg); | |
| 534 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 535 | + | |
| 536 | + return 0; | |
| 537 | +} | |
| 538 | + | |
| 539 | +static unsigned long alchemy_clk_fgv1_recalc(struct clk_hw *hw, | |
| 540 | + unsigned long parent_rate) | |
| 541 | +{ | |
| 542 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 543 | + unsigned long v = alchemy_rdsys(c->reg) >> (c->shift + 2); | |
| 544 | + | |
| 545 | + v = ((v & 0xff) + 1) * 2; | |
| 546 | + return parent_rate / v; | |
| 547 | +} | |
| 548 | + | |
| 549 | +static long alchemy_clk_fgv1_detr(struct clk_hw *hw, unsigned long rate, | |
| 550 | + unsigned long *best_parent_rate, | |
| 551 | + struct clk **best_parent_clk) | |
| 552 | +{ | |
| 553 | + return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate, | |
| 554 | + best_parent_clk, 2, 512); | |
| 555 | +} | |
| 556 | + | |
| 557 | +/* Au1000, Au1100, Au15x0, Au12x0 */ | |
| 558 | +static struct clk_ops alchemy_clkops_fgenv1 = { | |
| 559 | + .recalc_rate = alchemy_clk_fgv1_recalc, | |
| 560 | + .determine_rate = alchemy_clk_fgv1_detr, | |
| 561 | + .set_rate = alchemy_clk_fgv1_setr, | |
| 562 | + .set_parent = alchemy_clk_fgv1_setp, | |
| 563 | + .get_parent = alchemy_clk_fgv1_getp, | |
| 564 | + .enable = alchemy_clk_fgv1_en, | |
| 565 | + .disable = alchemy_clk_fgv1_dis, | |
| 566 | + .is_enabled = alchemy_clk_fgv1_isen, | |
| 567 | +}; | |
| 568 | + | |
| 569 | +static void __alchemy_clk_fgv2_en(struct alchemy_fgcs_clk *c) | |
| 570 | +{ | |
| 571 | + unsigned long v = alchemy_rdsys(c->reg); | |
| 572 | + | |
| 573 | + v &= ~(3 << c->shift); | |
| 574 | + v |= (c->parent & 3) << c->shift; | |
| 575 | + alchemy_wrsys(v, c->reg); | |
| 576 | + c->isen = 1; | |
| 577 | +} | |
| 578 | + | |
| 579 | +static int alchemy_clk_fgv2_en(struct clk_hw *hw) | |
| 580 | +{ | |
| 581 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 582 | + unsigned long flags; | |
| 583 | + | |
| 584 | + /* enable by setting the previous parent clock */ | |
| 585 | + spin_lock_irqsave(c->reglock, flags); | |
| 586 | + __alchemy_clk_fgv2_en(c); | |
| 587 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 588 | + | |
| 589 | + return 0; | |
| 590 | +} | |
| 591 | + | |
| 592 | +static int alchemy_clk_fgv2_isen(struct clk_hw *hw) | |
| 593 | +{ | |
| 594 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 595 | + | |
| 596 | + return ((alchemy_rdsys(c->reg) >> c->shift) & 3) != 0; | |
| 597 | +} | |
| 598 | + | |
| 599 | +static void alchemy_clk_fgv2_dis(struct clk_hw *hw) | |
| 600 | +{ | |
| 601 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 602 | + unsigned long v, flags; | |
| 603 | + | |
| 604 | + spin_lock_irqsave(c->reglock, flags); | |
| 605 | + v = alchemy_rdsys(c->reg); | |
| 606 | + v &= ~(3 << c->shift); /* set input mux to "disabled" state */ | |
| 607 | + alchemy_wrsys(v, c->reg); | |
| 608 | + c->isen = 0; | |
| 609 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 610 | +} | |
| 611 | + | |
| 612 | +static int alchemy_clk_fgv2_setp(struct clk_hw *hw, u8 index) | |
| 613 | +{ | |
| 614 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 615 | + unsigned long flags; | |
| 616 | + | |
| 617 | + spin_lock_irqsave(c->reglock, flags); | |
| 618 | + c->parent = index + 1; /* value to write to register */ | |
| 619 | + if (c->isen) | |
| 620 | + __alchemy_clk_fgv2_en(c); | |
| 621 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 622 | + | |
| 623 | + return 0; | |
| 624 | +} | |
| 625 | + | |
| 626 | +static u8 alchemy_clk_fgv2_getp(struct clk_hw *hw) | |
| 627 | +{ | |
| 628 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 629 | + unsigned long flags, v; | |
| 630 | + | |
| 631 | + spin_lock_irqsave(c->reglock, flags); | |
| 632 | + v = c->parent - 1; | |
| 633 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 634 | + return v; | |
| 635 | +} | |
| 636 | + | |
| 637 | +/* fg0-2 and fg4-6 share a "scale"-bit. With this bit cleared, the | |
| 638 | + * dividers behave exactly as on previous models (dividers are multiples | |
| 639 | + * of 2); with the bit set, dividers are multiples of 1, halving their | |
| 640 | + * range, but making them also much more flexible. | |
| 641 | + */ | |
| 642 | +static int alchemy_clk_fgv2_setr(struct clk_hw *hw, unsigned long rate, | |
| 643 | + unsigned long parent_rate) | |
| 644 | +{ | |
| 645 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 646 | + int sh = c->shift + 2; | |
| 647 | + unsigned long div, v, flags, ret; | |
| 648 | + | |
| 649 | + if (!rate || !parent_rate || rate > parent_rate) | |
| 650 | + return -EINVAL; | |
| 651 | + | |
| 652 | + v = alchemy_rdsys(c->reg) & (1 << 30); /* test "scale" bit */ | |
| 653 | + ret = alchemy_calc_div(rate, parent_rate, v ? 1 : 2, | |
| 654 | + v ? 256 : 512, &div); | |
| 655 | + | |
| 656 | + spin_lock_irqsave(c->reglock, flags); | |
| 657 | + v = alchemy_rdsys(c->reg); | |
| 658 | + v &= ~(0xff << sh); | |
| 659 | + v |= (div & 0xff) << sh; | |
| 660 | + alchemy_wrsys(v, c->reg); | |
| 661 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 662 | + | |
| 663 | + return 0; | |
| 664 | +} | |
| 665 | + | |
| 666 | +static unsigned long alchemy_clk_fgv2_recalc(struct clk_hw *hw, | |
| 667 | + unsigned long parent_rate) | |
| 668 | +{ | |
| 669 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 670 | + int sh = c->shift + 2; | |
| 671 | + unsigned long v, t; | |
| 672 | + | |
| 673 | + v = alchemy_rdsys(c->reg); | |
| 674 | + t = parent_rate / (((v >> sh) & 0xff) + 1); | |
| 675 | + if ((v & (1 << 30)) == 0) /* test scale bit */ | |
| 676 | + t /= 2; | |
| 677 | + | |
| 678 | + return t; | |
| 679 | +} | |
| 680 | + | |
| 681 | +static long alchemy_clk_fgv2_detr(struct clk_hw *hw, unsigned long rate, | |
| 682 | + unsigned long *best_parent_rate, | |
| 683 | + struct clk **best_parent_clk) | |
| 684 | +{ | |
| 685 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 686 | + int scale, maxdiv; | |
| 687 | + | |
| 688 | + if (alchemy_rdsys(c->reg) & (1 << 30)) { | |
| 689 | + scale = 1; | |
| 690 | + maxdiv = 256; | |
| 691 | + } else { | |
| 692 | + scale = 2; | |
| 693 | + maxdiv = 512; | |
| 694 | + } | |
| 695 | + | |
| 696 | + return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate, | |
| 697 | + best_parent_clk, scale, maxdiv); | |
| 698 | +} | |
| 699 | + | |
| 700 | +/* Au1300 larger input mux, no separate disable bit, flexible divider */ | |
| 701 | +static struct clk_ops alchemy_clkops_fgenv2 = { | |
| 702 | + .recalc_rate = alchemy_clk_fgv2_recalc, | |
| 703 | + .determine_rate = alchemy_clk_fgv2_detr, | |
| 704 | + .set_rate = alchemy_clk_fgv2_setr, | |
| 705 | + .set_parent = alchemy_clk_fgv2_setp, | |
| 706 | + .get_parent = alchemy_clk_fgv2_getp, | |
| 707 | + .enable = alchemy_clk_fgv2_en, | |
| 708 | + .disable = alchemy_clk_fgv2_dis, | |
| 709 | + .is_enabled = alchemy_clk_fgv2_isen, | |
| 710 | +}; | |
| 711 | + | |
| 712 | +static const char * const alchemy_clk_fgv1_parents[] = { | |
| 713 | + ALCHEMY_CPU_CLK, ALCHEMY_AUXPLL_CLK | |
| 714 | +}; | |
| 715 | + | |
| 716 | +static const char * const alchemy_clk_fgv2_parents[] = { | |
| 717 | + ALCHEMY_AUXPLL2_CLK, ALCHEMY_CPU_CLK, ALCHEMY_AUXPLL_CLK | |
| 718 | +}; | |
| 719 | + | |
| 720 | +static const char * const alchemy_clk_fgen_names[] = { | |
| 721 | + ALCHEMY_FG0_CLK, ALCHEMY_FG1_CLK, ALCHEMY_FG2_CLK, | |
| 722 | + ALCHEMY_FG3_CLK, ALCHEMY_FG4_CLK, ALCHEMY_FG5_CLK }; | |
| 723 | + | |
| 724 | +static int __init alchemy_clk_init_fgens(int ctype) | |
| 725 | +{ | |
| 726 | + struct clk *c; | |
| 727 | + struct clk_init_data id; | |
| 728 | + struct alchemy_fgcs_clk *a; | |
| 729 | + unsigned long v; | |
| 730 | + int i, ret; | |
| 731 | + | |
| 732 | + switch (ctype) { | |
| 733 | + case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200: | |
| 734 | + id.ops = &alchemy_clkops_fgenv1; | |
| 735 | + id.parent_names = (const char **)alchemy_clk_fgv1_parents; | |
| 736 | + id.num_parents = 2; | |
| 737 | + break; | |
| 738 | + case ALCHEMY_CPU_AU1300: | |
| 739 | + id.ops = &alchemy_clkops_fgenv2; | |
| 740 | + id.parent_names = (const char **)alchemy_clk_fgv2_parents; | |
| 741 | + id.num_parents = 3; | |
| 742 | + break; | |
| 743 | + default: | |
| 744 | + return -ENODEV; | |
| 745 | + } | |
| 746 | + id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE; | |
| 747 | + | |
| 748 | + a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL); | |
| 749 | + if (!a) | |
| 750 | + return -ENOMEM; | |
| 751 | + | |
| 752 | + spin_lock_init(&alchemy_clk_fg0_lock); | |
| 753 | + spin_lock_init(&alchemy_clk_fg1_lock); | |
| 754 | + ret = 0; | |
| 755 | + for (i = 0; i < 6; i++) { | |
| 756 | + id.name = alchemy_clk_fgen_names[i]; | |
| 757 | + a->shift = 10 * (i < 3 ? i : i - 3); | |
| 758 | + if (i > 2) { | |
| 759 | + a->reg = AU1000_SYS_FREQCTRL1; | |
| 760 | + a->reglock = &alchemy_clk_fg1_lock; | |
| 761 | + } else { | |
| 762 | + a->reg = AU1000_SYS_FREQCTRL0; | |
| 763 | + a->reglock = &alchemy_clk_fg0_lock; | |
| 764 | + } | |
| 765 | + | |
| 766 | + /* default to first parent if bootloader has set | |
| 767 | + * the mux to disabled state. | |
| 768 | + */ | |
| 769 | + if (ctype == ALCHEMY_CPU_AU1300) { | |
| 770 | + v = alchemy_rdsys(a->reg); | |
| 771 | + a->parent = (v >> a->shift) & 3; | |
| 772 | + if (!a->parent) { | |
| 773 | + a->parent = 1; | |
| 774 | + a->isen = 0; | |
| 775 | + } else | |
| 776 | + a->isen = 1; | |
| 777 | + } | |
| 778 | + | |
| 779 | + a->hw.init = &id; | |
| 780 | + c = clk_register(NULL, &a->hw); | |
| 781 | + if (IS_ERR(c)) | |
| 782 | + ret++; | |
| 783 | + else | |
| 784 | + clk_register_clkdev(c, id.name, NULL); | |
| 785 | + a++; | |
| 786 | + } | |
| 787 | + | |
| 788 | + return ret; | |
| 789 | +} | |
| 790 | + | |
| 791 | +/* internal sources muxes *********************************************/ | |
| 792 | + | |
| 793 | +static int alchemy_clk_csrc_isen(struct clk_hw *hw) | |
| 794 | +{ | |
| 795 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 796 | + unsigned long v = alchemy_rdsys(c->reg); | |
| 797 | + | |
| 798 | + return (((v >> c->shift) >> 2) & 7) != 0; | |
| 799 | +} | |
| 800 | + | |
| 801 | +static void __alchemy_clk_csrc_en(struct alchemy_fgcs_clk *c) | |
| 802 | +{ | |
| 803 | + unsigned long v = alchemy_rdsys(c->reg); | |
| 804 | + | |
| 805 | + v &= ~((7 << 2) << c->shift); | |
| 806 | + v |= ((c->parent & 7) << 2) << c->shift; | |
| 807 | + alchemy_wrsys(v, c->reg); | |
| 808 | + c->isen = 1; | |
| 809 | +} | |
| 810 | + | |
| 811 | +static int alchemy_clk_csrc_en(struct clk_hw *hw) | |
| 812 | +{ | |
| 813 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 814 | + unsigned long flags; | |
| 815 | + | |
| 816 | + /* enable by setting the previous parent clock */ | |
| 817 | + spin_lock_irqsave(c->reglock, flags); | |
| 818 | + __alchemy_clk_csrc_en(c); | |
| 819 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 820 | + | |
| 821 | + return 0; | |
| 822 | +} | |
| 823 | + | |
| 824 | +static void alchemy_clk_csrc_dis(struct clk_hw *hw) | |
| 825 | +{ | |
| 826 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 827 | + unsigned long v, flags; | |
| 828 | + | |
| 829 | + spin_lock_irqsave(c->reglock, flags); | |
| 830 | + v = alchemy_rdsys(c->reg); | |
| 831 | + v &= ~((3 << 2) << c->shift); /* mux to "disabled" state */ | |
| 832 | + alchemy_wrsys(v, c->reg); | |
| 833 | + c->isen = 0; | |
| 834 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 835 | +} | |
| 836 | + | |
| 837 | +static int alchemy_clk_csrc_setp(struct clk_hw *hw, u8 index) | |
| 838 | +{ | |
| 839 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 840 | + unsigned long flags; | |
| 841 | + | |
| 842 | + spin_lock_irqsave(c->reglock, flags); | |
| 843 | + c->parent = index + 1; /* value to write to register */ | |
| 844 | + if (c->isen) | |
| 845 | + __alchemy_clk_csrc_en(c); | |
| 846 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 847 | + | |
| 848 | + return 0; | |
| 849 | +} | |
| 850 | + | |
| 851 | +static u8 alchemy_clk_csrc_getp(struct clk_hw *hw) | |
| 852 | +{ | |
| 853 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 854 | + | |
| 855 | + return c->parent - 1; | |
| 856 | +} | |
| 857 | + | |
| 858 | +static unsigned long alchemy_clk_csrc_recalc(struct clk_hw *hw, | |
| 859 | + unsigned long parent_rate) | |
| 860 | +{ | |
| 861 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 862 | + unsigned long v = (alchemy_rdsys(c->reg) >> c->shift) & 3; | |
| 863 | + | |
| 864 | + return parent_rate / c->dt[v]; | |
| 865 | +} | |
| 866 | + | |
| 867 | +static int alchemy_clk_csrc_setr(struct clk_hw *hw, unsigned long rate, | |
| 868 | + unsigned long parent_rate) | |
| 869 | +{ | |
| 870 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 871 | + unsigned long d, v, flags; | |
| 872 | + int i; | |
| 873 | + | |
| 874 | + if (!rate || !parent_rate || rate > parent_rate) | |
| 875 | + return -EINVAL; | |
| 876 | + | |
| 877 | + d = (parent_rate + (rate / 2)) / rate; | |
| 878 | + if (d > 4) | |
| 879 | + return -EINVAL; | |
| 880 | + if ((d == 3) && (c->dt[2] != 3)) | |
| 881 | + d = 4; | |
| 882 | + | |
| 883 | + for (i = 0; i < 4; i++) | |
| 884 | + if (c->dt[i] == d) | |
| 885 | + break; | |
| 886 | + | |
| 887 | + if (i >= 4) | |
| 888 | + return -EINVAL; /* oops */ | |
| 889 | + | |
| 890 | + spin_lock_irqsave(c->reglock, flags); | |
| 891 | + v = alchemy_rdsys(c->reg); | |
| 892 | + v &= ~(3 << c->shift); | |
| 893 | + v |= (i & 3) << c->shift; | |
| 894 | + alchemy_wrsys(v, c->reg); | |
| 895 | + spin_unlock_irqrestore(c->reglock, flags); | |
| 896 | + | |
| 897 | + return 0; | |
| 898 | +} | |
| 899 | + | |
| 900 | +static long alchemy_clk_csrc_detr(struct clk_hw *hw, unsigned long rate, | |
| 901 | + unsigned long *best_parent_rate, | |
| 902 | + struct clk **best_parent_clk) | |
| 903 | +{ | |
| 904 | + struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | |
| 905 | + int scale = c->dt[2] == 3 ? 1 : 2; /* au1300 check */ | |
| 906 | + | |
| 907 | + return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate, | |
| 908 | + best_parent_clk, scale, 4); | |
| 909 | +} | |
| 910 | + | |
| 911 | +static struct clk_ops alchemy_clkops_csrc = { | |
| 912 | + .recalc_rate = alchemy_clk_csrc_recalc, | |
| 913 | + .determine_rate = alchemy_clk_csrc_detr, | |
| 914 | + .set_rate = alchemy_clk_csrc_setr, | |
| 915 | + .set_parent = alchemy_clk_csrc_setp, | |
| 916 | + .get_parent = alchemy_clk_csrc_getp, | |
| 917 | + .enable = alchemy_clk_csrc_en, | |
| 918 | + .disable = alchemy_clk_csrc_dis, | |
| 919 | + .is_enabled = alchemy_clk_csrc_isen, | |
| 920 | +}; | |
| 921 | + | |
| 922 | +static const char * const alchemy_clk_csrc_parents[] = { | |
| 923 | + /* disabled at index 0 */ ALCHEMY_AUXPLL_CLK, | |
| 924 | + ALCHEMY_FG0_CLK, ALCHEMY_FG1_CLK, ALCHEMY_FG2_CLK, | |
| 925 | + ALCHEMY_FG3_CLK, ALCHEMY_FG4_CLK, ALCHEMY_FG5_CLK | |
| 926 | +}; | |
| 927 | + | |
| 928 | +/* divider tables */ | |
| 929 | +static int alchemy_csrc_dt1[] = { 1, 4, 1, 2 }; /* rest */ | |
| 930 | +static int alchemy_csrc_dt2[] = { 1, 4, 3, 2 }; /* Au1300 */ | |
| 931 | + | |
| 932 | +static int __init alchemy_clk_setup_imux(int ctype) | |
| 933 | +{ | |
| 934 | + struct alchemy_fgcs_clk *a; | |
| 935 | + const char * const *names; | |
| 936 | + struct clk_init_data id; | |
| 937 | + unsigned long v; | |
| 938 | + int i, ret, *dt; | |
| 939 | + struct clk *c; | |
| 940 | + | |
| 941 | + id.ops = &alchemy_clkops_csrc; | |
| 942 | + id.parent_names = (const char **)alchemy_clk_csrc_parents; | |
| 943 | + id.num_parents = 7; | |
| 944 | + id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE; | |
| 945 | + | |
| 946 | + dt = alchemy_csrc_dt1; | |
| 947 | + switch (ctype) { | |
| 948 | + case ALCHEMY_CPU_AU1000: | |
| 949 | + names = alchemy_au1000_intclknames; | |
| 950 | + break; | |
| 951 | + case ALCHEMY_CPU_AU1500: | |
| 952 | + names = alchemy_au1500_intclknames; | |
| 953 | + break; | |
| 954 | + case ALCHEMY_CPU_AU1100: | |
| 955 | + names = alchemy_au1100_intclknames; | |
| 956 | + break; | |
| 957 | + case ALCHEMY_CPU_AU1550: | |
| 958 | + names = alchemy_au1550_intclknames; | |
| 959 | + break; | |
| 960 | + case ALCHEMY_CPU_AU1200: | |
| 961 | + names = alchemy_au1200_intclknames; | |
| 962 | + break; | |
| 963 | + case ALCHEMY_CPU_AU1300: | |
| 964 | + dt = alchemy_csrc_dt2; | |
| 965 | + names = alchemy_au1300_intclknames; | |
| 966 | + break; | |
| 967 | + default: | |
| 968 | + return -ENODEV; | |
| 969 | + } | |
| 970 | + | |
| 971 | + a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL); | |
| 972 | + if (!a) | |
| 973 | + return -ENOMEM; | |
| 974 | + | |
| 975 | + spin_lock_init(&alchemy_clk_csrc_lock); | |
| 976 | + ret = 0; | |
| 977 | + | |
| 978 | + for (i = 0; i < 6; i++) { | |
| 979 | + id.name = names[i]; | |
| 980 | + if (!id.name) | |
| 981 | + goto next; | |
| 982 | + | |
| 983 | + a->shift = i * 5; | |
| 984 | + a->reg = AU1000_SYS_CLKSRC; | |
| 985 | + a->reglock = &alchemy_clk_csrc_lock; | |
| 986 | + a->dt = dt; | |
| 987 | + | |
| 988 | + /* default to first parent clock if mux is initially | |
| 989 | + * set to disabled state. | |
| 990 | + */ | |
| 991 | + v = alchemy_rdsys(a->reg); | |
| 992 | + a->parent = ((v >> a->shift) >> 2) & 7; | |
| 993 | + if (!a->parent) { | |
| 994 | + a->parent = 1; | |
| 995 | + a->isen = 0; | |
| 996 | + } else | |
| 997 | + a->isen = 1; | |
| 998 | + | |
| 999 | + a->hw.init = &id; | |
| 1000 | + c = clk_register(NULL, &a->hw); | |
| 1001 | + if (IS_ERR(c)) | |
| 1002 | + ret++; | |
| 1003 | + else | |
| 1004 | + clk_register_clkdev(c, id.name, NULL); | |
| 1005 | +next: | |
| 1006 | + a++; | |
| 1007 | + } | |
| 1008 | + | |
| 1009 | + return ret; | |
| 1010 | +} | |
| 1011 | + | |
| 1012 | + | |
| 1013 | +/**********************************************************************/ | |
| 1014 | + | |
| 1015 | + | |
| 1016 | +#define ERRCK(x) \ | |
| 1017 | + if (IS_ERR(x)) { \ | |
| 1018 | + ret = PTR_ERR(x); \ | |
| 1019 | + goto out; \ | |
| 1020 | + } | |
| 1021 | + | |
| 1022 | +static int __init alchemy_clk_init(void) | |
| 1023 | +{ | |
| 1024 | + int ctype = alchemy_get_cputype(), ret, i; | |
| 1025 | + struct clk_aliastable *t = alchemy_clk_aliases; | |
| 1026 | + struct clk *c; | |
| 1027 | + | |
| 1028 | + /* Root of the Alchemy clock tree: external 12MHz crystal osc */ | |
| 1029 | + c = clk_register_fixed_rate(NULL, ALCHEMY_ROOT_CLK, NULL, | |
| 1030 | + CLK_IS_ROOT, | |
| 1031 | + ALCHEMY_ROOTCLK_RATE); | |
| 1032 | + ERRCK(c) | |
| 1033 | + | |
| 1034 | + /* CPU core clock */ | |
| 1035 | + c = alchemy_clk_setup_cpu(ALCHEMY_ROOT_CLK, ctype); | |
| 1036 | + ERRCK(c) | |
| 1037 | + | |
| 1038 | + /* AUXPLLs: max 1GHz on Au1300, 748MHz on older models */ | |
| 1039 | + i = (ctype == ALCHEMY_CPU_AU1300) ? 84 : 63; | |
| 1040 | + c = alchemy_clk_setup_aux(ALCHEMY_ROOT_CLK, ALCHEMY_AUXPLL_CLK, | |
| 1041 | + i, AU1000_SYS_AUXPLL); | |
| 1042 | + ERRCK(c) | |
| 1043 | + | |
| 1044 | + if (ctype == ALCHEMY_CPU_AU1300) { | |
| 1045 | + c = alchemy_clk_setup_aux(ALCHEMY_ROOT_CLK, | |
| 1046 | + ALCHEMY_AUXPLL2_CLK, i, | |
| 1047 | + AU1300_SYS_AUXPLL2); | |
| 1048 | + ERRCK(c) | |
| 1049 | + } | |
| 1050 | + | |
| 1051 | + /* sysbus clock: cpu core clock divided by 2, 3 or 4 */ | |
| 1052 | + c = alchemy_clk_setup_sysbus(ALCHEMY_CPU_CLK); | |
| 1053 | + ERRCK(c) | |
| 1054 | + | |
| 1055 | + /* peripheral clock: runs at half rate of sysbus clk */ | |
| 1056 | + c = alchemy_clk_setup_periph(ALCHEMY_SYSBUS_CLK); | |
| 1057 | + ERRCK(c) | |
| 1058 | + | |
| 1059 | + /* SDR/DDR memory clock */ | |
| 1060 | + c = alchemy_clk_setup_mem(ALCHEMY_SYSBUS_CLK, ctype); | |
| 1061 | + ERRCK(c) | |
| 1062 | + | |
| 1063 | + /* L/RCLK: external static bus clock for synchronous mode */ | |
| 1064 | + c = alchemy_clk_setup_lrclk(ALCHEMY_PERIPH_CLK); | |
| 1065 | + ERRCK(c) | |
| 1066 | + | |
| 1067 | + /* Frequency dividers 0-5 */ | |
| 1068 | + ret = alchemy_clk_init_fgens(ctype); | |
| 1069 | + if (ret) { | |
| 1070 | + ret = -ENODEV; | |
| 1071 | + goto out; | |
| 1072 | + } | |
| 1073 | + | |
| 1074 | + /* diving muxes for internal sources */ | |
| 1075 | + ret = alchemy_clk_setup_imux(ctype); | |
| 1076 | + if (ret) { | |
| 1077 | + ret = -ENODEV; | |
| 1078 | + goto out; | |
| 1079 | + } | |
| 1080 | + | |
| 1081 | + /* set up aliases drivers might look for */ | |
| 1082 | + while (t->base) { | |
| 1083 | + if (t->cputype == ctype) | |
| 1084 | + clk_add_alias(t->alias, NULL, t->base, NULL); | |
| 1085 | + t++; | |
| 1086 | + } | |
| 1087 | + | |
| 1088 | + pr_info("Alchemy clocktree installed\n"); | |
| 1089 | + return 0; | |
| 1090 | + | |
| 1091 | +out: | |
| 1092 | + return ret; | |
| 1093 | +} | |
| 1094 | +postcore_initcall(alchemy_clk_init); | |
| @@ -1,105 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * BRIEF MODULE DESCRIPTION | |
| 3 | − * Simple Au1xx0 clocks routines. | |
| 4 | − * | |
| 5 | − * Copyright 2001, 2008 MontaVista Software Inc. | |
| 6 | − * Author: MontaVista Software, Inc. <source@mvista.com> | |
| 7 | − * | |
| 8 | − * This program is free software; you can redistribute it and/or modify it | |
| 9 | − * under the terms of the GNU General Public License as published by the | |
| 10 | − * Free Software Foundation; either version 2 of the License, or (at your | |
| 11 | − * option) any later version. | |
| 12 | − * | |
| 13 | − * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
| 14 | − * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| 15 | − * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | |
| 16 | − * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 17 | − * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 18 | − * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
| 19 | − * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
| 20 | − * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 21 | − * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 22 | − * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 23 | − * | |
| 24 | − * You should have received a copy of the GNU General Public License along | |
| 25 | − * with this program; if not, write to the Free Software Foundation, Inc., | |
| 26 | − * 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 27 | − */ | |
| 28 | − | |
| 29 | −#include <linux/module.h> | |
| 30 | −#include <linux/spinlock.h> | |
| 31 | −#include <asm/time.h> | |
| 32 | −#include <asm/mach-au1x00/au1000.h> | |
| 33 | − | |
| 34 | −/* | |
| 35 | − * I haven't found anyone that doesn't use a 12 MHz source clock, | |
| 36 | − * but just in case..... | |
| 37 | − */ | |
| 38 | −#define AU1000_SRC_CLK 12000000 | |
| 39 | − | |
| 40 | −static unsigned int au1x00_clock; /* Hz */ | |
| 41 | −static unsigned long uart_baud_base; | |
| 42 | − | |
| 43 | −/* | |
| 44 | − * Set the au1000_clock | |
| 45 | − */ | |
| 46 | −void set_au1x00_speed(unsigned int new_freq) | |
| 47 | −{ | |
| 48 | − au1x00_clock = new_freq; | |
| 49 | −} | |
| 50 | − | |
| 51 | −unsigned int get_au1x00_speed(void) | |
| 52 | −{ | |
| 53 | − return au1x00_clock; | |
| 54 | −} | |
| 55 | −EXPORT_SYMBOL(get_au1x00_speed); | |
| 56 | − | |
| 57 | −/* | |
| 58 | − * The UART baud base is not known at compile time ... if | |
| 59 | − * we want to be able to use the same code on different | |
| 60 | − * speed CPUs. | |
| 61 | − */ | |
| 62 | −unsigned long get_au1x00_uart_baud_base(void) | |
| 63 | −{ | |
| 64 | − return uart_baud_base; | |
| 65 | −} | |
| 66 | − | |
| 67 | −void set_au1x00_uart_baud_base(unsigned long new_baud_base) | |
| 68 | −{ | |
| 69 | − uart_baud_base = new_baud_base; | |
| 70 | −} | |
| 71 | − | |
| 72 | −/* | |
| 73 | − * We read the real processor speed from the PLL. This is important | |
| 74 | − * because it is more accurate than computing it from the 32 KHz | |
| 75 | − * counter, if it exists. If we don't have an accurate processor | |
| 76 | − * speed, all of the peripherals that derive their clocks based on | |
| 77 | − * this advertised speed will introduce error and sometimes not work | |
| 78 | − * properly. This function is further convoluted to still allow configurations | |
| 79 | − * to do that in case they have really, really old silicon with a | |
| 80 | − * write-only PLL register. -- Dan | |
| 81 | − */ | |
| 82 | −unsigned long au1xxx_calc_clock(void) | |
| 83 | −{ | |
| 84 | − unsigned long cpu_speed; | |
| 85 | − | |
| 86 | − /* | |
| 87 | − * On early Au1000, sys_cpupll was write-only. Since these | |
| 88 | − * silicon versions of Au1000 are not sold by AMD, we don't bend | |
| 89 | − * over backwards trying to determine the frequency. | |
| 90 | − */ | |
| 91 | − if (au1xxx_cpu_has_pll_wo()) | |
| 92 | − cpu_speed = 396000000; | |
| 93 | − else | |
| 94 | − cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; | |
| 95 | − | |
| 96 | − /* On Alchemy CPU:counter ratio is 1:1 */ | |
| 97 | − mips_hpt_frequency = cpu_speed; | |
| 98 | − /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */ | |
| 99 | − set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL) | |
| 100 | − & 0x03) + 2) * 16)); | |
| 101 | − | |
| 102 | − set_au1x00_speed(cpu_speed); | |
| 103 | − | |
| 104 | − return cpu_speed; | |
| 105 | −} | |
| @@ -341,7 +341,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, · 340 unmodified lines | ||
| 341 | 341 | (dtp->dev_flags & DEV_FLAGS_SYNC)) |
| 342 | 342 | i |= DDMA_CFG_SYNC; |
| 343 | 343 | cp->ddma_cfg = i; |
| 344 | − au_sync(); | |
| 344 | + wmb(); /* drain writebuffer */ | |
| 345 | 345 | |
| 346 | 346 | /* |
| 347 | 347 | * Return a non-zero value that can be used to find the channel |
| @@ -631,7 +631,7 @@ u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) · 283 unmodified lines | ||
| 631 | 631 | */ |
| 632 | 632 | dma_cache_wback_inv((unsigned long)buf, nbytes); |
| 633 | 633 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ |
| 634 | − au_sync(); | |
| 634 | + wmb(); /* drain writebuffer */ | |
| 635 | 635 | dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); |
| 636 | 636 | ctp->chan_ptr->ddma_dbell = 0; |
| 637 | 637 | |
| @@ -693,7 +693,7 @@ u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) · 55 unmodified lines | ||
| 693 | 693 | */ |
| 694 | 694 | dma_cache_inv((unsigned long)buf, nbytes); |
| 695 | 695 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ |
| 696 | − au_sync(); | |
| 696 | + wmb(); /* drain writebuffer */ | |
| 697 | 697 | dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); |
| 698 | 698 | ctp->chan_ptr->ddma_dbell = 0; |
| 699 | 699 | |
| @@ -760,7 +760,7 @@ void au1xxx_dbdma_stop(u32 chanid) · 60 unmodified lines | ||
| 760 | 760 | |
| 761 | 761 | cp = ctp->chan_ptr; |
| 762 | 762 | cp->ddma_cfg &= ~DDMA_CFG_EN; /* Disable channel */ |
| 763 | − au_sync(); | |
| 763 | + wmb(); /* drain writebuffer */ | |
| 764 | 764 | while (!(cp->ddma_stat & DDMA_STAT_H)) { |
| 765 | 765 | udelay(1); |
| 766 | 766 | halt_timeout++; |
| @@ -771,7 +771,7 @@ void au1xxx_dbdma_stop(u32 chanid) · 4 unmodified lines | ||
| 771 | 771 | } |
| 772 | 772 | /* clear current desc valid and doorbell */ |
| 773 | 773 | cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); |
| 774 | − au_sync(); | |
| 774 | + wmb(); /* drain writebuffer */ | |
| 775 | 775 | } |
| 776 | 776 | EXPORT_SYMBOL(au1xxx_dbdma_stop); |
| 777 | 777 | |
| @@ -789,9 +789,9 @@ void au1xxx_dbdma_start(u32 chanid) · 11 unmodified lines | ||
| 789 | 789 | cp = ctp->chan_ptr; |
| 790 | 790 | cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); |
| 791 | 791 | cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ |
| 792 | − au_sync(); | |
| 792 | + wmb(); /* drain writebuffer */ | |
| 793 | 793 | cp->ddma_dbell = 0; |
| 794 | − au_sync(); | |
| 794 | + wmb(); /* drain writebuffer */ | |
| 795 | 795 | } |
| 796 | 796 | EXPORT_SYMBOL(au1xxx_dbdma_start); |
| 797 | 797 | |
| @@ -832,7 +832,7 @@ u32 au1xxx_get_dma_residue(u32 chanid) · 34 unmodified lines | ||
| 832 | 832 | |
| 833 | 833 | /* This is only valid if the channel is stopped. */ |
| 834 | 834 | rv = cp->ddma_bytecnt; |
| 835 | − au_sync(); | |
| 835 | + wmb(); /* drain writebuffer */ | |
| 836 | 836 | |
| 837 | 837 | return rv; |
| 838 | 838 | } |
| @@ -868,7 +868,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id) · 29 unmodified lines | ||
| 868 | 868 | au1x_dma_chan_t *cp; |
| 869 | 869 | |
| 870 | 870 | intstat = dbdma_gptr->ddma_intstat; |
| 871 | − au_sync(); | |
| 871 | + wmb(); /* drain writebuffer */ | |
| 872 | 872 | chan_index = __ffs(intstat); |
| 873 | 873 | |
| 874 | 874 | ctp = chan_tab_ptr[chan_index]; |
| @@ -877,7 +877,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id) · 2 unmodified lines | ||
| 877 | 877 | |
| 878 | 878 | /* Reset interrupt. */ |
| 879 | 879 | cp->ddma_irq = 0; |
| 880 | − au_sync(); | |
| 880 | + wmb(); /* drain writebuffer */ | |
| 881 | 881 | |
| 882 | 882 | if (ctp->chan_callback) |
| 883 | 883 | ctp->chan_callback(irq, ctp->chan_callparam); |
| @@ -1061,7 +1061,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) · 177 unmodified lines | ||
| 1061 | 1061 | dbdma_gptr->ddma_config = 0; |
| 1062 | 1062 | dbdma_gptr->ddma_throttle = 0; |
| 1063 | 1063 | dbdma_gptr->ddma_inten = 0xffff; |
| 1064 | − au_sync(); | |
| 1064 | + wmb(); /* drain writebuffer */ | |
| 1065 | 1065 | |
| 1066 | 1066 | ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr); |
| 1067 | 1067 | if (ret) |
| @@ -141,17 +141,17 @@ void dump_au1000_dma_channel(unsigned int dmanr) · 140 unmodified lines | ||
| 141 | 141 | |
| 142 | 142 | printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr); |
| 143 | 143 | printk(KERN_INFO " mode = 0x%08x\n", |
| 144 | − au_readl(chan->io + DMA_MODE_SET)); | |
| 144 | + __raw_readl(chan->io + DMA_MODE_SET)); | |
| 145 | 145 | printk(KERN_INFO " addr = 0x%08x\n", |
| 146 | − au_readl(chan->io + DMA_PERIPHERAL_ADDR)); | |
| 146 | + __raw_readl(chan->io + DMA_PERIPHERAL_ADDR)); | |
| 147 | 147 | printk(KERN_INFO " start0 = 0x%08x\n", |
| 148 | − au_readl(chan->io + DMA_BUFFER0_START)); | |
| 148 | + __raw_readl(chan->io + DMA_BUFFER0_START)); | |
| 149 | 149 | printk(KERN_INFO " start1 = 0x%08x\n", |
| 150 | − au_readl(chan->io + DMA_BUFFER1_START)); | |
| 150 | + __raw_readl(chan->io + DMA_BUFFER1_START)); | |
| 151 | 151 | printk(KERN_INFO " count0 = 0x%08x\n", |
| 152 | − au_readl(chan->io + DMA_BUFFER0_COUNT)); | |
| 152 | + __raw_readl(chan->io + DMA_BUFFER0_COUNT)); | |
| 153 | 153 | printk(KERN_INFO " count1 = 0x%08x\n", |
| 154 | − au_readl(chan->io + DMA_BUFFER1_COUNT)); | |
| 154 | + __raw_readl(chan->io + DMA_BUFFER1_COUNT)); | |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | /* |
| @@ -204,7 +204,8 @@ int request_au1000_dma(int dev_id, const char *dev_str, · 46 unmodified lines | ||
| 204 | 204 | } |
| 205 | 205 | |
| 206 | 206 | /* fill it in */ |
| 207 | − chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN; | |
| 207 | + chan->io = (void __iomem *)(KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + | |
| 208 | + i * DMA_CHANNEL_LEN); | |
| 208 | 209 | chan->dev_id = dev_id; |
| 209 | 210 | chan->dev_str = dev_str; |
| 210 | 211 | chan->fifo_addr = dev->fifo_addr; |
| @@ -389,13 +389,12 @@ static int au1x_ic1_setwake(struct irq_data *d, unsigned int on) · 388 unmodified lines | ||
| 389 | 389 | return -EINVAL; |
| 390 | 390 | |
| 391 | 391 | local_irq_save(flags); |
| 392 | − wakemsk = __raw_readl((void __iomem *)SYS_WAKEMSK); | |
| 392 | + wakemsk = alchemy_rdsys(AU1000_SYS_WAKEMSK); | |
| 393 | 393 | if (on) |
| 394 | 394 | wakemsk |= 1 << bit; |
| 395 | 395 | else |
| 396 | 396 | wakemsk &= ~(1 << bit); |
| 397 | − __raw_writel(wakemsk, (void __iomem *)SYS_WAKEMSK); | |
| 398 | − wmb(); | |
| 397 | + alchemy_wrsys(wakemsk, AU1000_SYS_WAKEMSK); | |
| 399 | 398 | local_irq_restore(flags); |
| 400 | 399 | |
| 401 | 400 | return 0; |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | * warranty of any kind, whether express or implied. |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | +#include <linux/clk.h> | |
| 14 | 15 | #include <linux/dma-mapping.h> |
| 15 | 16 | #include <linux/etherdevice.h> |
| 16 | 17 | #include <linux/init.h> |
| @@ -99,10 +100,20 @@ static struct platform_device au1xx0_uart_device = { · 82 unmodified lines | ||
| 99 | 100 | |
| 100 | 101 | static void __init alchemy_setup_uarts(int ctype) |
| 101 | 102 | { |
| 102 | − unsigned int uartclk = get_au1x00_uart_baud_base() * 16; | |
| 103 | + long uartclk; | |
| 103 | 104 | int s = sizeof(struct plat_serial8250_port); |
| 104 | 105 | int c = alchemy_get_uarts(ctype); |
| 105 | 106 | struct plat_serial8250_port *ports; |
| 107 | + struct clk *clk = clk_get(NULL, ALCHEMY_PERIPH_CLK); | |
| 108 | + | |
| 109 | + if (IS_ERR(clk)) | |
| 110 | + return; | |
| 111 | + if (clk_prepare_enable(clk)) { | |
| 112 | + clk_put(clk); | |
| 113 | + return; | |
| 114 | + } | |
| 115 | + uartclk = clk_get_rate(clk); | |
| 116 | + clk_put(clk); | |
| 106 | 117 | |
| 107 | 118 | ports = kzalloc(s * (c + 1), GFP_KERNEL); |
| 108 | 119 | if (!ports) { |
| @@ -420,7 +431,7 @@ static void __init alchemy_setup_macs(int ctype) · 311 unmodified lines | ||
| 420 | 431 | memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6); |
| 421 | 432 | |
| 422 | 433 | /* Register second MAC if enabled in pinfunc */ |
| 423 | − if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) { | |
| 434 | + if (!(alchemy_rdsys(AU1000_SYS_PINFUNC) & SYS_PF_NI2)) { | |
| 424 | 435 | ret = platform_device_register(&au1xxx_eth1_device); |
| 425 | 436 | if (ret) |
| 426 | 437 | printk(KERN_INFO "Alchemy: failed to register MAC1\n"); |
| @@ -54,28 +54,28 @@ static unsigned int sleep_static_memctlr[4][3]; · 53 unmodified lines | ||
| 54 | 54 | static void save_core_regs(void) |
| 55 | 55 | { |
| 56 | 56 | /* Clocks and PLLs. */ |
| 57 | − sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); | |
| 58 | − sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); | |
| 59 | − sleep_sys_clocks[2] = au_readl(SYS_CLKSRC); | |
| 60 | − sleep_sys_clocks[3] = au_readl(SYS_CPUPLL); | |
| 61 | − sleep_sys_clocks[4] = au_readl(SYS_AUXPLL); | |
| 57 | + sleep_sys_clocks[0] = alchemy_rdsys(AU1000_SYS_FREQCTRL0); | |
| 58 | + sleep_sys_clocks[1] = alchemy_rdsys(AU1000_SYS_FREQCTRL1); | |
| 59 | + sleep_sys_clocks[2] = alchemy_rdsys(AU1000_SYS_CLKSRC); | |
| 60 | + sleep_sys_clocks[3] = alchemy_rdsys(AU1000_SYS_CPUPLL); | |
| 61 | + sleep_sys_clocks[4] = alchemy_rdsys(AU1000_SYS_AUXPLL); | |
| 62 | 62 | |
| 63 | 63 | /* pin mux config */ |
| 64 | − sleep_sys_pinfunc = au_readl(SYS_PINFUNC); | |
| 64 | + sleep_sys_pinfunc = alchemy_rdsys(AU1000_SYS_PINFUNC); | |
| 65 | 65 | |
| 66 | 66 | /* Save the static memory controller configuration. */ |
| 67 | − sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); | |
| 68 | − sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); | |
| 69 | − sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); | |
| 70 | − sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1); | |
| 71 | − sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1); | |
| 72 | − sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1); | |
| 73 | − sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2); | |
| 74 | − sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2); | |
| 75 | − sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2); | |
| 76 | − sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); | |
| 77 | − sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); | |
| 78 | − sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); | |
| 67 | + sleep_static_memctlr[0][0] = alchemy_rdsmem(AU1000_MEM_STCFG0); | |
| 68 | + sleep_static_memctlr[0][1] = alchemy_rdsmem(AU1000_MEM_STTIME0); | |
| 69 | + sleep_static_memctlr[0][2] = alchemy_rdsmem(AU1000_MEM_STADDR0); | |
| 70 | + sleep_static_memctlr[1][0] = alchemy_rdsmem(AU1000_MEM_STCFG1); | |
| 71 | + sleep_static_memctlr[1][1] = alchemy_rdsmem(AU1000_MEM_STTIME1); | |
| 72 | + sleep_static_memctlr[1][2] = alchemy_rdsmem(AU1000_MEM_STADDR1); | |
| 73 | + sleep_static_memctlr[2][0] = alchemy_rdsmem(AU1000_MEM_STCFG2); | |
| 74 | + sleep_static_memctlr[2][1] = alchemy_rdsmem(AU1000_MEM_STTIME2); | |
| 75 | + sleep_static_memctlr[2][2] = alchemy_rdsmem(AU1000_MEM_STADDR2); | |
| 76 | + sleep_static_memctlr[3][0] = alchemy_rdsmem(AU1000_MEM_STCFG3); | |
| 77 | + sleep_static_memctlr[3][1] = alchemy_rdsmem(AU1000_MEM_STTIME3); | |
| 78 | + sleep_static_memctlr[3][2] = alchemy_rdsmem(AU1000_MEM_STADDR3); | |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | static void restore_core_regs(void) |
| @@ -85,30 +85,28 @@ static void restore_core_regs(void) · 3 unmodified lines | ||
| 85 | 85 | * one of those Au1000 with a write-only PLL, where we dont |
| 86 | 86 | * have a valid value) |
| 87 | 87 | */ |
| 88 | − au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0); | |
| 89 | − au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1); | |
| 90 | − au_writel(sleep_sys_clocks[2], SYS_CLKSRC); | |
| 91 | − au_writel(sleep_sys_clocks[4], SYS_AUXPLL); | |
| 88 | + alchemy_wrsys(sleep_sys_clocks[0], AU1000_SYS_FREQCTRL0); | |
| 89 | + alchemy_wrsys(sleep_sys_clocks[1], AU1000_SYS_FREQCTRL1); | |
| 90 | + alchemy_wrsys(sleep_sys_clocks[2], AU1000_SYS_CLKSRC); | |
| 91 | + alchemy_wrsys(sleep_sys_clocks[4], AU1000_SYS_AUXPLL); | |
| 92 | 92 | if (!au1xxx_cpu_has_pll_wo()) |
| 93 | − au_writel(sleep_sys_clocks[3], SYS_CPUPLL); | |
| 94 | − au_sync(); | |
| 93 | + alchemy_wrsys(sleep_sys_clocks[3], AU1000_SYS_CPUPLL); | |
| 95 | 94 | |
| 96 | − au_writel(sleep_sys_pinfunc, SYS_PINFUNC); | |
| 97 | − au_sync(); | |
| 95 | + alchemy_wrsys(sleep_sys_pinfunc, AU1000_SYS_PINFUNC); | |
| 98 | 96 | |
| 99 | 97 | /* Restore the static memory controller configuration. */ |
| 100 | − au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); | |
| 101 | − au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); | |
| 102 | − au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); | |
| 103 | − au_writel(sleep_static_memctlr[1][0], MEM_STCFG1); | |
| 104 | − au_writel(sleep_static_memctlr[1][1], MEM_STTIME1); | |
| 105 | − au_writel(sleep_static_memctlr[1][2], MEM_STADDR1); | |
| 106 | − au_writel(sleep_static_memctlr[2][0], MEM_STCFG2); | |
| 107 | − au_writel(sleep_static_memctlr[2][1], MEM_STTIME2); | |
| 108 | − au_writel(sleep_static_memctlr[2][2], MEM_STADDR2); | |
| 109 | − au_writel(sleep_static_memctlr[3][0], MEM_STCFG3); | |
| 110 | − au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); | |
| 111 | − au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); | |
| 98 | + alchemy_wrsmem(sleep_static_memctlr[0][0], AU1000_MEM_STCFG0); | |
| 99 | + alchemy_wrsmem(sleep_static_memctlr[0][1], AU1000_MEM_STTIME0); | |
| 100 | + alchemy_wrsmem(sleep_static_memctlr[0][2], AU1000_MEM_STADDR0); | |
| 101 | + alchemy_wrsmem(sleep_static_memctlr[1][0], AU1000_MEM_STCFG1); | |
| 102 | + alchemy_wrsmem(sleep_static_memctlr[1][1], AU1000_MEM_STTIME1); | |
| 103 | + alchemy_wrsmem(sleep_static_memctlr[1][2], AU1000_MEM_STADDR1); | |
| 104 | + alchemy_wrsmem(sleep_static_memctlr[2][0], AU1000_MEM_STCFG2); | |
| 105 | + alchemy_wrsmem(sleep_static_memctlr[2][1], AU1000_MEM_STTIME2); | |
| 106 | + alchemy_wrsmem(sleep_static_memctlr[2][2], AU1000_MEM_STADDR2); | |
| 107 | + alchemy_wrsmem(sleep_static_memctlr[3][0], AU1000_MEM_STCFG3); | |
| 108 | + alchemy_wrsmem(sleep_static_memctlr[3][1], AU1000_MEM_STTIME3); | |
| 109 | + alchemy_wrsmem(sleep_static_memctlr[3][2], AU1000_MEM_STADDR3); | |
| 112 | 110 | } |
| 113 | 111 | |
| 114 | 112 | void au_sleep(void) |
| @@ -27,12 +27,9 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #include <linux/init.h> |
| 29 | 29 | #include <linux/ioport.h> |
| 30 | −#include <linux/jiffies.h> | |
| 31 | −#include <linux/module.h> | |
| 32 | 30 | |
| 33 | 31 | #include <asm/dma-coherence.h> |
| 34 | 32 | #include <asm/mipsregs.h> |
| 35 | −#include <asm/time.h> | |
| 36 | 33 | |
| 37 | 34 | #include <au1000.h> |
| 38 | 35 | |
| @@ -41,18 +38,6 @@ extern void set_cpuspec(void); · 2 unmodified lines | ||
| 41 | 38 | |
| 42 | 39 | void __init plat_mem_setup(void) |
| 43 | 40 | { |
| 44 | − unsigned long est_freq; | |
| 45 | − | |
| 46 | − /* determine core clock */ | |
| 47 | − est_freq = au1xxx_calc_clock(); | |
| 48 | − est_freq += 5000; /* round */ | |
| 49 | − est_freq -= est_freq % 10000; | |
| 50 | − printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(), | |
| 51 | − est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); | |
| 52 | − | |
| 53 | − /* this is faster than wasting cycles trying to approximate it */ | |
| 54 | − preset_lpj = (est_freq >> 1) / HZ; | |
| 55 | − | |
| 56 | 41 | if (au1xxx_cpu_needs_config_od()) |
| 57 | 42 | /* Various early Au1xx0 errata corrected by this */ |
| 58 | 43 | set_c0_config(1 << 19); /* Set Config[OD] */ |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | static cycle_t au1x_counter1_read(struct clocksource *cs) |
| 48 | 48 | { |
| 49 | − return au_readl(SYS_RTCREAD); | |
| 49 | + return alchemy_rdsys(AU1000_SYS_RTCREAD); | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | static struct clocksource au1x_counter1_clocksource = { |
| @@ -60,12 +60,11 @@ static struct clocksource au1x_counter1_clocksource = { · 7 unmodified lines | ||
| 60 | 60 | static int au1x_rtcmatch2_set_next_event(unsigned long delta, |
| 61 | 61 | struct clock_event_device *cd) |
| 62 | 62 | { |
| 63 | − delta += au_readl(SYS_RTCREAD); | |
| 63 | + delta += alchemy_rdsys(AU1000_SYS_RTCREAD); | |
| 64 | 64 | /* wait for register access */ |
| 65 | − while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M21) | |
| 65 | + while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M21) | |
| 66 | 66 | ; |
| 67 | − au_writel(delta, SYS_RTCMATCH2); | |
| 68 | − au_sync(); | |
| 67 | + alchemy_wrsys(delta, AU1000_SYS_RTCMATCH2); | |
| 69 | 68 | |
| 70 | 69 | return 0; |
| 71 | 70 | } |
| @@ -112,31 +111,29 @@ static int __init alchemy_time_init(unsigned int m2int) · 40 unmodified lines | ||
| 112 | 111 | * (the 32S bit seems to be stuck set to 1 once a single clock- |
| 113 | 112 | * edge is detected, hence the timeouts). |
| 114 | 113 | */ |
| 115 | − if (CNTR_OK != (au_readl(SYS_COUNTER_CNTRL) & CNTR_OK)) | |
| 114 | + if (CNTR_OK != (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & CNTR_OK)) | |
| 116 | 115 | goto cntr_err; |
| 117 | 116 | |
| 118 | 117 | /* |
| 119 | 118 | * setup counter 1 (RTC) to tick at full speed |
| 120 | 119 | */ |
| 121 | 120 | t = 0xffffff; |
| 122 | − while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && --t) | |
| 121 | + while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_T1S) && --t) | |
| 123 | 122 | asm volatile ("nop"); |
| 124 | 123 | if (!t) |
| 125 | 124 | goto cntr_err; |
| 126 | 125 | |
| 127 | − au_writel(0, SYS_RTCTRIM); /* 32.768 kHz */ | |
| 128 | − au_sync(); | |
| 126 | + alchemy_wrsys(0, AU1000_SYS_RTCTRIM); /* 32.768 kHz */ | |
| 129 | 127 | |
| 130 | 128 | t = 0xffffff; |
| 131 | − while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) | |
| 129 | + while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C1S) && --t) | |
| 132 | 130 | asm volatile ("nop"); |
| 133 | 131 | if (!t) |
| 134 | 132 | goto cntr_err; |
| 135 | − au_writel(0, SYS_RTCWRITE); | |
| 136 | − au_sync(); | |
| 133 | + alchemy_wrsys(0, AU1000_SYS_RTCWRITE); | |
| 137 | 134 | |
| 138 | 135 | t = 0xffffff; |
| 139 | − while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) | |
| 136 | + while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C1S) && --t) | |
| 140 | 137 | asm volatile ("nop"); |
| 141 | 138 | if (!t) |
| 142 | 139 | goto cntr_err; |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | * |
| 10 | 10 | */ |
| 11 | 11 | |
| 12 | +#include <linux/clk.h> | |
| 12 | 13 | #include <linux/init.h> |
| 13 | 14 | #include <linux/io.h> |
| 14 | 15 | #include <linux/module.h> |
| @@ -387,10 +388,25 @@ static inline void au1200_usb_init(void) · 372 unmodified lines | ||
| 387 | 388 | udelay(1000); |
| 388 | 389 | } |
| 389 | 390 | |
| 390 | −static inline void au1000_usb_init(unsigned long rb, int reg) | |
| 391 | +static inline int au1000_usb_init(unsigned long rb, int reg) | |
| 391 | 392 | { |
| 392 | 393 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); |
| 393 | 394 | unsigned long r = __raw_readl(base); |
| 395 | + struct clk *c; | |
| 396 | + | |
| 397 | + /* 48MHz check. Don't init if no one can provide it */ | |
| 398 | + c = clk_get(NULL, "usbh_clk"); | |
| 399 | + if (IS_ERR(c)) | |
| 400 | + return -ENODEV; | |
| 401 | + if (clk_round_rate(c, 48000000) != 48000000) { | |
| 402 | + clk_put(c); | |
| 403 | + return -ENODEV; | |
| 404 | + } | |
| 405 | + if (clk_set_rate(c, 48000000)) { | |
| 406 | + clk_put(c); | |
| 407 | + return -ENODEV; | |
| 408 | + } | |
| 409 | + clk_put(c); | |
| 394 | 410 | |
| 395 | 411 | #if defined(__BIG_ENDIAN) |
| 396 | 412 | r |= USBHEN_BE; |
| @@ -400,6 +416,8 @@ static inline void au1000_usb_init(unsigned long rb, int reg) · 3 unmodified lines | ||
| 400 | 416 | __raw_writel(r, base); |
| 401 | 417 | wmb(); |
| 402 | 418 | udelay(1000); |
| 419 | + | |
| 420 | + return 0; | |
| 403 | 421 | } |
| 404 | 422 | |
| 405 | 423 | |
| @@ -407,8 +425,15 @@ static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) · 1 unmodified line | ||
| 407 | 425 | { |
| 408 | 426 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb); |
| 409 | 427 | unsigned long r = __raw_readl(base + creg); |
| 428 | + struct clk *c = clk_get(NULL, "usbh_clk"); | |
| 429 | + | |
| 430 | + if (IS_ERR(c)) | |
| 431 | + return; | |
| 410 | 432 | |
| 411 | 433 | if (enable) { |
| 434 | + if (clk_prepare_enable(c)) | |
| 435 | + goto out; | |
| 436 | + | |
| 412 | 437 | __raw_writel(r | USBHEN_CE, base + creg); |
| 413 | 438 | wmb(); |
| 414 | 439 | udelay(1000); |
| @@ -423,7 +448,10 @@ static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) · 8 unmodified lines | ||
| 423 | 448 | } else { |
| 424 | 449 | __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); |
| 425 | 450 | wmb(); |
| 451 | + clk_disable_unprepare(c); | |
| 426 | 452 | } |
| 453 | +out: | |
| 454 | + clk_put(c); | |
| 427 | 455 | } |
| 428 | 456 | |
| 429 | 457 | static inline int au1000_usb_control(int block, int enable, unsigned long rb, |
| @@ -457,11 +485,11 @@ int alchemy_usb_control(int block, int enable) · 27 unmodified lines | ||
| 457 | 485 | case ALCHEMY_CPU_AU1500: |
| 458 | 486 | case ALCHEMY_CPU_AU1100: |
| 459 | 487 | ret = au1000_usb_control(block, enable, |
| 460 | − AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | |
| 488 | + AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | |
| 461 | 489 | break; |
| 462 | 490 | case ALCHEMY_CPU_AU1550: |
| 463 | 491 | ret = au1000_usb_control(block, enable, |
| 464 | − AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | |
| 492 | + AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | |
| 465 | 493 | break; |
| 466 | 494 | case ALCHEMY_CPU_AU1200: |
| 467 | 495 | ret = au1200_usb_control(block, enable); |
| @@ -569,14 +597,18 @@ static struct syscore_ops alchemy_usb_pm_ops = { · 101 unmodified lines | ||
| 569 | 597 | |
| 570 | 598 | static int __init alchemy_usb_init(void) |
| 571 | 599 | { |
| 600 | + int ret = 0; | |
| 601 | + | |
| 572 | 602 | switch (alchemy_get_cputype()) { |
| 573 | 603 | case ALCHEMY_CPU_AU1000: |
| 574 | 604 | case ALCHEMY_CPU_AU1500: |
| 575 | 605 | case ALCHEMY_CPU_AU1100: |
| 576 | − au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | |
| 606 | + ret = au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, | |
| 607 | + AU1000_OHCICFG); | |
| 577 | 608 | break; |
| 578 | 609 | case ALCHEMY_CPU_AU1550: |
| 579 | − au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | |
| 610 | + ret = au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, | |
| 611 | + AU1550_OHCICFG); | |
| 580 | 612 | break; |
| 581 | 613 | case ALCHEMY_CPU_AU1200: |
| 582 | 614 | au1200_usb_init(); |
| @@ -586,8 +618,9 @@ static int __init alchemy_usb_init(void) · 3 unmodified lines | ||
| 586 | 618 | break; |
| 587 | 619 | } |
| 588 | 620 | |
| 589 | − register_syscore_ops(&alchemy_usb_pm_ops); | |
| 621 | + if (!ret) | |
| 622 | + register_syscore_ops(&alchemy_usb_pm_ops); | |
| 590 | 623 | |
| 591 | − return 0; | |
| 624 | + return ret; | |
| 592 | 625 | } |
| 593 | 626 | arch_initcall(alchemy_usb_init); |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | +#include <linux/clk.h> | |
| 22 | 23 | #include <linux/dma-mapping.h> |
| 23 | 24 | #include <linux/gpio.h> |
| 24 | 25 | #include <linux/init.h> |
| @@ -496,6 +497,7 @@ int __init db1000_dev_setup(void) · 471 unmodified lines | ||
| 496 | 497 | int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); |
| 497 | 498 | int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1; |
| 498 | 499 | unsigned long pfc; |
| 500 | + struct clk *c, *p; | |
| 499 | 501 | |
| 500 | 502 | if (board == BCSR_WHOAMI_DB1500) { |
| 501 | 503 | c0 = AU1500_GPIO2_INT; |
| @@ -518,14 +520,25 @@ int __init db1000_dev_setup(void) · 16 unmodified lines | ||
| 518 | 520 | gpio_direction_input(20); /* sd1 cd# */ |
| 519 | 521 | |
| 520 | 522 | /* spi_gpio on SSI0 pins */ |
| 521 | − pfc = __raw_readl((void __iomem *)SYS_PINFUNC); | |
| 523 | + pfc = alchemy_rdsys(AU1000_SYS_PINFUNC); | |
| 522 | 524 | pfc |= (1 << 0); /* SSI0 pins as GPIOs */ |
| 523 | − __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | |
| 524 | − wmb(); | |
| 525 | + alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); | |
| 525 | 526 | |
| 526 | 527 | spi_register_board_info(db1100_spi_info, |
| 527 | 528 | ARRAY_SIZE(db1100_spi_info)); |
| 528 | 529 | |
| 530 | + /* link LCD clock to AUXPLL */ | |
| 531 | + p = clk_get(NULL, "auxpll_clk"); | |
| 532 | + c = clk_get(NULL, "lcd_intclk"); | |
| 533 | + if (!IS_ERR(c) && !IS_ERR(p)) { | |
| 534 | + clk_set_parent(c, p); | |
| 535 | + clk_set_rate(c, clk_get_rate(p)); | |
| 536 | + } | |
| 537 | + if (!IS_ERR(c)) | |
| 538 | + clk_put(c); | |
| 539 | + if (!IS_ERR(p)) | |
| 540 | + clk_put(p); | |
| 541 | + | |
| 529 | 542 | platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); |
| 530 | 543 | platform_device_register(&db1100_spi_dev); |
| 531 | 544 | } else if (board == BCSR_WHOAMI_DB1000) { |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | +#include <linux/clk.h> | |
| 21 | 22 | #include <linux/dma-mapping.h> |
| 22 | 23 | #include <linux/gpio.h> |
| 23 | 24 | #include <linux/i2c.h> |
| @@ -129,7 +130,6 @@ static int __init db1200_detect_board(void) · 105 unmodified lines | ||
| 129 | 130 | |
| 130 | 131 | int __init db1200_board_setup(void) |
| 131 | 132 | { |
| 132 | − unsigned long freq0, clksrc, div, pfc; | |
| 133 | 133 | unsigned short whoami; |
| 134 | 134 | |
| 135 | 135 | if (db1200_detect_board()) |
| @@ -149,34 +149,6 @@ int __init db1200_board_setup(void) · 13 unmodified lines | ||
| 149 | 149 | " Board-ID %d Daughtercard ID %d\n", get_system_type(), |
| 150 | 150 | (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); |
| 151 | 151 | |
| 152 | − /* SMBus/SPI on PSC0, Audio on PSC1 */ | |
| 153 | − pfc = __raw_readl((void __iomem *)SYS_PINFUNC); | |
| 154 | − pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B); | |
| 155 | − pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3); | |
| 156 | − pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */ | |
| 157 | − __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | |
| 158 | − wmb(); | |
| 159 | − | |
| 160 | − /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from | |
| 161 | − * CPU clock; all other clock generators off/unused. | |
| 162 | − */ | |
| 163 | − div = (get_au1x00_speed() + 25000000) / 50000000; | |
| 164 | − if (div & 1) | |
| 165 | − div++; | |
| 166 | − div = ((div >> 1) - 1) & 0xff; | |
| 167 | − | |
| 168 | − freq0 = div << SYS_FC_FRDIV0_BIT; | |
| 169 | − __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0); | |
| 170 | − wmb(); | |
| 171 | − freq0 |= SYS_FC_FE0; /* enable F0 */ | |
| 172 | − __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0); | |
| 173 | − wmb(); | |
| 174 | − | |
| 175 | − /* psc0_intclk comes 1:1 from F0 */ | |
| 176 | − clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT; | |
| 177 | − __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC); | |
| 178 | − wmb(); | |
| 179 | − | |
| 180 | 152 | return 0; |
| 181 | 153 | } |
| 182 | 154 | |
| @@ -250,7 +222,7 @@ static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, · 67 unmodified lines | ||
| 250 | 222 | |
| 251 | 223 | static int au1200_nand_device_ready(struct mtd_info *mtd) |
| 252 | 224 | { |
| 253 | − return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | |
| 225 | + return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; | |
| 254 | 226 | } |
| 255 | 227 | |
| 256 | 228 | static struct mtd_partition db1200_nand_parts[] = { |
| @@ -847,6 +819,7 @@ int __init db1200_dev_setup(void) · 590 unmodified lines | ||
| 847 | 819 | unsigned long pfc; |
| 848 | 820 | unsigned short sw; |
| 849 | 821 | int swapped, bid; |
| 822 | + struct clk *c; | |
| 850 | 823 | |
| 851 | 824 | bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); |
| 852 | 825 | if ((bid == BCSR_WHOAMI_PB1200_DDR1) || |
| @@ -859,6 +832,24 @@ int __init db1200_dev_setup(void) · 6 unmodified lines | ||
| 859 | 832 | irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW); |
| 860 | 833 | bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); |
| 861 | 834 | |
| 835 | + /* SMBus/SPI on PSC0, Audio on PSC1 */ | |
| 836 | + pfc = alchemy_rdsys(AU1000_SYS_PINFUNC); | |
| 837 | + pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B); | |
| 838 | + pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3); | |
| 839 | + pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */ | |
| 840 | + alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); | |
| 841 | + | |
| 842 | + /* get 50MHz for I2C driver on PSC0 */ | |
| 843 | + c = clk_get(NULL, "psc0_intclk"); | |
| 844 | + if (!IS_ERR(c)) { | |
| 845 | + pfc = clk_round_rate(c, 50000000); | |
| 846 | + if ((pfc < 1) || (abs(50000000 - pfc) > 2500000)) | |
| 847 | + pr_warn("DB1200: cant get I2C close to 50MHz\n"); | |
| 848 | + else | |
| 849 | + clk_set_rate(c, pfc); | |
| 850 | + clk_put(c); | |
| 851 | + } | |
| 852 | + | |
| 862 | 853 | /* insert/eject pairs: one of both is always screaming. To avoid |
| 863 | 854 | * issues they must not be automatically enabled when initially |
| 864 | 855 | * requested. |
| @@ -886,7 +877,7 @@ int __init db1200_dev_setup(void) · 21 unmodified lines | ||
| 886 | 877 | * As a result, in SPI mode, OTG simply won't work (PSC0 uses |
| 887 | 878 | * it as an input pin which is pulled high on the boards). |
| 888 | 879 | */ |
| 889 | − pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A; | |
| 880 | + pfc = alchemy_rdsys(AU1000_SYS_PINFUNC) & ~SYS_PINFUNC_P0A; | |
| 890 | 881 | |
| 891 | 882 | /* switch off OTG VBUS supply */ |
| 892 | 883 | gpio_request(215, "otg-vbus"); |
| @@ -912,8 +903,7 @@ int __init db1200_dev_setup(void) · 19 unmodified lines | ||
| 912 | 903 | printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n"); |
| 913 | 904 | printk(KERN_INFO " OTG port VBUS supply disabled\n"); |
| 914 | 905 | } |
| 915 | − __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | |
| 916 | − wmb(); | |
| 906 | + alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); | |
| 917 | 907 | |
| 918 | 908 | /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S! |
| 919 | 909 | * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S |
| @@ -932,6 +922,11 @@ int __init db1200_dev_setup(void) · 12 unmodified lines | ||
| 932 | 922 | } |
| 933 | 923 | |
| 934 | 924 | /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ |
| 925 | + c = clk_get(NULL, "psc1_intclk"); | |
| 926 | + if (!IS_ERR(c)) { | |
| 927 | + clk_prepare_enable(c); | |
| 928 | + clk_put(c); | |
| 929 | + } | |
| 935 | 930 | __raw_writel(PSC_SEL_CLK_SERCLK, |
| 936 | 931 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); |
| 937 | 932 | wmb(); |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * (c) 2009 Manuel Lauss <manuel.lauss@googlemail.com> |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <linux/clk.h> | |
| 7 | 8 | #include <linux/dma-mapping.h> |
| 8 | 9 | #include <linux/gpio.h> |
| 9 | 10 | #include <linux/gpio_keys.h> |
| @@ -169,7 +170,7 @@ static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, · 159 unmodified lines | ||
| 169 | 170 | |
| 170 | 171 | static int au1300_nand_device_ready(struct mtd_info *mtd) |
| 171 | 172 | { |
| 172 | − return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | |
| 173 | + return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; | |
| 173 | 174 | } |
| 174 | 175 | |
| 175 | 176 | static struct mtd_partition db1300_nand_parts[] = { |
| @@ -731,6 +732,7 @@ static struct platform_device *db1300_dev[] __initdata = { · 555 unmodified lines | ||
| 731 | 732 | int __init db1300_dev_setup(void) |
| 732 | 733 | { |
| 733 | 734 | int swapped, cpldirq; |
| 735 | + struct clk *c; | |
| 734 | 736 | |
| 735 | 737 | /* setup CPLD IRQ muxer */ |
| 736 | 738 | cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1); |
| @@ -761,6 +763,11 @@ int __init db1300_dev_setup(void) · 24 unmodified lines | ||
| 761 | 763 | (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); |
| 762 | 764 | wmb(); |
| 763 | 765 | /* I2C uses internal 48MHz EXTCLK1 */ |
| 766 | + c = clk_get(NULL, "psc3_intclk"); | |
| 767 | + if (!IS_ERR(c)) { | |
| 768 | + clk_prepare_enable(c); | |
| 769 | + clk_put(c); | |
| 770 | + } | |
| 764 | 771 | __raw_writel(PSC_SEL_CLK_INTCLK, |
| 765 | 772 | (void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); |
| 766 | 773 | wmb(); |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <linux/clk.h> | |
| 7 | 8 | #include <linux/dma-mapping.h> |
| 8 | 9 | #include <linux/gpio.h> |
| 9 | 10 | #include <linux/i2c.h> |
| @@ -31,16 +32,16 @@ · 21 unmodified lines | ||
| 31 | 32 | static void __init db1550_hw_setup(void) |
| 32 | 33 | { |
| 33 | 34 | void __iomem *base; |
| 35 | + unsigned long v; | |
| 34 | 36 | |
| 35 | 37 | /* complete SPI setup: link psc0_intclk to a 48MHz source, |
| 36 | 38 | * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC |
| 37 | 39 | * for AC97 on PB1550. |
| 38 | 40 | */ |
| 39 | − base = (void __iomem *)SYS_CLKSRC; | |
| 40 | − __raw_writel(__raw_readl(base) | 0x000001e0, base); | |
| 41 | − base = (void __iomem *)SYS_PINFUNC; | |
| 42 | − __raw_writel(__raw_readl(base) | 1 | SYS_PF_PSC1_S1, base); | |
| 43 | − wmb(); | |
| 41 | + v = alchemy_rdsys(AU1000_SYS_CLKSRC); | |
| 42 | + alchemy_wrsys(v | 0x000001e0, AU1000_SYS_CLKSRC); | |
| 43 | + v = alchemy_rdsys(AU1000_SYS_PINFUNC); | |
| 44 | + alchemy_wrsys(v | 1 | SYS_PF_PSC1_S1, AU1000_SYS_PINFUNC); | |
| 44 | 45 | |
| 45 | 46 | /* reset the AC97 codec now, the reset time in the psc-ac97 driver |
| 46 | 47 | * is apparently too short although it's ridiculous as it is. |
| @@ -151,7 +152,7 @@ static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, · 104 unmodified lines | ||
| 151 | 152 | |
| 152 | 153 | static int au1550_nand_device_ready(struct mtd_info *mtd) |
| 153 | 154 | { |
| 154 | − return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | |
| 155 | + return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; | |
| 155 | 156 | } |
| 156 | 157 | |
| 157 | 158 | static struct mtd_partition db1550_nand_parts[] = { |
| @@ -217,7 +218,7 @@ static struct platform_device pb1550_nand_dev = { · 59 unmodified lines | ||
| 217 | 218 | |
| 218 | 219 | static void __init pb1550_nand_setup(void) |
| 219 | 220 | { |
| 220 | − int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | | |
| 221 | + int boot_swapboot = (alchemy_rdsmem(AU1000_MEM_STSTAT) & (0x7 << 1)) | | |
| 221 | 222 | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); |
| 222 | 223 | |
| 223 | 224 | gpio_direction_input(206); /* de-assert NAND CS# */ |
| @@ -574,6 +575,7 @@ static void __init pb1550_devices(void) · 350 unmodified lines | ||
| 574 | 575 | int __init db1550_dev_setup(void) |
| 575 | 576 | { |
| 576 | 577 | int swapped, id; |
| 578 | + struct clk *c; | |
| 577 | 579 | |
| 578 | 580 | id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550); |
| 579 | 581 | |
| @@ -582,6 +584,17 @@ int __init db1550_dev_setup(void) · 2 unmodified lines | ||
| 582 | 584 | spi_register_board_info(db1550_spi_devs, |
| 583 | 585 | ARRAY_SIZE(db1550_i2c_devs)); |
| 584 | 586 | |
| 587 | + c = clk_get(NULL, "psc0_intclk"); | |
| 588 | + if (!IS_ERR(c)) { | |
| 589 | + clk_prepare_enable(c); | |
| 590 | + clk_put(c); | |
| 591 | + } | |
| 592 | + c = clk_get(NULL, "psc2_intclk"); | |
| 593 | + if (!IS_ERR(c)) { | |
| 594 | + clk_prepare_enable(c); | |
| 595 | + clk_put(c); | |
| 596 | + } | |
| 597 | + | |
| 585 | 598 | /* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */ |
| 586 | 599 | __raw_writel(PSC_SEL_CLK_SERCLK, |
| 587 | 600 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); |
| @@ -45,23 +45,20 @@ static int db1x_pm_enter(suspend_state_t state) · 44 unmodified lines | ||
| 45 | 45 | alchemy_gpio1_input_enable(); |
| 46 | 46 | |
| 47 | 47 | /* clear and setup wake cause and source */ |
| 48 | − au_writel(0, SYS_WAKEMSK); | |
| 49 | − au_sync(); | |
| 50 | − au_writel(0, SYS_WAKESRC); | |
| 51 | − au_sync(); | |
| 48 | + alchemy_wrsys(0, AU1000_SYS_WAKEMSK); | |
| 49 | + alchemy_wrsys(0, AU1000_SYS_WAKESRC); | |
| 52 | 50 | |
| 53 | − au_writel(db1x_pm_wakemsk, SYS_WAKEMSK); | |
| 54 | − au_sync(); | |
| 51 | + alchemy_wrsys(db1x_pm_wakemsk, AU1000_SYS_WAKEMSK); | |
| 55 | 52 | |
| 56 | 53 | /* setup 1Hz-timer-based wakeup: wait for reg access */ |
| 57 | − while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) | |
| 54 | + while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M20) | |
| 58 | 55 | asm volatile ("nop"); |
| 59 | 56 | |
| 60 | − au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2); | |
| 61 | − au_sync(); | |
| 57 | + alchemy_wrsys(alchemy_rdsys(AU1000_SYS_TOYREAD) + db1x_pm_sleep_secs, | |
| 58 | + AU1000_SYS_TOYMATCH2); | |
| 62 | 59 | |
| 63 | 60 | /* wait for value to really hit the register */ |
| 64 | − while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) | |
| 61 | + while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M20) | |
| 65 | 62 | asm volatile ("nop"); |
| 66 | 63 | |
| 67 | 64 | /* ...and now the sandman can come! */ |
| @@ -102,12 +99,10 @@ static void db1x_pm_end(void) · 34 unmodified lines | ||
| 102 | 99 | /* read and store wakeup source, the clear the register. To |
| 103 | 100 | * be able to clear it, WAKEMSK must be cleared first. |
| 104 | 101 | */ |
| 105 | − db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC); | |
| 106 | − | |
| 107 | − au_writel(0, SYS_WAKEMSK); | |
| 108 | − au_writel(0, SYS_WAKESRC); | |
| 109 | − au_sync(); | |
| 102 | + db1x_pm_last_wakesrc = alchemy_rdsys(AU1000_SYS_WAKESRC); | |
| 110 | 103 | |
| 104 | + alchemy_wrsys(0, AU1000_SYS_WAKEMSK); | |
| 105 | + alchemy_wrsys(0, AU1000_SYS_WAKESRC); | |
| 111 | 106 | } |
| 112 | 107 | |
| 113 | 108 | static const struct platform_suspend_ops db1x_pm_ops = { |
| @@ -242,17 +237,13 @@ static int __init pm_init(void) · 128 unmodified lines | ||
| 242 | 237 | * for confirmation since there's plenty of time from here to |
| 243 | 238 | * the next suspend cycle. |
| 244 | 239 | */ |
| 245 | − if (au_readl(SYS_TOYTRIM) != 32767) { | |
| 246 | − au_writel(32767, SYS_TOYTRIM); | |
| 247 | − au_sync(); | |
| 248 | − } | |
| 240 | + if (alchemy_rdsys(AU1000_SYS_TOYTRIM) != 32767) | |
| 241 | + alchemy_wrsys(32767, AU1000_SYS_TOYTRIM); | |
| 249 | 242 | |
| 250 | − db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC); | |
| 243 | + db1x_pm_last_wakesrc = alchemy_rdsys(AU1000_SYS_WAKESRC); | |
| 251 | 244 | |
| 252 | − au_writel(0, SYS_WAKESRC); | |
| 253 | − au_sync(); | |
| 254 | − au_writel(0, SYS_WAKEMSK); | |
| 255 | − au_sync(); | |
| 245 | + alchemy_wrsys(0, AU1000_SYS_WAKESRC); | |
| 246 | + alchemy_wrsys(0, AU1000_SYS_WAKEMSK); | |
| 256 | 247 | |
| 257 | 248 | suspend_set_ops(&db1x_pm_ops); |
| 258 | 249 | |
| @@ -11,8 +11,6 @@ config BCM47XX_SSB · 10 unmodified lines | ||
| 11 | 11 | select SSB_DRIVER_PCICORE if PCI |
| 12 | 12 | select SSB_PCICORE_HOSTMODE if PCI |
| 13 | 13 | select SSB_DRIVER_GPIO |
| 14 | − select GPIOLIB | |
| 15 | − select LEDS_GPIO_REGISTER | |
| 16 | 14 | default y |
| 17 | 15 | help |
| 18 | 16 | Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. |
| @@ -22,6 +20,7 @@ config BCM47XX_SSB · 3 unmodified lines | ||
| 22 | 20 | config BCM47XX_BCMA |
| 23 | 21 | bool "BCMA Support for Broadcom BCM47XX" |
| 24 | 22 | select SYS_HAS_CPU_MIPS32_R2 |
| 23 | + select SYS_SUPPORTS_HIGHMEM | |
| 25 | 24 | select CPU_MIPSR2_IRQ_VI |
| 26 | 25 | select BCMA |
| 27 | 26 | select BCMA_HOST_SOC |
| @@ -29,8 +28,6 @@ config BCM47XX_BCMA · 1 unmodified line | ||
| 29 | 28 | select BCMA_HOST_PCI if PCI |
| 30 | 29 | select BCMA_DRIVER_PCI_HOSTMODE if PCI |
| 31 | 30 | select BCMA_DRIVER_GPIO |
| 32 | − select GPIOLIB | |
| 33 | − select LEDS_GPIO_REGISTER | |
| 34 | 31 | default y |
| 35 | 32 | help |
| 36 | 33 | Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus. |
| @@ -3,6 +3,9 @@ · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | #include <linux/kernel.h> |
| 5 | 5 | |
| 6 | +/* prom.c */ | |
| 7 | +void __init bcm47xx_prom_highmem_init(void); | |
| 8 | + | |
| 6 | 9 | /* buttons.c */ |
| 7 | 10 | int __init bcm47xx_buttons_register(void); |
| 8 | 11 | |
| @@ -58,6 +58,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = · 57 unmodified lines | ||
| 58 | 58 | static const |
| 59 | 59 | struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = { |
| 60 | 60 | {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"}, |
| 61 | + {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RTN10D"}, | |
| 61 | 62 | {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"}, |
| 62 | 63 | {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"}, |
| 63 | 64 | {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"}, |
| @@ -80,6 +81,14 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initcons · 16 unmodified lines | ||
| 80 | 81 | { {0}, NULL}, |
| 81 | 82 | }; |
| 82 | 83 | |
| 84 | +/* hardware_version, boardnum */ | |
| 85 | +static const | |
| 86 | +struct bcm47xx_board_type_list2 bcm47xx_board_list_hw_version_num[] __initconst = { | |
| 87 | + {{BCM47XX_BOARD_MICROSOFT_MN700, "Microsoft MN-700"}, "WL500-", "mn700"}, | |
| 88 | + {{BCM47XX_BOARD_ASUS_WL500G, "Asus WL500G"}, "WL500-", "asusX"}, | |
| 89 | + { {0}, NULL}, | |
| 90 | +}; | |
| 91 | + | |
| 83 | 92 | /* productid */ |
| 84 | 93 | static const |
| 85 | 94 | struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = { |
| @@ -98,7 +107,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = { · 12 unmodified lines | ||
| 98 | 107 | /* ModelId */ |
| 99 | 108 | static const |
| 100 | 109 | struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = { |
| 101 | − {{BCM47XX_BOARD_DELL_TM2300, "Dell WX-5565"}, "WX-5565"}, | |
| 110 | + {{BCM47XX_BOARD_DELL_TM2300, "Dell TrueMobile 2300"}, "WX-5565"}, | |
| 102 | 111 | {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"}, |
| 103 | 112 | {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"}, |
| 104 | 113 | {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"}, |
| @@ -180,9 +189,9 @@ struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = { · 75 unmodified lines | ||
| 180 | 189 | {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"}, |
| 181 | 190 | {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"}, |
| 182 | 191 | {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"}, |
| 183 | − {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"}, | |
| 184 | − {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"}, | |
| 185 | − {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"}, | |
| 192 | + {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"}, | |
| 193 | + {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"}, | |
| 194 | + {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"}, | |
| 186 | 195 | { {0}, NULL}, |
| 187 | 196 | }; |
| 188 | 197 | |
| @@ -237,6 +246,15 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void) · 48 unmodified lines | ||
| 237 | 246 | } |
| 238 | 247 | } |
| 239 | 248 | |
| 249 | + if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 && | |
| 250 | + bcm47xx_nvram_getenv("boardtype", buf2, sizeof(buf2)) >= 0) { | |
| 251 | + for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) { | |
| 252 | + if (!strstarts(buf1, e2->value1) && | |
| 253 | + !strcmp(buf2, e2->value2)) | |
| 254 | + return &e2->board; | |
| 255 | + } | |
| 256 | + } | |
| 257 | + | |
| 240 | 258 | if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) { |
| 241 | 259 | for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) { |
| 242 | 260 | if (!strcmp(buf1, e1->value1)) |
| @@ -55,6 +55,11 @@ bcm47xx_buttons_asus_wl330ge[] __initconst = { · 54 unmodified lines | ||
| 55 | 55 | BCM47XX_GPIO_KEY(2, KEY_RESTART), |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | +static const struct gpio_keys_button | |
| 59 | +bcm47xx_buttons_asus_wl500g[] __initconst = { | |
| 60 | + BCM47XX_GPIO_KEY(6, KEY_RESTART), | |
| 61 | +}; | |
| 62 | + | |
| 58 | 63 | static const struct gpio_keys_button |
| 59 | 64 | bcm47xx_buttons_asus_wl500gd[] __initconst = { |
| 60 | 65 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
| @@ -265,7 +270,7 @@ bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = { · 204 unmodified lines | ||
| 265 | 270 | }; |
| 266 | 271 | |
| 267 | 272 | static const struct gpio_keys_button |
| 268 | −bcm47xx_buttons_linksys_wrt54gsv1[] __initconst = { | |
| 273 | +bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = { | |
| 269 | 274 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), |
| 270 | 275 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
| 271 | 276 | }; |
| @@ -288,6 +293,13 @@ bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = { · 16 unmodified lines | ||
| 288 | 293 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
| 289 | 294 | }; |
| 290 | 295 | |
| 296 | +/* Microsoft */ | |
| 297 | + | |
| 298 | +static const struct gpio_keys_button | |
| 299 | +bcm47xx_buttons_microsoft_nm700[] __initconst = { | |
| 300 | + BCM47XX_GPIO_KEY(7, KEY_RESTART), | |
| 301 | +}; | |
| 302 | + | |
| 291 | 303 | /* Motorola */ |
| 292 | 304 | |
| 293 | 305 | static const struct gpio_keys_button |
| @@ -328,6 +340,12 @@ bcm47xx_buttons_netgear_wndr4500v1[] __initconst = { · 34 unmodified lines | ||
| 328 | 340 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
| 329 | 341 | }; |
| 330 | 342 | |
| 343 | +static const struct gpio_keys_button | |
| 344 | +bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = { | |
| 345 | + BCM47XX_GPIO_KEY(4, KEY_RESTART), | |
| 346 | + BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), | |
| 347 | +}; | |
| 348 | + | |
| 331 | 349 | static const struct gpio_keys_button |
| 332 | 350 | bcm47xx_buttons_netgear_wnr834bv2[] __initconst = { |
| 333 | 351 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
| @@ -395,6 +413,9 @@ int __init bcm47xx_buttons_register(void) · 61 unmodified lines | ||
| 395 | 413 | case BCM47XX_BOARD_ASUS_WL330GE: |
| 396 | 414 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge); |
| 397 | 415 | break; |
| 416 | + case BCM47XX_BOARD_ASUS_WL500G: | |
| 417 | + err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500g); | |
| 418 | + break; | |
| 398 | 419 | case BCM47XX_BOARD_ASUS_WL500GD: |
| 399 | 420 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd); |
| 400 | 421 | break; |
| @@ -501,12 +522,14 @@ int __init bcm47xx_buttons_register(void) · 100 unmodified lines | ||
| 501 | 522 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: |
| 502 | 523 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1); |
| 503 | 524 | break; |
| 504 | − case BCM47XX_BOARD_LINKSYS_WRT54G: | |
| 505 | − err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54gsv1); | |
| 506 | − break; | |
| 507 | 525 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: |
| 508 | 526 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2); |
| 509 | 527 | break; |
| 528 | + case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101: | |
| 529 | + case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467: | |
| 530 | + case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708: | |
| 531 | + err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g_generic); | |
| 532 | + break; | |
| 510 | 533 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: |
| 511 | 534 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1); |
| 512 | 535 | break; |
| @@ -517,6 +540,10 @@ int __init bcm47xx_buttons_register(void) · 4 unmodified lines | ||
| 517 | 540 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs); |
| 518 | 541 | break; |
| 519 | 542 | |
| 543 | + case BCM47XX_BOARD_MICROSOFT_MN700: | |
| 544 | + err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700); | |
| 545 | + break; | |
| 546 | + | |
| 520 | 547 | case BCM47XX_BOARD_MOTOROLA_WE800G: |
| 521 | 548 | err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g); |
| 522 | 549 | break; |
| @@ -536,6 +563,9 @@ int __init bcm47xx_buttons_register(void) · 13 unmodified lines | ||
| 536 | 563 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: |
| 537 | 564 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1); |
| 538 | 565 | break; |
| 566 | + case BCM47XX_BOARD_NETGEAR_WNR3500L: | |
| 567 | + err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv1); | |
| 568 | + break; | |
| 539 | 569 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: |
| 540 | 570 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2); |
| 541 | 571 | break; |
| @@ -34,6 +34,15 @@ bcm47xx_leds_asus_rtn12[] __initconst = { · 33 unmodified lines | ||
| 34 | 34 | BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | +static const struct gpio_led | |
| 38 | +bcm47xx_leds_asus_rtn15u[] __initconst = { | |
| 39 | + /* TODO: Add "wlan" LED */ | |
| 40 | + BCM47XX_GPIO_LED(3, "blue", "wan", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 41 | + BCM47XX_GPIO_LED(4, "blue", "lan", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 42 | + BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | |
| 43 | + BCM47XX_GPIO_LED(9, "blue", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | |
| 44 | +}; | |
| 45 | + | |
| 37 | 46 | static const struct gpio_led |
| 38 | 47 | bcm47xx_leds_asus_rtn16[] __initconst = { |
| 39 | 48 | BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), |
| @@ -42,8 +51,8 @@ bcm47xx_leds_asus_rtn16[] __initconst = { · 2 unmodified lines | ||
| 42 | 51 | |
| 43 | 52 | static const struct gpio_led |
| 44 | 53 | bcm47xx_leds_asus_rtn66u[] __initconst = { |
| 45 | − BCM47XX_GPIO_LED(12, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | |
| 46 | − BCM47XX_GPIO_LED(15, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 54 | + BCM47XX_GPIO_LED(12, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | |
| 55 | + BCM47XX_GPIO_LED(15, "blue", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 47 | 56 | }; |
| 48 | 57 | |
| 49 | 58 | static const struct gpio_led |
| @@ -63,6 +72,11 @@ bcm47xx_leds_asus_wl330ge[] __initconst = { · 13 unmodified lines | ||
| 63 | 72 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), |
| 64 | 73 | }; |
| 65 | 74 | |
| 75 | +static const struct gpio_led | |
| 76 | +bcm47xx_leds_asus_wl500g[] __initconst = { | |
| 77 | + BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | |
| 78 | +}; | |
| 79 | + | |
| 66 | 80 | static const struct gpio_led |
| 67 | 81 | bcm47xx_leds_asus_wl500gd[] __initconst = { |
| 68 | 82 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), |
| @@ -216,8 +230,8 @@ bcm47xx_leds_linksys_e1000v1[] __initconst = { · 147 unmodified lines | ||
| 216 | 230 | |
| 217 | 231 | static const struct gpio_led |
| 218 | 232 | bcm47xx_leds_linksys_e1000v21[] __initconst = { |
| 219 | − BCM47XX_GPIO_LED(5, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | |
| 220 | − BCM47XX_GPIO_LED(6, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | |
| 233 | + BCM47XX_GPIO_LED(5, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | |
| 234 | + BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | |
| 221 | 235 | BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), |
| 222 | 236 | BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), |
| 223 | 237 | }; |
| @@ -292,7 +306,7 @@ bcm47xx_leds_linksys_wrt310nv1[] __initconst = { · 68 unmodified lines | ||
| 292 | 306 | }; |
| 293 | 307 | |
| 294 | 308 | static const struct gpio_led |
| 295 | −bcm47xx_leds_linksys_wrt54gsv1[] __initconst = { | |
| 309 | +bcm47xx_leds_linksys_wrt54g_generic[] __initconst = { | |
| 296 | 310 | BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), |
| 297 | 311 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), |
| 298 | 312 | BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), |
| @@ -306,6 +320,24 @@ bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = { · 7 unmodified lines | ||
| 306 | 320 | BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF), |
| 307 | 321 | }; |
| 308 | 322 | |
| 323 | +/* Verified on: WRT54GS V1.0 */ | |
| 324 | +static const struct gpio_led | |
| 325 | +bcm47xx_leds_linksys_wrt54g_type_0101[] __initconst = { | |
| 326 | + BCM47XX_GPIO_LED(0, "green", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | |
| 327 | + BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | |
| 328 | + BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 329 | +}; | |
| 330 | + | |
| 331 | +/* Verified on: WRT54GL V1.1 */ | |
| 332 | +static const struct gpio_led | |
| 333 | +bcm47xx_leds_linksys_wrt54g_type_0467[] __initconst = { | |
| 334 | + BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 335 | + BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | |
| 336 | + BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 337 | + BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 338 | + BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 339 | +}; | |
| 340 | + | |
| 309 | 341 | static const struct gpio_led |
| 310 | 342 | bcm47xx_leds_linksys_wrt610nv1[] __initconst = { |
| 311 | 343 | BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), |
| @@ -325,11 +357,17 @@ bcm47xx_leds_linksys_wrt610nv2[] __initconst = { · 13 unmodified lines | ||
| 325 | 357 | |
| 326 | 358 | static const struct gpio_led |
| 327 | 359 | bcm47xx_leds_linksys_wrtsl54gs[] __initconst = { |
| 328 | − BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 329 | − BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | |
| 330 | − BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 331 | − BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 332 | − BCM47XX_GPIO_LED(7, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 360 | + BCM47XX_GPIO_LED(0, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 361 | + BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | |
| 362 | + BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 363 | + BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 364 | +}; | |
| 365 | + | |
| 366 | +/* Microsoft */ | |
| 367 | + | |
| 368 | +static const struct gpio_led | |
| 369 | +bcm47xx_leds_microsoft_nm700[] __initconst = { | |
| 370 | + BCM47XX_GPIO_LED(6, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | |
| 333 | 371 | }; |
| 334 | 372 | |
| 335 | 373 | /* Motorola */ |
| @@ -376,6 +414,15 @@ bcm47xx_leds_netgear_wndr4500v1[] __initconst = { · 40 unmodified lines | ||
| 376 | 414 | BCM47XX_GPIO_LED(14, "green", "usb2", 1, LEDS_GPIO_DEFSTATE_OFF), |
| 377 | 415 | }; |
| 378 | 416 | |
| 417 | +static const struct gpio_led | |
| 418 | +bcm47xx_leds_netgear_wnr3500lv1[] __initconst = { | |
| 419 | + BCM47XX_GPIO_LED(0, "blue", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 420 | + BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 421 | + BCM47XX_GPIO_LED(2, "green", "wan", 1, LEDS_GPIO_DEFSTATE_OFF), | |
| 422 | + BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | |
| 423 | + BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF), | |
| 424 | +}; | |
| 425 | + | |
| 379 | 426 | static const struct gpio_led |
| 380 | 427 | bcm47xx_leds_netgear_wnr834bv2[] __initconst = { |
| 381 | 428 | BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), |
| @@ -417,6 +464,9 @@ void __init bcm47xx_leds_register(void) · 35 unmodified lines | ||
| 417 | 464 | case BCM47XX_BOARD_ASUS_RTN12: |
| 418 | 465 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12); |
| 419 | 466 | break; |
| 467 | + case BCM47XX_BOARD_ASUS_RTN15U: | |
| 468 | + bcm47xx_set_pdata(bcm47xx_leds_asus_rtn15u); | |
| 469 | + break; | |
| 420 | 470 | case BCM47XX_BOARD_ASUS_RTN16: |
| 421 | 471 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16); |
| 422 | 472 | break; |
| @@ -432,6 +482,9 @@ void __init bcm47xx_leds_register(void) · 9 unmodified lines | ||
| 432 | 482 | case BCM47XX_BOARD_ASUS_WL330GE: |
| 433 | 483 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge); |
| 434 | 484 | break; |
| 485 | + case BCM47XX_BOARD_ASUS_WL500G: | |
| 486 | + bcm47xx_set_pdata(bcm47xx_leds_asus_wl500g); | |
| 487 | + break; | |
| 435 | 488 | case BCM47XX_BOARD_ASUS_WL500GD: |
| 436 | 489 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd); |
| 437 | 490 | break; |
| @@ -538,12 +591,18 @@ void __init bcm47xx_leds_register(void) · 100 unmodified lines | ||
| 538 | 591 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: |
| 539 | 592 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1); |
| 540 | 593 | break; |
| 541 | − case BCM47XX_BOARD_LINKSYS_WRT54G: | |
| 542 | − bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54gsv1); | |
| 543 | − break; | |
| 544 | 594 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: |
| 545 | 595 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2); |
| 546 | 596 | break; |
| 597 | + case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101: | |
| 598 | + bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0101); | |
| 599 | + break; | |
| 600 | + case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467: | |
| 601 | + bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0467); | |
| 602 | + break; | |
| 603 | + case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708: | |
| 604 | + bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_generic); | |
| 605 | + break; | |
| 547 | 606 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: |
| 548 | 607 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1); |
| 549 | 608 | break; |
| @@ -554,6 +613,10 @@ void __init bcm47xx_leds_register(void) · 4 unmodified lines | ||
| 554 | 613 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs); |
| 555 | 614 | break; |
| 556 | 615 | |
| 616 | + case BCM47XX_BOARD_MICROSOFT_MN700: | |
| 617 | + bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700); | |
| 618 | + break; | |
| 619 | + | |
| 557 | 620 | case BCM47XX_BOARD_MOTOROLA_WE800G: |
| 558 | 621 | bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g); |
| 559 | 622 | break; |
| @@ -570,6 +633,9 @@ void __init bcm47xx_leds_register(void) · 10 unmodified lines | ||
| 570 | 633 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: |
| 571 | 634 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1); |
| 572 | 635 | break; |
| 636 | + case BCM47XX_BOARD_NETGEAR_WNR3500L: | |
| 637 | + bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv1); | |
| 638 | + break; | |
| 573 | 639 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: |
| 574 | 640 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2); |
| 575 | 641 | break; |
| @@ -51,6 +51,8 @@ __init void bcm47xx_set_system_type(u16 chip_id) · 50 unmodified lines | ||
| 51 | 51 | chip_id); |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | +static unsigned long lowmem __initdata; | |
| 55 | + | |
| 54 | 56 | static __init void prom_init_mem(void) |
| 55 | 57 | { |
| 56 | 58 | unsigned long mem; |
| @@ -87,6 +89,7 @@ static __init void prom_init_mem(void) · 30 unmodified lines | ||
| 87 | 89 | if (!memcmp(prom_init, prom_init + mem, 32)) |
| 88 | 90 | break; |
| 89 | 91 | } |
| 92 | + lowmem = mem; | |
| 90 | 93 | |
| 91 | 94 | /* Ignoring the last page when ddr size is 128M. Cached |
| 92 | 95 | * accesses to last page is causing the processor to prefetch |
| @@ -95,7 +98,6 @@ static __init void prom_init_mem(void) · 2 unmodified lines | ||
| 95 | 98 | */ |
| 96 | 99 | if (c->cputype == CPU_74K && (mem == (128 << 20))) |
| 97 | 100 | mem -= 0x1000; |
| 98 | − | |
| 99 | 101 | add_memory_region(0, mem, BOOT_MEM_RAM); |
| 100 | 102 | } |
| 101 | 103 | |
| @@ -114,3 +116,67 @@ void __init prom_init(void) · 12 unmodified lines | ||
| 114 | 116 | void __init prom_free_prom_memory(void) |
| 115 | 117 | { |
| 116 | 118 | } |
| 119 | + | |
| 120 | +#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) | |
| 121 | + | |
| 122 | +#define EXTVBASE 0xc0000000 | |
| 123 | +#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1) | |
| 124 | + | |
| 125 | +#include <asm/tlbflush.h> | |
| 126 | + | |
| 127 | +/* Stripped version of tlb_init, with the call to build_tlb_refill_handler | |
| 128 | + * dropped. Calling it at this stage causes a hang. | |
| 129 | + */ | |
| 130 | +void __cpuinit early_tlb_init(void) | |
| 131 | +{ | |
| 132 | + write_c0_pagemask(PM_DEFAULT_MASK); | |
| 133 | + write_c0_wired(0); | |
| 134 | + temp_tlb_entry = current_cpu_data.tlbsize - 1; | |
| 135 | + local_flush_tlb_all(); | |
| 136 | +} | |
| 137 | + | |
| 138 | +void __init bcm47xx_prom_highmem_init(void) | |
| 139 | +{ | |
| 140 | + unsigned long off = (unsigned long)prom_init; | |
| 141 | + unsigned long extmem = 0; | |
| 142 | + bool highmem_region = false; | |
| 143 | + | |
| 144 | + if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA)) | |
| 145 | + return; | |
| 146 | + | |
| 147 | + if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706) | |
| 148 | + highmem_region = true; | |
| 149 | + | |
| 150 | + if (lowmem != 128 << 20 || !highmem_region) | |
| 151 | + return; | |
| 152 | + | |
| 153 | + early_tlb_init(); | |
| 154 | + | |
| 155 | + /* Add one temporary TLB entry to map SDRAM Region 2. | |
| 156 | + * Physical Virtual | |
| 157 | + * 0x80000000 0xc0000000 (1st: 256MB) | |
| 158 | + * 0x90000000 0xd0000000 (2nd: 256MB) | |
| 159 | + */ | |
| 160 | + add_temporary_entry(ENTRYLO(0x80000000), | |
| 161 | + ENTRYLO(0x80000000 + (256 << 20)), | |
| 162 | + EXTVBASE, PM_256M); | |
| 163 | + | |
| 164 | + off = EXTVBASE + __pa(off); | |
| 165 | + for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { | |
| 166 | + if (!memcmp(prom_init, (void *)(off + extmem), 16)) | |
| 167 | + break; | |
| 168 | + } | |
| 169 | + extmem -= lowmem; | |
| 170 | + | |
| 171 | + early_tlb_init(); | |
| 172 | + | |
| 173 | + if (!extmem) | |
| 174 | + return; | |
| 175 | + | |
| 176 | + pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n", | |
| 177 | + extmem >> 20); | |
| 178 | + | |
| 179 | + /* TODO: Register extra memory */ | |
| 180 | +} | |
| 181 | + | |
| 182 | +#endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */ | |
| @@ -59,12 +59,12 @@ static void bcm47xx_machine_restart(char *command) · 58 unmodified lines | ||
| 59 | 59 | switch (bcm47xx_bus_type) { |
| 60 | 60 | #ifdef CONFIG_BCM47XX_SSB |
| 61 | 61 | case BCM47XX_BUS_TYPE_SSB: |
| 62 | − ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1); | |
| 62 | + ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 3); | |
| 63 | 63 | break; |
| 64 | 64 | #endif |
| 65 | 65 | #ifdef CONFIG_BCM47XX_BCMA |
| 66 | 66 | case BCM47XX_BUS_TYPE_BCMA: |
| 67 | − bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1); | |
| 67 | + bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 3); | |
| 68 | 68 | break; |
| 69 | 69 | #endif |
| 70 | 70 | } |
| @@ -218,6 +218,9 @@ void __init plat_mem_setup(void) · 147 unmodified lines | ||
| 218 | 218 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; |
| 219 | 219 | bcm47xx_register_bcma(); |
| 220 | 220 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); |
| 221 | +#ifdef CONFIG_HIGHMEM | |
| 222 | + bcm47xx_prom_highmem_init(); | |
| 223 | +#endif | |
| 221 | 224 | #endif |
| 222 | 225 | } else { |
| 223 | 226 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); |
| @@ -28,6 +28,8 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #include <bcm47xx.h> |
| 30 | 30 | #include <bcm47xx_nvram.h> |
| 31 | +#include <linux/if_ether.h> | |
| 32 | +#include <linux/etherdevice.h> | |
| 31 | 33 | |
| 32 | 34 | static void create_key(const char *prefix, const char *postfix, |
| 33 | 35 | const char *name, char *buf, int len) |
| @@ -631,6 +633,33 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, · 597 unmodified lines | ||
| 631 | 633 | } |
| 632 | 634 | } |
| 633 | 635 | |
| 636 | +static bool bcm47xx_is_valid_mac(u8 *mac) | |
| 637 | +{ | |
| 638 | + return mac && !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c); | |
| 639 | +} | |
| 640 | + | |
| 641 | +static int bcm47xx_increase_mac_addr(u8 *mac, u8 num) | |
| 642 | +{ | |
| 643 | + u8 *oui = mac + ETH_ALEN/2 - 1; | |
| 644 | + u8 *p = mac + ETH_ALEN - 1; | |
| 645 | + | |
| 646 | + do { | |
| 647 | + (*p) += num; | |
| 648 | + if (*p > num) | |
| 649 | + break; | |
| 650 | + p--; | |
| 651 | + num = 1; | |
| 652 | + } while (p != oui); | |
| 653 | + | |
| 654 | + if (p == oui) { | |
| 655 | + pr_err("unable to fetch mac address\n"); | |
| 656 | + return -ENOENT; | |
| 657 | + } | |
| 658 | + return 0; | |
| 659 | +} | |
| 660 | + | |
| 661 | +static int mac_addr_used = 2; | |
| 662 | + | |
| 634 | 663 | static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, |
| 635 | 664 | const char *prefix, bool fallback) |
| 636 | 665 | { |
| @@ -648,6 +677,25 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, · 11 unmodified lines | ||
| 648 | 677 | |
| 649 | 678 | nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback); |
| 650 | 679 | nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback); |
| 680 | + | |
| 681 | + /* The address prefix 00:90:4C is used by Broadcom in their initial | |
| 682 | + configuration. When a mac address with the prefix 00:90:4C is used | |
| 683 | + all devices from the same series are sharing the same mac address. | |
| 684 | + To prevent mac address collisions we replace them with a mac address | |
| 685 | + based on the base address. */ | |
| 686 | + if (!bcm47xx_is_valid_mac(sprom->il0mac)) { | |
| 687 | + u8 mac[6]; | |
| 688 | + | |
| 689 | + nvram_read_macaddr(NULL, "et0macaddr", mac, false); | |
| 690 | + if (bcm47xx_is_valid_mac(mac)) { | |
| 691 | + int err = bcm47xx_increase_mac_addr(mac, mac_addr_used); | |
| 692 | + | |
| 693 | + if (!err) { | |
| 694 | + ether_addr_copy(sprom->il0mac, mac); | |
| 695 | + mac_addr_used++; | |
| 696 | + } | |
| 697 | + } | |
| 698 | + } | |
| 651 | 699 | } |
| 652 | 700 | |
| 653 | 701 | static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, |
| @@ -24,7 +24,9 @@ EXPORT_SYMBOL(bcm63xx_regs_base); · 23 unmodified lines | ||
| 24 | 24 | const int *bcm63xx_irqs; |
| 25 | 25 | EXPORT_SYMBOL(bcm63xx_irqs); |
| 26 | 26 | |
| 27 | −static u16 bcm63xx_cpu_id; | |
| 27 | +u16 bcm63xx_cpu_id __read_mostly; | |
| 28 | +EXPORT_SYMBOL(bcm63xx_cpu_id); | |
| 29 | + | |
| 28 | 30 | static u8 bcm63xx_cpu_rev; |
| 29 | 31 | static unsigned int bcm63xx_cpu_freq; |
| 30 | 32 | static unsigned int bcm63xx_memory_size; |
| @@ -97,13 +99,6 @@ static const int bcm6368_irqs[] = { · 66 unmodified lines | ||
| 97 | 99 | |
| 98 | 100 | }; |
| 99 | 101 | |
| 100 | −u16 __bcm63xx_get_cpu_id(void) | |
| 101 | −{ | |
| 102 | − return bcm63xx_cpu_id; | |
| 103 | −} | |
| 104 | − | |
| 105 | −EXPORT_SYMBOL(__bcm63xx_get_cpu_id); | |
| 106 | − | |
| 107 | 102 | u8 bcm63xx_get_cpu_rev(void) |
| 108 | 103 | { |
| 109 | 104 | return bcm63xx_cpu_rev; |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <bcm63xx_io.h> |
| 15 | 15 | #include <bcm63xx_regs.h> |
| 16 | 16 | |
| 17 | −#ifdef BCMCPU_RUNTIME_DETECT | |
| 18 | 17 | static const unsigned long bcm6348_regs_enetdmac[] = { |
| 19 | 18 | [ENETDMAC_CHANCFG] = ENETDMAC_CHANCFG_REG, |
| 20 | 19 | [ENETDMAC_IR] = ENETDMAC_IR_REG, |
| @@ -43,9 +42,6 @@ static __init void bcm63xx_enetdmac_regs_init(void) · 22 unmodified lines | ||
| 43 | 42 | else |
| 44 | 43 | bcm63xx_regs_enetdmac = bcm6348_regs_enetdmac; |
| 45 | 44 | } |
| 46 | −#else | |
| 47 | −static __init void bcm63xx_enetdmac_regs_init(void) { } | |
| 48 | −#endif | |
| 49 | 45 | |
| 50 | 46 | static struct resource shared_res[] = { |
| 51 | 47 | { |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <bcm63xx_dev_spi.h> |
| 19 | 19 | #include <bcm63xx_regs.h> |
| 20 | 20 | |
| 21 | −#ifdef BCMCPU_RUNTIME_DETECT | |
| 22 | 21 | /* |
| 23 | 22 | * register offsets |
| 24 | 23 | */ |
| @@ -41,9 +40,6 @@ static __init void bcm63xx_spi_regs_init(void) · 16 unmodified lines | ||
| 41 | 40 | BCMCPU_IS_6362() || BCMCPU_IS_6368()) |
| 42 | 41 | bcm63xx_regs_spi = bcm6358_regs_spi; |
| 43 | 42 | } |
| 44 | −#else | |
| 45 | −static __init void bcm63xx_spi_regs_init(void) { } | |
| 46 | −#endif | |
| 47 | 43 | |
| 48 | 44 | static struct resource spi_resources[] = { |
| 49 | 45 | { |
| @@ -18,19 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <bcm63xx_io.h> |
| 19 | 19 | #include <bcm63xx_regs.h> |
| 20 | 20 | |
| 21 | −#ifndef BCMCPU_RUNTIME_DETECT | |
| 22 | −#define gpio_out_low_reg GPIO_DATA_LO_REG | |
| 23 | −#ifdef CONFIG_BCM63XX_CPU_6345 | |
| 24 | −#ifdef gpio_out_low_reg | |
| 25 | −#undef gpio_out_low_reg | |
| 26 | −#define gpio_out_low_reg GPIO_DATA_LO_REG_6345 | |
| 27 | −#endif /* gpio_out_low_reg */ | |
| 28 | −#endif /* CONFIG_BCM63XX_CPU_6345 */ | |
| 29 | − | |
| 30 | −static inline void bcm63xx_gpio_out_low_reg_init(void) | |
| 31 | −{ | |
| 32 | −} | |
| 33 | −#else /* ! BCMCPU_RUNTIME_DETECT */ | |
| 34 | 21 | static u32 gpio_out_low_reg; |
| 35 | 22 | |
| 36 | 23 | static void bcm63xx_gpio_out_low_reg_init(void) |
| @@ -44,7 +31,6 @@ static void bcm63xx_gpio_out_low_reg_init(void) · 7 unmodified lines | ||
| 44 | 31 | break; |
| 45 | 32 | } |
| 46 | 33 | } |
| 47 | −#endif /* ! BCMCPU_RUNTIME_DETECT */ | |
| 48 | 34 | |
| 49 | 35 | static DEFINE_SPINLOCK(bcm63xx_gpio_lock); |
| 50 | 36 | static u32 gpio_out_low, gpio_out_high; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/interrupt.h> |
| 13 | 13 | #include <linux/module.h> |
| 14 | 14 | #include <linux/irq.h> |
| 15 | +#include <linux/spinlock.h> | |
| 15 | 16 | #include <asm/irq_cpu.h> |
| 16 | 17 | #include <asm/mipsregs.h> |
| 17 | 18 | #include <bcm63xx_cpu.h> |
| @@ -19,222 +20,20 @@ · 1 unmodified line | ||
| 19 | 20 | #include <bcm63xx_io.h> |
| 20 | 21 | #include <bcm63xx_irq.h> |
| 21 | 22 | |
| 22 | −static void __dispatch_internal(void) __maybe_unused; | |
| 23 | −static void __dispatch_internal_64(void) __maybe_unused; | |
| 24 | −static void __internal_irq_mask_32(unsigned int irq) __maybe_unused; | |
| 25 | −static void __internal_irq_mask_64(unsigned int irq) __maybe_unused; | |
| 26 | −static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused; | |
| 27 | −static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused; | |
| 28 | − | |
| 29 | −#ifndef BCMCPU_RUNTIME_DETECT | |
| 30 | −#ifdef CONFIG_BCM63XX_CPU_3368 | |
| 31 | −#define irq_stat_reg PERF_IRQSTAT_3368_REG | |
| 32 | −#define irq_mask_reg PERF_IRQMASK_3368_REG | |
| 33 | −#define irq_bits 32 | |
| 34 | −#define is_ext_irq_cascaded 0 | |
| 35 | −#define ext_irq_start 0 | |
| 36 | −#define ext_irq_end 0 | |
| 37 | −#define ext_irq_count 4 | |
| 38 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_3368 | |
| 39 | −#define ext_irq_cfg_reg2 0 | |
| 40 | −#endif | |
| 41 | −#ifdef CONFIG_BCM63XX_CPU_6328 | |
| 42 | −#define irq_stat_reg PERF_IRQSTAT_6328_REG | |
| 43 | −#define irq_mask_reg PERF_IRQMASK_6328_REG | |
| 44 | −#define irq_bits 64 | |
| 45 | −#define is_ext_irq_cascaded 1 | |
| 46 | −#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE) | |
| 47 | −#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE) | |
| 48 | −#define ext_irq_count 4 | |
| 49 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328 | |
| 50 | −#define ext_irq_cfg_reg2 0 | |
| 51 | −#endif | |
| 52 | −#ifdef CONFIG_BCM63XX_CPU_6338 | |
| 53 | −#define irq_stat_reg PERF_IRQSTAT_6338_REG | |
| 54 | −#define irq_mask_reg PERF_IRQMASK_6338_REG | |
| 55 | −#define irq_bits 32 | |
| 56 | −#define is_ext_irq_cascaded 0 | |
| 57 | −#define ext_irq_start 0 | |
| 58 | −#define ext_irq_end 0 | |
| 59 | −#define ext_irq_count 4 | |
| 60 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6338 | |
| 61 | −#define ext_irq_cfg_reg2 0 | |
| 62 | −#endif | |
| 63 | −#ifdef CONFIG_BCM63XX_CPU_6345 | |
| 64 | −#define irq_stat_reg PERF_IRQSTAT_6345_REG | |
| 65 | −#define irq_mask_reg PERF_IRQMASK_6345_REG | |
| 66 | −#define irq_bits 32 | |
| 67 | −#define is_ext_irq_cascaded 0 | |
| 68 | −#define ext_irq_start 0 | |
| 69 | −#define ext_irq_end 0 | |
| 70 | −#define ext_irq_count 4 | |
| 71 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6345 | |
| 72 | −#define ext_irq_cfg_reg2 0 | |
| 73 | −#endif | |
| 74 | −#ifdef CONFIG_BCM63XX_CPU_6348 | |
| 75 | −#define irq_stat_reg PERF_IRQSTAT_6348_REG | |
| 76 | −#define irq_mask_reg PERF_IRQMASK_6348_REG | |
| 77 | −#define irq_bits 32 | |
| 78 | −#define is_ext_irq_cascaded 0 | |
| 79 | −#define ext_irq_start 0 | |
| 80 | −#define ext_irq_end 0 | |
| 81 | −#define ext_irq_count 4 | |
| 82 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6348 | |
| 83 | −#define ext_irq_cfg_reg2 0 | |
| 84 | −#endif | |
| 85 | −#ifdef CONFIG_BCM63XX_CPU_6358 | |
| 86 | −#define irq_stat_reg PERF_IRQSTAT_6358_REG | |
| 87 | −#define irq_mask_reg PERF_IRQMASK_6358_REG | |
| 88 | −#define irq_bits 32 | |
| 89 | −#define is_ext_irq_cascaded 1 | |
| 90 | −#define ext_irq_start (BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE) | |
| 91 | −#define ext_irq_end (BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE) | |
| 92 | −#define ext_irq_count 4 | |
| 93 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358 | |
| 94 | −#define ext_irq_cfg_reg2 0 | |
| 95 | −#endif | |
| 96 | −#ifdef CONFIG_BCM63XX_CPU_6362 | |
| 97 | −#define irq_stat_reg PERF_IRQSTAT_6362_REG | |
| 98 | −#define irq_mask_reg PERF_IRQMASK_6362_REG | |
| 99 | −#define irq_bits 64 | |
| 100 | −#define is_ext_irq_cascaded 1 | |
| 101 | −#define ext_irq_start (BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE) | |
| 102 | −#define ext_irq_end (BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE) | |
| 103 | −#define ext_irq_count 4 | |
| 104 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6362 | |
| 105 | −#define ext_irq_cfg_reg2 0 | |
| 106 | −#endif | |
| 107 | −#ifdef CONFIG_BCM63XX_CPU_6368 | |
| 108 | −#define irq_stat_reg PERF_IRQSTAT_6368_REG | |
| 109 | −#define irq_mask_reg PERF_IRQMASK_6368_REG | |
| 110 | −#define irq_bits 64 | |
| 111 | −#define is_ext_irq_cascaded 1 | |
| 112 | −#define ext_irq_start (BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE) | |
| 113 | −#define ext_irq_end (BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE) | |
| 114 | −#define ext_irq_count 6 | |
| 115 | −#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6368 | |
| 116 | −#define ext_irq_cfg_reg2 PERF_EXTIRQ_CFG_REG2_6368 | |
| 117 | −#endif | |
| 118 | − | |
| 119 | −#if irq_bits == 32 | |
| 120 | −#define dispatch_internal __dispatch_internal | |
| 121 | −#define internal_irq_mask __internal_irq_mask_32 | |
| 122 | −#define internal_irq_unmask __internal_irq_unmask_32 | |
| 123 | −#else | |
| 124 | −#define dispatch_internal __dispatch_internal_64 | |
| 125 | −#define internal_irq_mask __internal_irq_mask_64 | |
| 126 | −#define internal_irq_unmask __internal_irq_unmask_64 | |
| 127 | −#endif | |
| 128 | 23 | |
| 129 | −#define irq_stat_addr (bcm63xx_regset_address(RSET_PERF) + irq_stat_reg) | |
| 130 | −#define irq_mask_addr (bcm63xx_regset_address(RSET_PERF) + irq_mask_reg) | |
| 24 | +static DEFINE_SPINLOCK(ipic_lock); | |
| 25 | +static DEFINE_SPINLOCK(epic_lock); | |
| 131 | 26 | |
| 132 | −static inline void bcm63xx_init_irq(void) | |
| 133 | −{ | |
| 134 | −} | |
| 135 | −#else /* ! BCMCPU_RUNTIME_DETECT */ | |
| 136 | − | |
| 137 | −static u32 irq_stat_addr, irq_mask_addr; | |
| 138 | −static void (*dispatch_internal)(void); | |
| 27 | +static u32 irq_stat_addr[2]; | |
| 28 | +static u32 irq_mask_addr[2]; | |
| 29 | +static void (*dispatch_internal)(int cpu); | |
| 139 | 30 | static int is_ext_irq_cascaded; |
| 140 | 31 | static unsigned int ext_irq_count; |
| 141 | 32 | static unsigned int ext_irq_start, ext_irq_end; |
| 142 | 33 | static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2; |
| 143 | −static void (*internal_irq_mask)(unsigned int irq); | |
| 144 | −static void (*internal_irq_unmask)(unsigned int irq); | |
| 34 | +static void (*internal_irq_mask)(struct irq_data *d); | |
| 35 | +static void (*internal_irq_unmask)(struct irq_data *d, const struct cpumask *m); | |
| 145 | 36 | |
| 146 | −static void bcm63xx_init_irq(void) | |
| 147 | −{ | |
| 148 | − int irq_bits; | |
| 149 | − | |
| 150 | − irq_stat_addr = bcm63xx_regset_address(RSET_PERF); | |
| 151 | − irq_mask_addr = bcm63xx_regset_address(RSET_PERF); | |
| 152 | − | |
| 153 | − switch (bcm63xx_get_cpu_id()) { | |
| 154 | − case BCM3368_CPU_ID: | |
| 155 | − irq_stat_addr += PERF_IRQSTAT_3368_REG; | |
| 156 | − irq_mask_addr += PERF_IRQMASK_3368_REG; | |
| 157 | − irq_bits = 32; | |
| 158 | − ext_irq_count = 4; | |
| 159 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368; | |
| 160 | − break; | |
| 161 | − case BCM6328_CPU_ID: | |
| 162 | − irq_stat_addr += PERF_IRQSTAT_6328_REG; | |
| 163 | − irq_mask_addr += PERF_IRQMASK_6328_REG; | |
| 164 | − irq_bits = 64; | |
| 165 | − ext_irq_count = 4; | |
| 166 | − is_ext_irq_cascaded = 1; | |
| 167 | − ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 168 | − ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; | |
| 169 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; | |
| 170 | − break; | |
| 171 | − case BCM6338_CPU_ID: | |
| 172 | − irq_stat_addr += PERF_IRQSTAT_6338_REG; | |
| 173 | − irq_mask_addr += PERF_IRQMASK_6338_REG; | |
| 174 | − irq_bits = 32; | |
| 175 | − ext_irq_count = 4; | |
| 176 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338; | |
| 177 | − break; | |
| 178 | − case BCM6345_CPU_ID: | |
| 179 | − irq_stat_addr += PERF_IRQSTAT_6345_REG; | |
| 180 | − irq_mask_addr += PERF_IRQMASK_6345_REG; | |
| 181 | − irq_bits = 32; | |
| 182 | − ext_irq_count = 4; | |
| 183 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345; | |
| 184 | − break; | |
| 185 | − case BCM6348_CPU_ID: | |
| 186 | − irq_stat_addr += PERF_IRQSTAT_6348_REG; | |
| 187 | − irq_mask_addr += PERF_IRQMASK_6348_REG; | |
| 188 | − irq_bits = 32; | |
| 189 | − ext_irq_count = 4; | |
| 190 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348; | |
| 191 | − break; | |
| 192 | − case BCM6358_CPU_ID: | |
| 193 | − irq_stat_addr += PERF_IRQSTAT_6358_REG; | |
| 194 | − irq_mask_addr += PERF_IRQMASK_6358_REG; | |
| 195 | − irq_bits = 32; | |
| 196 | − ext_irq_count = 4; | |
| 197 | − is_ext_irq_cascaded = 1; | |
| 198 | − ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 199 | − ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; | |
| 200 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; | |
| 201 | − break; | |
| 202 | − case BCM6362_CPU_ID: | |
| 203 | − irq_stat_addr += PERF_IRQSTAT_6362_REG; | |
| 204 | − irq_mask_addr += PERF_IRQMASK_6362_REG; | |
| 205 | − irq_bits = 64; | |
| 206 | − ext_irq_count = 4; | |
| 207 | − is_ext_irq_cascaded = 1; | |
| 208 | − ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 209 | − ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE; | |
| 210 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362; | |
| 211 | − break; | |
| 212 | − case BCM6368_CPU_ID: | |
| 213 | − irq_stat_addr += PERF_IRQSTAT_6368_REG; | |
| 214 | − irq_mask_addr += PERF_IRQMASK_6368_REG; | |
| 215 | − irq_bits = 64; | |
| 216 | − ext_irq_count = 6; | |
| 217 | − is_ext_irq_cascaded = 1; | |
| 218 | − ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 219 | − ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE; | |
| 220 | − ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368; | |
| 221 | − ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368; | |
| 222 | − break; | |
| 223 | − default: | |
| 224 | − BUG(); | |
| 225 | − } | |
| 226 | − | |
| 227 | − if (irq_bits == 32) { | |
| 228 | − dispatch_internal = __dispatch_internal; | |
| 229 | − internal_irq_mask = __internal_irq_mask_32; | |
| 230 | − internal_irq_unmask = __internal_irq_unmask_32; | |
| 231 | − } else { | |
| 232 | − dispatch_internal = __dispatch_internal_64; | |
| 233 | − internal_irq_mask = __internal_irq_mask_64; | |
| 234 | − internal_irq_unmask = __internal_irq_unmask_64; | |
| 235 | − } | |
| 236 | −} | |
| 237 | −#endif /* ! BCMCPU_RUNTIME_DETECT */ | |
| 238 | 37 | |
| 239 | 38 | static inline u32 get_ext_irq_perf_reg(int irq) |
| 240 | 39 | { |
| @@ -252,53 +51,113 @@ static inline void handle_internal(int intbit) · 11 unmodified lines | ||
| 252 | 51 | do_IRQ(intbit + IRQ_INTERNAL_BASE); |
| 253 | 52 | } |
| 254 | 53 | |
| 54 | +static inline int enable_irq_for_cpu(int cpu, struct irq_data *d, | |
| 55 | + const struct cpumask *m) | |
| 56 | +{ | |
| 57 | + bool enable = cpu_online(cpu); | |
| 58 | + | |
| 59 | +#ifdef CONFIG_SMP | |
| 60 | + if (m) | |
| 61 | + enable &= cpu_isset(cpu, *m); | |
| 62 | + else if (irqd_affinity_was_set(d)) | |
| 63 | + enable &= cpu_isset(cpu, *d->affinity); | |
| 64 | +#endif | |
| 65 | + return enable; | |
| 66 | +} | |
| 67 | + | |
| 255 | 68 | /* |
| 256 | 69 | * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not |
| 257 | 70 | * prioritize any interrupt relatively to another. the static counter |
| 258 | 71 | * will resume the loop where it ended the last time we left this |
| 259 | 72 | * function. |
| 260 | 73 | */ |
| 261 | −static void __dispatch_internal(void) | |
| 262 | −{ | |
| 263 | − u32 pending; | |
| 264 | − static int i; | |
| 265 | − | |
| 266 | − pending = bcm_readl(irq_stat_addr) & bcm_readl(irq_mask_addr); | |
| 267 | 74 | |
| 268 | − if (!pending) | |
| 269 | − return ; | |
| 270 | − | |
| 271 | − while (1) { | |
| 272 | − int to_call = i; | |
| 273 | − | |
| 274 | − i = (i + 1) & 0x1f; | |
| 275 | − if (pending & (1 << to_call)) { | |
| 276 | − handle_internal(to_call); | |
| 277 | − break; | |
| 278 | − } | |
| 279 | − } | |
| 75 | +#define BUILD_IPIC_INTERNAL(width) \ | |
| 76 | +void __dispatch_internal_##width(int cpu) \ | |
| 77 | +{ \ | |
| 78 | + u32 pending[width / 32]; \ | |
| 79 | + unsigned int src, tgt; \ | |
| 80 | + bool irqs_pending = false; \ | |
| 81 | + static unsigned int i[2]; \ | |
| 82 | + unsigned int *next = &i[cpu]; \ | |
| 83 | + unsigned long flags; \ | |
| 84 | + \ | |
| 85 | + /* read registers in reverse order */ \ | |
| 86 | + spin_lock_irqsave(&ipic_lock, flags); \ | |
| 87 | + for (src = 0, tgt = (width / 32); src < (width / 32); src++) { \ | |
| 88 | + u32 val; \ | |
| 89 | + \ | |
| 90 | + val = bcm_readl(irq_stat_addr[cpu] + src * sizeof(u32)); \ | |
| 91 | + val &= bcm_readl(irq_mask_addr[cpu] + src * sizeof(u32)); \ | |
| 92 | + pending[--tgt] = val; \ | |
| 93 | + \ | |
| 94 | + if (val) \ | |
| 95 | + irqs_pending = true; \ | |
| 96 | + } \ | |
| 97 | + spin_unlock_irqrestore(&ipic_lock, flags); \ | |
| 98 | + \ | |
| 99 | + if (!irqs_pending) \ | |
| 100 | + return; \ | |
| 101 | + \ | |
| 102 | + while (1) { \ | |
| 103 | + unsigned int to_call = *next; \ | |
| 104 | + \ | |
| 105 | + *next = (*next + 1) & (width - 1); \ | |
| 106 | + if (pending[to_call / 32] & (1 << (to_call & 0x1f))) { \ | |
| 107 | + handle_internal(to_call); \ | |
| 108 | + break; \ | |
| 109 | + } \ | |
| 110 | + } \ | |
| 111 | +} \ | |
| 112 | + \ | |
| 113 | +static void __internal_irq_mask_##width(struct irq_data *d) \ | |
| 114 | +{ \ | |
| 115 | + u32 val; \ | |
| 116 | + unsigned irq = d->irq - IRQ_INTERNAL_BASE; \ | |
| 117 | + unsigned reg = (irq / 32) ^ (width/32 - 1); \ | |
| 118 | + unsigned bit = irq & 0x1f; \ | |
| 119 | + unsigned long flags; \ | |
| 120 | + int cpu; \ | |
| 121 | + \ | |
| 122 | + spin_lock_irqsave(&ipic_lock, flags); \ | |
| 123 | + for_each_present_cpu(cpu) { \ | |
| 124 | + if (!irq_mask_addr[cpu]) \ | |
| 125 | + break; \ | |
| 126 | + \ | |
| 127 | + val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ | |
| 128 | + val &= ~(1 << bit); \ | |
| 129 | + bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ | |
| 130 | + } \ | |
| 131 | + spin_unlock_irqrestore(&ipic_lock, flags); \ | |
| 132 | +} \ | |
| 133 | + \ | |
| 134 | +static void __internal_irq_unmask_##width(struct irq_data *d, \ | |
| 135 | + const struct cpumask *m) \ | |
| 136 | +{ \ | |
| 137 | + u32 val; \ | |
| 138 | + unsigned irq = d->irq - IRQ_INTERNAL_BASE; \ | |
| 139 | + unsigned reg = (irq / 32) ^ (width/32 - 1); \ | |
| 140 | + unsigned bit = irq & 0x1f; \ | |
| 141 | + unsigned long flags; \ | |
| 142 | + int cpu; \ | |
| 143 | + \ | |
| 144 | + spin_lock_irqsave(&ipic_lock, flags); \ | |
| 145 | + for_each_present_cpu(cpu) { \ | |
| 146 | + if (!irq_mask_addr[cpu]) \ | |
| 147 | + break; \ | |
| 148 | + \ | |
| 149 | + val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ | |
| 150 | + if (enable_irq_for_cpu(cpu, d, m)) \ | |
| 151 | + val |= (1 << bit); \ | |
| 152 | + else \ | |
| 153 | + val &= ~(1 << bit); \ | |
| 154 | + bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ | |
| 155 | + } \ | |
| 156 | + spin_unlock_irqrestore(&ipic_lock, flags); \ | |
| 280 | 157 | } |
| 281 | 158 | |
| 282 | −static void __dispatch_internal_64(void) | |
| 283 | −{ | |
| 284 | − u64 pending; | |
| 285 | − static int i; | |
| 286 | − | |
| 287 | − pending = bcm_readq(irq_stat_addr) & bcm_readq(irq_mask_addr); | |
| 288 | − | |
| 289 | − if (!pending) | |
| 290 | − return ; | |
| 291 | − | |
| 292 | − while (1) { | |
| 293 | − int to_call = i; | |
| 294 | − | |
| 295 | − i = (i + 1) & 0x3f; | |
| 296 | − if (pending & (1ull << to_call)) { | |
| 297 | − handle_internal(to_call); | |
| 298 | − break; | |
| 299 | − } | |
| 300 | − } | |
| 301 | −} | |
| 159 | +BUILD_IPIC_INTERNAL(32); | |
| 160 | +BUILD_IPIC_INTERNAL(64); | |
| 302 | 161 | |
| 303 | 162 | asmlinkage void plat_irq_dispatch(void) |
| 304 | 163 | { |
| @@ -317,8 +176,11 @@ asmlinkage void plat_irq_dispatch(void) · 12 unmodified lines | ||
| 317 | 176 | if (cause & CAUSEF_IP1) |
| 318 | 177 | do_IRQ(1); |
| 319 | 178 | if (cause & CAUSEF_IP2) |
| 320 | − dispatch_internal(); | |
| 321 | − if (!is_ext_irq_cascaded) { | |
| 179 | + dispatch_internal(0); | |
| 180 | + if (is_ext_irq_cascaded) { | |
| 181 | + if (cause & CAUSEF_IP3) | |
| 182 | + dispatch_internal(1); | |
| 183 | + } else { | |
| 322 | 184 | if (cause & CAUSEF_IP3) |
| 323 | 185 | do_IRQ(IRQ_EXT_0); |
| 324 | 186 | if (cause & CAUSEF_IP4) |
| @@ -335,50 +197,14 @@ asmlinkage void plat_irq_dispatch(void) · 10 unmodified lines | ||
| 335 | 197 | * internal IRQs operations: only mask/unmask on PERF irq mask |
| 336 | 198 | * register. |
| 337 | 199 | */ |
| 338 | −static void __internal_irq_mask_32(unsigned int irq) | |
| 339 | −{ | |
| 340 | − u32 mask; | |
| 341 | − | |
| 342 | − mask = bcm_readl(irq_mask_addr); | |
| 343 | − mask &= ~(1 << irq); | |
| 344 | − bcm_writel(mask, irq_mask_addr); | |
| 345 | −} | |
| 346 | − | |
| 347 | −static void __internal_irq_mask_64(unsigned int irq) | |
| 348 | −{ | |
| 349 | − u64 mask; | |
| 350 | − | |
| 351 | − mask = bcm_readq(irq_mask_addr); | |
| 352 | − mask &= ~(1ull << irq); | |
| 353 | − bcm_writeq(mask, irq_mask_addr); | |
| 354 | −} | |
| 355 | − | |
| 356 | −static void __internal_irq_unmask_32(unsigned int irq) | |
| 357 | −{ | |
| 358 | − u32 mask; | |
| 359 | − | |
| 360 | − mask = bcm_readl(irq_mask_addr); | |
| 361 | − mask |= (1 << irq); | |
| 362 | − bcm_writel(mask, irq_mask_addr); | |
| 363 | −} | |
| 364 | − | |
| 365 | −static void __internal_irq_unmask_64(unsigned int irq) | |
| 366 | −{ | |
| 367 | − u64 mask; | |
| 368 | − | |
| 369 | − mask = bcm_readq(irq_mask_addr); | |
| 370 | − mask |= (1ull << irq); | |
| 371 | − bcm_writeq(mask, irq_mask_addr); | |
| 372 | −} | |
| 373 | − | |
| 374 | 200 | static void bcm63xx_internal_irq_mask(struct irq_data *d) |
| 375 | 201 | { |
| 376 | − internal_irq_mask(d->irq - IRQ_INTERNAL_BASE); | |
| 202 | + internal_irq_mask(d); | |
| 377 | 203 | } |
| 378 | 204 | |
| 379 | 205 | static void bcm63xx_internal_irq_unmask(struct irq_data *d) |
| 380 | 206 | { |
| 381 | − internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE); | |
| 207 | + internal_irq_unmask(d, NULL); | |
| 382 | 208 | } |
| 383 | 209 | |
| 384 | 210 | /* |
| @@ -389,8 +215,10 @@ static void bcm63xx_external_irq_mask(struct irq_data *d) · 4 unmodified lines | ||
| 389 | 215 | { |
| 390 | 216 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
| 391 | 217 | u32 reg, regaddr; |
| 218 | + unsigned long flags; | |
| 392 | 219 | |
| 393 | 220 | regaddr = get_ext_irq_perf_reg(irq); |
| 221 | + spin_lock_irqsave(&epic_lock, flags); | |
| 394 | 222 | reg = bcm_perf_readl(regaddr); |
| 395 | 223 | |
| 396 | 224 | if (BCMCPU_IS_6348()) |
| @@ -399,16 +227,20 @@ static void bcm63xx_external_irq_mask(struct irq_data *d) · 2 unmodified lines | ||
| 399 | 227 | reg &= ~EXTIRQ_CFG_MASK(irq % 4); |
| 400 | 228 | |
| 401 | 229 | bcm_perf_writel(reg, regaddr); |
| 230 | + spin_unlock_irqrestore(&epic_lock, flags); | |
| 231 | + | |
| 402 | 232 | if (is_ext_irq_cascaded) |
| 403 | − internal_irq_mask(irq + ext_irq_start); | |
| 233 | + internal_irq_mask(irq_get_irq_data(irq + ext_irq_start)); | |
| 404 | 234 | } |
| 405 | 235 | |
| 406 | 236 | static void bcm63xx_external_irq_unmask(struct irq_data *d) |
| 407 | 237 | { |
| 408 | 238 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
| 409 | 239 | u32 reg, regaddr; |
| 240 | + unsigned long flags; | |
| 410 | 241 | |
| 411 | 242 | regaddr = get_ext_irq_perf_reg(irq); |
| 243 | + spin_lock_irqsave(&epic_lock, flags); | |
| 412 | 244 | reg = bcm_perf_readl(regaddr); |
| 413 | 245 | |
| 414 | 246 | if (BCMCPU_IS_6348()) |
| @@ -417,17 +249,21 @@ static void bcm63xx_external_irq_unmask(struct irq_data *d) · 2 unmodified lines | ||
| 417 | 249 | reg |= EXTIRQ_CFG_MASK(irq % 4); |
| 418 | 250 | |
| 419 | 251 | bcm_perf_writel(reg, regaddr); |
| 252 | + spin_unlock_irqrestore(&epic_lock, flags); | |
| 420 | 253 | |
| 421 | 254 | if (is_ext_irq_cascaded) |
| 422 | − internal_irq_unmask(irq + ext_irq_start); | |
| 255 | + internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start), | |
| 256 | + NULL); | |
| 423 | 257 | } |
| 424 | 258 | |
| 425 | 259 | static void bcm63xx_external_irq_clear(struct irq_data *d) |
| 426 | 260 | { |
| 427 | 261 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
| 428 | 262 | u32 reg, regaddr; |
| 263 | + unsigned long flags; | |
| 429 | 264 | |
| 430 | 265 | regaddr = get_ext_irq_perf_reg(irq); |
| 266 | + spin_lock_irqsave(&epic_lock, flags); | |
| 431 | 267 | reg = bcm_perf_readl(regaddr); |
| 432 | 268 | |
| 433 | 269 | if (BCMCPU_IS_6348()) |
| @@ -436,6 +272,7 @@ static void bcm63xx_external_irq_clear(struct irq_data *d) · 2 unmodified lines | ||
| 436 | 272 | reg |= EXTIRQ_CFG_CLEAR(irq % 4); |
| 437 | 273 | |
| 438 | 274 | bcm_perf_writel(reg, regaddr); |
| 275 | + spin_unlock_irqrestore(&epic_lock, flags); | |
| 439 | 276 | } |
| 440 | 277 | |
| 441 | 278 | static int bcm63xx_external_irq_set_type(struct irq_data *d, |
| @@ -444,6 +281,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, · 2 unmodified lines | ||
| 444 | 281 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
| 445 | 282 | u32 reg, regaddr; |
| 446 | 283 | int levelsense, sense, bothedge; |
| 284 | + unsigned long flags; | |
| 447 | 285 | |
| 448 | 286 | flow_type &= IRQ_TYPE_SENSE_MASK; |
| 449 | 287 | |
| @@ -478,6 +316,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, · 28 unmodified lines | ||
| 478 | 316 | } |
| 479 | 317 | |
| 480 | 318 | regaddr = get_ext_irq_perf_reg(irq); |
| 319 | + spin_lock_irqsave(&epic_lock, flags); | |
| 481 | 320 | reg = bcm_perf_readl(regaddr); |
| 482 | 321 | irq %= 4; |
| 483 | 322 | |
| @@ -522,6 +361,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, · 38 unmodified lines | ||
| 522 | 361 | } |
| 523 | 362 | |
| 524 | 363 | bcm_perf_writel(reg, regaddr); |
| 364 | + spin_unlock_irqrestore(&epic_lock, flags); | |
| 525 | 365 | |
| 526 | 366 | irqd_set_trigger_type(d, flow_type); |
| 527 | 367 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
| @@ -532,6 +372,18 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, · 4 unmodified lines | ||
| 532 | 372 | return IRQ_SET_MASK_OK_NOCOPY; |
| 533 | 373 | } |
| 534 | 374 | |
| 375 | +#ifdef CONFIG_SMP | |
| 376 | +static int bcm63xx_internal_set_affinity(struct irq_data *data, | |
| 377 | + const struct cpumask *dest, | |
| 378 | + bool force) | |
| 379 | +{ | |
| 380 | + if (!irqd_irq_disabled(data)) | |
| 381 | + internal_irq_unmask(data, dest); | |
| 382 | + | |
| 383 | + return 0; | |
| 384 | +} | |
| 385 | +#endif | |
| 386 | + | |
| 535 | 387 | static struct irq_chip bcm63xx_internal_irq_chip = { |
| 536 | 388 | .name = "bcm63xx_ipic", |
| 537 | 389 | .irq_mask = bcm63xx_internal_irq_mask, |
| @@ -554,12 +406,130 @@ static struct irqaction cpu_ip2_cascade_action = { · 16 unmodified lines | ||
| 554 | 406 | .flags = IRQF_NO_THREAD, |
| 555 | 407 | }; |
| 556 | 408 | |
| 409 | +#ifdef CONFIG_SMP | |
| 410 | +static struct irqaction cpu_ip3_cascade_action = { | |
| 411 | + .handler = no_action, | |
| 412 | + .name = "cascade_ip3", | |
| 413 | + .flags = IRQF_NO_THREAD, | |
| 414 | +}; | |
| 415 | +#endif | |
| 416 | + | |
| 557 | 417 | static struct irqaction cpu_ext_cascade_action = { |
| 558 | 418 | .handler = no_action, |
| 559 | 419 | .name = "cascade_extirq", |
| 560 | 420 | .flags = IRQF_NO_THREAD, |
| 561 | 421 | }; |
| 562 | 422 | |
| 423 | +static void bcm63xx_init_irq(void) | |
| 424 | +{ | |
| 425 | + int irq_bits; | |
| 426 | + | |
| 427 | + irq_stat_addr[0] = bcm63xx_regset_address(RSET_PERF); | |
| 428 | + irq_mask_addr[0] = bcm63xx_regset_address(RSET_PERF); | |
| 429 | + irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF); | |
| 430 | + irq_mask_addr[1] = bcm63xx_regset_address(RSET_PERF); | |
| 431 | + | |
| 432 | + switch (bcm63xx_get_cpu_id()) { | |
| 433 | + case BCM3368_CPU_ID: | |
| 434 | + irq_stat_addr[0] += PERF_IRQSTAT_3368_REG; | |
| 435 | + irq_mask_addr[0] += PERF_IRQMASK_3368_REG; | |
| 436 | + irq_stat_addr[1] = 0; | |
| 437 | + irq_stat_addr[1] = 0; | |
| 438 | + irq_bits = 32; | |
| 439 | + ext_irq_count = 4; | |
| 440 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368; | |
| 441 | + break; | |
| 442 | + case BCM6328_CPU_ID: | |
| 443 | + irq_stat_addr[0] += PERF_IRQSTAT_6328_REG(0); | |
| 444 | + irq_mask_addr[0] += PERF_IRQMASK_6328_REG(0); | |
| 445 | + irq_stat_addr[1] += PERF_IRQSTAT_6328_REG(1); | |
| 446 | + irq_stat_addr[1] += PERF_IRQMASK_6328_REG(1); | |
| 447 | + irq_bits = 64; | |
| 448 | + ext_irq_count = 4; | |
| 449 | + is_ext_irq_cascaded = 1; | |
| 450 | + ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 451 | + ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; | |
| 452 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; | |
| 453 | + break; | |
| 454 | + case BCM6338_CPU_ID: | |
| 455 | + irq_stat_addr[0] += PERF_IRQSTAT_6338_REG; | |
| 456 | + irq_mask_addr[0] += PERF_IRQMASK_6338_REG; | |
| 457 | + irq_stat_addr[1] = 0; | |
| 458 | + irq_mask_addr[1] = 0; | |
| 459 | + irq_bits = 32; | |
| 460 | + ext_irq_count = 4; | |
| 461 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338; | |
| 462 | + break; | |
| 463 | + case BCM6345_CPU_ID: | |
| 464 | + irq_stat_addr[0] += PERF_IRQSTAT_6345_REG; | |
| 465 | + irq_mask_addr[0] += PERF_IRQMASK_6345_REG; | |
| 466 | + irq_stat_addr[1] = 0; | |
| 467 | + irq_mask_addr[1] = 0; | |
| 468 | + irq_bits = 32; | |
| 469 | + ext_irq_count = 4; | |
| 470 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345; | |
| 471 | + break; | |
| 472 | + case BCM6348_CPU_ID: | |
| 473 | + irq_stat_addr[0] += PERF_IRQSTAT_6348_REG; | |
| 474 | + irq_mask_addr[0] += PERF_IRQMASK_6348_REG; | |
| 475 | + irq_stat_addr[1] = 0; | |
| 476 | + irq_mask_addr[1] = 0; | |
| 477 | + irq_bits = 32; | |
| 478 | + ext_irq_count = 4; | |
| 479 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348; | |
| 480 | + break; | |
| 481 | + case BCM6358_CPU_ID: | |
| 482 | + irq_stat_addr[0] += PERF_IRQSTAT_6358_REG(0); | |
| 483 | + irq_mask_addr[0] += PERF_IRQMASK_6358_REG(0); | |
| 484 | + irq_stat_addr[1] += PERF_IRQSTAT_6358_REG(1); | |
| 485 | + irq_mask_addr[1] += PERF_IRQMASK_6358_REG(1); | |
| 486 | + irq_bits = 32; | |
| 487 | + ext_irq_count = 4; | |
| 488 | + is_ext_irq_cascaded = 1; | |
| 489 | + ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 490 | + ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; | |
| 491 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; | |
| 492 | + break; | |
| 493 | + case BCM6362_CPU_ID: | |
| 494 | + irq_stat_addr[0] += PERF_IRQSTAT_6362_REG(0); | |
| 495 | + irq_mask_addr[0] += PERF_IRQMASK_6362_REG(0); | |
| 496 | + irq_stat_addr[1] += PERF_IRQSTAT_6362_REG(1); | |
| 497 | + irq_mask_addr[1] += PERF_IRQMASK_6362_REG(1); | |
| 498 | + irq_bits = 64; | |
| 499 | + ext_irq_count = 4; | |
| 500 | + is_ext_irq_cascaded = 1; | |
| 501 | + ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 502 | + ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE; | |
| 503 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362; | |
| 504 | + break; | |
| 505 | + case BCM6368_CPU_ID: | |
| 506 | + irq_stat_addr[0] += PERF_IRQSTAT_6368_REG(0); | |
| 507 | + irq_mask_addr[0] += PERF_IRQMASK_6368_REG(0); | |
| 508 | + irq_stat_addr[1] += PERF_IRQSTAT_6368_REG(1); | |
| 509 | + irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1); | |
| 510 | + irq_bits = 64; | |
| 511 | + ext_irq_count = 6; | |
| 512 | + is_ext_irq_cascaded = 1; | |
| 513 | + ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE; | |
| 514 | + ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE; | |
| 515 | + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368; | |
| 516 | + ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368; | |
| 517 | + break; | |
| 518 | + default: | |
| 519 | + BUG(); | |
| 520 | + } | |
| 521 | + | |
| 522 | + if (irq_bits == 32) { | |
| 523 | + dispatch_internal = __dispatch_internal_32; | |
| 524 | + internal_irq_mask = __internal_irq_mask_32; | |
| 525 | + internal_irq_unmask = __internal_irq_unmask_32; | |
| 526 | + } else { | |
| 527 | + dispatch_internal = __dispatch_internal_64; | |
| 528 | + internal_irq_mask = __internal_irq_mask_64; | |
| 529 | + internal_irq_unmask = __internal_irq_unmask_64; | |
| 530 | + } | |
| 531 | +} | |
| 532 | + | |
| 563 | 533 | void __init arch_init_irq(void) |
| 564 | 534 | { |
| 565 | 535 | int i; |
| @@ -580,4 +550,14 @@ void __init arch_init_irq(void) · 14 unmodified lines | ||
| 580 | 550 | } |
| 581 | 551 | |
| 582 | 552 | setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action); |
| 553 | +#ifdef CONFIG_SMP | |
| 554 | + if (is_ext_irq_cascaded) { | |
| 555 | + setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action); | |
| 556 | + bcm63xx_internal_irq_chip.irq_set_affinity = | |
| 557 | + bcm63xx_internal_set_affinity; | |
| 558 | + | |
| 559 | + cpumask_clear(irq_default_affinity); | |
| 560 | + cpumask_set_cpu(smp_processor_id(), irq_default_affinity); | |
| 561 | + } | |
| 562 | +#endif | |
| 583 | 563 | } |
| @@ -125,8 +125,6 @@ · 124 unmodified lines | ||
| 125 | 125 | #define BCM6368_RESET_PCIE 0 |
| 126 | 126 | #define BCM6368_RESET_PCIE_EXT 0 |
| 127 | 127 | |
| 128 | −#ifdef BCMCPU_RUNTIME_DETECT | |
| 129 | − | |
| 130 | 128 | /* |
| 131 | 129 | * core reset bits |
| 132 | 130 | */ |
| @@ -188,64 +186,6 @@ static int __init bcm63xx_reset_bits_init(void) · 55 unmodified lines | ||
| 188 | 186 | |
| 189 | 187 | return 0; |
| 190 | 188 | } |
| 191 | −#else | |
| 192 | − | |
| 193 | −#ifdef CONFIG_BCM63XX_CPU_3368 | |
| 194 | −static const u32 bcm63xx_reset_bits[] = { | |
| 195 | − __GEN_RESET_BITS_TABLE(3368) | |
| 196 | −}; | |
| 197 | −#define reset_reg PERF_SOFTRESET_6358_REG | |
| 198 | −#endif | |
| 199 | − | |
| 200 | −#ifdef CONFIG_BCM63XX_CPU_6328 | |
| 201 | −static const u32 bcm63xx_reset_bits[] = { | |
| 202 | − __GEN_RESET_BITS_TABLE(6328) | |
| 203 | −}; | |
| 204 | −#define reset_reg PERF_SOFTRESET_6328_REG | |
| 205 | −#endif | |
| 206 | − | |
| 207 | −#ifdef CONFIG_BCM63XX_CPU_6338 | |
| 208 | −static const u32 bcm63xx_reset_bits[] = { | |
| 209 | − __GEN_RESET_BITS_TABLE(6338) | |
| 210 | −}; | |
| 211 | −#define reset_reg PERF_SOFTRESET_REG | |
| 212 | −#endif | |
| 213 | − | |
| 214 | −#ifdef CONFIG_BCM63XX_CPU_6345 | |
| 215 | −static const u32 bcm63xx_reset_bits[] = { }; | |
| 216 | −#define reset_reg 0 | |
| 217 | −#endif | |
| 218 | − | |
| 219 | −#ifdef CONFIG_BCM63XX_CPU_6348 | |
| 220 | −static const u32 bcm63xx_reset_bits[] = { | |
| 221 | − __GEN_RESET_BITS_TABLE(6348) | |
| 222 | −}; | |
| 223 | −#define reset_reg PERF_SOFTRESET_REG | |
| 224 | −#endif | |
| 225 | − | |
| 226 | −#ifdef CONFIG_BCM63XX_CPU_6358 | |
| 227 | −static const u32 bcm63xx_reset_bits[] = { | |
| 228 | − __GEN_RESET_BITS_TABLE(6358) | |
| 229 | −}; | |
| 230 | −#define reset_reg PERF_SOFTRESET_6358_REG | |
| 231 | −#endif | |
| 232 | − | |
| 233 | −#ifdef CONFIG_BCM63XX_CPU_6362 | |
| 234 | −static const u32 bcm63xx_reset_bits[] = { | |
| 235 | − __GEN_RESET_BITS_TABLE(6362) | |
| 236 | −}; | |
| 237 | −#define reset_reg PERF_SOFTRESET_6362_REG | |
| 238 | −#endif | |
| 239 | − | |
| 240 | −#ifdef CONFIG_BCM63XX_CPU_6368 | |
| 241 | −static const u32 bcm63xx_reset_bits[] = { | |
| 242 | − __GEN_RESET_BITS_TABLE(6368) | |
| 243 | −}; | |
| 244 | −#define reset_reg PERF_SOFTRESET_6368_REG | |
| 245 | −#endif | |
| 246 | − | |
| 247 | −static int __init bcm63xx_reset_bits_init(void) { return 0; } | |
| 248 | −#endif | |
| 249 | 189 | |
| 250 | 190 | static DEFINE_SPINLOCK(reset_mutex); |
| 251 | 191 | |
| @@ -67,10 +67,24 @@ void error(char *x) · 66 unmodified lines | ||
| 67 | 67 | #include "../../../../lib/decompress_unxz.c" |
| 68 | 68 | #endif |
| 69 | 69 | |
| 70 | +unsigned long __stack_chk_guard; | |
| 71 | + | |
| 72 | +void __stack_chk_guard_setup(void) | |
| 73 | +{ | |
| 74 | + __stack_chk_guard = 0x000a0dff; | |
| 75 | +} | |
| 76 | + | |
| 77 | +void __stack_chk_fail(void) | |
| 78 | +{ | |
| 79 | + error("stack-protector: Kernel stack is corrupted\n"); | |
| 80 | +} | |
| 81 | + | |
| 70 | 82 | void decompress_kernel(unsigned long boot_heap_start) |
| 71 | 83 | { |
| 72 | 84 | unsigned long zimage_start, zimage_size; |
| 73 | 85 | |
| 86 | + __stack_chk_guard_setup(); | |
| 87 | + | |
| 74 | 88 | zimage_start = (unsigned long)(&__image_begin); |
| 75 | 89 | zimage_size = (unsigned long)(&__image_end) - |
| 76 | 90 | (unsigned long)(&__image_begin); |
| @@ -186,6 +186,15 @@ int cvmx_helper_board_get_mii_address(int ipd_port) · 185 unmodified lines | ||
| 186 | 186 | return 7 - ipd_port; |
| 187 | 187 | else |
| 188 | 188 | return -1; |
| 189 | + case CVMX_BOARD_TYPE_CUST_DSR1000N: | |
| 190 | + /* | |
| 191 | + * Port 2 connects to Broadcom PHY (B5081). Other ports (0-1) | |
| 192 | + * connect to a switch (BCM53115). | |
| 193 | + */ | |
| 194 | + if (ipd_port == 2) | |
| 195 | + return 8; | |
| 196 | + else | |
| 197 | + return -1; | |
| 189 | 198 | } |
| 190 | 199 | |
| 191 | 200 | /* Some unknown board. Somebody forgot to update this function... */ |
| @@ -274,6 +283,18 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) · 82 unmodified lines | ||
| 274 | 283 | return result; |
| 275 | 284 | } |
| 276 | 285 | break; |
| 286 | + case CVMX_BOARD_TYPE_CUST_DSR1000N: | |
| 287 | + if (ipd_port == 0 || ipd_port == 1) { | |
| 288 | + /* Ports 0 and 1 connect to a switch (BCM53115). */ | |
| 289 | + result.s.link_up = 1; | |
| 290 | + result.s.full_duplex = 1; | |
| 291 | + result.s.speed = 1000; | |
| 292 | + return result; | |
| 293 | + } else { | |
| 294 | + /* Port 2 uses a Broadcom PHY (B5081). */ | |
| 295 | + is_broadcom_phy = 1; | |
| 296 | + } | |
| 297 | + break; | |
| 277 | 298 | } |
| 278 | 299 | |
| 279 | 300 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); |
| @@ -738,6 +759,7 @@ enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(vo · 458 unmodified lines | ||
| 738 | 759 | case CVMX_BOARD_TYPE_LANAI2_G: |
| 739 | 760 | case CVMX_BOARD_TYPE_NIC10E_66: |
| 740 | 761 | case CVMX_BOARD_TYPE_UBNT_E100: |
| 762 | + case CVMX_BOARD_TYPE_CUST_DSR1000N: | |
| 741 | 763 | return USB_CLOCK_TYPE_CRYSTAL_12; |
| 742 | 764 | case CVMX_BOARD_TYPE_NIC10E: |
| 743 | 765 | return USB_CLOCK_TYPE_REF_12; |
| @@ -194,8 +194,7 @@ err_irq: · 193 unmodified lines | ||
| 194 | 194 | static __exit void oct_ilm_module_exit(void) |
| 195 | 195 | { |
| 196 | 196 | disable_timer(TIMER_NUM); |
| 197 | − if (dir) | |
| 198 | − debugfs_remove_recursive(dir); | |
| 197 | + debugfs_remove_recursive(dir); | |
| 199 | 198 | free_irq(OCTEON_IRQ_TIMER0 + TIMER_NUM, 0); |
| 200 | 199 | } |
| 201 | 200 | |
| @@ -84,9 +84,14 @@ static void octeon_smp_hotplug_setup(void) · 83 unmodified lines | ||
| 84 | 84 | #ifdef CONFIG_HOTPLUG_CPU |
| 85 | 85 | struct linux_app_boot_info *labi; |
| 86 | 86 | |
| 87 | + if (!setup_max_cpus) | |
| 88 | + return; | |
| 89 | + | |
| 87 | 90 | labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); |
| 88 | − if (labi->labi_signature != LABI_SIGNATURE) | |
| 89 | − panic("The bootloader version on this board is incorrect."); | |
| 91 | + if (labi->labi_signature != LABI_SIGNATURE) { | |
| 92 | + pr_info("The bootloader on this board does not support HOTPLUG_CPU."); | |
| 93 | + return; | |
| 94 | + } | |
| 90 | 95 | |
| 91 | 96 | octeon_bootloader_entry_addr = labi->InitTLBStart_addr; |
| 92 | 97 | #endif |
| @@ -129,7 +134,8 @@ static void octeon_smp_setup(void) · 36 unmodified lines | ||
| 129 | 134 | * will assign CPU numbers for possible cores as well. Cores |
| 130 | 135 | * are always consecutively numberd from 0. |
| 131 | 136 | */ |
| 132 | − for (id = 0; id < num_cores && id < NR_CPUS; id++) { | |
| 137 | + for (id = 0; setup_max_cpus && octeon_bootloader_entry_addr && | |
| 138 | + id < num_cores && id < NR_CPUS; id++) { | |
| 133 | 139 | if (!(core_mask & (1 << id))) { |
| 134 | 140 | set_cpu_possible(cpus, true); |
| 135 | 141 | __cpu_number_map[id] = cpus; |
| @@ -192,14 +198,6 @@ static void octeon_init_secondary(void) · 56 unmodified lines | ||
| 192 | 198 | */ |
| 193 | 199 | void octeon_prepare_cpus(unsigned int max_cpus) |
| 194 | 200 | { |
| 195 | −#ifdef CONFIG_HOTPLUG_CPU | |
| 196 | − struct linux_app_boot_info *labi; | |
| 197 | − | |
| 198 | − labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); | |
| 199 | − | |
| 200 | − if (labi->labi_signature != LABI_SIGNATURE) | |
| 201 | − panic("The bootloader version on this board is incorrect."); | |
| 202 | −#endif | |
| 203 | 201 | /* |
| 204 | 202 | * Only the low order mailbox bits are used for IPIs, leave |
| 205 | 203 | * the other bits alone. |
| @@ -237,6 +235,9 @@ static int octeon_cpu_disable(void) · 31 unmodified lines | ||
| 237 | 235 | if (cpu == 0) |
| 238 | 236 | return -EBUSY; |
| 239 | 237 | |
| 238 | + if (!octeon_bootloader_entry_addr) | |
| 239 | + return -ENOTSUPP; | |
| 240 | + | |
| 240 | 241 | set_cpu_online(cpu, false); |
| 241 | 242 | cpu_clear(cpu, cpu_callin_map); |
| 242 | 243 | local_irq_disable(); |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | CONFIG_MACH_LOONGSON=y |
| 2 | 2 | CONFIG_SWIOTLB=y |
| 3 | −CONFIG_LEMOTE_MACH3A=y | |
| 3 | +CONFIG_LOONGSON_MACH3X=y | |
| 4 | 4 | CONFIG_CPU_LOONGSON3=y |
| 5 | 5 | CONFIG_64BIT=y |
| 6 | 6 | CONFIG_PAGE_SIZE_16KB=y |
| @@ -15,4 +15,5 @@ generic-y += segment.h · 14 unmodified lines | ||
| 15 | 15 | generic-y += serial.h |
| 16 | 16 | generic-y += trace_clock.h |
| 17 | 17 | generic-y += ucontext.h |
| 18 | +generic-y += user.h | |
| 18 | 19 | generic-y += xor.h |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | */ |
| 53 | 53 | #define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) |
| 54 | 54 | #define XPHYSADDR(a) ((_ACAST64_(a)) & \ |
| 55 | − _CONST64_(0x000000ffffffffff)) | |
| 55 | + _CONST64_(0x0000ffffffffffff)) | |
| 56 | 56 | |
| 57 | 57 | #ifdef CONFIG_64BIT |
| 58 | 58 | |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include <asm/hazards.h> |
| 12 | 12 | #include <asm/asm-offsets.h> |
| 13 | +#include <asm/msa.h> | |
| 13 | 14 | |
| 14 | 15 | #ifdef CONFIG_32BIT |
| 15 | 16 | #include <asm/asmmacro-32.h> |
| @@ -378,9 +379,19 @@ · 362 unmodified lines | ||
| 378 | 379 | st_d 29, THREAD_FPR29, \thread |
| 379 | 380 | st_d 30, THREAD_FPR30, \thread |
| 380 | 381 | st_d 31, THREAD_FPR31, \thread |
| 382 | + .set push | |
| 383 | + .set noat | |
| 384 | + cfcmsa $1, MSA_CSR | |
| 385 | + sw $1, THREAD_MSA_CSR(\thread) | |
| 386 | + .set pop | |
| 381 | 387 | .endm |
| 382 | 388 | |
| 383 | 389 | .macro msa_restore_all thread |
| 390 | + .set push | |
| 391 | + .set noat | |
| 392 | + lw $1, THREAD_MSA_CSR(\thread) | |
| 393 | + ctcmsa MSA_CSR, $1 | |
| 394 | + .set pop | |
| 384 | 395 | ld_d 0, THREAD_FPR0, \thread |
| 385 | 396 | ld_d 1, THREAD_FPR1, \thread |
| 386 | 397 | ld_d 2, THREAD_FPR2, \thread |
| @@ -415,4 +426,24 @@ · 28 unmodified lines | ||
| 415 | 426 | ld_d 31, THREAD_FPR31, \thread |
| 416 | 427 | .endm |
| 417 | 428 | |
| 429 | + .macro msa_init_upper wd | |
| 430 | +#ifdef CONFIG_64BIT | |
| 431 | + insert_d \wd, 1 | |
| 432 | +#else | |
| 433 | + insert_w \wd, 2 | |
| 434 | + insert_w \wd, 3 | |
| 435 | +#endif | |
| 436 | + .if 31-\wd | |
| 437 | + msa_init_upper (\wd+1) | |
| 438 | + .endif | |
| 439 | + .endm | |
| 440 | + | |
| 441 | + .macro msa_init_all_upper | |
| 442 | + .set push | |
| 443 | + .set noat | |
| 444 | + not $1, zero | |
| 445 | + msa_init_upper 0 | |
| 446 | + .set pop | |
| 447 | + .endm | |
| 448 | + | |
| 418 | 449 | #endif /* _ASM_ASMMACRO_H */ |
| @@ -559,7 +559,13 @@ static inline int fls(int x) · 558 unmodified lines | ||
| 559 | 559 | int r; |
| 560 | 560 | |
| 561 | 561 | if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) { |
| 562 | − __asm__("clz %0, %1" : "=r" (x) : "r" (x)); | |
| 562 | + __asm__( | |
| 563 | + " .set push \n" | |
| 564 | + " .set mips32 \n" | |
| 565 | + " clz %0, %1 \n" | |
| 566 | + " .set pop \n" | |
| 567 | + : "=r" (x) | |
| 568 | + : "r" (x)); | |
| 563 | 569 | |
| 564 | 570 | return 32 - x; |
| 565 | 571 | } |
| @@ -32,6 +32,14 @@ extern void nlm_cop2_restore(struct nlm_cop2_state *); · 31 unmodified lines | ||
| 32 | 32 | #define cop2_present 1 |
| 33 | 33 | #define cop2_lazy_restore 0 |
| 34 | 34 | |
| 35 | +#elif defined(CONFIG_CPU_LOONGSON3) | |
| 36 | + | |
| 37 | +#define cop2_save(r) | |
| 38 | +#define cop2_restore(r) | |
| 39 | + | |
| 40 | +#define cop2_present 1 | |
| 41 | +#define cop2_lazy_restore 1 | |
| 42 | + | |
| 35 | 43 | #else |
| 36 | 44 | |
| 37 | 45 | #define cop2_present 0 |
| @@ -29,6 +29,15 @@ · 28 unmodified lines | ||
| 29 | 29 | #ifndef cpu_has_eva |
| 30 | 30 | #define cpu_has_eva (cpu_data[0].options & MIPS_CPU_EVA) |
| 31 | 31 | #endif |
| 32 | +#ifndef cpu_has_htw | |
| 33 | +#define cpu_has_htw (cpu_data[0].options & MIPS_CPU_HTW) | |
| 34 | +#endif | |
| 35 | +#ifndef cpu_has_rixiex | |
| 36 | +#define cpu_has_rixiex (cpu_data[0].options & MIPS_CPU_RIXIEX) | |
| 37 | +#endif | |
| 38 | +#ifndef cpu_has_maar | |
| 39 | +#define cpu_has_maar (cpu_data[0].options & MIPS_CPU_MAAR) | |
| 40 | +#endif | |
| 32 | 41 | |
| 33 | 42 | /* |
| 34 | 43 | * For the moment we don't consider R6000 and R8000 so we can assume that |
| @@ -44,8 +44,8 @@ struct cpuinfo_mips { · 43 unmodified lines | ||
| 44 | 44 | /* |
| 45 | 45 | * Capability and feature descriptor structure for MIPS CPU |
| 46 | 46 | */ |
| 47 | − unsigned long options; | |
| 48 | 47 | unsigned long ases; |
| 48 | + unsigned long long options; | |
| 49 | 49 | unsigned int udelay_val; |
| 50 | 50 | unsigned int processor_id; |
| 51 | 51 | unsigned int fpu_id; |
| @@ -61,6 +61,7 @@ struct cpuinfo_mips { · 9 unmodified lines | ||
| 61 | 61 | struct cache_desc scache; /* Secondary cache */ |
| 62 | 62 | struct cache_desc tcache; /* Tertiary/split secondary cache */ |
| 63 | 63 | int srsets; /* Shadow register sets */ |
| 64 | + int package;/* physical package number */ | |
| 64 | 65 | int core; /* physical core number */ |
| 65 | 66 | #ifdef CONFIG_64BIT |
| 66 | 67 | int vmbits; /* Virtual memory size in bits */ |
| @@ -115,7 +116,7 @@ struct proc_cpuinfo_notifier_args { · 48 unmodified lines | ||
| 115 | 116 | #ifdef CONFIG_MIPS_MT_SMP |
| 116 | 117 | # define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) |
| 117 | 118 | #else |
| 118 | −# define cpu_vpe_id(cpuinfo) 0 | |
| 119 | +# define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) | |
| 119 | 120 | #endif |
| 120 | 121 | |
| 121 | 122 | #endif /* __ASM_CPU_INFO_H */ |
| @@ -233,6 +233,8 @@ · 232 unmodified lines | ||
| 233 | 233 | #define PRID_REV_LOONGSON2E 0x0002 |
| 234 | 234 | #define PRID_REV_LOONGSON2F 0x0003 |
| 235 | 235 | #define PRID_REV_LOONGSON3A 0x0005 |
| 236 | +#define PRID_REV_LOONGSON3B_R1 0x0006 | |
| 237 | +#define PRID_REV_LOONGSON3B_R2 0x0007 | |
| 236 | 238 | |
| 237 | 239 | /* |
| 238 | 240 | * Older processors used to encode processor version and revision in two |
| @@ -335,34 +337,37 @@ enum cpu_type_enum { · 96 unmodified lines | ||
| 335 | 337 | /* |
| 336 | 338 | * CPU Option encodings |
| 337 | 339 | */ |
| 338 | −#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ | |
| 339 | −#define MIPS_CPU_4KEX 0x00000002 /* "R4K" exception model */ | |
| 340 | −#define MIPS_CPU_3K_CACHE 0x00000004 /* R3000-style caches */ | |
| 341 | −#define MIPS_CPU_4K_CACHE 0x00000008 /* R4000-style caches */ | |
| 342 | −#define MIPS_CPU_TX39_CACHE 0x00000010 /* TX3900-style caches */ | |
| 343 | −#define MIPS_CPU_FPU 0x00000020 /* CPU has FPU */ | |
| 344 | −#define MIPS_CPU_32FPR 0x00000040 /* 32 dbl. prec. FP registers */ | |
| 345 | −#define MIPS_CPU_COUNTER 0x00000080 /* Cycle count/compare */ | |
| 346 | −#define MIPS_CPU_WATCH 0x00000100 /* watchpoint registers */ | |
| 347 | −#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ | |
| 348 | −#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ | |
| 349 | −#define MIPS_CPU_CACHE_CDEX_P 0x00000800 /* Create_Dirty_Exclusive CACHE op */ | |
| 350 | −#define MIPS_CPU_CACHE_CDEX_S 0x00001000 /* ... same for seconary cache ... */ | |
| 351 | −#define MIPS_CPU_MCHECK 0x00002000 /* Machine check exception */ | |
| 352 | −#define MIPS_CPU_EJTAG 0x00004000 /* EJTAG exception */ | |
| 353 | −#define MIPS_CPU_NOFPUEX 0x00008000 /* no FPU exception */ | |
| 354 | −#define MIPS_CPU_LLSC 0x00010000 /* CPU has ll/sc instructions */ | |
| 355 | −#define MIPS_CPU_INCLUSIVE_CACHES 0x00020000 /* P-cache subset enforced */ | |
| 356 | −#define MIPS_CPU_PREFETCH 0x00040000 /* CPU has usable prefetch */ | |
| 357 | −#define MIPS_CPU_VINT 0x00080000 /* CPU supports MIPSR2 vectored interrupts */ | |
| 358 | −#define MIPS_CPU_VEIC 0x00100000 /* CPU supports MIPSR2 external interrupt controller mode */ | |
| 359 | −#define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */ | |
| 360 | −#define MIPS_CPU_PCI 0x00400000 /* CPU has Perf Ctr Int indicator */ | |
| 361 | −#define MIPS_CPU_RIXI 0x00800000 /* CPU has TLB Read/eXec Inhibit */ | |
| 362 | −#define MIPS_CPU_MICROMIPS 0x01000000 /* CPU has microMIPS capability */ | |
| 363 | −#define MIPS_CPU_TLBINV 0x02000000 /* CPU supports TLBINV/F */ | |
| 364 | −#define MIPS_CPU_SEGMENTS 0x04000000 /* CPU supports Segmentation Control registers */ | |
| 365 | −#define MIPS_CPU_EVA 0x80000000 /* CPU supports Enhanced Virtual Addressing */ | |
| 340 | +#define MIPS_CPU_TLB 0x00000001ull /* CPU has TLB */ | |
| 341 | +#define MIPS_CPU_4KEX 0x00000002ull /* "R4K" exception model */ | |
| 342 | +#define MIPS_CPU_3K_CACHE 0x00000004ull /* R3000-style caches */ | |
| 343 | +#define MIPS_CPU_4K_CACHE 0x00000008ull /* R4000-style caches */ | |
| 344 | +#define MIPS_CPU_TX39_CACHE 0x00000010ull /* TX3900-style caches */ | |
| 345 | +#define MIPS_CPU_FPU 0x00000020ull /* CPU has FPU */ | |
| 346 | +#define MIPS_CPU_32FPR 0x00000040ull /* 32 dbl. prec. FP registers */ | |
| 347 | +#define MIPS_CPU_COUNTER 0x00000080ull /* Cycle count/compare */ | |
| 348 | +#define MIPS_CPU_WATCH 0x00000100ull /* watchpoint registers */ | |
| 349 | +#define MIPS_CPU_DIVEC 0x00000200ull /* dedicated interrupt vector */ | |
| 350 | +#define MIPS_CPU_VCE 0x00000400ull /* virt. coherence conflict possible */ | |
| 351 | +#define MIPS_CPU_CACHE_CDEX_P 0x00000800ull /* Create_Dirty_Exclusive CACHE op */ | |
| 352 | +#define MIPS_CPU_CACHE_CDEX_S 0x00001000ull /* ... same for seconary cache ... */ | |
| 353 | +#define MIPS_CPU_MCHECK 0x00002000ull /* Machine check exception */ | |
| 354 | +#define MIPS_CPU_EJTAG 0x00004000ull /* EJTAG exception */ | |
| 355 | +#define MIPS_CPU_NOFPUEX 0x00008000ull /* no FPU exception */ | |
| 356 | +#define MIPS_CPU_LLSC 0x00010000ull /* CPU has ll/sc instructions */ | |
| 357 | +#define MIPS_CPU_INCLUSIVE_CACHES 0x00020000ull /* P-cache subset enforced */ | |
| 358 | +#define MIPS_CPU_PREFETCH 0x00040000ull /* CPU has usable prefetch */ | |
| 359 | +#define MIPS_CPU_VINT 0x00080000ull /* CPU supports MIPSR2 vectored interrupts */ | |
| 360 | +#define MIPS_CPU_VEIC 0x00100000ull /* CPU supports MIPSR2 external interrupt controller mode */ | |
| 361 | +#define MIPS_CPU_ULRI 0x00200000ull /* CPU has ULRI feature */ | |
| 362 | +#define MIPS_CPU_PCI 0x00400000ull /* CPU has Perf Ctr Int indicator */ | |
| 363 | +#define MIPS_CPU_RIXI 0x00800000ull /* CPU has TLB Read/eXec Inhibit */ | |
| 364 | +#define MIPS_CPU_MICROMIPS 0x01000000ull /* CPU has microMIPS capability */ | |
| 365 | +#define MIPS_CPU_TLBINV 0x02000000ull /* CPU supports TLBINV/F */ | |
| 366 | +#define MIPS_CPU_SEGMENTS 0x04000000ull /* CPU supports Segmentation Control registers */ | |
| 367 | +#define MIPS_CPU_EVA 0x80000000ull /* CPU supports Enhanced Virtual Addressing */ | |
| 368 | +#define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ | |
| 369 | +#define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ | |
| 370 | +#define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ | |
| 366 | 371 | |
| 367 | 372 | /* |
| 368 | 373 | * CPU ASE encodings |
| @@ -339,23 +339,6 @@ do { \ · 338 unmodified lines | ||
| 339 | 339 | |
| 340 | 340 | #endif /* CONFIG_64BIT */ |
| 341 | 341 | |
| 342 | −struct pt_regs; | |
| 343 | −struct task_struct; | |
| 344 | − | |
| 345 | −extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs); | |
| 346 | −extern int dump_task_regs(struct task_struct *, elf_gregset_t *); | |
| 347 | −extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); | |
| 348 | − | |
| 349 | −#ifndef ELF_CORE_COPY_REGS | |
| 350 | −#define ELF_CORE_COPY_REGS(elf_regs, regs) \ | |
| 351 | − elf_dump_regs((elf_greg_t *)&(elf_regs), regs); | |
| 352 | −#endif | |
| 353 | −#ifndef ELF_CORE_COPY_TASK_REGS | |
| 354 | −#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) | |
| 355 | −#endif | |
| 356 | −#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ | |
| 357 | − dump_task_fpu(tsk, elf_fpregs) | |
| 358 | − | |
| 359 | 342 | #define CORE_DUMP_USE_REGSET |
| 360 | 343 | #define ELF_EXEC_PAGESIZE PAGE_SIZE |
| 361 | 344 | |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <asm/hazards.h> |
| 22 | 22 | #include <asm/processor.h> |
| 23 | 23 | #include <asm/current.h> |
| 24 | +#include <asm/msa.h> | |
| 24 | 25 | |
| 25 | 26 | #ifdef CONFIG_MIPS_MT_FPAFF |
| 26 | 27 | #include <asm/mips_mt.h> |
| @@ -141,13 +142,21 @@ static inline int own_fpu(int restore) · 114 unmodified lines | ||
| 141 | 142 | static inline void lose_fpu(int save) |
| 142 | 143 | { |
| 143 | 144 | preempt_disable(); |
| 144 | − if (is_fpu_owner()) { | |
| 145 | + if (is_msa_enabled()) { | |
| 146 | + if (save) { | |
| 147 | + save_msa(current); | |
| 148 | + asm volatile("cfc1 %0, $31" | |
| 149 | + : "=r"(current->thread.fpu.fcr31)); | |
| 150 | + } | |
| 151 | + disable_msa(); | |
| 152 | + clear_thread_flag(TIF_USEDMSA); | |
| 153 | + } else if (is_fpu_owner()) { | |
| 145 | 154 | if (save) |
| 146 | 155 | _save_fp(current); |
| 147 | − KSTK_STATUS(current) &= ~ST0_CU1; | |
| 148 | − clear_thread_flag(TIF_USEDFPU); | |
| 149 | 156 | __disable_fpu(); |
| 150 | 157 | } |
| 158 | + KSTK_STATUS(current) &= ~ST0_CU1; | |
| 159 | + clear_thread_flag(TIF_USEDFPU); | |
| 151 | 160 | preempt_enable(); |
| 152 | 161 | } |
| 153 | 162 | |
| @@ -155,8 +164,6 @@ static inline int init_fpu(void) · 1 unmodified line | ||
| 155 | 164 | { |
| 156 | 165 | int ret = 0; |
| 157 | 166 | |
| 158 | − preempt_disable(); | |
| 159 | − | |
| 160 | 167 | if (cpu_has_fpu) { |
| 161 | 168 | ret = __own_fpu(); |
| 162 | 169 | if (!ret) |
| @@ -164,8 +171,6 @@ static inline int init_fpu(void) · 1 unmodified line | ||
| 164 | 171 | } else |
| 165 | 172 | fpu_emulator_init_fpu(); |
| 166 | 173 | |
| 167 | − preempt_enable(); | |
| 168 | − | |
| 169 | 174 | return ret; |
| 170 | 175 | } |
| 171 | 176 | |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/bitmap.h> |
| 15 | 15 | #include <linux/threads.h> |
| 16 | 16 | |
| 17 | +#include <irq.h> | |
| 18 | + | |
| 17 | 19 | #undef GICISBYTELITTLEENDIAN |
| 18 | 20 | |
| 19 | 21 | /* Constants */ |
| @@ -22,8 +24,6 @@ · 2 unmodified lines | ||
| 22 | 24 | #define GIC_TRIG_EDGE 1 |
| 23 | 25 | #define GIC_TRIG_LEVEL 0 |
| 24 | 26 | |
| 25 | −#define GIC_NUM_INTRS (24 + NR_CPUS * 2) | |
| 26 | − | |
| 27 | 27 | #define MSK(n) ((1 << (n)) - 1) |
| 28 | 28 | #define REG32(addr) (*(volatile unsigned int *) (addr)) |
| 29 | 29 | #define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) |
| @@ -43,18 +43,17 @@ · 13 unmodified lines | ||
| 43 | 43 | #ifdef GICISBYTELITTLEENDIAN |
| 44 | 44 | #define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) |
| 45 | 45 | #define GICWRITE(reg, data) ((reg) = cpu_to_le32(data)) |
| 46 | −#define GICBIS(reg, bits) \ | |
| 47 | − ({unsigned int data; \ | |
| 48 | − GICREAD(reg, data); \ | |
| 49 | − data |= bits; \ | |
| 50 | − GICWRITE(reg, data); \ | |
| 51 | − }) | |
| 52 | − | |
| 53 | 46 | #else |
| 54 | 47 | #define GICREAD(reg, data) ((data) = (reg)) |
| 55 | 48 | #define GICWRITE(reg, data) ((reg) = (data)) |
| 56 | −#define GICBIS(reg, bits) ((reg) |= (bits)) | |
| 57 | 49 | #endif |
| 50 | +#define GICBIS(reg, mask, bits) \ | |
| 51 | + do { u32 data; \ | |
| 52 | + GICREAD((reg), data); \ | |
| 53 | + data &= ~(mask); \ | |
| 54 | + data |= ((bits) & (mask)); \ | |
| 55 | + GICWRITE((reg), data); \ | |
| 56 | + } while (0) | |
| 58 | 57 | |
| 59 | 58 | |
| 60 | 59 | /* GIC Address Space */ |
| @@ -170,13 +169,15 @@ · 109 unmodified lines | ||
| 170 | 169 | #define GIC_SH_SET_POLARITY_OFS 0x0100 |
| 171 | 170 | #define GIC_SET_POLARITY(intr, pol) \ |
| 172 | 171 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ |
| 173 | − GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr)) | |
| 172 | + GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | |
| 173 | + (pol) << GIC_INTR_BIT(intr)) | |
| 174 | 174 | |
| 175 | 175 | /* Triggering : Reset Value is always 0 */ |
| 176 | 176 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 |
| 177 | 177 | #define GIC_SET_TRIGGER(intr, trig) \ |
| 178 | 178 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ |
| 179 | − GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr)) | |
| 179 | + GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | |
| 180 | + (trig) << GIC_INTR_BIT(intr)) | |
| 180 | 181 | |
| 181 | 182 | /* Mask manipulation */ |
| 182 | 183 | #define GIC_SH_SMASK_OFS 0x0380 |
| @@ -306,18 +307,6 @@ · 123 unmodified lines | ||
| 306 | 307 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ |
| 307 | 308 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) |
| 308 | 309 | |
| 309 | −struct gic_pcpu_mask { | |
| 310 | − DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | |
| 311 | −}; | |
| 312 | − | |
| 313 | −struct gic_pending_regs { | |
| 314 | − DECLARE_BITMAP(pending, GIC_NUM_INTRS); | |
| 315 | −}; | |
| 316 | − | |
| 317 | −struct gic_intrmask_regs { | |
| 318 | − DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | |
| 319 | −}; | |
| 320 | − | |
| 321 | 310 | /* |
| 322 | 311 | * Interrupt Meta-data specification. The ipiflag helps |
| 323 | 312 | * in building ipi_map. |
| @@ -329,8 +318,7 @@ struct gic_intr_map { · 5 unmodified lines | ||
| 329 | 318 | unsigned int polarity; /* Polarity : +/- */ |
| 330 | 319 | unsigned int trigtype; /* Trigger : Edge/Levl */ |
| 331 | 320 | unsigned int flags; /* Misc flags */ |
| 332 | −#define GIC_FLAG_IPI 0x01 | |
| 333 | −#define GIC_FLAG_TRANSPARENT 0x02 | |
| 321 | +#define GIC_FLAG_TRANSPARENT 0x01 | |
| 334 | 322 | }; |
| 335 | 323 | |
| 336 | 324 | /* |
| @@ -386,6 +374,7 @@ extern unsigned int plat_ipi_call_int_xlate(unsigned int); · 49 unmodified lines | ||
| 386 | 374 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
| 387 | 375 | extern void gic_bind_eic_interrupt(int irq, int set); |
| 388 | 376 | extern unsigned int gic_get_timer_pending(void); |
| 377 | +extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); | |
| 389 | 378 | extern unsigned int gic_get_int(void); |
| 390 | 379 | extern void gic_enable_interrupt(int irq_vec); |
| 391 | 380 | extern void gic_disable_interrupt(int irq_vec); |
| @@ -0,0 +1,109 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2014 Imagination Technologies | |
| 3 | + * Author: Paul Burton <paul.burton@imgtec.com> | |
| 4 | + * | |
| 5 | + * This program is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License as published by the | |
| 7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 8 | + * option) any later version. | |
| 9 | + */ | |
| 10 | + | |
| 11 | +#ifndef __MIPS_ASM_MIPS_MAAR_H__ | |
| 12 | +#define __MIPS_ASM_MIPS_MAAR_H__ | |
| 13 | + | |
| 14 | +#include <asm/hazards.h> | |
| 15 | +#include <asm/mipsregs.h> | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * platform_maar_init() - perform platform-level MAAR configuration | |
| 19 | + * @num_pairs: The number of MAAR pairs present in the system. | |
| 20 | + * | |
| 21 | + * Platforms should implement this function such that it configures as many | |
| 22 | + * MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns | |
| 23 | + * the number that were used. Any further MAARs will be configured to be | |
| 24 | + * invalid. The default implementation of this function will simply indicate | |
| 25 | + * that it has configured 0 MAAR pairs. | |
| 26 | + * | |
| 27 | + * Return: The number of MAAR pairs configured. | |
| 28 | + */ | |
| 29 | +unsigned __weak platform_maar_init(unsigned num_pairs); | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * write_maar_pair() - write to a pair of MAARs | |
| 33 | + * @idx: The index of the pair (ie. use MAARs idx*2 & (idx*2)+1). | |
| 34 | + * @lower: The lowest address that the MAAR pair will affect. Must be | |
| 35 | + * aligned to a 2^16 byte boundary. | |
| 36 | + * @upper: The highest address that the MAAR pair will affect. Must be | |
| 37 | + * aligned to one byte before a 2^16 byte boundary. | |
| 38 | + * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The | |
| 39 | + * MIPS_MAAR_V attribute will automatically be set. | |
| 40 | + * | |
| 41 | + * Program the pair of MAAR registers specified by idx to apply the attributes | |
| 42 | + * specified by attrs to the range of addresses from lower to higher. | |
| 43 | + */ | |
| 44 | +static inline void write_maar_pair(unsigned idx, phys_addr_t lower, | |
| 45 | + phys_addr_t upper, unsigned attrs) | |
| 46 | +{ | |
| 47 | + /* Addresses begin at bit 16, but are shifted right 4 bits */ | |
| 48 | + BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4))); | |
| 49 | + BUG_ON(((upper & 0xffff) != 0xffff) | |
| 50 | + || ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4))); | |
| 51 | + | |
| 52 | + /* Automatically set MIPS_MAAR_V */ | |
| 53 | + attrs |= MIPS_MAAR_V; | |
| 54 | + | |
| 55 | + /* Write the upper address & attributes (only MIPS_MAAR_V matters) */ | |
| 56 | + write_c0_maari(idx << 1); | |
| 57 | + back_to_back_c0_hazard(); | |
| 58 | + write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs); | |
| 59 | + back_to_back_c0_hazard(); | |
| 60 | + | |
| 61 | + /* Write the lower address & attributes */ | |
| 62 | + write_c0_maari((idx << 1) | 0x1); | |
| 63 | + back_to_back_c0_hazard(); | |
| 64 | + write_c0_maar((lower >> 4) | attrs); | |
| 65 | + back_to_back_c0_hazard(); | |
| 66 | +} | |
| 67 | + | |
| 68 | +/** | |
| 69 | + * struct maar_config - MAAR configuration data | |
| 70 | + * @lower: The lowest address that the MAAR pair will affect. Must be | |
| 71 | + * aligned to a 2^16 byte boundary. | |
| 72 | + * @upper: The highest address that the MAAR pair will affect. Must be | |
| 73 | + * aligned to one byte before a 2^16 byte boundary. | |
| 74 | + * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The | |
| 75 | + * MIPS_MAAR_V attribute will automatically be set. | |
| 76 | + * | |
| 77 | + * Describes the configuration of a pair of Memory Accessibility Attribute | |
| 78 | + * Registers - applying attributes from attrs to the range of physical | |
| 79 | + * addresses from lower to upper inclusive. | |
| 80 | + */ | |
| 81 | +struct maar_config { | |
| 82 | + phys_addr_t lower; | |
| 83 | + phys_addr_t upper; | |
| 84 | + unsigned attrs; | |
| 85 | +}; | |
| 86 | + | |
| 87 | +/** | |
| 88 | + * maar_config() - configure MAARs according to provided data | |
| 89 | + * @cfg: Pointer to an array of struct maar_config. | |
| 90 | + * @num_cfg: The number of structs in the cfg array. | |
| 91 | + * @num_pairs: The number of MAAR pairs present in the system. | |
| 92 | + * | |
| 93 | + * Configures as many MAARs as are present and specified in the cfg | |
| 94 | + * array with the values taken from the cfg array. | |
| 95 | + * | |
| 96 | + * Return: The number of MAAR pairs configured. | |
| 97 | + */ | |
| 98 | +static inline unsigned maar_config(const struct maar_config *cfg, | |
| 99 | + unsigned num_cfg, unsigned num_pairs) | |
| 100 | +{ | |
| 101 | + unsigned i; | |
| 102 | + | |
| 103 | + for (i = 0; i < min(num_cfg, num_pairs); i++) | |
| 104 | + write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs); | |
| 105 | + | |
| 106 | + return i; | |
| 107 | +} | |
| 108 | + | |
| 109 | +#endif /* __MIPS_ASM_MIPS_MAAR_H__ */ | |
| @@ -34,1529 +34,1178 @@ · 33 unmodified lines | ||
| 34 | 34 | #ifndef _AU1000_H_ |
| 35 | 35 | #define _AU1000_H_ |
| 36 | 36 | |
| 37 | +/* SOC Interrupt numbers */ | |
| 38 | +/* Au1000-style (IC0/1): 2 controllers with 32 sources each */ | |
| 39 | +#define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | |
| 40 | +#define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31) | |
| 41 | +#define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_LAST + 1) | |
| 42 | +#define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31) | |
| 43 | +#define AU1000_MAX_INTR AU1000_INTC1_INT_LAST | |
| 37 | 44 | |
| 38 | −#ifndef _LANGUAGE_ASSEMBLY | |
| 45 | +/* Au1300-style (GPIC): 1 controller with up to 128 sources */ | |
| 46 | +#define ALCHEMY_GPIC_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | |
| 47 | +#define ALCHEMY_GPIC_INT_NUM 128 | |
| 48 | +#define ALCHEMY_GPIC_INT_LAST (ALCHEMY_GPIC_INT_BASE + ALCHEMY_GPIC_INT_NUM - 1) | |
| 39 | 49 | |
| 40 | −#include <linux/delay.h> | |
| 41 | −#include <linux/types.h> | |
| 50 | +/* common clock names, shared among all variants. AUXPLL2 is Au1300 */ | |
| 51 | +#define ALCHEMY_ROOT_CLK "root_clk" | |
| 52 | +#define ALCHEMY_CPU_CLK "cpu_clk" | |
| 53 | +#define ALCHEMY_AUXPLL_CLK "auxpll_clk" | |
| 54 | +#define ALCHEMY_AUXPLL2_CLK "auxpll2_clk" | |
| 55 | +#define ALCHEMY_SYSBUS_CLK "sysbus_clk" | |
| 56 | +#define ALCHEMY_PERIPH_CLK "periph_clk" | |
| 57 | +#define ALCHEMY_MEM_CLK "mem_clk" | |
| 58 | +#define ALCHEMY_LR_CLK "lr_clk" | |
| 59 | +#define ALCHEMY_FG0_CLK "fg0_clk" | |
| 60 | +#define ALCHEMY_FG1_CLK "fg1_clk" | |
| 61 | +#define ALCHEMY_FG2_CLK "fg2_clk" | |
| 62 | +#define ALCHEMY_FG3_CLK "fg3_clk" | |
| 63 | +#define ALCHEMY_FG4_CLK "fg4_clk" | |
| 64 | +#define ALCHEMY_FG5_CLK "fg5_clk" | |
| 42 | 65 | |
| 43 | −#include <linux/io.h> | |
| 44 | −#include <linux/irq.h> | |
| 66 | +/* Au1300 peripheral interrupt numbers */ | |
| 67 | +#define AU1300_FIRST_INT (ALCHEMY_GPIC_INT_BASE) | |
| 68 | +#define AU1300_UART1_INT (AU1300_FIRST_INT + 17) | |
| 69 | +#define AU1300_UART2_INT (AU1300_FIRST_INT + 25) | |
| 70 | +#define AU1300_UART3_INT (AU1300_FIRST_INT + 27) | |
| 71 | +#define AU1300_SD1_INT (AU1300_FIRST_INT + 32) | |
| 72 | +#define AU1300_SD2_INT (AU1300_FIRST_INT + 38) | |
| 73 | +#define AU1300_PSC0_INT (AU1300_FIRST_INT + 48) | |
| 74 | +#define AU1300_PSC1_INT (AU1300_FIRST_INT + 52) | |
| 75 | +#define AU1300_PSC2_INT (AU1300_FIRST_INT + 56) | |
| 76 | +#define AU1300_PSC3_INT (AU1300_FIRST_INT + 60) | |
| 77 | +#define AU1300_NAND_INT (AU1300_FIRST_INT + 62) | |
| 78 | +#define AU1300_DDMA_INT (AU1300_FIRST_INT + 75) | |
| 79 | +#define AU1300_MMU_INT (AU1300_FIRST_INT + 76) | |
| 80 | +#define AU1300_MPU_INT (AU1300_FIRST_INT + 77) | |
| 81 | +#define AU1300_GPU_INT (AU1300_FIRST_INT + 78) | |
| 82 | +#define AU1300_UDMA_INT (AU1300_FIRST_INT + 79) | |
| 83 | +#define AU1300_TOY_INT (AU1300_FIRST_INT + 80) | |
| 84 | +#define AU1300_TOY_MATCH0_INT (AU1300_FIRST_INT + 81) | |
| 85 | +#define AU1300_TOY_MATCH1_INT (AU1300_FIRST_INT + 82) | |
| 86 | +#define AU1300_TOY_MATCH2_INT (AU1300_FIRST_INT + 83) | |
| 87 | +#define AU1300_RTC_INT (AU1300_FIRST_INT + 84) | |
| 88 | +#define AU1300_RTC_MATCH0_INT (AU1300_FIRST_INT + 85) | |
| 89 | +#define AU1300_RTC_MATCH1_INT (AU1300_FIRST_INT + 86) | |
| 90 | +#define AU1300_RTC_MATCH2_INT (AU1300_FIRST_INT + 87) | |
| 91 | +#define AU1300_UART0_INT (AU1300_FIRST_INT + 88) | |
| 92 | +#define AU1300_SD0_INT (AU1300_FIRST_INT + 89) | |
| 93 | +#define AU1300_USB_INT (AU1300_FIRST_INT + 90) | |
| 94 | +#define AU1300_LCD_INT (AU1300_FIRST_INT + 91) | |
| 95 | +#define AU1300_BSA_INT (AU1300_FIRST_INT + 92) | |
| 96 | +#define AU1300_MPE_INT (AU1300_FIRST_INT + 93) | |
| 97 | +#define AU1300_ITE_INT (AU1300_FIRST_INT + 94) | |
| 98 | +#define AU1300_AES_INT (AU1300_FIRST_INT + 95) | |
| 99 | +#define AU1300_CIM_INT (AU1300_FIRST_INT + 96) | |
| 45 | 100 | |
| 46 | −#include <asm/cpu.h> | |
| 101 | +/**********************************************************************/ | |
| 47 | 102 | |
| 48 | −/* cpu pipeline flush */ | |
| 49 | −void static inline au_sync(void) | |
| 50 | −{ | |
| 51 | − __asm__ volatile ("sync"); | |
| 52 | −} | |
| 103 | +/* | |
| 104 | + * Physical base addresses for integrated peripherals | |
| 105 | + * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 5..au1300 | |
| 106 | + */ | |
| 53 | 107 | |
| 54 | −void static inline au_sync_udelay(int us) | |
| 55 | −{ | |
| 56 | − __asm__ volatile ("sync"); | |
| 57 | − udelay(us); | |
| 58 | −} | |
| 108 | +#define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ | |
| 109 | +#define AU1300_ROM_PHYS_ADDR 0x10000000 /* 5 */ | |
| 110 | +#define AU1300_OTP_PHYS_ADDR 0x10002000 /* 5 */ | |
| 111 | +#define AU1300_VSS_PHYS_ADDR 0x10003000 /* 5 */ | |
| 112 | +#define AU1300_UART0_PHYS_ADDR 0x10100000 /* 5 */ | |
| 113 | +#define AU1300_UART1_PHYS_ADDR 0x10101000 /* 5 */ | |
| 114 | +#define AU1300_UART2_PHYS_ADDR 0x10102000 /* 5 */ | |
| 115 | +#define AU1300_UART3_PHYS_ADDR 0x10103000 /* 5 */ | |
| 116 | +#define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */ | |
| 117 | +#define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */ | |
| 118 | +#define AU1300_GPIC_PHYS_ADDR 0x10200000 /* 5 */ | |
| 119 | +#define AU1000_IRDA_PHYS_ADDR 0x10300000 /* 02 */ | |
| 120 | +#define AU1200_AES_PHYS_ADDR 0x10300000 /* 45 */ | |
| 121 | +#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | |
| 122 | +#define AU1300_GPU_PHYS_ADDR 0x10500000 /* 5 */ | |
| 123 | +#define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | |
| 124 | +#define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | |
| 125 | +#define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */ | |
| 126 | +#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 245 */ | |
| 127 | +#define AU1300_SD1_PHYS_ADDR 0x10601000 /* 5 */ | |
| 128 | +#define AU1300_SD2_PHYS_ADDR 0x10602000 /* 5 */ | |
| 129 | +#define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */ | |
| 130 | +#define AU1300_SYS_PHYS_ADDR 0x10900000 /* 5 */ | |
| 131 | +#define AU1550_PSC2_PHYS_ADDR 0x10A00000 /* 3 */ | |
| 132 | +#define AU1550_PSC3_PHYS_ADDR 0x10B00000 /* 3 */ | |
| 133 | +#define AU1300_PSC0_PHYS_ADDR 0x10A00000 /* 5 */ | |
| 134 | +#define AU1300_PSC1_PHYS_ADDR 0x10A01000 /* 5 */ | |
| 135 | +#define AU1300_PSC2_PHYS_ADDR 0x10A02000 /* 5 */ | |
| 136 | +#define AU1300_PSC3_PHYS_ADDR 0x10A03000 /* 5 */ | |
| 137 | +#define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */ | |
| 138 | +#define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */ | |
| 139 | +#define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */ | |
| 140 | +#define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */ | |
| 141 | +#define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */ | |
| 142 | +#define AU1200_SWCNT_PHYS_ADDR 0x1110010C /* 4 */ | |
| 143 | +#define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */ | |
| 144 | +#define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */ | |
| 145 | +#define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */ | |
| 146 | +#define AU1000_SSI0_PHYS_ADDR 0x11600000 /* 02 */ | |
| 147 | +#define AU1000_SSI1_PHYS_ADDR 0x11680000 /* 02 */ | |
| 148 | +#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */ | |
| 149 | +#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ | |
| 150 | +#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 012345 */ | |
| 151 | +#define AU1550_PSC0_PHYS_ADDR 0x11A00000 /* 34 */ | |
| 152 | +#define AU1550_PSC1_PHYS_ADDR 0x11B00000 /* 34 */ | |
| 153 | +#define AU1000_MEM_PHYS_ADDR 0x14000000 /* 01234 */ | |
| 154 | +#define AU1000_STATIC_MEM_PHYS_ADDR 0x14001000 /* 01234 */ | |
| 155 | +#define AU1300_UDMA_PHYS_ADDR 0x14001800 /* 5 */ | |
| 156 | +#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */ | |
| 157 | +#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 345 */ | |
| 158 | +#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 345 */ | |
| 159 | +#define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | |
| 160 | +#define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | |
| 161 | +#define AU1200_CIM_PHYS_ADDR 0x14004000 /* 45 */ | |
| 162 | +#define AU1500_PCI_PHYS_ADDR 0x14005000 /* 13 */ | |
| 163 | +#define AU1550_PE_PHYS_ADDR 0x14008000 /* 3 */ | |
| 164 | +#define AU1200_MAEBE_PHYS_ADDR 0x14010000 /* 4 */ | |
| 165 | +#define AU1200_MAEFE_PHYS_ADDR 0x14012000 /* 4 */ | |
| 166 | +#define AU1300_MAEITE_PHYS_ADDR 0x14010000 /* 5 */ | |
| 167 | +#define AU1300_MAEMPE_PHYS_ADDR 0x14014000 /* 5 */ | |
| 168 | +#define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */ | |
| 169 | +#define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */ | |
| 170 | +#define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */ | |
| 171 | +#define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */ | |
| 172 | +#define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */ | |
| 173 | +#define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */ | |
| 174 | +#define AU1300_USB_EHCI_PHYS_ADDR 0x14020000 /* 5 */ | |
| 175 | +#define AU1300_USB_OHCI0_PHYS_ADDR 0x14020400 /* 5 */ | |
| 176 | +#define AU1300_USB_OHCI1_PHYS_ADDR 0x14020800 /* 5 */ | |
| 177 | +#define AU1300_USB_CTL_PHYS_ADDR 0x14021000 /* 5 */ | |
| 178 | +#define AU1300_USB_OTG_PHYS_ADDR 0x14022000 /* 5 */ | |
| 179 | +#define AU1300_MAEBSA_PHYS_ADDR 0x14030000 /* 5 */ | |
| 180 | +#define AU1100_LCD_PHYS_ADDR 0x15000000 /* 2 */ | |
| 181 | +#define AU1200_LCD_PHYS_ADDR 0x15000000 /* 45 */ | |
| 182 | +#define AU1500_PCI_MEM_PHYS_ADDR 0x400000000ULL /* 13 */ | |
| 183 | +#define AU1500_PCI_IO_PHYS_ADDR 0x500000000ULL /* 13 */ | |
| 184 | +#define AU1500_PCI_CONFIG0_PHYS_ADDR 0x600000000ULL /* 13 */ | |
| 185 | +#define AU1500_PCI_CONFIG1_PHYS_ADDR 0x680000000ULL /* 13 */ | |
| 186 | +#define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 012345 */ | |
| 187 | +#define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 012345 */ | |
| 188 | +#define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 012345 */ | |
| 59 | 189 | |
| 60 | −void static inline au_sync_delay(int ms) | |
| 61 | −{ | |
| 62 | − __asm__ volatile ("sync"); | |
| 63 | − mdelay(ms); | |
| 64 | −} | |
| 190 | +/**********************************************************************/ | |
| 65 | 191 | |
| 66 | −void static inline au_writeb(u8 val, unsigned long reg) | |
| 67 | −{ | |
| 68 | − *(volatile u8 *)reg = val; | |
| 69 | −} | |
| 70 | 192 | |
| 71 | −void static inline au_writew(u16 val, unsigned long reg) | |
| 72 | −{ | |
| 73 | − *(volatile u16 *)reg = val; | |
| 74 | −} | |
| 193 | +/* | |
| 194 | + * Au1300 GPIO+INT controller (GPIC) register offsets and bits | |
| 195 | + * Registers are 128bits (0x10 bytes), divided into 4 "banks". | |
| 196 | + */ | |
| 197 | +#define AU1300_GPIC_PINVAL 0x0000 | |
| 198 | +#define AU1300_GPIC_PINVALCLR 0x0010 | |
| 199 | +#define AU1300_GPIC_IPEND 0x0020 | |
| 200 | +#define AU1300_GPIC_PRIENC 0x0030 | |
| 201 | +#define AU1300_GPIC_IEN 0x0040 /* int_mask in manual */ | |
| 202 | +#define AU1300_GPIC_IDIS 0x0050 /* int_maskclr in manual */ | |
| 203 | +#define AU1300_GPIC_DMASEL 0x0060 | |
| 204 | +#define AU1300_GPIC_DEVSEL 0x0080 | |
| 205 | +#define AU1300_GPIC_DEVCLR 0x0090 | |
| 206 | +#define AU1300_GPIC_RSTVAL 0x00a0 | |
| 207 | +/* pin configuration space. one 32bit register for up to 128 IRQs */ | |
| 208 | +#define AU1300_GPIC_PINCFG 0x1000 | |
| 75 | 209 | |
| 76 | −void static inline au_writel(u32 val, unsigned long reg) | |
| 77 | −{ | |
| 78 | − *(volatile u32 *)reg = val; | |
| 79 | −} | |
| 210 | +#define GPIC_GPIO_TO_BIT(gpio) \ | |
| 211 | + (1 << ((gpio) & 0x1f)) | |
| 80 | 212 | |
| 81 | −static inline u8 au_readb(unsigned long reg) | |
| 82 | −{ | |
| 83 | − return *(volatile u8 *)reg; | |
| 84 | −} | |
| 213 | +#define GPIC_GPIO_BANKOFF(gpio) \ | |
| 214 | + (((gpio) >> 5) * 4) | |
| 85 | 215 | |
| 86 | −static inline u16 au_readw(unsigned long reg) | |
| 87 | −{ | |
| 88 | − return *(volatile u16 *)reg; | |
| 89 | −} | |
| 216 | +/* Pin Control bits: who owns the pin, what does it do */ | |
| 217 | +#define GPIC_CFG_PC_GPIN 0 | |
| 218 | +#define GPIC_CFG_PC_DEV 1 | |
| 219 | +#define GPIC_CFG_PC_GPOLOW 2 | |
| 220 | +#define GPIC_CFG_PC_GPOHIGH 3 | |
| 221 | +#define GPIC_CFG_PC_MASK 3 | |
| 90 | 222 | |
| 91 | −static inline u32 au_readl(unsigned long reg) | |
| 92 | −{ | |
| 93 | − return *(volatile u32 *)reg; | |
| 94 | −} | |
| 223 | +/* assign pin to MIPS IRQ line */ | |
| 224 | +#define GPIC_CFG_IL_SET(x) (((x) & 3) << 2) | |
| 225 | +#define GPIC_CFG_IL_MASK (3 << 2) | |
| 95 | 226 | |
| 96 | −/* Early Au1000 have a write-only SYS_CPUPLL register. */ | |
| 97 | −static inline int au1xxx_cpu_has_pll_wo(void) | |
| 98 | −{ | |
| 99 | − switch (read_c0_prid()) { | |
| 100 | − case 0x00030100: /* Au1000 DA */ | |
| 101 | − case 0x00030201: /* Au1000 HA */ | |
| 102 | − case 0x00030202: /* Au1000 HB */ | |
| 103 | − return 1; | |
| 104 | − } | |
| 105 | − return 0; | |
| 106 | −} | |
| 227 | +/* pin interrupt type setup */ | |
| 228 | +#define GPIC_CFG_IC_OFF (0 << 4) | |
| 229 | +#define GPIC_CFG_IC_LEVEL_LOW (1 << 4) | |
| 230 | +#define GPIC_CFG_IC_LEVEL_HIGH (2 << 4) | |
| 231 | +#define GPIC_CFG_IC_EDGE_FALL (5 << 4) | |
| 232 | +#define GPIC_CFG_IC_EDGE_RISE (6 << 4) | |
| 233 | +#define GPIC_CFG_IC_EDGE_BOTH (7 << 4) | |
| 234 | +#define GPIC_CFG_IC_MASK (7 << 4) | |
| 107 | 235 | |
| 108 | −/* does CPU need CONFIG[OD] set to fix tons of errata? */ | |
| 109 | −static inline int au1xxx_cpu_needs_config_od(void) | |
| 110 | −{ | |
| 111 | − /* | |
| 112 | − * c0_config.od (bit 19) was write only (and read as 0) on the | |
| 113 | − * early revisions of Alchemy SOCs. It disables the bus trans- | |
| 114 | − * action overlapping and needs to be set to fix various errata. | |
| 115 | − */ | |
| 116 | − switch (read_c0_prid()) { | |
| 117 | − case 0x00030100: /* Au1000 DA */ | |
| 118 | − case 0x00030201: /* Au1000 HA */ | |
| 119 | − case 0x00030202: /* Au1000 HB */ | |
| 120 | − case 0x01030200: /* Au1500 AB */ | |
| 121 | − /* | |
| 122 | − * Au1100/Au1200 errata actually keep silence about this bit, | |
| 123 | − * so we set it just in case for those revisions that require | |
| 124 | − * it to be set according to the (now gone) cpu_table. | |
| 125 | − */ | |
| 126 | − case 0x02030200: /* Au1100 AB */ | |
| 127 | − case 0x02030201: /* Au1100 BA */ | |
| 128 | − case 0x02030202: /* Au1100 BC */ | |
| 129 | − case 0x04030201: /* Au1200 AC */ | |
| 130 | − return 1; | |
| 131 | − } | |
| 132 | − return 0; | |
| 133 | −} | |
| 236 | +/* allow interrupt to wake cpu from 'wait' */ | |
| 237 | +#define GPIC_CFG_IDLEWAKE (1 << 7) | |
| 134 | 238 | |
| 135 | −#define ALCHEMY_CPU_UNKNOWN -1 | |
| 136 | −#define ALCHEMY_CPU_AU1000 0 | |
| 137 | −#define ALCHEMY_CPU_AU1500 1 | |
| 138 | −#define ALCHEMY_CPU_AU1100 2 | |
| 139 | −#define ALCHEMY_CPU_AU1550 3 | |
| 140 | −#define ALCHEMY_CPU_AU1200 4 | |
| 141 | −#define ALCHEMY_CPU_AU1300 5 | |
| 239 | +/***********************************************************************/ | |
| 142 | 240 | |
| 143 | −static inline int alchemy_get_cputype(void) | |
| 144 | −{ | |
| 145 | − switch (read_c0_prid() & (PRID_OPT_MASK | PRID_COMP_MASK)) { | |
| 146 | − case 0x00030000: | |
| 147 | − return ALCHEMY_CPU_AU1000; | |
| 148 | − break; | |
| 149 | − case 0x01030000: | |
| 150 | − return ALCHEMY_CPU_AU1500; | |
| 151 | − break; | |
| 152 | − case 0x02030000: | |
| 153 | − return ALCHEMY_CPU_AU1100; | |
| 154 | − break; | |
| 155 | − case 0x03030000: | |
| 156 | − return ALCHEMY_CPU_AU1550; | |
| 157 | − break; | |
| 158 | − case 0x04030000: | |
| 159 | − case 0x05030000: | |
| 160 | − return ALCHEMY_CPU_AU1200; | |
| 161 | − break; | |
| 162 | − case 0x800c0000: | |
| 163 | − return ALCHEMY_CPU_AU1300; | |
| 164 | − break; | |
| 165 | − } | |
| 241 | +/* Au1000 SDRAM memory controller register offsets */ | |
| 242 | +#define AU1000_MEM_SDMODE0 0x0000 | |
| 243 | +#define AU1000_MEM_SDMODE1 0x0004 | |
| 244 | +#define AU1000_MEM_SDMODE2 0x0008 | |
| 245 | +#define AU1000_MEM_SDADDR0 0x000C | |
| 246 | +#define AU1000_MEM_SDADDR1 0x0010 | |
| 247 | +#define AU1000_MEM_SDADDR2 0x0014 | |
| 248 | +#define AU1000_MEM_SDREFCFG 0x0018 | |
| 249 | +#define AU1000_MEM_SDPRECMD 0x001C | |
| 250 | +#define AU1000_MEM_SDAUTOREF 0x0020 | |
| 251 | +#define AU1000_MEM_SDWRMD0 0x0024 | |
| 252 | +#define AU1000_MEM_SDWRMD1 0x0028 | |
| 253 | +#define AU1000_MEM_SDWRMD2 0x002C | |
| 254 | +#define AU1000_MEM_SDSLEEP 0x0030 | |
| 255 | +#define AU1000_MEM_SDSMCKE 0x0034 | |
| 166 | 256 | |
| 167 | − return ALCHEMY_CPU_UNKNOWN; | |
| 168 | −} | |
| 257 | +/* MEM_SDMODE register content definitions */ | |
| 258 | +#define MEM_SDMODE_F (1 << 22) | |
| 259 | +#define MEM_SDMODE_SR (1 << 21) | |
| 260 | +#define MEM_SDMODE_BS (1 << 20) | |
| 261 | +#define MEM_SDMODE_RS (3 << 18) | |
| 262 | +#define MEM_SDMODE_CS (7 << 15) | |
| 263 | +#define MEM_SDMODE_TRAS (15 << 11) | |
| 264 | +#define MEM_SDMODE_TMRD (3 << 9) | |
| 265 | +#define MEM_SDMODE_TWR (3 << 7) | |
| 266 | +#define MEM_SDMODE_TRP (3 << 5) | |
| 267 | +#define MEM_SDMODE_TRCD (3 << 3) | |
| 268 | +#define MEM_SDMODE_TCL (7 << 0) | |
| 169 | 269 | |
| 170 | −/* return number of uarts on a given cputype */ | |
| 171 | −static inline int alchemy_get_uarts(int type) | |
| 172 | −{ | |
| 173 | − switch (type) { | |
| 174 | − case ALCHEMY_CPU_AU1000: | |
| 175 | − case ALCHEMY_CPU_AU1300: | |
| 176 | − return 4; | |
| 177 | − case ALCHEMY_CPU_AU1500: | |
| 178 | − case ALCHEMY_CPU_AU1200: | |
| 179 | − return 2; | |
| 180 | − case ALCHEMY_CPU_AU1100: | |
| 181 | − case ALCHEMY_CPU_AU1550: | |
| 182 | − return 3; | |
| 183 | − } | |
| 184 | − return 0; | |
| 185 | −} | |
| 270 | +#define MEM_SDMODE_BS_2Bank (0 << 20) | |
| 271 | +#define MEM_SDMODE_BS_4Bank (1 << 20) | |
| 272 | +#define MEM_SDMODE_RS_11Row (0 << 18) | |
| 273 | +#define MEM_SDMODE_RS_12Row (1 << 18) | |
| 274 | +#define MEM_SDMODE_RS_13Row (2 << 18) | |
| 275 | +#define MEM_SDMODE_RS_N(N) ((N) << 18) | |
| 276 | +#define MEM_SDMODE_CS_7Col (0 << 15) | |
| 277 | +#define MEM_SDMODE_CS_8Col (1 << 15) | |
| 278 | +#define MEM_SDMODE_CS_9Col (2 << 15) | |
| 279 | +#define MEM_SDMODE_CS_10Col (3 << 15) | |
| 280 | +#define MEM_SDMODE_CS_11Col (4 << 15) | |
| 281 | +#define MEM_SDMODE_CS_N(N) ((N) << 15) | |
| 282 | +#define MEM_SDMODE_TRAS_N(N) ((N) << 11) | |
| 283 | +#define MEM_SDMODE_TMRD_N(N) ((N) << 9) | |
| 284 | +#define MEM_SDMODE_TWR_N(N) ((N) << 7) | |
| 285 | +#define MEM_SDMODE_TRP_N(N) ((N) << 5) | |
| 286 | +#define MEM_SDMODE_TRCD_N(N) ((N) << 3) | |
| 287 | +#define MEM_SDMODE_TCL_N(N) ((N) << 0) | |
| 186 | 288 | |
| 187 | −/* enable an UART block if it isn't already */ | |
| 188 | −static inline void alchemy_uart_enable(u32 uart_phys) | |
| 189 | −{ | |
| 190 | − void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); | |
| 289 | +/* MEM_SDADDR register contents definitions */ | |
| 290 | +#define MEM_SDADDR_E (1 << 20) | |
| 291 | +#define MEM_SDADDR_CSBA (0x03FF << 10) | |
| 292 | +#define MEM_SDADDR_CSMASK (0x03FF << 0) | |
| 293 | +#define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) | |
| 294 | +#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) | |
| 191 | 295 | |
| 192 | − /* reset, enable clock, deassert reset */ | |
| 193 | − if ((__raw_readl(addr + 0x100) & 3) != 3) { | |
| 194 | − __raw_writel(0, addr + 0x100); | |
| 195 | − wmb(); | |
| 196 | − __raw_writel(1, addr + 0x100); | |
| 197 | − wmb(); | |
| 198 | − } | |
| 199 | − __raw_writel(3, addr + 0x100); | |
| 200 | − wmb(); | |
| 201 | −} | |
| 296 | +/* MEM_SDREFCFG register content definitions */ | |
| 297 | +#define MEM_SDREFCFG_TRC (15 << 28) | |
| 298 | +#define MEM_SDREFCFG_TRPM (3 << 26) | |
| 299 | +#define MEM_SDREFCFG_E (1 << 25) | |
| 300 | +#define MEM_SDREFCFG_RE (0x1ffffff << 0) | |
| 301 | +#define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC) | |
| 302 | +#define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM) | |
| 303 | +#define MEM_SDREFCFG_REF_N(N) (N) | |
| 202 | 304 | |
| 203 | −static inline void alchemy_uart_disable(u32 uart_phys) | |
| 204 | −{ | |
| 205 | − void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); | |
| 206 | − __raw_writel(0, addr + 0x100); /* UART_MOD_CNTRL */ | |
| 207 | − wmb(); | |
| 208 | −} | |
| 305 | +/* Au1550 SDRAM Register Offsets */ | |
| 306 | +#define AU1550_MEM_SDMODE0 0x0800 | |
| 307 | +#define AU1550_MEM_SDMODE1 0x0808 | |
| 308 | +#define AU1550_MEM_SDMODE2 0x0810 | |
| 309 | +#define AU1550_MEM_SDADDR0 0x0820 | |
| 310 | +#define AU1550_MEM_SDADDR1 0x0828 | |
| 311 | +#define AU1550_MEM_SDADDR2 0x0830 | |
| 312 | +#define AU1550_MEM_SDCONFIGA 0x0840 | |
| 313 | +#define AU1550_MEM_SDCONFIGB 0x0848 | |
| 314 | +#define AU1550_MEM_SDSTAT 0x0850 | |
| 315 | +#define AU1550_MEM_SDERRADDR 0x0858 | |
| 316 | +#define AU1550_MEM_SDSTRIDE0 0x0860 | |
| 317 | +#define AU1550_MEM_SDSTRIDE1 0x0868 | |
| 318 | +#define AU1550_MEM_SDSTRIDE2 0x0870 | |
| 319 | +#define AU1550_MEM_SDWRMD0 0x0880 | |
| 320 | +#define AU1550_MEM_SDWRMD1 0x0888 | |
| 321 | +#define AU1550_MEM_SDWRMD2 0x0890 | |
| 322 | +#define AU1550_MEM_SDPRECMD 0x08C0 | |
| 323 | +#define AU1550_MEM_SDAUTOREF 0x08C8 | |
| 324 | +#define AU1550_MEM_SDSREF 0x08D0 | |
| 325 | +#define AU1550_MEM_SDSLEEP MEM_SDSREF | |
| 209 | 326 | |
| 210 | −static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) | |
| 211 | −{ | |
| 212 | − void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys); | |
| 213 | − int timeout, i; | |
| 327 | +/* Static Bus Controller register offsets */ | |
| 328 | +#define AU1000_MEM_STCFG0 0x000 | |
| 329 | +#define AU1000_MEM_STTIME0 0x004 | |
| 330 | +#define AU1000_MEM_STADDR0 0x008 | |
| 331 | +#define AU1000_MEM_STCFG1 0x010 | |
| 332 | +#define AU1000_MEM_STTIME1 0x014 | |
| 333 | +#define AU1000_MEM_STADDR1 0x018 | |
| 334 | +#define AU1000_MEM_STCFG2 0x020 | |
| 335 | +#define AU1000_MEM_STTIME2 0x024 | |
| 336 | +#define AU1000_MEM_STADDR2 0x028 | |
| 337 | +#define AU1000_MEM_STCFG3 0x030 | |
| 338 | +#define AU1000_MEM_STTIME3 0x034 | |
| 339 | +#define AU1000_MEM_STADDR3 0x038 | |
| 340 | +#define AU1000_MEM_STNDCTL 0x100 | |
| 341 | +#define AU1000_MEM_STSTAT 0x104 | |
| 214 | 342 | |
| 215 | − /* check LSR TX_EMPTY bit */ | |
| 216 | − timeout = 0xffffff; | |
| 217 | − do { | |
| 218 | − if (__raw_readl(base + 0x1c) & 0x20) | |
| 219 | − break; | |
| 220 | − /* slow down */ | |
| 221 | − for (i = 10000; i; i--) | |
| 222 | − asm volatile ("nop"); | |
| 223 | − } while (--timeout); | |
| 343 | +#define MEM_STNAND_CMD 0x0 | |
| 344 | +#define MEM_STNAND_ADDR 0x4 | |
| 345 | +#define MEM_STNAND_DATA 0x20 | |
| 224 | 346 | |
| 225 | − __raw_writel(c, base + 0x04); /* tx */ | |
| 226 | − wmb(); | |
| 227 | −} | |
| 228 | 347 | |
| 229 | −/* return number of ethernet MACs on a given cputype */ | |
| 230 | −static inline int alchemy_get_macs(int type) | |
| 231 | −{ | |
| 232 | − switch (type) { | |
| 233 | − case ALCHEMY_CPU_AU1000: | |
| 234 | − case ALCHEMY_CPU_AU1500: | |
| 235 | − case ALCHEMY_CPU_AU1550: | |
| 236 | − return 2; | |
| 237 | − case ALCHEMY_CPU_AU1100: | |
| 238 | − return 1; | |
| 239 | − } | |
| 240 | − return 0; | |
| 241 | −} | |
| 348 | +/* Programmable Counters 0 and 1 */ | |
| 349 | +#define AU1000_SYS_CNTRCTRL 0x14 | |
| 350 | +# define SYS_CNTRL_E1S (1 << 23) | |
| 351 | +# define SYS_CNTRL_T1S (1 << 20) | |
| 352 | +# define SYS_CNTRL_M21 (1 << 19) | |
| 353 | +# define SYS_CNTRL_M11 (1 << 18) | |
| 354 | +# define SYS_CNTRL_M01 (1 << 17) | |
| 355 | +# define SYS_CNTRL_C1S (1 << 16) | |
| 356 | +# define SYS_CNTRL_BP (1 << 14) | |
| 357 | +# define SYS_CNTRL_EN1 (1 << 13) | |
| 358 | +# define SYS_CNTRL_BT1 (1 << 12) | |
| 359 | +# define SYS_CNTRL_EN0 (1 << 11) | |
| 360 | +# define SYS_CNTRL_BT0 (1 << 10) | |
| 361 | +# define SYS_CNTRL_E0 (1 << 8) | |
| 362 | +# define SYS_CNTRL_E0S (1 << 7) | |
| 363 | +# define SYS_CNTRL_32S (1 << 5) | |
| 364 | +# define SYS_CNTRL_T0S (1 << 4) | |
| 365 | +# define SYS_CNTRL_M20 (1 << 3) | |
| 366 | +# define SYS_CNTRL_M10 (1 << 2) | |
| 367 | +# define SYS_CNTRL_M00 (1 << 1) | |
| 368 | +# define SYS_CNTRL_C0S (1 << 0) | |
| 242 | 369 | |
| 243 | −/* arch/mips/au1000/common/clocks.c */ | |
| 244 | −extern void set_au1x00_speed(unsigned int new_freq); | |
| 245 | −extern unsigned int get_au1x00_speed(void); | |
| 246 | −extern void set_au1x00_uart_baud_base(unsigned long new_baud_base); | |
| 247 | −extern unsigned long get_au1x00_uart_baud_base(void); | |
| 248 | −extern unsigned long au1xxx_calc_clock(void); | |
| 370 | +/* Programmable Counter 0 Registers */ | |
| 371 | +#define AU1000_SYS_TOYTRIM 0x00 | |
| 372 | +#define AU1000_SYS_TOYWRITE 0x04 | |
| 373 | +#define AU1000_SYS_TOYMATCH0 0x08 | |
| 374 | +#define AU1000_SYS_TOYMATCH1 0x0c | |
| 375 | +#define AU1000_SYS_TOYMATCH2 0x10 | |
| 376 | +#define AU1000_SYS_TOYREAD 0x40 | |
| 249 | 377 | |
| 250 | −/* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */ | |
| 251 | −void alchemy_sleep_au1000(void); | |
| 252 | −void alchemy_sleep_au1550(void); | |
| 253 | −void alchemy_sleep_au1300(void); | |
| 254 | −void au_sleep(void); | |
| 378 | +/* Programmable Counter 1 Registers */ | |
| 379 | +#define AU1000_SYS_RTCTRIM 0x44 | |
| 380 | +#define AU1000_SYS_RTCWRITE 0x48 | |
| 381 | +#define AU1000_SYS_RTCMATCH0 0x4c | |
| 382 | +#define AU1000_SYS_RTCMATCH1 0x50 | |
| 383 | +#define AU1000_SYS_RTCMATCH2 0x54 | |
| 384 | +#define AU1000_SYS_RTCREAD 0x58 | |
| 255 | 385 | |
| 256 | −/* USB: drivers/usb/host/alchemy-common.c */ | |
| 257 | −enum alchemy_usb_block { | |
| 258 | − ALCHEMY_USB_OHCI0, | |
| 259 | − ALCHEMY_USB_UDC0, | |
| 260 | − ALCHEMY_USB_EHCI0, | |
| 261 | − ALCHEMY_USB_OTG0, | |
| 262 | − ALCHEMY_USB_OHCI1, | |
| 263 | −}; | |
| 264 | −int alchemy_usb_control(int block, int enable); | |
| 265 | 386 | |
| 266 | −/* PCI controller platform data */ | |
| 267 | −struct alchemy_pci_platdata { | |
| 268 | − int (*board_map_irq)(const struct pci_dev *d, u8 slot, u8 pin); | |
| 269 | − int (*board_pci_idsel)(unsigned int devsel, int assert); | |
| 270 | − /* bits to set/clear in PCI_CONFIG register */ | |
| 271 | − unsigned long pci_cfg_set; | |
| 272 | − unsigned long pci_cfg_clr; | |
| 273 | −}; | |
| 387 | +/* GPIO */ | |
| 388 | +#define AU1000_SYS_PINFUNC 0x2C | |
| 389 | +# define SYS_PF_USB (1 << 15) /* 2nd USB device/host */ | |
| 390 | +# define SYS_PF_U3 (1 << 14) /* GPIO23/U3TXD */ | |
| 391 | +# define SYS_PF_U2 (1 << 13) /* GPIO22/U2TXD */ | |
| 392 | +# define SYS_PF_U1 (1 << 12) /* GPIO21/U1TXD */ | |
| 393 | +# define SYS_PF_SRC (1 << 11) /* GPIO6/SROMCKE */ | |
| 394 | +# define SYS_PF_CK5 (1 << 10) /* GPIO3/CLK5 */ | |
| 395 | +# define SYS_PF_CK4 (1 << 9) /* GPIO2/CLK4 */ | |
| 396 | +# define SYS_PF_IRF (1 << 8) /* GPIO15/IRFIRSEL */ | |
| 397 | +# define SYS_PF_UR3 (1 << 7) /* GPIO[14:9]/UART3 */ | |
| 398 | +# define SYS_PF_I2D (1 << 6) /* GPIO8/I2SDI */ | |
| 399 | +# define SYS_PF_I2S (1 << 5) /* I2S/GPIO[29:31] */ | |
| 400 | +# define SYS_PF_NI2 (1 << 4) /* NI2/GPIO[24:28] */ | |
| 401 | +# define SYS_PF_U0 (1 << 3) /* U0TXD/GPIO20 */ | |
| 402 | +# define SYS_PF_RD (1 << 2) /* IRTXD/GPIO19 */ | |
| 403 | +# define SYS_PF_A97 (1 << 1) /* AC97/SSL1 */ | |
| 404 | +# define SYS_PF_S0 (1 << 0) /* SSI_0/GPIO[16:18] */ | |
| 274 | 405 | |
| 275 | −/* Multifunction pins: Each of these pins can either be assigned to the | |
| 276 | − * GPIO controller or a on-chip peripheral. | |
| 277 | − * Call "au1300_pinfunc_to_dev()" or "au1300_pinfunc_to_gpio()" to | |
| 278 | − * assign one of these to either the GPIO controller or the device. | |
| 279 | − */ | |
| 280 | −enum au1300_multifunc_pins { | |
| 281 | − /* wake-from-str pins 0-3 */ | |
| 282 | − AU1300_PIN_WAKE0 = 0, AU1300_PIN_WAKE1, AU1300_PIN_WAKE2, | |
| 283 | − AU1300_PIN_WAKE3, | |
| 284 | − /* external clock sources for PSCs: 4-5 */ | |
| 285 | − AU1300_PIN_EXTCLK0, AU1300_PIN_EXTCLK1, | |
| 286 | − /* 8bit MMC interface on SD0: 6-9 */ | |
| 287 | − AU1300_PIN_SD0DAT4, AU1300_PIN_SD0DAT5, AU1300_PIN_SD0DAT6, | |
| 288 | − AU1300_PIN_SD0DAT7, | |
| 289 | − /* aux clk input for freqgen 3: 10 */ | |
| 290 | − AU1300_PIN_FG3AUX, | |
| 291 | − /* UART1 pins: 11-18 */ | |
| 292 | − AU1300_PIN_U1RI, AU1300_PIN_U1DCD, AU1300_PIN_U1DSR, | |
| 293 | − AU1300_PIN_U1CTS, AU1300_PIN_U1RTS, AU1300_PIN_U1DTR, | |
| 294 | − AU1300_PIN_U1RX, AU1300_PIN_U1TX, | |
| 295 | − /* UART0 pins: 19-24 */ | |
| 296 | − AU1300_PIN_U0RI, AU1300_PIN_U0DCD, AU1300_PIN_U0DSR, | |
| 297 | − AU1300_PIN_U0CTS, AU1300_PIN_U0RTS, AU1300_PIN_U0DTR, | |
| 298 | − /* UART2: 25-26 */ | |
| 299 | − AU1300_PIN_U2RX, AU1300_PIN_U2TX, | |
| 300 | − /* UART3: 27-28 */ | |
| 301 | − AU1300_PIN_U3RX, AU1300_PIN_U3TX, | |
| 302 | − /* LCD controller PWMs, ext pixclock: 29-31 */ | |
| 303 | − AU1300_PIN_LCDPWM0, AU1300_PIN_LCDPWM1, AU1300_PIN_LCDCLKIN, | |
| 304 | − /* SD1 interface: 32-37 */ | |
| 305 | − AU1300_PIN_SD1DAT0, AU1300_PIN_SD1DAT1, AU1300_PIN_SD1DAT2, | |
| 306 | − AU1300_PIN_SD1DAT3, AU1300_PIN_SD1CMD, AU1300_PIN_SD1CLK, | |
| 307 | − /* SD2 interface: 38-43 */ | |
| 308 | − AU1300_PIN_SD2DAT0, AU1300_PIN_SD2DAT1, AU1300_PIN_SD2DAT2, | |
| 309 | − AU1300_PIN_SD2DAT3, AU1300_PIN_SD2CMD, AU1300_PIN_SD2CLK, | |
| 310 | − /* PSC0/1 clocks: 44-45 */ | |
| 311 | − AU1300_PIN_PSC0CLK, AU1300_PIN_PSC1CLK, | |
| 312 | − /* PSCs: 46-49/50-53/54-57/58-61 */ | |
| 313 | − AU1300_PIN_PSC0SYNC0, AU1300_PIN_PSC0SYNC1, AU1300_PIN_PSC0D0, | |
| 314 | − AU1300_PIN_PSC0D1, | |
| 315 | − AU1300_PIN_PSC1SYNC0, AU1300_PIN_PSC1SYNC1, AU1300_PIN_PSC1D0, | |
| 316 | − AU1300_PIN_PSC1D1, | |
| 317 | − AU1300_PIN_PSC2SYNC0, AU1300_PIN_PSC2SYNC1, AU1300_PIN_PSC2D0, | |
| 318 | − AU1300_PIN_PSC2D1, | |
| 319 | − AU1300_PIN_PSC3SYNC0, AU1300_PIN_PSC3SYNC1, AU1300_PIN_PSC3D0, | |
| 320 | − AU1300_PIN_PSC3D1, | |
| 321 | − /* PCMCIA interface: 62-70 */ | |
| 322 | − AU1300_PIN_PCE2, AU1300_PIN_PCE1, AU1300_PIN_PIOS16, | |
| 323 | − AU1300_PIN_PIOR, AU1300_PIN_PWE, AU1300_PIN_PWAIT, | |
| 324 | − AU1300_PIN_PREG, AU1300_PIN_POE, AU1300_PIN_PIOW, | |
| 325 | − /* camera interface H/V sync inputs: 71-72 */ | |
| 326 | − AU1300_PIN_CIMLS, AU1300_PIN_CIMFS, | |
| 327 | − /* PSC2/3 clocks: 73-74 */ | |
| 328 | − AU1300_PIN_PSC2CLK, AU1300_PIN_PSC3CLK, | |
| 329 | −}; | |
| 406 | +/* Au1100 only */ | |
| 407 | +# define SYS_PF_PC (1 << 18) /* PCMCIA/GPIO[207:204] */ | |
| 408 | +# define SYS_PF_LCD (1 << 17) /* extern lcd/GPIO[203:200] */ | |
| 409 | +# define SYS_PF_CS (1 << 16) /* EXTCLK0/32KHz to gpio2 */ | |
| 410 | +# define SYS_PF_EX0 (1 << 9) /* GPIO2/clock */ | |
| 330 | 411 | |
| 331 | −/* GPIC (Au1300) pin management: arch/mips/alchemy/common/gpioint.c */ | |
| 332 | −extern void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio); | |
| 333 | −extern void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio); | |
| 334 | −extern void au1300_set_irq_priority(unsigned int irq, int p); | |
| 335 | −extern void au1300_set_dbdma_gpio(int dchan, unsigned int gpio); | |
| 412 | +/* Au1550 only. Redefines lots of pins */ | |
| 413 | +# define SYS_PF_PSC2_MASK (7 << 17) | |
| 414 | +# define SYS_PF_PSC2_AC97 0 | |
| 415 | +# define SYS_PF_PSC2_SPI 0 | |
| 416 | +# define SYS_PF_PSC2_I2S (1 << 17) | |
| 417 | +# define SYS_PF_PSC2_SMBUS (3 << 17) | |
| 418 | +# define SYS_PF_PSC2_GPIO (7 << 17) | |
| 419 | +# define SYS_PF_PSC3_MASK (7 << 20) | |
| 420 | +# define SYS_PF_PSC3_AC97 0 | |
| 421 | +# define SYS_PF_PSC3_SPI 0 | |
| 422 | +# define SYS_PF_PSC3_I2S (1 << 20) | |
| 423 | +# define SYS_PF_PSC3_SMBUS (3 << 20) | |
| 424 | +# define SYS_PF_PSC3_GPIO (7 << 20) | |
| 425 | +# define SYS_PF_PSC1_S1 (1 << 1) | |
| 426 | +# define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) | |
| 336 | 427 | |
| 337 | −/* Au1300 allows to disconnect certain blocks from internal power supply */ | |
| 338 | −enum au1300_vss_block { | |
| 339 | − AU1300_VSS_MPE = 0, | |
| 340 | − AU1300_VSS_BSA, | |
| 341 | − AU1300_VSS_GPE, | |
| 342 | − AU1300_VSS_MGP, | |
| 343 | −}; | |
| 428 | +/* Au1200 only */ | |
| 429 | +#define SYS_PINFUNC_DMA (1 << 31) | |
| 430 | +#define SYS_PINFUNC_S0A (1 << 30) | |
| 431 | +#define SYS_PINFUNC_S1A (1 << 29) | |
| 432 | +#define SYS_PINFUNC_LP0 (1 << 28) | |
| 433 | +#define SYS_PINFUNC_LP1 (1 << 27) | |
| 434 | +#define SYS_PINFUNC_LD16 (1 << 26) | |
| 435 | +#define SYS_PINFUNC_LD8 (1 << 25) | |
| 436 | +#define SYS_PINFUNC_LD1 (1 << 24) | |
| 437 | +#define SYS_PINFUNC_LD0 (1 << 23) | |
| 438 | +#define SYS_PINFUNC_P1A (3 << 21) | |
| 439 | +#define SYS_PINFUNC_P1B (1 << 20) | |
| 440 | +#define SYS_PINFUNC_FS3 (1 << 19) | |
| 441 | +#define SYS_PINFUNC_P0A (3 << 17) | |
| 442 | +#define SYS_PINFUNC_CS (1 << 16) | |
| 443 | +#define SYS_PINFUNC_CIM (1 << 15) | |
| 444 | +#define SYS_PINFUNC_P1C (1 << 14) | |
| 445 | +#define SYS_PINFUNC_U1T (1 << 12) | |
| 446 | +#define SYS_PINFUNC_U1R (1 << 11) | |
| 447 | +#define SYS_PINFUNC_EX1 (1 << 10) | |
| 448 | +#define SYS_PINFUNC_EX0 (1 << 9) | |
| 449 | +#define SYS_PINFUNC_U0R (1 << 8) | |
| 450 | +#define SYS_PINFUNC_MC (1 << 7) | |
| 451 | +#define SYS_PINFUNC_S0B (1 << 6) | |
| 452 | +#define SYS_PINFUNC_S0C (1 << 5) | |
| 453 | +#define SYS_PINFUNC_P0B (1 << 4) | |
| 454 | +#define SYS_PINFUNC_U0T (1 << 3) | |
| 455 | +#define SYS_PINFUNC_S1B (1 << 2) | |
| 344 | 456 | |
| 345 | −extern void au1300_vss_block_control(int block, int enable); | |
| 457 | +/* Power Management */ | |
| 458 | +#define AU1000_SYS_SCRATCH0 0x18 | |
| 459 | +#define AU1000_SYS_SCRATCH1 0x1c | |
| 460 | +#define AU1000_SYS_WAKEMSK 0x34 | |
| 461 | +#define AU1000_SYS_ENDIAN 0x38 | |
| 462 | +#define AU1000_SYS_POWERCTRL 0x3c | |
| 463 | +#define AU1000_SYS_WAKESRC 0x5c | |
| 464 | +#define AU1000_SYS_SLPPWR 0x78 | |
| 465 | +#define AU1000_SYS_SLEEP 0x7c | |
| 346 | 466 | |
| 467 | +#define SYS_WAKEMSK_D2 (1 << 9) | |
| 468 | +#define SYS_WAKEMSK_M2 (1 << 8) | |
| 469 | +#define SYS_WAKEMSK_GPIO(x) (1 << (x)) | |
| 347 | 470 | |
| 348 | −/* SOC Interrupt numbers */ | |
| 349 | −/* Au1000-style (IC0/1): 2 controllers with 32 sources each */ | |
| 350 | −#define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | |
| 351 | −#define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31) | |
| 352 | −#define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_LAST + 1) | |
| 353 | −#define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31) | |
| 354 | −#define AU1000_MAX_INTR AU1000_INTC1_INT_LAST | |
| 471 | +/* Clock Controller */ | |
| 472 | +#define AU1000_SYS_FREQCTRL0 0x20 | |
| 473 | +#define AU1000_SYS_FREQCTRL1 0x24 | |
| 474 | +#define AU1000_SYS_CLKSRC 0x28 | |
| 475 | +#define AU1000_SYS_CPUPLL 0x60 | |
| 476 | +#define AU1000_SYS_AUXPLL 0x64 | |
| 477 | +#define AU1300_SYS_AUXPLL2 0x68 | |
| 355 | 478 | |
| 356 | −/* Au1300-style (GPIC): 1 controller with up to 128 sources */ | |
| 357 | −#define ALCHEMY_GPIC_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | |
| 358 | −#define ALCHEMY_GPIC_INT_NUM 128 | |
| 359 | −#define ALCHEMY_GPIC_INT_LAST (ALCHEMY_GPIC_INT_BASE + ALCHEMY_GPIC_INT_NUM - 1) | |
| 360 | 479 | |
| 361 | −enum soc_au1000_ints { | |
| 362 | − AU1000_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 363 | − AU1000_UART0_INT = AU1000_FIRST_INT, | |
| 364 | − AU1000_UART1_INT, | |
| 365 | − AU1000_UART2_INT, | |
| 366 | − AU1000_UART3_INT, | |
| 367 | − AU1000_SSI0_INT, | |
| 368 | − AU1000_SSI1_INT, | |
| 369 | − AU1000_DMA_INT_BASE, | |
| 480 | +/**********************************************************************/ | |
| 370 | 481 | |
| 371 | − AU1000_TOY_INT = AU1000_FIRST_INT + 14, | |
| 372 | − AU1000_TOY_MATCH0_INT, | |
| 373 | − AU1000_TOY_MATCH1_INT, | |
| 374 | − AU1000_TOY_MATCH2_INT, | |
| 375 | − AU1000_RTC_INT, | |
| 376 | − AU1000_RTC_MATCH0_INT, | |
| 377 | − AU1000_RTC_MATCH1_INT, | |
| 378 | − AU1000_RTC_MATCH2_INT, | |
| 379 | − AU1000_IRDA_TX_INT, | |
| 380 | − AU1000_IRDA_RX_INT, | |
| 381 | − AU1000_USB_DEV_REQ_INT, | |
| 382 | − AU1000_USB_DEV_SUS_INT, | |
| 383 | − AU1000_USB_HOST_INT, | |
| 384 | − AU1000_ACSYNC_INT, | |
| 385 | − AU1000_MAC0_DMA_INT, | |
| 386 | − AU1000_MAC1_DMA_INT, | |
| 387 | − AU1000_I2S_UO_INT, | |
| 388 | − AU1000_AC97C_INT, | |
| 389 | − AU1000_GPIO0_INT, | |
| 390 | − AU1000_GPIO1_INT, | |
| 391 | − AU1000_GPIO2_INT, | |
| 392 | − AU1000_GPIO3_INT, | |
| 393 | − AU1000_GPIO4_INT, | |
| 394 | − AU1000_GPIO5_INT, | |
| 395 | − AU1000_GPIO6_INT, | |
| 396 | − AU1000_GPIO7_INT, | |
| 397 | − AU1000_GPIO8_INT, | |
| 398 | − AU1000_GPIO9_INT, | |
| 399 | − AU1000_GPIO10_INT, | |
| 400 | − AU1000_GPIO11_INT, | |
| 401 | − AU1000_GPIO12_INT, | |
| 402 | − AU1000_GPIO13_INT, | |
| 403 | − AU1000_GPIO14_INT, | |
| 404 | − AU1000_GPIO15_INT, | |
| 405 | − AU1000_GPIO16_INT, | |
| 406 | − AU1000_GPIO17_INT, | |
| 407 | − AU1000_GPIO18_INT, | |
| 408 | − AU1000_GPIO19_INT, | |
| 409 | − AU1000_GPIO20_INT, | |
| 410 | − AU1000_GPIO21_INT, | |
| 411 | − AU1000_GPIO22_INT, | |
| 412 | − AU1000_GPIO23_INT, | |
| 413 | − AU1000_GPIO24_INT, | |
| 414 | − AU1000_GPIO25_INT, | |
| 415 | − AU1000_GPIO26_INT, | |
| 416 | − AU1000_GPIO27_INT, | |
| 417 | − AU1000_GPIO28_INT, | |
| 418 | − AU1000_GPIO29_INT, | |
| 419 | − AU1000_GPIO30_INT, | |
| 420 | − AU1000_GPIO31_INT, | |
| 421 | −}; | |
| 422 | 482 | |
| 423 | −enum soc_au1100_ints { | |
| 424 | − AU1100_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 425 | − AU1100_UART0_INT = AU1100_FIRST_INT, | |
| 426 | − AU1100_UART1_INT, | |
| 427 | − AU1100_SD_INT, | |
| 428 | − AU1100_UART3_INT, | |
| 429 | − AU1100_SSI0_INT, | |
| 430 | − AU1100_SSI1_INT, | |
| 431 | − AU1100_DMA_INT_BASE, | |
| 483 | +/* The PCI chip selects are outside the 32bit space, and since we can't | |
| 484 | + * just program the 36bit addresses into BARs, we have to take a chunk | |
| 485 | + * out of the 32bit space and reserve it for PCI. When these addresses | |
| 486 | + * are ioremap()ed, they'll be fixed up to the real 36bit address before | |
| 487 | + * being passed to the real ioremap function. | |
| 488 | + */ | |
| 489 | +#define ALCHEMY_PCI_MEMWIN_START (AU1500_PCI_MEM_PHYS_ADDR >> 4) | |
| 490 | +#define ALCHEMY_PCI_MEMWIN_END (ALCHEMY_PCI_MEMWIN_START + 0x0FFFFFFF) | |
| 432 | 491 | |
| 433 | − AU1100_TOY_INT = AU1100_FIRST_INT + 14, | |
| 434 | − AU1100_TOY_MATCH0_INT, | |
| 435 | − AU1100_TOY_MATCH1_INT, | |
| 436 | − AU1100_TOY_MATCH2_INT, | |
| 437 | − AU1100_RTC_INT, | |
| 438 | − AU1100_RTC_MATCH0_INT, | |
| 439 | − AU1100_RTC_MATCH1_INT, | |
| 440 | − AU1100_RTC_MATCH2_INT, | |
| 441 | − AU1100_IRDA_TX_INT, | |
| 442 | − AU1100_IRDA_RX_INT, | |
| 443 | − AU1100_USB_DEV_REQ_INT, | |
| 444 | − AU1100_USB_DEV_SUS_INT, | |
| 445 | − AU1100_USB_HOST_INT, | |
| 446 | − AU1100_ACSYNC_INT, | |
| 447 | − AU1100_MAC0_DMA_INT, | |
| 448 | − AU1100_GPIO208_215_INT, | |
| 449 | − AU1100_LCD_INT, | |
| 450 | − AU1100_AC97C_INT, | |
| 451 | − AU1100_GPIO0_INT, | |
| 452 | − AU1100_GPIO1_INT, | |
| 453 | − AU1100_GPIO2_INT, | |
| 454 | − AU1100_GPIO3_INT, | |
| 455 | − AU1100_GPIO4_INT, | |
| 456 | − AU1100_GPIO5_INT, | |
| 457 | − AU1100_GPIO6_INT, | |
| 458 | − AU1100_GPIO7_INT, | |
| 459 | − AU1100_GPIO8_INT, | |
| 460 | − AU1100_GPIO9_INT, | |
| 461 | − AU1100_GPIO10_INT, | |
| 462 | − AU1100_GPIO11_INT, | |
| 463 | − AU1100_GPIO12_INT, | |
| 464 | − AU1100_GPIO13_INT, | |
| 465 | − AU1100_GPIO14_INT, | |
| 466 | − AU1100_GPIO15_INT, | |
| 467 | − AU1100_GPIO16_INT, | |
| 468 | − AU1100_GPIO17_INT, | |
| 469 | − AU1100_GPIO18_INT, | |
| 470 | − AU1100_GPIO19_INT, | |
| 471 | − AU1100_GPIO20_INT, | |
| 472 | − AU1100_GPIO21_INT, | |
| 473 | − AU1100_GPIO22_INT, | |
| 474 | − AU1100_GPIO23_INT, | |
| 475 | − AU1100_GPIO24_INT, | |
| 476 | − AU1100_GPIO25_INT, | |
| 477 | − AU1100_GPIO26_INT, | |
| 478 | − AU1100_GPIO27_INT, | |
| 479 | − AU1100_GPIO28_INT, | |
| 480 | − AU1100_GPIO29_INT, | |
| 481 | − AU1100_GPIO30_INT, | |
| 482 | − AU1100_GPIO31_INT, | |
| 483 | −}; | |
| 492 | +/* for PCI IO it's simpler because we get to do the ioremap ourselves and then | |
| 493 | + * adjust the device's resources. | |
| 494 | + */ | |
| 495 | +#define ALCHEMY_PCI_IOWIN_START 0x00001000 | |
| 496 | +#define ALCHEMY_PCI_IOWIN_END 0x0000FFFF | |
| 484 | 497 | |
| 485 | −enum soc_au1500_ints { | |
| 486 | − AU1500_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 487 | − AU1500_UART0_INT = AU1500_FIRST_INT, | |
| 488 | − AU1500_PCI_INTA, | |
| 489 | − AU1500_PCI_INTB, | |
| 490 | − AU1500_UART3_INT, | |
| 491 | − AU1500_PCI_INTC, | |
| 492 | − AU1500_PCI_INTD, | |
| 493 | − AU1500_DMA_INT_BASE, | |
| 498 | +#ifdef CONFIG_PCI | |
| 494 | 499 | |
| 495 | − AU1500_TOY_INT = AU1500_FIRST_INT + 14, | |
| 496 | − AU1500_TOY_MATCH0_INT, | |
| 497 | − AU1500_TOY_MATCH1_INT, | |
| 498 | − AU1500_TOY_MATCH2_INT, | |
| 499 | − AU1500_RTC_INT, | |
| 500 | − AU1500_RTC_MATCH0_INT, | |
| 501 | − AU1500_RTC_MATCH1_INT, | |
| 502 | − AU1500_RTC_MATCH2_INT, | |
| 503 | − AU1500_PCI_ERR_INT, | |
| 504 | − AU1500_RESERVED_INT, | |
| 505 | − AU1500_USB_DEV_REQ_INT, | |
| 506 | − AU1500_USB_DEV_SUS_INT, | |
| 507 | − AU1500_USB_HOST_INT, | |
| 508 | − AU1500_ACSYNC_INT, | |
| 509 | − AU1500_MAC0_DMA_INT, | |
| 510 | − AU1500_MAC1_DMA_INT, | |
| 511 | − AU1500_AC97C_INT = AU1500_FIRST_INT + 31, | |
| 512 | − AU1500_GPIO0_INT, | |
| 513 | − AU1500_GPIO1_INT, | |
| 514 | − AU1500_GPIO2_INT, | |
| 515 | − AU1500_GPIO3_INT, | |
| 516 | − AU1500_GPIO4_INT, | |
| 517 | − AU1500_GPIO5_INT, | |
| 518 | − AU1500_GPIO6_INT, | |
| 519 | − AU1500_GPIO7_INT, | |
| 520 | − AU1500_GPIO8_INT, | |
| 521 | − AU1500_GPIO9_INT, | |
| 522 | − AU1500_GPIO10_INT, | |
| 523 | − AU1500_GPIO11_INT, | |
| 524 | − AU1500_GPIO12_INT, | |
| 525 | − AU1500_GPIO13_INT, | |
| 526 | − AU1500_GPIO14_INT, | |
| 527 | − AU1500_GPIO15_INT, | |
| 528 | − AU1500_GPIO200_INT, | |
| 529 | − AU1500_GPIO201_INT, | |
| 530 | − AU1500_GPIO202_INT, | |
| 531 | − AU1500_GPIO203_INT, | |
| 532 | − AU1500_GPIO20_INT, | |
| 533 | − AU1500_GPIO204_INT, | |
| 534 | − AU1500_GPIO205_INT, | |
| 535 | − AU1500_GPIO23_INT, | |
| 536 | − AU1500_GPIO24_INT, | |
| 537 | − AU1500_GPIO25_INT, | |
| 538 | − AU1500_GPIO26_INT, | |
| 539 | − AU1500_GPIO27_INT, | |
| 540 | − AU1500_GPIO28_INT, | |
| 541 | − AU1500_GPIO206_INT, | |
| 542 | − AU1500_GPIO207_INT, | |
| 543 | − AU1500_GPIO208_215_INT, | |
| 544 | −}; | |
| 545 | − | |
| 546 | −enum soc_au1550_ints { | |
| 547 | − AU1550_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 548 | − AU1550_UART0_INT = AU1550_FIRST_INT, | |
| 549 | − AU1550_PCI_INTA, | |
| 550 | − AU1550_PCI_INTB, | |
| 551 | − AU1550_DDMA_INT, | |
| 552 | − AU1550_CRYPTO_INT, | |
| 553 | − AU1550_PCI_INTC, | |
| 554 | − AU1550_PCI_INTD, | |
| 555 | − AU1550_PCI_RST_INT, | |
| 556 | − AU1550_UART1_INT, | |
| 557 | − AU1550_UART3_INT, | |
| 558 | − AU1550_PSC0_INT, | |
| 559 | − AU1550_PSC1_INT, | |
| 560 | − AU1550_PSC2_INT, | |
| 561 | − AU1550_PSC3_INT, | |
| 562 | − AU1550_TOY_INT, | |
| 563 | − AU1550_TOY_MATCH0_INT, | |
| 564 | − AU1550_TOY_MATCH1_INT, | |
| 565 | − AU1550_TOY_MATCH2_INT, | |
| 566 | − AU1550_RTC_INT, | |
| 567 | − AU1550_RTC_MATCH0_INT, | |
| 568 | − AU1550_RTC_MATCH1_INT, | |
| 569 | − AU1550_RTC_MATCH2_INT, | |
| 570 | − | |
| 571 | − AU1550_NAND_INT = AU1550_FIRST_INT + 23, | |
| 572 | − AU1550_USB_DEV_REQ_INT, | |
| 573 | − AU1550_USB_DEV_SUS_INT, | |
| 574 | − AU1550_USB_HOST_INT, | |
| 575 | − AU1550_MAC0_DMA_INT, | |
| 576 | − AU1550_MAC1_DMA_INT, | |
| 577 | − AU1550_GPIO0_INT = AU1550_FIRST_INT + 32, | |
| 578 | − AU1550_GPIO1_INT, | |
| 579 | − AU1550_GPIO2_INT, | |
| 580 | − AU1550_GPIO3_INT, | |
| 581 | − AU1550_GPIO4_INT, | |
| 582 | − AU1550_GPIO5_INT, | |
| 583 | − AU1550_GPIO6_INT, | |
| 584 | − AU1550_GPIO7_INT, | |
| 585 | − AU1550_GPIO8_INT, | |
| 586 | − AU1550_GPIO9_INT, | |
| 587 | − AU1550_GPIO10_INT, | |
| 588 | − AU1550_GPIO11_INT, | |
| 589 | − AU1550_GPIO12_INT, | |
| 590 | − AU1550_GPIO13_INT, | |
| 591 | − AU1550_GPIO14_INT, | |
| 592 | − AU1550_GPIO15_INT, | |
| 593 | − AU1550_GPIO200_INT, | |
| 594 | − AU1550_GPIO201_205_INT, /* Logical or of GPIO201:205 */ | |
| 595 | − AU1550_GPIO16_INT, | |
| 596 | − AU1550_GPIO17_INT, | |
| 597 | − AU1550_GPIO20_INT, | |
| 598 | − AU1550_GPIO21_INT, | |
| 599 | − AU1550_GPIO22_INT, | |
| 600 | − AU1550_GPIO23_INT, | |
| 601 | − AU1550_GPIO24_INT, | |
| 602 | − AU1550_GPIO25_INT, | |
| 603 | − AU1550_GPIO26_INT, | |
| 604 | − AU1550_GPIO27_INT, | |
| 605 | − AU1550_GPIO28_INT, | |
| 606 | − AU1550_GPIO206_INT, | |
| 607 | − AU1550_GPIO207_INT, | |
| 608 | − AU1550_GPIO208_215_INT, /* Logical or of GPIO208:215 */ | |
| 609 | −}; | |
| 610 | − | |
| 611 | −enum soc_au1200_ints { | |
| 612 | − AU1200_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 613 | − AU1200_UART0_INT = AU1200_FIRST_INT, | |
| 614 | − AU1200_SWT_INT, | |
| 615 | − AU1200_SD_INT, | |
| 616 | − AU1200_DDMA_INT, | |
| 617 | − AU1200_MAE_BE_INT, | |
| 618 | − AU1200_GPIO200_INT, | |
| 619 | − AU1200_GPIO201_INT, | |
| 620 | − AU1200_GPIO202_INT, | |
| 621 | − AU1200_UART1_INT, | |
| 622 | − AU1200_MAE_FE_INT, | |
| 623 | − AU1200_PSC0_INT, | |
| 624 | − AU1200_PSC1_INT, | |
| 625 | − AU1200_AES_INT, | |
| 626 | − AU1200_CAMERA_INT, | |
| 627 | − AU1200_TOY_INT, | |
| 628 | − AU1200_TOY_MATCH0_INT, | |
| 629 | − AU1200_TOY_MATCH1_INT, | |
| 630 | − AU1200_TOY_MATCH2_INT, | |
| 631 | − AU1200_RTC_INT, | |
| 632 | − AU1200_RTC_MATCH0_INT, | |
| 633 | − AU1200_RTC_MATCH1_INT, | |
| 634 | − AU1200_RTC_MATCH2_INT, | |
| 635 | − AU1200_GPIO203_INT, | |
| 636 | − AU1200_NAND_INT, | |
| 637 | − AU1200_GPIO204_INT, | |
| 638 | − AU1200_GPIO205_INT, | |
| 639 | − AU1200_GPIO206_INT, | |
| 640 | − AU1200_GPIO207_INT, | |
| 641 | − AU1200_GPIO208_215_INT, /* Logical OR of 208:215 */ | |
| 642 | − AU1200_USB_INT, | |
| 643 | − AU1200_LCD_INT, | |
| 644 | − AU1200_MAE_BOTH_INT, | |
| 645 | − AU1200_GPIO0_INT, | |
| 646 | − AU1200_GPIO1_INT, | |
| 647 | − AU1200_GPIO2_INT, | |
| 648 | − AU1200_GPIO3_INT, | |
| 649 | − AU1200_GPIO4_INT, | |
| 650 | − AU1200_GPIO5_INT, | |
| 651 | − AU1200_GPIO6_INT, | |
| 652 | − AU1200_GPIO7_INT, | |
| 653 | − AU1200_GPIO8_INT, | |
| 654 | − AU1200_GPIO9_INT, | |
| 655 | − AU1200_GPIO10_INT, | |
| 656 | − AU1200_GPIO11_INT, | |
| 657 | − AU1200_GPIO12_INT, | |
| 658 | − AU1200_GPIO13_INT, | |
| 659 | − AU1200_GPIO14_INT, | |
| 660 | − AU1200_GPIO15_INT, | |
| 661 | − AU1200_GPIO16_INT, | |
| 662 | − AU1200_GPIO17_INT, | |
| 663 | − AU1200_GPIO18_INT, | |
| 664 | − AU1200_GPIO19_INT, | |
| 665 | − AU1200_GPIO20_INT, | |
| 666 | − AU1200_GPIO21_INT, | |
| 667 | − AU1200_GPIO22_INT, | |
| 668 | − AU1200_GPIO23_INT, | |
| 669 | − AU1200_GPIO24_INT, | |
| 670 | − AU1200_GPIO25_INT, | |
| 671 | − AU1200_GPIO26_INT, | |
| 672 | − AU1200_GPIO27_INT, | |
| 673 | − AU1200_GPIO28_INT, | |
| 674 | − AU1200_GPIO29_INT, | |
| 675 | − AU1200_GPIO30_INT, | |
| 676 | − AU1200_GPIO31_INT, | |
| 677 | −}; | |
| 500 | +#define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */ | |
| 501 | +#define IOPORT_RESOURCE_END 0xffffffff | |
| 502 | +#define IOMEM_RESOURCE_START 0x10000000 | |
| 503 | +#define IOMEM_RESOURCE_END 0xfffffffffULL | |
| 678 | 504 | |
| 679 | −#endif /* !defined (_LANGUAGE_ASSEMBLY) */ | |
| 505 | +#else | |
| 680 | 506 | |
| 681 | −/* Au1300 peripheral interrupt numbers */ | |
| 682 | −#define AU1300_FIRST_INT (ALCHEMY_GPIC_INT_BASE) | |
| 683 | −#define AU1300_UART1_INT (AU1300_FIRST_INT + 17) | |
| 684 | −#define AU1300_UART2_INT (AU1300_FIRST_INT + 25) | |
| 685 | −#define AU1300_UART3_INT (AU1300_FIRST_INT + 27) | |
| 686 | −#define AU1300_SD1_INT (AU1300_FIRST_INT + 32) | |
| 687 | −#define AU1300_SD2_INT (AU1300_FIRST_INT + 38) | |
| 688 | −#define AU1300_PSC0_INT (AU1300_FIRST_INT + 48) | |
| 689 | −#define AU1300_PSC1_INT (AU1300_FIRST_INT + 52) | |
| 690 | −#define AU1300_PSC2_INT (AU1300_FIRST_INT + 56) | |
| 691 | −#define AU1300_PSC3_INT (AU1300_FIRST_INT + 60) | |
| 692 | −#define AU1300_NAND_INT (AU1300_FIRST_INT + 62) | |
| 693 | −#define AU1300_DDMA_INT (AU1300_FIRST_INT + 75) | |
| 694 | −#define AU1300_MMU_INT (AU1300_FIRST_INT + 76) | |
| 695 | −#define AU1300_MPU_INT (AU1300_FIRST_INT + 77) | |
| 696 | −#define AU1300_GPU_INT (AU1300_FIRST_INT + 78) | |
| 697 | −#define AU1300_UDMA_INT (AU1300_FIRST_INT + 79) | |
| 698 | −#define AU1300_TOY_INT (AU1300_FIRST_INT + 80) | |
| 699 | −#define AU1300_TOY_MATCH0_INT (AU1300_FIRST_INT + 81) | |
| 700 | −#define AU1300_TOY_MATCH1_INT (AU1300_FIRST_INT + 82) | |
| 701 | −#define AU1300_TOY_MATCH2_INT (AU1300_FIRST_INT + 83) | |
| 702 | −#define AU1300_RTC_INT (AU1300_FIRST_INT + 84) | |
| 703 | −#define AU1300_RTC_MATCH0_INT (AU1300_FIRST_INT + 85) | |
| 704 | −#define AU1300_RTC_MATCH1_INT (AU1300_FIRST_INT + 86) | |
| 705 | −#define AU1300_RTC_MATCH2_INT (AU1300_FIRST_INT + 87) | |
| 706 | −#define AU1300_UART0_INT (AU1300_FIRST_INT + 88) | |
| 707 | −#define AU1300_SD0_INT (AU1300_FIRST_INT + 89) | |
| 708 | −#define AU1300_USB_INT (AU1300_FIRST_INT + 90) | |
| 709 | −#define AU1300_LCD_INT (AU1300_FIRST_INT + 91) | |
| 710 | −#define AU1300_BSA_INT (AU1300_FIRST_INT + 92) | |
| 711 | −#define AU1300_MPE_INT (AU1300_FIRST_INT + 93) | |
| 712 | −#define AU1300_ITE_INT (AU1300_FIRST_INT + 94) | |
| 713 | −#define AU1300_AES_INT (AU1300_FIRST_INT + 95) | |
| 714 | −#define AU1300_CIM_INT (AU1300_FIRST_INT + 96) | |
| 507 | +/* Don't allow any legacy ports probing */ | |
| 508 | +#define IOPORT_RESOURCE_START 0x10000000 | |
| 509 | +#define IOPORT_RESOURCE_END 0xffffffff | |
| 510 | +#define IOMEM_RESOURCE_START 0x10000000 | |
| 511 | +#define IOMEM_RESOURCE_END 0xfffffffffULL | |
| 715 | 512 | |
| 716 | −/**********************************************************************/ | |
| 513 | +#endif | |
| 717 | 514 | |
| 718 | −/* | |
| 719 | − * Physical base addresses for integrated peripherals | |
| 720 | − * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 5..au1300 | |
| 721 | − */ | |
| 515 | +/* PCI controller block register offsets */ | |
| 516 | +#define PCI_REG_CMEM 0x0000 | |
| 517 | +#define PCI_REG_CONFIG 0x0004 | |
| 518 | +#define PCI_REG_B2BMASK_CCH 0x0008 | |
| 519 | +#define PCI_REG_B2BBASE0_VID 0x000C | |
| 520 | +#define PCI_REG_B2BBASE1_SID 0x0010 | |
| 521 | +#define PCI_REG_MWMASK_DEV 0x0014 | |
| 522 | +#define PCI_REG_MWBASE_REV_CCL 0x0018 | |
| 523 | +#define PCI_REG_ERR_ADDR 0x001C | |
| 524 | +#define PCI_REG_SPEC_INTACK 0x0020 | |
| 525 | +#define PCI_REG_ID 0x0100 | |
| 526 | +#define PCI_REG_STATCMD 0x0104 | |
| 527 | +#define PCI_REG_CLASSREV 0x0108 | |
| 528 | +#define PCI_REG_PARAM 0x010C | |
| 529 | +#define PCI_REG_MBAR 0x0110 | |
| 530 | +#define PCI_REG_TIMEOUT 0x0140 | |
| 722 | 531 | |
| 723 | −#define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ | |
| 724 | −#define AU1300_ROM_PHYS_ADDR 0x10000000 /* 5 */ | |
| 725 | −#define AU1300_OTP_PHYS_ADDR 0x10002000 /* 5 */ | |
| 726 | −#define AU1300_VSS_PHYS_ADDR 0x10003000 /* 5 */ | |
| 727 | −#define AU1300_UART0_PHYS_ADDR 0x10100000 /* 5 */ | |
| 728 | −#define AU1300_UART1_PHYS_ADDR 0x10101000 /* 5 */ | |
| 729 | −#define AU1300_UART2_PHYS_ADDR 0x10102000 /* 5 */ | |
| 730 | −#define AU1300_UART3_PHYS_ADDR 0x10103000 /* 5 */ | |
| 731 | −#define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */ | |
| 732 | −#define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */ | |
| 733 | −#define AU1300_GPIC_PHYS_ADDR 0x10200000 /* 5 */ | |
| 734 | −#define AU1000_IRDA_PHYS_ADDR 0x10300000 /* 02 */ | |
| 735 | −#define AU1200_AES_PHYS_ADDR 0x10300000 /* 45 */ | |
| 736 | −#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | |
| 737 | −#define AU1300_GPU_PHYS_ADDR 0x10500000 /* 5 */ | |
| 738 | −#define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | |
| 739 | −#define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | |
| 740 | −#define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */ | |
| 741 | −#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 245 */ | |
| 742 | −#define AU1300_SD1_PHYS_ADDR 0x10601000 /* 5 */ | |
| 743 | −#define AU1300_SD2_PHYS_ADDR 0x10602000 /* 5 */ | |
| 744 | −#define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */ | |
| 745 | −#define AU1300_SYS_PHYS_ADDR 0x10900000 /* 5 */ | |
| 746 | −#define AU1550_PSC2_PHYS_ADDR 0x10A00000 /* 3 */ | |
| 747 | −#define AU1550_PSC3_PHYS_ADDR 0x10B00000 /* 3 */ | |
| 748 | −#define AU1300_PSC0_PHYS_ADDR 0x10A00000 /* 5 */ | |
| 749 | −#define AU1300_PSC1_PHYS_ADDR 0x10A01000 /* 5 */ | |
| 750 | −#define AU1300_PSC2_PHYS_ADDR 0x10A02000 /* 5 */ | |
| 751 | −#define AU1300_PSC3_PHYS_ADDR 0x10A03000 /* 5 */ | |
| 752 | −#define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */ | |
| 753 | −#define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */ | |
| 754 | −#define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */ | |
| 755 | −#define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */ | |
| 756 | −#define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */ | |
| 757 | −#define AU1200_SWCNT_PHYS_ADDR 0x1110010C /* 4 */ | |
| 758 | −#define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */ | |
| 759 | −#define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */ | |
| 760 | −#define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */ | |
| 761 | −#define AU1000_SSI0_PHYS_ADDR 0x11600000 /* 02 */ | |
| 762 | −#define AU1000_SSI1_PHYS_ADDR 0x11680000 /* 02 */ | |
| 763 | −#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */ | |
| 764 | −#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ | |
| 765 | −#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 012345 */ | |
| 766 | −#define AU1550_PSC0_PHYS_ADDR 0x11A00000 /* 34 */ | |
| 767 | −#define AU1550_PSC1_PHYS_ADDR 0x11B00000 /* 34 */ | |
| 768 | −#define AU1000_MEM_PHYS_ADDR 0x14000000 /* 01234 */ | |
| 769 | −#define AU1000_STATIC_MEM_PHYS_ADDR 0x14001000 /* 01234 */ | |
| 770 | −#define AU1300_UDMA_PHYS_ADDR 0x14001800 /* 5 */ | |
| 771 | −#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */ | |
| 772 | −#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 345 */ | |
| 773 | −#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 345 */ | |
| 774 | −#define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | |
| 775 | −#define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | |
| 776 | −#define AU1200_CIM_PHYS_ADDR 0x14004000 /* 45 */ | |
| 777 | −#define AU1500_PCI_PHYS_ADDR 0x14005000 /* 13 */ | |
| 778 | −#define AU1550_PE_PHYS_ADDR 0x14008000 /* 3 */ | |
| 779 | −#define AU1200_MAEBE_PHYS_ADDR 0x14010000 /* 4 */ | |
| 780 | −#define AU1200_MAEFE_PHYS_ADDR 0x14012000 /* 4 */ | |
| 781 | −#define AU1300_MAEITE_PHYS_ADDR 0x14010000 /* 5 */ | |
| 782 | −#define AU1300_MAEMPE_PHYS_ADDR 0x14014000 /* 5 */ | |
| 783 | −#define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */ | |
| 784 | −#define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */ | |
| 785 | −#define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */ | |
| 786 | −#define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */ | |
| 787 | −#define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */ | |
| 788 | −#define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */ | |
| 789 | −#define AU1300_USB_EHCI_PHYS_ADDR 0x14020000 /* 5 */ | |
| 790 | −#define AU1300_USB_OHCI0_PHYS_ADDR 0x14020400 /* 5 */ | |
| 791 | −#define AU1300_USB_OHCI1_PHYS_ADDR 0x14020800 /* 5 */ | |
| 792 | −#define AU1300_USB_CTL_PHYS_ADDR 0x14021000 /* 5 */ | |
| 793 | −#define AU1300_USB_OTG_PHYS_ADDR 0x14022000 /* 5 */ | |
| 794 | −#define AU1300_MAEBSA_PHYS_ADDR 0x14030000 /* 5 */ | |
| 795 | −#define AU1100_LCD_PHYS_ADDR 0x15000000 /* 2 */ | |
| 796 | −#define AU1200_LCD_PHYS_ADDR 0x15000000 /* 45 */ | |
| 797 | −#define AU1500_PCI_MEM_PHYS_ADDR 0x400000000ULL /* 13 */ | |
| 798 | −#define AU1500_PCI_IO_PHYS_ADDR 0x500000000ULL /* 13 */ | |
| 799 | −#define AU1500_PCI_CONFIG0_PHYS_ADDR 0x600000000ULL /* 13 */ | |
| 800 | −#define AU1500_PCI_CONFIG1_PHYS_ADDR 0x680000000ULL /* 13 */ | |
| 801 | −#define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 012345 */ | |
| 802 | −#define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 012345 */ | |
| 803 | −#define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 012345 */ | |
| 804 | − | |
| 805 | −/**********************************************************************/ | |
| 806 | − | |
| 807 | − | |
| 808 | −/* | |
| 809 | − * Au1300 GPIO+INT controller (GPIC) register offsets and bits | |
| 810 | − * Registers are 128bits (0x10 bytes), divided into 4 "banks". | |
| 811 | − */ | |
| 812 | −#define AU1300_GPIC_PINVAL 0x0000 | |
| 813 | −#define AU1300_GPIC_PINVALCLR 0x0010 | |
| 814 | −#define AU1300_GPIC_IPEND 0x0020 | |
| 815 | −#define AU1300_GPIC_PRIENC 0x0030 | |
| 816 | −#define AU1300_GPIC_IEN 0x0040 /* int_mask in manual */ | |
| 817 | −#define AU1300_GPIC_IDIS 0x0050 /* int_maskclr in manual */ | |
| 818 | −#define AU1300_GPIC_DMASEL 0x0060 | |
| 819 | −#define AU1300_GPIC_DEVSEL 0x0080 | |
| 820 | −#define AU1300_GPIC_DEVCLR 0x0090 | |
| 821 | −#define AU1300_GPIC_RSTVAL 0x00a0 | |
| 822 | −/* pin configuration space. one 32bit register for up to 128 IRQs */ | |
| 823 | −#define AU1300_GPIC_PINCFG 0x1000 | |
| 824 | − | |
| 825 | −#define GPIC_GPIO_TO_BIT(gpio) \ | |
| 826 | − (1 << ((gpio) & 0x1f)) | |
| 827 | − | |
| 828 | −#define GPIC_GPIO_BANKOFF(gpio) \ | |
| 829 | − (((gpio) >> 5) * 4) | |
| 532 | +/* PCI controller block register bits */ | |
| 533 | +#define PCI_CMEM_E (1 << 28) /* enable cacheable memory */ | |
| 534 | +#define PCI_CMEM_CMBASE(x) (((x) & 0x3fff) << 14) | |
| 535 | +#define PCI_CMEM_CMMASK(x) ((x) & 0x3fff) | |
| 536 | +#define PCI_CONFIG_ERD (1 << 27) /* pci error during R/W */ | |
| 537 | +#define PCI_CONFIG_ET (1 << 26) /* error in target mode */ | |
| 538 | +#define PCI_CONFIG_EF (1 << 25) /* fatal error */ | |
| 539 | +#define PCI_CONFIG_EP (1 << 24) /* parity error */ | |
| 540 | +#define PCI_CONFIG_EM (1 << 23) /* multiple errors */ | |
| 541 | +#define PCI_CONFIG_BM (1 << 22) /* bad master error */ | |
| 542 | +#define PCI_CONFIG_PD (1 << 20) /* PCI Disable */ | |
| 543 | +#define PCI_CONFIG_BME (1 << 19) /* Byte Mask Enable for reads */ | |
| 544 | +#define PCI_CONFIG_NC (1 << 16) /* mark mem access non-coherent */ | |
| 545 | +#define PCI_CONFIG_IA (1 << 15) /* INTA# enabled (target mode) */ | |
| 546 | +#define PCI_CONFIG_IP (1 << 13) /* int on PCI_PERR# */ | |
| 547 | +#define PCI_CONFIG_IS (1 << 12) /* int on PCI_SERR# */ | |
| 548 | +#define PCI_CONFIG_IMM (1 << 11) /* int on master abort */ | |
| 549 | +#define PCI_CONFIG_ITM (1 << 10) /* int on target abort (as master) */ | |
| 550 | +#define PCI_CONFIG_ITT (1 << 9) /* int on target abort (as target) */ | |
| 551 | +#define PCI_CONFIG_IPB (1 << 8) /* int on PERR# in bus master acc */ | |
| 552 | +#define PCI_CONFIG_SIC_NO (0 << 6) /* no byte mask changes */ | |
| 553 | +#define PCI_CONFIG_SIC_BA_ADR (1 << 6) /* on byte/hw acc, invert adr bits */ | |
| 554 | +#define PCI_CONFIG_SIC_HWA_DAT (2 << 6) /* on halfword acc, swap data */ | |
| 555 | +#define PCI_CONFIG_SIC_ALL (3 << 6) /* swap data bytes on all accesses */ | |
| 556 | +#define PCI_CONFIG_ST (1 << 5) /* swap data by target transactions */ | |
| 557 | +#define PCI_CONFIG_SM (1 << 4) /* swap data from PCI ctl */ | |
| 558 | +#define PCI_CONFIG_AEN (1 << 3) /* enable internal arbiter */ | |
| 559 | +#define PCI_CONFIG_R2H (1 << 2) /* REQ2# to hi-prio arbiter */ | |
| 560 | +#define PCI_CONFIG_R1H (1 << 1) /* REQ1# to hi-prio arbiter */ | |
| 561 | +#define PCI_CONFIG_CH (1 << 0) /* PCI ctl to hi-prio arbiter */ | |
| 562 | +#define PCI_B2BMASK_B2BMASK(x) (((x) & 0xffff) << 16) | |
| 563 | +#define PCI_B2BMASK_CCH(x) ((x) & 0xffff) /* 16 upper bits of class code */ | |
| 564 | +#define PCI_B2BBASE0_VID_B0(x) (((x) & 0xffff) << 16) | |
| 565 | +#define PCI_B2BBASE0_VID_SV(x) ((x) & 0xffff) | |
| 566 | +#define PCI_B2BBASE1_SID_B1(x) (((x) & 0xffff) << 16) | |
| 567 | +#define PCI_B2BBASE1_SID_SI(x) ((x) & 0xffff) | |
| 568 | +#define PCI_MWMASKDEV_MWMASK(x) (((x) & 0xffff) << 16) | |
| 569 | +#define PCI_MWMASKDEV_DEVID(x) ((x) & 0xffff) | |
| 570 | +#define PCI_MWBASEREVCCL_BASE(x) (((x) & 0xffff) << 16) | |
| 571 | +#define PCI_MWBASEREVCCL_REV(x) (((x) & 0xff) << 8) | |
| 572 | +#define PCI_MWBASEREVCCL_CCL(x) ((x) & 0xff) | |
| 573 | +#define PCI_ID_DID(x) (((x) & 0xffff) << 16) | |
| 574 | +#define PCI_ID_VID(x) ((x) & 0xffff) | |
| 575 | +#define PCI_STATCMD_STATUS(x) (((x) & 0xffff) << 16) | |
| 576 | +#define PCI_STATCMD_CMD(x) ((x) & 0xffff) | |
| 577 | +#define PCI_CLASSREV_CLASS(x) (((x) & 0x00ffffff) << 8) | |
| 578 | +#define PCI_CLASSREV_REV(x) ((x) & 0xff) | |
| 579 | +#define PCI_PARAM_BIST(x) (((x) & 0xff) << 24) | |
| 580 | +#define PCI_PARAM_HT(x) (((x) & 0xff) << 16) | |
| 581 | +#define PCI_PARAM_LT(x) (((x) & 0xff) << 8) | |
| 582 | +#define PCI_PARAM_CLS(x) ((x) & 0xff) | |
| 583 | +#define PCI_TIMEOUT_RETRIES(x) (((x) & 0xff) << 8) /* max retries */ | |
| 584 | +#define PCI_TIMEOUT_TO(x) ((x) & 0xff) /* target ready timeout */ | |
| 830 | 585 | |
| 831 | −/* Pin Control bits: who owns the pin, what does it do */ | |
| 832 | −#define GPIC_CFG_PC_GPIN 0 | |
| 833 | −#define GPIC_CFG_PC_DEV 1 | |
| 834 | −#define GPIC_CFG_PC_GPOLOW 2 | |
| 835 | −#define GPIC_CFG_PC_GPOHIGH 3 | |
| 836 | −#define GPIC_CFG_PC_MASK 3 | |
| 837 | 586 | |
| 838 | −/* assign pin to MIPS IRQ line */ | |
| 839 | −#define GPIC_CFG_IL_SET(x) (((x) & 3) << 2) | |
| 840 | −#define GPIC_CFG_IL_MASK (3 << 2) | |
| 587 | +/**********************************************************************/ | |
| 841 | 588 | |
| 842 | −/* pin interrupt type setup */ | |
| 843 | −#define GPIC_CFG_IC_OFF (0 << 4) | |
| 844 | −#define GPIC_CFG_IC_LEVEL_LOW (1 << 4) | |
| 845 | −#define GPIC_CFG_IC_LEVEL_HIGH (2 << 4) | |
| 846 | −#define GPIC_CFG_IC_EDGE_FALL (5 << 4) | |
| 847 | −#define GPIC_CFG_IC_EDGE_RISE (6 << 4) | |
| 848 | −#define GPIC_CFG_IC_EDGE_BOTH (7 << 4) | |
| 849 | −#define GPIC_CFG_IC_MASK (7 << 4) | |
| 850 | 589 | |
| 851 | −/* allow interrupt to wake cpu from 'wait' */ | |
| 852 | −#define GPIC_CFG_IDLEWAKE (1 << 7) | |
| 590 | +#ifndef _LANGUAGE_ASSEMBLY | |
| 853 | 591 | |
| 854 | −/***********************************************************************/ | |
| 592 | +#include <linux/delay.h> | |
| 593 | +#include <linux/types.h> | |
| 855 | 594 | |
| 856 | −/* Au1000 SDRAM memory controller register offsets */ | |
| 857 | −#define AU1000_MEM_SDMODE0 0x0000 | |
| 858 | −#define AU1000_MEM_SDMODE1 0x0004 | |
| 859 | −#define AU1000_MEM_SDMODE2 0x0008 | |
| 860 | −#define AU1000_MEM_SDADDR0 0x000C | |
| 861 | −#define AU1000_MEM_SDADDR1 0x0010 | |
| 862 | −#define AU1000_MEM_SDADDR2 0x0014 | |
| 863 | −#define AU1000_MEM_SDREFCFG 0x0018 | |
| 864 | −#define AU1000_MEM_SDPRECMD 0x001C | |
| 865 | −#define AU1000_MEM_SDAUTOREF 0x0020 | |
| 866 | −#define AU1000_MEM_SDWRMD0 0x0024 | |
| 867 | −#define AU1000_MEM_SDWRMD1 0x0028 | |
| 868 | −#define AU1000_MEM_SDWRMD2 0x002C | |
| 869 | −#define AU1000_MEM_SDSLEEP 0x0030 | |
| 870 | −#define AU1000_MEM_SDSMCKE 0x0034 | |
| 595 | +#include <linux/io.h> | |
| 596 | +#include <linux/irq.h> | |
| 871 | 597 | |
| 872 | −/* MEM_SDMODE register content definitions */ | |
| 873 | −#define MEM_SDMODE_F (1 << 22) | |
| 874 | −#define MEM_SDMODE_SR (1 << 21) | |
| 875 | −#define MEM_SDMODE_BS (1 << 20) | |
| 876 | −#define MEM_SDMODE_RS (3 << 18) | |
| 877 | −#define MEM_SDMODE_CS (7 << 15) | |
| 878 | −#define MEM_SDMODE_TRAS (15 << 11) | |
| 879 | −#define MEM_SDMODE_TMRD (3 << 9) | |
| 880 | −#define MEM_SDMODE_TWR (3 << 7) | |
| 881 | −#define MEM_SDMODE_TRP (3 << 5) | |
| 882 | −#define MEM_SDMODE_TRCD (3 << 3) | |
| 883 | −#define MEM_SDMODE_TCL (7 << 0) | |
| 598 | +#include <asm/cpu.h> | |
| 884 | 599 | |
| 885 | −#define MEM_SDMODE_BS_2Bank (0 << 20) | |
| 886 | −#define MEM_SDMODE_BS_4Bank (1 << 20) | |
| 887 | −#define MEM_SDMODE_RS_11Row (0 << 18) | |
| 888 | −#define MEM_SDMODE_RS_12Row (1 << 18) | |
| 889 | −#define MEM_SDMODE_RS_13Row (2 << 18) | |
| 890 | −#define MEM_SDMODE_RS_N(N) ((N) << 18) | |
| 891 | −#define MEM_SDMODE_CS_7Col (0 << 15) | |
| 892 | −#define MEM_SDMODE_CS_8Col (1 << 15) | |
| 893 | −#define MEM_SDMODE_CS_9Col (2 << 15) | |
| 894 | −#define MEM_SDMODE_CS_10Col (3 << 15) | |
| 895 | −#define MEM_SDMODE_CS_11Col (4 << 15) | |
| 896 | −#define MEM_SDMODE_CS_N(N) ((N) << 15) | |
| 897 | −#define MEM_SDMODE_TRAS_N(N) ((N) << 11) | |
| 898 | −#define MEM_SDMODE_TMRD_N(N) ((N) << 9) | |
| 899 | −#define MEM_SDMODE_TWR_N(N) ((N) << 7) | |
| 900 | −#define MEM_SDMODE_TRP_N(N) ((N) << 5) | |
| 901 | −#define MEM_SDMODE_TRCD_N(N) ((N) << 3) | |
| 902 | −#define MEM_SDMODE_TCL_N(N) ((N) << 0) | |
| 600 | +/* helpers to access the SYS_* registers */ | |
| 601 | +static inline unsigned long alchemy_rdsys(int regofs) | |
| 602 | +{ | |
| 603 | + void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | |
| 903 | 604 | |
| 904 | −/* MEM_SDADDR register contents definitions */ | |
| 905 | −#define MEM_SDADDR_E (1 << 20) | |
| 906 | −#define MEM_SDADDR_CSBA (0x03FF << 10) | |
| 907 | −#define MEM_SDADDR_CSMASK (0x03FF << 0) | |
| 908 | −#define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) | |
| 909 | −#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) | |
| 605 | + return __raw_readl(b + regofs); | |
| 606 | +} | |
| 910 | 607 | |
| 911 | −/* MEM_SDREFCFG register content definitions */ | |
| 912 | −#define MEM_SDREFCFG_TRC (15 << 28) | |
| 913 | −#define MEM_SDREFCFG_TRPM (3 << 26) | |
| 914 | −#define MEM_SDREFCFG_E (1 << 25) | |
| 915 | −#define MEM_SDREFCFG_RE (0x1ffffff << 0) | |
| 916 | −#define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC) | |
| 917 | −#define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM) | |
| 918 | −#define MEM_SDREFCFG_REF_N(N) (N) | |
| 608 | +static inline void alchemy_wrsys(unsigned long v, int regofs) | |
| 609 | +{ | |
| 610 | + void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | |
| 919 | 611 | |
| 920 | −/* Au1550 SDRAM Register Offsets */ | |
| 921 | −#define AU1550_MEM_SDMODE0 0x0800 | |
| 922 | −#define AU1550_MEM_SDMODE1 0x0808 | |
| 923 | −#define AU1550_MEM_SDMODE2 0x0810 | |
| 924 | −#define AU1550_MEM_SDADDR0 0x0820 | |
| 925 | −#define AU1550_MEM_SDADDR1 0x0828 | |
| 926 | −#define AU1550_MEM_SDADDR2 0x0830 | |
| 927 | −#define AU1550_MEM_SDCONFIGA 0x0840 | |
| 928 | −#define AU1550_MEM_SDCONFIGB 0x0848 | |
| 929 | −#define AU1550_MEM_SDSTAT 0x0850 | |
| 930 | −#define AU1550_MEM_SDERRADDR 0x0858 | |
| 931 | −#define AU1550_MEM_SDSTRIDE0 0x0860 | |
| 932 | −#define AU1550_MEM_SDSTRIDE1 0x0868 | |
| 933 | −#define AU1550_MEM_SDSTRIDE2 0x0870 | |
| 934 | −#define AU1550_MEM_SDWRMD0 0x0880 | |
| 935 | −#define AU1550_MEM_SDWRMD1 0x0888 | |
| 936 | −#define AU1550_MEM_SDWRMD2 0x0890 | |
| 937 | −#define AU1550_MEM_SDPRECMD 0x08C0 | |
| 938 | −#define AU1550_MEM_SDAUTOREF 0x08C8 | |
| 939 | −#define AU1550_MEM_SDSREF 0x08D0 | |
| 940 | −#define AU1550_MEM_SDSLEEP MEM_SDSREF | |
| 612 | + __raw_writel(v, b + regofs); | |
| 613 | + wmb(); /* drain writebuffer */ | |
| 614 | +} | |
| 941 | 615 | |
| 942 | −/* Static Bus Controller */ | |
| 943 | −#define MEM_STCFG0 0xB4001000 | |
| 944 | −#define MEM_STTIME0 0xB4001004 | |
| 945 | −#define MEM_STADDR0 0xB4001008 | |
| 616 | +/* helpers to access static memctrl registers */ | |
| 617 | +static inline unsigned long alchemy_rdsmem(int regofs) | |
| 618 | +{ | |
| 619 | + void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); | |
| 946 | 620 | |
| 947 | −#define MEM_STCFG1 0xB4001010 | |
| 948 | −#define MEM_STTIME1 0xB4001014 | |
| 949 | −#define MEM_STADDR1 0xB4001018 | |
| 621 | + return __raw_readl(b + regofs); | |
| 622 | +} | |
| 950 | 623 | |
| 951 | −#define MEM_STCFG2 0xB4001020 | |
| 952 | −#define MEM_STTIME2 0xB4001024 | |
| 953 | −#define MEM_STADDR2 0xB4001028 | |
| 624 | +static inline void alchemy_wrsmem(unsigned long v, int regofs) | |
| 625 | +{ | |
| 626 | + void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); | |
| 954 | 627 | |
| 955 | −#define MEM_STCFG3 0xB4001030 | |
| 956 | −#define MEM_STTIME3 0xB4001034 | |
| 957 | −#define MEM_STADDR3 0xB4001038 | |
| 628 | + __raw_writel(v, b + regofs); | |
| 629 | + wmb(); /* drain writebuffer */ | |
| 630 | +} | |
| 958 | 631 | |
| 959 | −#define MEM_STNDCTL 0xB4001100 | |
| 960 | −#define MEM_STSTAT 0xB4001104 | |
| 632 | +/* Early Au1000 have a write-only SYS_CPUPLL register. */ | |
| 633 | +static inline int au1xxx_cpu_has_pll_wo(void) | |
| 634 | +{ | |
| 635 | + switch (read_c0_prid()) { | |
| 636 | + case 0x00030100: /* Au1000 DA */ | |
| 637 | + case 0x00030201: /* Au1000 HA */ | |
| 638 | + case 0x00030202: /* Au1000 HB */ | |
| 639 | + return 1; | |
| 640 | + } | |
| 641 | + return 0; | |
| 642 | +} | |
| 961 | 643 | |
| 962 | −#define MEM_STNAND_CMD 0x0 | |
| 963 | −#define MEM_STNAND_ADDR 0x4 | |
| 964 | −#define MEM_STNAND_DATA 0x20 | |
| 965 | − | |
| 966 | − | |
| 967 | −/* Programmable Counters 0 and 1 */ | |
| 968 | −#define SYS_BASE 0xB1900000 | |
| 969 | −#define SYS_COUNTER_CNTRL (SYS_BASE + 0x14) | |
| 970 | −# define SYS_CNTRL_E1S (1 << 23) | |
| 971 | −# define SYS_CNTRL_T1S (1 << 20) | |
| 972 | −# define SYS_CNTRL_M21 (1 << 19) | |
| 973 | −# define SYS_CNTRL_M11 (1 << 18) | |
| 974 | −# define SYS_CNTRL_M01 (1 << 17) | |
| 975 | −# define SYS_CNTRL_C1S (1 << 16) | |
| 976 | −# define SYS_CNTRL_BP (1 << 14) | |
| 977 | −# define SYS_CNTRL_EN1 (1 << 13) | |
| 978 | −# define SYS_CNTRL_BT1 (1 << 12) | |
| 979 | −# define SYS_CNTRL_EN0 (1 << 11) | |
| 980 | −# define SYS_CNTRL_BT0 (1 << 10) | |
| 981 | −# define SYS_CNTRL_E0 (1 << 8) | |
| 982 | −# define SYS_CNTRL_E0S (1 << 7) | |
| 983 | −# define SYS_CNTRL_32S (1 << 5) | |
| 984 | −# define SYS_CNTRL_T0S (1 << 4) | |
| 985 | −# define SYS_CNTRL_M20 (1 << 3) | |
| 986 | −# define SYS_CNTRL_M10 (1 << 2) | |
| 987 | −# define SYS_CNTRL_M00 (1 << 1) | |
| 988 | −# define SYS_CNTRL_C0S (1 << 0) | |
| 644 | +/* does CPU need CONFIG[OD] set to fix tons of errata? */ | |
| 645 | +static inline int au1xxx_cpu_needs_config_od(void) | |
| 646 | +{ | |
| 647 | + /* | |
| 648 | + * c0_config.od (bit 19) was write only (and read as 0) on the | |
| 649 | + * early revisions of Alchemy SOCs. It disables the bus trans- | |
| 650 | + * action overlapping and needs to be set to fix various errata. | |
| 651 | + */ | |
| 652 | + switch (read_c0_prid()) { | |
| 653 | + case 0x00030100: /* Au1000 DA */ | |
| 654 | + case 0x00030201: /* Au1000 HA */ | |
| 655 | + case 0x00030202: /* Au1000 HB */ | |
| 656 | + case 0x01030200: /* Au1500 AB */ | |
| 657 | + /* | |
| 658 | + * Au1100/Au1200 errata actually keep silence about this bit, | |
| 659 | + * so we set it just in case for those revisions that require | |
| 660 | + * it to be set according to the (now gone) cpu_table. | |
| 661 | + */ | |
| 662 | + case 0x02030200: /* Au1100 AB */ | |
| 663 | + case 0x02030201: /* Au1100 BA */ | |
| 664 | + case 0x02030202: /* Au1100 BC */ | |
| 665 | + case 0x04030201: /* Au1200 AC */ | |
| 666 | + return 1; | |
| 667 | + } | |
| 668 | + return 0; | |
| 669 | +} | |
| 989 | 670 | |
| 990 | −/* Programmable Counter 0 Registers */ | |
| 991 | −#define SYS_TOYTRIM (SYS_BASE + 0) | |
| 992 | −#define SYS_TOYWRITE (SYS_BASE + 4) | |
| 993 | −#define SYS_TOYMATCH0 (SYS_BASE + 8) | |
| 994 | −#define SYS_TOYMATCH1 (SYS_BASE + 0xC) | |
| 995 | −#define SYS_TOYMATCH2 (SYS_BASE + 0x10) | |
| 996 | −#define SYS_TOYREAD (SYS_BASE + 0x40) | |
| 671 | +#define ALCHEMY_CPU_UNKNOWN -1 | |
| 672 | +#define ALCHEMY_CPU_AU1000 0 | |
| 673 | +#define ALCHEMY_CPU_AU1500 1 | |
| 674 | +#define ALCHEMY_CPU_AU1100 2 | |
| 675 | +#define ALCHEMY_CPU_AU1550 3 | |
| 676 | +#define ALCHEMY_CPU_AU1200 4 | |
| 677 | +#define ALCHEMY_CPU_AU1300 5 | |
| 997 | 678 | |
| 998 | −/* Programmable Counter 1 Registers */ | |
| 999 | −#define SYS_RTCTRIM (SYS_BASE + 0x44) | |
| 1000 | −#define SYS_RTCWRITE (SYS_BASE + 0x48) | |
| 1001 | −#define SYS_RTCMATCH0 (SYS_BASE + 0x4C) | |
| 1002 | −#define SYS_RTCMATCH1 (SYS_BASE + 0x50) | |
| 1003 | −#define SYS_RTCMATCH2 (SYS_BASE + 0x54) | |
| 1004 | −#define SYS_RTCREAD (SYS_BASE + 0x58) | |
| 1005 | − | |
| 1006 | −/* I2S Controller */ | |
| 1007 | −#define I2S_DATA 0xB1000000 | |
| 1008 | −# define I2S_DATA_MASK 0xffffff | |
| 1009 | −#define I2S_CONFIG 0xB1000004 | |
| 1010 | −# define I2S_CONFIG_XU (1 << 25) | |
| 1011 | −# define I2S_CONFIG_XO (1 << 24) | |
| 1012 | −# define I2S_CONFIG_RU (1 << 23) | |
| 1013 | −# define I2S_CONFIG_RO (1 << 22) | |
| 1014 | −# define I2S_CONFIG_TR (1 << 21) | |
| 1015 | −# define I2S_CONFIG_TE (1 << 20) | |
| 1016 | −# define I2S_CONFIG_TF (1 << 19) | |
| 1017 | −# define I2S_CONFIG_RR (1 << 18) | |
| 1018 | −# define I2S_CONFIG_RE (1 << 17) | |
| 1019 | −# define I2S_CONFIG_RF (1 << 16) | |
| 1020 | −# define I2S_CONFIG_PD (1 << 11) | |
| 1021 | −# define I2S_CONFIG_LB (1 << 10) | |
| 1022 | −# define I2S_CONFIG_IC (1 << 9) | |
| 1023 | −# define I2S_CONFIG_FM_BIT 7 | |
| 1024 | −# define I2S_CONFIG_FM_MASK (0x3 << I2S_CONFIG_FM_BIT) | |
| 1025 | −# define I2S_CONFIG_FM_I2S (0x0 << I2S_CONFIG_FM_BIT) | |
| 1026 | −# define I2S_CONFIG_FM_LJ (0x1 << I2S_CONFIG_FM_BIT) | |
| 1027 | −# define I2S_CONFIG_FM_RJ (0x2 << I2S_CONFIG_FM_BIT) | |
| 1028 | −# define I2S_CONFIG_TN (1 << 6) | |
| 1029 | −# define I2S_CONFIG_RN (1 << 5) | |
| 1030 | −# define I2S_CONFIG_SZ_BIT 0 | |
| 1031 | −# define I2S_CONFIG_SZ_MASK (0x1F << I2S_CONFIG_SZ_BIT) | |
| 1032 | − | |
| 1033 | −#define I2S_CONTROL 0xB1000008 | |
| 1034 | −# define I2S_CONTROL_D (1 << 1) | |
| 1035 | −# define I2S_CONTROL_CE (1 << 0) | |
| 1036 | − | |
| 1037 | − | |
| 1038 | −/* Ethernet Controllers */ | |
| 1039 | − | |
| 1040 | −/* 4 byte offsets from AU1000_ETH_BASE */ | |
| 1041 | −#define MAC_CONTROL 0x0 | |
| 1042 | −# define MAC_RX_ENABLE (1 << 2) | |
| 1043 | −# define MAC_TX_ENABLE (1 << 3) | |
| 1044 | −# define MAC_DEF_CHECK (1 << 5) | |
| 1045 | −# define MAC_SET_BL(X) (((X) & 0x3) << 6) | |
| 1046 | −# define MAC_AUTO_PAD (1 << 8) | |
| 1047 | −# define MAC_DISABLE_RETRY (1 << 10) | |
| 1048 | −# define MAC_DISABLE_BCAST (1 << 11) | |
| 1049 | −# define MAC_LATE_COL (1 << 12) | |
| 1050 | −# define MAC_HASH_MODE (1 << 13) | |
| 1051 | −# define MAC_HASH_ONLY (1 << 15) | |
| 1052 | −# define MAC_PASS_ALL (1 << 16) | |
| 1053 | −# define MAC_INVERSE_FILTER (1 << 17) | |
| 1054 | −# define MAC_PROMISCUOUS (1 << 18) | |
| 1055 | −# define MAC_PASS_ALL_MULTI (1 << 19) | |
| 1056 | −# define MAC_FULL_DUPLEX (1 << 20) | |
| 1057 | −# define MAC_NORMAL_MODE 0 | |
| 1058 | −# define MAC_INT_LOOPBACK (1 << 21) | |
| 1059 | −# define MAC_EXT_LOOPBACK (1 << 22) | |
| 1060 | −# define MAC_DISABLE_RX_OWN (1 << 23) | |
| 1061 | −# define MAC_BIG_ENDIAN (1 << 30) | |
| 1062 | −# define MAC_RX_ALL (1 << 31) | |
| 1063 | −#define MAC_ADDRESS_HIGH 0x4 | |
| 1064 | −#define MAC_ADDRESS_LOW 0x8 | |
| 1065 | −#define MAC_MCAST_HIGH 0xC | |
| 1066 | −#define MAC_MCAST_LOW 0x10 | |
| 1067 | −#define MAC_MII_CNTRL 0x14 | |
| 1068 | −# define MAC_MII_BUSY (1 << 0) | |
| 1069 | −# define MAC_MII_READ 0 | |
| 1070 | −# define MAC_MII_WRITE (1 << 1) | |
| 1071 | −# define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6) | |
| 1072 | −# define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11) | |
| 1073 | −#define MAC_MII_DATA 0x18 | |
| 1074 | −#define MAC_FLOW_CNTRL 0x1C | |
| 1075 | −# define MAC_FLOW_CNTRL_BUSY (1 << 0) | |
| 1076 | −# define MAC_FLOW_CNTRL_ENABLE (1 << 1) | |
| 1077 | −# define MAC_PASS_CONTROL (1 << 2) | |
| 1078 | −# define MAC_SET_PAUSE(X) (((X) & 0xffff) << 16) | |
| 1079 | −#define MAC_VLAN1_TAG 0x20 | |
| 1080 | −#define MAC_VLAN2_TAG 0x24 | |
| 1081 | − | |
| 1082 | −/* Ethernet Controller Enable */ | |
| 1083 | − | |
| 1084 | −# define MAC_EN_CLOCK_ENABLE (1 << 0) | |
| 1085 | −# define MAC_EN_RESET0 (1 << 1) | |
| 1086 | −# define MAC_EN_TOSS (0 << 2) | |
| 1087 | −# define MAC_EN_CACHEABLE (1 << 3) | |
| 1088 | −# define MAC_EN_RESET1 (1 << 4) | |
| 1089 | −# define MAC_EN_RESET2 (1 << 5) | |
| 1090 | −# define MAC_DMA_RESET (1 << 6) | |
| 1091 | − | |
| 1092 | −/* Ethernet Controller DMA Channels */ | |
| 1093 | − | |
| 1094 | −#define MAC0_TX_DMA_ADDR 0xB4004000 | |
| 1095 | −#define MAC1_TX_DMA_ADDR 0xB4004200 | |
| 1096 | −/* offsets from MAC_TX_RING_ADDR address */ | |
| 1097 | −#define MAC_TX_BUFF0_STATUS 0x0 | |
| 1098 | −# define TX_FRAME_ABORTED (1 << 0) | |
| 1099 | −# define TX_JAB_TIMEOUT (1 << 1) | |
| 1100 | −# define TX_NO_CARRIER (1 << 2) | |
| 1101 | −# define TX_LOSS_CARRIER (1 << 3) | |
| 1102 | −# define TX_EXC_DEF (1 << 4) | |
| 1103 | −# define TX_LATE_COLL_ABORT (1 << 5) | |
| 1104 | −# define TX_EXC_COLL (1 << 6) | |
| 1105 | −# define TX_UNDERRUN (1 << 7) | |
| 1106 | −# define TX_DEFERRED (1 << 8) | |
| 1107 | −# define TX_LATE_COLL (1 << 9) | |
| 1108 | −# define TX_COLL_CNT_MASK (0xF << 10) | |
| 1109 | −# define TX_PKT_RETRY (1 << 31) | |
| 1110 | −#define MAC_TX_BUFF0_ADDR 0x4 | |
| 1111 | −# define TX_DMA_ENABLE (1 << 0) | |
| 1112 | −# define TX_T_DONE (1 << 1) | |
| 1113 | −# define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | |
| 1114 | −#define MAC_TX_BUFF0_LEN 0x8 | |
| 1115 | −#define MAC_TX_BUFF1_STATUS 0x10 | |
| 1116 | −#define MAC_TX_BUFF1_ADDR 0x14 | |
| 1117 | −#define MAC_TX_BUFF1_LEN 0x18 | |
| 1118 | −#define MAC_TX_BUFF2_STATUS 0x20 | |
| 1119 | −#define MAC_TX_BUFF2_ADDR 0x24 | |
| 1120 | −#define MAC_TX_BUFF2_LEN 0x28 | |
| 1121 | −#define MAC_TX_BUFF3_STATUS 0x30 | |
| 1122 | −#define MAC_TX_BUFF3_ADDR 0x34 | |
| 1123 | −#define MAC_TX_BUFF3_LEN 0x38 | |
| 1124 | − | |
| 1125 | −#define MAC0_RX_DMA_ADDR 0xB4004100 | |
| 1126 | −#define MAC1_RX_DMA_ADDR 0xB4004300 | |
| 1127 | −/* offsets from MAC_RX_RING_ADDR */ | |
| 1128 | −#define MAC_RX_BUFF0_STATUS 0x0 | |
| 1129 | −# define RX_FRAME_LEN_MASK 0x3fff | |
| 1130 | −# define RX_WDOG_TIMER (1 << 14) | |
| 1131 | −# define RX_RUNT (1 << 15) | |
| 1132 | −# define RX_OVERLEN (1 << 16) | |
| 1133 | −# define RX_COLL (1 << 17) | |
| 1134 | −# define RX_ETHER (1 << 18) | |
| 1135 | −# define RX_MII_ERROR (1 << 19) | |
| 1136 | −# define RX_DRIBBLING (1 << 20) | |
| 1137 | −# define RX_CRC_ERROR (1 << 21) | |
| 1138 | −# define RX_VLAN1 (1 << 22) | |
| 1139 | −# define RX_VLAN2 (1 << 23) | |
| 1140 | −# define RX_LEN_ERROR (1 << 24) | |
| 1141 | −# define RX_CNTRL_FRAME (1 << 25) | |
| 1142 | −# define RX_U_CNTRL_FRAME (1 << 26) | |
| 1143 | −# define RX_MCAST_FRAME (1 << 27) | |
| 1144 | −# define RX_BCAST_FRAME (1 << 28) | |
| 1145 | −# define RX_FILTER_FAIL (1 << 29) | |
| 1146 | −# define RX_PACKET_FILTER (1 << 30) | |
| 1147 | −# define RX_MISSED_FRAME (1 << 31) | |
| 1148 | − | |
| 1149 | −# define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \ | |
| 1150 | − RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \ | |
| 1151 | − RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME) | |
| 1152 | −#define MAC_RX_BUFF0_ADDR 0x4 | |
| 1153 | −# define RX_DMA_ENABLE (1 << 0) | |
| 1154 | −# define RX_T_DONE (1 << 1) | |
| 1155 | −# define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | |
| 1156 | −# define RX_SET_BUFF_ADDR(X) ((X) & 0xffffffc0) | |
| 1157 | −#define MAC_RX_BUFF1_STATUS 0x10 | |
| 1158 | −#define MAC_RX_BUFF1_ADDR 0x14 | |
| 1159 | −#define MAC_RX_BUFF2_STATUS 0x20 | |
| 1160 | −#define MAC_RX_BUFF2_ADDR 0x24 | |
| 1161 | −#define MAC_RX_BUFF3_STATUS 0x30 | |
| 1162 | −#define MAC_RX_BUFF3_ADDR 0x34 | |
| 1163 | − | |
| 1164 | −/* SSIO */ | |
| 1165 | −#define SSI0_STATUS 0xB1600000 | |
| 1166 | −# define SSI_STATUS_BF (1 << 4) | |
| 1167 | −# define SSI_STATUS_OF (1 << 3) | |
| 1168 | −# define SSI_STATUS_UF (1 << 2) | |
| 1169 | −# define SSI_STATUS_D (1 << 1) | |
| 1170 | −# define SSI_STATUS_B (1 << 0) | |
| 1171 | −#define SSI0_INT 0xB1600004 | |
| 1172 | −# define SSI_INT_OI (1 << 3) | |
| 1173 | −# define SSI_INT_UI (1 << 2) | |
| 1174 | −# define SSI_INT_DI (1 << 1) | |
| 1175 | −#define SSI0_INT_ENABLE 0xB1600008 | |
| 1176 | −# define SSI_INTE_OIE (1 << 3) | |
| 1177 | −# define SSI_INTE_UIE (1 << 2) | |
| 1178 | −# define SSI_INTE_DIE (1 << 1) | |
| 1179 | −#define SSI0_CONFIG 0xB1600020 | |
| 1180 | −# define SSI_CONFIG_AO (1 << 24) | |
| 1181 | −# define SSI_CONFIG_DO (1 << 23) | |
| 1182 | −# define SSI_CONFIG_ALEN_BIT 20 | |
| 1183 | −# define SSI_CONFIG_ALEN_MASK (0x7 << 20) | |
| 1184 | −# define SSI_CONFIG_DLEN_BIT 16 | |
| 1185 | −# define SSI_CONFIG_DLEN_MASK (0x7 << 16) | |
| 1186 | −# define SSI_CONFIG_DD (1 << 11) | |
| 1187 | −# define SSI_CONFIG_AD (1 << 10) | |
| 1188 | −# define SSI_CONFIG_BM_BIT 8 | |
| 1189 | −# define SSI_CONFIG_BM_MASK (0x3 << 8) | |
| 1190 | −# define SSI_CONFIG_CE (1 << 7) | |
| 1191 | −# define SSI_CONFIG_DP (1 << 6) | |
| 1192 | −# define SSI_CONFIG_DL (1 << 5) | |
| 1193 | −# define SSI_CONFIG_EP (1 << 4) | |
| 1194 | −#define SSI0_ADATA 0xB1600024 | |
| 1195 | −# define SSI_AD_D (1 << 24) | |
| 1196 | −# define SSI_AD_ADDR_BIT 16 | |
| 1197 | −# define SSI_AD_ADDR_MASK (0xff << 16) | |
| 1198 | −# define SSI_AD_DATA_BIT 0 | |
| 1199 | −# define SSI_AD_DATA_MASK (0xfff << 0) | |
| 1200 | −#define SSI0_CLKDIV 0xB1600028 | |
| 1201 | −#define SSI0_CONTROL 0xB1600100 | |
| 1202 | −# define SSI_CONTROL_CD (1 << 1) | |
| 1203 | −# define SSI_CONTROL_E (1 << 0) | |
| 1204 | − | |
| 1205 | −/* SSI1 */ | |
| 1206 | −#define SSI1_STATUS 0xB1680000 | |
| 1207 | −#define SSI1_INT 0xB1680004 | |
| 1208 | −#define SSI1_INT_ENABLE 0xB1680008 | |
| 1209 | −#define SSI1_CONFIG 0xB1680020 | |
| 1210 | −#define SSI1_ADATA 0xB1680024 | |
| 1211 | −#define SSI1_CLKDIV 0xB1680028 | |
| 1212 | −#define SSI1_ENABLE 0xB1680100 | |
| 679 | +static inline int alchemy_get_cputype(void) | |
| 680 | +{ | |
| 681 | + switch (read_c0_prid() & (PRID_OPT_MASK | PRID_COMP_MASK)) { | |
| 682 | + case 0x00030000: | |
| 683 | + return ALCHEMY_CPU_AU1000; | |
| 684 | + break; | |
| 685 | + case 0x01030000: | |
| 686 | + return ALCHEMY_CPU_AU1500; | |
| 687 | + break; | |
| 688 | + case 0x02030000: | |
| 689 | + return ALCHEMY_CPU_AU1100; | |
| 690 | + break; | |
| 691 | + case 0x03030000: | |
| 692 | + return ALCHEMY_CPU_AU1550; | |
| 693 | + break; | |
| 694 | + case 0x04030000: | |
| 695 | + case 0x05030000: | |
| 696 | + return ALCHEMY_CPU_AU1200; | |
| 697 | + break; | |
| 698 | + case 0x800c0000: | |
| 699 | + return ALCHEMY_CPU_AU1300; | |
| 700 | + break; | |
| 701 | + } | |
| 1213 | 702 | |
| 1214 | −/* | |
| 1215 | − * Register content definitions | |
| 1216 | − */ | |
| 1217 | −#define SSI_STATUS_BF (1 << 4) | |
| 1218 | −#define SSI_STATUS_OF (1 << 3) | |
| 1219 | −#define SSI_STATUS_UF (1 << 2) | |
| 1220 | −#define SSI_STATUS_D (1 << 1) | |
| 1221 | −#define SSI_STATUS_B (1 << 0) | |
| 1222 | − | |
| 1223 | −/* SSI_INT */ | |
| 1224 | −#define SSI_INT_OI (1 << 3) | |
| 1225 | −#define SSI_INT_UI (1 << 2) | |
| 1226 | −#define SSI_INT_DI (1 << 1) | |
| 1227 | − | |
| 1228 | −/* SSI_INTEN */ | |
| 1229 | −#define SSI_INTEN_OIE (1 << 3) | |
| 1230 | −#define SSI_INTEN_UIE (1 << 2) | |
| 1231 | −#define SSI_INTEN_DIE (1 << 1) | |
| 1232 | − | |
| 1233 | −#define SSI_CONFIG_AO (1 << 24) | |
| 1234 | −#define SSI_CONFIG_DO (1 << 23) | |
| 1235 | −#define SSI_CONFIG_ALEN (7 << 20) | |
| 1236 | −#define SSI_CONFIG_DLEN (15 << 16) | |
| 1237 | −#define SSI_CONFIG_DD (1 << 11) | |
| 1238 | −#define SSI_CONFIG_AD (1 << 10) | |
| 1239 | −#define SSI_CONFIG_BM (3 << 8) | |
| 1240 | −#define SSI_CONFIG_CE (1 << 7) | |
| 1241 | −#define SSI_CONFIG_DP (1 << 6) | |
| 1242 | −#define SSI_CONFIG_DL (1 << 5) | |
| 1243 | −#define SSI_CONFIG_EP (1 << 4) | |
| 1244 | −#define SSI_CONFIG_ALEN_N(N) ((N-1) << 20) | |
| 1245 | −#define SSI_CONFIG_DLEN_N(N) ((N-1) << 16) | |
| 1246 | −#define SSI_CONFIG_BM_HI (0 << 8) | |
| 1247 | −#define SSI_CONFIG_BM_LO (1 << 8) | |
| 1248 | −#define SSI_CONFIG_BM_CY (2 << 8) | |
| 1249 | − | |
| 1250 | −#define SSI_ADATA_D (1 << 24) | |
| 1251 | −#define SSI_ADATA_ADDR (0xFF << 16) | |
| 1252 | −#define SSI_ADATA_DATA 0x0FFF | |
| 1253 | −#define SSI_ADATA_ADDR_N(N) (N << 16) | |
| 1254 | − | |
| 1255 | −#define SSI_ENABLE_CD (1 << 1) | |
| 1256 | −#define SSI_ENABLE_E (1 << 0) | |
| 703 | + return ALCHEMY_CPU_UNKNOWN; | |
| 704 | +} | |
| 1257 | 705 | |
| 706 | +/* return number of uarts on a given cputype */ | |
| 707 | +static inline int alchemy_get_uarts(int type) | |
| 708 | +{ | |
| 709 | + switch (type) { | |
| 710 | + case ALCHEMY_CPU_AU1000: | |
| 711 | + case ALCHEMY_CPU_AU1300: | |
| 712 | + return 4; | |
| 713 | + case ALCHEMY_CPU_AU1500: | |
| 714 | + case ALCHEMY_CPU_AU1200: | |
| 715 | + return 2; | |
| 716 | + case ALCHEMY_CPU_AU1100: | |
| 717 | + case ALCHEMY_CPU_AU1550: | |
| 718 | + return 3; | |
| 719 | + } | |
| 720 | + return 0; | |
| 721 | +} | |
| 1258 | 722 | |
| 1259 | −/* | |
| 1260 | − * The IrDA peripheral has an IRFIRSEL pin, but on the DB/PB boards it's not | |
| 1261 | − * used to select FIR/SIR mode on the transceiver but as a GPIO. Instead a | |
| 1262 | − * CPLD has to be told about the mode. | |
| 1263 | − */ | |
| 1264 | −#define AU1000_IRDA_PHY_MODE_OFF 0 | |
| 1265 | −#define AU1000_IRDA_PHY_MODE_SIR 1 | |
| 1266 | −#define AU1000_IRDA_PHY_MODE_FIR 2 | |
| 723 | +/* enable an UART block if it isn't already */ | |
| 724 | +static inline void alchemy_uart_enable(u32 uart_phys) | |
| 725 | +{ | |
| 726 | + void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); | |
| 1267 | 727 | |
| 1268 | −struct au1k_irda_platform_data { | |
| 1269 | − void(*set_phy_mode)(int mode); | |
| 1270 | −}; | |
| 728 | + /* reset, enable clock, deassert reset */ | |
| 729 | + if ((__raw_readl(addr + 0x100) & 3) != 3) { | |
| 730 | + __raw_writel(0, addr + 0x100); | |
| 731 | + wmb(); /* drain writebuffer */ | |
| 732 | + __raw_writel(1, addr + 0x100); | |
| 733 | + wmb(); /* drain writebuffer */ | |
| 734 | + } | |
| 735 | + __raw_writel(3, addr + 0x100); | |
| 736 | + wmb(); /* drain writebuffer */ | |
| 737 | +} | |
| 1271 | 738 | |
| 739 | +static inline void alchemy_uart_disable(u32 uart_phys) | |
| 740 | +{ | |
| 741 | + void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); | |
| 1272 | 742 | |
| 1273 | −/* GPIO */ | |
| 1274 | −#define SYS_PINFUNC 0xB190002C | |
| 1275 | −# define SYS_PF_USB (1 << 15) /* 2nd USB device/host */ | |
| 1276 | −# define SYS_PF_U3 (1 << 14) /* GPIO23/U3TXD */ | |
| 1277 | −# define SYS_PF_U2 (1 << 13) /* GPIO22/U2TXD */ | |
| 1278 | −# define SYS_PF_U1 (1 << 12) /* GPIO21/U1TXD */ | |
| 1279 | −# define SYS_PF_SRC (1 << 11) /* GPIO6/SROMCKE */ | |
| 1280 | −# define SYS_PF_CK5 (1 << 10) /* GPIO3/CLK5 */ | |
| 1281 | −# define SYS_PF_CK4 (1 << 9) /* GPIO2/CLK4 */ | |
| 1282 | −# define SYS_PF_IRF (1 << 8) /* GPIO15/IRFIRSEL */ | |
| 1283 | −# define SYS_PF_UR3 (1 << 7) /* GPIO[14:9]/UART3 */ | |
| 1284 | −# define SYS_PF_I2D (1 << 6) /* GPIO8/I2SDI */ | |
| 1285 | −# define SYS_PF_I2S (1 << 5) /* I2S/GPIO[29:31] */ | |
| 1286 | −# define SYS_PF_NI2 (1 << 4) /* NI2/GPIO[24:28] */ | |
| 1287 | −# define SYS_PF_U0 (1 << 3) /* U0TXD/GPIO20 */ | |
| 1288 | −# define SYS_PF_RD (1 << 2) /* IRTXD/GPIO19 */ | |
| 1289 | −# define SYS_PF_A97 (1 << 1) /* AC97/SSL1 */ | |
| 1290 | −# define SYS_PF_S0 (1 << 0) /* SSI_0/GPIO[16:18] */ | |
| 743 | + __raw_writel(0, addr + 0x100); /* UART_MOD_CNTRL */ | |
| 744 | + wmb(); /* drain writebuffer */ | |
| 745 | +} | |
| 1291 | 746 | |
| 1292 | −/* Au1100 only */ | |
| 1293 | −# define SYS_PF_PC (1 << 18) /* PCMCIA/GPIO[207:204] */ | |
| 1294 | −# define SYS_PF_LCD (1 << 17) /* extern lcd/GPIO[203:200] */ | |
| 1295 | −# define SYS_PF_CS (1 << 16) /* EXTCLK0/32KHz to gpio2 */ | |
| 1296 | −# define SYS_PF_EX0 (1 << 9) /* GPIO2/clock */ | |
| 747 | +static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) | |
| 748 | +{ | |
| 749 | + void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys); | |
| 750 | + int timeout, i; | |
| 1297 | 751 | |
| 1298 | −/* Au1550 only. Redefines lots of pins */ | |
| 1299 | −# define SYS_PF_PSC2_MASK (7 << 17) | |
| 1300 | −# define SYS_PF_PSC2_AC97 0 | |
| 1301 | −# define SYS_PF_PSC2_SPI 0 | |
| 1302 | −# define SYS_PF_PSC2_I2S (1 << 17) | |
| 1303 | −# define SYS_PF_PSC2_SMBUS (3 << 17) | |
| 1304 | −# define SYS_PF_PSC2_GPIO (7 << 17) | |
| 1305 | −# define SYS_PF_PSC3_MASK (7 << 20) | |
| 1306 | −# define SYS_PF_PSC3_AC97 0 | |
| 1307 | −# define SYS_PF_PSC3_SPI 0 | |
| 1308 | −# define SYS_PF_PSC3_I2S (1 << 20) | |
| 1309 | −# define SYS_PF_PSC3_SMBUS (3 << 20) | |
| 1310 | −# define SYS_PF_PSC3_GPIO (7 << 20) | |
| 1311 | −# define SYS_PF_PSC1_S1 (1 << 1) | |
| 1312 | −# define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) | |
| 752 | + /* check LSR TX_EMPTY bit */ | |
| 753 | + timeout = 0xffffff; | |
| 754 | + do { | |
| 755 | + if (__raw_readl(base + 0x1c) & 0x20) | |
| 756 | + break; | |
| 757 | + /* slow down */ | |
| 758 | + for (i = 10000; i; i--) | |
| 759 | + asm volatile ("nop"); | |
| 760 | + } while (--timeout); | |
| 1313 | 761 | |
| 1314 | −/* Au1200 only */ | |
| 1315 | −#define SYS_PINFUNC_DMA (1 << 31) | |
| 1316 | −#define SYS_PINFUNC_S0A (1 << 30) | |
| 1317 | −#define SYS_PINFUNC_S1A (1 << 29) | |
| 1318 | −#define SYS_PINFUNC_LP0 (1 << 28) | |
| 1319 | −#define SYS_PINFUNC_LP1 (1 << 27) | |
| 1320 | −#define SYS_PINFUNC_LD16 (1 << 26) | |
| 1321 | −#define SYS_PINFUNC_LD8 (1 << 25) | |
| 1322 | −#define SYS_PINFUNC_LD1 (1 << 24) | |
| 1323 | −#define SYS_PINFUNC_LD0 (1 << 23) | |
| 1324 | −#define SYS_PINFUNC_P1A (3 << 21) | |
| 1325 | −#define SYS_PINFUNC_P1B (1 << 20) | |
| 1326 | −#define SYS_PINFUNC_FS3 (1 << 19) | |
| 1327 | −#define SYS_PINFUNC_P0A (3 << 17) | |
| 1328 | −#define SYS_PINFUNC_CS (1 << 16) | |
| 1329 | −#define SYS_PINFUNC_CIM (1 << 15) | |
| 1330 | −#define SYS_PINFUNC_P1C (1 << 14) | |
| 1331 | −#define SYS_PINFUNC_U1T (1 << 12) | |
| 1332 | −#define SYS_PINFUNC_U1R (1 << 11) | |
| 1333 | −#define SYS_PINFUNC_EX1 (1 << 10) | |
| 1334 | −#define SYS_PINFUNC_EX0 (1 << 9) | |
| 1335 | −#define SYS_PINFUNC_U0R (1 << 8) | |
| 1336 | −#define SYS_PINFUNC_MC (1 << 7) | |
| 1337 | −#define SYS_PINFUNC_S0B (1 << 6) | |
| 1338 | −#define SYS_PINFUNC_S0C (1 << 5) | |
| 1339 | −#define SYS_PINFUNC_P0B (1 << 4) | |
| 1340 | −#define SYS_PINFUNC_U0T (1 << 3) | |
| 1341 | −#define SYS_PINFUNC_S1B (1 << 2) | |
| 762 | + __raw_writel(c, base + 0x04); /* tx */ | |
| 763 | + wmb(); /* drain writebuffer */ | |
| 764 | +} | |
| 1342 | 765 | |
| 1343 | −/* Power Management */ | |
| 1344 | −#define SYS_SCRATCH0 0xB1900018 | |
| 1345 | −#define SYS_SCRATCH1 0xB190001C | |
| 1346 | −#define SYS_WAKEMSK 0xB1900034 | |
| 1347 | −#define SYS_ENDIAN 0xB1900038 | |
| 1348 | −#define SYS_POWERCTRL 0xB190003C | |
| 1349 | −#define SYS_WAKESRC 0xB190005C | |
| 1350 | −#define SYS_SLPPWR 0xB1900078 | |
| 1351 | −#define SYS_SLEEP 0xB190007C | |
| 766 | +/* return number of ethernet MACs on a given cputype */ | |
| 767 | +static inline int alchemy_get_macs(int type) | |
| 768 | +{ | |
| 769 | + switch (type) { | |
| 770 | + case ALCHEMY_CPU_AU1000: | |
| 771 | + case ALCHEMY_CPU_AU1500: | |
| 772 | + case ALCHEMY_CPU_AU1550: | |
| 773 | + return 2; | |
| 774 | + case ALCHEMY_CPU_AU1100: | |
| 775 | + return 1; | |
| 776 | + } | |
| 777 | + return 0; | |
| 778 | +} | |
| 1352 | 779 | |
| 1353 | −#define SYS_WAKEMSK_D2 (1 << 9) | |
| 1354 | −#define SYS_WAKEMSK_M2 (1 << 8) | |
| 1355 | −#define SYS_WAKEMSK_GPIO(x) (1 << (x)) | |
| 780 | +/* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */ | |
| 781 | +void alchemy_sleep_au1000(void); | |
| 782 | +void alchemy_sleep_au1550(void); | |
| 783 | +void alchemy_sleep_au1300(void); | |
| 784 | +void au_sleep(void); | |
| 1356 | 785 | |
| 1357 | −/* Clock Controller */ | |
| 1358 | −#define SYS_FREQCTRL0 0xB1900020 | |
| 1359 | −# define SYS_FC_FRDIV2_BIT 22 | |
| 1360 | −# define SYS_FC_FRDIV2_MASK (0xff << SYS_FC_FRDIV2_BIT) | |
| 1361 | −# define SYS_FC_FE2 (1 << 21) | |
| 1362 | −# define SYS_FC_FS2 (1 << 20) | |
| 1363 | −# define SYS_FC_FRDIV1_BIT 12 | |
| 1364 | −# define SYS_FC_FRDIV1_MASK (0xff << SYS_FC_FRDIV1_BIT) | |
| 1365 | −# define SYS_FC_FE1 (1 << 11) | |
| 1366 | −# define SYS_FC_FS1 (1 << 10) | |
| 1367 | −# define SYS_FC_FRDIV0_BIT 2 | |
| 1368 | −# define SYS_FC_FRDIV0_MASK (0xff << SYS_FC_FRDIV0_BIT) | |
| 1369 | −# define SYS_FC_FE0 (1 << 1) | |
| 1370 | −# define SYS_FC_FS0 (1 << 0) | |
| 1371 | −#define SYS_FREQCTRL1 0xB1900024 | |
| 1372 | −# define SYS_FC_FRDIV5_BIT 22 | |
| 1373 | −# define SYS_FC_FRDIV5_MASK (0xff << SYS_FC_FRDIV5_BIT) | |
| 1374 | −# define SYS_FC_FE5 (1 << 21) | |
| 1375 | −# define SYS_FC_FS5 (1 << 20) | |
| 1376 | −# define SYS_FC_FRDIV4_BIT 12 | |
| 1377 | −# define SYS_FC_FRDIV4_MASK (0xff << SYS_FC_FRDIV4_BIT) | |
| 1378 | −# define SYS_FC_FE4 (1 << 11) | |
| 1379 | −# define SYS_FC_FS4 (1 << 10) | |
| 1380 | −# define SYS_FC_FRDIV3_BIT 2 | |
| 1381 | −# define SYS_FC_FRDIV3_MASK (0xff << SYS_FC_FRDIV3_BIT) | |
| 1382 | −# define SYS_FC_FE3 (1 << 1) | |
| 1383 | −# define SYS_FC_FS3 (1 << 0) | |
| 1384 | −#define SYS_CLKSRC 0xB1900028 | |
| 1385 | −# define SYS_CS_ME1_BIT 27 | |
| 1386 | −# define SYS_CS_ME1_MASK (0x7 << SYS_CS_ME1_BIT) | |
| 1387 | −# define SYS_CS_DE1 (1 << 26) | |
| 1388 | −# define SYS_CS_CE1 (1 << 25) | |
| 1389 | −# define SYS_CS_ME0_BIT 22 | |
| 1390 | −# define SYS_CS_ME0_MASK (0x7 << SYS_CS_ME0_BIT) | |
| 1391 | −# define SYS_CS_DE0 (1 << 21) | |
| 1392 | −# define SYS_CS_CE0 (1 << 20) | |
| 1393 | −# define SYS_CS_MI2_BIT 17 | |
| 1394 | −# define SYS_CS_MI2_MASK (0x7 << SYS_CS_MI2_BIT) | |
| 1395 | −# define SYS_CS_DI2 (1 << 16) | |
| 1396 | −# define SYS_CS_CI2 (1 << 15) | |
| 1397 | − | |
| 1398 | −# define SYS_CS_ML_BIT 7 | |
| 1399 | −# define SYS_CS_ML_MASK (0x7 << SYS_CS_ML_BIT) | |
| 1400 | −# define SYS_CS_DL (1 << 6) | |
| 1401 | −# define SYS_CS_CL (1 << 5) | |
| 1402 | − | |
| 1403 | −# define SYS_CS_MUH_BIT 12 | |
| 1404 | −# define SYS_CS_MUH_MASK (0x7 << SYS_CS_MUH_BIT) | |
| 1405 | −# define SYS_CS_DUH (1 << 11) | |
| 1406 | −# define SYS_CS_CUH (1 << 10) | |
| 1407 | −# define SYS_CS_MUD_BIT 7 | |
| 1408 | −# define SYS_CS_MUD_MASK (0x7 << SYS_CS_MUD_BIT) | |
| 1409 | −# define SYS_CS_DUD (1 << 6) | |
| 1410 | −# define SYS_CS_CUD (1 << 5) | |
| 1411 | − | |
| 1412 | −# define SYS_CS_MIR_BIT 2 | |
| 1413 | −# define SYS_CS_MIR_MASK (0x7 << SYS_CS_MIR_BIT) | |
| 1414 | −# define SYS_CS_DIR (1 << 1) | |
| 1415 | −# define SYS_CS_CIR (1 << 0) | |
| 1416 | − | |
| 1417 | −# define SYS_CS_MUX_AUX 0x1 | |
| 1418 | −# define SYS_CS_MUX_FQ0 0x2 | |
| 1419 | −# define SYS_CS_MUX_FQ1 0x3 | |
| 1420 | −# define SYS_CS_MUX_FQ2 0x4 | |
| 1421 | −# define SYS_CS_MUX_FQ3 0x5 | |
| 1422 | −# define SYS_CS_MUX_FQ4 0x6 | |
| 1423 | −# define SYS_CS_MUX_FQ5 0x7 | |
| 1424 | −#define SYS_CPUPLL 0xB1900060 | |
| 1425 | −#define SYS_AUXPLL 0xB1900064 | |
| 1426 | − | |
| 1427 | −/* AC97 Controller */ | |
| 1428 | −#define AC97C_CONFIG 0xB0000000 | |
| 1429 | −# define AC97C_RECV_SLOTS_BIT 13 | |
| 1430 | −# define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT) | |
| 1431 | −# define AC97C_XMIT_SLOTS_BIT 3 | |
| 1432 | −# define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT) | |
| 1433 | −# define AC97C_SG (1 << 2) | |
| 1434 | −# define AC97C_SYNC (1 << 1) | |
| 1435 | −# define AC97C_RESET (1 << 0) | |
| 1436 | −#define AC97C_STATUS 0xB0000004 | |
| 1437 | −# define AC97C_XU (1 << 11) | |
| 1438 | −# define AC97C_XO (1 << 10) | |
| 1439 | −# define AC97C_RU (1 << 9) | |
| 1440 | −# define AC97C_RO (1 << 8) | |
| 1441 | −# define AC97C_READY (1 << 7) | |
| 1442 | −# define AC97C_CP (1 << 6) | |
| 1443 | −# define AC97C_TR (1 << 5) | |
| 1444 | −# define AC97C_TE (1 << 4) | |
| 1445 | −# define AC97C_TF (1 << 3) | |
| 1446 | −# define AC97C_RR (1 << 2) | |
| 1447 | −# define AC97C_RE (1 << 1) | |
| 1448 | −# define AC97C_RF (1 << 0) | |
| 1449 | −#define AC97C_DATA 0xB0000008 | |
| 1450 | −#define AC97C_CMD 0xB000000C | |
| 1451 | −# define AC97C_WD_BIT 16 | |
| 1452 | −# define AC97C_READ (1 << 7) | |
| 1453 | −# define AC97C_INDEX_MASK 0x7f | |
| 1454 | −#define AC97C_CNTRL 0xB0000010 | |
| 1455 | −# define AC97C_RS (1 << 1) | |
| 1456 | −# define AC97C_CE (1 << 0) | |
| 786 | +/* USB: arch/mips/alchemy/common/usb.c */ | |
| 787 | +enum alchemy_usb_block { | |
| 788 | + ALCHEMY_USB_OHCI0, | |
| 789 | + ALCHEMY_USB_UDC0, | |
| 790 | + ALCHEMY_USB_EHCI0, | |
| 791 | + ALCHEMY_USB_OTG0, | |
| 792 | + ALCHEMY_USB_OHCI1, | |
| 793 | +}; | |
| 794 | +int alchemy_usb_control(int block, int enable); | |
| 1457 | 795 | |
| 796 | +/* PCI controller platform data */ | |
| 797 | +struct alchemy_pci_platdata { | |
| 798 | + int (*board_map_irq)(const struct pci_dev *d, u8 slot, u8 pin); | |
| 799 | + int (*board_pci_idsel)(unsigned int devsel, int assert); | |
| 800 | + /* bits to set/clear in PCI_CONFIG register */ | |
| 801 | + unsigned long pci_cfg_set; | |
| 802 | + unsigned long pci_cfg_clr; | |
| 803 | +}; | |
| 1458 | 804 | |
| 1459 | −/* The PCI chip selects are outside the 32bit space, and since we can't | |
| 1460 | − * just program the 36bit addresses into BARs, we have to take a chunk | |
| 1461 | − * out of the 32bit space and reserve it for PCI. When these addresses | |
| 1462 | − * are ioremap()ed, they'll be fixed up to the real 36bit address before | |
| 1463 | − * being passed to the real ioremap function. | |
| 805 | +/* The IrDA peripheral has an IRFIRSEL pin, but on the DB/PB boards it's | |
| 806 | + * not used to select FIR/SIR mode on the transceiver but as a GPIO. | |
| 807 | + * Instead a CPLD has to be told about the mode. The driver calls the | |
| 808 | + * set_phy_mode() function in addition to driving the IRFIRSEL pin. | |
| 1464 | 809 | */ |
| 1465 | −#define ALCHEMY_PCI_MEMWIN_START (AU1500_PCI_MEM_PHYS_ADDR >> 4) | |
| 1466 | −#define ALCHEMY_PCI_MEMWIN_END (ALCHEMY_PCI_MEMWIN_START + 0x0FFFFFFF) | |
| 810 | +#define AU1000_IRDA_PHY_MODE_OFF 0 | |
| 811 | +#define AU1000_IRDA_PHY_MODE_SIR 1 | |
| 812 | +#define AU1000_IRDA_PHY_MODE_FIR 2 | |
| 1467 | 813 | |
| 1468 | −/* for PCI IO it's simpler because we get to do the ioremap ourselves and then | |
| 1469 | − * adjust the device's resources. | |
| 814 | +struct au1k_irda_platform_data { | |
| 815 | + void (*set_phy_mode)(int mode); | |
| 816 | +}; | |
| 817 | + | |
| 818 | + | |
| 819 | +/* Multifunction pins: Each of these pins can either be assigned to the | |
| 820 | + * GPIO controller or a on-chip peripheral. | |
| 821 | + * Call "au1300_pinfunc_to_dev()" or "au1300_pinfunc_to_gpio()" to | |
| 822 | + * assign one of these to either the GPIO controller or the device. | |
| 1470 | 823 | */ |
| 1471 | −#define ALCHEMY_PCI_IOWIN_START 0x00001000 | |
| 1472 | −#define ALCHEMY_PCI_IOWIN_END 0x0000FFFF | |
| 824 | +enum au1300_multifunc_pins { | |
| 825 | + /* wake-from-str pins 0-3 */ | |
| 826 | + AU1300_PIN_WAKE0 = 0, AU1300_PIN_WAKE1, AU1300_PIN_WAKE2, | |
| 827 | + AU1300_PIN_WAKE3, | |
| 828 | + /* external clock sources for PSCs: 4-5 */ | |
| 829 | + AU1300_PIN_EXTCLK0, AU1300_PIN_EXTCLK1, | |
| 830 | + /* 8bit MMC interface on SD0: 6-9 */ | |
| 831 | + AU1300_PIN_SD0DAT4, AU1300_PIN_SD0DAT5, AU1300_PIN_SD0DAT6, | |
| 832 | + AU1300_PIN_SD0DAT7, | |
| 833 | + /* aux clk input for freqgen 3: 10 */ | |
| 834 | + AU1300_PIN_FG3AUX, | |
| 835 | + /* UART1 pins: 11-18 */ | |
| 836 | + AU1300_PIN_U1RI, AU1300_PIN_U1DCD, AU1300_PIN_U1DSR, | |
| 837 | + AU1300_PIN_U1CTS, AU1300_PIN_U1RTS, AU1300_PIN_U1DTR, | |
| 838 | + AU1300_PIN_U1RX, AU1300_PIN_U1TX, | |
| 839 | + /* UART0 pins: 19-24 */ | |
| 840 | + AU1300_PIN_U0RI, AU1300_PIN_U0DCD, AU1300_PIN_U0DSR, | |
| 841 | + AU1300_PIN_U0CTS, AU1300_PIN_U0RTS, AU1300_PIN_U0DTR, | |
| 842 | + /* UART2: 25-26 */ | |
| 843 | + AU1300_PIN_U2RX, AU1300_PIN_U2TX, | |
| 844 | + /* UART3: 27-28 */ | |
| 845 | + AU1300_PIN_U3RX, AU1300_PIN_U3TX, | |
| 846 | + /* LCD controller PWMs, ext pixclock: 29-31 */ | |
| 847 | + AU1300_PIN_LCDPWM0, AU1300_PIN_LCDPWM1, AU1300_PIN_LCDCLKIN, | |
| 848 | + /* SD1 interface: 32-37 */ | |
| 849 | + AU1300_PIN_SD1DAT0, AU1300_PIN_SD1DAT1, AU1300_PIN_SD1DAT2, | |
| 850 | + AU1300_PIN_SD1DAT3, AU1300_PIN_SD1CMD, AU1300_PIN_SD1CLK, | |
| 851 | + /* SD2 interface: 38-43 */ | |
| 852 | + AU1300_PIN_SD2DAT0, AU1300_PIN_SD2DAT1, AU1300_PIN_SD2DAT2, | |
| 853 | + AU1300_PIN_SD2DAT3, AU1300_PIN_SD2CMD, AU1300_PIN_SD2CLK, | |
| 854 | + /* PSC0/1 clocks: 44-45 */ | |
| 855 | + AU1300_PIN_PSC0CLK, AU1300_PIN_PSC1CLK, | |
| 856 | + /* PSCs: 46-49/50-53/54-57/58-61 */ | |
| 857 | + AU1300_PIN_PSC0SYNC0, AU1300_PIN_PSC0SYNC1, AU1300_PIN_PSC0D0, | |
| 858 | + AU1300_PIN_PSC0D1, | |
| 859 | + AU1300_PIN_PSC1SYNC0, AU1300_PIN_PSC1SYNC1, AU1300_PIN_PSC1D0, | |
| 860 | + AU1300_PIN_PSC1D1, | |
| 861 | + AU1300_PIN_PSC2SYNC0, AU1300_PIN_PSC2SYNC1, AU1300_PIN_PSC2D0, | |
| 862 | + AU1300_PIN_PSC2D1, | |
| 863 | + AU1300_PIN_PSC3SYNC0, AU1300_PIN_PSC3SYNC1, AU1300_PIN_PSC3D0, | |
| 864 | + AU1300_PIN_PSC3D1, | |
| 865 | + /* PCMCIA interface: 62-70 */ | |
| 866 | + AU1300_PIN_PCE2, AU1300_PIN_PCE1, AU1300_PIN_PIOS16, | |
| 867 | + AU1300_PIN_PIOR, AU1300_PIN_PWE, AU1300_PIN_PWAIT, | |
| 868 | + AU1300_PIN_PREG, AU1300_PIN_POE, AU1300_PIN_PIOW, | |
| 869 | + /* camera interface H/V sync inputs: 71-72 */ | |
| 870 | + AU1300_PIN_CIMLS, AU1300_PIN_CIMFS, | |
| 871 | + /* PSC2/3 clocks: 73-74 */ | |
| 872 | + AU1300_PIN_PSC2CLK, AU1300_PIN_PSC3CLK, | |
| 873 | +}; | |
| 1473 | 874 | |
| 1474 | −#ifdef CONFIG_PCI | |
| 875 | +/* GPIC (Au1300) pin management: arch/mips/alchemy/common/gpioint.c */ | |
| 876 | +extern void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio); | |
| 877 | +extern void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio); | |
| 878 | +extern void au1300_set_irq_priority(unsigned int irq, int p); | |
| 879 | +extern void au1300_set_dbdma_gpio(int dchan, unsigned int gpio); | |
| 1475 | 880 | |
| 1476 | −#define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */ | |
| 1477 | −#define IOPORT_RESOURCE_END 0xffffffff | |
| 1478 | −#define IOMEM_RESOURCE_START 0x10000000 | |
| 1479 | −#define IOMEM_RESOURCE_END 0xfffffffffULL | |
| 881 | +/* Au1300 allows to disconnect certain blocks from internal power supply */ | |
| 882 | +enum au1300_vss_block { | |
| 883 | + AU1300_VSS_MPE = 0, | |
| 884 | + AU1300_VSS_BSA, | |
| 885 | + AU1300_VSS_GPE, | |
| 886 | + AU1300_VSS_MGP, | |
| 887 | +}; | |
| 1480 | 888 | |
| 1481 | −#else | |
| 889 | +extern void au1300_vss_block_control(int block, int enable); | |
| 1482 | 890 | |
| 1483 | −/* Don't allow any legacy ports probing */ | |
| 1484 | −#define IOPORT_RESOURCE_START 0x10000000 | |
| 1485 | −#define IOPORT_RESOURCE_END 0xffffffff | |
| 1486 | −#define IOMEM_RESOURCE_START 0x10000000 | |
| 1487 | −#define IOMEM_RESOURCE_END 0xfffffffffULL | |
| 891 | +enum soc_au1000_ints { | |
| 892 | + AU1000_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 893 | + AU1000_UART0_INT = AU1000_FIRST_INT, | |
| 894 | + AU1000_UART1_INT, | |
| 895 | + AU1000_UART2_INT, | |
| 896 | + AU1000_UART3_INT, | |
| 897 | + AU1000_SSI0_INT, | |
| 898 | + AU1000_SSI1_INT, | |
| 899 | + AU1000_DMA_INT_BASE, | |
| 1488 | 900 | |
| 1489 | −#endif | |
| 901 | + AU1000_TOY_INT = AU1000_FIRST_INT + 14, | |
| 902 | + AU1000_TOY_MATCH0_INT, | |
| 903 | + AU1000_TOY_MATCH1_INT, | |
| 904 | + AU1000_TOY_MATCH2_INT, | |
| 905 | + AU1000_RTC_INT, | |
| 906 | + AU1000_RTC_MATCH0_INT, | |
| 907 | + AU1000_RTC_MATCH1_INT, | |
| 908 | + AU1000_RTC_MATCH2_INT, | |
| 909 | + AU1000_IRDA_TX_INT, | |
| 910 | + AU1000_IRDA_RX_INT, | |
| 911 | + AU1000_USB_DEV_REQ_INT, | |
| 912 | + AU1000_USB_DEV_SUS_INT, | |
| 913 | + AU1000_USB_HOST_INT, | |
| 914 | + AU1000_ACSYNC_INT, | |
| 915 | + AU1000_MAC0_DMA_INT, | |
| 916 | + AU1000_MAC1_DMA_INT, | |
| 917 | + AU1000_I2S_UO_INT, | |
| 918 | + AU1000_AC97C_INT, | |
| 919 | + AU1000_GPIO0_INT, | |
| 920 | + AU1000_GPIO1_INT, | |
| 921 | + AU1000_GPIO2_INT, | |
| 922 | + AU1000_GPIO3_INT, | |
| 923 | + AU1000_GPIO4_INT, | |
| 924 | + AU1000_GPIO5_INT, | |
| 925 | + AU1000_GPIO6_INT, | |
| 926 | + AU1000_GPIO7_INT, | |
| 927 | + AU1000_GPIO8_INT, | |
| 928 | + AU1000_GPIO9_INT, | |
| 929 | + AU1000_GPIO10_INT, | |
| 930 | + AU1000_GPIO11_INT, | |
| 931 | + AU1000_GPIO12_INT, | |
| 932 | + AU1000_GPIO13_INT, | |
| 933 | + AU1000_GPIO14_INT, | |
| 934 | + AU1000_GPIO15_INT, | |
| 935 | + AU1000_GPIO16_INT, | |
| 936 | + AU1000_GPIO17_INT, | |
| 937 | + AU1000_GPIO18_INT, | |
| 938 | + AU1000_GPIO19_INT, | |
| 939 | + AU1000_GPIO20_INT, | |
| 940 | + AU1000_GPIO21_INT, | |
| 941 | + AU1000_GPIO22_INT, | |
| 942 | + AU1000_GPIO23_INT, | |
| 943 | + AU1000_GPIO24_INT, | |
| 944 | + AU1000_GPIO25_INT, | |
| 945 | + AU1000_GPIO26_INT, | |
| 946 | + AU1000_GPIO27_INT, | |
| 947 | + AU1000_GPIO28_INT, | |
| 948 | + AU1000_GPIO29_INT, | |
| 949 | + AU1000_GPIO30_INT, | |
| 950 | + AU1000_GPIO31_INT, | |
| 951 | +}; | |
| 1490 | 952 | |
| 1491 | −/* PCI controller block register offsets */ | |
| 1492 | −#define PCI_REG_CMEM 0x0000 | |
| 1493 | −#define PCI_REG_CONFIG 0x0004 | |
| 1494 | −#define PCI_REG_B2BMASK_CCH 0x0008 | |
| 1495 | −#define PCI_REG_B2BBASE0_VID 0x000C | |
| 1496 | −#define PCI_REG_B2BBASE1_SID 0x0010 | |
| 1497 | −#define PCI_REG_MWMASK_DEV 0x0014 | |
| 1498 | −#define PCI_REG_MWBASE_REV_CCL 0x0018 | |
| 1499 | −#define PCI_REG_ERR_ADDR 0x001C | |
| 1500 | −#define PCI_REG_SPEC_INTACK 0x0020 | |
| 1501 | −#define PCI_REG_ID 0x0100 | |
| 1502 | −#define PCI_REG_STATCMD 0x0104 | |
| 1503 | −#define PCI_REG_CLASSREV 0x0108 | |
| 1504 | −#define PCI_REG_PARAM 0x010C | |
| 1505 | −#define PCI_REG_MBAR 0x0110 | |
| 1506 | −#define PCI_REG_TIMEOUT 0x0140 | |
| 953 | +enum soc_au1100_ints { | |
| 954 | + AU1100_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 955 | + AU1100_UART0_INT = AU1100_FIRST_INT, | |
| 956 | + AU1100_UART1_INT, | |
| 957 | + AU1100_SD_INT, | |
| 958 | + AU1100_UART3_INT, | |
| 959 | + AU1100_SSI0_INT, | |
| 960 | + AU1100_SSI1_INT, | |
| 961 | + AU1100_DMA_INT_BASE, | |
| 1507 | 962 | |
| 1508 | −/* PCI controller block register bits */ | |
| 1509 | −#define PCI_CMEM_E (1 << 28) /* enable cacheable memory */ | |
| 1510 | −#define PCI_CMEM_CMBASE(x) (((x) & 0x3fff) << 14) | |
| 1511 | −#define PCI_CMEM_CMMASK(x) ((x) & 0x3fff) | |
| 1512 | −#define PCI_CONFIG_ERD (1 << 27) /* pci error during R/W */ | |
| 1513 | −#define PCI_CONFIG_ET (1 << 26) /* error in target mode */ | |
| 1514 | −#define PCI_CONFIG_EF (1 << 25) /* fatal error */ | |
| 1515 | −#define PCI_CONFIG_EP (1 << 24) /* parity error */ | |
| 1516 | −#define PCI_CONFIG_EM (1 << 23) /* multiple errors */ | |
| 1517 | −#define PCI_CONFIG_BM (1 << 22) /* bad master error */ | |
| 1518 | −#define PCI_CONFIG_PD (1 << 20) /* PCI Disable */ | |
| 1519 | −#define PCI_CONFIG_BME (1 << 19) /* Byte Mask Enable for reads */ | |
| 1520 | −#define PCI_CONFIG_NC (1 << 16) /* mark mem access non-coherent */ | |
| 1521 | −#define PCI_CONFIG_IA (1 << 15) /* INTA# enabled (target mode) */ | |
| 1522 | −#define PCI_CONFIG_IP (1 << 13) /* int on PCI_PERR# */ | |
| 1523 | −#define PCI_CONFIG_IS (1 << 12) /* int on PCI_SERR# */ | |
| 1524 | −#define PCI_CONFIG_IMM (1 << 11) /* int on master abort */ | |
| 1525 | −#define PCI_CONFIG_ITM (1 << 10) /* int on target abort (as master) */ | |
| 1526 | −#define PCI_CONFIG_ITT (1 << 9) /* int on target abort (as target) */ | |
| 1527 | −#define PCI_CONFIG_IPB (1 << 8) /* int on PERR# in bus master acc */ | |
| 1528 | −#define PCI_CONFIG_SIC_NO (0 << 6) /* no byte mask changes */ | |
| 1529 | −#define PCI_CONFIG_SIC_BA_ADR (1 << 6) /* on byte/hw acc, invert adr bits */ | |
| 1530 | −#define PCI_CONFIG_SIC_HWA_DAT (2 << 6) /* on halfword acc, swap data */ | |
| 1531 | −#define PCI_CONFIG_SIC_ALL (3 << 6) /* swap data bytes on all accesses */ | |
| 1532 | −#define PCI_CONFIG_ST (1 << 5) /* swap data by target transactions */ | |
| 1533 | −#define PCI_CONFIG_SM (1 << 4) /* swap data from PCI ctl */ | |
| 1534 | −#define PCI_CONFIG_AEN (1 << 3) /* enable internal arbiter */ | |
| 1535 | −#define PCI_CONFIG_R2H (1 << 2) /* REQ2# to hi-prio arbiter */ | |
| 1536 | −#define PCI_CONFIG_R1H (1 << 1) /* REQ1# to hi-prio arbiter */ | |
| 1537 | −#define PCI_CONFIG_CH (1 << 0) /* PCI ctl to hi-prio arbiter */ | |
| 1538 | −#define PCI_B2BMASK_B2BMASK(x) (((x) & 0xffff) << 16) | |
| 1539 | −#define PCI_B2BMASK_CCH(x) ((x) & 0xffff) /* 16 upper bits of class code */ | |
| 1540 | −#define PCI_B2BBASE0_VID_B0(x) (((x) & 0xffff) << 16) | |
| 1541 | −#define PCI_B2BBASE0_VID_SV(x) ((x) & 0xffff) | |
| 1542 | −#define PCI_B2BBASE1_SID_B1(x) (((x) & 0xffff) << 16) | |
| 1543 | −#define PCI_B2BBASE1_SID_SI(x) ((x) & 0xffff) | |
| 1544 | −#define PCI_MWMASKDEV_MWMASK(x) (((x) & 0xffff) << 16) | |
| 1545 | −#define PCI_MWMASKDEV_DEVID(x) ((x) & 0xffff) | |
| 1546 | −#define PCI_MWBASEREVCCL_BASE(x) (((x) & 0xffff) << 16) | |
| 1547 | −#define PCI_MWBASEREVCCL_REV(x) (((x) & 0xff) << 8) | |
| 1548 | −#define PCI_MWBASEREVCCL_CCL(x) ((x) & 0xff) | |
| 1549 | −#define PCI_ID_DID(x) (((x) & 0xffff) << 16) | |
| 1550 | −#define PCI_ID_VID(x) ((x) & 0xffff) | |
| 1551 | −#define PCI_STATCMD_STATUS(x) (((x) & 0xffff) << 16) | |
| 1552 | −#define PCI_STATCMD_CMD(x) ((x) & 0xffff) | |
| 1553 | −#define PCI_CLASSREV_CLASS(x) (((x) & 0x00ffffff) << 8) | |
| 1554 | −#define PCI_CLASSREV_REV(x) ((x) & 0xff) | |
| 1555 | −#define PCI_PARAM_BIST(x) (((x) & 0xff) << 24) | |
| 1556 | −#define PCI_PARAM_HT(x) (((x) & 0xff) << 16) | |
| 1557 | −#define PCI_PARAM_LT(x) (((x) & 0xff) << 8) | |
| 1558 | −#define PCI_PARAM_CLS(x) ((x) & 0xff) | |
| 1559 | −#define PCI_TIMEOUT_RETRIES(x) (((x) & 0xff) << 8) /* max retries */ | |
| 1560 | −#define PCI_TIMEOUT_TO(x) ((x) & 0xff) /* target ready timeout */ | |
| 963 | + AU1100_TOY_INT = AU1100_FIRST_INT + 14, | |
| 964 | + AU1100_TOY_MATCH0_INT, | |
| 965 | + AU1100_TOY_MATCH1_INT, | |
| 966 | + AU1100_TOY_MATCH2_INT, | |
| 967 | + AU1100_RTC_INT, | |
| 968 | + AU1100_RTC_MATCH0_INT, | |
| 969 | + AU1100_RTC_MATCH1_INT, | |
| 970 | + AU1100_RTC_MATCH2_INT, | |
| 971 | + AU1100_IRDA_TX_INT, | |
| 972 | + AU1100_IRDA_RX_INT, | |
| 973 | + AU1100_USB_DEV_REQ_INT, | |
| 974 | + AU1100_USB_DEV_SUS_INT, | |
| 975 | + AU1100_USB_HOST_INT, | |
| 976 | + AU1100_ACSYNC_INT, | |
| 977 | + AU1100_MAC0_DMA_INT, | |
| 978 | + AU1100_GPIO208_215_INT, | |
| 979 | + AU1100_LCD_INT, | |
| 980 | + AU1100_AC97C_INT, | |
| 981 | + AU1100_GPIO0_INT, | |
| 982 | + AU1100_GPIO1_INT, | |
| 983 | + AU1100_GPIO2_INT, | |
| 984 | + AU1100_GPIO3_INT, | |
| 985 | + AU1100_GPIO4_INT, | |
| 986 | + AU1100_GPIO5_INT, | |
| 987 | + AU1100_GPIO6_INT, | |
| 988 | + AU1100_GPIO7_INT, | |
| 989 | + AU1100_GPIO8_INT, | |
| 990 | + AU1100_GPIO9_INT, | |
| 991 | + AU1100_GPIO10_INT, | |
| 992 | + AU1100_GPIO11_INT, | |
| 993 | + AU1100_GPIO12_INT, | |
| 994 | + AU1100_GPIO13_INT, | |
| 995 | + AU1100_GPIO14_INT, | |
| 996 | + AU1100_GPIO15_INT, | |
| 997 | + AU1100_GPIO16_INT, | |
| 998 | + AU1100_GPIO17_INT, | |
| 999 | + AU1100_GPIO18_INT, | |
| 1000 | + AU1100_GPIO19_INT, | |
| 1001 | + AU1100_GPIO20_INT, | |
| 1002 | + AU1100_GPIO21_INT, | |
| 1003 | + AU1100_GPIO22_INT, | |
| 1004 | + AU1100_GPIO23_INT, | |
| 1005 | + AU1100_GPIO24_INT, | |
| 1006 | + AU1100_GPIO25_INT, | |
| 1007 | + AU1100_GPIO26_INT, | |
| 1008 | + AU1100_GPIO27_INT, | |
| 1009 | + AU1100_GPIO28_INT, | |
| 1010 | + AU1100_GPIO29_INT, | |
| 1011 | + AU1100_GPIO30_INT, | |
| 1012 | + AU1100_GPIO31_INT, | |
| 1013 | +}; | |
| 1014 | + | |
| 1015 | +enum soc_au1500_ints { | |
| 1016 | + AU1500_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 1017 | + AU1500_UART0_INT = AU1500_FIRST_INT, | |
| 1018 | + AU1500_PCI_INTA, | |
| 1019 | + AU1500_PCI_INTB, | |
| 1020 | + AU1500_UART3_INT, | |
| 1021 | + AU1500_PCI_INTC, | |
| 1022 | + AU1500_PCI_INTD, | |
| 1023 | + AU1500_DMA_INT_BASE, | |
| 1024 | + | |
| 1025 | + AU1500_TOY_INT = AU1500_FIRST_INT + 14, | |
| 1026 | + AU1500_TOY_MATCH0_INT, | |
| 1027 | + AU1500_TOY_MATCH1_INT, | |
| 1028 | + AU1500_TOY_MATCH2_INT, | |
| 1029 | + AU1500_RTC_INT, | |
| 1030 | + AU1500_RTC_MATCH0_INT, | |
| 1031 | + AU1500_RTC_MATCH1_INT, | |
| 1032 | + AU1500_RTC_MATCH2_INT, | |
| 1033 | + AU1500_PCI_ERR_INT, | |
| 1034 | + AU1500_RESERVED_INT, | |
| 1035 | + AU1500_USB_DEV_REQ_INT, | |
| 1036 | + AU1500_USB_DEV_SUS_INT, | |
| 1037 | + AU1500_USB_HOST_INT, | |
| 1038 | + AU1500_ACSYNC_INT, | |
| 1039 | + AU1500_MAC0_DMA_INT, | |
| 1040 | + AU1500_MAC1_DMA_INT, | |
| 1041 | + AU1500_AC97C_INT = AU1500_FIRST_INT + 31, | |
| 1042 | + AU1500_GPIO0_INT, | |
| 1043 | + AU1500_GPIO1_INT, | |
| 1044 | + AU1500_GPIO2_INT, | |
| 1045 | + AU1500_GPIO3_INT, | |
| 1046 | + AU1500_GPIO4_INT, | |
| 1047 | + AU1500_GPIO5_INT, | |
| 1048 | + AU1500_GPIO6_INT, | |
| 1049 | + AU1500_GPIO7_INT, | |
| 1050 | + AU1500_GPIO8_INT, | |
| 1051 | + AU1500_GPIO9_INT, | |
| 1052 | + AU1500_GPIO10_INT, | |
| 1053 | + AU1500_GPIO11_INT, | |
| 1054 | + AU1500_GPIO12_INT, | |
| 1055 | + AU1500_GPIO13_INT, | |
| 1056 | + AU1500_GPIO14_INT, | |
| 1057 | + AU1500_GPIO15_INT, | |
| 1058 | + AU1500_GPIO200_INT, | |
| 1059 | + AU1500_GPIO201_INT, | |
| 1060 | + AU1500_GPIO202_INT, | |
| 1061 | + AU1500_GPIO203_INT, | |
| 1062 | + AU1500_GPIO20_INT, | |
| 1063 | + AU1500_GPIO204_INT, | |
| 1064 | + AU1500_GPIO205_INT, | |
| 1065 | + AU1500_GPIO23_INT, | |
| 1066 | + AU1500_GPIO24_INT, | |
| 1067 | + AU1500_GPIO25_INT, | |
| 1068 | + AU1500_GPIO26_INT, | |
| 1069 | + AU1500_GPIO27_INT, | |
| 1070 | + AU1500_GPIO28_INT, | |
| 1071 | + AU1500_GPIO206_INT, | |
| 1072 | + AU1500_GPIO207_INT, | |
| 1073 | + AU1500_GPIO208_215_INT, | |
| 1074 | +}; | |
| 1075 | + | |
| 1076 | +enum soc_au1550_ints { | |
| 1077 | + AU1550_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 1078 | + AU1550_UART0_INT = AU1550_FIRST_INT, | |
| 1079 | + AU1550_PCI_INTA, | |
| 1080 | + AU1550_PCI_INTB, | |
| 1081 | + AU1550_DDMA_INT, | |
| 1082 | + AU1550_CRYPTO_INT, | |
| 1083 | + AU1550_PCI_INTC, | |
| 1084 | + AU1550_PCI_INTD, | |
| 1085 | + AU1550_PCI_RST_INT, | |
| 1086 | + AU1550_UART1_INT, | |
| 1087 | + AU1550_UART3_INT, | |
| 1088 | + AU1550_PSC0_INT, | |
| 1089 | + AU1550_PSC1_INT, | |
| 1090 | + AU1550_PSC2_INT, | |
| 1091 | + AU1550_PSC3_INT, | |
| 1092 | + AU1550_TOY_INT, | |
| 1093 | + AU1550_TOY_MATCH0_INT, | |
| 1094 | + AU1550_TOY_MATCH1_INT, | |
| 1095 | + AU1550_TOY_MATCH2_INT, | |
| 1096 | + AU1550_RTC_INT, | |
| 1097 | + AU1550_RTC_MATCH0_INT, | |
| 1098 | + AU1550_RTC_MATCH1_INT, | |
| 1099 | + AU1550_RTC_MATCH2_INT, | |
| 1100 | + | |
| 1101 | + AU1550_NAND_INT = AU1550_FIRST_INT + 23, | |
| 1102 | + AU1550_USB_DEV_REQ_INT, | |
| 1103 | + AU1550_USB_DEV_SUS_INT, | |
| 1104 | + AU1550_USB_HOST_INT, | |
| 1105 | + AU1550_MAC0_DMA_INT, | |
| 1106 | + AU1550_MAC1_DMA_INT, | |
| 1107 | + AU1550_GPIO0_INT = AU1550_FIRST_INT + 32, | |
| 1108 | + AU1550_GPIO1_INT, | |
| 1109 | + AU1550_GPIO2_INT, | |
| 1110 | + AU1550_GPIO3_INT, | |
| 1111 | + AU1550_GPIO4_INT, | |
| 1112 | + AU1550_GPIO5_INT, | |
| 1113 | + AU1550_GPIO6_INT, | |
| 1114 | + AU1550_GPIO7_INT, | |
| 1115 | + AU1550_GPIO8_INT, | |
| 1116 | + AU1550_GPIO9_INT, | |
| 1117 | + AU1550_GPIO10_INT, | |
| 1118 | + AU1550_GPIO11_INT, | |
| 1119 | + AU1550_GPIO12_INT, | |
| 1120 | + AU1550_GPIO13_INT, | |
| 1121 | + AU1550_GPIO14_INT, | |
| 1122 | + AU1550_GPIO15_INT, | |
| 1123 | + AU1550_GPIO200_INT, | |
| 1124 | + AU1550_GPIO201_205_INT, /* Logical or of GPIO201:205 */ | |
| 1125 | + AU1550_GPIO16_INT, | |
| 1126 | + AU1550_GPIO17_INT, | |
| 1127 | + AU1550_GPIO20_INT, | |
| 1128 | + AU1550_GPIO21_INT, | |
| 1129 | + AU1550_GPIO22_INT, | |
| 1130 | + AU1550_GPIO23_INT, | |
| 1131 | + AU1550_GPIO24_INT, | |
| 1132 | + AU1550_GPIO25_INT, | |
| 1133 | + AU1550_GPIO26_INT, | |
| 1134 | + AU1550_GPIO27_INT, | |
| 1135 | + AU1550_GPIO28_INT, | |
| 1136 | + AU1550_GPIO206_INT, | |
| 1137 | + AU1550_GPIO207_INT, | |
| 1138 | + AU1550_GPIO208_215_INT, /* Logical or of GPIO208:215 */ | |
| 1139 | +}; | |
| 1140 | + | |
| 1141 | +enum soc_au1200_ints { | |
| 1142 | + AU1200_FIRST_INT = AU1000_INTC0_INT_BASE, | |
| 1143 | + AU1200_UART0_INT = AU1200_FIRST_INT, | |
| 1144 | + AU1200_SWT_INT, | |
| 1145 | + AU1200_SD_INT, | |
| 1146 | + AU1200_DDMA_INT, | |
| 1147 | + AU1200_MAE_BE_INT, | |
| 1148 | + AU1200_GPIO200_INT, | |
| 1149 | + AU1200_GPIO201_INT, | |
| 1150 | + AU1200_GPIO202_INT, | |
| 1151 | + AU1200_UART1_INT, | |
| 1152 | + AU1200_MAE_FE_INT, | |
| 1153 | + AU1200_PSC0_INT, | |
| 1154 | + AU1200_PSC1_INT, | |
| 1155 | + AU1200_AES_INT, | |
| 1156 | + AU1200_CAMERA_INT, | |
| 1157 | + AU1200_TOY_INT, | |
| 1158 | + AU1200_TOY_MATCH0_INT, | |
| 1159 | + AU1200_TOY_MATCH1_INT, | |
| 1160 | + AU1200_TOY_MATCH2_INT, | |
| 1161 | + AU1200_RTC_INT, | |
| 1162 | + AU1200_RTC_MATCH0_INT, | |
| 1163 | + AU1200_RTC_MATCH1_INT, | |
| 1164 | + AU1200_RTC_MATCH2_INT, | |
| 1165 | + AU1200_GPIO203_INT, | |
| 1166 | + AU1200_NAND_INT, | |
| 1167 | + AU1200_GPIO204_INT, | |
| 1168 | + AU1200_GPIO205_INT, | |
| 1169 | + AU1200_GPIO206_INT, | |
| 1170 | + AU1200_GPIO207_INT, | |
| 1171 | + AU1200_GPIO208_215_INT, /* Logical OR of 208:215 */ | |
| 1172 | + AU1200_USB_INT, | |
| 1173 | + AU1200_LCD_INT, | |
| 1174 | + AU1200_MAE_BOTH_INT, | |
| 1175 | + AU1200_GPIO0_INT, | |
| 1176 | + AU1200_GPIO1_INT, | |
| 1177 | + AU1200_GPIO2_INT, | |
| 1178 | + AU1200_GPIO3_INT, | |
| 1179 | + AU1200_GPIO4_INT, | |
| 1180 | + AU1200_GPIO5_INT, | |
| 1181 | + AU1200_GPIO6_INT, | |
| 1182 | + AU1200_GPIO7_INT, | |
| 1183 | + AU1200_GPIO8_INT, | |
| 1184 | + AU1200_GPIO9_INT, | |
| 1185 | + AU1200_GPIO10_INT, | |
| 1186 | + AU1200_GPIO11_INT, | |
| 1187 | + AU1200_GPIO12_INT, | |
| 1188 | + AU1200_GPIO13_INT, | |
| 1189 | + AU1200_GPIO14_INT, | |
| 1190 | + AU1200_GPIO15_INT, | |
| 1191 | + AU1200_GPIO16_INT, | |
| 1192 | + AU1200_GPIO17_INT, | |
| 1193 | + AU1200_GPIO18_INT, | |
| 1194 | + AU1200_GPIO19_INT, | |
| 1195 | + AU1200_GPIO20_INT, | |
| 1196 | + AU1200_GPIO21_INT, | |
| 1197 | + AU1200_GPIO22_INT, | |
| 1198 | + AU1200_GPIO23_INT, | |
| 1199 | + AU1200_GPIO24_INT, | |
| 1200 | + AU1200_GPIO25_INT, | |
| 1201 | + AU1200_GPIO26_INT, | |
| 1202 | + AU1200_GPIO27_INT, | |
| 1203 | + AU1200_GPIO28_INT, | |
| 1204 | + AU1200_GPIO29_INT, | |
| 1205 | + AU1200_GPIO30_INT, | |
| 1206 | + AU1200_GPIO31_INT, | |
| 1207 | +}; | |
| 1208 | + | |
| 1209 | +#endif /* !defined (_LANGUAGE_ASSEMBLY) */ | |
| 1561 | 1210 | |
| 1562 | 1211 | #endif |
| @@ -106,7 +106,7 @@ enum { · 105 unmodified lines | ||
| 106 | 106 | struct dma_chan { |
| 107 | 107 | int dev_id; /* this channel is allocated if >= 0, */ |
| 108 | 108 | /* free otherwise */ |
| 109 | − unsigned int io; | |
| 109 | + void __iomem *io; | |
| 110 | 110 | const char *dev_str; |
| 111 | 111 | int irq; |
| 112 | 112 | void *irq_dev; |
| @@ -157,7 +157,7 @@ static inline void enable_dma_buffer0(unsigned int dmanr) · 44 unmodified lines | ||
| 157 | 157 | |
| 158 | 158 | if (!chan) |
| 159 | 159 | return; |
| 160 | − au_writel(DMA_BE0, chan->io + DMA_MODE_SET); | |
| 160 | + __raw_writel(DMA_BE0, chan->io + DMA_MODE_SET); | |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | static inline void enable_dma_buffer1(unsigned int dmanr) |
| @@ -166,7 +166,7 @@ static inline void enable_dma_buffer1(unsigned int dmanr) · 2 unmodified lines | ||
| 166 | 166 | |
| 167 | 167 | if (!chan) |
| 168 | 168 | return; |
| 169 | − au_writel(DMA_BE1, chan->io + DMA_MODE_SET); | |
| 169 | + __raw_writel(DMA_BE1, chan->io + DMA_MODE_SET); | |
| 170 | 170 | } |
| 171 | 171 | static inline void enable_dma_buffers(unsigned int dmanr) |
| 172 | 172 | { |
| @@ -174,7 +174,7 @@ static inline void enable_dma_buffers(unsigned int dmanr) · 1 unmodified line | ||
| 174 | 174 | |
| 175 | 175 | if (!chan) |
| 176 | 176 | return; |
| 177 | − au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); | |
| 177 | + __raw_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); | |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | static inline void start_dma(unsigned int dmanr) |
| @@ -183,7 +183,7 @@ static inline void start_dma(unsigned int dmanr) · 2 unmodified lines | ||
| 183 | 183 | |
| 184 | 184 | if (!chan) |
| 185 | 185 | return; |
| 186 | − au_writel(DMA_GO, chan->io + DMA_MODE_SET); | |
| 186 | + __raw_writel(DMA_GO, chan->io + DMA_MODE_SET); | |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | 189 | #define DMA_HALT_POLL 0x5000 |
| @@ -195,11 +195,11 @@ static inline void halt_dma(unsigned int dmanr) · 5 unmodified lines | ||
| 195 | 195 | |
| 196 | 196 | if (!chan) |
| 197 | 197 | return; |
| 198 | − au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); | |
| 198 | + __raw_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); | |
| 199 | 199 | |
| 200 | 200 | /* Poll the halt bit */ |
| 201 | 201 | for (i = 0; i < DMA_HALT_POLL; i++) |
| 202 | − if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) | |
| 202 | + if (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) | |
| 203 | 203 | break; |
| 204 | 204 | if (i == DMA_HALT_POLL) |
| 205 | 205 | printk(KERN_INFO "halt_dma: HALT poll expired!\n"); |
| @@ -215,7 +215,7 @@ static inline void disable_dma(unsigned int dmanr) · 9 unmodified lines | ||
| 215 | 215 | halt_dma(dmanr); |
| 216 | 216 | |
| 217 | 217 | /* Now we can disable the buffers */ |
| 218 | − au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); | |
| 218 | + __raw_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); | |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | 221 | static inline int dma_halted(unsigned int dmanr) |
| @@ -224,7 +224,7 @@ static inline int dma_halted(unsigned int dmanr) · 2 unmodified lines | ||
| 224 | 224 | |
| 225 | 225 | if (!chan) |
| 226 | 226 | return 1; |
| 227 | − return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; | |
| 227 | + return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; | |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | /* Initialize a DMA channel. */ |
| @@ -239,14 +239,14 @@ static inline void init_dma(unsigned int dmanr) · 8 unmodified lines | ||
| 239 | 239 | disable_dma(dmanr); |
| 240 | 240 | |
| 241 | 241 | /* Set device FIFO address */ |
| 242 | − au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR); | |
| 242 | + __raw_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR); | |
| 243 | 243 | |
| 244 | 244 | mode = chan->mode | (chan->dev_id << DMA_DID_BIT); |
| 245 | 245 | if (chan->irq) |
| 246 | 246 | mode |= DMA_IE; |
| 247 | 247 | |
| 248 | − au_writel(~mode, chan->io + DMA_MODE_CLEAR); | |
| 249 | − au_writel(mode, chan->io + DMA_MODE_SET); | |
| 248 | + __raw_writel(~mode, chan->io + DMA_MODE_CLEAR); | |
| 249 | + __raw_writel(mode, chan->io + DMA_MODE_SET); | |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | /* |
| @@ -283,7 +283,7 @@ static inline int get_dma_active_buffer(unsigned int dmanr) · 30 unmodified lines | ||
| 283 | 283 | |
| 284 | 284 | if (!chan) |
| 285 | 285 | return -1; |
| 286 | − return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; | |
| 286 | + return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; | |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | 289 | /* |
| @@ -304,7 +304,7 @@ static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a) · 14 unmodified lines | ||
| 304 | 304 | if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05) |
| 305 | 305 | return; |
| 306 | 306 | |
| 307 | − au_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); | |
| 307 | + __raw_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); | |
| 308 | 308 | } |
| 309 | 309 | |
| 310 | 310 | /* |
| @@ -316,7 +316,7 @@ static inline void clear_dma_done0(unsigned int dmanr) · 5 unmodified lines | ||
| 316 | 316 | |
| 317 | 317 | if (!chan) |
| 318 | 318 | return; |
| 319 | − au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); | |
| 319 | + __raw_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); | |
| 320 | 320 | } |
| 321 | 321 | |
| 322 | 322 | static inline void clear_dma_done1(unsigned int dmanr) |
| @@ -325,7 +325,7 @@ static inline void clear_dma_done1(unsigned int dmanr) · 2 unmodified lines | ||
| 325 | 325 | |
| 326 | 326 | if (!chan) |
| 327 | 327 | return; |
| 328 | − au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); | |
| 328 | + __raw_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); | |
| 329 | 329 | } |
| 330 | 330 | |
| 331 | 331 | /* |
| @@ -344,7 +344,7 @@ static inline void set_dma_addr0(unsigned int dmanr, unsigned int a) · 12 unmodified lines | ||
| 344 | 344 | |
| 345 | 345 | if (!chan) |
| 346 | 346 | return; |
| 347 | − au_writel(a, chan->io + DMA_BUFFER0_START); | |
| 347 | + __raw_writel(a, chan->io + DMA_BUFFER0_START); | |
| 348 | 348 | } |
| 349 | 349 | |
| 350 | 350 | /* |
| @@ -356,7 +356,7 @@ static inline void set_dma_addr1(unsigned int dmanr, unsigned int a) · 5 unmodified lines | ||
| 356 | 356 | |
| 357 | 357 | if (!chan) |
| 358 | 358 | return; |
| 359 | − au_writel(a, chan->io + DMA_BUFFER1_START); | |
| 359 | + __raw_writel(a, chan->io + DMA_BUFFER1_START); | |
| 360 | 360 | } |
| 361 | 361 | |
| 362 | 362 | |
| @@ -370,7 +370,7 @@ static inline void set_dma_count0(unsigned int dmanr, unsigned int count) · 7 unmodified lines | ||
| 370 | 370 | if (!chan) |
| 371 | 371 | return; |
| 372 | 372 | count &= DMA_COUNT_MASK; |
| 373 | − au_writel(count, chan->io + DMA_BUFFER0_COUNT); | |
| 373 | + __raw_writel(count, chan->io + DMA_BUFFER0_COUNT); | |
| 374 | 374 | } |
| 375 | 375 | |
| 376 | 376 | /* |
| @@ -383,7 +383,7 @@ static inline void set_dma_count1(unsigned int dmanr, unsigned int count) · 6 unmodified lines | ||
| 383 | 383 | if (!chan) |
| 384 | 384 | return; |
| 385 | 385 | count &= DMA_COUNT_MASK; |
| 386 | − au_writel(count, chan->io + DMA_BUFFER1_COUNT); | |
| 386 | + __raw_writel(count, chan->io + DMA_BUFFER1_COUNT); | |
| 387 | 387 | } |
| 388 | 388 | |
| 389 | 389 | /* |
| @@ -396,8 +396,8 @@ static inline void set_dma_count(unsigned int dmanr, unsigned int count) · 6 unmodified lines | ||
| 396 | 396 | if (!chan) |
| 397 | 397 | return; |
| 398 | 398 | count &= DMA_COUNT_MASK; |
| 399 | − au_writel(count, chan->io + DMA_BUFFER0_COUNT); | |
| 400 | − au_writel(count, chan->io + DMA_BUFFER1_COUNT); | |
| 399 | + __raw_writel(count, chan->io + DMA_BUFFER0_COUNT); | |
| 400 | + __raw_writel(count, chan->io + DMA_BUFFER1_COUNT); | |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | /* |
| @@ -410,7 +410,7 @@ static inline unsigned int get_dma_buffer_done(unsigned int dmanr) · 6 unmodified lines | ||
| 410 | 410 | |
| 411 | 411 | if (!chan) |
| 412 | 412 | return 0; |
| 413 | − return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); | |
| 413 | + return __raw_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); | |
| 414 | 414 | } |
| 415 | 415 | |
| 416 | 416 | |
| @@ -437,10 +437,10 @@ static inline int get_dma_residue(unsigned int dmanr) · 20 unmodified lines | ||
| 437 | 437 | if (!chan) |
| 438 | 438 | return 0; |
| 439 | 439 | |
| 440 | − curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? | |
| 440 | + curBufCntReg = (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? | |
| 441 | 441 | DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT; |
| 442 | 442 | |
| 443 | − count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; | |
| 443 | + count = __raw_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; | |
| 444 | 444 | |
| 445 | 445 | if ((chan->mode & DMA_DW_MASK) == DMA_DW16) |
| 446 | 446 | count <<= 1; |
| @@ -25,20 +25,20 @@ · 24 unmodified lines | ||
| 25 | 25 | #define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off)) |
| 26 | 26 | |
| 27 | 27 | /* GPIO1 registers within SYS_ area */ |
| 28 | −#define SYS_TRIOUTRD 0x100 | |
| 29 | −#define SYS_TRIOUTCLR 0x100 | |
| 30 | −#define SYS_OUTPUTRD 0x108 | |
| 31 | −#define SYS_OUTPUTSET 0x108 | |
| 32 | −#define SYS_OUTPUTCLR 0x10C | |
| 33 | −#define SYS_PINSTATERD 0x110 | |
| 34 | −#define SYS_PININPUTEN 0x110 | |
| 28 | +#define AU1000_SYS_TRIOUTRD 0x100 | |
| 29 | +#define AU1000_SYS_TRIOUTCLR 0x100 | |
| 30 | +#define AU1000_SYS_OUTPUTRD 0x108 | |
| 31 | +#define AU1000_SYS_OUTPUTSET 0x108 | |
| 32 | +#define AU1000_SYS_OUTPUTCLR 0x10C | |
| 33 | +#define AU1000_SYS_PINSTATERD 0x110 | |
| 34 | +#define AU1000_SYS_PININPUTEN 0x110 | |
| 35 | 35 | |
| 36 | 36 | /* register offsets within GPIO2 block */ |
| 37 | −#define GPIO2_DIR 0x00 | |
| 38 | −#define GPIO2_OUTPUT 0x08 | |
| 39 | −#define GPIO2_PINSTATE 0x0C | |
| 40 | −#define GPIO2_INTENABLE 0x10 | |
| 41 | −#define GPIO2_ENABLE 0x14 | |
| 37 | +#define AU1000_GPIO2_DIR 0x00 | |
| 38 | +#define AU1000_GPIO2_OUTPUT 0x08 | |
| 39 | +#define AU1000_GPIO2_PINSTATE 0x0C | |
| 40 | +#define AU1000_GPIO2_INTENABLE 0x10 | |
| 41 | +#define AU1000_GPIO2_ENABLE 0x14 | |
| 42 | 42 | |
| 43 | 43 | struct gpio; |
| 44 | 44 | |
| @@ -217,26 +217,21 @@ static inline int au1200_irq_to_gpio(int irq) · 172 unmodified lines | ||
| 217 | 217 | */ |
| 218 | 218 | static inline void alchemy_gpio1_set_value(int gpio, int v) |
| 219 | 219 | { |
| 220 | − void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | |
| 221 | 220 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
| 222 | − unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR; | |
| 223 | − __raw_writel(mask, base + r); | |
| 224 | − wmb(); | |
| 221 | + unsigned long r = v ? AU1000_SYS_OUTPUTSET : AU1000_SYS_OUTPUTCLR; | |
| 222 | + alchemy_wrsys(mask, r); | |
| 225 | 223 | } |
| 226 | 224 | |
| 227 | 225 | static inline int alchemy_gpio1_get_value(int gpio) |
| 228 | 226 | { |
| 229 | − void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | |
| 230 | 227 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
| 231 | − return __raw_readl(base + SYS_PINSTATERD) & mask; | |
| 228 | + return alchemy_rdsys(AU1000_SYS_PINSTATERD) & mask; | |
| 232 | 229 | } |
| 233 | 230 | |
| 234 | 231 | static inline int alchemy_gpio1_direction_input(int gpio) |
| 235 | 232 | { |
| 236 | − void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | |
| 237 | 233 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
| 238 | − __raw_writel(mask, base + SYS_TRIOUTCLR); | |
| 239 | − wmb(); | |
| 234 | + alchemy_wrsys(mask, AU1000_SYS_TRIOUTCLR); | |
| 240 | 235 | return 0; |
| 241 | 236 | } |
| 242 | 237 | |
| @@ -279,13 +274,13 @@ static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out) · 36 unmodified lines | ||
| 279 | 274 | { |
| 280 | 275 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
| 281 | 276 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE); |
| 282 | − unsigned long d = __raw_readl(base + GPIO2_DIR); | |
| 277 | + unsigned long d = __raw_readl(base + AU1000_GPIO2_DIR); | |
| 283 | 278 | |
| 284 | 279 | if (to_out) |
| 285 | 280 | d |= mask; |
| 286 | 281 | else |
| 287 | 282 | d &= ~mask; |
| 288 | − __raw_writel(d, base + GPIO2_DIR); | |
| 283 | + __raw_writel(d, base + AU1000_GPIO2_DIR); | |
| 289 | 284 | wmb(); |
| 290 | 285 | } |
| 291 | 286 | |
| @@ -294,14 +289,15 @@ static inline void alchemy_gpio2_set_value(int gpio, int v) · 2 unmodified lines | ||
| 294 | 289 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
| 295 | 290 | unsigned long mask; |
| 296 | 291 | mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE); |
| 297 | − __raw_writel(mask, base + GPIO2_OUTPUT); | |
| 292 | + __raw_writel(mask, base + AU1000_GPIO2_OUTPUT); | |
| 298 | 293 | wmb(); |
| 299 | 294 | } |
| 300 | 295 | |
| 301 | 296 | static inline int alchemy_gpio2_get_value(int gpio) |
| 302 | 297 | { |
| 303 | 298 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
| 304 | − return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE)); | |
| 299 | + return __raw_readl(base + AU1000_GPIO2_PINSTATE) & | |
| 300 | + (1 << (gpio - ALCHEMY_GPIO2_BASE)); | |
| 305 | 301 | } |
| 306 | 302 | |
| 307 | 303 | static inline int alchemy_gpio2_direction_input(int gpio) |
| @@ -352,12 +348,12 @@ static inline int alchemy_gpio2_to_irq(int gpio) · 44 unmodified lines | ||
| 352 | 348 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) |
| 353 | 349 | { |
| 354 | 350 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
| 355 | − unsigned long r = __raw_readl(base + GPIO2_INTENABLE); | |
| 351 | + unsigned long r = __raw_readl(base + AU1000_GPIO2_INTENABLE); | |
| 356 | 352 | if (en) |
| 357 | 353 | r |= 1 << gpio2; |
| 358 | 354 | else |
| 359 | 355 | r &= ~(1 << gpio2); |
| 360 | − __raw_writel(r, base + GPIO2_INTENABLE); | |
| 356 | + __raw_writel(r, base + AU1000_GPIO2_INTENABLE); | |
| 361 | 357 | wmb(); |
| 362 | 358 | } |
| 363 | 359 | |
| @@ -434,9 +430,9 @@ static inline void alchemy_gpio2_disable_int(int gpio2) · 70 unmodified lines | ||
| 434 | 430 | static inline void alchemy_gpio2_enable(void) |
| 435 | 431 | { |
| 436 | 432 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
| 437 | − __raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */ | |
| 433 | + __raw_writel(3, base + AU1000_GPIO2_ENABLE); /* reset, clock enabled */ | |
| 438 | 434 | wmb(); |
| 439 | − __raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */ | |
| 435 | + __raw_writel(1, base + AU1000_GPIO2_ENABLE); /* clock enabled */ | |
| 440 | 436 | wmb(); |
| 441 | 437 | } |
| 442 | 438 | |
| @@ -448,7 +444,7 @@ static inline void alchemy_gpio2_enable(void) · 5 unmodified lines | ||
| 448 | 444 | static inline void alchemy_gpio2_disable(void) |
| 449 | 445 | { |
| 450 | 446 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
| 451 | − __raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */ | |
| 447 | + __raw_writel(2, base + AU1000_GPIO2_ENABLE); /* reset, clock disabled */ | |
| 452 | 448 | wmb(); |
| 453 | 449 | } |
| 454 | 450 | |
| @@ -18,6 +18,7 @@ enum bcm47xx_board { · 17 unmodified lines | ||
| 18 | 18 | BCM47XX_BOARD_ASUS_WL300G, |
| 19 | 19 | BCM47XX_BOARD_ASUS_WL320GE, |
| 20 | 20 | BCM47XX_BOARD_ASUS_WL330GE, |
| 21 | + BCM47XX_BOARD_ASUS_WL500G, | |
| 21 | 22 | BCM47XX_BOARD_ASUS_WL500GD, |
| 22 | 23 | BCM47XX_BOARD_ASUS_WL500GPV1, |
| 23 | 24 | BCM47XX_BOARD_ASUS_WL500GPV2, |
| @@ -70,11 +71,15 @@ enum bcm47xx_board { · 46 unmodified lines | ||
| 70 | 71 | BCM47XX_BOARD_LINKSYS_WRT310NV1, |
| 71 | 72 | BCM47XX_BOARD_LINKSYS_WRT310NV2, |
| 72 | 73 | BCM47XX_BOARD_LINKSYS_WRT54G3GV2, |
| 73 | − BCM47XX_BOARD_LINKSYS_WRT54G, | |
| 74 | + BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, | |
| 75 | + BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, | |
| 76 | + BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, | |
| 74 | 77 | BCM47XX_BOARD_LINKSYS_WRT610NV1, |
| 75 | 78 | BCM47XX_BOARD_LINKSYS_WRT610NV2, |
| 76 | 79 | BCM47XX_BOARD_LINKSYS_WRTSL54GS, |
| 77 | 80 | |
| 81 | + BCM47XX_BOARD_MICROSOFT_MN700, | |
| 82 | + | |
| 78 | 83 | BCM47XX_BOARD_MOTOROLA_WE800G, |
| 79 | 84 | BCM47XX_BOARD_MOTOROLA_WR850GP, |
| 80 | 85 | BCM47XX_BOARD_MOTOROLA_WR850GV2V3, |
| @@ -19,118 +19,68 @@ · 18 unmodified lines | ||
| 19 | 19 | #define BCM6368_CPU_ID 0x6368 |
| 20 | 20 | |
| 21 | 21 | void __init bcm63xx_cpu_init(void); |
| 22 | −u16 __bcm63xx_get_cpu_id(void); | |
| 23 | 22 | u8 bcm63xx_get_cpu_rev(void); |
| 24 | 23 | unsigned int bcm63xx_get_cpu_freq(void); |
| 25 | 24 | |
| 25 | +static inline u16 __pure __bcm63xx_get_cpu_id(const u16 cpu_id) | |
| 26 | +{ | |
| 27 | + switch (cpu_id) { | |
| 26 | 28 | #ifdef CONFIG_BCM63XX_CPU_3368 |
| 27 | −# ifdef bcm63xx_get_cpu_id | |
| 28 | −# undef bcm63xx_get_cpu_id | |
| 29 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 30 | −# define BCMCPU_RUNTIME_DETECT | |
| 31 | −# else | |
| 32 | −# define bcm63xx_get_cpu_id() BCM3368_CPU_ID | |
| 33 | −# endif | |
| 34 | −# define BCMCPU_IS_3368() (bcm63xx_get_cpu_id() == BCM3368_CPU_ID) | |
| 35 | −#else | |
| 36 | −# define BCMCPU_IS_3368() (0) | |
| 29 | + case BCM3368_CPU_ID: | |
| 37 | 30 | #endif |
| 38 | 31 | |
| 39 | 32 | #ifdef CONFIG_BCM63XX_CPU_6328 |
| 40 | −# ifdef bcm63xx_get_cpu_id | |
| 41 | −# undef bcm63xx_get_cpu_id | |
| 42 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 43 | −# define BCMCPU_RUNTIME_DETECT | |
| 44 | −# else | |
| 45 | −# define bcm63xx_get_cpu_id() BCM6328_CPU_ID | |
| 46 | −# endif | |
| 47 | −# define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID) | |
| 48 | −#else | |
| 49 | −# define BCMCPU_IS_6328() (0) | |
| 33 | + case BCM6328_CPU_ID: | |
| 50 | 34 | #endif |
| 51 | 35 | |
| 52 | 36 | #ifdef CONFIG_BCM63XX_CPU_6338 |
| 53 | −# ifdef bcm63xx_get_cpu_id | |
| 54 | −# undef bcm63xx_get_cpu_id | |
| 55 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 56 | −# define BCMCPU_RUNTIME_DETECT | |
| 57 | −# else | |
| 58 | −# define bcm63xx_get_cpu_id() BCM6338_CPU_ID | |
| 59 | −# endif | |
| 60 | −# define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID) | |
| 61 | −#else | |
| 62 | −# define BCMCPU_IS_6338() (0) | |
| 37 | + case BCM6338_CPU_ID: | |
| 63 | 38 | #endif |
| 64 | 39 | |
| 65 | 40 | #ifdef CONFIG_BCM63XX_CPU_6345 |
| 66 | −# ifdef bcm63xx_get_cpu_id | |
| 67 | −# undef bcm63xx_get_cpu_id | |
| 68 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 69 | −# define BCMCPU_RUNTIME_DETECT | |
| 70 | −# else | |
| 71 | −# define bcm63xx_get_cpu_id() BCM6345_CPU_ID | |
| 72 | −# endif | |
| 73 | −# define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID) | |
| 74 | −#else | |
| 75 | −# define BCMCPU_IS_6345() (0) | |
| 41 | + case BCM6345_CPU_ID: | |
| 76 | 42 | #endif |
| 77 | 43 | |
| 78 | 44 | #ifdef CONFIG_BCM63XX_CPU_6348 |
| 79 | −# ifdef bcm63xx_get_cpu_id | |
| 80 | −# undef bcm63xx_get_cpu_id | |
| 81 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 82 | −# define BCMCPU_RUNTIME_DETECT | |
| 83 | −# else | |
| 84 | −# define bcm63xx_get_cpu_id() BCM6348_CPU_ID | |
| 85 | −# endif | |
| 86 | −# define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID) | |
| 87 | −#else | |
| 88 | −# define BCMCPU_IS_6348() (0) | |
| 45 | + case BCM6348_CPU_ID: | |
| 89 | 46 | #endif |
| 90 | 47 | |
| 91 | 48 | #ifdef CONFIG_BCM63XX_CPU_6358 |
| 92 | −# ifdef bcm63xx_get_cpu_id | |
| 93 | −# undef bcm63xx_get_cpu_id | |
| 94 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 95 | −# define BCMCPU_RUNTIME_DETECT | |
| 96 | −# else | |
| 97 | −# define bcm63xx_get_cpu_id() BCM6358_CPU_ID | |
| 98 | −# endif | |
| 99 | −# define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID) | |
| 100 | −#else | |
| 101 | −# define BCMCPU_IS_6358() (0) | |
| 49 | + case BCM6358_CPU_ID: | |
| 102 | 50 | #endif |
| 103 | 51 | |
| 104 | 52 | #ifdef CONFIG_BCM63XX_CPU_6362 |
| 105 | −# ifdef bcm63xx_get_cpu_id | |
| 106 | −# undef bcm63xx_get_cpu_id | |
| 107 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 108 | −# define BCMCPU_RUNTIME_DETECT | |
| 109 | −# else | |
| 110 | −# define bcm63xx_get_cpu_id() BCM6362_CPU_ID | |
| 111 | −# endif | |
| 112 | −# define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID) | |
| 113 | −#else | |
| 114 | −# define BCMCPU_IS_6362() (0) | |
| 53 | + case BCM6362_CPU_ID: | |
| 115 | 54 | #endif |
| 116 | 55 | |
| 117 | − | |
| 118 | 56 | #ifdef CONFIG_BCM63XX_CPU_6368 |
| 119 | −# ifdef bcm63xx_get_cpu_id | |
| 120 | −# undef bcm63xx_get_cpu_id | |
| 121 | −# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | |
| 122 | −# define BCMCPU_RUNTIME_DETECT | |
| 123 | −# else | |
| 124 | −# define bcm63xx_get_cpu_id() BCM6368_CPU_ID | |
| 125 | −# endif | |
| 126 | −# define BCMCPU_IS_6368() (bcm63xx_get_cpu_id() == BCM6368_CPU_ID) | |
| 127 | −#else | |
| 128 | −# define BCMCPU_IS_6368() (0) | |
| 57 | + case BCM6368_CPU_ID: | |
| 129 | 58 | #endif |
| 59 | + break; | |
| 60 | + default: | |
| 61 | + unreachable(); | |
| 62 | + } | |
| 130 | 63 | |
| 131 | −#ifndef bcm63xx_get_cpu_id | |
| 132 | −#error "No CPU support configured" | |
| 133 | −#endif | |
| 64 | + return cpu_id; | |
| 65 | +} | |
| 66 | + | |
| 67 | +extern u16 bcm63xx_cpu_id; | |
| 68 | + | |
| 69 | +static inline u16 __pure bcm63xx_get_cpu_id(void) | |
| 70 | +{ | |
| 71 | + const u16 cpu_id = bcm63xx_cpu_id; | |
| 72 | + | |
| 73 | + return __bcm63xx_get_cpu_id(cpu_id); | |
| 74 | +} | |
| 75 | + | |
| 76 | +#define BCMCPU_IS_3368() (bcm63xx_get_cpu_id() == BCM3368_CPU_ID) | |
| 77 | +#define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID) | |
| 78 | +#define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID) | |
| 79 | +#define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID) | |
| 80 | +#define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID) | |
| 81 | +#define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID) | |
| 82 | +#define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID) | |
| 83 | +#define BCMCPU_IS_6368() (bcm63xx_get_cpu_id() == BCM6368_CPU_ID) | |
| 134 | 84 | |
| 135 | 85 | /* |
| 136 | 86 | * While registers sets are (mostly) the same across 63xx CPU, base |
| @@ -598,55 +548,6 @@ enum bcm63xx_regs_set { · 461 unmodified lines | ||
| 598 | 548 | |
| 599 | 549 | extern const unsigned long *bcm63xx_regs_base; |
| 600 | 550 | |
| 601 | −#define __GEN_RSET_BASE(__cpu, __rset) \ | |
| 602 | − case RSET_## __rset : \ | |
| 603 | − return BCM_## __cpu ##_## __rset ##_BASE; | |
| 604 | − | |
| 605 | −#define __GEN_RSET(__cpu) \ | |
| 606 | − switch (set) { \ | |
| 607 | − __GEN_RSET_BASE(__cpu, DSL_LMEM) \ | |
| 608 | − __GEN_RSET_BASE(__cpu, PERF) \ | |
| 609 | − __GEN_RSET_BASE(__cpu, TIMER) \ | |
| 610 | − __GEN_RSET_BASE(__cpu, WDT) \ | |
| 611 | − __GEN_RSET_BASE(__cpu, UART0) \ | |
| 612 | − __GEN_RSET_BASE(__cpu, UART1) \ | |
| 613 | − __GEN_RSET_BASE(__cpu, GPIO) \ | |
| 614 | − __GEN_RSET_BASE(__cpu, SPI) \ | |
| 615 | − __GEN_RSET_BASE(__cpu, HSSPI) \ | |
| 616 | − __GEN_RSET_BASE(__cpu, UDC0) \ | |
| 617 | − __GEN_RSET_BASE(__cpu, OHCI0) \ | |
| 618 | − __GEN_RSET_BASE(__cpu, OHCI_PRIV) \ | |
| 619 | − __GEN_RSET_BASE(__cpu, USBH_PRIV) \ | |
| 620 | − __GEN_RSET_BASE(__cpu, USBD) \ | |
| 621 | − __GEN_RSET_BASE(__cpu, USBDMA) \ | |
| 622 | − __GEN_RSET_BASE(__cpu, MPI) \ | |
| 623 | − __GEN_RSET_BASE(__cpu, PCMCIA) \ | |
| 624 | − __GEN_RSET_BASE(__cpu, PCIE) \ | |
| 625 | − __GEN_RSET_BASE(__cpu, DSL) \ | |
| 626 | − __GEN_RSET_BASE(__cpu, ENET0) \ | |
| 627 | − __GEN_RSET_BASE(__cpu, ENET1) \ | |
| 628 | − __GEN_RSET_BASE(__cpu, ENETDMA) \ | |
| 629 | − __GEN_RSET_BASE(__cpu, ENETDMAC) \ | |
| 630 | − __GEN_RSET_BASE(__cpu, ENETDMAS) \ | |
| 631 | − __GEN_RSET_BASE(__cpu, ENETSW) \ | |
| 632 | − __GEN_RSET_BASE(__cpu, EHCI0) \ | |
| 633 | − __GEN_RSET_BASE(__cpu, SDRAM) \ | |
| 634 | − __GEN_RSET_BASE(__cpu, MEMC) \ | |
| 635 | − __GEN_RSET_BASE(__cpu, DDR) \ | |
| 636 | − __GEN_RSET_BASE(__cpu, M2M) \ | |
| 637 | − __GEN_RSET_BASE(__cpu, ATM) \ | |
| 638 | − __GEN_RSET_BASE(__cpu, XTM) \ | |
| 639 | − __GEN_RSET_BASE(__cpu, XTMDMA) \ | |
| 640 | − __GEN_RSET_BASE(__cpu, XTMDMAC) \ | |
| 641 | − __GEN_RSET_BASE(__cpu, XTMDMAS) \ | |
| 642 | − __GEN_RSET_BASE(__cpu, PCM) \ | |
| 643 | − __GEN_RSET_BASE(__cpu, PCMDMA) \ | |
| 644 | − __GEN_RSET_BASE(__cpu, PCMDMAC) \ | |
| 645 | − __GEN_RSET_BASE(__cpu, PCMDMAS) \ | |
| 646 | − __GEN_RSET_BASE(__cpu, RNG) \ | |
| 647 | − __GEN_RSET_BASE(__cpu, MISC) \ | |
| 648 | − } | |
| 649 | − | |
| 650 | 551 | #define __GEN_CPU_REGS_TABLE(__cpu) \ |
| 651 | 552 | [RSET_DSL_LMEM] = BCM_## __cpu ##_DSL_LMEM_BASE, \ |
| 652 | 553 | [RSET_PERF] = BCM_## __cpu ##_PERF_BASE, \ |
| @@ -693,36 +594,7 @@ extern const unsigned long *bcm63xx_regs_base; · 40 unmodified lines | ||
| 693 | 594 | |
| 694 | 595 | static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) |
| 695 | 596 | { |
| 696 | −#ifdef BCMCPU_RUNTIME_DETECT | |
| 697 | 597 | return bcm63xx_regs_base[set]; |
| 698 | −#else | |
| 699 | −#ifdef CONFIG_BCM63XX_CPU_3368 | |
| 700 | − __GEN_RSET(3368) | |
| 701 | −#endif | |
| 702 | −#ifdef CONFIG_BCM63XX_CPU_6328 | |
| 703 | − __GEN_RSET(6328) | |
| 704 | −#endif | |
| 705 | −#ifdef CONFIG_BCM63XX_CPU_6338 | |
| 706 | − __GEN_RSET(6338) | |
| 707 | −#endif | |
| 708 | −#ifdef CONFIG_BCM63XX_CPU_6345 | |
| 709 | − __GEN_RSET(6345) | |
| 710 | −#endif | |
| 711 | −#ifdef CONFIG_BCM63XX_CPU_6348 | |
| 712 | − __GEN_RSET(6348) | |
| 713 | −#endif | |
| 714 | −#ifdef CONFIG_BCM63XX_CPU_6358 | |
| 715 | − __GEN_RSET(6358) | |
| 716 | −#endif | |
| 717 | −#ifdef CONFIG_BCM63XX_CPU_6362 | |
| 718 | − __GEN_RSET(6362) | |
| 719 | −#endif | |
| 720 | −#ifdef CONFIG_BCM63XX_CPU_6368 | |
| 721 | − __GEN_RSET(6368) | |
| 722 | −#endif | |
| 723 | −#endif | |
| 724 | − /* unreached */ | |
| 725 | − return 0; | |
| 726 | 598 | } |
| 727 | 599 | |
| 728 | 600 | /* |
| @@ -112,55 +112,9 @@ enum bcm63xx_regs_enetdmac { · 111 unmodified lines | ||
| 112 | 112 | |
| 113 | 113 | static inline unsigned long bcm63xx_enetdmacreg(enum bcm63xx_regs_enetdmac reg) |
| 114 | 114 | { |
| 115 | −#ifdef BCMCPU_RUNTIME_DETECT | |
| 116 | 115 | extern const unsigned long *bcm63xx_regs_enetdmac; |
| 117 | 116 | |
| 118 | 117 | return bcm63xx_regs_enetdmac[reg]; |
| 119 | −#else | |
| 120 | −#ifdef CONFIG_BCM63XX_CPU_6345 | |
| 121 | − switch (reg) { | |
| 122 | − case ENETDMAC_CHANCFG: | |
| 123 | − return ENETDMA_6345_CHANCFG_REG; | |
| 124 | − case ENETDMAC_IR: | |
| 125 | − return ENETDMA_6345_IR_REG; | |
| 126 | − case ENETDMAC_IRMASK: | |
| 127 | − return ENETDMA_6345_IRMASK_REG; | |
| 128 | − case ENETDMAC_MAXBURST: | |
| 129 | − return ENETDMA_6345_MAXBURST_REG; | |
| 130 | − case ENETDMAC_BUFALLOC: | |
| 131 | − return ENETDMA_6345_BUFALLOC_REG; | |
| 132 | − case ENETDMAC_RSTART: | |
| 133 | − return ENETDMA_6345_RSTART_REG; | |
| 134 | − case ENETDMAC_FC: | |
| 135 | − return ENETDMA_6345_FC_REG; | |
| 136 | − case ENETDMAC_LEN: | |
| 137 | − return ENETDMA_6345_LEN_REG; | |
| 138 | − } | |
| 139 | −#endif | |
| 140 | −#if defined(CONFIG_BCM63XX_CPU_6328) || \ | |
| 141 | − defined(CONFIG_BCM63XX_CPU_6338) || \ | |
| 142 | − defined(CONFIG_BCM63XX_CPU_6348) || \ | |
| 143 | − defined(CONFIG_BCM63XX_CPU_6358) || \ | |
| 144 | − defined(CONFIG_BCM63XX_CPU_6362) || \ | |
| 145 | − defined(CONFIG_BCM63XX_CPU_6368) | |
| 146 | − switch (reg) { | |
| 147 | − case ENETDMAC_CHANCFG: | |
| 148 | − return ENETDMAC_CHANCFG_REG; | |
| 149 | − case ENETDMAC_IR: | |
| 150 | − return ENETDMAC_IR_REG; | |
| 151 | − case ENETDMAC_IRMASK: | |
| 152 | − return ENETDMAC_IRMASK_REG; | |
| 153 | − case ENETDMAC_MAXBURST: | |
| 154 | − return ENETDMAC_MAXBURST_REG; | |
| 155 | − case ENETDMAC_BUFALLOC: | |
| 156 | − case ENETDMAC_RSTART: | |
| 157 | − case ENETDMAC_FC: | |
| 158 | − case ENETDMAC_LEN: | |
| 159 | − return 0; | |
| 160 | − } | |
| 161 | −#endif | |
| 162 | −#endif | |
| 163 | − return 0; | |
| 164 | 118 | } |
| 165 | 119 | |
| 166 | 120 | |
| @@ -30,26 +30,6 @@ enum bcm63xx_regs_spi { · 29 unmodified lines | ||
| 30 | 30 | SPI_RX_DATA, |
| 31 | 31 | }; |
| 32 | 32 | |
| 33 | −#define __GEN_SPI_RSET_BASE(__cpu, __rset) \ | |
| 34 | − case SPI_## __rset: \ | |
| 35 | − return SPI_## __cpu ##_## __rset; | |
| 36 | − | |
| 37 | −#define __GEN_SPI_RSET(__cpu) \ | |
| 38 | − switch (reg) { \ | |
| 39 | − __GEN_SPI_RSET_BASE(__cpu, CMD) \ | |
| 40 | − __GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \ | |
| 41 | − __GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \ | |
| 42 | − __GEN_SPI_RSET_BASE(__cpu, INT_MASK) \ | |
| 43 | − __GEN_SPI_RSET_BASE(__cpu, ST) \ | |
| 44 | − __GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \ | |
| 45 | − __GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \ | |
| 46 | − __GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \ | |
| 47 | − __GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \ | |
| 48 | − __GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \ | |
| 49 | − __GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \ | |
| 50 | − __GEN_SPI_RSET_BASE(__cpu, RX_DATA) \ | |
| 51 | − } | |
| 52 | − | |
| 53 | 33 | #define __GEN_SPI_REGS_TABLE(__cpu) \ |
| 54 | 34 | [SPI_CMD] = SPI_## __cpu ##_CMD, \ |
| 55 | 35 | [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ |
| @@ -66,20 +46,9 @@ enum bcm63xx_regs_spi { · 10 unmodified lines | ||
| 66 | 46 | |
| 67 | 47 | static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) |
| 68 | 48 | { |
| 69 | −#ifdef BCMCPU_RUNTIME_DETECT | |
| 70 | 49 | extern const unsigned long *bcm63xx_regs_spi; |
| 71 | 50 | |
| 72 | 51 | return bcm63xx_regs_spi[reg]; |
| 73 | −#else | |
| 74 | −#if defined(CONFIG_BCM63XX_CPU_6338) || defined(CONFIG_BCM63XX_CPU_6348) | |
| 75 | − __GEN_SPI_RSET(6348) | |
| 76 | −#endif | |
| 77 | −#if defined(CONFIG_BCM63XX_CPU_6358) || defined(CONFIG_BCM63XX_CPU_6362) || \ | |
| 78 | − defined(CONFIG_BCM63XX_CPU_6368) | |
| 79 | − __GEN_SPI_RSET(6358) | |
| 80 | −#endif | |
| 81 | −#endif | |
| 82 | − return 0; | |
| 83 | 52 | } |
| 84 | 53 | |
| 85 | 54 | #endif /* BCM63XX_DEV_SPI_H */ |
| @@ -215,23 +215,23 @@ · 214 unmodified lines | ||
| 215 | 215 | |
| 216 | 216 | /* Interrupt Mask register */ |
| 217 | 217 | #define PERF_IRQMASK_3368_REG 0xc |
| 218 | −#define PERF_IRQMASK_6328_REG 0x20 | |
| 218 | +#define PERF_IRQMASK_6328_REG(x) (0x20 + (x) * 0x10) | |
| 219 | 219 | #define PERF_IRQMASK_6338_REG 0xc |
| 220 | 220 | #define PERF_IRQMASK_6345_REG 0xc |
| 221 | 221 | #define PERF_IRQMASK_6348_REG 0xc |
| 222 | −#define PERF_IRQMASK_6358_REG 0xc | |
| 223 | −#define PERF_IRQMASK_6362_REG 0x20 | |
| 224 | −#define PERF_IRQMASK_6368_REG 0x20 | |
| 222 | +#define PERF_IRQMASK_6358_REG(x) (0xc + (x) * 0x2c) | |
| 223 | +#define PERF_IRQMASK_6362_REG(x) (0x20 + (x) * 0x10) | |
| 224 | +#define PERF_IRQMASK_6368_REG(x) (0x20 + (x) * 0x10) | |
| 225 | 225 | |
| 226 | 226 | /* Interrupt Status register */ |
| 227 | 227 | #define PERF_IRQSTAT_3368_REG 0x10 |
| 228 | −#define PERF_IRQSTAT_6328_REG 0x28 | |
| 228 | +#define PERF_IRQSTAT_6328_REG(x) (0x28 + (x) * 0x10) | |
| 229 | 229 | #define PERF_IRQSTAT_6338_REG 0x10 |
| 230 | 230 | #define PERF_IRQSTAT_6345_REG 0x10 |
| 231 | 231 | #define PERF_IRQSTAT_6348_REG 0x10 |
| 232 | −#define PERF_IRQSTAT_6358_REG 0x10 | |
| 233 | −#define PERF_IRQSTAT_6362_REG 0x28 | |
| 234 | −#define PERF_IRQSTAT_6368_REG 0x28 | |
| 232 | +#define PERF_IRQSTAT_6358_REG(x) (0x10 + (x) * 0x2c) | |
| 233 | +#define PERF_IRQSTAT_6362_REG(x) (0x28 + (x) * 0x10) | |
| 234 | +#define PERF_IRQSTAT_6368_REG(x) (0x28 + (x) * 0x10) | |
| 235 | 235 | |
| 236 | 236 | /* External Interrupt Configuration register */ |
| 237 | 237 | #define PERF_EXTIRQ_CFG_REG_3368 0x14 |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #define cpu_has_smartmips 0 |
| 25 | 25 | #define cpu_has_vtag_icache 0 |
| 26 | 26 | |
| 27 | −#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338)) | |
| 27 | +#if !defined(CONFIG_SYS_HAS_CPU_BMIPS4350) | |
| 28 | 28 | #define cpu_has_dc_aliases 0 |
| 29 | 29 | #endif |
| 30 | 30 | |
| @@ -146,6 +146,9 @@ struct boot_params { · 145 unmodified lines | ||
| 146 | 146 | |
| 147 | 147 | struct loongson_system_configuration { |
| 148 | 148 | u32 nr_cpus; |
| 149 | + u32 nr_nodes; | |
| 150 | + int cores_per_node; | |
| 151 | + int cores_per_package; | |
| 149 | 152 | enum loongson_cpu_type cputype; |
| 150 | 153 | u64 ht_control_base; |
| 151 | 154 | u64 pci_mem_start_addr; |
| @@ -160,4 +163,5 @@ struct loongson_system_configuration { · 8 unmodified lines | ||
| 160 | 163 | |
| 161 | 164 | extern struct efi_memory_map_loongson *loongson_memmap; |
| 162 | 165 | extern struct loongson_system_configuration loongson_sysconf; |
| 166 | +extern int cpuhotplug_workaround; | |
| 163 | 167 | #endif |
| @@ -0,0 +1,52 @@ | ||
| 1 | +/* | |
| 2 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | + * License. See the file "COPYING" in the main directory of this archive | |
| 4 | + * for more details. | |
| 5 | + * | |
| 6 | + * Copyright (C) 2005 Embedded Alley Solutions, Inc | |
| 7 | + * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) | |
| 8 | + * Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn) | |
| 9 | + * Copyright (C) 2012 Huacai Chen (chenhc@lemote.com) | |
| 10 | + */ | |
| 11 | +#ifndef __ASM_MACH_LOONGSON_KERNEL_ENTRY_H | |
| 12 | +#define __ASM_MACH_LOONGSON_KERNEL_ENTRY_H | |
| 13 | + | |
| 14 | +/* | |
| 15 | + * Override macros used in arch/mips/kernel/head.S. | |
| 16 | + */ | |
| 17 | + .macro kernel_entry_setup | |
| 18 | +#ifdef CONFIG_CPU_LOONGSON3 | |
| 19 | + .set push | |
| 20 | + .set mips64 | |
| 21 | + /* Set LPA on LOONGSON3 config3 */ | |
| 22 | + mfc0 t0, $16, 3 | |
| 23 | + or t0, (0x1 << 7) | |
| 24 | + mtc0 t0, $16, 3 | |
| 25 | + /* Set ELPA on LOONGSON3 pagegrain */ | |
| 26 | + li t0, (0x1 << 29) | |
| 27 | + mtc0 t0, $5, 1 | |
| 28 | + _ehb | |
| 29 | + .set pop | |
| 30 | +#endif | |
| 31 | + .endm | |
| 32 | + | |
| 33 | +/* | |
| 34 | + * Do SMP slave processor setup. | |
| 35 | + */ | |
| 36 | + .macro smp_slave_setup | |
| 37 | +#ifdef CONFIG_CPU_LOONGSON3 | |
| 38 | + .set push | |
| 39 | + .set mips64 | |
| 40 | + /* Set LPA on LOONGSON3 config3 */ | |
| 41 | + mfc0 t0, $16, 3 | |
| 42 | + or t0, (0x1 << 7) | |
| 43 | + mtc0 t0, $16, 3 | |
| 44 | + /* Set ELPA on LOONGSON3 pagegrain */ | |
| 45 | + li t0, (0x1 << 29) | |
| 46 | + mtc0 t0, $5, 1 | |
| 47 | + _ehb | |
| 48 | + .set pop | |
| 49 | +#endif | |
| 50 | + .endm | |
| 51 | + | |
| 52 | +#endif /* __ASM_MACH_LOONGSON_KERNEL_ENTRY_H */ | |
| @@ -249,8 +249,15 @@ static inline void do_perfcnt_IRQ(void) · 248 unmodified lines | ||
| 249 | 249 | #define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68) |
| 250 | 250 | #define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c) |
| 251 | 251 | |
| 252 | −/* Chip Config */ | |
| 253 | −#define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) | |
| 252 | +#define MAX_PACKAGES 4 | |
| 253 | + | |
| 254 | +/* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */ | |
| 255 | +extern u64 loongson_chipcfg[MAX_PACKAGES]; | |
| 256 | +#define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id])) | |
| 257 | + | |
| 258 | +/* Freq Control register of each physical cpu package, PRid >= Loongson-3B */ | |
| 259 | +extern u64 loongson_freqctrl[MAX_PACKAGES]; | |
| 260 | +#define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id])) | |
| 254 | 261 | |
| 255 | 262 | /* pcimap */ |
| 256 | 263 | |
| @@ -24,10 +24,10 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | −#ifdef CONFIG_LEMOTE_MACH3A | |
| 27 | +#ifdef CONFIG_LOONGSON_MACH3X | |
| 28 | 28 | |
| 29 | 29 | #define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 |
| 30 | 30 | |
| 31 | −#endif /* CONFIG_LEMOTE_MACH3A */ | |
| 31 | +#endif /* CONFIG_LOONGSON_MACH3X */ | |
| 32 | 32 | |
| 33 | 33 | #endif /* __ASM_MACH_LOONGSON_MACHINE_H */ |
| @@ -0,0 +1,53 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & | |
| 3 | + * Insititute of Computing Technology | |
| 4 | + * Author: Xiang Gao, gaoxiang@ict.ac.cn | |
| 5 | + * Huacai Chen, chenhc@lemote.com | |
| 6 | + * Xiaofu Meng, Shuangshuang Zhang | |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or modify it | |
| 9 | + * under the terms of the GNU General Public License as published by the | |
| 10 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 11 | + * option) any later version. | |
| 12 | + */ | |
| 13 | +#ifndef _ASM_MACH_MMZONE_H | |
| 14 | +#define _ASM_MACH_MMZONE_H | |
| 15 | + | |
| 16 | +#include <boot_param.h> | |
| 17 | +#define NODE_ADDRSPACE_SHIFT 44 | |
| 18 | +#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL | |
| 19 | +#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL | |
| 20 | +#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL | |
| 21 | +#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL | |
| 22 | + | |
| 23 | +#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT) | |
| 24 | + | |
| 25 | +#define LEVELS_PER_SLICE 128 | |
| 26 | + | |
| 27 | +struct slice_data { | |
| 28 | + unsigned long irq_enable_mask[2]; | |
| 29 | + int level_to_irq[LEVELS_PER_SLICE]; | |
| 30 | +}; | |
| 31 | + | |
| 32 | +struct hub_data { | |
| 33 | + cpumask_t h_cpus; | |
| 34 | + unsigned long slice_map; | |
| 35 | + unsigned long irq_alloc_mask[2]; | |
| 36 | + struct slice_data slice[2]; | |
| 37 | +}; | |
| 38 | + | |
| 39 | +struct node_data { | |
| 40 | + struct pglist_data pglist; | |
| 41 | + struct hub_data hub; | |
| 42 | + cpumask_t cpumask; | |
| 43 | +}; | |
| 44 | + | |
| 45 | +extern struct node_data *__node_data[]; | |
| 46 | + | |
| 47 | +#define NODE_DATA(n) (&__node_data[(n)]->pglist) | |
| 48 | +#define hub_data(n) (&__node_data[(n)]->hub) | |
| 49 | + | |
| 50 | +extern void setup_zero_pages(void); | |
| 51 | +extern void __init prom_init_numa_memory(void); | |
| 52 | + | |
| 53 | +#endif /* _ASM_MACH_MMZONE_H */ | |
| @@ -0,0 +1,23 @@ | ||
| 1 | +#ifndef _ASM_MACH_TOPOLOGY_H | |
| 2 | +#define _ASM_MACH_TOPOLOGY_H | |
| 3 | + | |
| 4 | +#ifdef CONFIG_NUMA | |
| 5 | + | |
| 6 | +#define cpu_to_node(cpu) ((cpu) >> 2) | |
| 7 | +#define parent_node(node) (node) | |
| 8 | +#define cpumask_of_node(node) (&__node_data[(node)]->cpumask) | |
| 9 | + | |
| 10 | +struct pci_bus; | |
| 11 | +extern int pcibus_to_node(struct pci_bus *); | |
| 12 | + | |
| 13 | +#define cpumask_of_pcibus(bus) (cpu_online_mask) | |
| 14 | + | |
| 15 | +extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; | |
| 16 | + | |
| 17 | +#define node_distance(from, to) (__node_distances[(from)][(to)]) | |
| 18 | + | |
| 19 | +#endif | |
| 20 | + | |
| 21 | +#include <asm-generic/topology.h> | |
| 22 | + | |
| 23 | +#endif /* _ASM_MACH_TOPOLOGY_H */ | |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #define __ASM_MACH_MIPS_IRQ_H |
| 3 | 3 | |
| 4 | 4 | |
| 5 | +#define GIC_NUM_INTRS (24 + NR_CPUS * 2) | |
| 5 | 6 | #define NR_IRQS 256 |
| 6 | 7 | |
| 7 | 8 | #include_next <irq.h> |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | #ifndef __ASM_MACH_MIPS_IRQ_H |
| 2 | 2 | #define __ASM_MACH_MIPS_IRQ_H |
| 3 | 3 | |
| 4 | +#define GIC_NUM_INTRS (24 + NR_CPUS * 2) | |
| 4 | 5 | #define NR_IRQS 256 |
| 5 | 6 | |
| 6 | 7 | |
| @@ -413,7 +413,6 @@ extern unsigned long _pcictrl_bonito_pcicfg; · 412 unmodified lines | ||
| 413 | 413 | #define BONITO_PCIMEMBASECFG_SIZE(WIN, CFG) (((((~(CFG)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)) << (BONITO_PCIMEMBASECFG_ASHIFT - BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) | BONITO_PCIMEMBASECFG_AMASK) |
| 414 | 414 | |
| 415 | 415 | |
| 416 | −#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) | |
| 417 | 416 | #define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) |
| 418 | 417 | #define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) |
| 419 | 418 | |
| @@ -265,6 +265,7 @@ · 264 unmodified lines | ||
| 265 | 265 | #define PG_XIE (_ULCAST_(1) << 30) |
| 266 | 266 | #define PG_ELPA (_ULCAST_(1) << 29) |
| 267 | 267 | #define PG_ESP (_ULCAST_(1) << 28) |
| 268 | +#define PG_IEC (_ULCAST_(1) << 27) | |
| 268 | 269 | |
| 269 | 270 | /* |
| 270 | 271 | * R4x00 interrupt enable / cause bits |
| @@ -630,7 +631,6 @@ · 359 unmodified lines | ||
| 630 | 631 | #define MIPS_CONF4_MMUSIZEEXT_SHIFT (0) |
| 631 | 632 | #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) |
| 632 | 633 | #define MIPS_CONF4_FTLBSETS_SHIFT (0) |
| 633 | −#define MIPS_CONF4_FTLBSETS_SHIFT (0) | |
| 634 | 634 | #define MIPS_CONF4_FTLBSETS (_ULCAST_(15) << MIPS_CONF4_FTLBSETS_SHIFT) |
| 635 | 635 | #define MIPS_CONF4_FTLBWAYS_SHIFT (4) |
| 636 | 636 | #define MIPS_CONF4_FTLBWAYS (_ULCAST_(15) << MIPS_CONF4_FTLBWAYS_SHIFT) |
| @@ -652,6 +652,7 @@ · 15 unmodified lines | ||
| 652 | 652 | |
| 653 | 653 | #define MIPS_CONF5_NF (_ULCAST_(1) << 0) |
| 654 | 654 | #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) |
| 655 | +#define MIPS_CONF5_MRP (_ULCAST_(1) << 3) | |
| 655 | 656 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) |
| 656 | 657 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) |
| 657 | 658 | #define MIPS_CONF5_CV (_ULCAST_(1) << 29) |
| @@ -668,6 +669,12 @@ · 10 unmodified lines | ||
| 668 | 669 | #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) |
| 669 | 670 | #define MIPS_CONF7_AR (_ULCAST_(1) << 16) |
| 670 | 671 | |
| 672 | +/* MAAR bit definitions */ | |
| 673 | +#define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) | |
| 674 | +#define MIPS_MAAR_ADDR_SHIFT 12 | |
| 675 | +#define MIPS_MAAR_S (_ULCAST_(1) << 1) | |
| 676 | +#define MIPS_MAAR_V (_ULCAST_(1) << 0) | |
| 677 | + | |
| 671 | 678 | /* EntryHI bit definition */ |
| 672 | 679 | #define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10) |
| 673 | 680 | |
| @@ -706,6 +713,37 @@ · 32 unmodified lines | ||
| 706 | 713 | #define MIPS_SEGCFG_MK _ULCAST_(1) |
| 707 | 714 | #define MIPS_SEGCFG_UK _ULCAST_(0) |
| 708 | 715 | |
| 716 | +#define MIPS_PWFIELD_GDI_SHIFT 24 | |
| 717 | +#define MIPS_PWFIELD_GDI_MASK 0x3f000000 | |
| 718 | +#define MIPS_PWFIELD_UDI_SHIFT 18 | |
| 719 | +#define MIPS_PWFIELD_UDI_MASK 0x00fc0000 | |
| 720 | +#define MIPS_PWFIELD_MDI_SHIFT 12 | |
| 721 | +#define MIPS_PWFIELD_MDI_MASK 0x0003f000 | |
| 722 | +#define MIPS_PWFIELD_PTI_SHIFT 6 | |
| 723 | +#define MIPS_PWFIELD_PTI_MASK 0x00000fc0 | |
| 724 | +#define MIPS_PWFIELD_PTEI_SHIFT 0 | |
| 725 | +#define MIPS_PWFIELD_PTEI_MASK 0x0000003f | |
| 726 | + | |
| 727 | +#define MIPS_PWSIZE_GDW_SHIFT 24 | |
| 728 | +#define MIPS_PWSIZE_GDW_MASK 0x3f000000 | |
| 729 | +#define MIPS_PWSIZE_UDW_SHIFT 18 | |
| 730 | +#define MIPS_PWSIZE_UDW_MASK 0x00fc0000 | |
| 731 | +#define MIPS_PWSIZE_MDW_SHIFT 12 | |
| 732 | +#define MIPS_PWSIZE_MDW_MASK 0x0003f000 | |
| 733 | +#define MIPS_PWSIZE_PTW_SHIFT 6 | |
| 734 | +#define MIPS_PWSIZE_PTW_MASK 0x00000fc0 | |
| 735 | +#define MIPS_PWSIZE_PTEW_SHIFT 0 | |
| 736 | +#define MIPS_PWSIZE_PTEW_MASK 0x0000003f | |
| 737 | + | |
| 738 | +#define MIPS_PWCTL_PWEN_SHIFT 31 | |
| 739 | +#define MIPS_PWCTL_PWEN_MASK 0x80000000 | |
| 740 | +#define MIPS_PWCTL_DPH_SHIFT 7 | |
| 741 | +#define MIPS_PWCTL_DPH_MASK 0x00000080 | |
| 742 | +#define MIPS_PWCTL_HUGEPG_SHIFT 6 | |
| 743 | +#define MIPS_PWCTL_HUGEPG_MASK 0x00000060 | |
| 744 | +#define MIPS_PWCTL_PSN_SHIFT 0 | |
| 745 | +#define MIPS_PWCTL_PSN_MASK 0x0000003f | |
| 746 | + | |
| 709 | 747 | #ifndef __ASSEMBLY__ |
| 710 | 748 | |
| 711 | 749 | /* |
| @@ -1044,6 +1082,11 @@ do { \ · 332 unmodified lines | ||
| 1044 | 1082 | #define write_c0_config6(val) __write_32bit_c0_register($16, 6, val) |
| 1045 | 1083 | #define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) |
| 1046 | 1084 | |
| 1085 | +#define read_c0_maar() __read_ulong_c0_register($17, 1) | |
| 1086 | +#define write_c0_maar(val) __write_ulong_c0_register($17, 1, val) | |
| 1087 | +#define read_c0_maari() __read_32bit_c0_register($17, 2) | |
| 1088 | +#define write_c0_maari(val) __write_32bit_c0_register($17, 2, val) | |
| 1089 | + | |
| 1047 | 1090 | /* |
| 1048 | 1091 | * The WatchLo register. There may be up to 8 of them. |
| 1049 | 1092 | */ |
| @@ -1201,6 +1244,19 @@ do { \ · 151 unmodified lines | ||
| 1201 | 1244 | #define read_c0_segctl2() __read_32bit_c0_register($5, 4) |
| 1202 | 1245 | #define write_c0_segctl2(val) __write_32bit_c0_register($5, 4, val) |
| 1203 | 1246 | |
| 1247 | +/* Hardware Page Table Walker */ | |
| 1248 | +#define read_c0_pwbase() __read_ulong_c0_register($5, 5) | |
| 1249 | +#define write_c0_pwbase(val) __write_ulong_c0_register($5, 5, val) | |
| 1250 | + | |
| 1251 | +#define read_c0_pwfield() __read_ulong_c0_register($5, 6) | |
| 1252 | +#define write_c0_pwfield(val) __write_ulong_c0_register($5, 6, val) | |
| 1253 | + | |
| 1254 | +#define read_c0_pwsize() __read_ulong_c0_register($5, 7) | |
| 1255 | +#define write_c0_pwsize(val) __write_ulong_c0_register($5, 7, val) | |
| 1256 | + | |
| 1257 | +#define read_c0_pwctl() __read_32bit_c0_register($6, 6) | |
| 1258 | +#define write_c0_pwctl(val) __write_32bit_c0_register($6, 6, val) | |
| 1259 | + | |
| 1204 | 1260 | /* Cavium OCTEON (cnMIPS) */ |
| 1205 | 1261 | #define read_c0_cvmcount() __read_ulong_c0_register($9, 6) |
| 1206 | 1262 | #define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val) |
| @@ -20,10 +20,20 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <asm/tlbflush.h> |
| 21 | 21 | #include <asm-generic/mm_hooks.h> |
| 22 | 22 | |
| 23 | +#define htw_set_pwbase(pgd) \ | |
| 24 | +do { \ | |
| 25 | + if (cpu_has_htw) { \ | |
| 26 | + write_c0_pwbase(pgd); \ | |
| 27 | + back_to_back_c0_hazard(); \ | |
| 28 | + htw_reset(); \ | |
| 29 | + } \ | |
| 30 | +} while (0) | |
| 31 | + | |
| 23 | 32 | #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ |
| 24 | 33 | do { \ |
| 25 | 34 | extern void tlbmiss_handler_setup_pgd(unsigned long); \ |
| 26 | 35 | tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \ |
| 36 | + htw_set_pwbase((unsigned long)pgd); \ | |
| 27 | 37 | } while (0) |
| 28 | 38 | |
| 29 | 39 | #ifdef CONFIG_MIPS_PGD_C0_CONTEXT |
| @@ -12,8 +12,11 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | #include <asm/mipsregs.h> |
| 14 | 14 | |
| 15 | +#ifndef __ASSEMBLY__ | |
| 16 | + | |
| 15 | 17 | extern void _save_msa(struct task_struct *); |
| 16 | 18 | extern void _restore_msa(struct task_struct *); |
| 19 | +extern void _init_msa_upper(void); | |
| 17 | 20 | |
| 18 | 21 | static inline void enable_msa(void) |
| 19 | 22 | { |
| @@ -112,10 +115,10 @@ static inline unsigned int read_msa_##name(void) \ · 92 unmodified lines | ||
| 112 | 115 | " .set push\n" \ |
| 113 | 116 | " .set noat\n" \ |
| 114 | 117 | " .insn\n" \ |
| 115 | − " .word #CFC_MSA_INSN | (" #cs " << 11)\n" \ | |
| 118 | + " .word %1 | (" #cs " << 11)\n" \ | |
| 116 | 119 | " move %0, $1\n" \ |
| 117 | 120 | " .set pop\n" \ |
| 118 | − : "=r"(reg)); \ | |
| 121 | + : "=r"(reg) : "i"(CFC_MSA_INSN)); \ | |
| 119 | 122 | return reg; \ |
| 120 | 123 | } \ |
| 121 | 124 | \ |
| @@ -126,22 +129,13 @@ static inline void write_msa_##name(unsigned int val) \ · 4 unmodified lines | ||
| 126 | 129 | " .set noat\n" \ |
| 127 | 130 | " move $1, %0\n" \ |
| 128 | 131 | " .insn\n" \ |
| 129 | − " .word #CTC_MSA_INSN | (" #cs " << 6)\n" \ | |
| 132 | + " .word %1 | (" #cs " << 6)\n" \ | |
| 130 | 133 | " .set pop\n" \ |
| 131 | − : : "r"(val)); \ | |
| 134 | + : : "r"(val), "i"(CTC_MSA_INSN)); \ | |
| 132 | 135 | } |
| 133 | 136 | |
| 134 | 137 | #endif /* !TOOLCHAIN_SUPPORTS_MSA */ |
| 135 | 138 | |
| 136 | −#define MSA_IR 0 | |
| 137 | −#define MSA_CSR 1 | |
| 138 | −#define MSA_ACCESS 2 | |
| 139 | −#define MSA_SAVE 3 | |
| 140 | −#define MSA_MODIFY 4 | |
| 141 | −#define MSA_REQUEST 5 | |
| 142 | −#define MSA_MAP 6 | |
| 143 | −#define MSA_UNMAP 7 | |
| 144 | − | |
| 145 | 139 | __BUILD_MSA_CTL_REG(ir, 0) |
| 146 | 140 | __BUILD_MSA_CTL_REG(csr, 1) |
| 147 | 141 | __BUILD_MSA_CTL_REG(access, 2) |
| @@ -151,6 +145,17 @@ __BUILD_MSA_CTL_REG(request, 5) · 3 unmodified lines | ||
| 151 | 145 | __BUILD_MSA_CTL_REG(map, 6) |
| 152 | 146 | __BUILD_MSA_CTL_REG(unmap, 7) |
| 153 | 147 | |
| 148 | +#endif /* !__ASSEMBLY__ */ | |
| 149 | + | |
| 150 | +#define MSA_IR 0 | |
| 151 | +#define MSA_CSR 1 | |
| 152 | +#define MSA_ACCESS 2 | |
| 153 | +#define MSA_SAVE 3 | |
| 154 | +#define MSA_MODIFY 4 | |
| 155 | +#define MSA_REQUEST 5 | |
| 156 | +#define MSA_MAP 6 | |
| 157 | +#define MSA_UNMAP 7 | |
| 158 | + | |
| 154 | 159 | /* MSA Implementation Register (MSAIR) */ |
| 155 | 160 | #define MSA_IR_REVB 0 |
| 156 | 161 | #define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB) |
| @@ -228,6 +228,7 @@ enum cvmx_board_types_enum { · 227 unmodified lines | ||
| 228 | 228 | */ |
| 229 | 229 | CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001, |
| 230 | 230 | CVMX_BOARD_TYPE_UBNT_E100 = 20002, |
| 231 | + CVMX_BOARD_TYPE_CUST_DSR1000N = 20006, | |
| 231 | 232 | CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000, |
| 232 | 233 | |
| 233 | 234 | /* The remaining range is reserved for future use. */ |
| @@ -327,6 +328,7 @@ static inline const char *cvmx_board_type_to_string(enum · 93 unmodified lines | ||
| 327 | 328 | /* Customer private range */ |
| 328 | 329 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN) |
| 329 | 330 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100) |
| 331 | + ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N) | |
| 330 | 332 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX) |
| 331 | 333 | } |
| 332 | 334 | return "Unsupported Board"; |
| @@ -18,6 +18,18 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #include <asm-generic/pgtable-nopmd.h> |
| 20 | 20 | |
| 21 | +extern int temp_tlb_entry __cpuinitdata; | |
| 22 | + | |
| 23 | +/* | |
| 24 | + * - add_temporary_entry() add a temporary TLB entry. We use TLB entries | |
| 25 | + * starting at the top and working down. This is for populating the | |
| 26 | + * TLB before trap_init() puts the TLB miss handler in place. It | |
| 27 | + * should be used only for entries matching the actual page tables, | |
| 28 | + * to prevent inconsistencies. | |
| 29 | + */ | |
| 30 | +extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |
| 31 | + unsigned long entryhi, unsigned long pagemask); | |
| 32 | + | |
| 21 | 33 | /* |
| 22 | 34 | * Basically we have the same two-level (which is the logical three level |
| 23 | 35 | * Linux page table layout folded) page tables as the i386. Some day |
| @@ -97,6 +97,31 @@ extern void paging_init(void); · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | #define pmd_page_vaddr(pmd) pmd_val(pmd) |
| 99 | 99 | |
| 100 | +#define htw_stop() \ | |
| 101 | +do { \ | |
| 102 | + if (cpu_has_htw) \ | |
| 103 | + write_c0_pwctl(read_c0_pwctl() & \ | |
| 104 | + ~(1 << MIPS_PWCTL_PWEN_SHIFT)); \ | |
| 105 | +} while(0) | |
| 106 | + | |
| 107 | +#define htw_start() \ | |
| 108 | +do { \ | |
| 109 | + if (cpu_has_htw) \ | |
| 110 | + write_c0_pwctl(read_c0_pwctl() | \ | |
| 111 | + (1 << MIPS_PWCTL_PWEN_SHIFT)); \ | |
| 112 | +} while(0) | |
| 113 | + | |
| 114 | + | |
| 115 | +#define htw_reset() \ | |
| 116 | +do { \ | |
| 117 | + if (cpu_has_htw) { \ | |
| 118 | + htw_stop(); \ | |
| 119 | + back_to_back_c0_hazard(); \ | |
| 120 | + htw_start(); \ | |
| 121 | + back_to_back_c0_hazard(); \ | |
| 122 | + } \ | |
| 123 | +} while(0) | |
| 124 | + | |
| 100 | 125 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) |
| 101 | 126 | |
| 102 | 127 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) |
| @@ -131,6 +156,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt · 28 unmodified lines | ||
| 131 | 156 | null.pte_low = null.pte_high = _PAGE_GLOBAL; |
| 132 | 157 | |
| 133 | 158 | set_pte_at(mm, addr, ptep, null); |
| 159 | + htw_reset(); | |
| 134 | 160 | } |
| 135 | 161 | #else |
| 136 | 162 | |
| @@ -168,6 +194,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt · 31 unmodified lines | ||
| 168 | 194 | else |
| 169 | 195 | #endif |
| 170 | 196 | set_pte_at(mm, addr, ptep, __pte(0)); |
| 197 | + htw_reset(); | |
| 171 | 198 | } |
| 172 | 199 | #endif |
| 173 | 200 | |
| @@ -238,7 +238,13 @@ typedef struct { · 237 unmodified lines | ||
| 238 | 238 | unsigned long seg; |
| 239 | 239 | } mm_segment_t; |
| 240 | 240 | |
| 241 | −#define ARCH_MIN_TASKALIGN 8 | |
| 241 | +#ifdef CONFIG_CPU_HAS_MSA | |
| 242 | +# define ARCH_MIN_TASKALIGN 16 | |
| 243 | +# define FPU_ALIGN __aligned(16) | |
| 244 | +#else | |
| 245 | +# define ARCH_MIN_TASKALIGN 8 | |
| 246 | +# define FPU_ALIGN | |
| 247 | +#endif | |
| 242 | 248 | |
| 243 | 249 | struct mips_abi; |
| 244 | 250 | |
| @@ -255,7 +261,7 @@ struct thread_struct { · 10 unmodified lines | ||
| 255 | 261 | unsigned long cp0_status; |
| 256 | 262 | |
| 257 | 263 | /* Saved fpu/fpu emulator stuff. */ |
| 258 | − struct mips_fpu_struct fpu; | |
| 264 | + struct mips_fpu_struct fpu FPU_ALIGN; | |
| 259 | 265 | #ifdef CONFIG_MIPS_MT_FPAFF |
| 260 | 266 | /* Emulated instruction count */ |
| 261 | 267 | unsigned long emulated_fp; |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | struct pt_regs { |
| 24 | 24 | #ifdef CONFIG_32BIT |
| 25 | 25 | /* Pad bytes for argument save space on the stack. */ |
| 26 | − unsigned long pad0[6]; | |
| 26 | + unsigned long pad0[8]; | |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | 29 | /* Saved main processor registers. */ |
| @@ -47,8 +47,10 @@ struct pt_regs { · 17 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | struct task_struct; |
| 49 | 49 | |
| 50 | −extern int ptrace_getregs(struct task_struct *child, __s64 __user *data); | |
| 51 | −extern int ptrace_setregs(struct task_struct *child, __s64 __user *data); | |
| 50 | +extern int ptrace_getregs(struct task_struct *child, | |
| 51 | + struct user_pt_regs __user *data); | |
| 52 | +extern int ptrace_setregs(struct task_struct *child, | |
| 53 | + struct user_pt_regs __user *data); | |
| 52 | 54 | |
| 53 | 55 | extern int ptrace_getfpregs(struct task_struct *child, __u32 __user *data); |
| 54 | 56 | extern int ptrace_setfpregs(struct task_struct *child, __u32 __user *data); |
| @@ -1,128 +1 @@ | ||
| 1 | −/* | |
| 2 | − * Various register offset definitions for debuggers, core file | |
| 3 | − * examiners and whatnot. | |
| 4 | − * | |
| 5 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 6 | − * License. See the file "COPYING" in the main directory of this archive | |
| 7 | − * for more details. | |
| 8 | − * | |
| 9 | − * Copyright (C) 1995, 1999 Ralf Baechle | |
| 10 | − * Copyright (C) 1995, 1999 Silicon Graphics | |
| 11 | − */ | |
| 12 | −#ifndef __ASM_MIPS_REG_H | |
| 13 | −#define __ASM_MIPS_REG_H | |
| 14 | − | |
| 15 | − | |
| 16 | −#if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H) | |
| 17 | − | |
| 18 | −#define EF_R0 6 | |
| 19 | −#define EF_R1 7 | |
| 20 | −#define EF_R2 8 | |
| 21 | −#define EF_R3 9 | |
| 22 | −#define EF_R4 10 | |
| 23 | −#define EF_R5 11 | |
| 24 | −#define EF_R6 12 | |
| 25 | −#define EF_R7 13 | |
| 26 | −#define EF_R8 14 | |
| 27 | −#define EF_R9 15 | |
| 28 | −#define EF_R10 16 | |
| 29 | −#define EF_R11 17 | |
| 30 | −#define EF_R12 18 | |
| 31 | −#define EF_R13 19 | |
| 32 | −#define EF_R14 20 | |
| 33 | −#define EF_R15 21 | |
| 34 | −#define EF_R16 22 | |
| 35 | −#define EF_R17 23 | |
| 36 | −#define EF_R18 24 | |
| 37 | −#define EF_R19 25 | |
| 38 | −#define EF_R20 26 | |
| 39 | −#define EF_R21 27 | |
| 40 | −#define EF_R22 28 | |
| 41 | −#define EF_R23 29 | |
| 42 | −#define EF_R24 30 | |
| 43 | −#define EF_R25 31 | |
| 44 | − | |
| 45 | −/* | |
| 46 | − * k0/k1 unsaved | |
| 47 | − */ | |
| 48 | −#define EF_R26 32 | |
| 49 | −#define EF_R27 33 | |
| 50 | − | |
| 51 | −#define EF_R28 34 | |
| 52 | −#define EF_R29 35 | |
| 53 | −#define EF_R30 36 | |
| 54 | −#define EF_R31 37 | |
| 55 | − | |
| 56 | −/* | |
| 57 | − * Saved special registers | |
| 58 | − */ | |
| 59 | −#define EF_LO 38 | |
| 60 | −#define EF_HI 39 | |
| 61 | − | |
| 62 | −#define EF_CP0_EPC 40 | |
| 63 | −#define EF_CP0_BADVADDR 41 | |
| 64 | −#define EF_CP0_STATUS 42 | |
| 65 | −#define EF_CP0_CAUSE 43 | |
| 66 | −#define EF_UNUSED0 44 | |
| 67 | − | |
| 68 | −#define EF_SIZE 180 | |
| 69 | − | |
| 70 | −#endif | |
| 71 | − | |
| 72 | −#if defined(CONFIG_64BIT) && !defined(WANT_COMPAT_REG_H) | |
| 73 | − | |
| 74 | −#define EF_R0 0 | |
| 75 | −#define EF_R1 1 | |
| 76 | −#define EF_R2 2 | |
| 77 | −#define EF_R3 3 | |
| 78 | −#define EF_R4 4 | |
| 79 | −#define EF_R5 5 | |
| 80 | −#define EF_R6 6 | |
| 81 | −#define EF_R7 7 | |
| 82 | −#define EF_R8 8 | |
| 83 | −#define EF_R9 9 | |
| 84 | −#define EF_R10 10 | |
| 85 | −#define EF_R11 11 | |
| 86 | −#define EF_R12 12 | |
| 87 | −#define EF_R13 13 | |
| 88 | −#define EF_R14 14 | |
| 89 | −#define EF_R15 15 | |
| 90 | −#define EF_R16 16 | |
| 91 | −#define EF_R17 17 | |
| 92 | −#define EF_R18 18 | |
| 93 | −#define EF_R19 19 | |
| 94 | −#define EF_R20 20 | |
| 95 | −#define EF_R21 21 | |
| 96 | −#define EF_R22 22 | |
| 97 | −#define EF_R23 23 | |
| 98 | −#define EF_R24 24 | |
| 99 | −#define EF_R25 25 | |
| 100 | − | |
| 101 | −/* | |
| 102 | − * k0/k1 unsaved | |
| 103 | − */ | |
| 104 | −#define EF_R26 26 | |
| 105 | −#define EF_R27 27 | |
| 106 | − | |
| 107 | − | |
| 108 | −#define EF_R28 28 | |
| 109 | −#define EF_R29 29 | |
| 110 | −#define EF_R30 30 | |
| 111 | −#define EF_R31 31 | |
| 112 | − | |
| 113 | −/* | |
| 114 | − * Saved special registers | |
| 115 | − */ | |
| 116 | −#define EF_LO 32 | |
| 117 | −#define EF_HI 33 | |
| 118 | − | |
| 119 | −#define EF_CP0_EPC 34 | |
| 120 | −#define EF_CP0_BADVADDR 35 | |
| 121 | −#define EF_CP0_STATUS 36 | |
| 122 | −#define EF_CP0_CAUSE 37 | |
| 123 | − | |
| 124 | −#define EF_SIZE 304 /* size in bytes */ | |
| 125 | − | |
| 126 | −#endif /* CONFIG_64BIT */ | |
| 127 | − | |
| 128 | −#endif /* __ASM_MIPS_REG_H */ | |
| 1 | +#include <uapi/asm/reg.h> | |
| @@ -31,11 +31,19 @@ extern void mips_cps_core_init(void); · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | extern struct vpe_boot_config *mips_cps_boot_vpes(void); |
| 33 | 33 | |
| 34 | −extern bool mips_cps_smp_in_use(void); | |
| 35 | − | |
| 36 | 34 | extern void mips_cps_pm_save(void); |
| 37 | 35 | extern void mips_cps_pm_restore(void); |
| 38 | 36 | |
| 37 | +#ifdef CONFIG_MIPS_CPS | |
| 38 | + | |
| 39 | +extern bool mips_cps_smp_in_use(void); | |
| 40 | + | |
| 41 | +#else /* !CONFIG_MIPS_CPS */ | |
| 42 | + | |
| 43 | +static inline bool mips_cps_smp_in_use(void) { return false; } | |
| 44 | + | |
| 45 | +#endif /* !CONFIG_MIPS_CPS */ | |
| 46 | + | |
| 39 | 47 | #else /* __ASSEMBLY__ */ |
| 40 | 48 | |
| 41 | 49 | .extern mips_cps_bootcfg; |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | extern int smp_num_siblings; |
| 24 | 24 | extern cpumask_t cpu_sibling_map[]; |
| 25 | +extern cpumask_t cpu_core_map[]; | |
| 25 | 26 | |
| 26 | 27 | #define raw_smp_processor_id() (current_thread_info()->cpu) |
| 27 | 28 | |
| @@ -36,6 +37,11 @@ extern int __cpu_logical_map[NR_CPUS]; · 8 unmodified lines | ||
| 36 | 37 | |
| 37 | 38 | #define NO_PROC_ID (-1) |
| 38 | 39 | |
| 40 | +#define topology_physical_package_id(cpu) (cpu_data[cpu].package) | |
| 41 | +#define topology_core_id(cpu) (cpu_data[cpu].core) | |
| 42 | +#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) | |
| 43 | +#define topology_thread_cpumask(cpu) (&cpu_sibling_map[cpu]) | |
| 44 | + | |
| 39 | 45 | #define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */ |
| 40 | 46 | #define SMP_CALL_FUNCTION 0x2 |
| 41 | 47 | /* Octeon - Tell another core to flush its icache */ |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #else |
| 12 | 12 | # define SECTION_SIZE_BITS 28 |
| 13 | 13 | #endif |
| 14 | −#define MAX_PHYSMEM_BITS 35 | |
| 14 | +#define MAX_PHYSMEM_BITS 48 | |
| 15 | 15 | |
| 16 | 16 | #endif /* CONFIG_SPARSEMEM */ |
| 17 | 17 | #endif /* _MIPS_SPARSEMEM_H */ |
| @@ -1,58 +0,0 @@ | ||
| 1 | −/* | |
| 2 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | − * License. See the file "COPYING" in the main directory of this archive | |
| 4 | − * for more details. | |
| 5 | − * | |
| 6 | − * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle | |
| 7 | − */ | |
| 8 | −#ifndef _ASM_USER_H | |
| 9 | −#define _ASM_USER_H | |
| 10 | − | |
| 11 | −#include <asm/page.h> | |
| 12 | −#include <asm/reg.h> | |
| 13 | − | |
| 14 | −/* | |
| 15 | − * Core file format: The core file is written in such a way that gdb | |
| 16 | − * can understand it and provide useful information to the user (under | |
| 17 | − * linux we use the `trad-core' bfd, NOT the irix-core). The file | |
| 18 | − * contents are as follows: | |
| 19 | − * | |
| 20 | − * upage: 1 page consisting of a user struct that tells gdb | |
| 21 | − * what is present in the file. Directly after this is a | |
| 22 | − * copy of the task_struct, which is currently not used by gdb, | |
| 23 | − * but it may come in handy at some point. All of the registers | |
| 24 | − * are stored as part of the upage. The upage should always be | |
| 25 | − * only one page long. | |
| 26 | − * data: The data segment follows next. We use current->end_text to | |
| 27 | − * current->brk to pick up all of the user variables, plus any memory | |
| 28 | − * that may have been sbrk'ed. No attempt is made to determine if a | |
| 29 | − * page is demand-zero or if a page is totally unused, we just cover | |
| 30 | − * the entire range. All of the addresses are rounded in such a way | |
| 31 | − * that an integral number of pages is written. | |
| 32 | − * stack: We need the stack information in order to get a meaningful | |
| 33 | − * backtrace. We need to write the data from usp to | |
| 34 | − * current->start_stack, so we round each of these in order to be able | |
| 35 | − * to write an integer number of pages. | |
| 36 | − */ | |
| 37 | −struct user { | |
| 38 | − unsigned long regs[EF_SIZE / /* integer and fp regs */ | |
| 39 | − sizeof(unsigned long) + 64]; | |
| 40 | − size_t u_tsize; /* text size (pages) */ | |
| 41 | − size_t u_dsize; /* data size (pages) */ | |
| 42 | − size_t u_ssize; /* stack size (pages) */ | |
| 43 | − unsigned long start_code; /* text starting address */ | |
| 44 | − unsigned long start_data; /* data starting address */ | |
| 45 | − unsigned long start_stack; /* stack starting address */ | |
| 46 | − long int signal; /* signal causing core dump */ | |
| 47 | − unsigned long u_ar0; /* help gdb find registers */ | |
| 48 | − unsigned long magic; /* identifies a core file */ | |
| 49 | − char u_comm[32]; /* user command name */ | |
| 50 | −}; | |
| 51 | − | |
| 52 | −#define NBPG PAGE_SIZE | |
| 53 | −#define UPAGES 1 | |
| 54 | −#define HOST_TEXT_START_ADDR (u.start_code) | |
| 55 | −#define HOST_DATA_START_ADDR (u.start_data) | |
| 56 | −#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) | |
| 57 | − | |
| 58 | −#endif /* _ASM_USER_H */ | |
| @@ -22,24 +22,27 @@ · 21 unmodified lines | ||
| 22 | 22 | #define DSP_CONTROL 77 |
| 23 | 23 | #define ACX 78 |
| 24 | 24 | |
| 25 | −#ifndef __KERNEL__ | |
| 26 | 25 | /* |
| 27 | − * This struct defines the way the registers are stored on the stack during a | |
| 28 | − * system call/exception. As usual the registers k0/k1 aren't being saved. | |
| 26 | + * This struct defines the registers as used by PTRACE_{GET,SET}REGS. The | |
| 27 | + * format is the same for both 32- and 64-bit processes. Registers for 32-bit | |
| 28 | + * processes are sign extended. | |
| 29 | 29 | */ |
| 30 | +#ifdef __KERNEL__ | |
| 31 | +struct user_pt_regs { | |
| 32 | +#else | |
| 30 | 33 | struct pt_regs { |
| 34 | +#endif | |
| 31 | 35 | /* Saved main processor registers. */ |
| 32 | − unsigned long regs[32]; | |
| 36 | + __u64 regs[32]; | |
| 33 | 37 | |
| 34 | 38 | /* Saved special registers. */ |
| 35 | − unsigned long cp0_status; | |
| 36 | − unsigned long hi; | |
| 37 | − unsigned long lo; | |
| 38 | − unsigned long cp0_badvaddr; | |
| 39 | − unsigned long cp0_cause; | |
| 40 | − unsigned long cp0_epc; | |
| 39 | + __u64 lo; | |
| 40 | + __u64 hi; | |
| 41 | + __u64 cp0_epc; | |
| 42 | + __u64 cp0_badvaddr; | |
| 43 | + __u64 cp0_status; | |
| 44 | + __u64 cp0_cause; | |
| 41 | 45 | } __attribute__ ((aligned (8))); |
| 42 | −#endif /* __KERNEL__ */ | |
| 43 | 46 | |
| 44 | 47 | /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ |
| 45 | 48 | #define PTRACE_GETREGS 12 |
| @@ -0,0 +1,206 @@ | ||
| 1 | +/* | |
| 2 | + * Various register offset definitions for debuggers, core file | |
| 3 | + * examiners and whatnot. | |
| 4 | + * | |
| 5 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 6 | + * License. See the file "COPYING" in the main directory of this archive | |
| 7 | + * for more details. | |
| 8 | + * | |
| 9 | + * Copyright (C) 1995, 1999 Ralf Baechle | |
| 10 | + * Copyright (C) 1995, 1999 Silicon Graphics | |
| 11 | + */ | |
| 12 | +#ifndef __UAPI_ASM_MIPS_REG_H | |
| 13 | +#define __UAPI_ASM_MIPS_REG_H | |
| 14 | + | |
| 15 | +#define MIPS32_EF_R0 6 | |
| 16 | +#define MIPS32_EF_R1 7 | |
| 17 | +#define MIPS32_EF_R2 8 | |
| 18 | +#define MIPS32_EF_R3 9 | |
| 19 | +#define MIPS32_EF_R4 10 | |
| 20 | +#define MIPS32_EF_R5 11 | |
| 21 | +#define MIPS32_EF_R6 12 | |
| 22 | +#define MIPS32_EF_R7 13 | |
| 23 | +#define MIPS32_EF_R8 14 | |
| 24 | +#define MIPS32_EF_R9 15 | |
| 25 | +#define MIPS32_EF_R10 16 | |
| 26 | +#define MIPS32_EF_R11 17 | |
| 27 | +#define MIPS32_EF_R12 18 | |
| 28 | +#define MIPS32_EF_R13 19 | |
| 29 | +#define MIPS32_EF_R14 20 | |
| 30 | +#define MIPS32_EF_R15 21 | |
| 31 | +#define MIPS32_EF_R16 22 | |
| 32 | +#define MIPS32_EF_R17 23 | |
| 33 | +#define MIPS32_EF_R18 24 | |
| 34 | +#define MIPS32_EF_R19 25 | |
| 35 | +#define MIPS32_EF_R20 26 | |
| 36 | +#define MIPS32_EF_R21 27 | |
| 37 | +#define MIPS32_EF_R22 28 | |
| 38 | +#define MIPS32_EF_R23 29 | |
| 39 | +#define MIPS32_EF_R24 30 | |
| 40 | +#define MIPS32_EF_R25 31 | |
| 41 | + | |
| 42 | +/* | |
| 43 | + * k0/k1 unsaved | |
| 44 | + */ | |
| 45 | +#define MIPS32_EF_R26 32 | |
| 46 | +#define MIPS32_EF_R27 33 | |
| 47 | + | |
| 48 | +#define MIPS32_EF_R28 34 | |
| 49 | +#define MIPS32_EF_R29 35 | |
| 50 | +#define MIPS32_EF_R30 36 | |
| 51 | +#define MIPS32_EF_R31 37 | |
| 52 | + | |
| 53 | +/* | |
| 54 | + * Saved special registers | |
| 55 | + */ | |
| 56 | +#define MIPS32_EF_LO 38 | |
| 57 | +#define MIPS32_EF_HI 39 | |
| 58 | + | |
| 59 | +#define MIPS32_EF_CP0_EPC 40 | |
| 60 | +#define MIPS32_EF_CP0_BADVADDR 41 | |
| 61 | +#define MIPS32_EF_CP0_STATUS 42 | |
| 62 | +#define MIPS32_EF_CP0_CAUSE 43 | |
| 63 | +#define MIPS32_EF_UNUSED0 44 | |
| 64 | + | |
| 65 | +#define MIPS32_EF_SIZE 180 | |
| 66 | + | |
| 67 | +#define MIPS64_EF_R0 0 | |
| 68 | +#define MIPS64_EF_R1 1 | |
| 69 | +#define MIPS64_EF_R2 2 | |
| 70 | +#define MIPS64_EF_R3 3 | |
| 71 | +#define MIPS64_EF_R4 4 | |
| 72 | +#define MIPS64_EF_R5 5 | |
| 73 | +#define MIPS64_EF_R6 6 | |
| 74 | +#define MIPS64_EF_R7 7 | |
| 75 | +#define MIPS64_EF_R8 8 | |
| 76 | +#define MIPS64_EF_R9 9 | |
| 77 | +#define MIPS64_EF_R10 10 | |
| 78 | +#define MIPS64_EF_R11 11 | |
| 79 | +#define MIPS64_EF_R12 12 | |
| 80 | +#define MIPS64_EF_R13 13 | |
| 81 | +#define MIPS64_EF_R14 14 | |
| 82 | +#define MIPS64_EF_R15 15 | |
| 83 | +#define MIPS64_EF_R16 16 | |
| 84 | +#define MIPS64_EF_R17 17 | |
| 85 | +#define MIPS64_EF_R18 18 | |
| 86 | +#define MIPS64_EF_R19 19 | |
| 87 | +#define MIPS64_EF_R20 20 | |
| 88 | +#define MIPS64_EF_R21 21 | |
| 89 | +#define MIPS64_EF_R22 22 | |
| 90 | +#define MIPS64_EF_R23 23 | |
| 91 | +#define MIPS64_EF_R24 24 | |
| 92 | +#define MIPS64_EF_R25 25 | |
| 93 | + | |
| 94 | +/* | |
| 95 | + * k0/k1 unsaved | |
| 96 | + */ | |
| 97 | +#define MIPS64_EF_R26 26 | |
| 98 | +#define MIPS64_EF_R27 27 | |
| 99 | + | |
| 100 | + | |
| 101 | +#define MIPS64_EF_R28 28 | |
| 102 | +#define MIPS64_EF_R29 29 | |
| 103 | +#define MIPS64_EF_R30 30 | |
| 104 | +#define MIPS64_EF_R31 31 | |
| 105 | + | |
| 106 | +/* | |
| 107 | + * Saved special registers | |
| 108 | + */ | |
| 109 | +#define MIPS64_EF_LO 32 | |
| 110 | +#define MIPS64_EF_HI 33 | |
| 111 | + | |
| 112 | +#define MIPS64_EF_CP0_EPC 34 | |
| 113 | +#define MIPS64_EF_CP0_BADVADDR 35 | |
| 114 | +#define MIPS64_EF_CP0_STATUS 36 | |
| 115 | +#define MIPS64_EF_CP0_CAUSE 37 | |
| 116 | + | |
| 117 | +#define MIPS64_EF_SIZE 304 /* size in bytes */ | |
| 118 | + | |
| 119 | +#if _MIPS_SIM == _MIPS_SIM_ABI32 | |
| 120 | + | |
| 121 | +#define EF_R0 MIPS32_EF_R0 | |
| 122 | +#define EF_R1 MIPS32_EF_R1 | |
| 123 | +#define EF_R2 MIPS32_EF_R2 | |
| 124 | +#define EF_R3 MIPS32_EF_R3 | |
| 125 | +#define EF_R4 MIPS32_EF_R4 | |
| 126 | +#define EF_R5 MIPS32_EF_R5 | |
| 127 | +#define EF_R6 MIPS32_EF_R6 | |
| 128 | +#define EF_R7 MIPS32_EF_R7 | |
| 129 | +#define EF_R8 MIPS32_EF_R8 | |
| 130 | +#define EF_R9 MIPS32_EF_R9 | |
| 131 | +#define EF_R10 MIPS32_EF_R10 | |
| 132 | +#define EF_R11 MIPS32_EF_R11 | |
| 133 | +#define EF_R12 MIPS32_EF_R12 | |
| 134 | +#define EF_R13 MIPS32_EF_R13 | |
| 135 | +#define EF_R14 MIPS32_EF_R14 | |
| 136 | +#define EF_R15 MIPS32_EF_R15 | |
| 137 | +#define EF_R16 MIPS32_EF_R16 | |
| 138 | +#define EF_R17 MIPS32_EF_R17 | |
| 139 | +#define EF_R18 MIPS32_EF_R18 | |
| 140 | +#define EF_R19 MIPS32_EF_R19 | |
| 141 | +#define EF_R20 MIPS32_EF_R20 | |
| 142 | +#define EF_R21 MIPS32_EF_R21 | |
| 143 | +#define EF_R22 MIPS32_EF_R22 | |
| 144 | +#define EF_R23 MIPS32_EF_R23 | |
| 145 | +#define EF_R24 MIPS32_EF_R24 | |
| 146 | +#define EF_R25 MIPS32_EF_R25 | |
| 147 | +#define EF_R26 MIPS32_EF_R26 | |
| 148 | +#define EF_R27 MIPS32_EF_R27 | |
| 149 | +#define EF_R28 MIPS32_EF_R28 | |
| 150 | +#define EF_R29 MIPS32_EF_R29 | |
| 151 | +#define EF_R30 MIPS32_EF_R30 | |
| 152 | +#define EF_R31 MIPS32_EF_R31 | |
| 153 | +#define EF_LO MIPS32_EF_LO | |
| 154 | +#define EF_HI MIPS32_EF_HI | |
| 155 | +#define EF_CP0_EPC MIPS32_EF_CP0_EPC | |
| 156 | +#define EF_CP0_BADVADDR MIPS32_EF_CP0_BADVADDR | |
| 157 | +#define EF_CP0_STATUS MIPS32_EF_CP0_STATUS | |
| 158 | +#define EF_CP0_CAUSE MIPS32_EF_CP0_CAUSE | |
| 159 | +#define EF_UNUSED0 MIPS32_EF_UNUSED0 | |
| 160 | +#define EF_SIZE MIPS32_EF_SIZE | |
| 161 | + | |
| 162 | +#elif _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 | |
| 163 | + | |
| 164 | +#define EF_R0 MIPS64_EF_R0 | |
| 165 | +#define EF_R1 MIPS64_EF_R1 | |
| 166 | +#define EF_R2 MIPS64_EF_R2 | |
| 167 | +#define EF_R3 MIPS64_EF_R3 | |
| 168 | +#define EF_R4 MIPS64_EF_R4 | |
| 169 | +#define EF_R5 MIPS64_EF_R5 | |
| 170 | +#define EF_R6 MIPS64_EF_R6 | |
| 171 | +#define EF_R7 MIPS64_EF_R7 | |
| 172 | +#define EF_R8 MIPS64_EF_R8 | |
| 173 | +#define EF_R9 MIPS64_EF_R9 | |
| 174 | +#define EF_R10 MIPS64_EF_R10 | |
| 175 | +#define EF_R11 MIPS64_EF_R11 | |
| 176 | +#define EF_R12 MIPS64_EF_R12 | |
| 177 | +#define EF_R13 MIPS64_EF_R13 | |
| 178 | +#define EF_R14 MIPS64_EF_R14 | |
| 179 | +#define EF_R15 MIPS64_EF_R15 | |
| 180 | +#define EF_R16 MIPS64_EF_R16 | |
| 181 | +#define EF_R17 MIPS64_EF_R17 | |
| 182 | +#define EF_R18 MIPS64_EF_R18 | |
| 183 | +#define EF_R19 MIPS64_EF_R19 | |
| 184 | +#define EF_R20 MIPS64_EF_R20 | |
| 185 | +#define EF_R21 MIPS64_EF_R21 | |
| 186 | +#define EF_R22 MIPS64_EF_R22 | |
| 187 | +#define EF_R23 MIPS64_EF_R23 | |
| 188 | +#define EF_R24 MIPS64_EF_R24 | |
| 189 | +#define EF_R25 MIPS64_EF_R25 | |
| 190 | +#define EF_R26 MIPS64_EF_R26 | |
| 191 | +#define EF_R27 MIPS64_EF_R27 | |
| 192 | +#define EF_R28 MIPS64_EF_R28 | |
| 193 | +#define EF_R29 MIPS64_EF_R29 | |
| 194 | +#define EF_R30 MIPS64_EF_R30 | |
| 195 | +#define EF_R31 MIPS64_EF_R31 | |
| 196 | +#define EF_LO MIPS64_EF_LO | |
| 197 | +#define EF_HI MIPS64_EF_HI | |
| 198 | +#define EF_CP0_EPC MIPS64_EF_CP0_EPC | |
| 199 | +#define EF_CP0_BADVADDR MIPS64_EF_CP0_BADVADDR | |
| 200 | +#define EF_CP0_STATUS MIPS64_EF_CP0_STATUS | |
| 201 | +#define EF_CP0_CAUSE MIPS64_EF_CP0_CAUSE | |
| 202 | +#define EF_SIZE MIPS64_EF_SIZE | |
| 203 | + | |
| 204 | +#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */ | |
| 205 | + | |
| 206 | +#endif /* __UAPI_ASM_MIPS_REG_H */ | |
| @@ -87,8 +87,7 @@ void jz4740_clock_debugfs_add_clk(struct clk *clk) · 86 unmodified lines | ||
| 87 | 87 | /* TODO: Locking */ |
| 88 | 88 | void jz4740_clock_debugfs_update_parent(struct clk *clk) |
| 89 | 89 | { |
| 90 | − if (clk->debugfs_parent_entry) | |
| 91 | − debugfs_remove(clk->debugfs_parent_entry); | |
| 90 | + debugfs_remove(clk->debugfs_parent_entry); | |
| 92 | 91 | |
| 93 | 92 | if (clk->parent) { |
| 94 | 93 | char parent_path[100]; |
| @@ -59,7 +59,7 @@ struct platform_device jz4740_usb_ohci_device = { · 58 unmodified lines | ||
| 59 | 59 | |
| 60 | 60 | /* USB Device Controller */ |
| 61 | 61 | struct platform_device jz4740_udc_xceiv_device = { |
| 62 | − .name = "usb_phy_gen_xceiv", | |
| 62 | + .name = "usb_phy_generic", | |
| 63 | 63 | .id = 0, |
| 64 | 64 | }; |
| 65 | 65 | |
| @@ -234,6 +234,7 @@ void output_thread_fpu_defines(void) · 233 unmodified lines | ||
| 234 | 234 | thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]); |
| 235 | 235 | |
| 236 | 236 | OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31); |
| 237 | + OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr); | |
| 237 | 238 | BLANK(); |
| 238 | 239 | } |
| 239 | 240 | |
| @@ -72,22 +72,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | #include <asm/processor.h> |
| 74 | 74 | |
| 75 | −/* | |
| 76 | − * When this file is selected, we are definitely running a 64bit kernel. | |
| 77 | − * So using the right regs define in asm/reg.h | |
| 78 | − */ | |
| 79 | −#define WANT_COMPAT_REG_H | |
| 80 | − | |
| 81 | −/* These MUST be defined before elf.h gets included */ | |
| 82 | −extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs); | |
| 83 | −#define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs); | |
| 84 | −#define ELF_CORE_COPY_TASK_REGS(_tsk, _dest) \ | |
| 85 | −({ \ | |
| 86 | − int __res = 1; \ | |
| 87 | − elf32_core_copy_regs(*(_dest), task_pt_regs(_tsk)); \ | |
| 88 | − __res; \ | |
| 89 | −}) | |
| 90 | − | |
| 91 | 75 | #include <linux/module.h> |
| 92 | 76 | #include <linux/elfcore.h> |
| 93 | 77 | #include <linux/compat.h> |
| @@ -145,28 +129,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) · 51 unmodified lines | ||
| 145 | 129 | value->tv_usec = rem / NSEC_PER_USEC; |
| 146 | 130 | } |
| 147 | 131 | |
| 148 | −void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs) | |
| 149 | −{ | |
| 150 | − int i; | |
| 151 | − | |
| 152 | − for (i = 0; i < EF_R0; i++) | |
| 153 | − grp[i] = 0; | |
| 154 | − grp[EF_R0] = 0; | |
| 155 | − for (i = 1; i <= 31; i++) | |
| 156 | − grp[EF_R0 + i] = (elf_greg_t) regs->regs[i]; | |
| 157 | − grp[EF_R26] = 0; | |
| 158 | − grp[EF_R27] = 0; | |
| 159 | − grp[EF_LO] = (elf_greg_t) regs->lo; | |
| 160 | − grp[EF_HI] = (elf_greg_t) regs->hi; | |
| 161 | − grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc; | |
| 162 | − grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr; | |
| 163 | − grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status; | |
| 164 | − grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause; | |
| 165 | −#ifdef EF_UNUSED0 | |
| 166 | − grp[EF_UNUSED0] = 0; | |
| 167 | −#endif | |
| 168 | −} | |
| 169 | − | |
| 170 | 132 | MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); |
| 171 | 133 | MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); |
| 172 | 134 | |
| @@ -54,6 +54,20 @@ static int __init dsp_disable(char *s) · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | __setup("nodsp", dsp_disable); |
| 56 | 56 | |
| 57 | +static int mips_htw_disabled; | |
| 58 | + | |
| 59 | +static int __init htw_disable(char *s) | |
| 60 | +{ | |
| 61 | + mips_htw_disabled = 1; | |
| 62 | + cpu_data[0].options &= ~MIPS_CPU_HTW; | |
| 63 | + write_c0_pwctl(read_c0_pwctl() & | |
| 64 | + ~(1 << MIPS_PWCTL_PWEN_SHIFT)); | |
| 65 | + | |
| 66 | + return 1; | |
| 67 | +} | |
| 68 | + | |
| 69 | +__setup("nohtw", htw_disable); | |
| 70 | + | |
| 57 | 71 | static inline void check_errata(void) |
| 58 | 72 | { |
| 59 | 73 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| @@ -130,14 +144,13 @@ static inline int __cpu_has_fpu(void) · 70 unmodified lines | ||
| 130 | 144 | |
| 131 | 145 | static inline unsigned long cpu_get_msa_id(void) |
| 132 | 146 | { |
| 133 | − unsigned long status, conf5, msa_id; | |
| 147 | + unsigned long status, msa_id; | |
| 134 | 148 | |
| 135 | 149 | status = read_c0_status(); |
| 136 | 150 | __enable_fpu(FPU_64BIT); |
| 137 | − conf5 = read_c0_config5(); | |
| 138 | 151 | enable_msa(); |
| 139 | 152 | msa_id = read_msa_ir(); |
| 140 | − write_c0_config5(conf5); | |
| 153 | + disable_msa(); | |
| 141 | 154 | write_c0_status(status); |
| 142 | 155 | return msa_id; |
| 143 | 156 | } |
| @@ -321,6 +334,9 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) · 177 unmodified lines | ||
| 321 | 334 | c->options |= MIPS_CPU_SEGMENTS; |
| 322 | 335 | if (config3 & MIPS_CONF3_MSA) |
| 323 | 336 | c->ases |= MIPS_ASE_MSA; |
| 337 | + /* Only tested on 32-bit cores */ | |
| 338 | + if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT)) | |
| 339 | + c->options |= MIPS_CPU_HTW; | |
| 324 | 340 | |
| 325 | 341 | return config3 & MIPS_CONF_M; |
| 326 | 342 | } |
| @@ -389,6 +405,8 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) · 62 unmodified lines | ||
| 389 | 405 | |
| 390 | 406 | if (config5 & MIPS_CONF5_EVA) |
| 391 | 407 | c->options |= MIPS_CPU_EVA; |
| 408 | + if (config5 & MIPS_CONF5_MRP) | |
| 409 | + c->options |= MIPS_CPU_MAAR; | |
| 392 | 410 | |
| 393 | 411 | return config5 & MIPS_CONF_M; |
| 394 | 412 | } |
| @@ -421,6 +439,15 @@ static void decode_configs(struct cpuinfo_mips *c) · 26 unmodified lines | ||
| 421 | 439 | |
| 422 | 440 | mips_probe_watch_registers(c); |
| 423 | 441 | |
| 442 | + if (cpu_has_rixi) { | |
| 443 | + /* Enable the RIXI exceptions */ | |
| 444 | + write_c0_pagegrain(read_c0_pagegrain() | PG_IEC); | |
| 445 | + back_to_back_c0_hazard(); | |
| 446 | + /* Verify the IEC bit is set */ | |
| 447 | + if (read_c0_pagegrain() & PG_IEC) | |
| 448 | + c->options |= MIPS_CPU_RIXIEX; | |
| 449 | + } | |
| 450 | + | |
| 424 | 451 | #ifndef CONFIG_MIPS_CPS |
| 425 | 452 | if (cpu_has_mips_r2) { |
| 426 | 453 | c->core = get_ebase_cpunum(); |
| @@ -740,6 +767,12 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) · 313 unmodified lines | ||
| 740 | 767 | __cpu_name[cpu] = "ICT Loongson-3"; |
| 741 | 768 | set_elf_platform(cpu, "loongson3a"); |
| 742 | 769 | break; |
| 770 | + case PRID_REV_LOONGSON3B_R1: | |
| 771 | + case PRID_REV_LOONGSON3B_R2: | |
| 772 | + c->cputype = CPU_LOONGSON3; | |
| 773 | + __cpu_name[cpu] = "ICT Loongson-3"; | |
| 774 | + set_elf_platform(cpu, "loongson3b"); | |
| 775 | + break; | |
| 743 | 776 | } |
| 744 | 777 | |
| 745 | 778 | set_isa(c, MIPS_CPU_ISA_III); |
| @@ -1187,6 +1220,12 @@ void cpu_probe(void) · 441 unmodified lines | ||
| 1187 | 1220 | if (mips_dsp_disabled) |
| 1188 | 1221 | c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P); |
| 1189 | 1222 | |
| 1223 | + if (mips_htw_disabled) { | |
| 1224 | + c->options &= ~MIPS_CPU_HTW; | |
| 1225 | + write_c0_pwctl(read_c0_pwctl() & | |
| 1226 | + ~(1 << MIPS_PWCTL_PWEN_SHIFT)); | |
| 1227 | + } | |
| 1228 | + | |
| 1190 | 1229 | if (c->options & MIPS_CPU_FPU) { |
| 1191 | 1230 | c->fpu_id = cpu_get_fpu_id(); |
| 1192 | 1231 | |
| @@ -63,7 +63,7 @@ static inline int in_kernel_space(unsigned long ip) · 62 unmodified lines | ||
| 63 | 63 | ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK))) |
| 64 | 64 | |
| 65 | 65 | static unsigned int insn_jal_ftrace_caller __read_mostly; |
| 66 | −static unsigned int insn_lui_v1_hi16_mcount __read_mostly; | |
| 66 | +static unsigned int insn_la_mcount[2] __read_mostly; | |
| 67 | 67 | static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly; |
| 68 | 68 | |
| 69 | 69 | static inline void ftrace_dyn_arch_init_insns(void) |
| @@ -71,10 +71,10 @@ static inline void ftrace_dyn_arch_init_insns(void) · 1 unmodified line | ||
| 71 | 71 | u32 *buf; |
| 72 | 72 | unsigned int v1; |
| 73 | 73 | |
| 74 | − /* lui v1, hi16_mcount */ | |
| 74 | + /* la v1, _mcount */ | |
| 75 | 75 | v1 = 3; |
| 76 | − buf = (u32 *)&insn_lui_v1_hi16_mcount; | |
| 77 | − UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR); | |
| 76 | + buf = (u32 *)&insn_la_mcount[0]; | |
| 77 | + UASM_i_LA(&buf, v1, MCOUNT_ADDR); | |
| 78 | 78 | |
| 79 | 79 | /* jal (ftrace_caller + 8), jump over the first two instruction */ |
| 80 | 80 | buf = (u32 *)&insn_jal_ftrace_caller; |
| @@ -111,14 +111,47 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, · 30 unmodified lines | ||
| 111 | 111 | unsigned int new_code2) |
| 112 | 112 | { |
| 113 | 113 | int faulted; |
| 114 | + mm_segment_t old_fs; | |
| 114 | 115 | |
| 115 | 116 | safe_store_code(new_code1, ip, faulted); |
| 116 | 117 | if (unlikely(faulted)) |
| 117 | 118 | return -EFAULT; |
| 118 | − safe_store_code(new_code2, ip + 4, faulted); | |
| 119 | + | |
| 120 | + ip += 4; | |
| 121 | + safe_store_code(new_code2, ip, faulted); | |
| 119 | 122 | if (unlikely(faulted)) |
| 120 | 123 | return -EFAULT; |
| 124 | + | |
| 125 | + ip -= 4; | |
| 126 | + old_fs = get_fs(); | |
| 127 | + set_fs(get_ds()); | |
| 121 | 128 | flush_icache_range(ip, ip + 8); |
| 129 | + set_fs(old_fs); | |
| 130 | + | |
| 131 | + return 0; | |
| 132 | +} | |
| 133 | + | |
| 134 | +static int ftrace_modify_code_2r(unsigned long ip, unsigned int new_code1, | |
| 135 | + unsigned int new_code2) | |
| 136 | +{ | |
| 137 | + int faulted; | |
| 138 | + mm_segment_t old_fs; | |
| 139 | + | |
| 140 | + ip += 4; | |
| 141 | + safe_store_code(new_code2, ip, faulted); | |
| 142 | + if (unlikely(faulted)) | |
| 143 | + return -EFAULT; | |
| 144 | + | |
| 145 | + ip -= 4; | |
| 146 | + safe_store_code(new_code1, ip, faulted); | |
| 147 | + if (unlikely(faulted)) | |
| 148 | + return -EFAULT; | |
| 149 | + | |
| 150 | + old_fs = get_fs(); | |
| 151 | + set_fs(get_ds()); | |
| 152 | + flush_icache_range(ip, ip + 8); | |
| 153 | + set_fs(old_fs); | |
| 154 | + | |
| 122 | 155 | return 0; |
| 123 | 156 | } |
| 124 | 157 | #endif |
| @@ -130,13 +163,14 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, · 5 unmodified lines | ||
| 130 | 163 | * |
| 131 | 164 | * move at, ra |
| 132 | 165 | * jal _mcount --> nop |
| 166 | + * sub sp, sp, 8 --> nop (CONFIG_32BIT) | |
| 133 | 167 | * |
| 134 | 168 | * 2. For modules: |
| 135 | 169 | * |
| 136 | 170 | * 2.1 For KBUILD_MCOUNT_RA_ADDRESS and CONFIG_32BIT |
| 137 | 171 | * |
| 138 | 172 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005) |
| 139 | − * addiu v1, v1, low_16bit_of_mcount | |
| 173 | + * addiu v1, v1, low_16bit_of_mcount --> nop (CONFIG_32BIT) | |
| 140 | 174 | * move at, ra |
| 141 | 175 | * move $12, ra_address |
| 142 | 176 | * jalr v1 |
| @@ -145,7 +179,7 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, · 2 unmodified lines | ||
| 145 | 179 | * 2.2 For the Other situations |
| 146 | 180 | * |
| 147 | 181 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000004) |
| 148 | − * addiu v1, v1, low_16bit_of_mcount | |
| 182 | + * addiu v1, v1, low_16bit_of_mcount --> nop (CONFIG_32BIT) | |
| 149 | 183 | * move at, ra |
| 150 | 184 | * jalr v1 |
| 151 | 185 | * nop | move $12, ra_address | sub sp, sp, 8 |
| @@ -184,10 +218,14 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) · 32 unmodified lines | ||
| 184 | 218 | unsigned int new; |
| 185 | 219 | unsigned long ip = rec->ip; |
| 186 | 220 | |
| 187 | − new = in_kernel_space(ip) ? insn_jal_ftrace_caller : | |
| 188 | − insn_lui_v1_hi16_mcount; | |
| 221 | + new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0]; | |
| 189 | 222 | |
| 223 | +#ifdef CONFIG_64BIT | |
| 190 | 224 | return ftrace_modify_code(ip, new); |
| 225 | +#else | |
| 226 | + return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ? | |
| 227 | + INSN_NOP : insn_la_mcount[1]); | |
| 228 | +#endif | |
| 191 | 229 | } |
| 192 | 230 | |
| 193 | 231 | #define FTRACE_CALL_IP ((unsigned long)(&ftrace_call)) |
| @@ -28,6 +28,18 @@ unsigned int gic_irq_flags[GIC_NUM_INTRS]; · 27 unmodified lines | ||
| 28 | 28 | /* The index into this array is the vector # of the interrupt. */ |
| 29 | 29 | struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS]; |
| 30 | 30 | |
| 31 | +struct gic_pcpu_mask { | |
| 32 | + DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | |
| 33 | +}; | |
| 34 | + | |
| 35 | +struct gic_pending_regs { | |
| 36 | + DECLARE_BITMAP(pending, GIC_NUM_INTRS); | |
| 37 | +}; | |
| 38 | + | |
| 39 | +struct gic_intrmask_regs { | |
| 40 | + DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | |
| 41 | +}; | |
| 42 | + | |
| 31 | 43 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; |
| 32 | 44 | static struct gic_pending_regs pending_regs[NR_CPUS]; |
| 33 | 45 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; |
| @@ -177,7 +189,7 @@ unsigned int gic_compare_int(void) · 143 unmodified lines | ||
| 177 | 189 | return 0; |
| 178 | 190 | } |
| 179 | 191 | |
| 180 | −unsigned int gic_get_int(void) | |
| 192 | +void gic_get_int_mask(unsigned long *dst, const unsigned long *src) | |
| 181 | 193 | { |
| 182 | 194 | unsigned int i; |
| 183 | 195 | unsigned long *pending, *intrmask, *pcpu_mask; |
| @@ -202,8 +214,17 @@ unsigned int gic_get_int(void) · 18 unmodified lines | ||
| 202 | 214 | |
| 203 | 215 | bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); |
| 204 | 216 | bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); |
| 217 | + bitmap_and(dst, src, pending, GIC_NUM_INTRS); | |
| 218 | +} | |
| 205 | 219 | |
| 206 | − return find_first_bit(pending, GIC_NUM_INTRS); | |
| 220 | +unsigned int gic_get_int(void) | |
| 221 | +{ | |
| 222 | + DECLARE_BITMAP(interrupts, GIC_NUM_INTRS); | |
| 223 | + | |
| 224 | + bitmap_fill(interrupts, GIC_NUM_INTRS); | |
| 225 | + gic_get_int_mask(interrupts, interrupts); | |
| 226 | + | |
| 227 | + return find_first_bit(interrupts, GIC_NUM_INTRS); | |
| 207 | 228 | } |
| 208 | 229 | |
| 209 | 230 | static void gic_mask_irq(struct irq_data *d) |
| @@ -269,11 +290,13 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, · 59 unmodified lines | ||
| 269 | 290 | |
| 270 | 291 | /* Setup Intr to Pin mapping */ |
| 271 | 292 | if (pin & GIC_MAP_TO_NMI_MSK) { |
| 293 | + int i; | |
| 294 | + | |
| 272 | 295 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); |
| 273 | 296 | /* FIXME: hack to route NMI to all cpu's */ |
| 274 | − for (cpu = 0; cpu < NR_CPUS; cpu += 32) { | |
| 297 | + for (i = 0; i < NR_CPUS; i += 32) { | |
| 275 | 298 | GICWRITE(GIC_REG_ADDR(SHARED, |
| 276 | − GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)), | |
| 299 | + GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)), | |
| 277 | 300 | 0xffffffff); |
| 278 | 301 | } |
| 279 | 302 | } else { |
| @@ -299,9 +322,10 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, · 19 unmodified lines | ||
| 299 | 322 | |
| 300 | 323 | /* Init Intr Masks */ |
| 301 | 324 | GIC_CLR_INTR_MASK(intr); |
| 325 | + | |
| 302 | 326 | /* Initialise per-cpu Interrupt software masks */ |
| 303 | − if (flags & GIC_FLAG_IPI) | |
| 304 | − set_bit(intr, pcpu_masks[cpu].pcpu_mask); | |
| 327 | + set_bit(intr, pcpu_masks[cpu].pcpu_mask); | |
| 328 | + | |
| 305 | 329 | if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) |
| 306 | 330 | GIC_SET_INTR_MASK(intr); |
| 307 | 331 | if (trigtype == GIC_TRIG_EDGE) |
| @@ -340,8 +364,6 @@ static void __init gic_basic_init(int numintrs, int numvpes, · 32 unmodified lines | ||
| 340 | 364 | cpu = intrmap[i].cpunum; |
| 341 | 365 | if (cpu == GIC_UNUSED) |
| 342 | 366 | continue; |
| 343 | − if (cpu == 0 && i != 0 && intrmap[i].flags == 0) | |
| 344 | − continue; | |
| 345 | 367 | gic_setup_intr(i, |
| 346 | 368 | intrmap[i].cpunum, |
| 347 | 369 | intrmap[i].pin + pin_offset, |
| @@ -80,6 +80,19 @@ _mcount: · 79 unmodified lines | ||
| 80 | 80 | #endif |
| 81 | 81 | |
| 82 | 82 | PTR_SUBU a0, ra, 8 /* arg1: self address */ |
| 83 | + PTR_LA t1, _stext | |
| 84 | + sltu t2, a0, t1 /* t2 = (a0 < _stext) */ | |
| 85 | + PTR_LA t1, _etext | |
| 86 | + sltu t3, t1, a0 /* t3 = (a0 > _etext) */ | |
| 87 | + or t1, t2, t3 | |
| 88 | + beqz t1, ftrace_call | |
| 89 | + nop | |
| 90 | +#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) | |
| 91 | + PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */ | |
| 92 | +#else | |
| 93 | + PTR_SUBU a0, a0, 12 | |
| 94 | +#endif | |
| 95 | + | |
| 83 | 96 | .globl ftrace_call |
| 84 | 97 | ftrace_call: |
| 85 | 98 | nop /* a placeholder for the call to a real tracing function */ |
| @@ -1386,6 +1386,9 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev) · 1385 unmodified lines | ||
| 1386 | 1386 | /* proAptiv */ |
| 1387 | 1387 | #define IS_BOTH_COUNTERS_PROAPTIV_EVENT(b) \ |
| 1388 | 1388 | ((b) == 0 || (b) == 1) |
| 1389 | +/* P5600 */ | |
| 1390 | +#define IS_BOTH_COUNTERS_P5600_EVENT(b) \ | |
| 1391 | + ((b) == 0 || (b) == 1) | |
| 1389 | 1392 | |
| 1390 | 1393 | /* 1004K */ |
| 1391 | 1394 | #define IS_BOTH_COUNTERS_1004K_EVENT(b) \ |
| @@ -1420,20 +1423,23 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev) · 28 unmodified lines | ||
| 1420 | 1423 | |
| 1421 | 1424 | |
| 1422 | 1425 | /* |
| 1423 | − * User can use 0-255 raw events, where 0-127 for the events of even | |
| 1424 | − * counters, and 128-255 for odd counters. Note that bit 7 is used to | |
| 1425 | − * indicate the parity. So, for example, when user wants to take the | |
| 1426 | − * Event Num of 15 for odd counters (by referring to the user manual), | |
| 1427 | − * then 128 needs to be added to 15 as the input for the event config, | |
| 1428 | − * i.e., 143 (0x8F) to be used. | |
| 1426 | + * For most cores the user can use 0-255 raw events, where 0-127 for the events | |
| 1427 | + * of even counters, and 128-255 for odd counters. Note that bit 7 is used to | |
| 1428 | + * indicate the even/odd bank selector. So, for example, when user wants to take | |
| 1429 | + * the Event Num of 15 for odd counters (by referring to the user manual), then | |
| 1430 | + * 128 needs to be added to 15 as the input for the event config, i.e., 143 (0x8F) | |
| 1431 | + * to be used. | |
| 1432 | + * | |
| 1433 | + * Some newer cores have even more events, in which case the user can use raw | |
| 1434 | + * events 0-511, where 0-255 are for the events of even counters, and 256-511 | |
| 1435 | + * are for odd counters, so bit 8 is used to indicate the even/odd bank selector. | |
| 1429 | 1436 | */ |
| 1430 | 1437 | static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) |
| 1431 | 1438 | { |
| 1439 | + /* currently most cores have 7-bit event numbers */ | |
| 1432 | 1440 | unsigned int raw_id = config & 0xff; |
| 1433 | 1441 | unsigned int base_id = raw_id & 0x7f; |
| 1434 | 1442 | |
| 1435 | − raw_event.event_id = base_id; | |
| 1436 | − | |
| 1437 | 1443 | switch (current_cpu_type()) { |
| 1438 | 1444 | case CPU_24K: |
| 1439 | 1445 | if (IS_BOTH_COUNTERS_24K_EVENT(base_id)) |
| @@ -1483,6 +1489,19 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) · 43 unmodified lines | ||
| 1483 | 1489 | raw_id > 127 ? CNTR_ODD : CNTR_EVEN; |
| 1484 | 1490 | #ifdef CONFIG_MIPS_MT_SMP |
| 1485 | 1491 | raw_event.range = P; |
| 1492 | +#endif | |
| 1493 | + break; | |
| 1494 | + case CPU_P5600: | |
| 1495 | + /* 8-bit event numbers */ | |
| 1496 | + raw_id = config & 0x1ff; | |
| 1497 | + base_id = raw_id & 0xff; | |
| 1498 | + if (IS_BOTH_COUNTERS_P5600_EVENT(base_id)) | |
| 1499 | + raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; | |
| 1500 | + else | |
| 1501 | + raw_event.cntr_mask = | |
| 1502 | + raw_id > 255 ? CNTR_ODD : CNTR_EVEN; | |
| 1503 | +#ifdef CONFIG_MIPS_MT_SMP | |
| 1504 | + raw_event.range = P; | |
| 1486 | 1505 | #endif |
| 1487 | 1506 | break; |
| 1488 | 1507 | case CPU_1004K: |
| @@ -1523,6 +1542,8 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) · 34 unmodified lines | ||
| 1523 | 1542 | raw_id > 127 ? CNTR_ODD : CNTR_EVEN; |
| 1524 | 1543 | } |
| 1525 | 1544 | |
| 1545 | + raw_event.event_id = base_id; | |
| 1546 | + | |
| 1526 | 1547 | return &raw_event; |
| 1527 | 1548 | } |
| 1528 | 1549 | |
| @@ -1633,6 +1654,11 @@ init_hw_perf_events(void) · 104 unmodified lines | ||
| 1633 | 1654 | mipspmu.general_event_map = &mipsxxcore_event_map2; |
| 1634 | 1655 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; |
| 1635 | 1656 | break; |
| 1657 | + case CPU_P5600: | |
| 1658 | + mipspmu.name = "mips/P5600"; | |
| 1659 | + mipspmu.general_event_map = &mipsxxcore_event_map2; | |
| 1660 | + mipspmu.cache_event_map = &mipsxxcore_cache_map2; | |
| 1661 | + break; | |
| 1636 | 1662 | case CPU_1004K: |
| 1637 | 1663 | mipspmu.name = "mips/1004K"; |
| 1638 | 1664 | mipspmu.general_event_map = &mipsxxcore_event_map; |
| @@ -149,8 +149,12 @@ int cps_pm_enter_state(enum cps_pm_state state) · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | /* Setup the VPE to run mips_cps_pm_restore when started again */ |
| 151 | 151 | if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) { |
| 152 | + /* Power gating relies upon CPS SMP */ | |
| 153 | + if (!mips_cps_smp_in_use()) | |
| 154 | + return -EINVAL; | |
| 155 | + | |
| 152 | 156 | core_cfg = &mips_cps_core_bootcfg[core]; |
| 153 | − vpe_cfg = &core_cfg->vpe_config[current_cpu_data.vpe_id]; | |
| 157 | + vpe_cfg = &core_cfg->vpe_config[cpu_vpe_id(¤t_cpu_data)]; | |
| 154 | 158 | vpe_cfg->pc = (unsigned long)mips_cps_pm_restore; |
| 155 | 159 | vpe_cfg->gp = (unsigned long)current_thread_info(); |
| 156 | 160 | vpe_cfg->sp = 0; |
| @@ -376,6 +380,10 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) · 219 unmodified lines | ||
| 376 | 380 | memset(relocs, 0, sizeof(relocs)); |
| 377 | 381 | |
| 378 | 382 | if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) { |
| 383 | + /* Power gating relies upon CPS SMP */ | |
| 384 | + if (!mips_cps_smp_in_use()) | |
| 385 | + goto out_err; | |
| 386 | + | |
| 379 | 387 | /* |
| 380 | 388 | * Save CPU state. Note the non-standard calling convention |
| 381 | 389 | * with the return address placed in v0 to avoid clobbering |
| @@ -113,6 +113,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) · 112 unmodified lines | ||
| 113 | 113 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); |
| 114 | 114 | if (cpu_has_msa) seq_printf(m, "%s", " msa"); |
| 115 | 115 | if (cpu_has_eva) seq_printf(m, "%s", " eva"); |
| 116 | + if (cpu_has_htw) seq_printf(m, "%s", " htw"); | |
| 116 | 117 | seq_printf(m, "\n"); |
| 117 | 118 | |
| 118 | 119 | if (cpu_has_mmips) { |
| @@ -123,6 +124,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) · 4 unmodified lines | ||
| 123 | 124 | cpu_data[n].srsets); |
| 124 | 125 | seq_printf(m, "kscratch registers\t: %d\n", |
| 125 | 126 | hweight8(cpu_data[n].kscratch_mask)); |
| 127 | + seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); | |
| 126 | 128 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); |
| 127 | 129 | |
| 128 | 130 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/mman.h> |
| 22 | 22 | #include <linux/personality.h> |
| 23 | 23 | #include <linux/sys.h> |
| 24 | −#include <linux/user.h> | |
| 25 | 24 | #include <linux/init.h> |
| 26 | 25 | #include <linux/completion.h> |
| 27 | 26 | #include <linux/kallsyms.h> |
| @@ -36,6 +35,7 @@ · 8 unmodified lines | ||
| 36 | 35 | #include <asm/pgtable.h> |
| 37 | 36 | #include <asm/mipsregs.h> |
| 38 | 37 | #include <asm/processor.h> |
| 38 | +#include <asm/reg.h> | |
| 39 | 39 | #include <asm/uaccess.h> |
| 40 | 40 | #include <asm/io.h> |
| 41 | 41 | #include <asm/elf.h> |
| @@ -66,6 +66,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) · 24 unmodified lines | ||
| 66 | 66 | clear_used_math(); |
| 67 | 67 | clear_fpu_owner(); |
| 68 | 68 | init_dsp(); |
| 69 | + clear_thread_flag(TIF_USEDMSA); | |
| 69 | 70 | clear_thread_flag(TIF_MSA_CTX_LIVE); |
| 70 | 71 | disable_msa(); |
| 71 | 72 | regs->cp0_epc = pc; |
| @@ -141,6 +142,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, · 69 unmodified lines | ||
| 141 | 142 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); |
| 142 | 143 | |
| 143 | 144 | clear_tsk_thread_flag(p, TIF_USEDFPU); |
| 145 | + clear_tsk_thread_flag(p, TIF_USEDMSA); | |
| 146 | + clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); | |
| 144 | 147 | |
| 145 | 148 | #ifdef CONFIG_MIPS_MT_FPAFF |
| 146 | 149 | clear_tsk_thread_flag(p, TIF_FPUBOUND); |
| @@ -152,61 +155,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, · 5 unmodified lines | ||
| 152 | 155 | return 0; |
| 153 | 156 | } |
| 154 | 157 | |
| 155 | −/* Fill in the fpu structure for a core dump.. */ | |
| 156 | −int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) | |
| 157 | −{ | |
| 158 | − int i; | |
| 159 | − | |
| 160 | − for (i = 0; i < NUM_FPU_REGS; i++) | |
| 161 | − memcpy(&r[i], ¤t->thread.fpu.fpr[i], sizeof(*r)); | |
| 162 | − | |
| 163 | − memcpy(&r[NUM_FPU_REGS], ¤t->thread.fpu.fcr31, | |
| 164 | − sizeof(current->thread.fpu.fcr31)); | |
| 165 | − | |
| 166 | − return 1; | |
| 167 | −} | |
| 168 | − | |
| 169 | −void elf_dump_regs(elf_greg_t *gp, struct pt_regs *regs) | |
| 170 | −{ | |
| 171 | − int i; | |
| 172 | − | |
| 173 | − for (i = 0; i < EF_R0; i++) | |
| 174 | − gp[i] = 0; | |
| 175 | − gp[EF_R0] = 0; | |
| 176 | − for (i = 1; i <= 31; i++) | |
| 177 | − gp[EF_R0 + i] = regs->regs[i]; | |
| 178 | − gp[EF_R26] = 0; | |
| 179 | − gp[EF_R27] = 0; | |
| 180 | − gp[EF_LO] = regs->lo; | |
| 181 | − gp[EF_HI] = regs->hi; | |
| 182 | − gp[EF_CP0_EPC] = regs->cp0_epc; | |
| 183 | − gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr; | |
| 184 | − gp[EF_CP0_STATUS] = regs->cp0_status; | |
| 185 | − gp[EF_CP0_CAUSE] = regs->cp0_cause; | |
| 186 | −#ifdef EF_UNUSED0 | |
| 187 | − gp[EF_UNUSED0] = 0; | |
| 188 | −#endif | |
| 189 | −} | |
| 190 | − | |
| 191 | −int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) | |
| 192 | −{ | |
| 193 | − elf_dump_regs(*regs, task_pt_regs(tsk)); | |
| 194 | − return 1; | |
| 195 | −} | |
| 196 | − | |
| 197 | −int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr) | |
| 198 | −{ | |
| 199 | − int i; | |
| 200 | − | |
| 201 | − for (i = 0; i < NUM_FPU_REGS; i++) | |
| 202 | − memcpy(&fpr[i], &t->thread.fpu.fpr[i], sizeof(*fpr)); | |
| 203 | − | |
| 204 | − memcpy(&fpr[NUM_FPU_REGS], &t->thread.fpu.fcr31, | |
| 205 | − sizeof(t->thread.fpu.fcr31)); | |
| 206 | − | |
| 207 | − return 1; | |
| 208 | −} | |
| 209 | − | |
| 210 | 158 | #ifdef CONFIG_CC_STACKPROTECTOR |
| 211 | 159 | #include <linux/stackprotector.h> |
| 212 | 160 | unsigned long __stack_chk_guard __read_mostly; |
| @@ -24,7 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/ptrace.h> |
| 25 | 25 | #include <linux/regset.h> |
| 26 | 26 | #include <linux/smp.h> |
| 27 | −#include <linux/user.h> | |
| 28 | 27 | #include <linux/security.h> |
| 29 | 28 | #include <linux/tracehook.h> |
| 30 | 29 | #include <linux/audit.h> |
| @@ -63,7 +62,7 @@ void ptrace_disable(struct task_struct *child) · 32 unmodified lines | ||
| 63 | 62 | * for 32-bit kernels and for 32-bit processes on a 64-bit kernel. |
| 64 | 63 | * Registers are sign extended to fill the available space. |
| 65 | 64 | */ |
| 66 | −int ptrace_getregs(struct task_struct *child, __s64 __user *data) | |
| 65 | +int ptrace_getregs(struct task_struct *child, struct user_pt_regs __user *data) | |
| 67 | 66 | { |
| 68 | 67 | struct pt_regs *regs; |
| 69 | 68 | int i; |
| @@ -74,13 +73,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data) · 4 unmodified lines | ||
| 74 | 73 | regs = task_pt_regs(child); |
| 75 | 74 | |
| 76 | 75 | for (i = 0; i < 32; i++) |
| 77 | − __put_user((long)regs->regs[i], data + i); | |
| 78 | − __put_user((long)regs->lo, data + EF_LO - EF_R0); | |
| 79 | − __put_user((long)regs->hi, data + EF_HI - EF_R0); | |
| 80 | − __put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0); | |
| 81 | − __put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0); | |
| 82 | − __put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0); | |
| 83 | − __put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0); | |
| 76 | + __put_user((long)regs->regs[i], (__s64 __user *)&data->regs[i]); | |
| 77 | + __put_user((long)regs->lo, (__s64 __user *)&data->lo); | |
| 78 | + __put_user((long)regs->hi, (__s64 __user *)&data->hi); | |
| 79 | + __put_user((long)regs->cp0_epc, (__s64 __user *)&data->cp0_epc); | |
| 80 | + __put_user((long)regs->cp0_badvaddr, (__s64 __user *)&data->cp0_badvaddr); | |
| 81 | + __put_user((long)regs->cp0_status, (__s64 __user *)&data->cp0_status); | |
| 82 | + __put_user((long)regs->cp0_cause, (__s64 __user *)&data->cp0_cause); | |
| 84 | 83 | |
| 85 | 84 | return 0; |
| 86 | 85 | } |
| @@ -90,7 +89,7 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data) · 3 unmodified lines | ||
| 90 | 89 | * the 64-bit format. On a 32-bit kernel only the lower order half |
| 91 | 90 | * (according to endianness) will be used. |
| 92 | 91 | */ |
| 93 | −int ptrace_setregs(struct task_struct *child, __s64 __user *data) | |
| 92 | +int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data) | |
| 94 | 93 | { |
| 95 | 94 | struct pt_regs *regs; |
| 96 | 95 | int i; |
| @@ -101,10 +100,10 @@ int ptrace_setregs(struct task_struct *child, __s64 __user *data) · 4 unmodified lines | ||
| 101 | 100 | regs = task_pt_regs(child); |
| 102 | 101 | |
| 103 | 102 | for (i = 0; i < 32; i++) |
| 104 | − __get_user(regs->regs[i], data + i); | |
| 105 | − __get_user(regs->lo, data + EF_LO - EF_R0); | |
| 106 | − __get_user(regs->hi, data + EF_HI - EF_R0); | |
| 107 | − __get_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0); | |
| 103 | + __get_user(regs->regs[i], (__s64 __user *)&data->regs[i]); | |
| 104 | + __get_user(regs->lo, (__s64 __user *)&data->lo); | |
| 105 | + __get_user(regs->hi, (__s64 __user *)&data->hi); | |
| 106 | + __get_user(regs->cp0_epc, (__s64 __user *)&data->cp0_epc); | |
| 108 | 107 | |
| 109 | 108 | /* badvaddr, status, and cause may not be written. */ |
| 110 | 109 | |
| @@ -129,7 +128,7 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data) · 18 unmodified lines | ||
| 129 | 128 | } |
| 130 | 129 | |
| 131 | 130 | __put_user(child->thread.fpu.fcr31, data + 64); |
| 132 | − __put_user(current_cpu_data.fpu_id, data + 65); | |
| 131 | + __put_user(boot_cpu_data.fpu_id, data + 65); | |
| 133 | 132 | |
| 134 | 133 | return 0; |
| 135 | 134 | } |
| @@ -151,6 +150,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) · 15 unmodified lines | ||
| 151 | 150 | } |
| 152 | 151 | |
| 153 | 152 | __get_user(child->thread.fpu.fcr31, data + 64); |
| 153 | + child->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; | |
| 154 | 154 | |
| 155 | 155 | /* FIR may not be written. */ |
| 156 | 156 | |
| @@ -246,36 +246,160 @@ int ptrace_set_watch_regs(struct task_struct *child, · 89 unmodified lines | ||
| 246 | 246 | |
| 247 | 247 | /* regset get/set implementations */ |
| 248 | 248 | |
| 249 | −static int gpr_get(struct task_struct *target, | |
| 250 | − const struct user_regset *regset, | |
| 251 | − unsigned int pos, unsigned int count, | |
| 252 | − void *kbuf, void __user *ubuf) | |
| 249 | +#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) | |
| 250 | + | |
| 251 | +static int gpr32_get(struct task_struct *target, | |
| 252 | + const struct user_regset *regset, | |
| 253 | + unsigned int pos, unsigned int count, | |
| 254 | + void *kbuf, void __user *ubuf) | |
| 253 | 255 | { |
| 254 | 256 | struct pt_regs *regs = task_pt_regs(target); |
| 257 | + u32 uregs[ELF_NGREG] = {}; | |
| 258 | + unsigned i; | |
| 259 | + | |
| 260 | + for (i = MIPS32_EF_R1; i <= MIPS32_EF_R31; i++) { | |
| 261 | + /* k0/k1 are copied as zero. */ | |
| 262 | + if (i == MIPS32_EF_R26 || i == MIPS32_EF_R27) | |
| 263 | + continue; | |
| 264 | + | |
| 265 | + uregs[i] = regs->regs[i - MIPS32_EF_R0]; | |
| 266 | + } | |
| 255 | 267 | |
| 256 | − return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | |
| 257 | − regs, 0, sizeof(*regs)); | |
| 268 | + uregs[MIPS32_EF_LO] = regs->lo; | |
| 269 | + uregs[MIPS32_EF_HI] = regs->hi; | |
| 270 | + uregs[MIPS32_EF_CP0_EPC] = regs->cp0_epc; | |
| 271 | + uregs[MIPS32_EF_CP0_BADVADDR] = regs->cp0_badvaddr; | |
| 272 | + uregs[MIPS32_EF_CP0_STATUS] = regs->cp0_status; | |
| 273 | + uregs[MIPS32_EF_CP0_CAUSE] = regs->cp0_cause; | |
| 274 | + | |
| 275 | + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, | |
| 276 | + sizeof(uregs)); | |
| 258 | 277 | } |
| 259 | 278 | |
| 260 | −static int gpr_set(struct task_struct *target, | |
| 261 | − const struct user_regset *regset, | |
| 262 | − unsigned int pos, unsigned int count, | |
| 263 | − const void *kbuf, const void __user *ubuf) | |
| 279 | +static int gpr32_set(struct task_struct *target, | |
| 280 | + const struct user_regset *regset, | |
| 281 | + unsigned int pos, unsigned int count, | |
| 282 | + const void *kbuf, const void __user *ubuf) | |
| 264 | 283 | { |
| 265 | − struct pt_regs newregs; | |
| 266 | − int ret; | |
| 284 | + struct pt_regs *regs = task_pt_regs(target); | |
| 285 | + u32 uregs[ELF_NGREG]; | |
| 286 | + unsigned start, num_regs, i; | |
| 287 | + int err; | |
| 288 | + | |
| 289 | + start = pos / sizeof(u32); | |
| 290 | + num_regs = count / sizeof(u32); | |
| 291 | + | |
| 292 | + if (start + num_regs > ELF_NGREG) | |
| 293 | + return -EIO; | |
| 294 | + | |
| 295 | + err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, | |
| 296 | + sizeof(uregs)); | |
| 297 | + if (err) | |
| 298 | + return err; | |
| 299 | + | |
| 300 | + for (i = start; i < num_regs; i++) { | |
| 301 | + /* | |
| 302 | + * Cast all values to signed here so that if this is a 64-bit | |
| 303 | + * kernel, the supplied 32-bit values will be sign extended. | |
| 304 | + */ | |
| 305 | + switch (i) { | |
| 306 | + case MIPS32_EF_R1 ... MIPS32_EF_R25: | |
| 307 | + /* k0/k1 are ignored. */ | |
| 308 | + case MIPS32_EF_R28 ... MIPS32_EF_R31: | |
| 309 | + regs->regs[i - MIPS32_EF_R0] = (s32)uregs[i]; | |
| 310 | + break; | |
| 311 | + case MIPS32_EF_LO: | |
| 312 | + regs->lo = (s32)uregs[i]; | |
| 313 | + break; | |
| 314 | + case MIPS32_EF_HI: | |
| 315 | + regs->hi = (s32)uregs[i]; | |
| 316 | + break; | |
| 317 | + case MIPS32_EF_CP0_EPC: | |
| 318 | + regs->cp0_epc = (s32)uregs[i]; | |
| 319 | + break; | |
| 320 | + } | |
| 321 | + } | |
| 322 | + | |
| 323 | + return 0; | |
| 324 | +} | |
| 325 | + | |
| 326 | +#endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ | |
| 327 | + | |
| 328 | +#ifdef CONFIG_64BIT | |
| 329 | + | |
| 330 | +static int gpr64_get(struct task_struct *target, | |
| 331 | + const struct user_regset *regset, | |
| 332 | + unsigned int pos, unsigned int count, | |
| 333 | + void *kbuf, void __user *ubuf) | |
| 334 | +{ | |
| 335 | + struct pt_regs *regs = task_pt_regs(target); | |
| 336 | + u64 uregs[ELF_NGREG] = {}; | |
| 337 | + unsigned i; | |
| 338 | + | |
| 339 | + for (i = MIPS64_EF_R1; i <= MIPS64_EF_R31; i++) { | |
| 340 | + /* k0/k1 are copied as zero. */ | |
| 341 | + if (i == MIPS64_EF_R26 || i == MIPS64_EF_R27) | |
| 342 | + continue; | |
| 343 | + | |
| 344 | + uregs[i] = regs->regs[i - MIPS64_EF_R0]; | |
| 345 | + } | |
| 346 | + | |
| 347 | + uregs[MIPS64_EF_LO] = regs->lo; | |
| 348 | + uregs[MIPS64_EF_HI] = regs->hi; | |
| 349 | + uregs[MIPS64_EF_CP0_EPC] = regs->cp0_epc; | |
| 350 | + uregs[MIPS64_EF_CP0_BADVADDR] = regs->cp0_badvaddr; | |
| 351 | + uregs[MIPS64_EF_CP0_STATUS] = regs->cp0_status; | |
| 352 | + uregs[MIPS64_EF_CP0_CAUSE] = regs->cp0_cause; | |
| 353 | + | |
| 354 | + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, | |
| 355 | + sizeof(uregs)); | |
| 356 | +} | |
| 267 | 357 | |
| 268 | − ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | |
| 269 | − &newregs, | |
| 270 | − 0, sizeof(newregs)); | |
| 271 | − if (ret) | |
| 272 | − return ret; | |
| 358 | +static int gpr64_set(struct task_struct *target, | |
| 359 | + const struct user_regset *regset, | |
| 360 | + unsigned int pos, unsigned int count, | |
| 361 | + const void *kbuf, const void __user *ubuf) | |
| 362 | +{ | |
| 363 | + struct pt_regs *regs = task_pt_regs(target); | |
| 364 | + u64 uregs[ELF_NGREG]; | |
| 365 | + unsigned start, num_regs, i; | |
| 366 | + int err; | |
| 367 | + | |
| 368 | + start = pos / sizeof(u64); | |
| 369 | + num_regs = count / sizeof(u64); | |
| 273 | 370 | |
| 274 | − *task_pt_regs(target) = newregs; | |
| 371 | + if (start + num_regs > ELF_NGREG) | |
| 372 | + return -EIO; | |
| 373 | + | |
| 374 | + err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, | |
| 375 | + sizeof(uregs)); | |
| 376 | + if (err) | |
| 377 | + return err; | |
| 378 | + | |
| 379 | + for (i = start; i < num_regs; i++) { | |
| 380 | + switch (i) { | |
| 381 | + case MIPS64_EF_R1 ... MIPS64_EF_R25: | |
| 382 | + /* k0/k1 are ignored. */ | |
| 383 | + case MIPS64_EF_R28 ... MIPS64_EF_R31: | |
| 384 | + regs->regs[i - MIPS64_EF_R0] = uregs[i]; | |
| 385 | + break; | |
| 386 | + case MIPS64_EF_LO: | |
| 387 | + regs->lo = uregs[i]; | |
| 388 | + break; | |
| 389 | + case MIPS64_EF_HI: | |
| 390 | + regs->hi = uregs[i]; | |
| 391 | + break; | |
| 392 | + case MIPS64_EF_CP0_EPC: | |
| 393 | + regs->cp0_epc = uregs[i]; | |
| 394 | + break; | |
| 395 | + } | |
| 396 | + } | |
| 275 | 397 | |
| 276 | 398 | return 0; |
| 277 | 399 | } |
| 278 | 400 | |
| 401 | +#endif /* CONFIG_64BIT */ | |
| 402 | + | |
| 279 | 403 | static int fpr_get(struct task_struct *target, |
| 280 | 404 | const struct user_regset *regset, |
| 281 | 405 | unsigned int pos, unsigned int count, |
| @@ -337,14 +461,16 @@ enum mips_regset { · 55 unmodified lines | ||
| 337 | 461 | REGSET_FPR, |
| 338 | 462 | }; |
| 339 | 463 | |
| 464 | +#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) | |
| 465 | + | |
| 340 | 466 | static const struct user_regset mips_regsets[] = { |
| 341 | 467 | [REGSET_GPR] = { |
| 342 | 468 | .core_note_type = NT_PRSTATUS, |
| 343 | 469 | .n = ELF_NGREG, |
| 344 | 470 | .size = sizeof(unsigned int), |
| 345 | 471 | .align = sizeof(unsigned int), |
| 346 | − .get = gpr_get, | |
| 347 | − .set = gpr_set, | |
| 472 | + .get = gpr32_get, | |
| 473 | + .set = gpr32_set, | |
| 348 | 474 | }, |
| 349 | 475 | [REGSET_FPR] = { |
| 350 | 476 | .core_note_type = NT_PRFPREG, |
| @@ -364,14 +490,18 @@ static const struct user_regset_view user_mips_view = { · 13 unmodified lines | ||
| 364 | 490 | .n = ARRAY_SIZE(mips_regsets), |
| 365 | 491 | }; |
| 366 | 492 | |
| 493 | +#endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ | |
| 494 | + | |
| 495 | +#ifdef CONFIG_64BIT | |
| 496 | + | |
| 367 | 497 | static const struct user_regset mips64_regsets[] = { |
| 368 | 498 | [REGSET_GPR] = { |
| 369 | 499 | .core_note_type = NT_PRSTATUS, |
| 370 | 500 | .n = ELF_NGREG, |
| 371 | 501 | .size = sizeof(unsigned long), |
| 372 | 502 | .align = sizeof(unsigned long), |
| 373 | − .get = gpr_get, | |
| 374 | − .set = gpr_set, | |
| 503 | + .get = gpr64_get, | |
| 504 | + .set = gpr64_set, | |
| 375 | 505 | }, |
| 376 | 506 | [REGSET_FPR] = { |
| 377 | 507 | .core_note_type = NT_PRFPREG, |
| @@ -384,25 +514,26 @@ static const struct user_regset mips64_regsets[] = { · 6 unmodified lines | ||
| 384 | 514 | }; |
| 385 | 515 | |
| 386 | 516 | static const struct user_regset_view user_mips64_view = { |
| 387 | − .name = "mips", | |
| 517 | + .name = "mips64", | |
| 388 | 518 | .e_machine = ELF_ARCH, |
| 389 | 519 | .ei_osabi = ELF_OSABI, |
| 390 | 520 | .regsets = mips64_regsets, |
| 391 | − .n = ARRAY_SIZE(mips_regsets), | |
| 521 | + .n = ARRAY_SIZE(mips64_regsets), | |
| 392 | 522 | }; |
| 393 | 523 | |
| 524 | +#endif /* CONFIG_64BIT */ | |
| 525 | + | |
| 394 | 526 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) |
| 395 | 527 | { |
| 396 | 528 | #ifdef CONFIG_32BIT |
| 397 | 529 | return &user_mips_view; |
| 398 | −#endif | |
| 399 | − | |
| 530 | +#else | |
| 400 | 531 | #ifdef CONFIG_MIPS32_O32 |
| 401 | − if (test_thread_flag(TIF_32BIT_REGS)) | |
| 402 | − return &user_mips_view; | |
| 532 | + if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) | |
| 533 | + return &user_mips_view; | |
| 403 | 534 | #endif |
| 404 | − | |
| 405 | 535 | return &user_mips64_view; |
| 536 | +#endif | |
| 406 | 537 | } |
| 407 | 538 | |
| 408 | 539 | long arch_ptrace(struct task_struct *child, long request, |
| @@ -480,7 +611,7 @@ long arch_ptrace(struct task_struct *child, long request, · 71 unmodified lines | ||
| 480 | 611 | break; |
| 481 | 612 | case FPC_EIR: |
| 482 | 613 | /* implementation / version register */ |
| 483 | − tmp = current_cpu_data.fpu_id; | |
| 614 | + tmp = boot_cpu_data.fpu_id; | |
| 484 | 615 | break; |
| 485 | 616 | case DSP_BASE ... DSP_BASE + 5: { |
| 486 | 617 | dspreg_t *dregs; |
| @@ -565,7 +696,7 @@ long arch_ptrace(struct task_struct *child, long request, · 78 unmodified lines | ||
| 565 | 696 | break; |
| 566 | 697 | #endif |
| 567 | 698 | case FPC_CSR: |
| 568 | − child->thread.fpu.fcr31 = data; | |
| 699 | + child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X; | |
| 569 | 700 | break; |
| 570 | 701 | case DSP_BASE ... DSP_BASE + 5: { |
| 571 | 702 | dspreg_t *dregs; |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/errno.h> |
| 23 | 23 | #include <linux/ptrace.h> |
| 24 | 24 | #include <linux/smp.h> |
| 25 | −#include <linux/user.h> | |
| 26 | 25 | #include <linux/security.h> |
| 27 | 26 | |
| 28 | 27 | #include <asm/cpu.h> |
| @@ -32,6 +31,7 @@ · 3 unmodified lines | ||
| 32 | 31 | #include <asm/mipsmtregs.h> |
| 33 | 32 | #include <asm/pgtable.h> |
| 34 | 33 | #include <asm/page.h> |
| 34 | +#include <asm/reg.h> | |
| 35 | 35 | #include <asm/uaccess.h> |
| 36 | 36 | #include <asm/bootinfo.h> |
| 37 | 37 | |
| @@ -129,7 +129,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, · 91 unmodified lines | ||
| 129 | 129 | break; |
| 130 | 130 | case FPC_EIR: |
| 131 | 131 | /* implementation / version register */ |
| 132 | − tmp = current_cpu_data.fpu_id; | |
| 132 | + tmp = boot_cpu_data.fpu_id; | |
| 133 | 133 | break; |
| 134 | 134 | case DSP_BASE ... DSP_BASE + 5: { |
| 135 | 135 | dspreg_t *dregs; |
| @@ -256,11 +256,13 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, · 120 unmodified lines | ||
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | case PTRACE_GETREGS: |
| 259 | − ret = ptrace_getregs(child, (__s64 __user *) (__u64) data); | |
| 259 | + ret = ptrace_getregs(child, | |
| 260 | + (struct user_pt_regs __user *) (__u64) data); | |
| 260 | 261 | break; |
| 261 | 262 | |
| 262 | 263 | case PTRACE_SETREGS: |
| 263 | − ret = ptrace_setregs(child, (__s64 __user *) (__u64) data); | |
| 264 | + ret = ptrace_setregs(child, | |
| 265 | + (struct user_pt_regs __user *) (__u64) data); | |
| 264 | 266 | break; |
| 265 | 267 | |
| 266 | 268 | case PTRACE_GETFPREGS: |
| @@ -64,8 +64,10 @@ · 63 unmodified lines | ||
| 64 | 64 | /* Check whether we're saving scalar or vector context. */ |
| 65 | 65 | bgtz a3, 1f |
| 66 | 66 | |
| 67 | − /* Save 128b MSA vector context. */ | |
| 67 | + /* Save 128b MSA vector context + scalar FP control & status. */ | |
| 68 | + cfc1 t1, fcr31 | |
| 68 | 69 | msa_save_all a0 |
| 70 | + sw t1, THREAD_FCR31(a0) | |
| 69 | 71 | b 2f |
| 70 | 72 | |
| 71 | 73 | 1: /* Save 32b/64b scalar FP context. */ |
| @@ -142,6 +144,11 @@ LEAF(_restore_msa) · 70 unmodified lines | ||
| 142 | 144 | jr ra |
| 143 | 145 | END(_restore_msa) |
| 144 | 146 | |
| 147 | +LEAF(_init_msa_upper) | |
| 148 | + msa_init_all_upper | |
| 149 | + jr ra | |
| 150 | + END(_init_msa_upper) | |
| 151 | + | |
| 145 | 152 | #endif |
| 146 | 153 | |
| 147 | 154 | /* |
| @@ -77,6 +77,9 @@ int __init rtlx_module_init(void) · 76 unmodified lines | ||
| 77 | 77 | dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, |
| 78 | 78 | "%s%d", RTLX_MODULE_NAME, i); |
| 79 | 79 | if (IS_ERR(dev)) { |
| 80 | + while (i--) | |
| 81 | + device_destroy(mt_class, MKDEV(major, i)); | |
| 82 | + | |
| 80 | 83 | err = PTR_ERR(dev); |
| 81 | 84 | goto out_chrdev; |
| 82 | 85 | } |
| @@ -103,6 +103,9 @@ int __init rtlx_module_init(void) · 102 unmodified lines | ||
| 103 | 103 | dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, |
| 104 | 104 | "%s%d", RTLX_MODULE_NAME, i); |
| 105 | 105 | if (IS_ERR(dev)) { |
| 106 | + while (i--) | |
| 107 | + device_destroy(mt_class, MKDEV(major, i)); | |
| 108 | + | |
| 106 | 109 | err = PTR_ERR(dev); |
| 107 | 110 | goto out_chrdev; |
| 108 | 111 | } |
| @@ -67,8 +67,6 @@ NESTED(handle_sys, PT_SIZE, sp) · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | /* |
| 69 | 69 | * Ok, copy the args from the luser stack to the kernel stack. |
| 70 | − * t3 is the precomputed number of instruction bytes needed to | |
| 71 | − * load or store arguments 6-8. | |
| 72 | 70 | */ |
| 73 | 71 | |
| 74 | 72 | .set push |
| @@ -495,8 +493,8 @@ EXPORT(sys_call_table) · 420 unmodified lines | ||
| 495 | 493 | PTR sys_tgkill |
| 496 | 494 | PTR sys_utimes |
| 497 | 495 | PTR sys_mbind |
| 498 | − PTR sys_ni_syscall /* sys_get_mempolicy */ | |
| 499 | − PTR sys_ni_syscall /* 4270 sys_set_mempolicy */ | |
| 496 | + PTR sys_get_mempolicy | |
| 497 | + PTR sys_set_mempolicy /* 4270 */ | |
| 500 | 498 | PTR sys_mq_open |
| 501 | 499 | PTR sys_mq_unlink |
| 502 | 500 | PTR sys_mq_timedsend |
| @@ -347,8 +347,8 @@ EXPORT(sys_call_table) · 346 unmodified lines | ||
| 347 | 347 | PTR sys_tgkill /* 5225 */ |
| 348 | 348 | PTR sys_utimes |
| 349 | 349 | PTR sys_mbind |
| 350 | − PTR sys_ni_syscall /* sys_get_mempolicy */ | |
| 351 | − PTR sys_ni_syscall /* sys_set_mempolicy */ | |
| 350 | + PTR sys_get_mempolicy | |
| 351 | + PTR sys_set_mempolicy | |
| 352 | 352 | PTR sys_mq_open /* 5230 */ |
| 353 | 353 | PTR sys_mq_unlink |
| 354 | 354 | PTR sys_mq_timedsend |
| @@ -162,7 +162,7 @@ EXPORT(sysn32_call_table) · 161 unmodified lines | ||
| 162 | 162 | PTR sys_getpeername |
| 163 | 163 | PTR sys_socketpair |
| 164 | 164 | PTR compat_sys_setsockopt |
| 165 | − PTR sys_getsockopt | |
| 165 | + PTR compat_sys_getsockopt | |
| 166 | 166 | PTR __sys_clone /* 6055 */ |
| 167 | 167 | PTR __sys_fork |
| 168 | 168 | PTR compat_sys_execve |
| @@ -339,9 +339,9 @@ EXPORT(sysn32_call_table) · 170 unmodified lines | ||
| 339 | 339 | PTR compat_sys_clock_nanosleep |
| 340 | 340 | PTR sys_tgkill |
| 341 | 341 | PTR compat_sys_utimes /* 6230 */ |
| 342 | − PTR sys_ni_syscall /* sys_mbind */ | |
| 343 | − PTR sys_ni_syscall /* sys_get_mempolicy */ | |
| 344 | − PTR sys_ni_syscall /* sys_set_mempolicy */ | |
| 342 | + PTR compat_sys_mbind | |
| 343 | + PTR compat_sys_get_mempolicy | |
| 344 | + PTR compat_sys_set_mempolicy | |
| 345 | 345 | PTR compat_sys_mq_open |
| 346 | 346 | PTR sys_mq_unlink /* 6235 */ |
| 347 | 347 | PTR compat_sys_mq_timedsend |
| @@ -358,7 +358,7 @@ EXPORT(sysn32_call_table) · 10 unmodified lines | ||
| 358 | 358 | PTR sys_inotify_init |
| 359 | 359 | PTR sys_inotify_add_watch |
| 360 | 360 | PTR sys_inotify_rm_watch |
| 361 | − PTR sys_migrate_pages /* 6250 */ | |
| 361 | + PTR compat_sys_migrate_pages /* 6250 */ | |
| 362 | 362 | PTR sys_openat |
| 363 | 363 | PTR sys_mkdirat |
| 364 | 364 | PTR sys_mknodat |
| @@ -379,7 +379,7 @@ EXPORT(sysn32_call_table) · 14 unmodified lines | ||
| 379 | 379 | PTR sys_sync_file_range |
| 380 | 380 | PTR sys_tee |
| 381 | 381 | PTR compat_sys_vmsplice /* 6270 */ |
| 382 | − PTR sys_move_pages | |
| 382 | + PTR compat_sys_move_pages | |
| 383 | 383 | PTR compat_sys_set_robust_list |
| 384 | 384 | PTR compat_sys_get_robust_list |
| 385 | 385 | PTR compat_sys_kexec_load |
| @@ -473,9 +473,9 @@ EXPORT(sys32_call_table) · 472 unmodified lines | ||
| 473 | 473 | PTR compat_sys_clock_nanosleep /* 4265 */ |
| 474 | 474 | PTR sys_tgkill |
| 475 | 475 | PTR compat_sys_utimes |
| 476 | − PTR sys_ni_syscall /* sys_mbind */ | |
| 477 | − PTR sys_ni_syscall /* sys_get_mempolicy */ | |
| 478 | − PTR sys_ni_syscall /* 4270 sys_set_mempolicy */ | |
| 476 | + PTR compat_sys_mbind | |
| 477 | + PTR compat_sys_get_mempolicy | |
| 478 | + PTR compat_sys_set_mempolicy /* 4270 */ | |
| 479 | 479 | PTR compat_sys_mq_open |
| 480 | 480 | PTR sys_mq_unlink |
| 481 | 481 | PTR compat_sys_mq_timedsend |
| @@ -492,7 +492,7 @@ EXPORT(sys32_call_table) · 10 unmodified lines | ||
| 492 | 492 | PTR sys_inotify_init |
| 493 | 493 | PTR sys_inotify_add_watch /* 4285 */ |
| 494 | 494 | PTR sys_inotify_rm_watch |
| 495 | − PTR sys_migrate_pages | |
| 495 | + PTR compat_sys_migrate_pages | |
| 496 | 496 | PTR compat_sys_openat |
| 497 | 497 | PTR sys_mkdirat |
| 498 | 498 | PTR sys_mknodat /* 4290 */ |
| @@ -282,7 +282,7 @@ static unsigned long __init init_initrd(void) · 281 unmodified lines | ||
| 282 | 282 | * Initialize the bootmem allocator. It also setup initrd related data |
| 283 | 283 | * if needed. |
| 284 | 284 | */ |
| 285 | −#ifdef CONFIG_SGI_IP27 | |
| 285 | +#if defined(CONFIG_SGI_IP27) || (defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_NUMA)) | |
| 286 | 286 | |
| 287 | 287 | static void __init bootmem_init(void) |
| 288 | 288 | { |
| @@ -729,6 +729,25 @@ static void __init resource_init(void) · 440 unmodified lines | ||
| 729 | 729 | } |
| 730 | 730 | } |
| 731 | 731 | |
| 732 | +#ifdef CONFIG_SMP | |
| 733 | +static void __init prefill_possible_map(void) | |
| 734 | +{ | |
| 735 | + int i, possible = num_possible_cpus(); | |
| 736 | + | |
| 737 | + if (possible > nr_cpu_ids) | |
| 738 | + possible = nr_cpu_ids; | |
| 739 | + | |
| 740 | + for (i = 0; i < possible; i++) | |
| 741 | + set_cpu_possible(i, true); | |
| 742 | + for (; i < NR_CPUS; i++) | |
| 743 | + set_cpu_possible(i, false); | |
| 744 | + | |
| 745 | + nr_cpu_ids = possible; | |
| 746 | +} | |
| 747 | +#else | |
| 748 | +static inline void prefill_possible_map(void) {} | |
| 749 | +#endif | |
| 750 | + | |
| 732 | 751 | void __init setup_arch(char **cmdline_p) |
| 733 | 752 | { |
| 734 | 753 | cpu_probe(); |
| @@ -752,6 +771,7 @@ void __init setup_arch(char **cmdline_p) · 17 unmodified lines | ||
| 752 | 771 | |
| 753 | 772 | resource_init(); |
| 754 | 773 | plat_smp_setup(); |
| 774 | + prefill_possible_map(); | |
| 755 | 775 | |
| 756 | 776 | cpu_cache_init(); |
| 757 | 777 | } |
| @@ -14,13 +14,14 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/smp.h> |
| 15 | 15 | #include <linux/types.h> |
| 16 | 16 | |
| 17 | −#include <asm/cacheflush.h> | |
| 17 | +#include <asm/bcache.h> | |
| 18 | 18 | #include <asm/gic.h> |
| 19 | 19 | #include <asm/mips-cm.h> |
| 20 | 20 | #include <asm/mips-cpc.h> |
| 21 | 21 | #include <asm/mips_mt.h> |
| 22 | 22 | #include <asm/mipsregs.h> |
| 23 | 23 | #include <asm/pm-cps.h> |
| 24 | +#include <asm/r4kcache.h> | |
| 24 | 25 | #include <asm/smp-cps.h> |
| 25 | 26 | #include <asm/time.h> |
| 26 | 27 | #include <asm/uasm.h> |
| @@ -132,8 +133,11 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) · 105 unmodified lines | ||
| 132 | 133 | entry_code = (u32 *)&mips_cps_core_entry; |
| 133 | 134 | UASM_i_LA(&entry_code, 3, (long)mips_cm_base); |
| 134 | 135 | uasm_i_addiu(&entry_code, 16, 0, cca); |
| 135 | − dma_cache_wback_inv((unsigned long)&mips_cps_core_entry, | |
| 136 | − (void *)entry_code - (void *)&mips_cps_core_entry); | |
| 136 | + blast_dcache_range((unsigned long)&mips_cps_core_entry, | |
| 137 | + (unsigned long)entry_code); | |
| 138 | + bc_wback_inv((unsigned long)&mips_cps_core_entry, | |
| 139 | + (void *)entry_code - (void *)&mips_cps_core_entry); | |
| 140 | + __sync(); | |
| 137 | 141 | |
| 138 | 142 | /* Allocate core boot configuration structs */ |
| 139 | 143 | mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg), |
| @@ -360,7 +364,7 @@ void play_dead(void) · 220 unmodified lines | ||
| 360 | 364 | static void wait_for_sibling_halt(void *ptr_cpu) |
| 361 | 365 | { |
| 362 | 366 | unsigned cpu = (unsigned)ptr_cpu; |
| 363 | − unsigned vpe_id = cpu_data[cpu].vpe_id; | |
| 367 | + unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); | |
| 364 | 368 | unsigned halted; |
| 365 | 369 | unsigned long flags; |
| 366 | 370 | |
| @@ -288,6 +288,7 @@ struct plat_smp_ops vsmp_smp_ops = { · 287 unmodified lines | ||
| 288 | 288 | .prepare_cpus = vsmp_prepare_cpus, |
| 289 | 289 | }; |
| 290 | 290 | |
| 291 | +#ifdef CONFIG_PROC_FS | |
| 291 | 292 | static int proc_cpuinfo_chain_call(struct notifier_block *nfb, |
| 292 | 293 | unsigned long action_unused, void *data) |
| 293 | 294 | { |
| @@ -309,3 +310,4 @@ static int __init proc_cpuinfo_notifier_init(void) · 15 unmodified lines | ||
| 309 | 310 | } |
| 310 | 311 | |
| 311 | 312 | subsys_initcall(proc_cpuinfo_notifier_init); |
| 313 | +#endif | |
| @@ -59,9 +59,16 @@ EXPORT_SYMBOL(smp_num_siblings); · 58 unmodified lines | ||
| 59 | 59 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; |
| 60 | 60 | EXPORT_SYMBOL(cpu_sibling_map); |
| 61 | 61 | |
| 62 | +/* representing the core map of multi-core chips of each logical CPU */ | |
| 63 | +cpumask_t cpu_core_map[NR_CPUS] __read_mostly; | |
| 64 | +EXPORT_SYMBOL(cpu_core_map); | |
| 65 | + | |
| 62 | 66 | /* representing cpus for which sibling maps can be computed */ |
| 63 | 67 | static cpumask_t cpu_sibling_setup_map; |
| 64 | 68 | |
| 69 | +/* representing cpus for which core maps can be computed */ | |
| 70 | +static cpumask_t cpu_core_setup_map; | |
| 71 | + | |
| 65 | 72 | cpumask_t cpu_coherent_mask; |
| 66 | 73 | |
| 67 | 74 | static inline void set_cpu_sibling_map(int cpu) |
| @@ -72,7 +79,8 @@ static inline void set_cpu_sibling_map(int cpu) · 4 unmodified lines | ||
| 72 | 79 | |
| 73 | 80 | if (smp_num_siblings > 1) { |
| 74 | 81 | for_each_cpu_mask(i, cpu_sibling_setup_map) { |
| 75 | − if (cpu_data[cpu].core == cpu_data[i].core) { | |
| 82 | + if (cpu_data[cpu].package == cpu_data[i].package && | |
| 83 | + cpu_data[cpu].core == cpu_data[i].core) { | |
| 76 | 84 | cpu_set(i, cpu_sibling_map[cpu]); |
| 77 | 85 | cpu_set(cpu, cpu_sibling_map[i]); |
| 78 | 86 | } |
| @@ -81,6 +89,20 @@ static inline void set_cpu_sibling_map(int cpu) · 2 unmodified lines | ||
| 81 | 89 | cpu_set(cpu, cpu_sibling_map[cpu]); |
| 82 | 90 | } |
| 83 | 91 | |
| 92 | +static inline void set_cpu_core_map(int cpu) | |
| 93 | +{ | |
| 94 | + int i; | |
| 95 | + | |
| 96 | + cpu_set(cpu, cpu_core_setup_map); | |
| 97 | + | |
| 98 | + for_each_cpu_mask(i, cpu_core_setup_map) { | |
| 99 | + if (cpu_data[cpu].package == cpu_data[i].package) { | |
| 100 | + cpu_set(i, cpu_core_map[cpu]); | |
| 101 | + cpu_set(cpu, cpu_core_map[i]); | |
| 102 | + } | |
| 103 | + } | |
| 104 | +} | |
| 105 | + | |
| 84 | 106 | struct plat_smp_ops *mp_ops; |
| 85 | 107 | EXPORT_SYMBOL(mp_ops); |
| 86 | 108 | |
| @@ -122,6 +144,7 @@ asmlinkage void start_secondary(void) · 35 unmodified lines | ||
| 122 | 144 | set_cpu_online(cpu, true); |
| 123 | 145 | |
| 124 | 146 | set_cpu_sibling_map(cpu); |
| 147 | + set_cpu_core_map(cpu); | |
| 125 | 148 | |
| 126 | 149 | cpu_set(cpu, cpu_callin_map); |
| 127 | 150 | |
| @@ -175,6 +198,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) · 47 unmodified lines | ||
| 175 | 198 | current_thread_info()->cpu = 0; |
| 176 | 199 | mp_ops->prepare_cpus(max_cpus); |
| 177 | 200 | set_cpu_sibling_map(0); |
| 201 | + set_cpu_core_map(0); | |
| 178 | 202 | #ifndef CONFIG_HOTPLUG_CPU |
| 179 | 203 | init_cpu_present(cpu_possible_mask); |
| 180 | 204 | #endif |
| @@ -90,6 +90,7 @@ extern asmlinkage void handle_mt(void); · 89 unmodified lines | ||
| 90 | 90 | extern asmlinkage void handle_dsp(void); |
| 91 | 91 | extern asmlinkage void handle_mcheck(void); |
| 92 | 92 | extern asmlinkage void handle_reserved(void); |
| 93 | +extern void tlb_do_page_fault_0(void); | |
| 93 | 94 | |
| 94 | 95 | void (*board_be_init)(void); |
| 95 | 96 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); |
| @@ -1088,13 +1089,19 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action, · 992 unmodified lines | ||
| 1088 | 1089 | |
| 1089 | 1090 | static int enable_restore_fp_context(int msa) |
| 1090 | 1091 | { |
| 1091 | − int err, was_fpu_owner; | |
| 1092 | + int err, was_fpu_owner, prior_msa; | |
| 1092 | 1093 | |
| 1093 | 1094 | if (!used_math()) { |
| 1094 | 1095 | /* First time FP context user. */ |
| 1096 | + preempt_disable(); | |
| 1095 | 1097 | err = init_fpu(); |
| 1096 | − if (msa && !err) | |
| 1098 | + if (msa && !err) { | |
| 1097 | 1099 | enable_msa(); |
| 1100 | + _init_msa_upper(); | |
| 1101 | + set_thread_flag(TIF_USEDMSA); | |
| 1102 | + set_thread_flag(TIF_MSA_CTX_LIVE); | |
| 1103 | + } | |
| 1104 | + preempt_enable(); | |
| 1098 | 1105 | if (!err) |
| 1099 | 1106 | set_used_math(); |
| 1100 | 1107 | return err; |
| @@ -1134,10 +1141,11 @@ static int enable_restore_fp_context(int msa) · 33 unmodified lines | ||
| 1134 | 1141 | * This task is using or has previously used MSA. Thus we require |
| 1135 | 1142 | * that Status.FR == 1. |
| 1136 | 1143 | */ |
| 1144 | + preempt_disable(); | |
| 1137 | 1145 | was_fpu_owner = is_fpu_owner(); |
| 1138 | − err = own_fpu(0); | |
| 1146 | + err = own_fpu_inatomic(0); | |
| 1139 | 1147 | if (err) |
| 1140 | − return err; | |
| 1148 | + goto out; | |
| 1141 | 1149 | |
| 1142 | 1150 | enable_msa(); |
| 1143 | 1151 | write_msa_csr(current->thread.fpu.msacsr); |
| @@ -1146,13 +1154,42 @@ static int enable_restore_fp_context(int msa) · 2 unmodified lines | ||
| 1146 | 1154 | /* |
| 1147 | 1155 | * If this is the first time that the task is using MSA and it has |
| 1148 | 1156 | * previously used scalar FP in this time slice then we already nave |
| 1149 | − * FP context which we shouldn't clobber. | |
| 1157 | + * FP context which we shouldn't clobber. We do however need to clear | |
| 1158 | + * the upper 64b of each vector register so that this task has no | |
| 1159 | + * opportunity to see data left behind by another. | |
| 1150 | 1160 | */ |
| 1151 | − if (!test_and_set_thread_flag(TIF_MSA_CTX_LIVE) && was_fpu_owner) | |
| 1152 | − return 0; | |
| 1161 | + prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE); | |
| 1162 | + if (!prior_msa && was_fpu_owner) { | |
| 1163 | + _init_msa_upper(); | |
| 1164 | + | |
| 1165 | + goto out; | |
| 1166 | + } | |
| 1167 | + | |
| 1168 | + if (!prior_msa) { | |
| 1169 | + /* | |
| 1170 | + * Restore the least significant 64b of each vector register | |
| 1171 | + * from the existing scalar FP context. | |
| 1172 | + */ | |
| 1173 | + _restore_fp(current); | |
| 1174 | + | |
| 1175 | + /* | |
| 1176 | + * The task has not formerly used MSA, so clear the upper 64b | |
| 1177 | + * of each vector register such that it cannot see data left | |
| 1178 | + * behind by another task. | |
| 1179 | + */ | |
| 1180 | + _init_msa_upper(); | |
| 1181 | + } else { | |
| 1182 | + /* We need to restore the vector context. */ | |
| 1183 | + restore_msa(current); | |
| 1184 | + | |
| 1185 | + /* Restore the scalar FP control & status register */ | |
| 1186 | + if (!was_fpu_owner) | |
| 1187 | + asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31)); | |
| 1188 | + } | |
| 1189 | + | |
| 1190 | +out: | |
| 1191 | + preempt_enable(); | |
| 1153 | 1192 | |
| 1154 | − /* We need to restore the vector context. */ | |
| 1155 | − restore_msa(current); | |
| 1156 | 1193 | return 0; |
| 1157 | 1194 | } |
| 1158 | 1195 | |
| @@ -2114,6 +2151,12 @@ void __init trap_init(void) · 955 unmodified lines | ||
| 2114 | 2151 | set_except_vector(15, handle_fpe); |
| 2115 | 2152 | |
| 2116 | 2153 | set_except_vector(16, handle_ftlb); |
| 2154 | + | |
| 2155 | + if (cpu_has_rixiex) { | |
| 2156 | + set_except_vector(19, tlb_do_page_fault_0); | |
| 2157 | + set_except_vector(20, tlb_do_page_fault_0); | |
| 2158 | + } | |
| 2159 | + | |
| 2117 | 2160 | set_except_vector(21, handle_msa); |
| 2118 | 2161 | set_except_vector(22, handle_mdmx); |
| 2119 | 2162 | |
| @@ -690,7 +690,6 @@ static void emulate_load_store_insn(struct pt_regs *regs, · 689 unmodified lines | ||
| 690 | 690 | case sdc1_op: |
| 691 | 691 | die_if_kernel("Unaligned FP access in kernel code", regs); |
| 692 | 692 | BUG_ON(!used_math()); |
| 693 | − BUG_ON(!is_fpu_owner()); | |
| 694 | 693 | |
| 695 | 694 | lose_fpu(1); /* Save FPU state for the emulator. */ |
| 696 | 695 | res = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, |
| @@ -60,8 +60,8 @@ config LEMOTE_MACH2F · 59 unmodified lines | ||
| 60 | 60 | These family machines include fuloong2f mini PC, yeeloong2f notebook, |
| 61 | 61 | LingLoong allinone PC and so forth. |
| 62 | 62 | |
| 63 | −config LEMOTE_MACH3A | |
| 64 | − bool "Lemote Loongson 3A family machines" | |
| 63 | +config LOONGSON_MACH3X | |
| 64 | + bool "Generic Loongson 3 family machines" | |
| 65 | 65 | select ARCH_SPARSEMEM_ENABLE |
| 66 | 66 | select GENERIC_ISA_DMA_SUPPORT_BROKEN |
| 67 | 67 | select BOOT_ELF32 |
| @@ -79,6 +79,7 @@ config LEMOTE_MACH3A · 11 unmodified lines | ||
| 79 | 79 | select SYS_HAS_EARLY_PRINTK |
| 80 | 80 | select SYS_SUPPORTS_SMP |
| 81 | 81 | select SYS_SUPPORTS_HOTPLUG_CPU |
| 82 | + select SYS_SUPPORTS_NUMA | |
| 82 | 83 | select SYS_SUPPORTS_64BIT_KERNEL |
| 83 | 84 | select SYS_SUPPORTS_HIGHMEM |
| 84 | 85 | select SYS_SUPPORTS_LITTLE_ENDIAN |
| @@ -86,8 +87,8 @@ config LEMOTE_MACH3A · 1 unmodified line | ||
| 86 | 87 | select ZONE_DMA32 |
| 87 | 88 | select LEFI_FIRMWARE_INTERFACE |
| 88 | 89 | help |
| 89 | − Lemote Loongson 3A family machines utilize the 3A revision of | |
| 90 | − Loongson processor and RS780/SBX00 chipset. | |
| 90 | + Generic Loongson 3 family machines utilize the 3A/3B revision | |
| 91 | + of Loongson processor and RS780/SBX00 chipset. | |
| 91 | 92 | endchoice |
| 92 | 93 | |
| 93 | 94 | config CS5536 |
| @@ -30,4 +30,4 @@ platform-$(CONFIG_MACH_LOONGSON) += loongson/ · 29 unmodified lines | ||
| 30 | 30 | cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely |
| 31 | 31 | load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000 |
| 32 | 32 | load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000 |
| 33 | −load-$(CONFIG_CPU_LOONGSON3) += 0xffffffff80200000 | |
| 33 | +load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000 | |
| @@ -27,6 +27,12 @@ EXPORT_SYMBOL(cpu_clock_freq); · 26 unmodified lines | ||
| 27 | 27 | struct efi_memory_map_loongson *loongson_memmap; |
| 28 | 28 | struct loongson_system_configuration loongson_sysconf; |
| 29 | 29 | |
| 30 | +u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; | |
| 31 | +u64 loongson_freqctrl[MAX_PACKAGES]; | |
| 32 | + | |
| 33 | +unsigned long long smp_group[4]; | |
| 34 | +int cpuhotplug_workaround = 0; | |
| 35 | + | |
| 30 | 36 | #define parse_even_earlier(res, option, p) \ |
| 31 | 37 | do { \ |
| 32 | 38 | unsigned int tmp __maybe_unused; \ |
| @@ -77,9 +83,47 @@ void __init prom_init_env(void) · 44 unmodified lines | ||
| 77 | 83 | |
| 78 | 84 | cpu_clock_freq = ecpu->cpu_clock_freq; |
| 79 | 85 | loongson_sysconf.cputype = ecpu->cputype; |
| 86 | + if (ecpu->cputype == Loongson_3A) { | |
| 87 | + loongson_sysconf.cores_per_node = 4; | |
| 88 | + loongson_sysconf.cores_per_package = 4; | |
| 89 | + smp_group[0] = 0x900000003ff01000; | |
| 90 | + smp_group[1] = 0x900010003ff01000; | |
| 91 | + smp_group[2] = 0x900020003ff01000; | |
| 92 | + smp_group[3] = 0x900030003ff01000; | |
| 93 | + loongson_chipcfg[0] = 0x900000001fe00180; | |
| 94 | + loongson_chipcfg[1] = 0x900010001fe00180; | |
| 95 | + loongson_chipcfg[2] = 0x900020001fe00180; | |
| 96 | + loongson_chipcfg[3] = 0x900030001fe00180; | |
| 97 | + loongson_sysconf.ht_control_base = 0x90000EFDFB000000; | |
| 98 | + } else if (ecpu->cputype == Loongson_3B) { | |
| 99 | + loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ | |
| 100 | + loongson_sysconf.cores_per_package = 8; | |
| 101 | + smp_group[0] = 0x900000003ff01000; | |
| 102 | + smp_group[1] = 0x900010003ff05000; | |
| 103 | + smp_group[2] = 0x900020003ff09000; | |
| 104 | + smp_group[3] = 0x900030003ff0d000; | |
| 105 | + loongson_chipcfg[0] = 0x900000001fe00180; | |
| 106 | + loongson_chipcfg[1] = 0x900020001fe00180; | |
| 107 | + loongson_chipcfg[2] = 0x900040001fe00180; | |
| 108 | + loongson_chipcfg[3] = 0x900060001fe00180; | |
| 109 | + loongson_freqctrl[0] = 0x900000001fe001d0; | |
| 110 | + loongson_freqctrl[1] = 0x900020001fe001d0; | |
| 111 | + loongson_freqctrl[2] = 0x900040001fe001d0; | |
| 112 | + loongson_freqctrl[3] = 0x900060001fe001d0; | |
| 113 | + loongson_sysconf.ht_control_base = 0x90001EFDFB000000; | |
| 114 | + cpuhotplug_workaround = 1; | |
| 115 | + } else { | |
| 116 | + loongson_sysconf.cores_per_node = 1; | |
| 117 | + loongson_sysconf.cores_per_package = 1; | |
| 118 | + loongson_chipcfg[0] = 0x900000001fe00180; | |
| 119 | + } | |
| 120 | + | |
| 80 | 121 | loongson_sysconf.nr_cpus = ecpu->nr_cpus; |
| 81 | 122 | if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) |
| 82 | 123 | loongson_sysconf.nr_cpus = NR_CPUS; |
| 124 | + loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + | |
| 125 | + loongson_sysconf.cores_per_node - 1) / | |
| 126 | + loongson_sysconf.cores_per_node; | |
| 83 | 127 | |
| 84 | 128 | loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr; |
| 85 | 129 | loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr; |
| @@ -93,7 +137,6 @@ void __init prom_init_env(void) · 7 unmodified lines | ||
| 93 | 137 | loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; |
| 94 | 138 | loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend; |
| 95 | 139 | |
| 96 | − loongson_sysconf.ht_control_base = 0x90000EFDFB000000; | |
| 97 | 140 | loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios; |
| 98 | 141 | pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", |
| 99 | 142 | loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, |
| @@ -111,6 +154,10 @@ void __init prom_init_env(void) · 11 unmodified lines | ||
| 111 | 154 | case PRID_REV_LOONGSON3A: |
| 112 | 155 | cpu_clock_freq = 900000000; |
| 113 | 156 | break; |
| 157 | + case PRID_REV_LOONGSON3B_R1: | |
| 158 | + case PRID_REV_LOONGSON3B_R2: | |
| 159 | + cpu_clock_freq = 1000000000; | |
| 160 | + break; | |
| 114 | 161 | default: |
| 115 | 162 | cpu_clock_freq = 100000000; |
| 116 | 163 | break; |
| @@ -30,7 +30,11 @@ void __init prom_init(void) · 29 unmodified lines | ||
| 30 | 30 | set_io_port_base((unsigned long) |
| 31 | 31 | ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); |
| 32 | 32 | |
| 33 | +#ifdef CONFIG_NUMA | |
| 34 | + prom_init_numa_memory(); | |
| 35 | +#else | |
| 33 | 36 | prom_init_memory(); |
| 37 | +#endif | |
| 34 | 38 | |
| 35 | 39 | /*init the uart base address */ |
| 36 | 40 | prom_init_uart_base(); |
| @@ -79,7 +79,7 @@ int __weak wakeup_loongson(void) · 78 unmodified lines | ||
| 79 | 79 | static void wait_for_wakeup_events(void) |
| 80 | 80 | { |
| 81 | 81 | while (!wakeup_loongson()) |
| 82 | − LOONGSON_CHIPCFG0 &= ~0x7; | |
| 82 | + LOONGSON_CHIPCFG(0) &= ~0x7; | |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | /* |
| @@ -102,15 +102,15 @@ static void loongson_suspend_enter(void) · 16 unmodified lines | ||
| 102 | 102 | |
| 103 | 103 | stop_perf_counters(); |
| 104 | 104 | |
| 105 | − cached_cpu_freq = LOONGSON_CHIPCFG0; | |
| 105 | + cached_cpu_freq = LOONGSON_CHIPCFG(0); | |
| 106 | 106 | |
| 107 | 107 | /* Put CPU into wait mode */ |
| 108 | − LOONGSON_CHIPCFG0 &= ~0x7; | |
| 108 | + LOONGSON_CHIPCFG(0) &= ~0x7; | |
| 109 | 109 | |
| 110 | 110 | /* wait for the given events to wakeup cpu from wait mode */ |
| 111 | 111 | wait_for_wakeup_events(); |
| 112 | 112 | |
| 113 | − LOONGSON_CHIPCFG0 = cached_cpu_freq; | |
| 113 | + LOONGSON_CHIPCFG(0) = cached_cpu_freq; | |
| 114 | 114 | mmiowb(); |
| 115 | 115 | } |
| 116 | 116 | |
| @@ -114,9 +114,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate) · 113 unmodified lines | ||
| 114 | 114 | |
| 115 | 115 | clk->rate = rate; |
| 116 | 116 | |
| 117 | − regval = LOONGSON_CHIPCFG0; | |
| 117 | + regval = LOONGSON_CHIPCFG(0); | |
| 118 | 118 | regval = (regval & ~0x7) | (pos->driver_data - 1); |
| 119 | − LOONGSON_CHIPCFG0 = regval; | |
| 119 | + LOONGSON_CHIPCFG(0) = regval; | |
| 120 | 120 | |
| 121 | 121 | return ret; |
| 122 | 122 | } |
| @@ -28,7 +28,7 @@ static void reset_cpu(void) · 27 unmodified lines | ||
| 28 | 28 | * reset cpu to full speed, this is needed when enabling cpu frequency |
| 29 | 29 | * scalling |
| 30 | 30 | */ |
| 31 | − LOONGSON_CHIPCFG0 |= 0x7; | |
| 31 | + LOONGSON_CHIPCFG(0) |= 0x7; | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | /* reset support for fuloong2f */ |
| @@ -1,6 +1,8 @@ | ||
| 1 | 1 | # |
| 2 | 2 | # Makefile for Loongson-3 family machines |
| 3 | 3 | # |
| 4 | −obj-y += irq.o | |
| 4 | +obj-y += irq.o cop2-ex.o | |
| 5 | 5 | |
| 6 | 6 | obj-$(CONFIG_SMP) += smp.o |
| 7 | + | |
| 8 | +obj-$(CONFIG_NUMA) += numa.o | |
| @@ -0,0 +1,63 @@ | ||
| 1 | +/* | |
| 2 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | + * License. See the file "COPYING" in the main directory of this archive | |
| 4 | + * for more details. | |
| 5 | + * | |
| 6 | + * Copyright (C) 2014 Lemote Corporation. | |
| 7 | + * written by Huacai Chen <chenhc@lemote.com> | |
| 8 | + * | |
| 9 | + * based on arch/mips/cavium-octeon/cpu.c | |
| 10 | + * Copyright (C) 2009 Wind River Systems, | |
| 11 | + * written by Ralf Baechle <ralf@linux-mips.org> | |
| 12 | + */ | |
| 13 | +#include <linux/init.h> | |
| 14 | +#include <linux/sched.h> | |
| 15 | +#include <linux/notifier.h> | |
| 16 | + | |
| 17 | +#include <asm/fpu.h> | |
| 18 | +#include <asm/cop2.h> | |
| 19 | +#include <asm/current.h> | |
| 20 | +#include <asm/mipsregs.h> | |
| 21 | + | |
| 22 | +static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, | |
| 23 | + void *data) | |
| 24 | +{ | |
| 25 | + int fpu_enabled; | |
| 26 | + int fr = !test_thread_flag(TIF_32BIT_FPREGS); | |
| 27 | + | |
| 28 | + switch (action) { | |
| 29 | + case CU2_EXCEPTION: | |
| 30 | + preempt_disable(); | |
| 31 | + fpu_enabled = read_c0_status() & ST0_CU1; | |
| 32 | + if (!fr) | |
| 33 | + set_c0_status(ST0_CU1 | ST0_CU2); | |
| 34 | + else | |
| 35 | + set_c0_status(ST0_CU1 | ST0_CU2 | ST0_FR); | |
| 36 | + enable_fpu_hazard(); | |
| 37 | + KSTK_STATUS(current) |= (ST0_CU1 | ST0_CU2); | |
| 38 | + if (fr) | |
| 39 | + KSTK_STATUS(current) |= ST0_FR; | |
| 40 | + else | |
| 41 | + KSTK_STATUS(current) &= ~ST0_FR; | |
| 42 | + /* If FPU is enabled, we needn't init or restore fp */ | |
| 43 | + if(!fpu_enabled) { | |
| 44 | + set_thread_flag(TIF_USEDFPU); | |
| 45 | + if (!used_math()) { | |
| 46 | + _init_fpu(); | |
| 47 | + set_used_math(); | |
| 48 | + } else | |
| 49 | + _restore_fp(current); | |
| 50 | + } | |
| 51 | + preempt_enable(); | |
| 52 | + | |
| 53 | + return NOTIFY_STOP; /* Don't call default notifier */ | |
| 54 | + } | |
| 55 | + | |
| 56 | + return NOTIFY_OK; /* Let default notifier send signals */ | |
| 57 | +} | |
| 58 | + | |
| 59 | +static int __init loongson_cu2_setup(void) | |
| 60 | +{ | |
| 61 | + return cu2_notifier(loongson_cu2_call, 0); | |
| 62 | +} | |
| 63 | +early_initcall(loongson_cu2_setup); | |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <asm/i8259.h> |
| 8 | 8 | #include <asm/mipsregs.h> |
| 9 | 9 | |
| 10 | +#include "smp.h" | |
| 11 | + | |
| 10 | 12 | unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; |
| 11 | 13 | |
| 12 | 14 | static void ht_irqdispatch(void) |
| @@ -53,9 +55,15 @@ static inline void mask_loongson_irq(struct irq_data *d) · 40 unmodified lines | ||
| 53 | 55 | /* Workaround: UART IRQ may deliver to any core */ |
| 54 | 56 | if (d->irq == LOONGSON_UART_IRQ) { |
| 55 | 57 | int cpu = smp_processor_id(); |
| 56 | − | |
| 57 | − LOONGSON_INT_ROUTER_INTENCLR = 1 << 10; | |
| 58 | − LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu); | |
| 58 | + int node_id = cpu / loongson_sysconf.cores_per_node; | |
| 59 | + int core_id = cpu % loongson_sysconf.cores_per_node; | |
| 60 | + u64 intenclr_addr = smp_group[node_id] | | |
| 61 | + (u64)(&LOONGSON_INT_ROUTER_INTENCLR); | |
| 62 | + u64 introuter_lpc_addr = smp_group[node_id] | | |
| 63 | + (u64)(&LOONGSON_INT_ROUTER_LPC); | |
| 64 | + | |
| 65 | + *(volatile u32 *)intenclr_addr = 1 << 10; | |
| 66 | + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id); | |
| 59 | 67 | } |
| 60 | 68 | } |
| 61 | 69 | |
| @@ -64,9 +72,15 @@ static inline void unmask_loongson_irq(struct irq_data *d) · 2 unmodified lines | ||
| 64 | 72 | /* Workaround: UART IRQ may deliver to any core */ |
| 65 | 73 | if (d->irq == LOONGSON_UART_IRQ) { |
| 66 | 74 | int cpu = smp_processor_id(); |
| 67 | − | |
| 68 | − LOONGSON_INT_ROUTER_INTENSET = 1 << 10; | |
| 69 | − LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu); | |
| 75 | + int node_id = cpu / loongson_sysconf.cores_per_node; | |
| 76 | + int core_id = cpu % loongson_sysconf.cores_per_node; | |
| 77 | + u64 intenset_addr = smp_group[node_id] | | |
| 78 | + (u64)(&LOONGSON_INT_ROUTER_INTENSET); | |
| 79 | + u64 introuter_lpc_addr = smp_group[node_id] | | |
| 80 | + (u64)(&LOONGSON_INT_ROUTER_LPC); | |
| 81 | + | |
| 82 | + *(volatile u32 *)intenset_addr = 1 << 10; | |
| 83 | + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id); | |
| 70 | 84 | } |
| 71 | 85 | |
| 72 | 86 | set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); |
| @@ -0,0 +1,291 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & | |
| 3 | + * Insititute of Computing Technology | |
| 4 | + * Author: Xiang Gao, gaoxiang@ict.ac.cn | |
| 5 | + * Huacai Chen, chenhc@lemote.com | |
| 6 | + * Xiaofu Meng, Shuangshuang Zhang | |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or modify it | |
| 9 | + * under the terms of the GNU General Public License as published by the | |
| 10 | + * Free Software Foundation; either version 2 of the License, or (at your | |
| 11 | + * option) any later version. | |
| 12 | + */ | |
| 13 | +#include <linux/init.h> | |
| 14 | +#include <linux/kernel.h> | |
| 15 | +#include <linux/mm.h> | |
| 16 | +#include <linux/mmzone.h> | |
| 17 | +#include <linux/module.h> | |
| 18 | +#include <linux/nodemask.h> | |
| 19 | +#include <linux/swap.h> | |
| 20 | +#include <linux/memblock.h> | |
| 21 | +#include <linux/bootmem.h> | |
| 22 | +#include <linux/pfn.h> | |
| 23 | +#include <linux/highmem.h> | |
| 24 | +#include <asm/page.h> | |
| 25 | +#include <asm/pgalloc.h> | |
| 26 | +#include <asm/sections.h> | |
| 27 | +#include <linux/bootmem.h> | |
| 28 | +#include <linux/init.h> | |
| 29 | +#include <linux/irq.h> | |
| 30 | +#include <asm/bootinfo.h> | |
| 31 | +#include <asm/mc146818-time.h> | |
| 32 | +#include <asm/time.h> | |
| 33 | +#include <asm/wbflush.h> | |
| 34 | +#include <boot_param.h> | |
| 35 | + | |
| 36 | +static struct node_data prealloc__node_data[MAX_NUMNODES]; | |
| 37 | +unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; | |
| 38 | +struct node_data *__node_data[MAX_NUMNODES]; | |
| 39 | +EXPORT_SYMBOL(__node_data); | |
| 40 | + | |
| 41 | +static void enable_lpa(void) | |
| 42 | +{ | |
| 43 | + unsigned long value; | |
| 44 | + | |
| 45 | + value = __read_32bit_c0_register($16, 3); | |
| 46 | + value |= 0x00000080; | |
| 47 | + __write_32bit_c0_register($16, 3, value); | |
| 48 | + value = __read_32bit_c0_register($16, 3); | |
| 49 | + pr_info("CP0_Config3: CP0 16.3 (0x%lx)\n", value); | |
| 50 | + | |
| 51 | + value = __read_32bit_c0_register($5, 1); | |
| 52 | + value |= 0x20000000; | |
| 53 | + __write_32bit_c0_register($5, 1, value); | |
| 54 | + value = __read_32bit_c0_register($5, 1); | |
| 55 | + pr_info("CP0_PageGrain: CP0 5.1 (0x%lx)\n", value); | |
| 56 | +} | |
| 57 | + | |
| 58 | +static void cpu_node_probe(void) | |
| 59 | +{ | |
| 60 | + int i; | |
| 61 | + | |
| 62 | + nodes_clear(node_possible_map); | |
| 63 | + nodes_clear(node_online_map); | |
| 64 | + for (i = 0; i < loongson_sysconf.nr_nodes; i++) { | |
| 65 | + node_set_state(num_online_nodes(), N_POSSIBLE); | |
| 66 | + node_set_online(num_online_nodes()); | |
| 67 | + } | |
| 68 | + | |
| 69 | + pr_info("NUMA: Discovered %d cpus on %d nodes\n", | |
| 70 | + loongson_sysconf.nr_cpus, num_online_nodes()); | |
| 71 | +} | |
| 72 | + | |
| 73 | +static int __init compute_node_distance(int row, int col) | |
| 74 | +{ | |
| 75 | + int package_row = row * loongson_sysconf.cores_per_node / | |
| 76 | + loongson_sysconf.cores_per_package; | |
| 77 | + int package_col = col * loongson_sysconf.cores_per_node / | |
| 78 | + loongson_sysconf.cores_per_package; | |
| 79 | + | |
| 80 | + if (col == row) | |
| 81 | + return 0; | |
| 82 | + else if (package_row == package_col) | |
| 83 | + return 40; | |
| 84 | + else | |
| 85 | + return 100; | |
| 86 | +} | |
| 87 | + | |
| 88 | +static void __init init_topology_matrix(void) | |
| 89 | +{ | |
| 90 | + int row, col; | |
| 91 | + | |
| 92 | + for (row = 0; row < MAX_NUMNODES; row++) | |
| 93 | + for (col = 0; col < MAX_NUMNODES; col++) | |
| 94 | + __node_distances[row][col] = -1; | |
| 95 | + | |
| 96 | + for_each_online_node(row) { | |
| 97 | + for_each_online_node(col) { | |
| 98 | + __node_distances[row][col] = | |
| 99 | + compute_node_distance(row, col); | |
| 100 | + } | |
| 101 | + } | |
| 102 | +} | |
| 103 | + | |
| 104 | +static unsigned long nid_to_addroffset(unsigned int nid) | |
| 105 | +{ | |
| 106 | + unsigned long result; | |
| 107 | + switch (nid) { | |
| 108 | + case 0: | |
| 109 | + default: | |
| 110 | + result = NODE0_ADDRSPACE_OFFSET; | |
| 111 | + break; | |
| 112 | + case 1: | |
| 113 | + result = NODE1_ADDRSPACE_OFFSET; | |
| 114 | + break; | |
| 115 | + case 2: | |
| 116 | + result = NODE2_ADDRSPACE_OFFSET; | |
| 117 | + break; | |
| 118 | + case 3: | |
| 119 | + result = NODE3_ADDRSPACE_OFFSET; | |
| 120 | + break; | |
| 121 | + } | |
| 122 | + return result; | |
| 123 | +} | |
| 124 | + | |
| 125 | +static void __init szmem(unsigned int node) | |
| 126 | +{ | |
| 127 | + u32 i, mem_type; | |
| 128 | + static unsigned long num_physpages = 0; | |
| 129 | + u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; | |
| 130 | + | |
| 131 | + /* Parse memory information and activate */ | |
| 132 | + for (i = 0; i < loongson_memmap->nr_map; i++) { | |
| 133 | + node_id = loongson_memmap->map[i].node_id; | |
| 134 | + if (node_id != node) | |
| 135 | + continue; | |
| 136 | + | |
| 137 | + mem_type = loongson_memmap->map[i].mem_type; | |
| 138 | + mem_size = loongson_memmap->map[i].mem_size; | |
| 139 | + mem_start = loongson_memmap->map[i].mem_start; | |
| 140 | + | |
| 141 | + switch (mem_type) { | |
| 142 | + case SYSTEM_RAM_LOW: | |
| 143 | + start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; | |
| 144 | + node_psize = (mem_size << 20) >> PAGE_SHIFT; | |
| 145 | + end_pfn = start_pfn + node_psize; | |
| 146 | + num_physpages += node_psize; | |
| 147 | + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | |
| 148 | + (u32)node_id, mem_type, mem_start, mem_size); | |
| 149 | + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", | |
| 150 | + start_pfn, end_pfn, num_physpages); | |
| 151 | + add_memory_region((node_id << 44) + mem_start, | |
| 152 | + (u64)mem_size << 20, BOOT_MEM_RAM); | |
| 153 | + memblock_add_node(PFN_PHYS(start_pfn), | |
| 154 | + PFN_PHYS(end_pfn - start_pfn), node); | |
| 155 | + break; | |
| 156 | + case SYSTEM_RAM_HIGH: | |
| 157 | + start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; | |
| 158 | + node_psize = (mem_size << 20) >> PAGE_SHIFT; | |
| 159 | + end_pfn = start_pfn + node_psize; | |
| 160 | + num_physpages += node_psize; | |
| 161 | + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | |
| 162 | + (u32)node_id, mem_type, mem_start, mem_size); | |
| 163 | + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", | |
| 164 | + start_pfn, end_pfn, num_physpages); | |
| 165 | + add_memory_region((node_id << 44) + mem_start, | |
| 166 | + (u64)mem_size << 20, BOOT_MEM_RAM); | |
| 167 | + memblock_add_node(PFN_PHYS(start_pfn), | |
| 168 | + PFN_PHYS(end_pfn - start_pfn), node); | |
| 169 | + break; | |
| 170 | + case MEM_RESERVED: | |
| 171 | + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | |
| 172 | + (u32)node_id, mem_type, mem_start, mem_size); | |
| 173 | + add_memory_region((node_id << 44) + mem_start, | |
| 174 | + (u64)mem_size << 20, BOOT_MEM_RESERVED); | |
| 175 | + memblock_reserve(((node_id << 44) + mem_start), | |
| 176 | + mem_size << 20); | |
| 177 | + break; | |
| 178 | + } | |
| 179 | + } | |
| 180 | +} | |
| 181 | + | |
| 182 | +static void __init node_mem_init(unsigned int node) | |
| 183 | +{ | |
| 184 | + unsigned long bootmap_size; | |
| 185 | + unsigned long node_addrspace_offset; | |
| 186 | + unsigned long start_pfn, end_pfn, freepfn; | |
| 187 | + | |
| 188 | + node_addrspace_offset = nid_to_addroffset(node); | |
| 189 | + pr_info("Node%d's addrspace_offset is 0x%lx\n", | |
| 190 | + node, node_addrspace_offset); | |
| 191 | + | |
| 192 | + get_pfn_range_for_nid(node, &start_pfn, &end_pfn); | |
| 193 | + freepfn = start_pfn; | |
| 194 | + if (node == 0) | |
| 195 | + freepfn = PFN_UP(__pa_symbol(&_end)); /* kernel end address */ | |
| 196 | + pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx, freepfn=0x%lx\n", | |
| 197 | + node, start_pfn, end_pfn, freepfn); | |
| 198 | + | |
| 199 | + __node_data[node] = prealloc__node_data + node; | |
| 200 | + | |
| 201 | + NODE_DATA(node)->bdata = &bootmem_node_data[node]; | |
| 202 | + NODE_DATA(node)->node_start_pfn = start_pfn; | |
| 203 | + NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; | |
| 204 | + | |
| 205 | + bootmap_size = init_bootmem_node(NODE_DATA(node), freepfn, | |
| 206 | + start_pfn, end_pfn); | |
| 207 | + free_bootmem_with_active_regions(node, end_pfn); | |
| 208 | + if (node == 0) /* used by finalize_initrd() */ | |
| 209 | + max_low_pfn = end_pfn; | |
| 210 | + | |
| 211 | + /* This is reserved for the kernel and bdata->node_bootmem_map */ | |
| 212 | + reserve_bootmem_node(NODE_DATA(node), start_pfn << PAGE_SHIFT, | |
| 213 | + ((freepfn - start_pfn) << PAGE_SHIFT) + bootmap_size, | |
| 214 | + BOOTMEM_DEFAULT); | |
| 215 | + | |
| 216 | + if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { | |
| 217 | + /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */ | |
| 218 | + reserve_bootmem_node(NODE_DATA(node), | |
| 219 | + (node_addrspace_offset | 0xff800000), | |
| 220 | + 8 << 20, BOOTMEM_DEFAULT); | |
| 221 | + } | |
| 222 | + | |
| 223 | + sparse_memory_present_with_active_regions(node); | |
| 224 | +} | |
| 225 | + | |
| 226 | +static __init void prom_meminit(void) | |
| 227 | +{ | |
| 228 | + unsigned int node, cpu; | |
| 229 | + | |
| 230 | + cpu_node_probe(); | |
| 231 | + init_topology_matrix(); | |
| 232 | + | |
| 233 | + for (node = 0; node < loongson_sysconf.nr_nodes; node++) { | |
| 234 | + if (node_online(node)) { | |
| 235 | + szmem(node); | |
| 236 | + node_mem_init(node); | |
| 237 | + cpus_clear(__node_data[(node)]->cpumask); | |
| 238 | + } | |
| 239 | + } | |
| 240 | + for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { | |
| 241 | + node = cpu / loongson_sysconf.cores_per_node; | |
| 242 | + if (node >= num_online_nodes()) | |
| 243 | + node = 0; | |
| 244 | + pr_info("NUMA: set cpumask cpu %d on node %d\n", cpu, node); | |
| 245 | + cpu_set(cpu, __node_data[(node)]->cpumask); | |
| 246 | + } | |
| 247 | +} | |
| 248 | + | |
| 249 | +void __init paging_init(void) | |
| 250 | +{ | |
| 251 | + unsigned node; | |
| 252 | + unsigned long zones_size[MAX_NR_ZONES] = {0, }; | |
| 253 | + | |
| 254 | + pagetable_init(); | |
| 255 | + | |
| 256 | + for_each_online_node(node) { | |
| 257 | + unsigned long start_pfn, end_pfn; | |
| 258 | + | |
| 259 | + get_pfn_range_for_nid(node, &start_pfn, &end_pfn); | |
| 260 | + | |
| 261 | + if (end_pfn > max_low_pfn) | |
| 262 | + max_low_pfn = end_pfn; | |
| 263 | + } | |
| 264 | +#ifdef CONFIG_ZONE_DMA32 | |
| 265 | + zones_size[ZONE_DMA32] = MAX_DMA32_PFN; | |
| 266 | +#endif | |
| 267 | + zones_size[ZONE_NORMAL] = max_low_pfn; | |
| 268 | + free_area_init_nodes(zones_size); | |
| 269 | +} | |
| 270 | + | |
| 271 | +void __init mem_init(void) | |
| 272 | +{ | |
| 273 | + high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); | |
| 274 | + free_all_bootmem(); | |
| 275 | + setup_zero_pages(); /* This comes from node 0 */ | |
| 276 | + mem_init_print_info(NULL); | |
| 277 | +} | |
| 278 | + | |
| 279 | +/* All PCI device belongs to logical Node-0 */ | |
| 280 | +int pcibus_to_node(struct pci_bus *bus) | |
| 281 | +{ | |
| 282 | + return 0; | |
| 283 | +} | |
| 284 | +EXPORT_SYMBOL(pcibus_to_node); | |
| 285 | + | |
| 286 | +void __init prom_init_numa_memory(void) | |
| 287 | +{ | |
| 288 | + enable_lpa(); | |
| 289 | + prom_meminit(); | |
| 290 | +} | |
| 291 | +EXPORT_SYMBOL(prom_init_numa_memory); | |
| @@ -31,6 +31,12 @@ · 30 unmodified lines | ||
| 31 | 31 | DEFINE_PER_CPU(int, cpu_state); |
| 32 | 32 | DEFINE_PER_CPU(uint32_t, core0_c0count); |
| 33 | 33 | |
| 34 | +static void *ipi_set0_regs[16]; | |
| 35 | +static void *ipi_clear0_regs[16]; | |
| 36 | +static void *ipi_status0_regs[16]; | |
| 37 | +static void *ipi_en0_regs[16]; | |
| 38 | +static void *ipi_mailbox_buf[16]; | |
| 39 | + | |
| 34 | 40 | /* read a 32bit value from ipi register */ |
| 35 | 41 | #define loongson3_ipi_read32(addr) readl(addr) |
| 36 | 42 | /* read a 64bit value from ipi register */ |
| @@ -48,100 +54,185 @@ DEFINE_PER_CPU(uint32_t, core0_c0count); · 11 unmodified lines | ||
| 48 | 54 | __wbflush(); \ |
| 49 | 55 | } while (0) |
| 50 | 56 | |
| 51 | −static void *ipi_set0_regs[] = { | |
| 52 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0), | |
| 53 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0), | |
| 54 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0), | |
| 55 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0), | |
| 56 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0), | |
| 57 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0), | |
| 58 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0), | |
| 59 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0), | |
| 60 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0), | |
| 61 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0), | |
| 62 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0), | |
| 63 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0), | |
| 64 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0), | |
| 65 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0), | |
| 66 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0), | |
| 67 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0), | |
| 68 | −}; | |
| 57 | +static void ipi_set0_regs_init(void) | |
| 58 | +{ | |
| 59 | + ipi_set0_regs[0] = (void *) | |
| 60 | + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0); | |
| 61 | + ipi_set0_regs[1] = (void *) | |
| 62 | + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0); | |
| 63 | + ipi_set0_regs[2] = (void *) | |
| 64 | + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0); | |
| 65 | + ipi_set0_regs[3] = (void *) | |
| 66 | + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0); | |
| 67 | + ipi_set0_regs[4] = (void *) | |
| 68 | + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0); | |
| 69 | + ipi_set0_regs[5] = (void *) | |
| 70 | + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0); | |
| 71 | + ipi_set0_regs[6] = (void *) | |
| 72 | + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0); | |
| 73 | + ipi_set0_regs[7] = (void *) | |
| 74 | + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0); | |
| 75 | + ipi_set0_regs[8] = (void *) | |
| 76 | + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0); | |
| 77 | + ipi_set0_regs[9] = (void *) | |
| 78 | + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0); | |
| 79 | + ipi_set0_regs[10] = (void *) | |
| 80 | + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0); | |
| 81 | + ipi_set0_regs[11] = (void *) | |
| 82 | + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0); | |
| 83 | + ipi_set0_regs[12] = (void *) | |
| 84 | + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0); | |
| 85 | + ipi_set0_regs[13] = (void *) | |
| 86 | + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0); | |
| 87 | + ipi_set0_regs[14] = (void *) | |
| 88 | + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0); | |
| 89 | + ipi_set0_regs[15] = (void *) | |
| 90 | + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0); | |
| 91 | +} | |
| 69 | 92 | |
| 70 | −static void *ipi_clear0_regs[] = { | |
| 71 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0), | |
| 72 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0), | |
| 73 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0), | |
| 74 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0), | |
| 75 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0), | |
| 76 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0), | |
| 77 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0), | |
| 78 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0), | |
| 79 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0), | |
| 80 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0), | |
| 81 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0), | |
| 82 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0), | |
| 83 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0), | |
| 84 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0), | |
| 85 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0), | |
| 86 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0), | |
| 87 | −}; | |
| 93 | +static void ipi_clear0_regs_init(void) | |
| 94 | +{ | |
| 95 | + ipi_clear0_regs[0] = (void *) | |
| 96 | + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0); | |
| 97 | + ipi_clear0_regs[1] = (void *) | |
| 98 | + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0); | |
| 99 | + ipi_clear0_regs[2] = (void *) | |
| 100 | + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0); | |
| 101 | + ipi_clear0_regs[3] = (void *) | |
| 102 | + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0); | |
| 103 | + ipi_clear0_regs[4] = (void *) | |
| 104 | + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0); | |
| 105 | + ipi_clear0_regs[5] = (void *) | |
| 106 | + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0); | |
| 107 | + ipi_clear0_regs[6] = (void *) | |
| 108 | + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0); | |
| 109 | + ipi_clear0_regs[7] = (void *) | |
| 110 | + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0); | |
| 111 | + ipi_clear0_regs[8] = (void *) | |
| 112 | + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0); | |
| 113 | + ipi_clear0_regs[9] = (void *) | |
| 114 | + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0); | |
| 115 | + ipi_clear0_regs[10] = (void *) | |
| 116 | + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0); | |
| 117 | + ipi_clear0_regs[11] = (void *) | |
| 118 | + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0); | |
| 119 | + ipi_clear0_regs[12] = (void *) | |
| 120 | + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0); | |
| 121 | + ipi_clear0_regs[13] = (void *) | |
| 122 | + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0); | |
| 123 | + ipi_clear0_regs[14] = (void *) | |
| 124 | + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0); | |
| 125 | + ipi_clear0_regs[15] = (void *) | |
| 126 | + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0); | |
| 127 | +} | |
| 88 | 128 | |
| 89 | −static void *ipi_status0_regs[] = { | |
| 90 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0), | |
| 91 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0), | |
| 92 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0), | |
| 93 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0), | |
| 94 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0), | |
| 95 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0), | |
| 96 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0), | |
| 97 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0), | |
| 98 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0), | |
| 99 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0), | |
| 100 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0), | |
| 101 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0), | |
| 102 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0), | |
| 103 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0), | |
| 104 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0), | |
| 105 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0), | |
| 106 | −}; | |
| 129 | +static void ipi_status0_regs_init(void) | |
| 130 | +{ | |
| 131 | + ipi_status0_regs[0] = (void *) | |
| 132 | + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0); | |
| 133 | + ipi_status0_regs[1] = (void *) | |
| 134 | + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0); | |
| 135 | + ipi_status0_regs[2] = (void *) | |
| 136 | + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0); | |
| 137 | + ipi_status0_regs[3] = (void *) | |
| 138 | + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0); | |
| 139 | + ipi_status0_regs[4] = (void *) | |
| 140 | + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0); | |
| 141 | + ipi_status0_regs[5] = (void *) | |
| 142 | + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0); | |
| 143 | + ipi_status0_regs[6] = (void *) | |
| 144 | + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0); | |
| 145 | + ipi_status0_regs[7] = (void *) | |
| 146 | + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0); | |
| 147 | + ipi_status0_regs[8] = (void *) | |
| 148 | + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0); | |
| 149 | + ipi_status0_regs[9] = (void *) | |
| 150 | + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0); | |
| 151 | + ipi_status0_regs[10] = (void *) | |
| 152 | + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0); | |
| 153 | + ipi_status0_regs[11] = (void *) | |
| 154 | + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0); | |
| 155 | + ipi_status0_regs[12] = (void *) | |
| 156 | + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0); | |
| 157 | + ipi_status0_regs[13] = (void *) | |
| 158 | + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0); | |
| 159 | + ipi_status0_regs[14] = (void *) | |
| 160 | + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0); | |
| 161 | + ipi_status0_regs[15] = (void *) | |
| 162 | + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0); | |
| 163 | +} | |
| 107 | 164 | |
| 108 | −static void *ipi_en0_regs[] = { | |
| 109 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0), | |
| 110 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0), | |
| 111 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0), | |
| 112 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0), | |
| 113 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0), | |
| 114 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0), | |
| 115 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0), | |
| 116 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0), | |
| 117 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0), | |
| 118 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0), | |
| 119 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0), | |
| 120 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0), | |
| 121 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0), | |
| 122 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0), | |
| 123 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0), | |
| 124 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0), | |
| 125 | −}; | |
| 165 | +static void ipi_en0_regs_init(void) | |
| 166 | +{ | |
| 167 | + ipi_en0_regs[0] = (void *) | |
| 168 | + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0); | |
| 169 | + ipi_en0_regs[1] = (void *) | |
| 170 | + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0); | |
| 171 | + ipi_en0_regs[2] = (void *) | |
| 172 | + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0); | |
| 173 | + ipi_en0_regs[3] = (void *) | |
| 174 | + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0); | |
| 175 | + ipi_en0_regs[4] = (void *) | |
| 176 | + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0); | |
| 177 | + ipi_en0_regs[5] = (void *) | |
| 178 | + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0); | |
| 179 | + ipi_en0_regs[6] = (void *) | |
| 180 | + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0); | |
| 181 | + ipi_en0_regs[7] = (void *) | |
| 182 | + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0); | |
| 183 | + ipi_en0_regs[8] = (void *) | |
| 184 | + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0); | |
| 185 | + ipi_en0_regs[9] = (void *) | |
| 186 | + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0); | |
| 187 | + ipi_en0_regs[10] = (void *) | |
| 188 | + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0); | |
| 189 | + ipi_en0_regs[11] = (void *) | |
| 190 | + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0); | |
| 191 | + ipi_en0_regs[12] = (void *) | |
| 192 | + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0); | |
| 193 | + ipi_en0_regs[13] = (void *) | |
| 194 | + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0); | |
| 195 | + ipi_en0_regs[14] = (void *) | |
| 196 | + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0); | |
| 197 | + ipi_en0_regs[15] = (void *) | |
| 198 | + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0); | |
| 199 | +} | |
| 126 | 200 | |
| 127 | −static void *ipi_mailbox_buf[] = { | |
| 128 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF), | |
| 129 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF), | |
| 130 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF), | |
| 131 | − (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF), | |
| 132 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF), | |
| 133 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF), | |
| 134 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF), | |
| 135 | − (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF), | |
| 136 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF), | |
| 137 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF), | |
| 138 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF), | |
| 139 | − (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF), | |
| 140 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF), | |
| 141 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF), | |
| 142 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF), | |
| 143 | − (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF), | |
| 144 | −}; | |
| 201 | +static void ipi_mailbox_buf_init(void) | |
| 202 | +{ | |
| 203 | + ipi_mailbox_buf[0] = (void *) | |
| 204 | + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF); | |
| 205 | + ipi_mailbox_buf[1] = (void *) | |
| 206 | + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF); | |
| 207 | + ipi_mailbox_buf[2] = (void *) | |
| 208 | + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF); | |
| 209 | + ipi_mailbox_buf[3] = (void *) | |
| 210 | + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF); | |
| 211 | + ipi_mailbox_buf[4] = (void *) | |
| 212 | + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF); | |
| 213 | + ipi_mailbox_buf[5] = (void *) | |
| 214 | + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF); | |
| 215 | + ipi_mailbox_buf[6] = (void *) | |
| 216 | + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF); | |
| 217 | + ipi_mailbox_buf[7] = (void *) | |
| 218 | + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF); | |
| 219 | + ipi_mailbox_buf[8] = (void *) | |
| 220 | + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF); | |
| 221 | + ipi_mailbox_buf[9] = (void *) | |
| 222 | + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF); | |
| 223 | + ipi_mailbox_buf[10] = (void *) | |
| 224 | + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF); | |
| 225 | + ipi_mailbox_buf[11] = (void *) | |
| 226 | + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF); | |
| 227 | + ipi_mailbox_buf[12] = (void *) | |
| 228 | + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF); | |
| 229 | + ipi_mailbox_buf[13] = (void *) | |
| 230 | + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF); | |
| 231 | + ipi_mailbox_buf[14] = (void *) | |
| 232 | + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF); | |
| 233 | + ipi_mailbox_buf[15] = (void *) | |
| 234 | + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF); | |
| 235 | +} | |
| 145 | 236 | |
| 146 | 237 | /* |
| 147 | 238 | * Simple enough, just poke the appropriate ipi register |
| @@ -203,6 +294,8 @@ static void loongson3_init_secondary(void) · 55 unmodified lines | ||
| 203 | 294 | for (i = 0; i < loongson_sysconf.nr_cpus; i++) |
| 204 | 295 | loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); |
| 205 | 296 | |
| 297 | + cpu_data[cpu].package = cpu / loongson_sysconf.cores_per_package; | |
| 298 | + cpu_data[cpu].core = cpu % loongson_sysconf.cores_per_package; | |
| 206 | 299 | per_cpu(cpu_state, cpu) = CPU_ONLINE; |
| 207 | 300 | |
| 208 | 301 | i = 0; |
| @@ -246,6 +339,11 @@ static void __init loongson3_smp_setup(void) · 37 unmodified lines | ||
| 246 | 339 | __cpu_number_map[i] = ++num; |
| 247 | 340 | __cpu_logical_map[num] = i; |
| 248 | 341 | } |
| 342 | + ipi_set0_regs_init(); | |
| 343 | + ipi_clear0_regs_init(); | |
| 344 | + ipi_status0_regs_init(); | |
| 345 | + ipi_en0_regs_init(); | |
| 346 | + ipi_mailbox_buf_init(); | |
| 249 | 347 | pr_info("Detected %i available secondary CPU(s)\n", num); |
| 250 | 348 | } |
| 251 | 349 | |
| @@ -313,7 +411,7 @@ static void loongson3_cpu_die(unsigned int cpu) · 61 unmodified lines | ||
| 313 | 411 | * flush all L1 entries at first. Then, another core (usually Core 0) can |
| 314 | 412 | * safely disable the clock of the target core. loongson3_play_dead() is |
| 315 | 413 | * called via CKSEG1 (uncached and unmmaped) */ |
| 316 | −static void loongson3_play_dead(int *state_addr) | |
| 414 | +static void loongson3a_play_dead(int *state_addr) | |
| 317 | 415 | { |
| 318 | 416 | register int val; |
| 319 | 417 | register long cpuid, core, node, count; |
| @@ -375,6 +473,70 @@ static void loongson3_play_dead(int *state_addr) · 55 unmodified lines | ||
| 375 | 473 | : "a1"); |
| 376 | 474 | } |
| 377 | 475 | |
| 476 | +static void loongson3b_play_dead(int *state_addr) | |
| 477 | +{ | |
| 478 | + register int val; | |
| 479 | + register long cpuid, core, node, count; | |
| 480 | + register void *addr, *base, *initfunc; | |
| 481 | + | |
| 482 | + __asm__ __volatile__( | |
| 483 | + " .set push \n" | |
| 484 | + " .set noreorder \n" | |
| 485 | + " li %[addr], 0x80000000 \n" /* KSEG0 */ | |
| 486 | + "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */ | |
| 487 | + " cache 0, 1(%[addr]) \n" | |
| 488 | + " cache 0, 2(%[addr]) \n" | |
| 489 | + " cache 0, 3(%[addr]) \n" | |
| 490 | + " cache 1, 0(%[addr]) \n" /* flush L1 DCache */ | |
| 491 | + " cache 1, 1(%[addr]) \n" | |
| 492 | + " cache 1, 2(%[addr]) \n" | |
| 493 | + " cache 1, 3(%[addr]) \n" | |
| 494 | + " addiu %[sets], %[sets], -1 \n" | |
| 495 | + " bnez %[sets], 1b \n" | |
| 496 | + " addiu %[addr], %[addr], 0x20 \n" | |
| 497 | + " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */ | |
| 498 | + " sw %[val], (%[state_addr]) \n" | |
| 499 | + " sync \n" | |
| 500 | + " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */ | |
| 501 | + " .set pop \n" | |
| 502 | + : [addr] "=&r" (addr), [val] "=&r" (val) | |
| 503 | + : [state_addr] "r" (state_addr), | |
| 504 | + [sets] "r" (cpu_data[smp_processor_id()].dcache.sets)); | |
| 505 | + | |
| 506 | + __asm__ __volatile__( | |
| 507 | + " .set push \n" | |
| 508 | + " .set noreorder \n" | |
| 509 | + " .set mips64 \n" | |
| 510 | + " mfc0 %[cpuid], $15, 1 \n" | |
| 511 | + " andi %[cpuid], 0x3ff \n" | |
| 512 | + " dli %[base], 0x900000003ff01000 \n" | |
| 513 | + " andi %[core], %[cpuid], 0x3 \n" | |
| 514 | + " sll %[core], 8 \n" /* get core id */ | |
| 515 | + " or %[base], %[base], %[core] \n" | |
| 516 | + " andi %[node], %[cpuid], 0xc \n" | |
| 517 | + " dsll %[node], 42 \n" /* get node id */ | |
| 518 | + " or %[base], %[base], %[node] \n" | |
| 519 | + " dsrl %[node], 30 \n" /* 15:14 */ | |
| 520 | + " or %[base], %[base], %[node] \n" | |
| 521 | + "1: li %[count], 0x100 \n" /* wait for init loop */ | |
| 522 | + "2: bnez %[count], 2b \n" /* limit mailbox access */ | |
| 523 | + " addiu %[count], -1 \n" | |
| 524 | + " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */ | |
| 525 | + " beqz %[initfunc], 1b \n" | |
| 526 | + " nop \n" | |
| 527 | + " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */ | |
| 528 | + " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */ | |
| 529 | + " ld $a1, 0x38(%[base]) \n" | |
| 530 | + " jr %[initfunc] \n" /* jump to initial PC */ | |
| 531 | + " nop \n" | |
| 532 | + " .set pop \n" | |
| 533 | + : [core] "=&r" (core), [node] "=&r" (node), | |
| 534 | + [base] "=&r" (base), [cpuid] "=&r" (cpuid), | |
| 535 | + [count] "=&r" (count), [initfunc] "=&r" (initfunc) | |
| 536 | + : /* No Input */ | |
| 537 | + : "a1"); | |
| 538 | +} | |
| 539 | + | |
| 378 | 540 | void play_dead(void) |
| 379 | 541 | { |
| 380 | 542 | int *state_addr; |
| @@ -382,13 +544,48 @@ void play_dead(void) · 1 unmodified line | ||
| 382 | 544 | void (*play_dead_at_ckseg1)(int *); |
| 383 | 545 | |
| 384 | 546 | idle_task_exit(); |
| 385 | − play_dead_at_ckseg1 = | |
| 386 | − (void *)CKSEG1ADDR((unsigned long)loongson3_play_dead); | |
| 547 | + switch (loongson_sysconf.cputype) { | |
| 548 | + case Loongson_3A: | |
| 549 | + default: | |
| 550 | + play_dead_at_ckseg1 = | |
| 551 | + (void *)CKSEG1ADDR((unsigned long)loongson3a_play_dead); | |
| 552 | + break; | |
| 553 | + case Loongson_3B: | |
| 554 | + play_dead_at_ckseg1 = | |
| 555 | + (void *)CKSEG1ADDR((unsigned long)loongson3b_play_dead); | |
| 556 | + break; | |
| 557 | + } | |
| 387 | 558 | state_addr = &per_cpu(cpu_state, cpu); |
| 388 | 559 | mb(); |
| 389 | 560 | play_dead_at_ckseg1(state_addr); |
| 390 | 561 | } |
| 391 | 562 | |
| 563 | +void loongson3_disable_clock(int cpu) | |
| 564 | +{ | |
| 565 | + uint64_t core_id = cpu_data[cpu].core; | |
| 566 | + uint64_t package_id = cpu_data[cpu].package; | |
| 567 | + | |
| 568 | + if (loongson_sysconf.cputype == Loongson_3A) { | |
| 569 | + LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); | |
| 570 | + } else if (loongson_sysconf.cputype == Loongson_3B) { | |
| 571 | + if (!cpuhotplug_workaround) | |
| 572 | + LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); | |
| 573 | + } | |
| 574 | +} | |
| 575 | + | |
| 576 | +void loongson3_enable_clock(int cpu) | |
| 577 | +{ | |
| 578 | + uint64_t core_id = cpu_data[cpu].core; | |
| 579 | + uint64_t package_id = cpu_data[cpu].package; | |
| 580 | + | |
| 581 | + if (loongson_sysconf.cputype == Loongson_3A) { | |
| 582 | + LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); | |
| 583 | + } else if (loongson_sysconf.cputype == Loongson_3B) { | |
| 584 | + if (!cpuhotplug_workaround) | |
| 585 | + LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); | |
| 586 | + } | |
| 587 | +} | |
| 588 | + | |
| 392 | 589 | #define CPU_POST_DEAD_FROZEN (CPU_POST_DEAD | CPU_TASKS_FROZEN) |
| 393 | 590 | static int loongson3_cpu_callback(struct notifier_block *nfb, |
| 394 | 591 | unsigned long action, void *hcpu) |
| @@ -399,12 +596,12 @@ static int loongson3_cpu_callback(struct notifier_block *nfb, · 4 unmodified lines | ||
| 399 | 596 | case CPU_POST_DEAD: |
| 400 | 597 | case CPU_POST_DEAD_FROZEN: |
| 401 | 598 | pr_info("Disable clock for CPU#%d\n", cpu); |
| 402 | − LOONGSON_CHIPCFG0 &= ~(1 << (12 + cpu)); | |
| 599 | + loongson3_disable_clock(cpu); | |
| 403 | 600 | break; |
| 404 | 601 | case CPU_UP_PREPARE: |
| 405 | 602 | case CPU_UP_PREPARE_FROZEN: |
| 406 | 603 | pr_info("Enable clock for CPU#%d\n", cpu); |
| 407 | − LOONGSON_CHIPCFG0 |= 1 << (12 + cpu); | |
| 604 | + loongson3_enable_clock(cpu); | |
| 408 | 605 | break; |
| 409 | 606 | } |
| 410 | 607 | |
| @@ -1,29 +1,30 @@ | ||
| 1 | 1 | #ifndef __LOONGSON_SMP_H_ |
| 2 | 2 | #define __LOONGSON_SMP_H_ |
| 3 | 3 | |
| 4 | −/* for Loongson-3A smp support */ | |
| 4 | +/* for Loongson-3 smp support */ | |
| 5 | +extern unsigned long long smp_group[4]; | |
| 5 | 6 | |
| 6 | 7 | /* 4 groups(nodes) in maximum in numa case */ |
| 7 | −#define SMP_CORE_GROUP0_BASE 0x900000003ff01000 | |
| 8 | −#define SMP_CORE_GROUP1_BASE 0x900010003ff01000 | |
| 9 | −#define SMP_CORE_GROUP2_BASE 0x900020003ff01000 | |
| 10 | −#define SMP_CORE_GROUP3_BASE 0x900030003ff01000 | |
| 8 | +#define SMP_CORE_GROUP0_BASE (smp_group[0]) | |
| 9 | +#define SMP_CORE_GROUP1_BASE (smp_group[1]) | |
| 10 | +#define SMP_CORE_GROUP2_BASE (smp_group[2]) | |
| 11 | +#define SMP_CORE_GROUP3_BASE (smp_group[3]) | |
| 11 | 12 | |
| 12 | 13 | /* 4 cores in each group(node) */ |
| 13 | −#define SMP_CORE0_OFFSET 0x000 | |
| 14 | −#define SMP_CORE1_OFFSET 0x100 | |
| 15 | −#define SMP_CORE2_OFFSET 0x200 | |
| 16 | −#define SMP_CORE3_OFFSET 0x300 | |
| 14 | +#define SMP_CORE0_OFFSET 0x000 | |
| 15 | +#define SMP_CORE1_OFFSET 0x100 | |
| 16 | +#define SMP_CORE2_OFFSET 0x200 | |
| 17 | +#define SMP_CORE3_OFFSET 0x300 | |
| 17 | 18 | |
| 18 | 19 | /* ipi registers offsets */ |
| 19 | −#define STATUS0 0x00 | |
| 20 | −#define EN0 0x04 | |
| 21 | −#define SET0 0x08 | |
| 22 | −#define CLEAR0 0x0c | |
| 23 | −#define STATUS1 0x10 | |
| 24 | −#define MASK1 0x14 | |
| 25 | −#define SET1 0x18 | |
| 26 | −#define CLEAR1 0x1c | |
| 27 | −#define BUF 0x20 | |
| 20 | +#define STATUS0 0x00 | |
| 21 | +#define EN0 0x04 | |
| 22 | +#define SET0 0x08 | |
| 23 | +#define CLEAR0 0x0c | |
| 24 | +#define STATUS1 0x10 | |
| 25 | +#define MASK1 0x14 | |
| 26 | +#define SET1 0x18 | |
| 27 | +#define CLEAR1 0x1c | |
| 28 | +#define BUF 0x20 | |
| 28 | 29 | |
| 29 | 30 | #endif |
| @@ -1827,7 +1827,7 @@ dcopuop: · 1826 unmodified lines | ||
| 1827 | 1827 | case -1: |
| 1828 | 1828 | |
| 1829 | 1829 | if (cpu_has_mips_4_5_r) |
| 1830 | − cbit = fpucondbit[MIPSInst_RT(ir) >> 2]; | |
| 1830 | + cbit = fpucondbit[MIPSInst_FD(ir) >> 2]; | |
| 1831 | 1831 | else |
| 1832 | 1832 | cbit = FPU_CSR_COND; |
| 1833 | 1833 | if (rv.w) |
| @@ -1230,19 +1230,19 @@ static void probe_pcache(void) · 1229 unmodified lines | ||
| 1230 | 1230 | case CPU_R14000: |
| 1231 | 1231 | break; |
| 1232 | 1232 | |
| 1233 | + case CPU_74K: | |
| 1234 | + case CPU_1074K: | |
| 1235 | + alias_74k_erratum(c); | |
| 1236 | + /* Fall through. */ | |
| 1233 | 1237 | case CPU_M14KC: |
| 1234 | 1238 | case CPU_M14KEC: |
| 1235 | 1239 | case CPU_24K: |
| 1236 | 1240 | case CPU_34K: |
| 1237 | − case CPU_74K: | |
| 1238 | 1241 | case CPU_1004K: |
| 1239 | − case CPU_1074K: | |
| 1240 | 1242 | case CPU_INTERAPTIV: |
| 1241 | 1243 | case CPU_P5600: |
| 1242 | 1244 | case CPU_PROAPTIV: |
| 1243 | 1245 | case CPU_M5150: |
| 1244 | − if ((c->cputype == CPU_74K) || (c->cputype == CPU_1074K)) | |
| 1245 | − alias_74k_erratum(c); | |
| 1246 | 1246 | if (!(read_c0_config7() & MIPS_CONF7_IAR) && |
| 1247 | 1247 | (c->icache.waysize > PAGE_SIZE)) |
| 1248 | 1248 | c->icache.flags |= MIPS_CACHE_ALIASES; |
| @@ -325,6 +325,38 @@ static inline void mem_init_free_highmem(void) · 324 unmodified lines | ||
| 325 | 325 | #endif |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | +unsigned __weak platform_maar_init(unsigned num_maars) | |
| 329 | +{ | |
| 330 | + return 0; | |
| 331 | +} | |
| 332 | + | |
| 333 | +static void maar_init(void) | |
| 334 | +{ | |
| 335 | + unsigned num_maars, used, i; | |
| 336 | + | |
| 337 | + if (!cpu_has_maar) | |
| 338 | + return; | |
| 339 | + | |
| 340 | + /* Detect the number of MAARs */ | |
| 341 | + write_c0_maari(~0); | |
| 342 | + back_to_back_c0_hazard(); | |
| 343 | + num_maars = read_c0_maari() + 1; | |
| 344 | + | |
| 345 | + /* MAARs should be in pairs */ | |
| 346 | + WARN_ON(num_maars % 2); | |
| 347 | + | |
| 348 | + /* Configure the required MAARs */ | |
| 349 | + used = platform_maar_init(num_maars / 2); | |
| 350 | + | |
| 351 | + /* Disable any further MAARs */ | |
| 352 | + for (i = (used * 2); i < num_maars; i++) { | |
| 353 | + write_c0_maari(i); | |
| 354 | + back_to_back_c0_hazard(); | |
| 355 | + write_c0_maar(0); | |
| 356 | + back_to_back_c0_hazard(); | |
| 357 | + } | |
| 358 | +} | |
| 359 | + | |
| 328 | 360 | void __init mem_init(void) |
| 329 | 361 | { |
| 330 | 362 | #ifdef CONFIG_HIGHMEM |
| @@ -337,6 +369,7 @@ void __init mem_init(void) · 6 unmodified lines | ||
| 337 | 369 | #endif |
| 338 | 370 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
| 339 | 371 | |
| 372 | + maar_init(); | |
| 340 | 373 | free_all_bootmem(); |
| 341 | 374 | setup_zero_pages(); /* Setup zeroed pages. */ |
| 342 | 375 | mem_init_free_highmem(); |
| @@ -158,7 +158,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) · 157 unmodified lines | ||
| 158 | 158 | { |
| 159 | 159 | int cpu = smp_processor_id(); |
| 160 | 160 | |
| 161 | − if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { | |
| 161 | + if (cpu_context(cpu, vma->vm_mm) != 0) { | |
| 162 | 162 | unsigned long flags; |
| 163 | 163 | int oldpid, newpid, idx; |
| 164 | 164 | |
| @@ -57,6 +57,7 @@ void local_flush_tlb_all(void) · 56 unmodified lines | ||
| 57 | 57 | local_irq_save(flags); |
| 58 | 58 | /* Save old context and create impossible VPN2 value */ |
| 59 | 59 | old_ctx = read_c0_entryhi(); |
| 60 | + htw_stop(); | |
| 60 | 61 | write_c0_entrylo0(0); |
| 61 | 62 | write_c0_entrylo1(0); |
| 62 | 63 | |
| @@ -90,6 +91,7 @@ void local_flush_tlb_all(void) · 27 unmodified lines | ||
| 90 | 91 | } |
| 91 | 92 | tlbw_use_hazard(); |
| 92 | 93 | write_c0_entryhi(old_ctx); |
| 94 | + htw_start(); | |
| 93 | 95 | flush_itlb(); |
| 94 | 96 | local_irq_restore(flags); |
| 95 | 97 | } |
| @@ -131,6 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, · 35 unmodified lines | ||
| 131 | 133 | int oldpid = read_c0_entryhi(); |
| 132 | 134 | int newpid = cpu_asid(cpu, mm); |
| 133 | 135 | |
| 136 | + htw_stop(); | |
| 134 | 137 | while (start < end) { |
| 135 | 138 | int idx; |
| 136 | 139 | |
| @@ -151,6 +154,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, · 14 unmodified lines | ||
| 151 | 154 | } |
| 152 | 155 | tlbw_use_hazard(); |
| 153 | 156 | write_c0_entryhi(oldpid); |
| 157 | + htw_start(); | |
| 154 | 158 | } else { |
| 155 | 159 | drop_mmu_context(mm, cpu); |
| 156 | 160 | } |
| @@ -174,6 +178,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) · 17 unmodified lines | ||
| 174 | 178 | start &= (PAGE_MASK << 1); |
| 175 | 179 | end += ((PAGE_SIZE << 1) - 1); |
| 176 | 180 | end &= (PAGE_MASK << 1); |
| 181 | + htw_stop(); | |
| 177 | 182 | |
| 178 | 183 | while (start < end) { |
| 179 | 184 | int idx; |
| @@ -195,6 +200,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) · 15 unmodified lines | ||
| 195 | 200 | } |
| 196 | 201 | tlbw_use_hazard(); |
| 197 | 202 | write_c0_entryhi(pid); |
| 203 | + htw_start(); | |
| 198 | 204 | } else { |
| 199 | 205 | local_flush_tlb_all(); |
| 200 | 206 | } |
| @@ -214,6 +220,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) · 13 unmodified lines | ||
| 214 | 220 | page &= (PAGE_MASK << 1); |
| 215 | 221 | local_irq_save(flags); |
| 216 | 222 | oldpid = read_c0_entryhi(); |
| 223 | + htw_stop(); | |
| 217 | 224 | write_c0_entryhi(page | newpid); |
| 218 | 225 | mtc0_tlbw_hazard(); |
| 219 | 226 | tlb_probe(); |
| @@ -231,6 +238,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) · 11 unmodified lines | ||
| 231 | 238 | |
| 232 | 239 | finish: |
| 233 | 240 | write_c0_entryhi(oldpid); |
| 241 | + htw_start(); | |
| 234 | 242 | flush_itlb_vm(vma); |
| 235 | 243 | local_irq_restore(flags); |
| 236 | 244 | } |
| @@ -247,6 +255,7 @@ void local_flush_tlb_one(unsigned long page) · 10 unmodified lines | ||
| 247 | 255 | |
| 248 | 256 | local_irq_save(flags); |
| 249 | 257 | oldpid = read_c0_entryhi(); |
| 258 | + htw_stop(); | |
| 250 | 259 | page &= (PAGE_MASK << 1); |
| 251 | 260 | write_c0_entryhi(page); |
| 252 | 261 | mtc0_tlbw_hazard(); |
| @@ -263,6 +272,7 @@ void local_flush_tlb_one(unsigned long page) · 10 unmodified lines | ||
| 263 | 272 | tlbw_use_hazard(); |
| 264 | 273 | } |
| 265 | 274 | write_c0_entryhi(oldpid); |
| 275 | + htw_start(); | |
| 266 | 276 | flush_itlb(); |
| 267 | 277 | local_irq_restore(flags); |
| 268 | 278 | } |
| @@ -351,6 +361,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, · 82 unmodified lines | ||
| 351 | 361 | local_irq_save(flags); |
| 352 | 362 | /* Save old context and create impossible VPN2 value */ |
| 353 | 363 | old_ctx = read_c0_entryhi(); |
| 364 | + htw_stop(); | |
| 354 | 365 | old_pagemask = read_c0_pagemask(); |
| 355 | 366 | wired = read_c0_wired(); |
| 356 | 367 | write_c0_wired(wired + 1); |
| @@ -366,6 +377,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, · 9 unmodified lines | ||
| 366 | 377 | |
| 367 | 378 | write_c0_entryhi(old_ctx); |
| 368 | 379 | tlbw_use_hazard(); /* What is the hazard here? */ |
| 380 | + htw_start(); | |
| 369 | 381 | write_c0_pagemask(old_pagemask); |
| 370 | 382 | local_flush_tlb_all(); |
| 371 | 383 | local_irq_restore(flags); |
| @@ -391,6 +403,51 @@ int __init has_transparent_hugepage(void) · 19 unmodified lines | ||
| 391 | 403 | |
| 392 | 404 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
| 393 | 405 | |
| 406 | +/* | |
| 407 | + * Used for loading TLB entries before trap_init() has started, when we | |
| 408 | + * don't actually want to add a wired entry which remains throughout the | |
| 409 | + * lifetime of the system | |
| 410 | + */ | |
| 411 | + | |
| 412 | +int temp_tlb_entry __cpuinitdata; | |
| 413 | + | |
| 414 | +__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |
| 415 | + unsigned long entryhi, unsigned long pagemask) | |
| 416 | +{ | |
| 417 | + int ret = 0; | |
| 418 | + unsigned long flags; | |
| 419 | + unsigned long wired; | |
| 420 | + unsigned long old_pagemask; | |
| 421 | + unsigned long old_ctx; | |
| 422 | + | |
| 423 | + local_irq_save(flags); | |
| 424 | + /* Save old context and create impossible VPN2 value */ | |
| 425 | + old_ctx = read_c0_entryhi(); | |
| 426 | + old_pagemask = read_c0_pagemask(); | |
| 427 | + wired = read_c0_wired(); | |
| 428 | + if (--temp_tlb_entry < wired) { | |
| 429 | + printk(KERN_WARNING | |
| 430 | + "No TLB space left for add_temporary_entry\n"); | |
| 431 | + ret = -ENOSPC; | |
| 432 | + goto out; | |
| 433 | + } | |
| 434 | + | |
| 435 | + write_c0_index(temp_tlb_entry); | |
| 436 | + write_c0_pagemask(pagemask); | |
| 437 | + write_c0_entryhi(entryhi); | |
| 438 | + write_c0_entrylo0(entrylo0); | |
| 439 | + write_c0_entrylo1(entrylo1); | |
| 440 | + mtc0_tlbw_hazard(); | |
| 441 | + tlb_write_indexed(); | |
| 442 | + tlbw_use_hazard(); | |
| 443 | + | |
| 444 | + write_c0_entryhi(old_ctx); | |
| 445 | + write_c0_pagemask(old_pagemask); | |
| 446 | +out: | |
| 447 | + local_irq_restore(flags); | |
| 448 | + return ret; | |
| 449 | +} | |
| 450 | + | |
| 394 | 451 | static int ntlb; |
| 395 | 452 | static int __init set_ntlb(char *str) |
| 396 | 453 | { |
| @@ -431,6 +488,8 @@ static void r4k_tlb_configure(void) · 34 unmodified lines | ||
| 431 | 488 | write_c0_pagegrain(pg); |
| 432 | 489 | } |
| 433 | 490 | |
| 491 | + temp_tlb_entry = current_cpu_data.tlbsize - 1; | |
| 492 | + | |
| 434 | 493 | /* From this point on the ARC firmware is dead. */ |
| 435 | 494 | local_flush_tlb_all(); |
| 436 | 495 | |
| @@ -429,6 +429,7 @@ static void build_r3000_tlb_refill_handler(void) · 428 unmodified lines | ||
| 429 | 429 | (unsigned int)(p - tlb_handler)); |
| 430 | 430 | |
| 431 | 431 | memcpy((void *)ebase, tlb_handler, 0x80); |
| 432 | + local_flush_icache_range(ebase, ebase + 0x80); | |
| 432 | 433 | |
| 433 | 434 | dump_handler("r3000_tlb_refill", (u32 *)ebase, 32); |
| 434 | 435 | } |
| @@ -1299,6 +1300,7 @@ static void build_r4000_tlb_refill_handler(void) · 864 unmodified lines | ||
| 1299 | 1300 | } |
| 1300 | 1301 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
| 1301 | 1302 | uasm_l_tlb_huge_update(&l, p); |
| 1303 | + UASM_i_LW(&p, K0, 0, K1); | |
| 1302 | 1304 | build_huge_update_entries(&p, htlb_info.huge_pte, K1); |
| 1303 | 1305 | build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random, |
| 1304 | 1306 | htlb_info.restore_scratch); |
| @@ -1415,6 +1417,7 @@ static void build_r4000_tlb_refill_handler(void) · 110 unmodified lines | ||
| 1415 | 1417 | final_len); |
| 1416 | 1418 | |
| 1417 | 1419 | memcpy((void *)ebase, final_handler, 0x100); |
| 1420 | + local_flush_icache_range(ebase, ebase + 0x100); | |
| 1418 | 1421 | |
| 1419 | 1422 | dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); |
| 1420 | 1423 | } |
| @@ -1919,7 +1922,7 @@ static void build_r4000_tlb_load_handler(void) · 498 unmodified lines | ||
| 1919 | 1922 | if (m4kc_tlbp_war()) |
| 1920 | 1923 | build_tlb_probe_entry(&p); |
| 1921 | 1924 | |
| 1922 | − if (cpu_has_rixi) { | |
| 1925 | + if (cpu_has_rixi && !cpu_has_rixiex) { | |
| 1923 | 1926 | /* |
| 1924 | 1927 | * If the page is not _PAGE_VALID, RI or XI could not |
| 1925 | 1928 | * have triggered it. Skip the expensive test.. |
| @@ -1986,7 +1989,7 @@ static void build_r4000_tlb_load_handler(void) · 60 unmodified lines | ||
| 1986 | 1989 | build_pte_present(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbl); |
| 1987 | 1990 | build_tlb_probe_entry(&p); |
| 1988 | 1991 | |
| 1989 | − if (cpu_has_rixi) { | |
| 1992 | + if (cpu_has_rixi && !cpu_has_rixiex) { | |
| 1990 | 1993 | /* |
| 1991 | 1994 | * If the page is not _PAGE_VALID, RI or XI could not |
| 1992 | 1995 | * have triggered it. Skip the expensive test.. |
| @@ -2194,6 +2197,94 @@ static void flush_tlb_handlers(void) · 201 unmodified lines | ||
| 2194 | 2197 | (unsigned long)tlbmiss_handler_setup_pgd_end); |
| 2195 | 2198 | } |
| 2196 | 2199 | |
| 2200 | +static void print_htw_config(void) | |
| 2201 | +{ | |
| 2202 | + unsigned long config; | |
| 2203 | + unsigned int pwctl; | |
| 2204 | + const int field = 2 * sizeof(unsigned long); | |
| 2205 | + | |
| 2206 | + config = read_c0_pwfield(); | |
| 2207 | + pr_debug("PWField (0x%0*lx): GDI: 0x%02lx UDI: 0x%02lx MDI: 0x%02lx PTI: 0x%02lx PTEI: 0x%02lx\n", | |
| 2208 | + field, config, | |
| 2209 | + (config & MIPS_PWFIELD_GDI_MASK) >> MIPS_PWFIELD_GDI_SHIFT, | |
| 2210 | + (config & MIPS_PWFIELD_UDI_MASK) >> MIPS_PWFIELD_UDI_SHIFT, | |
| 2211 | + (config & MIPS_PWFIELD_MDI_MASK) >> MIPS_PWFIELD_MDI_SHIFT, | |
| 2212 | + (config & MIPS_PWFIELD_PTI_MASK) >> MIPS_PWFIELD_PTI_SHIFT, | |
| 2213 | + (config & MIPS_PWFIELD_PTEI_MASK) >> MIPS_PWFIELD_PTEI_SHIFT); | |
| 2214 | + | |
| 2215 | + config = read_c0_pwsize(); | |
| 2216 | + pr_debug("PWSize (0x%0*lx): GDW: 0x%02lx UDW: 0x%02lx MDW: 0x%02lx PTW: 0x%02lx PTEW: 0x%02lx\n", | |
| 2217 | + field, config, | |
| 2218 | + (config & MIPS_PWSIZE_GDW_MASK) >> MIPS_PWSIZE_GDW_SHIFT, | |
| 2219 | + (config & MIPS_PWSIZE_UDW_MASK) >> MIPS_PWSIZE_UDW_SHIFT, | |
| 2220 | + (config & MIPS_PWSIZE_MDW_MASK) >> MIPS_PWSIZE_MDW_SHIFT, | |
| 2221 | + (config & MIPS_PWSIZE_PTW_MASK) >> MIPS_PWSIZE_PTW_SHIFT, | |
| 2222 | + (config & MIPS_PWSIZE_PTEW_MASK) >> MIPS_PWSIZE_PTEW_SHIFT); | |
| 2223 | + | |
| 2224 | + pwctl = read_c0_pwctl(); | |
| 2225 | + pr_debug("PWCtl (0x%x): PWEn: 0x%x DPH: 0x%x HugePg: 0x%x Psn: 0x%x\n", | |
| 2226 | + pwctl, | |
| 2227 | + (pwctl & MIPS_PWCTL_PWEN_MASK) >> MIPS_PWCTL_PWEN_SHIFT, | |
| 2228 | + (pwctl & MIPS_PWCTL_DPH_MASK) >> MIPS_PWCTL_DPH_SHIFT, | |
| 2229 | + (pwctl & MIPS_PWCTL_HUGEPG_MASK) >> MIPS_PWCTL_HUGEPG_SHIFT, | |
| 2230 | + (pwctl & MIPS_PWCTL_PSN_MASK) >> MIPS_PWCTL_PSN_SHIFT); | |
| 2231 | +} | |
| 2232 | + | |
| 2233 | +static void config_htw_params(void) | |
| 2234 | +{ | |
| 2235 | + unsigned long pwfield, pwsize, ptei; | |
| 2236 | + unsigned int config; | |
| 2237 | + | |
| 2238 | + /* | |
| 2239 | + * We are using 2-level page tables, so we only need to | |
| 2240 | + * setup GDW and PTW appropriately. UDW and MDW will remain 0. | |
| 2241 | + * The default value of GDI/UDI/MDI/PTI is 0xc. It is illegal to | |
| 2242 | + * write values less than 0xc in these fields because the entire | |
| 2243 | + * write will be dropped. As a result of which, we must preserve | |
| 2244 | + * the original reset values and overwrite only what we really want. | |
| 2245 | + */ | |
| 2246 | + | |
| 2247 | + pwfield = read_c0_pwfield(); | |
| 2248 | + /* re-initialize the GDI field */ | |
| 2249 | + pwfield &= ~MIPS_PWFIELD_GDI_MASK; | |
| 2250 | + pwfield |= PGDIR_SHIFT << MIPS_PWFIELD_GDI_SHIFT; | |
| 2251 | + /* re-initialize the PTI field including the even/odd bit */ | |
| 2252 | + pwfield &= ~MIPS_PWFIELD_PTI_MASK; | |
| 2253 | + pwfield |= PAGE_SHIFT << MIPS_PWFIELD_PTI_SHIFT; | |
| 2254 | + /* Set the PTEI right shift */ | |
| 2255 | + ptei = _PAGE_GLOBAL_SHIFT << MIPS_PWFIELD_PTEI_SHIFT; | |
| 2256 | + pwfield |= ptei; | |
| 2257 | + write_c0_pwfield(pwfield); | |
| 2258 | + /* Check whether the PTEI value is supported */ | |
| 2259 | + back_to_back_c0_hazard(); | |
| 2260 | + pwfield = read_c0_pwfield(); | |
| 2261 | + if (((pwfield & MIPS_PWFIELD_PTEI_MASK) << MIPS_PWFIELD_PTEI_SHIFT) | |
| 2262 | + != ptei) { | |
| 2263 | + pr_warn("Unsupported PTEI field value: 0x%lx. HTW will not be enabled", | |
| 2264 | + ptei); | |
| 2265 | + /* | |
| 2266 | + * Drop option to avoid HTW being enabled via another path | |
| 2267 | + * (eg htw_reset()) | |
| 2268 | + */ | |
| 2269 | + current_cpu_data.options &= ~MIPS_CPU_HTW; | |
| 2270 | + return; | |
| 2271 | + } | |
| 2272 | + | |
| 2273 | + pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT; | |
| 2274 | + pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT; | |
| 2275 | + write_c0_pwsize(pwsize); | |
| 2276 | + | |
| 2277 | + /* Make sure everything is set before we enable the HTW */ | |
| 2278 | + back_to_back_c0_hazard(); | |
| 2279 | + | |
| 2280 | + /* Enable HTW and disable the rest of the pwctl fields */ | |
| 2281 | + config = 1 << MIPS_PWCTL_PWEN_SHIFT; | |
| 2282 | + write_c0_pwctl(config); | |
| 2283 | + pr_info("Hardware Page Table Walker enabled\n"); | |
| 2284 | + | |
| 2285 | + print_htw_config(); | |
| 2286 | +} | |
| 2287 | + | |
| 2197 | 2288 | void build_tlb_refill_handler(void) |
| 2198 | 2289 | { |
| 2199 | 2290 | /* |
| @@ -2258,5 +2349,8 @@ void build_tlb_refill_handler(void) · 58 unmodified lines | ||
| 2258 | 2349 | } |
| 2259 | 2350 | if (cpu_has_local_ebase) |
| 2260 | 2351 | build_r4000_tlb_refill_handler(); |
| 2352 | + if (cpu_has_htw) | |
| 2353 | + config_htw_params(); | |
| 2354 | + | |
| 2261 | 2355 | } |
| 2262 | 2356 | } |
| @@ -42,6 +42,10 @@ static unsigned int ipi_map[NR_CPUS]; · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); |
| 44 | 44 | |
| 45 | +#ifdef CONFIG_MIPS_GIC_IPI | |
| 46 | +DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS); | |
| 47 | +#endif | |
| 48 | + | |
| 45 | 49 | static inline int mips_pcibios_iack(void) |
| 46 | 50 | { |
| 47 | 51 | int irq; |
| @@ -125,16 +129,22 @@ static void malta_hw0_irqdispatch(void) · 77 unmodified lines | ||
| 125 | 129 | |
| 126 | 130 | static void malta_ipi_irqdispatch(void) |
| 127 | 131 | { |
| 128 | − int irq; | |
| 132 | +#ifdef CONFIG_MIPS_GIC_IPI | |
| 133 | + unsigned long irq; | |
| 134 | + DECLARE_BITMAP(pending, GIC_NUM_INTRS); | |
| 129 | 135 | |
| 130 | − if (gic_compare_int()) | |
| 131 | − do_IRQ(MIPS_GIC_IRQ_BASE); | |
| 136 | + gic_get_int_mask(pending, ipi_ints); | |
| 137 | + | |
| 138 | + irq = find_first_bit(pending, GIC_NUM_INTRS); | |
| 132 | 139 | |
| 133 | − irq = gic_get_int(); | |
| 134 | − if (irq < 0) | |
| 135 | − return; /* interrupt has already been cleared */ | |
| 140 | + while (irq < GIC_NUM_INTRS) { | |
| 141 | + do_IRQ(MIPS_GIC_IRQ_BASE + irq); | |
| 136 | 142 | |
| 137 | − do_IRQ(MIPS_GIC_IRQ_BASE + irq); | |
| 143 | + irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1); | |
| 144 | + } | |
| 145 | +#endif | |
| 146 | + if (gic_compare_int()) | |
| 147 | + do_IRQ(MIPS_GIC_IRQ_BASE); | |
| 138 | 148 | } |
| 139 | 149 | |
| 140 | 150 | static void corehi_irqdispatch(void) |
| @@ -427,8 +437,9 @@ static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) · 286 unmodified lines | ||
| 427 | 437 | gic_intr_map[intr].pin = cpupin; |
| 428 | 438 | gic_intr_map[intr].polarity = GIC_POL_POS; |
| 429 | 439 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; |
| 430 | − gic_intr_map[intr].flags = GIC_FLAG_IPI; | |
| 440 | + gic_intr_map[intr].flags = 0; | |
| 431 | 441 | ipi_map[cpu] |= (1 << (cpupin + 2)); |
| 442 | + bitmap_set(ipi_ints, intr, 1); | |
| 432 | 443 | } |
| 433 | 444 | |
| 434 | 445 | static void __init fill_ipi_map(void) |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/string.h> |
| 17 | 17 | |
| 18 | 18 | #include <asm/bootinfo.h> |
| 19 | +#include <asm/maar.h> | |
| 19 | 20 | #include <asm/sections.h> |
| 20 | 21 | #include <asm/fw/fw.h> |
| 21 | 22 | |
| @@ -164,3 +165,28 @@ void __init prom_free_prom_memory(void) · 142 unmodified lines | ||
| 164 | 165 | addr, addr + boot_mem_map.map[i].size); |
| 165 | 166 | } |
| 166 | 167 | } |
| 168 | + | |
| 169 | +unsigned platform_maar_init(unsigned num_pairs) | |
| 170 | +{ | |
| 171 | + phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1; | |
| 172 | + struct maar_config cfg[] = { | |
| 173 | + /* DRAM preceding I/O */ | |
| 174 | + { 0x00000000, 0x0fffffff, MIPS_MAAR_S }, | |
| 175 | + | |
| 176 | + /* DRAM following I/O */ | |
| 177 | + { 0x20000000, mem_end, MIPS_MAAR_S }, | |
| 178 | + | |
| 179 | + /* DRAM alias in upper half of physical */ | |
| 180 | + { 0x80000000, 0x80000000 + mem_end, MIPS_MAAR_S }, | |
| 181 | + }; | |
| 182 | + unsigned i, num_cfg = ARRAY_SIZE(cfg); | |
| 183 | + | |
| 184 | + /* If DRAM fits before I/O, drop the region following it */ | |
| 185 | + if (physical_memsize <= 0x10000000) { | |
| 186 | + num_cfg--; | |
| 187 | + for (i = 1; i < num_cfg; i++) | |
| 188 | + cfg[i] = cfg[i + 1]; | |
| 189 | + } | |
| 190 | + | |
| 191 | + return maar_config(cfg, num_cfg, num_pairs); | |
| 192 | +} | |
| @@ -29,7 +29,7 @@ obj-$(CONFIG_LASAT) += pci-lasat.o · 28 unmodified lines | ||
| 29 | 29 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o |
| 30 | 30 | obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o |
| 31 | 31 | obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o |
| 32 | −obj-$(CONFIG_LEMOTE_MACH3A) += fixup-loongson3.o ops-loongson3.o | |
| 32 | +obj-$(CONFIG_LOONGSON_MACH3X) += fixup-loongson3.o ops-loongson3.o | |
| 33 | 33 | obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o pci-malta.o |
| 34 | 34 | obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o |
| 35 | 35 | obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o |
| @@ -199,8 +199,6 @@ static struct { · 198 unmodified lines | ||
| 199 | 199 | |
| 200 | 200 | char *tx4927_pcibios_setup(char *str) |
| 201 | 201 | { |
| 202 | − unsigned long val; | |
| 203 | − | |
| 204 | 202 | if (!strncmp(str, "trdyto=", 7)) { |
| 205 | 203 | u8 val = 0; |
| 206 | 204 | if (kstrtou8(str + 7, 0, &val) == 0) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * Support for all devices (greater than 16) added by David Gathright. |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#include <linux/clk.h> | |
| 10 | 11 | #include <linux/export.h> |
| 11 | 12 | #include <linux/types.h> |
| 12 | 13 | #include <linux/pci.h> |
| @@ -364,6 +365,7 @@ static int alchemy_pci_probe(struct platform_device *pdev) · 351 unmodified lines | ||
| 364 | 365 | void __iomem *virt_io; |
| 365 | 366 | unsigned long val; |
| 366 | 367 | struct resource *r; |
| 368 | + struct clk *c; | |
| 367 | 369 | int ret; |
| 368 | 370 | |
| 369 | 371 | /* need at least PCI IRQ mapping table */ |
| @@ -393,11 +395,24 @@ static int alchemy_pci_probe(struct platform_device *pdev) · 23 unmodified lines | ||
| 393 | 395 | goto out1; |
| 394 | 396 | } |
| 395 | 397 | |
| 398 | + c = clk_get(&pdev->dev, "pci_clko"); | |
| 399 | + if (IS_ERR(c)) { | |
| 400 | + dev_err(&pdev->dev, "unable to find PCI clock\n"); | |
| 401 | + ret = PTR_ERR(c); | |
| 402 | + goto out2; | |
| 403 | + } | |
| 404 | + | |
| 405 | + ret = clk_prepare_enable(c); | |
| 406 | + if (ret) { | |
| 407 | + dev_err(&pdev->dev, "cannot enable PCI clock\n"); | |
| 408 | + goto out6; | |
| 409 | + } | |
| 410 | + | |
| 396 | 411 | ctx->regs = ioremap_nocache(r->start, resource_size(r)); |
| 397 | 412 | if (!ctx->regs) { |
| 398 | 413 | dev_err(&pdev->dev, "cannot map pci regs\n"); |
| 399 | 414 | ret = -ENODEV; |
| 400 | − goto out2; | |
| 415 | + goto out5; | |
| 401 | 416 | } |
| 402 | 417 | |
| 403 | 418 | /* map parts of the PCI IO area */ |
| @@ -465,12 +480,19 @@ static int alchemy_pci_probe(struct platform_device *pdev) · 61 unmodified lines | ||
| 465 | 480 | register_syscore_ops(&alchemy_pci_pmops); |
| 466 | 481 | register_pci_controller(&ctx->alchemy_pci_ctrl); |
| 467 | 482 | |
| 483 | + dev_info(&pdev->dev, "PCI controller at %ld MHz\n", | |
| 484 | + clk_get_rate(c) / 1000000); | |
| 485 | + | |
| 468 | 486 | return 0; |
| 469 | 487 | |
| 470 | 488 | out4: |
| 471 | 489 | iounmap(virt_io); |
| 472 | 490 | out3: |
| 473 | 491 | iounmap(ctx->regs); |
| 492 | +out5: | |
| 493 | + clk_disable_unprepare(c); | |
| 494 | +out6: | |
| 495 | + clk_put(c); | |
| 474 | 496 | out2: |
| 475 | 497 | release_mem_region(r->start, resource_size(r)); |
| 476 | 498 | out1: |
| @@ -81,7 +81,7 @@ static int __init plat_of_setup(void) · 80 unmodified lines | ||
| 81 | 81 | panic("device tree not present"); |
| 82 | 82 | |
| 83 | 83 | strlcpy(of_ids[0].compatible, soc_info.compatible, len); |
| 84 | − strncpy(of_ids[1].compatible, "palmbus", len); | |
| 84 | + strlcpy(of_ids[1].compatible, "palmbus", len); | |
| 85 | 85 | |
| 86 | 86 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) |
| 87 | 87 | panic("failed to populate DT"); |
| @@ -223,6 +223,7 @@ static struct platform_device rb532_wdt = { · 222 unmodified lines | ||
| 223 | 223 | |
| 224 | 224 | static struct plat_serial8250_port rb532_uart_res[] = { |
| 225 | 225 | { |
| 226 | + .type = PORT_16550A, | |
| 226 | 227 | .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE), |
| 227 | 228 | .irq = UART0_IRQ, |
| 228 | 229 | .regshift = 2, |
| @@ -250,28 +251,6 @@ static struct platform_device *rb532_devs[] = { · 21 unmodified lines | ||
| 250 | 251 | &rb532_wdt |
| 251 | 252 | }; |
| 252 | 253 | |
| 253 | −static void __init parse_mac_addr(char *macstr) | |
| 254 | −{ | |
| 255 | − int i, h, l; | |
| 256 | − | |
| 257 | − for (i = 0; i < 6; i++) { | |
| 258 | − if (i != 5 && *(macstr + 2) != ':') | |
| 259 | − return; | |
| 260 | − | |
| 261 | − h = hex_to_bin(*macstr++); | |
| 262 | − if (h == -1) | |
| 263 | − return; | |
| 264 | − | |
| 265 | − l = hex_to_bin(*macstr++); | |
| 266 | − if (l == -1) | |
| 267 | − return; | |
| 268 | − | |
| 269 | − macstr++; | |
| 270 | − korina_dev0_data.mac[i] = (h << 4) + l; | |
| 271 | − } | |
| 272 | −} | |
| 273 | − | |
| 274 | − | |
| 275 | 254 | /* NAND definitions */ |
| 276 | 255 | #define NAND_CHIP_DELAY 25 |
| 277 | 256 | |
| @@ -333,7 +312,10 @@ static int __init plat_setup_devices(void) · 55 unmodified lines | ||
| 333 | 312 | static int __init setup_kmac(char *s) |
| 334 | 313 | { |
| 335 | 314 | printk(KERN_INFO "korina mac = %s\n", s); |
| 336 | − parse_mac_addr(s); | |
| 315 | + if (!mac_pton(s, korina_dev0_data.mac)) { | |
| 316 | + printk(KERN_ERR "Invalid mac\n"); | |
| 317 | + return -EINVAL; | |
| 318 | + } | |
| 337 | 319 | return 0; |
| 338 | 320 | } |
| 339 | 321 | |
| @@ -27,8 +27,14 @@ static struct { · 26 unmodified lines | ||
| 27 | 27 | { .name = "SGI GR2/GR3", .id = 0x7f }, |
| 28 | 28 | }; |
| 29 | 29 | |
| 30 | +static void gio_bus_release(struct device *dev) | |
| 31 | +{ | |
| 32 | + kfree(dev); | |
| 33 | +} | |
| 34 | + | |
| 30 | 35 | static struct device gio_bus = { |
| 31 | 36 | .init_name = "gio", |
| 37 | + .release = &gio_bus_release, | |
| 32 | 38 | }; |
| 33 | 39 | |
| 34 | 40 | /** |
| @@ -413,8 +419,10 @@ int __init ip22_gio_init(void) · 378 unmodified lines | ||
| 413 | 419 | int ret; |
| 414 | 420 | |
| 415 | 421 | ret = device_register(&gio_bus); |
| 416 | − if (ret) | |
| 422 | + if (ret) { | |
| 423 | + put_device(&gio_bus); | |
| 417 | 424 | return ret; |
| 425 | + } | |
| 418 | 426 | |
| 419 | 427 | ret = bus_register(&gio_bus_type); |
| 420 | 428 | if (!ret) { |
| @@ -83,6 +83,11 @@ static struct bus_type tx_7segled_subsys = { · 82 unmodified lines | ||
| 83 | 83 | .dev_name = "7segled", |
| 84 | 84 | }; |
| 85 | 85 | |
| 86 | +static void tx_7segled_release(struct device *dev) | |
| 87 | +{ | |
| 88 | + kfree(dev); | |
| 89 | +} | |
| 90 | + | |
| 86 | 91 | static int __init tx_7segled_init_sysfs(void) |
| 87 | 92 | { |
| 88 | 93 | int error, i; |
| @@ -103,11 +108,14 @@ static int __init tx_7segled_init_sysfs(void) · 14 unmodified lines | ||
| 103 | 108 | } |
| 104 | 109 | dev->id = i; |
| 105 | 110 | dev->bus = &tx_7segled_subsys; |
| 111 | + dev->release = &tx_7segled_release; | |
| 106 | 112 | error = device_register(dev); |
| 107 | − if (!error) { | |
| 108 | − device_create_file(dev, &dev_attr_ascii); | |
| 109 | − device_create_file(dev, &dev_attr_raw); | |
| 113 | + if (error) { | |
| 114 | + put_device(dev); | |
| 115 | + return error; | |
| 110 | 116 | } |
| 117 | + device_create_file(dev, &dev_attr_ascii); | |
| 118 | + device_create_file(dev, &dev_attr_raw); | |
| 111 | 119 | } |
| 112 | 120 | return error; |
| 113 | 121 | } |
| @@ -268,7 +268,7 @@ static int txx9_i8259_irq_setup(int irq) · 267 unmodified lines | ||
| 268 | 268 | return err; |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | −static void quirk_slc90e66_bridge(struct pci_dev *dev) | |
| 271 | +static void __init_refok quirk_slc90e66_bridge(struct pci_dev *dev) | |
| 272 | 272 | { |
| 273 | 273 | int irq; /* PCI/ISA Bridge interrupt */ |
| 274 | 274 | u8 reg_64; |
| @@ -331,7 +331,7 @@ static void quirk_slc90e66_ide(struct pci_dev *dev) · 56 unmodified lines | ||
| 331 | 331 | * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! |
| 332 | 332 | */ |
| 333 | 333 | dat |= 0x01; |
| 334 | − pci_write_config_byte(dev, regs[i], dat); | |
| 334 | + pci_write_config_byte(dev, 0x5c, dat); | |
| 335 | 335 | pci_read_config_byte(dev, 0x5c, &dat); |
| 336 | 336 | printk(KERN_CONT " REG5C %02x", dat); |
| 337 | 337 | printk(KERN_CONT "\n"); |
| @@ -937,6 +937,14 @@ static ssize_t txx9_sram_write(struct file *filp, struct kobject *kobj, · 936 unmodified lines | ||
| 937 | 937 | return size; |
| 938 | 938 | } |
| 939 | 939 | |
| 940 | +static void txx9_device_release(struct device *dev) | |
| 941 | +{ | |
| 942 | + struct txx9_sramc_dev *tdev; | |
| 943 | + | |
| 944 | + tdev = container_of(dev, struct txx9_sramc_dev, dev); | |
| 945 | + kfree(tdev); | |
| 946 | +} | |
| 947 | + | |
| 940 | 948 | void __init txx9_sramc_init(struct resource *r) |
| 941 | 949 | { |
| 942 | 950 | struct txx9_sramc_dev *dev; |
| @@ -951,8 +959,11 @@ void __init txx9_sramc_init(struct resource *r) · 8 unmodified lines | ||
| 951 | 959 | return; |
| 952 | 960 | size = resource_size(r); |
| 953 | 961 | dev->base = ioremap(r->start, size); |
| 954 | − if (!dev->base) | |
| 955 | − goto exit; | |
| 962 | + if (!dev->base) { | |
| 963 | + kfree(dev); | |
| 964 | + return; | |
| 965 | + } | |
| 966 | + dev->dev.release = &txx9_device_release; | |
| 956 | 967 | dev->dev.bus = &txx9_sramc_subsys; |
| 957 | 968 | sysfs_bin_attr_init(&dev->bindata_attr); |
| 958 | 969 | dev->bindata_attr.attr.name = "bindata"; |
| @@ -963,17 +974,15 @@ void __init txx9_sramc_init(struct resource *r) · 4 unmodified lines | ||
| 963 | 974 | dev->bindata_attr.private = dev; |
| 964 | 975 | err = device_register(&dev->dev); |
| 965 | 976 | if (err) |
| 966 | − goto exit; | |
| 977 | + goto exit_put; | |
| 967 | 978 | err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr); |
| 968 | 979 | if (err) { |
| 969 | 980 | device_unregister(&dev->dev); |
| 970 | − goto exit; | |
| 971 | − } | |
| 972 | − return; | |
| 973 | −exit: | |
| 974 | − if (dev) { | |
| 975 | − if (dev->base) | |
| 976 | − iounmap(dev->base); | |
| 981 | + iounmap(dev->base); | |
| 977 | 982 | kfree(dev); |
| 978 | 983 | } |
| 984 | + return; | |
| 985 | +exit_put: | |
| 986 | + put_device(&dev->dev); | |
| 987 | + return; | |
| 979 | 988 | } |
| @@ -148,9 +148,9 @@ static void loongson2_cpu_wait(void) · 147 unmodified lines | ||
| 148 | 148 | u32 cpu_freq; |
| 149 | 149 | |
| 150 | 150 | spin_lock_irqsave(&loongson2_wait_lock, flags); |
| 151 | − cpu_freq = LOONGSON_CHIPCFG0; | |
| 152 | − LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ | |
| 153 | − LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */ | |
| 151 | + cpu_freq = LOONGSON_CHIPCFG(0); | |
| 152 | + LOONGSON_CHIPCFG(0) &= ~0x7; /* Put CPU into wait mode */ | |
| 153 | + LOONGSON_CHIPCFG(0) = cpu_freq; /* Restore CPU state */ | |
| 154 | 154 | spin_unlock_irqrestore(&loongson2_wait_lock, flags); |
| 155 | 155 | local_irq_enable(); |
| 156 | 156 | } |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | * (the low to high transition will not occur). |
| 33 | 33 | */ |
| 34 | 34 | |
| 35 | +#include <linux/clk.h> | |
| 35 | 36 | #include <linux/module.h> |
| 36 | 37 | #include <linux/init.h> |
| 37 | 38 | #include <linux/platform_device.h> |
| @@ -90,7 +91,7 @@ struct au1xmmc_host { · 52 unmodified lines | ||
| 90 | 91 | struct mmc_request *mrq; |
| 91 | 92 | |
| 92 | 93 | u32 flags; |
| 93 | − u32 iobase; | |
| 94 | + void __iomem *iobase; | |
| 94 | 95 | u32 clock; |
| 95 | 96 | u32 bus_width; |
| 96 | 97 | u32 power_mode; |
| @@ -118,6 +119,7 @@ struct au1xmmc_host { · 21 unmodified lines | ||
| 118 | 119 | struct au1xmmc_platform_data *platdata; |
| 119 | 120 | struct platform_device *pdev; |
| 120 | 121 | struct resource *ioarea; |
| 122 | + struct clk *clk; | |
| 121 | 123 | }; |
| 122 | 124 | |
| 123 | 125 | /* Status flags used by the host structure */ |
| @@ -162,32 +164,33 @@ static inline int has_dbdma(void) · 38 unmodified lines | ||
| 162 | 164 | |
| 163 | 165 | static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) |
| 164 | 166 | { |
| 165 | − u32 val = au_readl(HOST_CONFIG(host)); | |
| 167 | + u32 val = __raw_readl(HOST_CONFIG(host)); | |
| 166 | 168 | val |= mask; |
| 167 | − au_writel(val, HOST_CONFIG(host)); | |
| 168 | − au_sync(); | |
| 169 | + __raw_writel(val, HOST_CONFIG(host)); | |
| 170 | + wmb(); /* drain writebuffer */ | |
| 169 | 171 | } |
| 170 | 172 | |
| 171 | 173 | static inline void FLUSH_FIFO(struct au1xmmc_host *host) |
| 172 | 174 | { |
| 173 | − u32 val = au_readl(HOST_CONFIG2(host)); | |
| 175 | + u32 val = __raw_readl(HOST_CONFIG2(host)); | |
| 174 | 176 | |
| 175 | − au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host)); | |
| 176 | − au_sync_delay(1); | |
| 177 | + __raw_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host)); | |
| 178 | + wmb(); /* drain writebuffer */ | |
| 179 | + mdelay(1); | |
| 177 | 180 | |
| 178 | 181 | /* SEND_STOP will turn off clock control - this re-enables it */ |
| 179 | 182 | val &= ~SD_CONFIG2_DF; |
| 180 | 183 | |
| 181 | − au_writel(val, HOST_CONFIG2(host)); | |
| 182 | − au_sync(); | |
| 184 | + __raw_writel(val, HOST_CONFIG2(host)); | |
| 185 | + wmb(); /* drain writebuffer */ | |
| 183 | 186 | } |
| 184 | 187 | |
| 185 | 188 | static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask) |
| 186 | 189 | { |
| 187 | − u32 val = au_readl(HOST_CONFIG(host)); | |
| 190 | + u32 val = __raw_readl(HOST_CONFIG(host)); | |
| 188 | 191 | val &= ~mask; |
| 189 | − au_writel(val, HOST_CONFIG(host)); | |
| 190 | − au_sync(); | |
| 192 | + __raw_writel(val, HOST_CONFIG(host)); | |
| 193 | + wmb(); /* drain writebuffer */ | |
| 191 | 194 | } |
| 192 | 195 | |
| 193 | 196 | static inline void SEND_STOP(struct au1xmmc_host *host) |
| @@ -197,12 +200,13 @@ static inline void SEND_STOP(struct au1xmmc_host *host) · 3 unmodified lines | ||
| 197 | 200 | WARN_ON(host->status != HOST_S_DATA); |
| 198 | 201 | host->status = HOST_S_STOP; |
| 199 | 202 | |
| 200 | − config2 = au_readl(HOST_CONFIG2(host)); | |
| 201 | − au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); | |
| 202 | − au_sync(); | |
| 203 | + config2 = __raw_readl(HOST_CONFIG2(host)); | |
| 204 | + __raw_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); | |
| 205 | + wmb(); /* drain writebuffer */ | |
| 203 | 206 | |
| 204 | 207 | /* Send the stop command */ |
| 205 | − au_writel(STOP_CMD, HOST_CMD(host)); | |
| 208 | + __raw_writel(STOP_CMD, HOST_CMD(host)); | |
| 209 | + wmb(); /* drain writebuffer */ | |
| 206 | 210 | } |
| 207 | 211 | |
| 208 | 212 | static void au1xmmc_set_power(struct au1xmmc_host *host, int state) |
| @@ -296,28 +300,28 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, · 87 unmodified lines | ||
| 296 | 300 | } |
| 297 | 301 | } |
| 298 | 302 | |
| 299 | − au_writel(cmd->arg, HOST_CMDARG(host)); | |
| 300 | − au_sync(); | |
| 303 | + __raw_writel(cmd->arg, HOST_CMDARG(host)); | |
| 304 | + wmb(); /* drain writebuffer */ | |
| 301 | 305 | |
| 302 | 306 | if (wait) |
| 303 | 307 | IRQ_OFF(host, SD_CONFIG_CR); |
| 304 | 308 | |
| 305 | − au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); | |
| 306 | − au_sync(); | |
| 309 | + __raw_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); | |
| 310 | + wmb(); /* drain writebuffer */ | |
| 307 | 311 | |
| 308 | 312 | /* Wait for the command to go on the line */ |
| 309 | − while (au_readl(HOST_CMD(host)) & SD_CMD_GO) | |
| 313 | + while (__raw_readl(HOST_CMD(host)) & SD_CMD_GO) | |
| 310 | 314 | /* nop */; |
| 311 | 315 | |
| 312 | 316 | /* Wait for the command to come back */ |
| 313 | 317 | if (wait) { |
| 314 | − u32 status = au_readl(HOST_STATUS(host)); | |
| 318 | + u32 status = __raw_readl(HOST_STATUS(host)); | |
| 315 | 319 | |
| 316 | 320 | while (!(status & SD_STATUS_CR)) |
| 317 | − status = au_readl(HOST_STATUS(host)); | |
| 321 | + status = __raw_readl(HOST_STATUS(host)); | |
| 318 | 322 | |
| 319 | 323 | /* Clear the CR status */ |
| 320 | − au_writel(SD_STATUS_CR, HOST_STATUS(host)); | |
| 324 | + __raw_writel(SD_STATUS_CR, HOST_STATUS(host)); | |
| 321 | 325 | |
| 322 | 326 | IRQ_ON(host, SD_CONFIG_CR); |
| 323 | 327 | } |
| @@ -339,11 +343,11 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) · 15 unmodified lines | ||
| 339 | 343 | data = mrq->cmd->data; |
| 340 | 344 | |
| 341 | 345 | if (status == 0) |
| 342 | − status = au_readl(HOST_STATUS(host)); | |
| 346 | + status = __raw_readl(HOST_STATUS(host)); | |
| 343 | 347 | |
| 344 | 348 | /* The transaction is really over when the SD_STATUS_DB bit is clear */ |
| 345 | 349 | while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) |
| 346 | − status = au_readl(HOST_STATUS(host)); | |
| 350 | + status = __raw_readl(HOST_STATUS(host)); | |
| 347 | 351 | |
| 348 | 352 | data->error = 0; |
| 349 | 353 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); |
| @@ -357,7 +361,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) · 7 unmodified lines | ||
| 357 | 361 | data->error = -EILSEQ; |
| 358 | 362 | |
| 359 | 363 | /* Clear the CRC bits */ |
| 360 | − au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); | |
| 364 | + __raw_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); | |
| 361 | 365 | |
| 362 | 366 | data->bytes_xfered = 0; |
| 363 | 367 | |
| @@ -380,7 +384,7 @@ static void au1xmmc_tasklet_data(unsigned long param) · 16 unmodified lines | ||
| 380 | 384 | { |
| 381 | 385 | struct au1xmmc_host *host = (struct au1xmmc_host *)param; |
| 382 | 386 | |
| 383 | − u32 status = au_readl(HOST_STATUS(host)); | |
| 387 | + u32 status = __raw_readl(HOST_STATUS(host)); | |
| 384 | 388 | au1xmmc_data_complete(host, status); |
| 385 | 389 | } |
| 386 | 390 | |
| @@ -412,15 +416,15 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) · 25 unmodified lines | ||
| 412 | 416 | max = AU1XMMC_MAX_TRANSFER; |
| 413 | 417 | |
| 414 | 418 | for (count = 0; count < max; count++) { |
| 415 | − status = au_readl(HOST_STATUS(host)); | |
| 419 | + status = __raw_readl(HOST_STATUS(host)); | |
| 416 | 420 | |
| 417 | 421 | if (!(status & SD_STATUS_TH)) |
| 418 | 422 | break; |
| 419 | 423 | |
| 420 | 424 | val = *sg_ptr++; |
| 421 | 425 | |
| 422 | − au_writel((unsigned long)val, HOST_TXPORT(host)); | |
| 423 | − au_sync(); | |
| 426 | + __raw_writel((unsigned long)val, HOST_TXPORT(host)); | |
| 427 | + wmb(); /* drain writebuffer */ | |
| 424 | 428 | } |
| 425 | 429 | |
| 426 | 430 | host->pio.len -= count; |
| @@ -472,7 +476,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) · 45 unmodified lines | ||
| 472 | 476 | max = AU1XMMC_MAX_TRANSFER; |
| 473 | 477 | |
| 474 | 478 | for (count = 0; count < max; count++) { |
| 475 | − status = au_readl(HOST_STATUS(host)); | |
| 479 | + status = __raw_readl(HOST_STATUS(host)); | |
| 476 | 480 | |
| 477 | 481 | if (!(status & SD_STATUS_NE)) |
| 478 | 482 | break; |
| @@ -494,7 +498,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) · 15 unmodified lines | ||
| 494 | 498 | break; |
| 495 | 499 | } |
| 496 | 500 | |
| 497 | − val = au_readl(HOST_RXPORT(host)); | |
| 501 | + val = __raw_readl(HOST_RXPORT(host)); | |
| 498 | 502 | |
| 499 | 503 | if (sg_ptr) |
| 500 | 504 | *sg_ptr++ = (unsigned char)(val & 0xFF); |
| @@ -537,10 +541,10 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) · 36 unmodified lines | ||
| 537 | 541 | |
| 538 | 542 | if (cmd->flags & MMC_RSP_PRESENT) { |
| 539 | 543 | if (cmd->flags & MMC_RSP_136) { |
| 540 | − r[0] = au_readl(host->iobase + SD_RESP3); | |
| 541 | − r[1] = au_readl(host->iobase + SD_RESP2); | |
| 542 | − r[2] = au_readl(host->iobase + SD_RESP1); | |
| 543 | − r[3] = au_readl(host->iobase + SD_RESP0); | |
| 544 | + r[0] = __raw_readl(host->iobase + SD_RESP3); | |
| 545 | + r[1] = __raw_readl(host->iobase + SD_RESP2); | |
| 546 | + r[2] = __raw_readl(host->iobase + SD_RESP1); | |
| 547 | + r[3] = __raw_readl(host->iobase + SD_RESP0); | |
| 544 | 548 | |
| 545 | 549 | /* The CRC is omitted from the response, so really |
| 546 | 550 | * we only got 120 bytes, but the engine expects |
| @@ -559,7 +563,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) · 12 unmodified lines | ||
| 559 | 563 | * that means that the OSR data starts at bit 31, |
| 560 | 564 | * so we can just read RESP0 and return that. |
| 561 | 565 | */ |
| 562 | − cmd->resp[0] = au_readl(host->iobase + SD_RESP0); | |
| 566 | + cmd->resp[0] = __raw_readl(host->iobase + SD_RESP0); | |
| 563 | 567 | } |
| 564 | 568 | } |
| 565 | 569 | |
| @@ -586,7 +590,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) · 20 unmodified lines | ||
| 586 | 590 | u32 mask = SD_STATUS_DB | SD_STATUS_NE; |
| 587 | 591 | |
| 588 | 592 | while((status & mask) != mask) |
| 589 | − status = au_readl(HOST_STATUS(host)); | |
| 593 | + status = __raw_readl(HOST_STATUS(host)); | |
| 590 | 594 | } |
| 591 | 595 | |
| 592 | 596 | au1xxx_dbdma_start(channel); |
| @@ -595,24 +599,17 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) · 2 unmodified lines | ||
| 595 | 599 | |
| 596 | 600 | static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) |
| 597 | 601 | { |
| 598 | − unsigned int pbus = get_au1x00_speed(); | |
| 599 | − unsigned int divisor; | |
| 602 | + unsigned int pbus = clk_get_rate(host->clk); | |
| 603 | + unsigned int divisor = ((pbus / rate) / 2) - 1; | |
| 600 | 604 | u32 config; |
| 601 | 605 | |
| 602 | − /* From databook: | |
| 603 | − * divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1 | |
| 604 | − */ | |
| 605 | − pbus /= ((au_readl(SYS_POWERCTRL) & 0x3) + 2); | |
| 606 | − pbus /= 2; | |
| 607 | − divisor = ((pbus / rate) / 2) - 1; | |
| 608 | − | |
| 609 | − config = au_readl(HOST_CONFIG(host)); | |
| 606 | + config = __raw_readl(HOST_CONFIG(host)); | |
| 610 | 607 | |
| 611 | 608 | config &= ~(SD_CONFIG_DIV); |
| 612 | 609 | config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE; |
| 613 | 610 | |
| 614 | − au_writel(config, HOST_CONFIG(host)); | |
| 615 | − au_sync(); | |
| 611 | + __raw_writel(config, HOST_CONFIG(host)); | |
| 612 | + wmb(); /* drain writebuffer */ | |
| 616 | 613 | } |
| 617 | 614 | |
| 618 | 615 | static int au1xmmc_prepare_data(struct au1xmmc_host *host, |
| @@ -636,7 +633,7 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, · 17 unmodified lines | ||
| 636 | 633 | if (host->dma.len == 0) |
| 637 | 634 | return -ETIMEDOUT; |
| 638 | 635 | |
| 639 | − au_writel(data->blksz - 1, HOST_BLKSIZE(host)); | |
| 636 | + __raw_writel(data->blksz - 1, HOST_BLKSIZE(host)); | |
| 640 | 637 | |
| 641 | 638 | if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) { |
| 642 | 639 | int i; |
| @@ -723,31 +720,34 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) · 80 unmodified lines | ||
| 723 | 720 | static void au1xmmc_reset_controller(struct au1xmmc_host *host) |
| 724 | 721 | { |
| 725 | 722 | /* Apply the clock */ |
| 726 | − au_writel(SD_ENABLE_CE, HOST_ENABLE(host)); | |
| 727 | − au_sync_delay(1); | |
| 723 | + __raw_writel(SD_ENABLE_CE, HOST_ENABLE(host)); | |
| 724 | + wmb(); /* drain writebuffer */ | |
| 725 | + mdelay(1); | |
| 728 | 726 | |
| 729 | − au_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host)); | |
| 730 | − au_sync_delay(5); | |
| 727 | + __raw_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host)); | |
| 728 | + wmb(); /* drain writebuffer */ | |
| 729 | + mdelay(5); | |
| 731 | 730 | |
| 732 | − au_writel(~0, HOST_STATUS(host)); | |
| 733 | − au_sync(); | |
| 731 | + __raw_writel(~0, HOST_STATUS(host)); | |
| 732 | + wmb(); /* drain writebuffer */ | |
| 734 | 733 | |
| 735 | − au_writel(0, HOST_BLKSIZE(host)); | |
| 736 | − au_writel(0x001fffff, HOST_TIMEOUT(host)); | |
| 737 | − au_sync(); | |
| 734 | + __raw_writel(0, HOST_BLKSIZE(host)); | |
| 735 | + __raw_writel(0x001fffff, HOST_TIMEOUT(host)); | |
| 736 | + wmb(); /* drain writebuffer */ | |
| 738 | 737 | |
| 739 | − au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); | |
| 740 | − au_sync(); | |
| 738 | + __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); | |
| 739 | + wmb(); /* drain writebuffer */ | |
| 741 | 740 | |
| 742 | − au_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host)); | |
| 743 | − au_sync_delay(1); | |
| 741 | + __raw_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host)); | |
| 742 | + wmb(); /* drain writebuffer */ | |
| 743 | + mdelay(1); | |
| 744 | 744 | |
| 745 | − au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); | |
| 746 | − au_sync(); | |
| 745 | + __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); | |
| 746 | + wmb(); /* drain writebuffer */ | |
| 747 | 747 | |
| 748 | 748 | /* Configure interrupts */ |
| 749 | − au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host)); | |
| 750 | − au_sync(); | |
| 749 | + __raw_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host)); | |
| 750 | + wmb(); /* drain writebuffer */ | |
| 751 | 751 | } |
| 752 | 752 | |
| 753 | 753 | |
| @@ -767,7 +767,7 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 13 unmodified lines | ||
| 767 | 767 | host->clock = ios->clock; |
| 768 | 768 | } |
| 769 | 769 | |
| 770 | − config2 = au_readl(HOST_CONFIG2(host)); | |
| 770 | + config2 = __raw_readl(HOST_CONFIG2(host)); | |
| 771 | 771 | switch (ios->bus_width) { |
| 772 | 772 | case MMC_BUS_WIDTH_8: |
| 773 | 773 | config2 |= SD_CONFIG2_BB; |
| @@ -780,8 +780,8 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 6 unmodified lines | ||
| 780 | 780 | config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB); |
| 781 | 781 | break; |
| 782 | 782 | } |
| 783 | − au_writel(config2, HOST_CONFIG2(host)); | |
| 784 | − au_sync(); | |
| 783 | + __raw_writel(config2, HOST_CONFIG2(host)); | |
| 784 | + wmb(); /* drain writebuffer */ | |
| 785 | 785 | } |
| 786 | 786 | |
| 787 | 787 | #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) |
| @@ -793,7 +793,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) · 5 unmodified lines | ||
| 793 | 793 | struct au1xmmc_host *host = dev_id; |
| 794 | 794 | u32 status; |
| 795 | 795 | |
| 796 | − status = au_readl(HOST_STATUS(host)); | |
| 796 | + status = __raw_readl(HOST_STATUS(host)); | |
| 797 | 797 | |
| 798 | 798 | if (!(status & SD_STATUS_I)) |
| 799 | 799 | return IRQ_NONE; /* not ours */ |
| @@ -839,8 +839,8 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) · 39 unmodified lines | ||
| 839 | 839 | status); |
| 840 | 840 | } |
| 841 | 841 | |
| 842 | − au_writel(status, HOST_STATUS(host)); | |
| 843 | − au_sync(); | |
| 842 | + __raw_writel(status, HOST_STATUS(host)); | |
| 843 | + wmb(); /* drain writebuffer */ | |
| 844 | 844 | |
| 845 | 845 | return IRQ_HANDLED; |
| 846 | 846 | } |
| @@ -976,7 +976,7 @@ static int au1xmmc_probe(struct platform_device *pdev) · 129 unmodified lines | ||
| 976 | 976 | goto out1; |
| 977 | 977 | } |
| 978 | 978 | |
| 979 | − host->iobase = (unsigned long)ioremap(r->start, 0x3c); | |
| 979 | + host->iobase = ioremap(r->start, 0x3c); | |
| 980 | 980 | if (!host->iobase) { |
| 981 | 981 | dev_err(&pdev->dev, "cannot remap mmio\n"); |
| 982 | 982 | goto out2; |
| @@ -1025,6 +1025,16 @@ static int au1xmmc_probe(struct platform_device *pdev) · 42 unmodified lines | ||
| 1025 | 1025 | goto out3; |
| 1026 | 1026 | } |
| 1027 | 1027 | |
| 1028 | + host->clk = clk_get(&pdev->dev, ALCHEMY_PERIPH_CLK); | |
| 1029 | + if (IS_ERR(host->clk)) { | |
| 1030 | + dev_err(&pdev->dev, "cannot find clock\n"); | |
| 1031 | + goto out_irq; | |
| 1032 | + } | |
| 1033 | + if (clk_prepare_enable(host->clk)) { | |
| 1034 | + dev_err(&pdev->dev, "cannot enable clock\n"); | |
| 1035 | + goto out_clk; | |
| 1036 | + } | |
| 1037 | + | |
| 1028 | 1038 | host->status = HOST_S_IDLE; |
| 1029 | 1039 | |
| 1030 | 1040 | /* board-specific carddetect setup, if any */ |
| @@ -1075,7 +1085,7 @@ static int au1xmmc_probe(struct platform_device *pdev) · 44 unmodified lines | ||
| 1075 | 1085 | |
| 1076 | 1086 | platform_set_drvdata(pdev, host); |
| 1077 | 1087 | |
| 1078 | − pr_info(DRIVER_NAME ": MMC Controller %d set up at %8.8X" | |
| 1088 | + pr_info(DRIVER_NAME ": MMC Controller %d set up at %p" | |
| 1079 | 1089 | " (mode=%s)\n", pdev->id, host->iobase, |
| 1080 | 1090 | host->flags & HOST_F_DMA ? "dma" : "pio"); |
| 1081 | 1091 | |
| @@ -1087,10 +1097,10 @@ out6: · 5 unmodified lines | ||
| 1087 | 1097 | led_classdev_unregister(host->platdata->led); |
| 1088 | 1098 | out5: |
| 1089 | 1099 | #endif |
| 1090 | − au_writel(0, HOST_ENABLE(host)); | |
| 1091 | − au_writel(0, HOST_CONFIG(host)); | |
| 1092 | − au_writel(0, HOST_CONFIG2(host)); | |
| 1093 | − au_sync(); | |
| 1100 | + __raw_writel(0, HOST_ENABLE(host)); | |
| 1101 | + __raw_writel(0, HOST_CONFIG(host)); | |
| 1102 | + __raw_writel(0, HOST_CONFIG2(host)); | |
| 1103 | + wmb(); /* drain writebuffer */ | |
| 1094 | 1104 | |
| 1095 | 1105 | if (host->flags & HOST_F_DBDMA) |
| 1096 | 1106 | au1xmmc_dbdma_shutdown(host); |
| @@ -1101,7 +1111,10 @@ out5: · 4 unmodified lines | ||
| 1101 | 1111 | if (host->platdata && host->platdata->cd_setup && |
| 1102 | 1112 | !(mmc->caps & MMC_CAP_NEEDS_POLL)) |
| 1103 | 1113 | host->platdata->cd_setup(mmc, 0); |
| 1104 | − | |
| 1114 | +out_clk: | |
| 1115 | + clk_disable_unprepare(host->clk); | |
| 1116 | + clk_put(host->clk); | |
| 1117 | +out_irq: | |
| 1105 | 1118 | free_irq(host->irq, host); |
| 1106 | 1119 | out3: |
| 1107 | 1120 | iounmap((void *)host->iobase); |
| @@ -1130,10 +1143,10 @@ static int au1xmmc_remove(struct platform_device *pdev) · 22 unmodified lines | ||
| 1130 | 1143 | !(host->mmc->caps & MMC_CAP_NEEDS_POLL)) |
| 1131 | 1144 | host->platdata->cd_setup(host->mmc, 0); |
| 1132 | 1145 | |
| 1133 | − au_writel(0, HOST_ENABLE(host)); | |
| 1134 | − au_writel(0, HOST_CONFIG(host)); | |
| 1135 | − au_writel(0, HOST_CONFIG2(host)); | |
| 1136 | − au_sync(); | |
| 1146 | + __raw_writel(0, HOST_ENABLE(host)); | |
| 1147 | + __raw_writel(0, HOST_CONFIG(host)); | |
| 1148 | + __raw_writel(0, HOST_CONFIG2(host)); | |
| 1149 | + wmb(); /* drain writebuffer */ | |
| 1137 | 1150 | |
| 1138 | 1151 | tasklet_kill(&host->data_task); |
| 1139 | 1152 | tasklet_kill(&host->finish_task); |
| @@ -1143,6 +1156,9 @@ static int au1xmmc_remove(struct platform_device *pdev) · 3 unmodified lines | ||
| 1143 | 1156 | |
| 1144 | 1157 | au1xmmc_set_power(host, 0); |
| 1145 | 1158 | |
| 1159 | + clk_disable_unprepare(host->clk); | |
| 1160 | + clk_put(host->clk); | |
| 1161 | + | |
| 1146 | 1162 | free_irq(host->irq, host); |
| 1147 | 1163 | iounmap((void *)host->iobase); |
| 1148 | 1164 | release_resource(host->ioarea); |
| @@ -1158,11 +1174,11 @@ static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state) · 9 unmodified lines | ||
| 1158 | 1174 | { |
| 1159 | 1175 | struct au1xmmc_host *host = platform_get_drvdata(pdev); |
| 1160 | 1176 | |
| 1161 | − au_writel(0, HOST_CONFIG2(host)); | |
| 1162 | − au_writel(0, HOST_CONFIG(host)); | |
| 1163 | − au_writel(0xffffffff, HOST_STATUS(host)); | |
| 1164 | − au_writel(0, HOST_ENABLE(host)); | |
| 1165 | − au_sync(); | |
| 1177 | + __raw_writel(0, HOST_CONFIG2(host)); | |
| 1178 | + __raw_writel(0, HOST_CONFIG(host)); | |
| 1179 | + __raw_writel(0xffffffff, HOST_STATUS(host)); | |
| 1180 | + __raw_writel(0, HOST_ENABLE(host)); | |
| 1181 | + wmb(); /* drain writebuffer */ | |
| 1166 | 1182 | |
| 1167 | 1183 | return 0; |
| 1168 | 1184 | } |
| @@ -41,7 +41,7 @@ static u_char au_read_byte(struct mtd_info *mtd) · 40 unmodified lines | ||
| 41 | 41 | { |
| 42 | 42 | struct nand_chip *this = mtd->priv; |
| 43 | 43 | u_char ret = readb(this->IO_ADDR_R); |
| 44 | − au_sync(); | |
| 44 | + wmb(); /* drain writebuffer */ | |
| 45 | 45 | return ret; |
| 46 | 46 | } |
| 47 | 47 | |
| @@ -56,7 +56,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte) · 8 unmodified lines | ||
| 56 | 56 | { |
| 57 | 57 | struct nand_chip *this = mtd->priv; |
| 58 | 58 | writeb(byte, this->IO_ADDR_W); |
| 59 | − au_sync(); | |
| 59 | + wmb(); /* drain writebuffer */ | |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | /** |
| @@ -69,7 +69,7 @@ static u_char au_read_byte16(struct mtd_info *mtd) · 6 unmodified lines | ||
| 69 | 69 | { |
| 70 | 70 | struct nand_chip *this = mtd->priv; |
| 71 | 71 | u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); |
| 72 | − au_sync(); | |
| 72 | + wmb(); /* drain writebuffer */ | |
| 73 | 73 | return ret; |
| 74 | 74 | } |
| 75 | 75 | |
| @@ -84,7 +84,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte) · 8 unmodified lines | ||
| 84 | 84 | { |
| 85 | 85 | struct nand_chip *this = mtd->priv; |
| 86 | 86 | writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); |
| 87 | − au_sync(); | |
| 87 | + wmb(); /* drain writebuffer */ | |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | /** |
| @@ -97,7 +97,7 @@ static u16 au_read_word(struct mtd_info *mtd) · 6 unmodified lines | ||
| 97 | 97 | { |
| 98 | 98 | struct nand_chip *this = mtd->priv; |
| 99 | 99 | u16 ret = readw(this->IO_ADDR_R); |
| 100 | − au_sync(); | |
| 100 | + wmb(); /* drain writebuffer */ | |
| 101 | 101 | return ret; |
| 102 | 102 | } |
| 103 | 103 | |
| @@ -116,7 +116,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) · 12 unmodified lines | ||
| 116 | 116 | |
| 117 | 117 | for (i = 0; i < len; i++) { |
| 118 | 118 | writeb(buf[i], this->IO_ADDR_W); |
| 119 | − au_sync(); | |
| 119 | + wmb(); /* drain writebuffer */ | |
| 120 | 120 | } |
| 121 | 121 | } |
| 122 | 122 | |
| @@ -135,7 +135,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) · 12 unmodified lines | ||
| 135 | 135 | |
| 136 | 136 | for (i = 0; i < len; i++) { |
| 137 | 137 | buf[i] = readb(this->IO_ADDR_R); |
| 138 | − au_sync(); | |
| 138 | + wmb(); /* drain writebuffer */ | |
| 139 | 139 | } |
| 140 | 140 | } |
| 141 | 141 | |
| @@ -156,7 +156,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) · 14 unmodified lines | ||
| 156 | 156 | |
| 157 | 157 | for (i = 0; i < len; i++) { |
| 158 | 158 | writew(p[i], this->IO_ADDR_W); |
| 159 | − au_sync(); | |
| 159 | + wmb(); /* drain writebuffer */ | |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | } |
| @@ -178,7 +178,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) · 15 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | for (i = 0; i < len; i++) { |
| 180 | 180 | p[i] = readw(this->IO_ADDR_R); |
| 181 | − au_sync(); | |
| 181 | + wmb(); /* drain writebuffer */ | |
| 182 | 182 | } |
| 183 | 183 | } |
| 184 | 184 | |
| @@ -223,26 +223,23 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) · 38 unmodified lines | ||
| 223 | 223 | |
| 224 | 224 | case NAND_CTL_SETNCE: |
| 225 | 225 | /* assert (force assert) chip enable */ |
| 226 | − au_writel((1 << (4 + ctx->cs)), MEM_STNDCTL); | |
| 226 | + alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL); | |
| 227 | 227 | break; |
| 228 | 228 | |
| 229 | 229 | case NAND_CTL_CLRNCE: |
| 230 | 230 | /* deassert chip enable */ |
| 231 | − au_writel(0, MEM_STNDCTL); | |
| 231 | + alchemy_wrsmem(0, AU1000_MEM_STNDCTL); | |
| 232 | 232 | break; |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | 235 | this->IO_ADDR_R = this->IO_ADDR_W; |
| 236 | 236 | |
| 237 | − /* Drain the writebuffer */ | |
| 238 | − au_sync(); | |
| 237 | + wmb(); /* Drain the writebuffer */ | |
| 239 | 238 | } |
| 240 | 239 | |
| 241 | 240 | int au1550_device_ready(struct mtd_info *mtd) |
| 242 | 241 | { |
| 243 | − int ret = (au_readl(MEM_STSTAT) & 0x1) ? 1 : 0; | |
| 244 | − au_sync(); | |
| 245 | − return ret; | |
| 242 | + return (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1) ? 1 : 0; | |
| 246 | 243 | } |
| 247 | 244 | |
| 248 | 245 | /** |
| @@ -89,6 +89,124 @@ MODULE_DESCRIPTION(DRV_DESC); · 88 unmodified lines | ||
| 89 | 89 | MODULE_LICENSE("GPL"); |
| 90 | 90 | MODULE_VERSION(DRV_VERSION); |
| 91 | 91 | |
| 92 | +/* AU1000 MAC registers and bits */ | |
| 93 | +#define MAC_CONTROL 0x0 | |
| 94 | +# define MAC_RX_ENABLE (1 << 2) | |
| 95 | +# define MAC_TX_ENABLE (1 << 3) | |
| 96 | +# define MAC_DEF_CHECK (1 << 5) | |
| 97 | +# define MAC_SET_BL(X) (((X) & 0x3) << 6) | |
| 98 | +# define MAC_AUTO_PAD (1 << 8) | |
| 99 | +# define MAC_DISABLE_RETRY (1 << 10) | |
| 100 | +# define MAC_DISABLE_BCAST (1 << 11) | |
| 101 | +# define MAC_LATE_COL (1 << 12) | |
| 102 | +# define MAC_HASH_MODE (1 << 13) | |
| 103 | +# define MAC_HASH_ONLY (1 << 15) | |
| 104 | +# define MAC_PASS_ALL (1 << 16) | |
| 105 | +# define MAC_INVERSE_FILTER (1 << 17) | |
| 106 | +# define MAC_PROMISCUOUS (1 << 18) | |
| 107 | +# define MAC_PASS_ALL_MULTI (1 << 19) | |
| 108 | +# define MAC_FULL_DUPLEX (1 << 20) | |
| 109 | +# define MAC_NORMAL_MODE 0 | |
| 110 | +# define MAC_INT_LOOPBACK (1 << 21) | |
| 111 | +# define MAC_EXT_LOOPBACK (1 << 22) | |
| 112 | +# define MAC_DISABLE_RX_OWN (1 << 23) | |
| 113 | +# define MAC_BIG_ENDIAN (1 << 30) | |
| 114 | +# define MAC_RX_ALL (1 << 31) | |
| 115 | +#define MAC_ADDRESS_HIGH 0x4 | |
| 116 | +#define MAC_ADDRESS_LOW 0x8 | |
| 117 | +#define MAC_MCAST_HIGH 0xC | |
| 118 | +#define MAC_MCAST_LOW 0x10 | |
| 119 | +#define MAC_MII_CNTRL 0x14 | |
| 120 | +# define MAC_MII_BUSY (1 << 0) | |
| 121 | +# define MAC_MII_READ 0 | |
| 122 | +# define MAC_MII_WRITE (1 << 1) | |
| 123 | +# define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6) | |
| 124 | +# define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11) | |
| 125 | +#define MAC_MII_DATA 0x18 | |
| 126 | +#define MAC_FLOW_CNTRL 0x1C | |
| 127 | +# define MAC_FLOW_CNTRL_BUSY (1 << 0) | |
| 128 | +# define MAC_FLOW_CNTRL_ENABLE (1 << 1) | |
| 129 | +# define MAC_PASS_CONTROL (1 << 2) | |
| 130 | +# define MAC_SET_PAUSE(X) (((X) & 0xffff) << 16) | |
| 131 | +#define MAC_VLAN1_TAG 0x20 | |
| 132 | +#define MAC_VLAN2_TAG 0x24 | |
| 133 | + | |
| 134 | +/* Ethernet Controller Enable */ | |
| 135 | +# define MAC_EN_CLOCK_ENABLE (1 << 0) | |
| 136 | +# define MAC_EN_RESET0 (1 << 1) | |
| 137 | +# define MAC_EN_TOSS (0 << 2) | |
| 138 | +# define MAC_EN_CACHEABLE (1 << 3) | |
| 139 | +# define MAC_EN_RESET1 (1 << 4) | |
| 140 | +# define MAC_EN_RESET2 (1 << 5) | |
| 141 | +# define MAC_DMA_RESET (1 << 6) | |
| 142 | + | |
| 143 | +/* Ethernet Controller DMA Channels */ | |
| 144 | +/* offsets from MAC_TX_RING_ADDR address */ | |
| 145 | +#define MAC_TX_BUFF0_STATUS 0x0 | |
| 146 | +# define TX_FRAME_ABORTED (1 << 0) | |
| 147 | +# define TX_JAB_TIMEOUT (1 << 1) | |
| 148 | +# define TX_NO_CARRIER (1 << 2) | |
| 149 | +# define TX_LOSS_CARRIER (1 << 3) | |
| 150 | +# define TX_EXC_DEF (1 << 4) | |
| 151 | +# define TX_LATE_COLL_ABORT (1 << 5) | |
| 152 | +# define TX_EXC_COLL (1 << 6) | |
| 153 | +# define TX_UNDERRUN (1 << 7) | |
| 154 | +# define TX_DEFERRED (1 << 8) | |
| 155 | +# define TX_LATE_COLL (1 << 9) | |
| 156 | +# define TX_COLL_CNT_MASK (0xF << 10) | |
| 157 | +# define TX_PKT_RETRY (1 << 31) | |
| 158 | +#define MAC_TX_BUFF0_ADDR 0x4 | |
| 159 | +# define TX_DMA_ENABLE (1 << 0) | |
| 160 | +# define TX_T_DONE (1 << 1) | |
| 161 | +# define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | |
| 162 | +#define MAC_TX_BUFF0_LEN 0x8 | |
| 163 | +#define MAC_TX_BUFF1_STATUS 0x10 | |
| 164 | +#define MAC_TX_BUFF1_ADDR 0x14 | |
| 165 | +#define MAC_TX_BUFF1_LEN 0x18 | |
| 166 | +#define MAC_TX_BUFF2_STATUS 0x20 | |
| 167 | +#define MAC_TX_BUFF2_ADDR 0x24 | |
| 168 | +#define MAC_TX_BUFF2_LEN 0x28 | |
| 169 | +#define MAC_TX_BUFF3_STATUS 0x30 | |
| 170 | +#define MAC_TX_BUFF3_ADDR 0x34 | |
| 171 | +#define MAC_TX_BUFF3_LEN 0x38 | |
| 172 | + | |
| 173 | +/* offsets from MAC_RX_RING_ADDR */ | |
| 174 | +#define MAC_RX_BUFF0_STATUS 0x0 | |
| 175 | +# define RX_FRAME_LEN_MASK 0x3fff | |
| 176 | +# define RX_WDOG_TIMER (1 << 14) | |
| 177 | +# define RX_RUNT (1 << 15) | |
| 178 | +# define RX_OVERLEN (1 << 16) | |
| 179 | +# define RX_COLL (1 << 17) | |
| 180 | +# define RX_ETHER (1 << 18) | |
| 181 | +# define RX_MII_ERROR (1 << 19) | |
| 182 | +# define RX_DRIBBLING (1 << 20) | |
| 183 | +# define RX_CRC_ERROR (1 << 21) | |
| 184 | +# define RX_VLAN1 (1 << 22) | |
| 185 | +# define RX_VLAN2 (1 << 23) | |
| 186 | +# define RX_LEN_ERROR (1 << 24) | |
| 187 | +# define RX_CNTRL_FRAME (1 << 25) | |
| 188 | +# define RX_U_CNTRL_FRAME (1 << 26) | |
| 189 | +# define RX_MCAST_FRAME (1 << 27) | |
| 190 | +# define RX_BCAST_FRAME (1 << 28) | |
| 191 | +# define RX_FILTER_FAIL (1 << 29) | |
| 192 | +# define RX_PACKET_FILTER (1 << 30) | |
| 193 | +# define RX_MISSED_FRAME (1 << 31) | |
| 194 | + | |
| 195 | +# define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \ | |
| 196 | + RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \ | |
| 197 | + RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME) | |
| 198 | +#define MAC_RX_BUFF0_ADDR 0x4 | |
| 199 | +# define RX_DMA_ENABLE (1 << 0) | |
| 200 | +# define RX_T_DONE (1 << 1) | |
| 201 | +# define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | |
| 202 | +# define RX_SET_BUFF_ADDR(X) ((X) & 0xffffffc0) | |
| 203 | +#define MAC_RX_BUFF1_STATUS 0x10 | |
| 204 | +#define MAC_RX_BUFF1_ADDR 0x14 | |
| 205 | +#define MAC_RX_BUFF2_STATUS 0x20 | |
| 206 | +#define MAC_RX_BUFF2_ADDR 0x24 | |
| 207 | +#define MAC_RX_BUFF3_STATUS 0x30 | |
| 208 | +#define MAC_RX_BUFF3_ADDR 0x34 | |
| 209 | + | |
| 92 | 210 | /* |
| 93 | 211 | * Theory of operation |
| 94 | 212 | * |
| @@ -152,10 +270,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) · 57 unmodified lines | ||
| 152 | 270 | |
| 153 | 271 | if (force_reset || (!aup->mac_enabled)) { |
| 154 | 272 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); |
| 155 | − au_sync_delay(2); | |
| 273 | + wmb(); /* drain writebuffer */ | |
| 274 | + mdelay(2); | |
| 156 | 275 | writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
| 157 | 276 | | MAC_EN_CLOCK_ENABLE), aup->enable); |
| 158 | − au_sync_delay(2); | |
| 277 | + wmb(); /* drain writebuffer */ | |
| 278 | + mdelay(2); | |
| 159 | 279 | |
| 160 | 280 | aup->mac_enabled = 1; |
| 161 | 281 | } |
| @@ -273,7 +393,8 @@ static void au1000_hard_stop(struct net_device *dev) · 111 unmodified lines | ||
| 273 | 393 | reg = readl(&aup->mac->control); |
| 274 | 394 | reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); |
| 275 | 395 | writel(reg, &aup->mac->control); |
| 276 | − au_sync_delay(10); | |
| 396 | + wmb(); /* drain writebuffer */ | |
| 397 | + mdelay(10); | |
| 277 | 398 | } |
| 278 | 399 | |
| 279 | 400 | static void au1000_enable_rx_tx(struct net_device *dev) |
| @@ -286,7 +407,8 @@ static void au1000_enable_rx_tx(struct net_device *dev) · 6 unmodified lines | ||
| 286 | 407 | reg = readl(&aup->mac->control); |
| 287 | 408 | reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE); |
| 288 | 409 | writel(reg, &aup->mac->control); |
| 289 | − au_sync_delay(10); | |
| 410 | + wmb(); /* drain writebuffer */ | |
| 411 | + mdelay(10); | |
| 290 | 412 | } |
| 291 | 413 | |
| 292 | 414 | static void |
| @@ -336,7 +458,8 @@ au1000_adjust_link(struct net_device *dev) · 43 unmodified lines | ||
| 336 | 458 | reg |= MAC_DISABLE_RX_OWN; |
| 337 | 459 | } |
| 338 | 460 | writel(reg, &aup->mac->control); |
| 339 | − au_sync_delay(1); | |
| 461 | + wmb(); /* drain writebuffer */ | |
| 462 | + mdelay(1); | |
| 340 | 463 | |
| 341 | 464 | au1000_enable_rx_tx(dev); |
| 342 | 465 | aup->old_duplex = phydev->duplex; |
| @@ -500,9 +623,11 @@ static void au1000_reset_mac_unlocked(struct net_device *dev) · 157 unmodified lines | ||
| 500 | 623 | au1000_hard_stop(dev); |
| 501 | 624 | |
| 502 | 625 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); |
| 503 | − au_sync_delay(2); | |
| 626 | + wmb(); /* drain writebuffer */ | |
| 627 | + mdelay(2); | |
| 504 | 628 | writel(0, aup->enable); |
| 505 | − au_sync_delay(2); | |
| 629 | + wmb(); /* drain writebuffer */ | |
| 630 | + mdelay(2); | |
| 506 | 631 | |
| 507 | 632 | aup->tx_full = 0; |
| 508 | 633 | for (i = 0; i < NUM_RX_DMA; i++) { |
| @@ -652,7 +777,7 @@ static int au1000_init(struct net_device *dev) · 143 unmodified lines | ||
| 652 | 777 | for (i = 0; i < NUM_RX_DMA; i++) |
| 653 | 778 | aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; |
| 654 | 779 | |
| 655 | − au_sync(); | |
| 780 | + wmb(); /* drain writebuffer */ | |
| 656 | 781 | |
| 657 | 782 | control = MAC_RX_ENABLE | MAC_TX_ENABLE; |
| 658 | 783 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
| @@ -669,7 +794,7 @@ static int au1000_init(struct net_device *dev) · 10 unmodified lines | ||
| 669 | 794 | |
| 670 | 795 | writel(control, &aup->mac->control); |
| 671 | 796 | writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */ |
| 672 | − au_sync(); | |
| 797 | + wmb(); /* drain writebuffer */ | |
| 673 | 798 | |
| 674 | 799 | spin_unlock_irqrestore(&aup->lock, flags); |
| 675 | 800 | return 0; |
| @@ -760,7 +885,7 @@ static int au1000_rx(struct net_device *dev) · 84 unmodified lines | ||
| 760 | 885 | } |
| 761 | 886 | prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); |
| 762 | 887 | aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1); |
| 763 | − au_sync(); | |
| 888 | + wmb(); /* drain writebuffer */ | |
| 764 | 889 | |
| 765 | 890 | /* next descriptor */ |
| 766 | 891 | prxd = aup->rx_dma_ring[aup->rx_head]; |
| @@ -808,7 +933,7 @@ static void au1000_tx_ack(struct net_device *dev) · 41 unmodified lines | ||
| 808 | 933 | au1000_update_tx_stats(dev, ptxd->status); |
| 809 | 934 | ptxd->buff_stat &= ~TX_T_DONE; |
| 810 | 935 | ptxd->len = 0; |
| 811 | − au_sync(); | |
| 936 | + wmb(); /* drain writebuffer */ | |
| 812 | 937 | |
| 813 | 938 | aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1); |
| 814 | 939 | ptxd = aup->tx_dma_ring[aup->tx_tail]; |
| @@ -939,7 +1064,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) · 124 unmodified lines | ||
| 939 | 1064 | ps->tx_bytes += ptxd->len; |
| 940 | 1065 | |
| 941 | 1066 | ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; |
| 942 | − au_sync(); | |
| 1067 | + wmb(); /* drain writebuffer */ | |
| 943 | 1068 | dev_kfree_skb(skb); |
| 944 | 1069 | aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1); |
| 945 | 1070 | return NETDEV_TX_OK; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | * with this program; if not, see <http://www.gnu.org/licenses/>. |
| 19 | 19 | */ |
| 20 | 20 | |
| 21 | +#include <linux/clk.h> | |
| 21 | 22 | #include <linux/module.h> |
| 22 | 23 | #include <linux/netdevice.h> |
| 23 | 24 | #include <linux/interrupt.h> |
| @@ -175,6 +176,7 @@ struct au1k_private { · 151 unmodified lines | ||
| 175 | 176 | |
| 176 | 177 | struct resource *ioarea; |
| 177 | 178 | struct au1k_irda_platform_data *platdata; |
| 179 | + struct clk *irda_clk; | |
| 178 | 180 | }; |
| 179 | 181 | |
| 180 | 182 | static int qos_mtt_bits = 0x07; /* 1 ms or more */ |
| @@ -514,9 +516,39 @@ static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id) · 333 unmodified lines | ||
| 514 | 516 | static int au1k_init(struct net_device *dev) |
| 515 | 517 | { |
| 516 | 518 | struct au1k_private *aup = netdev_priv(dev); |
| 517 | − u32 enable, ring_address; | |
| 519 | + u32 enable, ring_address, phyck; | |
| 520 | + struct clk *c; | |
| 518 | 521 | int i; |
| 519 | 522 | |
| 523 | + c = clk_get(NULL, "irda_clk"); | |
| 524 | + if (IS_ERR(c)) | |
| 525 | + return PTR_ERR(c); | |
| 526 | + i = clk_prepare_enable(c); | |
| 527 | + if (i) { | |
| 528 | + clk_put(c); | |
| 529 | + return i; | |
| 530 | + } | |
| 531 | + | |
| 532 | + switch (clk_get_rate(c)) { | |
| 533 | + case 40000000: | |
| 534 | + phyck = IR_PHYCLK_40MHZ; | |
| 535 | + break; | |
| 536 | + case 48000000: | |
| 537 | + phyck = IR_PHYCLK_48MHZ; | |
| 538 | + break; | |
| 539 | + case 56000000: | |
| 540 | + phyck = IR_PHYCLK_56MHZ; | |
| 541 | + break; | |
| 542 | + case 64000000: | |
| 543 | + phyck = IR_PHYCLK_64MHZ; | |
| 544 | + break; | |
| 545 | + default: | |
| 546 | + clk_disable_unprepare(c); | |
| 547 | + clk_put(c); | |
| 548 | + return -EINVAL; | |
| 549 | + } | |
| 550 | + aup->irda_clk = c; | |
| 551 | + | |
| 520 | 552 | enable = IR_HC | IR_CE | IR_C; |
| 521 | 553 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
| 522 | 554 | enable |= IR_BE; |
| @@ -545,7 +577,7 @@ static int au1k_init(struct net_device *dev) · 22 unmodified lines | ||
| 545 | 577 | irda_write(aup, IR_RING_SIZE, |
| 546 | 578 | (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12)); |
| 547 | 579 | |
| 548 | − irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN); | |
| 580 | + irda_write(aup, IR_CONFIG_2, phyck | IR_ONE_PIN); | |
| 549 | 581 | irda_write(aup, IR_RING_ADDR_CMPR, 0); |
| 550 | 582 | |
| 551 | 583 | au1k_irda_set_speed(dev, 9600); |
| @@ -619,6 +651,9 @@ static int au1k_irda_stop(struct net_device *dev) · 67 unmodified lines | ||
| 619 | 651 | free_irq(aup->irq_tx, dev); |
| 620 | 652 | free_irq(aup->irq_rx, dev); |
| 621 | 653 | |
| 654 | + clk_disable_unprepare(aup->irda_clk); | |
| 655 | + clk_put(aup->irda_clk); | |
| 656 | + | |
| 622 | 657 | return 0; |
| 623 | 658 | } |
| 624 | 659 | |
| @@ -853,6 +888,7 @@ static int au1k_irda_probe(struct platform_device *pdev) · 228 unmodified lines | ||
| 853 | 888 | struct au1k_private *aup; |
| 854 | 889 | struct net_device *dev; |
| 855 | 890 | struct resource *r; |
| 891 | + struct clk *c; | |
| 856 | 892 | int err; |
| 857 | 893 | |
| 858 | 894 | dev = alloc_irdadev(sizeof(struct au1k_private)); |
| @@ -886,6 +922,14 @@ static int au1k_irda_probe(struct platform_device *pdev) · 27 unmodified lines | ||
| 886 | 922 | if (!aup->ioarea) |
| 887 | 923 | goto out; |
| 888 | 924 | |
| 925 | + /* bail out early if clock doesn't exist */ | |
| 926 | + c = clk_get(NULL, "irda_clk"); | |
| 927 | + if (IS_ERR(c)) { | |
| 928 | + err = PTR_ERR(c); | |
| 929 | + goto out; | |
| 930 | + } | |
| 931 | + clk_put(c); | |
| 932 | + | |
| 889 | 933 | aup->iobase = ioremap_nocache(r->start, resource_size(r)); |
| 890 | 934 | if (!aup->iobase) |
| 891 | 935 | goto out2; |
| @@ -32,7 +32,7 @@ static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm) · 31 unmodified lines | ||
| 32 | 32 | { |
| 33 | 33 | unsigned long t; |
| 34 | 34 | |
| 35 | − t = au_readl(SYS_TOYREAD); | |
| 35 | + t = alchemy_rdsys(AU1000_SYS_TOYREAD); | |
| 36 | 36 | |
| 37 | 37 | rtc_time_to_tm(t, tm); |
| 38 | 38 | |
| @@ -45,13 +45,12 @@ static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm) · 6 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | rtc_tm_to_time(tm, &t); |
| 47 | 47 | |
| 48 | − au_writel(t, SYS_TOYWRITE); | |
| 49 | − au_sync(); | |
| 48 | + alchemy_wrsys(t, AU1000_SYS_TOYWRITE); | |
| 50 | 49 | |
| 51 | 50 | /* wait for the pending register write to succeed. This can |
| 52 | 51 | * take up to 6 seconds... |
| 53 | 52 | */ |
| 54 | − while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | |
| 53 | + while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C0S) | |
| 55 | 54 | msleep(1); |
| 56 | 55 | |
| 57 | 56 | return 0; |
| @@ -68,7 +67,7 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 68 | 67 | unsigned long t; |
| 69 | 68 | int ret; |
| 70 | 69 | |
| 71 | − t = au_readl(SYS_COUNTER_CNTRL); | |
| 70 | + t = alchemy_rdsys(AU1000_SYS_CNTRCTRL); | |
| 72 | 71 | if (!(t & CNTR_OK)) { |
| 73 | 72 | dev_err(&pdev->dev, "counters not working; aborting.\n"); |
| 74 | 73 | ret = -ENODEV; |
| @@ -78,10 +77,10 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 78 | 77 | ret = -ETIMEDOUT; |
| 79 | 78 | |
| 80 | 79 | /* set counter0 tickrate to 1Hz if necessary */ |
| 81 | − if (au_readl(SYS_TOYTRIM) != 32767) { | |
| 80 | + if (alchemy_rdsys(AU1000_SYS_TOYTRIM) != 32767) { | |
| 82 | 81 | /* wait until hardware gives access to TRIM register */ |
| 83 | 82 | t = 0x00100000; |
| 84 | − while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && --t) | |
| 83 | + while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_T0S) && --t) | |
| 85 | 84 | msleep(1); |
| 86 | 85 | |
| 87 | 86 | if (!t) { |
| @@ -93,12 +92,11 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 93 | 92 | } |
| 94 | 93 | |
| 95 | 94 | /* set 1Hz TOY tick rate */ |
| 96 | − au_writel(32767, SYS_TOYTRIM); | |
| 97 | − au_sync(); | |
| 95 | + alchemy_wrsys(32767, AU1000_SYS_TOYTRIM); | |
| 98 | 96 | } |
| 99 | 97 | |
| 100 | 98 | /* wait until the hardware allows writes to the counter reg */ |
| 101 | − while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | |
| 99 | + while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C0S) | |
| 102 | 100 | msleep(1); |
| 103 | 101 | |
| 104 | 102 | rtcdev = devm_rtc_device_register(&pdev->dev, "rtc-au1xxx", |
| @@ -141,13 +141,13 @@ static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw) · 140 unmodified lines | ||
| 141 | 141 | PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO |
| 142 | 142 | | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO |
| 143 | 143 | | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD; |
| 144 | − au_sync(); | |
| 144 | + wmb(); /* drain writebuffer */ | |
| 145 | 145 | |
| 146 | 146 | hw->regs->psc_spievent = |
| 147 | 147 | PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO |
| 148 | 148 | | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO |
| 149 | 149 | | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD; |
| 150 | − au_sync(); | |
| 150 | + wmb(); /* drain writebuffer */ | |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | 153 | static void au1550_spi_reset_fifos(struct au1550_spi *hw) |
| @@ -155,10 +155,10 @@ static void au1550_spi_reset_fifos(struct au1550_spi *hw) · 1 unmodified line | ||
| 155 | 155 | u32 pcr; |
| 156 | 156 | |
| 157 | 157 | hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC; |
| 158 | − au_sync(); | |
| 158 | + wmb(); /* drain writebuffer */ | |
| 159 | 159 | do { |
| 160 | 160 | pcr = hw->regs->psc_spipcr; |
| 161 | − au_sync(); | |
| 161 | + wmb(); /* drain writebuffer */ | |
| 162 | 162 | } while (pcr != 0); |
| 163 | 163 | } |
| 164 | 164 | |
| @@ -188,9 +188,9 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value) · 23 unmodified lines | ||
| 188 | 188 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); |
| 189 | 189 | |
| 190 | 190 | cfg = hw->regs->psc_spicfg; |
| 191 | − au_sync(); | |
| 191 | + wmb(); /* drain writebuffer */ | |
| 192 | 192 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; |
| 193 | − au_sync(); | |
| 193 | + wmb(); /* drain writebuffer */ | |
| 194 | 194 | |
| 195 | 195 | if (spi->mode & SPI_CPOL) |
| 196 | 196 | cfg |= PSC_SPICFG_BI; |
| @@ -218,10 +218,10 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value) · 21 unmodified lines | ||
| 218 | 218 | cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz); |
| 219 | 219 | |
| 220 | 220 | hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE; |
| 221 | − au_sync(); | |
| 221 | + wmb(); /* drain writebuffer */ | |
| 222 | 222 | do { |
| 223 | 223 | stat = hw->regs->psc_spistat; |
| 224 | − au_sync(); | |
| 224 | + wmb(); /* drain writebuffer */ | |
| 225 | 225 | } while ((stat & PSC_SPISTAT_DR) == 0); |
| 226 | 226 | |
| 227 | 227 | if (hw->pdata->activate_cs) |
| @@ -252,9 +252,9 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) · 24 unmodified lines | ||
| 252 | 252 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); |
| 253 | 253 | |
| 254 | 254 | cfg = hw->regs->psc_spicfg; |
| 255 | − au_sync(); | |
| 255 | + wmb(); /* drain writebuffer */ | |
| 256 | 256 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; |
| 257 | − au_sync(); | |
| 257 | + wmb(); /* drain writebuffer */ | |
| 258 | 258 | |
| 259 | 259 | if (hw->usedma && bpw <= 8) |
| 260 | 260 | cfg &= ~PSC_SPICFG_DD_DISABLE; |
| @@ -268,12 +268,12 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) · 7 unmodified lines | ||
| 268 | 268 | cfg |= au1550_spi_baudcfg(hw, hz); |
| 269 | 269 | |
| 270 | 270 | hw->regs->psc_spicfg = cfg; |
| 271 | − au_sync(); | |
| 271 | + wmb(); /* drain writebuffer */ | |
| 272 | 272 | |
| 273 | 273 | if (cfg & PSC_SPICFG_DE_ENABLE) { |
| 274 | 274 | do { |
| 275 | 275 | stat = hw->regs->psc_spistat; |
| 276 | − au_sync(); | |
| 276 | + wmb(); /* drain writebuffer */ | |
| 277 | 277 | } while ((stat & PSC_SPISTAT_DR) == 0); |
| 278 | 278 | } |
| 279 | 279 | |
| @@ -396,11 +396,11 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) · 116 unmodified lines | ||
| 396 | 396 | |
| 397 | 397 | /* by default enable nearly all events interrupt */ |
| 398 | 398 | hw->regs->psc_spimsk = PSC_SPIMSK_SD; |
| 399 | − au_sync(); | |
| 399 | + wmb(); /* drain writebuffer */ | |
| 400 | 400 | |
| 401 | 401 | /* start the transfer */ |
| 402 | 402 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; |
| 403 | − au_sync(); | |
| 403 | + wmb(); /* drain writebuffer */ | |
| 404 | 404 | |
| 405 | 405 | wait_for_completion(&hw->master_done); |
| 406 | 406 | |
| @@ -429,7 +429,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) · 22 unmodified lines | ||
| 429 | 429 | |
| 430 | 430 | stat = hw->regs->psc_spistat; |
| 431 | 431 | evnt = hw->regs->psc_spievent; |
| 432 | − au_sync(); | |
| 432 | + wmb(); /* drain writebuffer */ | |
| 433 | 433 | if ((stat & PSC_SPISTAT_DI) == 0) { |
| 434 | 434 | dev_err(hw->dev, "Unexpected IRQ!\n"); |
| 435 | 435 | return IRQ_NONE; |
| @@ -484,7 +484,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) · 48 unmodified lines | ||
| 484 | 484 | static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \ |
| 485 | 485 | { \ |
| 486 | 486 | u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \ |
| 487 | − au_sync(); \ | |
| 487 | + wmb(); /* drain writebuffer */ \ | |
| 488 | 488 | if (hw->rx) { \ |
| 489 | 489 | *(u##size *)hw->rx = (u##size)fifoword; \ |
| 490 | 490 | hw->rx += (size) / 8; \ |
| @@ -504,7 +504,7 @@ static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \ · 13 unmodified lines | ||
| 504 | 504 | if (hw->tx_count >= hw->len) \ |
| 505 | 505 | fifoword |= PSC_SPITXRX_LC; \ |
| 506 | 506 | hw->regs->psc_spitxrx = fifoword; \ |
| 507 | − au_sync(); \ | |
| 507 | + wmb(); /* drain writebuffer */ \ | |
| 508 | 508 | } |
| 509 | 509 | |
| 510 | 510 | AU1550_SPI_RX_WORD(8,0xff) |
| @@ -539,18 +539,18 @@ static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t) · 28 unmodified lines | ||
| 539 | 539 | } |
| 540 | 540 | |
| 541 | 541 | stat = hw->regs->psc_spistat; |
| 542 | − au_sync(); | |
| 542 | + wmb(); /* drain writebuffer */ | |
| 543 | 543 | if (stat & PSC_SPISTAT_TF) |
| 544 | 544 | break; |
| 545 | 545 | } |
| 546 | 546 | |
| 547 | 547 | /* enable event interrupts */ |
| 548 | 548 | hw->regs->psc_spimsk = mask; |
| 549 | − au_sync(); | |
| 549 | + wmb(); /* drain writebuffer */ | |
| 550 | 550 | |
| 551 | 551 | /* start the transfer */ |
| 552 | 552 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; |
| 553 | − au_sync(); | |
| 553 | + wmb(); /* drain writebuffer */ | |
| 554 | 554 | |
| 555 | 555 | wait_for_completion(&hw->master_done); |
| 556 | 556 | |
| @@ -564,7 +564,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) · 7 unmodified lines | ||
| 564 | 564 | |
| 565 | 565 | stat = hw->regs->psc_spistat; |
| 566 | 566 | evnt = hw->regs->psc_spievent; |
| 567 | − au_sync(); | |
| 567 | + wmb(); /* drain writebuffer */ | |
| 568 | 568 | if ((stat & PSC_SPISTAT_DI) == 0) { |
| 569 | 569 | dev_err(hw->dev, "Unexpected IRQ!\n"); |
| 570 | 570 | return IRQ_NONE; |
| @@ -594,7 +594,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) · 23 unmodified lines | ||
| 594 | 594 | do { |
| 595 | 595 | busy = 0; |
| 596 | 596 | stat = hw->regs->psc_spistat; |
| 597 | − au_sync(); | |
| 597 | + wmb(); /* drain writebuffer */ | |
| 598 | 598 | |
| 599 | 599 | /* |
| 600 | 600 | * Take care to not let the Rx FIFO overflow. |
| @@ -615,7 +615,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) · 14 unmodified lines | ||
| 615 | 615 | } while (busy); |
| 616 | 616 | |
| 617 | 617 | hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR; |
| 618 | − au_sync(); | |
| 618 | + wmb(); /* drain writebuffer */ | |
| 619 | 619 | |
| 620 | 620 | /* |
| 621 | 621 | * Restart the SPI transmission in case of a transmit underflow. |
| @@ -634,9 +634,9 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) · 12 unmodified lines | ||
| 634 | 634 | */ |
| 635 | 635 | if (evnt & PSC_SPIEVNT_TU) { |
| 636 | 636 | hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD; |
| 637 | − au_sync(); | |
| 637 | + wmb(); /* drain writebuffer */ | |
| 638 | 638 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; |
| 639 | − au_sync(); | |
| 639 | + wmb(); /* drain writebuffer */ | |
| 640 | 640 | } |
| 641 | 641 | |
| 642 | 642 | if (hw->rx_count >= hw->len) { |
| @@ -690,19 +690,19 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) · 47 unmodified lines | ||
| 690 | 690 | |
| 691 | 691 | /* set up the PSC for SPI mode */ |
| 692 | 692 | hw->regs->psc_ctrl = PSC_CTRL_DISABLE; |
| 693 | − au_sync(); | |
| 693 | + wmb(); /* drain writebuffer */ | |
| 694 | 694 | hw->regs->psc_sel = PSC_SEL_PS_SPIMODE; |
| 695 | − au_sync(); | |
| 695 | + wmb(); /* drain writebuffer */ | |
| 696 | 696 | |
| 697 | 697 | hw->regs->psc_spicfg = 0; |
| 698 | − au_sync(); | |
| 698 | + wmb(); /* drain writebuffer */ | |
| 699 | 699 | |
| 700 | 700 | hw->regs->psc_ctrl = PSC_CTRL_ENABLE; |
| 701 | − au_sync(); | |
| 701 | + wmb(); /* drain writebuffer */ | |
| 702 | 702 | |
| 703 | 703 | do { |
| 704 | 704 | stat = hw->regs->psc_spistat; |
| 705 | − au_sync(); | |
| 705 | + wmb(); /* drain writebuffer */ | |
| 706 | 706 | } while ((stat & PSC_SPISTAT_SR) == 0); |
| 707 | 707 | |
| 708 | 708 | |
| @@ -717,16 +717,16 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) · 8 unmodified lines | ||
| 717 | 717 | #endif |
| 718 | 718 | |
| 719 | 719 | hw->regs->psc_spicfg = cfg; |
| 720 | − au_sync(); | |
| 720 | + wmb(); /* drain writebuffer */ | |
| 721 | 721 | |
| 722 | 722 | au1550_spi_mask_ack_all(hw); |
| 723 | 723 | |
| 724 | 724 | hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE; |
| 725 | − au_sync(); | |
| 725 | + wmb(); /* drain writebuffer */ | |
| 726 | 726 | |
| 727 | 727 | do { |
| 728 | 728 | stat = hw->regs->psc_spistat; |
| 729 | − au_sync(); | |
| 729 | + wmb(); /* drain writebuffer */ | |
| 730 | 730 | } while ((stat & PSC_SPISTAT_DR) == 0); |
| 731 | 731 | |
| 732 | 732 | au1550_spi_reset_fifos(hw); |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | * with this program; if not, write to the Free Software Foundation, Inc., |
| 42 | 42 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 43 | 43 | */ |
| 44 | +#include <linux/clk.h> | |
| 44 | 45 | #include <linux/module.h> |
| 45 | 46 | #include <linux/kernel.h> |
| 46 | 47 | #include <linux/errno.h> |
| @@ -113,7 +114,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) · 66 unmodified lines | ||
| 113 | 114 | case VESA_NO_BLANKING: |
| 114 | 115 | /* Turn on panel */ |
| 115 | 116 | fbdev->regs->lcd_control |= LCD_CONTROL_GO; |
| 116 | − au_sync(); | |
| 117 | + wmb(); /* drain writebuffer */ | |
| 117 | 118 | break; |
| 118 | 119 | |
| 119 | 120 | case VESA_VSYNC_SUSPEND: |
| @@ -121,7 +122,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) · 1 unmodified line | ||
| 121 | 122 | case VESA_POWERDOWN: |
| 122 | 123 | /* Turn off panel */ |
| 123 | 124 | fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; |
| 124 | − au_sync(); | |
| 125 | + wmb(); /* drain writebuffer */ | |
| 125 | 126 | break; |
| 126 | 127 | default: |
| 127 | 128 | break; |
| @@ -434,7 +435,7 @@ static int au1100fb_drv_probe(struct platform_device *dev) · 306 unmodified lines | ||
| 434 | 435 | struct au1100fb_device *fbdev = NULL; |
| 435 | 436 | struct resource *regs_res; |
| 436 | 437 | unsigned long page; |
| 437 | − u32 sys_clksrc; | |
| 438 | + struct clk *c; | |
| 438 | 439 | |
| 439 | 440 | /* Allocate new device private */ |
| 440 | 441 | fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device), |
| @@ -473,6 +474,13 @@ static int au1100fb_drv_probe(struct platform_device *dev) · 32 unmodified lines | ||
| 473 | 474 | print_dbg("Register memory map at %p", fbdev->regs); |
| 474 | 475 | print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len); |
| 475 | 476 | |
| 477 | + c = clk_get(NULL, "lcd_intclk"); | |
| 478 | + if (!IS_ERR(c)) { | |
| 479 | + fbdev->lcdclk = c; | |
| 480 | + clk_set_rate(c, 48000000); | |
| 481 | + clk_prepare_enable(c); | |
| 482 | + } | |
| 483 | + | |
| 476 | 484 | /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */ |
| 477 | 485 | fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * |
| 478 | 486 | (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; |
| @@ -506,10 +514,6 @@ static int au1100fb_drv_probe(struct platform_device *dev) · 27 unmodified lines | ||
| 506 | 514 | print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); |
| 507 | 515 | print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); |
| 508 | 516 | |
| 509 | − /* Setup LCD clock to AUX (48 MHz) */ | |
| 510 | − sys_clksrc = au_readl(SYS_CLKSRC) & ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL); | |
| 511 | − au_writel((sys_clksrc | (1 << SYS_CS_ML_BIT)), SYS_CLKSRC); | |
| 512 | − | |
| 513 | 517 | /* load the panel info into the var struct */ |
| 514 | 518 | au1100fb_var.bits_per_pixel = fbdev->panel->bpp; |
| 515 | 519 | au1100fb_var.xres = fbdev->panel->xres; |
| @@ -546,6 +550,10 @@ static int au1100fb_drv_probe(struct platform_device *dev) · 30 unmodified lines | ||
| 546 | 550 | return 0; |
| 547 | 551 | |
| 548 | 552 | failed: |
| 553 | + if (fbdev->lcdclk) { | |
| 554 | + clk_disable_unprepare(fbdev->lcdclk); | |
| 555 | + clk_put(fbdev->lcdclk); | |
| 556 | + } | |
| 549 | 557 | if (fbdev->fb_mem) { |
| 550 | 558 | dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, |
| 551 | 559 | fbdev->fb_phys); |
| @@ -576,11 +584,15 @@ int au1100fb_drv_remove(struct platform_device *dev) · 24 unmodified lines | ||
| 576 | 584 | |
| 577 | 585 | fb_dealloc_cmap(&fbdev->info.cmap); |
| 578 | 586 | |
| 587 | + if (fbdev->lcdclk) { | |
| 588 | + clk_disable_unprepare(fbdev->lcdclk); | |
| 589 | + clk_put(fbdev->lcdclk); | |
| 590 | + } | |
| 591 | + | |
| 579 | 592 | return 0; |
| 580 | 593 | } |
| 581 | 594 | |
| 582 | 595 | #ifdef CONFIG_PM |
| 583 | −static u32 sys_clksrc; | |
| 584 | 596 | static struct au1100fb_regs fbregs; |
| 585 | 597 | |
| 586 | 598 | int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) |
| @@ -590,14 +602,11 @@ int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) · 3 unmodified lines | ||
| 590 | 602 | if (!fbdev) |
| 591 | 603 | return 0; |
| 592 | 604 | |
| 593 | − /* Save the clock source state */ | |
| 594 | − sys_clksrc = au_readl(SYS_CLKSRC); | |
| 595 | − | |
| 596 | 605 | /* Blank the LCD */ |
| 597 | 606 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); |
| 598 | 607 | |
| 599 | − /* Stop LCD clocking */ | |
| 600 | − au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC); | |
| 608 | + if (fbdev->lcdclk) | |
| 609 | + clk_disable(fbdev->lcdclk); | |
| 601 | 610 | |
| 602 | 611 | memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); |
| 603 | 612 | |
| @@ -613,8 +622,8 @@ int au1100fb_drv_resume(struct platform_device *dev) · 9 unmodified lines | ||
| 613 | 622 | |
| 614 | 623 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); |
| 615 | 624 | |
| 616 | − /* Restart LCD clocking */ | |
| 617 | − au_writel(sys_clksrc, SYS_CLKSRC); | |
| 625 | + if (fbdev->lcdclk) | |
| 626 | + clk_enable(fbdev->lcdclk); | |
| 618 | 627 | |
| 619 | 628 | /* Unblank the LCD */ |
| 620 | 629 | au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); |
| @@ -109,6 +109,7 @@ struct au1100fb_device { · 108 unmodified lines | ||
| 109 | 109 | size_t fb_len; |
| 110 | 110 | dma_addr_t fb_phys; |
| 111 | 111 | int panel_idx; |
| 112 | + struct clk *lcdclk; | |
| 112 | 113 | }; |
| 113 | 114 | |
| 114 | 115 | /********************************************************************/ |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 31 | 31 | */ |
| 32 | 32 | |
| 33 | +#include <linux/clk.h> | |
| 33 | 34 | #include <linux/module.h> |
| 34 | 35 | #include <linux/platform_device.h> |
| 35 | 36 | #include <linux/kernel.h> |
| @@ -330,9 +331,8 @@ struct panel_settings · 294 unmodified lines | ||
| 330 | 331 | uint32 mode_pwmhi; |
| 331 | 332 | uint32 mode_outmask; |
| 332 | 333 | uint32 mode_fifoctrl; |
| 333 | − uint32 mode_toyclksrc; | |
| 334 | 334 | uint32 mode_backlight; |
| 335 | − uint32 mode_auxpll; | |
| 335 | + uint32 lcdclk; | |
| 336 | 336 | #define Xres min_xres |
| 337 | 337 | #define Yres min_yres |
| 338 | 338 | u32 min_xres; /* Minimum horizontal resolution */ |
| @@ -379,9 +379,8 @@ static struct panel_settings known_lcd_panels[] = · 40 unmodified lines | ||
| 379 | 379 | .mode_pwmhi = 0x00000000, |
| 380 | 380 | .mode_outmask = 0x00FFFFFF, |
| 381 | 381 | .mode_fifoctrl = 0x2f2f2f2f, |
| 382 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 383 | 382 | .mode_backlight = 0x00000000, |
| 384 | − .mode_auxpll = 8, /* 96MHz AUXPLL */ | |
| 383 | + .lcdclk = 96, | |
| 385 | 384 | 320, 320, |
| 386 | 385 | 240, 240, |
| 387 | 386 | }, |
| @@ -407,9 +406,8 @@ static struct panel_settings known_lcd_panels[] = · 19 unmodified lines | ||
| 407 | 406 | .mode_pwmhi = 0x00000000, |
| 408 | 407 | .mode_outmask = 0x00FFFFFF, |
| 409 | 408 | .mode_fifoctrl = 0x2f2f2f2f, |
| 410 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 411 | 409 | .mode_backlight = 0x00000000, |
| 412 | − .mode_auxpll = 8, /* 96MHz AUXPLL */ | |
| 410 | + .lcdclk = 96, | |
| 413 | 411 | 640, 480, |
| 414 | 412 | 640, 480, |
| 415 | 413 | }, |
| @@ -435,9 +433,8 @@ static struct panel_settings known_lcd_panels[] = · 19 unmodified lines | ||
| 435 | 433 | .mode_pwmhi = 0x00000000, |
| 436 | 434 | .mode_outmask = 0x00FFFFFF, |
| 437 | 435 | .mode_fifoctrl = 0x2f2f2f2f, |
| 438 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 439 | 436 | .mode_backlight = 0x00000000, |
| 440 | − .mode_auxpll = 8, /* 96MHz AUXPLL */ | |
| 437 | + .lcdclk = 96, | |
| 441 | 438 | 800, 800, |
| 442 | 439 | 600, 600, |
| 443 | 440 | }, |
| @@ -463,9 +460,8 @@ static struct panel_settings known_lcd_panels[] = · 19 unmodified lines | ||
| 463 | 460 | .mode_pwmhi = 0x00000000, |
| 464 | 461 | .mode_outmask = 0x00FFFFFF, |
| 465 | 462 | .mode_fifoctrl = 0x2f2f2f2f, |
| 466 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 467 | 463 | .mode_backlight = 0x00000000, |
| 468 | − .mode_auxpll = 6, /* 72MHz AUXPLL */ | |
| 464 | + .lcdclk = 72, | |
| 469 | 465 | 1024, 1024, |
| 470 | 466 | 768, 768, |
| 471 | 467 | }, |
| @@ -491,9 +487,8 @@ static struct panel_settings known_lcd_panels[] = · 19 unmodified lines | ||
| 491 | 487 | .mode_pwmhi = 0x00000000, |
| 492 | 488 | .mode_outmask = 0x00FFFFFF, |
| 493 | 489 | .mode_fifoctrl = 0x2f2f2f2f, |
| 494 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 495 | 490 | .mode_backlight = 0x00000000, |
| 496 | − .mode_auxpll = 10, /* 120MHz AUXPLL */ | |
| 491 | + .lcdclk = 120, | |
| 497 | 492 | 1280, 1280, |
| 498 | 493 | 1024, 1024, |
| 499 | 494 | }, |
| @@ -519,9 +514,8 @@ static struct panel_settings known_lcd_panels[] = · 19 unmodified lines | ||
| 519 | 514 | .mode_pwmhi = 0x03400000, /* SCB 0x0 */ |
| 520 | 515 | .mode_outmask = 0x00FFFFFF, |
| 521 | 516 | .mode_fifoctrl = 0x2f2f2f2f, |
| 522 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 523 | 517 | .mode_backlight = 0x00000000, |
| 524 | − .mode_auxpll = 8, /* 96MHz AUXPLL */ | |
| 518 | + .lcdclk = 96, | |
| 525 | 519 | 1024, 1024, |
| 526 | 520 | 768, 768, |
| 527 | 521 | }, |
| @@ -550,9 +544,8 @@ static struct panel_settings known_lcd_panels[] = · 22 unmodified lines | ||
| 550 | 544 | .mode_pwmhi = 0x03400000, |
| 551 | 545 | .mode_outmask = 0x00fcfcfc, |
| 552 | 546 | .mode_fifoctrl = 0x2f2f2f2f, |
| 553 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 554 | 547 | .mode_backlight = 0x00000000, |
| 555 | − .mode_auxpll = 8, /* 96MHz AUXPLL */ | |
| 548 | + .lcdclk = 96, | |
| 556 | 549 | 640, 480, |
| 557 | 550 | 640, 480, |
| 558 | 551 | }, |
| @@ -581,9 +574,8 @@ static struct panel_settings known_lcd_panels[] = · 22 unmodified lines | ||
| 581 | 574 | .mode_pwmhi = 0x03400000, |
| 582 | 575 | .mode_outmask = 0x00fcfcfc, |
| 583 | 576 | .mode_fifoctrl = 0x2f2f2f2f, |
| 584 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 585 | 577 | .mode_backlight = 0x00000000, |
| 586 | − .mode_auxpll = 8, /* 96MHz AUXPLL */ | |
| 578 | + .lcdclk = 96, /* 96MHz AUXPLL */ | |
| 587 | 579 | 320, 320, |
| 588 | 580 | 240, 240, |
| 589 | 581 | }, |
| @@ -612,9 +604,8 @@ static struct panel_settings known_lcd_panels[] = · 22 unmodified lines | ||
| 612 | 604 | .mode_pwmhi = 0x03400000, |
| 613 | 605 | .mode_outmask = 0x00fcfcfc, |
| 614 | 606 | .mode_fifoctrl = 0x2f2f2f2f, |
| 615 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 616 | 607 | .mode_backlight = 0x00000000, |
| 617 | − .mode_auxpll = 8, /* 96MHz AUXPLL */ | |
| 608 | + .lcdclk = 96, | |
| 618 | 609 | 856, 856, |
| 619 | 610 | 480, 480, |
| 620 | 611 | }, |
| @@ -646,9 +637,8 @@ static struct panel_settings known_lcd_panels[] = · 25 unmodified lines | ||
| 646 | 637 | .mode_pwmhi = 0x00000000, |
| 647 | 638 | .mode_outmask = 0x00FFFFFF, |
| 648 | 639 | .mode_fifoctrl = 0x2f2f2f2f, |
| 649 | − .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | |
| 650 | 640 | .mode_backlight = 0x00000000, |
| 651 | − .mode_auxpll = (48/12) * 2, | |
| 641 | + .lcdclk = 96, | |
| 652 | 642 | 800, 800, |
| 653 | 643 | 480, 480, |
| 654 | 644 | }, |
| @@ -764,7 +754,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, · 109 unmodified lines | ||
| 764 | 754 | |
| 765 | 755 | /* Disable the window while making changes, then restore WINEN */ |
| 766 | 756 | winenable = lcd->winenable & (1 << plane); |
| 767 | − au_sync(); | |
| 757 | + wmb(); /* drain writebuffer */ | |
| 768 | 758 | lcd->winenable &= ~(1 << plane); |
| 769 | 759 | lcd->window[plane].winctrl0 = winctrl0; |
| 770 | 760 | lcd->window[plane].winctrl1 = winctrl1; |
| @@ -772,7 +762,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, · 1 unmodified line | ||
| 772 | 762 | lcd->window[plane].winbuf1 = fbdev->fb_phys; |
| 773 | 763 | lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ |
| 774 | 764 | lcd->winenable |= winenable; |
| 775 | − au_sync(); | |
| 765 | + wmb(); /* drain writebuffer */ | |
| 776 | 766 | |
| 777 | 767 | return 0; |
| 778 | 768 | } |
| @@ -788,22 +778,21 @@ static void au1200_setpanel(struct panel_settings *newpanel, · 9 unmodified lines | ||
| 788 | 778 | /* Make sure all windows disabled */ |
| 789 | 779 | winenable = lcd->winenable; |
| 790 | 780 | lcd->winenable = 0; |
| 791 | − au_sync(); | |
| 781 | + wmb(); /* drain writebuffer */ | |
| 792 | 782 | /* |
| 793 | 783 | * Ensure everything is disabled before reconfiguring |
| 794 | 784 | */ |
| 795 | 785 | if (lcd->screen & LCD_SCREEN_SEN) { |
| 796 | 786 | /* Wait for vertical sync period */ |
| 797 | 787 | lcd->intstatus = LCD_INT_SS; |
| 798 | − while ((lcd->intstatus & LCD_INT_SS) == 0) { | |
| 799 | − au_sync(); | |
| 800 | − } | |
| 788 | + while ((lcd->intstatus & LCD_INT_SS) == 0) | |
| 789 | + ; | |
| 801 | 790 | |
| 802 | 791 | lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ |
| 803 | 792 | |
| 804 | 793 | do { |
| 805 | 794 | lcd->intstatus = lcd->intstatus; /*clear interrupts*/ |
| 806 | − au_sync(); | |
| 795 | + wmb(); /* drain writebuffer */ | |
| 807 | 796 | /*wait for controller to shut down*/ |
| 808 | 797 | } while ((lcd->intstatus & LCD_INT_SD) == 0); |
| 809 | 798 | |
| @@ -829,11 +818,17 @@ static void au1200_setpanel(struct panel_settings *newpanel, · 19 unmodified lines | ||
| 829 | 818 | */ |
| 830 | 819 | if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) |
| 831 | 820 | { |
| 832 | − uint32 sys_clksrc; | |
| 833 | − au_writel(panel->mode_auxpll, SYS_AUXPLL); | |
| 834 | − sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; | |
| 835 | − sys_clksrc |= panel->mode_toyclksrc; | |
| 836 | − au_writel(sys_clksrc, SYS_CLKSRC); | |
| 821 | + struct clk *c = clk_get(NULL, "lcd_intclk"); | |
| 822 | + long r, pc = panel->lcdclk * 1000000; | |
| 823 | + | |
| 824 | + if (!IS_ERR(c)) { | |
| 825 | + r = clk_round_rate(c, pc); | |
| 826 | + if ((pc - r) < (pc / 10)) { /* 10% slack */ | |
| 827 | + clk_set_rate(c, r); | |
| 828 | + clk_prepare_enable(c); | |
| 829 | + } | |
| 830 | + clk_put(c); | |
| 831 | + } | |
| 837 | 832 | } |
| 838 | 833 | |
| 839 | 834 | /* |
| @@ -847,7 +842,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, · 7 unmodified lines | ||
| 847 | 842 | lcd->pwmhi = panel->mode_pwmhi; |
| 848 | 843 | lcd->outmask = panel->mode_outmask; |
| 849 | 844 | lcd->fifoctrl = panel->mode_fifoctrl; |
| 850 | − au_sync(); | |
| 845 | + wmb(); /* drain writebuffer */ | |
| 851 | 846 | |
| 852 | 847 | /* fixme: Check window settings to make sure still valid |
| 853 | 848 | * for new geometry */ |
| @@ -863,7 +858,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, · 9 unmodified lines | ||
| 863 | 858 | * Re-enable screen now that it is configured |
| 864 | 859 | */ |
| 865 | 860 | lcd->screen |= LCD_SCREEN_SEN; |
| 866 | − au_sync(); | |
| 861 | + wmb(); /* drain writebuffer */ | |
| 867 | 862 | |
| 868 | 863 | /* Call init of panel */ |
| 869 | 864 | if (pd->panel_init) |
| @@ -956,7 +951,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev) · 86 unmodified lines | ||
| 956 | 951 | | LCD_WINCTRL2_SCY_1 |
| 957 | 952 | ) ; |
| 958 | 953 | lcd->winenable |= win->w[plane].mode_winenable; |
| 959 | − au_sync(); | |
| 954 | + wmb(); /* drain writebuffer */ | |
| 960 | 955 | } |
| 961 | 956 | |
| 962 | 957 | |
| @@ -1270,7 +1265,7 @@ static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) · 307 unmodified lines | ||
| 1270 | 1265 | |
| 1271 | 1266 | if (pdata->flags & SCREEN_MASK) |
| 1272 | 1267 | lcd->colorkeymsk = pdata->mask; |
| 1273 | − au_sync(); | |
| 1268 | + wmb(); /* drain writebuffer */ | |
| 1274 | 1269 | } |
| 1275 | 1270 | |
| 1276 | 1271 | static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) |
| @@ -1288,7 +1283,7 @@ static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) · 11 unmodified lines | ||
| 1288 | 1283 | hi1 = (lcd->pwmhi >> 16) + 1; |
| 1289 | 1284 | divider = (lcd->pwmdiv & 0x3FFFF) + 1; |
| 1290 | 1285 | pdata->brightness = ((hi1 << 8) / divider) - 1; |
| 1291 | − au_sync(); | |
| 1286 | + wmb(); /* drain writebuffer */ | |
| 1292 | 1287 | } |
| 1293 | 1288 | |
| 1294 | 1289 | static void set_window(unsigned int plane, |
| @@ -1387,7 +1382,7 @@ static void set_window(unsigned int plane, · 92 unmodified lines | ||
| 1387 | 1382 | val |= (pdata->enable & 1) << plane; |
| 1388 | 1383 | lcd->winenable = val; |
| 1389 | 1384 | } |
| 1390 | − au_sync(); | |
| 1385 | + wmb(); /* drain writebuffer */ | |
| 1391 | 1386 | } |
| 1392 | 1387 | |
| 1393 | 1388 | static void get_window(unsigned int plane, |
| @@ -1414,7 +1409,7 @@ static void get_window(unsigned int plane, · 20 unmodified lines | ||
| 1414 | 1409 | pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; |
| 1415 | 1410 | |
| 1416 | 1411 | pdata->enable = (lcd->winenable >> plane) & 1; |
| 1417 | − au_sync(); | |
| 1412 | + wmb(); /* drain writebuffer */ | |
| 1418 | 1413 | } |
| 1419 | 1414 | |
| 1420 | 1415 | static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, |
| @@ -1511,7 +1506,7 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) · 90 unmodified lines | ||
| 1511 | 1506 | { |
| 1512 | 1507 | /* Nothing to do for now, just clear any pending interrupt */ |
| 1513 | 1508 | lcd->intstatus = lcd->intstatus; |
| 1514 | − au_sync(); | |
| 1509 | + wmb(); /* drain writebuffer */ | |
| 1515 | 1510 | |
| 1516 | 1511 | return IRQ_HANDLED; |
| 1517 | 1512 | } |
| @@ -1809,7 +1804,7 @@ static int au1200fb_drv_suspend(struct device *dev) · 291 unmodified lines | ||
| 1809 | 1804 | au1200_setpanel(NULL, pd); |
| 1810 | 1805 | |
| 1811 | 1806 | lcd->outmask = 0; |
| 1812 | − au_sync(); | |
| 1807 | + wmb(); /* drain writebuffer */ | |
| 1813 | 1808 | |
| 1814 | 1809 | return 0; |
| 1815 | 1810 | } |
| @@ -145,35 +145,39 @@ static void __init octeon_wdt_build_stage1(void) · 144 unmodified lines | ||
| 145 | 145 | |
| 146 | 146 | uasm_i_mfc0(&p, K0, C0_STATUS); |
| 147 | 147 | #ifdef CONFIG_HOTPLUG_CPU |
| 148 | − uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), label_enter_bootloader); | |
| 148 | + if (octeon_bootloader_entry_addr) | |
| 149 | + uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), | |
| 150 | + label_enter_bootloader); | |
| 149 | 151 | #endif |
| 150 | 152 | /* Force 64-bit addressing enabled */ |
| 151 | 153 | uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX); |
| 152 | 154 | uasm_i_mtc0(&p, K0, C0_STATUS); |
| 153 | 155 | |
| 154 | 156 | #ifdef CONFIG_HOTPLUG_CPU |
| 155 | − uasm_i_mfc0(&p, K0, C0_EBASE); | |
| 156 | − /* Coreid number in K0 */ | |
| 157 | − uasm_i_andi(&p, K0, K0, 0xf); | |
| 158 | − /* 8 * coreid in bits 16-31 */ | |
| 159 | − uasm_i_dsll_safe(&p, K0, K0, 3 + 16); | |
| 160 | − uasm_i_ori(&p, K0, K0, 0x8001); | |
| 161 | − uasm_i_dsll_safe(&p, K0, K0, 16); | |
| 162 | − uasm_i_ori(&p, K0, K0, 0x0700); | |
| 163 | − uasm_i_drotr_safe(&p, K0, K0, 32); | |
| 164 | − /* | |
| 165 | − * Should result in: 0x8001,0700,0000,8*coreid which is | |
| 166 | − * CVMX_CIU_WDOGX(coreid) - 0x0500 | |
| 167 | − * | |
| 168 | − * Now ld K0, CVMX_CIU_WDOGX(coreid) | |
| 169 | − */ | |
| 170 | − uasm_i_ld(&p, K0, 0x500, K0); | |
| 171 | − /* | |
| 172 | − * If bit one set handle the NMI as a watchdog event. | |
| 173 | − * otherwise transfer control to bootloader. | |
| 174 | − */ | |
| 175 | − uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); | |
| 176 | − uasm_i_nop(&p); | |
| 157 | + if (octeon_bootloader_entry_addr) { | |
| 158 | + uasm_i_mfc0(&p, K0, C0_EBASE); | |
| 159 | + /* Coreid number in K0 */ | |
| 160 | + uasm_i_andi(&p, K0, K0, 0xf); | |
| 161 | + /* 8 * coreid in bits 16-31 */ | |
| 162 | + uasm_i_dsll_safe(&p, K0, K0, 3 + 16); | |
| 163 | + uasm_i_ori(&p, K0, K0, 0x8001); | |
| 164 | + uasm_i_dsll_safe(&p, K0, K0, 16); | |
| 165 | + uasm_i_ori(&p, K0, K0, 0x0700); | |
| 166 | + uasm_i_drotr_safe(&p, K0, K0, 32); | |
| 167 | + /* | |
| 168 | + * Should result in: 0x8001,0700,0000,8*coreid which is | |
| 169 | + * CVMX_CIU_WDOGX(coreid) - 0x0500 | |
| 170 | + * | |
| 171 | + * Now ld K0, CVMX_CIU_WDOGX(coreid) | |
| 172 | + */ | |
| 173 | + uasm_i_ld(&p, K0, 0x500, K0); | |
| 174 | + /* | |
| 175 | + * If bit one set handle the NMI as a watchdog event. | |
| 176 | + * otherwise transfer control to bootloader. | |
| 177 | + */ | |
| 178 | + uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); | |
| 179 | + uasm_i_nop(&p); | |
| 180 | + } | |
| 177 | 181 | #endif |
| 178 | 182 | |
| 179 | 183 | /* Clear Dcache so cvmseg works right. */ |
| @@ -194,11 +198,13 @@ static void __init octeon_wdt_build_stage1(void) · 14 unmodified lines | ||
| 194 | 198 | uasm_i_dmfc0(&p, K0, C0_DESAVE); |
| 195 | 199 | |
| 196 | 200 | #ifdef CONFIG_HOTPLUG_CPU |
| 197 | − uasm_build_label(&l, p, label_enter_bootloader); | |
| 198 | − /* Jump to the bootloader and restore K0 */ | |
| 199 | − UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); | |
| 200 | − uasm_i_jr(&p, K0); | |
| 201 | − uasm_i_dmfc0(&p, K0, C0_DESAVE); | |
| 201 | + if (octeon_bootloader_entry_addr) { | |
| 202 | + uasm_build_label(&l, p, label_enter_bootloader); | |
| 203 | + /* Jump to the bootloader and restore K0 */ | |
| 204 | + UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); | |
| 205 | + uasm_i_jr(&p, K0); | |
| 206 | + uasm_i_dmfc0(&p, K0, C0_DESAVE); | |
| 207 | + } | |
| 202 | 208 | #endif |
| 203 | 209 | uasm_resolve_relocs(relocs, labels); |
| 204 | 210 | |
| @@ -79,28 +79,28 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, · 78 unmodified lines | ||
| 79 | 79 | unsigned short retry, tmo; |
| 80 | 80 | unsigned long data; |
| 81 | 81 | |
| 82 | − au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 83 | − au_sync(); | |
| 82 | + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 83 | + wmb(); /* drain writebuffer */ | |
| 84 | 84 | |
| 85 | 85 | retry = AC97_RW_RETRIES; |
| 86 | 86 | do { |
| 87 | 87 | mutex_lock(&pscdata->lock); |
| 88 | 88 | |
| 89 | − au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), | |
| 89 | + __raw_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), | |
| 90 | 90 | AC97_CDC(pscdata)); |
| 91 | − au_sync(); | |
| 91 | + wmb(); /* drain writebuffer */ | |
| 92 | 92 | |
| 93 | 93 | tmo = 20; |
| 94 | 94 | do { |
| 95 | 95 | udelay(21); |
| 96 | − if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) | |
| 96 | + if (__raw_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) | |
| 97 | 97 | break; |
| 98 | 98 | } while (--tmo); |
| 99 | 99 | |
| 100 | − data = au_readl(AC97_CDC(pscdata)); | |
| 100 | + data = __raw_readl(AC97_CDC(pscdata)); | |
| 101 | 101 | |
| 102 | − au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 103 | − au_sync(); | |
| 102 | + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 103 | + wmb(); /* drain writebuffer */ | |
| 104 | 104 | |
| 105 | 105 | mutex_unlock(&pscdata->lock); |
| 106 | 106 | |
| @@ -119,26 +119,26 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, · 12 unmodified lines | ||
| 119 | 119 | struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); |
| 120 | 120 | unsigned int tmo, retry; |
| 121 | 121 | |
| 122 | − au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 123 | − au_sync(); | |
| 122 | + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 123 | + wmb(); /* drain writebuffer */ | |
| 124 | 124 | |
| 125 | 125 | retry = AC97_RW_RETRIES; |
| 126 | 126 | do { |
| 127 | 127 | mutex_lock(&pscdata->lock); |
| 128 | 128 | |
| 129 | − au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), | |
| 129 | + __raw_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), | |
| 130 | 130 | AC97_CDC(pscdata)); |
| 131 | − au_sync(); | |
| 131 | + wmb(); /* drain writebuffer */ | |
| 132 | 132 | |
| 133 | 133 | tmo = 20; |
| 134 | 134 | do { |
| 135 | 135 | udelay(21); |
| 136 | − if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) | |
| 136 | + if (__raw_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) | |
| 137 | 137 | break; |
| 138 | 138 | } while (--tmo); |
| 139 | 139 | |
| 140 | − au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 141 | − au_sync(); | |
| 140 | + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); | |
| 141 | + wmb(); /* drain writebuffer */ | |
| 142 | 142 | |
| 143 | 143 | mutex_unlock(&pscdata->lock); |
| 144 | 144 | } while (--retry && !tmo); |
| @@ -149,11 +149,11 @@ static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97) · 4 unmodified lines | ||
| 149 | 149 | { |
| 150 | 150 | struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); |
| 151 | 151 | |
| 152 | − au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata)); | |
| 153 | − au_sync(); | |
| 152 | + __raw_writel(PSC_AC97RST_SNC, AC97_RST(pscdata)); | |
| 153 | + wmb(); /* drain writebuffer */ | |
| 154 | 154 | msleep(10); |
| 155 | − au_writel(0, AC97_RST(pscdata)); | |
| 156 | − au_sync(); | |
| 155 | + __raw_writel(0, AC97_RST(pscdata)); | |
| 156 | + wmb(); /* drain writebuffer */ | |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) |
| @@ -162,25 +162,25 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) · 2 unmodified lines | ||
| 162 | 162 | int i; |
| 163 | 163 | |
| 164 | 164 | /* disable PSC during cold reset */ |
| 165 | − au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); | |
| 166 | − au_sync(); | |
| 167 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata)); | |
| 168 | − au_sync(); | |
| 165 | + __raw_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); | |
| 166 | + wmb(); /* drain writebuffer */ | |
| 167 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata)); | |
| 168 | + wmb(); /* drain writebuffer */ | |
| 169 | 169 | |
| 170 | 170 | /* issue cold reset */ |
| 171 | − au_writel(PSC_AC97RST_RST, AC97_RST(pscdata)); | |
| 172 | − au_sync(); | |
| 171 | + __raw_writel(PSC_AC97RST_RST, AC97_RST(pscdata)); | |
| 172 | + wmb(); /* drain writebuffer */ | |
| 173 | 173 | msleep(500); |
| 174 | − au_writel(0, AC97_RST(pscdata)); | |
| 175 | − au_sync(); | |
| 174 | + __raw_writel(0, AC97_RST(pscdata)); | |
| 175 | + wmb(); /* drain writebuffer */ | |
| 176 | 176 | |
| 177 | 177 | /* enable PSC */ |
| 178 | − au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); | |
| 179 | − au_sync(); | |
| 178 | + __raw_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); | |
| 179 | + wmb(); /* drain writebuffer */ | |
| 180 | 180 | |
| 181 | 181 | /* wait for PSC to indicate it's ready */ |
| 182 | 182 | i = 1000; |
| 183 | − while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) | |
| 183 | + while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) | |
| 184 | 184 | msleep(1); |
| 185 | 185 | |
| 186 | 186 | if (i == 0) { |
| @@ -189,12 +189,12 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) · 2 unmodified lines | ||
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | /* enable the ac97 function */ |
| 192 | − au_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | |
| 193 | − au_sync(); | |
| 192 | + __raw_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | |
| 193 | + wmb(); /* drain writebuffer */ | |
| 194 | 194 | |
| 195 | 195 | /* wait for AC97 core to become ready */ |
| 196 | 196 | i = 1000; |
| 197 | − while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) | |
| 197 | + while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) | |
| 198 | 198 | msleep(1); |
| 199 | 199 | if (i == 0) |
| 200 | 200 | printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n"); |
| @@ -218,8 +218,8 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, · 17 unmodified lines | ||
| 218 | 218 | |
| 219 | 219 | chans = params_channels(params); |
| 220 | 220 | |
| 221 | − r = ro = au_readl(AC97_CFG(pscdata)); | |
| 222 | − stat = au_readl(AC97_STAT(pscdata)); | |
| 221 | + r = ro = __raw_readl(AC97_CFG(pscdata)); | |
| 222 | + stat = __raw_readl(AC97_STAT(pscdata)); | |
| 223 | 223 | |
| 224 | 224 | /* already active? */ |
| 225 | 225 | if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) { |
| @@ -252,28 +252,28 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, · 26 unmodified lines | ||
| 252 | 252 | mutex_lock(&pscdata->lock); |
| 253 | 253 | |
| 254 | 254 | /* disable AC97 device controller first... */ |
| 255 | − au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | |
| 256 | − au_sync(); | |
| 255 | + __raw_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | |
| 256 | + wmb(); /* drain writebuffer */ | |
| 257 | 257 | |
| 258 | 258 | /* ...wait for it... */ |
| 259 | 259 | t = 100; |
| 260 | − while ((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t) | |
| 260 | + while ((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t) | |
| 261 | 261 | msleep(1); |
| 262 | 262 | |
| 263 | 263 | if (!t) |
| 264 | 264 | printk(KERN_ERR "PSC-AC97: can't disable!\n"); |
| 265 | 265 | |
| 266 | 266 | /* ...write config... */ |
| 267 | − au_writel(r, AC97_CFG(pscdata)); | |
| 268 | − au_sync(); | |
| 267 | + __raw_writel(r, AC97_CFG(pscdata)); | |
| 268 | + wmb(); /* drain writebuffer */ | |
| 269 | 269 | |
| 270 | 270 | /* ...enable the AC97 controller again... */ |
| 271 | − au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | |
| 272 | − au_sync(); | |
| 271 | + __raw_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); | |
| 272 | + wmb(); /* drain writebuffer */ | |
| 273 | 273 | |
| 274 | 274 | /* ...and wait for ready bit */ |
| 275 | 275 | t = 100; |
| 276 | − while ((!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t) | |
| 276 | + while ((!(__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t) | |
| 277 | 277 | msleep(1); |
| 278 | 278 | |
| 279 | 279 | if (!t) |
| @@ -300,21 +300,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, · 20 unmodified lines | ||
| 300 | 300 | switch (cmd) { |
| 301 | 301 | case SNDRV_PCM_TRIGGER_START: |
| 302 | 302 | case SNDRV_PCM_TRIGGER_RESUME: |
| 303 | − au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); | |
| 304 | − au_sync(); | |
| 305 | − au_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); | |
| 306 | − au_sync(); | |
| 303 | + __raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); | |
| 304 | + wmb(); /* drain writebuffer */ | |
| 305 | + __raw_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); | |
| 306 | + wmb(); /* drain writebuffer */ | |
| 307 | 307 | break; |
| 308 | 308 | case SNDRV_PCM_TRIGGER_STOP: |
| 309 | 309 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 310 | − au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); | |
| 311 | − au_sync(); | |
| 310 | + __raw_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); | |
| 311 | + wmb(); /* drain writebuffer */ | |
| 312 | 312 | |
| 313 | − while (au_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype)) | |
| 313 | + while (__raw_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype)) | |
| 314 | 314 | asm volatile ("nop"); |
| 315 | 315 | |
| 316 | − au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); | |
| 317 | − au_sync(); | |
| 316 | + __raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); | |
| 317 | + wmb(); /* drain writebuffer */ | |
| 318 | 318 | |
| 319 | 319 | break; |
| 320 | 320 | default: |
| @@ -398,13 +398,13 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) · 77 unmodified lines | ||
| 398 | 398 | PSC_AC97CFG_DE_ENABLE; |
| 399 | 399 | |
| 400 | 400 | /* preserve PSC clock source set up by platform */ |
| 401 | − sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; | |
| 402 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 403 | − au_sync(); | |
| 404 | − au_writel(0, PSC_SEL(wd)); | |
| 405 | − au_sync(); | |
| 406 | − au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd)); | |
| 407 | − au_sync(); | |
| 401 | + sel = __raw_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; | |
| 402 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 403 | + wmb(); /* drain writebuffer */ | |
| 404 | + __raw_writel(0, PSC_SEL(wd)); | |
| 405 | + wmb(); /* drain writebuffer */ | |
| 406 | + __raw_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd)); | |
| 407 | + wmb(); /* drain writebuffer */ | |
| 408 | 408 | |
| 409 | 409 | /* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */ |
| 410 | 410 | memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template, |
| @@ -433,10 +433,10 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev) · 22 unmodified lines | ||
| 433 | 433 | snd_soc_unregister_component(&pdev->dev); |
| 434 | 434 | |
| 435 | 435 | /* disable PSC completely */ |
| 436 | − au_writel(0, AC97_CFG(wd)); | |
| 437 | − au_sync(); | |
| 438 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 439 | − au_sync(); | |
| 436 | + __raw_writel(0, AC97_CFG(wd)); | |
| 437 | + wmb(); /* drain writebuffer */ | |
| 438 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 439 | + wmb(); /* drain writebuffer */ | |
| 440 | 440 | |
| 441 | 441 | au1xpsc_ac97_workdata = NULL; /* MDEV */ |
| 442 | 442 | |
| @@ -449,12 +449,12 @@ static int au1xpsc_ac97_drvsuspend(struct device *dev) · 6 unmodified lines | ||
| 449 | 449 | struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); |
| 450 | 450 | |
| 451 | 451 | /* save interesting registers and disable PSC */ |
| 452 | − wd->pm[0] = au_readl(PSC_SEL(wd)); | |
| 452 | + wd->pm[0] = __raw_readl(PSC_SEL(wd)); | |
| 453 | 453 | |
| 454 | − au_writel(0, AC97_CFG(wd)); | |
| 455 | − au_sync(); | |
| 456 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 457 | − au_sync(); | |
| 454 | + __raw_writel(0, AC97_CFG(wd)); | |
| 455 | + wmb(); /* drain writebuffer */ | |
| 456 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 457 | + wmb(); /* drain writebuffer */ | |
| 458 | 458 | |
| 459 | 459 | return 0; |
| 460 | 460 | } |
| @@ -464,8 +464,8 @@ static int au1xpsc_ac97_drvresume(struct device *dev) · 3 unmodified lines | ||
| 464 | 464 | struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); |
| 465 | 465 | |
| 466 | 466 | /* restore PSC clock config */ |
| 467 | − au_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd)); | |
| 468 | − au_sync(); | |
| 467 | + __raw_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd)); | |
| 468 | + wmb(); /* drain writebuffer */ | |
| 469 | 469 | |
| 470 | 470 | /* after this point the ac97 core will cold-reset the codec. |
| 471 | 471 | * During cold-reset the PSC is reinitialized and the last |
| @@ -120,10 +120,10 @@ static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream, · 119 unmodified lines | ||
| 120 | 120 | unsigned long stat; |
| 121 | 121 | |
| 122 | 122 | /* check if the PSC is already streaming data */ |
| 123 | − stat = au_readl(I2S_STAT(pscdata)); | |
| 123 | + stat = __raw_readl(I2S_STAT(pscdata)); | |
| 124 | 124 | if (stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB)) { |
| 125 | 125 | /* reject parameters not currently set up in hardware */ |
| 126 | − cfgbits = au_readl(I2S_CFG(pscdata)); | |
| 126 | + cfgbits = __raw_readl(I2S_CFG(pscdata)); | |
| 127 | 127 | if ((PSC_I2SCFG_GET_LEN(cfgbits) != params->msbits) || |
| 128 | 128 | (params_rate(params) != pscdata->rate)) |
| 129 | 129 | return -EINVAL; |
| @@ -149,33 +149,33 @@ static int au1xpsc_i2s_configure(struct au1xpsc_audio_data *pscdata) · 19 unmodified lines | ||
| 149 | 149 | unsigned long tmo; |
| 150 | 150 | |
| 151 | 151 | /* bring PSC out of sleep, and configure I2S unit */ |
| 152 | − au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); | |
| 153 | − au_sync(); | |
| 152 | + __raw_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); | |
| 153 | + wmb(); /* drain writebuffer */ | |
| 154 | 154 | |
| 155 | 155 | tmo = 1000000; |
| 156 | − while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_SR) && tmo) | |
| 156 | + while (!(__raw_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_SR) && tmo) | |
| 157 | 157 | tmo--; |
| 158 | 158 | |
| 159 | 159 | if (!tmo) |
| 160 | 160 | goto psc_err; |
| 161 | 161 | |
| 162 | − au_writel(0, I2S_CFG(pscdata)); | |
| 163 | − au_sync(); | |
| 164 | − au_writel(pscdata->cfg | PSC_I2SCFG_DE_ENABLE, I2S_CFG(pscdata)); | |
| 165 | − au_sync(); | |
| 162 | + __raw_writel(0, I2S_CFG(pscdata)); | |
| 163 | + wmb(); /* drain writebuffer */ | |
| 164 | + __raw_writel(pscdata->cfg | PSC_I2SCFG_DE_ENABLE, I2S_CFG(pscdata)); | |
| 165 | + wmb(); /* drain writebuffer */ | |
| 166 | 166 | |
| 167 | 167 | /* wait for I2S controller to become ready */ |
| 168 | 168 | tmo = 1000000; |
| 169 | − while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_DR) && tmo) | |
| 169 | + while (!(__raw_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_DR) && tmo) | |
| 170 | 170 | tmo--; |
| 171 | 171 | |
| 172 | 172 | if (tmo) |
| 173 | 173 | return 0; |
| 174 | 174 | |
| 175 | 175 | psc_err: |
| 176 | − au_writel(0, I2S_CFG(pscdata)); | |
| 177 | − au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); | |
| 178 | − au_sync(); | |
| 176 | + __raw_writel(0, I2S_CFG(pscdata)); | |
| 177 | + __raw_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); | |
| 178 | + wmb(); /* drain writebuffer */ | |
| 179 | 179 | return -ETIMEDOUT; |
| 180 | 180 | } |
| 181 | 181 | |
| @@ -187,26 +187,26 @@ static int au1xpsc_i2s_start(struct au1xpsc_audio_data *pscdata, int stype) · 5 unmodified lines | ||
| 187 | 187 | ret = 0; |
| 188 | 188 | |
| 189 | 189 | /* if both TX and RX are idle, configure the PSC */ |
| 190 | − stat = au_readl(I2S_STAT(pscdata)); | |
| 190 | + stat = __raw_readl(I2S_STAT(pscdata)); | |
| 191 | 191 | if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) { |
| 192 | 192 | ret = au1xpsc_i2s_configure(pscdata); |
| 193 | 193 | if (ret) |
| 194 | 194 | goto out; |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | − au_writel(I2SPCR_CLRFIFO(stype), I2S_PCR(pscdata)); | |
| 198 | − au_sync(); | |
| 199 | − au_writel(I2SPCR_START(stype), I2S_PCR(pscdata)); | |
| 200 | − au_sync(); | |
| 197 | + __raw_writel(I2SPCR_CLRFIFO(stype), I2S_PCR(pscdata)); | |
| 198 | + wmb(); /* drain writebuffer */ | |
| 199 | + __raw_writel(I2SPCR_START(stype), I2S_PCR(pscdata)); | |
| 200 | + wmb(); /* drain writebuffer */ | |
| 201 | 201 | |
| 202 | 202 | /* wait for start confirmation */ |
| 203 | 203 | tmo = 1000000; |
| 204 | − while (!(au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) | |
| 204 | + while (!(__raw_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) | |
| 205 | 205 | tmo--; |
| 206 | 206 | |
| 207 | 207 | if (!tmo) { |
| 208 | − au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); | |
| 209 | − au_sync(); | |
| 208 | + __raw_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); | |
| 209 | + wmb(); /* drain writebuffer */ | |
| 210 | 210 | ret = -ETIMEDOUT; |
| 211 | 211 | } |
| 212 | 212 | out: |
| @@ -217,21 +217,21 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype) · 4 unmodified lines | ||
| 217 | 217 | { |
| 218 | 218 | unsigned long tmo, stat; |
| 219 | 219 | |
| 220 | − au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); | |
| 221 | − au_sync(); | |
| 220 | + __raw_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); | |
| 221 | + wmb(); /* drain writebuffer */ | |
| 222 | 222 | |
| 223 | 223 | /* wait for stop confirmation */ |
| 224 | 224 | tmo = 1000000; |
| 225 | − while ((au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) | |
| 225 | + while ((__raw_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) | |
| 226 | 226 | tmo--; |
| 227 | 227 | |
| 228 | 228 | /* if both TX and RX are idle, disable PSC */ |
| 229 | − stat = au_readl(I2S_STAT(pscdata)); | |
| 229 | + stat = __raw_readl(I2S_STAT(pscdata)); | |
| 230 | 230 | if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) { |
| 231 | − au_writel(0, I2S_CFG(pscdata)); | |
| 232 | − au_sync(); | |
| 233 | − au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); | |
| 234 | − au_sync(); | |
| 231 | + __raw_writel(0, I2S_CFG(pscdata)); | |
| 232 | + wmb(); /* drain writebuffer */ | |
| 233 | + __raw_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); | |
| 234 | + wmb(); /* drain writebuffer */ | |
| 235 | 235 | } |
| 236 | 236 | return 0; |
| 237 | 237 | } |
| @@ -332,12 +332,12 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) · 94 unmodified lines | ||
| 332 | 332 | /* preserve PSC clock source set up by platform (dev.platform_data |
| 333 | 333 | * is already occupied by soc layer) |
| 334 | 334 | */ |
| 335 | − sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; | |
| 336 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 337 | − au_sync(); | |
| 338 | − au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd)); | |
| 339 | − au_writel(0, I2S_CFG(wd)); | |
| 340 | − au_sync(); | |
| 335 | + sel = __raw_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; | |
| 336 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 337 | + wmb(); /* drain writebuffer */ | |
| 338 | + __raw_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd)); | |
| 339 | + __raw_writel(0, I2S_CFG(wd)); | |
| 340 | + wmb(); /* drain writebuffer */ | |
| 341 | 341 | |
| 342 | 342 | /* preconfigure: set max rx/tx fifo depths */ |
| 343 | 343 | wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8; |
| @@ -364,10 +364,10 @@ static int au1xpsc_i2s_drvremove(struct platform_device *pdev) · 20 unmodified lines | ||
| 364 | 364 | |
| 365 | 365 | snd_soc_unregister_component(&pdev->dev); |
| 366 | 366 | |
| 367 | − au_writel(0, I2S_CFG(wd)); | |
| 368 | − au_sync(); | |
| 369 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 370 | − au_sync(); | |
| 367 | + __raw_writel(0, I2S_CFG(wd)); | |
| 368 | + wmb(); /* drain writebuffer */ | |
| 369 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 370 | + wmb(); /* drain writebuffer */ | |
| 371 | 371 | |
| 372 | 372 | return 0; |
| 373 | 373 | } |
| @@ -378,12 +378,12 @@ static int au1xpsc_i2s_drvsuspend(struct device *dev) · 4 unmodified lines | ||
| 378 | 378 | struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); |
| 379 | 379 | |
| 380 | 380 | /* save interesting register and disable PSC */ |
| 381 | − wd->pm[0] = au_readl(PSC_SEL(wd)); | |
| 381 | + wd->pm[0] = __raw_readl(PSC_SEL(wd)); | |
| 382 | 382 | |
| 383 | − au_writel(0, I2S_CFG(wd)); | |
| 384 | − au_sync(); | |
| 385 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 386 | − au_sync(); | |
| 383 | + __raw_writel(0, I2S_CFG(wd)); | |
| 384 | + wmb(); /* drain writebuffer */ | |
| 385 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 386 | + wmb(); /* drain writebuffer */ | |
| 387 | 387 | |
| 388 | 388 | return 0; |
| 389 | 389 | } |
| @@ -393,12 +393,12 @@ static int au1xpsc_i2s_drvresume(struct device *dev) · 3 unmodified lines | ||
| 393 | 393 | struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); |
| 394 | 394 | |
| 395 | 395 | /* select I2S mode and PSC clock */ |
| 396 | − au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 397 | − au_sync(); | |
| 398 | − au_writel(0, PSC_SEL(wd)); | |
| 399 | − au_sync(); | |
| 400 | − au_writel(wd->pm[0], PSC_SEL(wd)); | |
| 401 | − au_sync(); | |
| 396 | + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); | |
| 397 | + wmb(); /* drain writebuffer */ | |
| 398 | + __raw_writel(0, PSC_SEL(wd)); | |
| 399 | + wmb(); /* drain writebuffer */ | |
| 400 | + __raw_writel(wd->pm[0], PSC_SEL(wd)); | |
| 401 | + wmb(); /* drain writebuffer */ | |
| 402 | 402 | |
| 403 | 403 | return 0; |
| 404 | 404 | } |
| @@ -27,16 +27,16 @@ struct au1xpsc_audio_data { · 26 unmodified lines | ||
| 27 | 27 | }; |
| 28 | 28 | |
| 29 | 29 | /* easy access macros */ |
| 30 | −#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) | |
| 31 | −#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) | |
| 32 | −#define I2S_STAT(x) ((unsigned long)((x)->mmio) + PSC_I2SSTAT_OFFSET) | |
| 33 | −#define I2S_CFG(x) ((unsigned long)((x)->mmio) + PSC_I2SCFG_OFFSET) | |
| 34 | −#define I2S_PCR(x) ((unsigned long)((x)->mmio) + PSC_I2SPCR_OFFSET) | |
| 35 | −#define AC97_CFG(x) ((unsigned long)((x)->mmio) + PSC_AC97CFG_OFFSET) | |
| 36 | −#define AC97_CDC(x) ((unsigned long)((x)->mmio) + PSC_AC97CDC_OFFSET) | |
| 37 | −#define AC97_EVNT(x) ((unsigned long)((x)->mmio) + PSC_AC97EVNT_OFFSET) | |
| 38 | −#define AC97_PCR(x) ((unsigned long)((x)->mmio) + PSC_AC97PCR_OFFSET) | |
| 39 | −#define AC97_RST(x) ((unsigned long)((x)->mmio) + PSC_AC97RST_OFFSET) | |
| 40 | −#define AC97_STAT(x) ((unsigned long)((x)->mmio) + PSC_AC97STAT_OFFSET) | |
| 30 | +#define PSC_CTRL(x) ((x)->mmio + PSC_CTRL_OFFSET) | |
| 31 | +#define PSC_SEL(x) ((x)->mmio + PSC_SEL_OFFSET) | |
| 32 | +#define I2S_STAT(x) ((x)->mmio + PSC_I2SSTAT_OFFSET) | |
| 33 | +#define I2S_CFG(x) ((x)->mmio + PSC_I2SCFG_OFFSET) | |
| 34 | +#define I2S_PCR(x) ((x)->mmio + PSC_I2SPCR_OFFSET) | |
| 35 | +#define AC97_CFG(x) ((x)->mmio + PSC_AC97CFG_OFFSET) | |
| 36 | +#define AC97_CDC(x) ((x)->mmio + PSC_AC97CDC_OFFSET) | |
| 37 | +#define AC97_EVNT(x) ((x)->mmio + PSC_AC97EVNT_OFFSET) | |
| 38 | +#define AC97_PCR(x) ((x)->mmio + PSC_AC97PCR_OFFSET) | |
| 39 | +#define AC97_RST(x) ((x)->mmio + PSC_AC97RST_OFFSET) | |
| 40 | +#define AC97_STAT(x) ((x)->mmio + PSC_AC97STAT_OFFSET) | |
| 41 | 41 | |
| 42 | 42 | #endif |