Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
 "This is an unusually large pull request for MIPS - in parts because
  lots of patches missed the 3.18 deadline but primarily because some
  folks opened the flood gates.
   - Retire the MIPS-specific phys_t with the generic phys_addr_t.
   - Improvments for the backtrace code used by oprofile.
   - Better backtraces on SMP systems.
   - Cleanups for the Octeon platform code.
   - Cleanups and fixes for the Loongson platform code.
   - Cleanups and fixes to the firmware library.
   - Switch ATH79 platform to use the firmware library.
   - Grand overhault to the SEAD3 and Malta interrupt code.
   - Move the GIC interrupt code to drivers/irqchip
   - Lots of GIC cleanups and updates to the GIC code to use modern IRQ
     infrastructures and features of the kernel.
   - OF documentation updates for the GIC bindings
   - Move GIC clocksource driver to drivers/clocksource
   - Merge GIC clocksource driver with clockevent driver.
   - Further updates to bring the GIC clocksource driver up to date.
   - R3000 TLB code cleanups
   - Improvments to the Loongson 3 platform code.
   - Convert pr_warning to pr_warn.
   - Merge a bunch of small lantiq and ralink fixes that have been
     staged/lingering inside the openwrt tree for a while.
   - Update archhelp for IP22/IP32
   - Fix a number of issues for Loongson 1B.
   - New clocksource and clockevent driver for Loongson 1B.
   - Further work on clk handling for Loongson 1B.
   - Platform work for Broadcom BMIPS.
   - Error handling cleanups for TurboChannel.
   - Fixes and optimization to the microMIPS support.
   - Option to disable the FTLB.
   - Dump more relevant information on machine check exception
   - Change binfmt to allow arch to examine PT_*PROC headers
   - Support for new style FPU register model in O32
   - VDSO randomization.
   - BCM47xx cleanups
   - BCM47xx reimplement the way the kernel accesses NVRAM information.
   - Random cleanups
   - Add support for ATH25 platforms
   - Remove pointless locking code in some PCI platforms.
   - Some improvments to EVA support
   - Minor Alchemy cleanup"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (185 commits)
  MIPS: Add MFHC0 and MTHC0 instructions to uasm.
  MIPS: Cosmetic cleanups of page table headers.
  MIPS: Add CP0 macros for extended EntryLo registers
  MIPS: Remove now unused definition of phys_t.
  MIPS: Replace use of phys_t with phys_addr_t.
  MIPS: Replace MIPS-specific 64BIT_PHYS_ADDR with generic PHYS_ADDR_T_64BIT
  PCMCIA: Alchemy Don't select 64BIT_PHYS_ADDR in Kconfig.
  MIPS: lib: memset: Clean up some MIPS{EL,EB} ifdefery
  MIPS: iomap: Use __mem_{read,write}{b,w,l} for MMIO
  MIPS: <asm/types.h> fix indentation.
  MAINTAINERS: Add entry for BMIPS multiplatform kernel
  MIPS: Enable VDSO randomization
  MIPS: Remove a temporary hack for debugging cache flushes in SMTC configuration
  MIPS: Remove declaration of obsolete arch_init_clk_ops()
  MIPS: atomic.h: Reformat to fit in 79 columns
  MIPS: Apply `.insn' to fixup labels throughout
  MIPS: Fix microMIPS LL/SC immediate offsets
  MIPS: Kconfig: Only allow 32-bit microMIPS builds
  MIPS: signal.c: Fix an invalid cast in ISA mode bit handling
  MIPS: mm: Only build one microassembler that is suitable
  ...
	
	
This commit is contained in:
		
				commit
				
					
						c0222ac086
					
				
			
		
					 289 changed files with 9838 additions and 3446 deletions
				
			
		|  | @ -0,0 +1,55 @@ | |||
| MIPS Global Interrupt Controller (GIC) | ||||
| 
 | ||||
| The MIPS GIC routes external interrupts to individual VPEs and IRQ pins. | ||||
| It also supports local (per-processor) interrupts and software-generated | ||||
| interrupts which can be used as IPIs.  The GIC also includes a free-running | ||||
| global timer, per-CPU count/compare timers, and a watchdog. | ||||
| 
 | ||||
| Required properties: | ||||
| - compatible : Should be "mti,gic". | ||||
| - interrupt-controller : Identifies the node as an interrupt controller | ||||
| - #interrupt-cells : Specifies the number of cells needed to encode an | ||||
|   interrupt specifier.  Should be 3. | ||||
|   - The first cell is the type of interrupt, local or shared. | ||||
|     See <include/dt-bindings/interrupt-controller/mips-gic.h>. | ||||
|   - The second cell is the GIC interrupt number. | ||||
|   - The third cell encodes the interrupt flags. | ||||
|     See <include/dt-bindings/interrupt-controller/irq.h> for a list of valid | ||||
|     flags. | ||||
| 
 | ||||
| Optional properties: | ||||
| - reg : Base address and length of the GIC registers.  If not present, | ||||
|   the base address reported by the hardware GCR_GIC_BASE will be used. | ||||
| - mti,reserved-cpu-vectors : Specifies the list of CPU interrupt vectors | ||||
|   to which the GIC may not route interrupts.  Valid values are 2 - 7. | ||||
|   This property is ignored if the CPU is started in EIC mode. | ||||
| 
 | ||||
| Required properties for timer sub-node: | ||||
| - compatible : Should be "mti,gic-timer". | ||||
| - interrupts : Interrupt for the GIC local timer. | ||||
| - clock-frequency : Clock frequency at which the GIC timers operate. | ||||
| 
 | ||||
| Example: | ||||
| 
 | ||||
| 	gic: interrupt-controller@1bdc0000 { | ||||
| 		compatible = "mti,gic"; | ||||
| 		reg = <0x1bdc0000 0x20000>; | ||||
| 
 | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <3>; | ||||
| 
 | ||||
| 		mti,reserved-cpu-vectors = <7>; | ||||
| 
 | ||||
| 		timer { | ||||
| 			compatible = "mti,gic-timer"; | ||||
| 			interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>; | ||||
| 			clock-frequency = <50000000>; | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 	uart@18101400 { | ||||
| 		... | ||||
| 		interrupt-parent = <&gic>; | ||||
| 		interrupts = <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>; | ||||
| 		... | ||||
| 	}; | ||||
							
								
								
									
										37
									
								
								Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| * Interrupt Controller | ||||
| 
 | ||||
| Properties: | ||||
| - compatible: "brcm,bcm3384-intc" | ||||
| 
 | ||||
|   Compatibility with BCM3384 and possibly other BCM33xx/BCM63xx SoCs. | ||||
| 
 | ||||
| - reg: Address/length pairs for each mask/status register set.  Length must | ||||
|   be 8.  If multiple register sets are specified, the first set will | ||||
|   handle IRQ offsets 0..31, the second set 32..63, and so on. | ||||
| 
 | ||||
| - interrupt-controller: This is an interrupt controller. | ||||
| 
 | ||||
| - #interrupt-cells: Must be <1>.  Just a simple IRQ offset; no level/edge | ||||
|   or polarity configuration is possible with this controller. | ||||
| 
 | ||||
| - interrupt-parent: This controller is cascaded from a MIPS CPU HW IRQ, or | ||||
|   from another INTC. | ||||
| 
 | ||||
| - interrupts: The IRQ on the parent controller. | ||||
| 
 | ||||
| Example: | ||||
| 	periph_intc: periph_intc@14e00038 { | ||||
| 		compatible = "brcm,bcm3384-intc"; | ||||
| 
 | ||||
| 		/* | ||||
| 		 * IRQs 0..31:  mask reg 0x14e00038, status reg 0x14e0003c | ||||
| 		 * IRQs 32..63: mask reg 0x14e00340, status reg 0x14e00344 | ||||
| 		 */ | ||||
| 		reg = <0x14e00038 0x8 0x14e00340 0x8>; | ||||
| 
 | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 
 | ||||
| 		interrupt-parent = <&cpu_intc>; | ||||
| 		interrupts = <4>; | ||||
| 	}; | ||||
							
								
								
									
										8
									
								
								Documentation/devicetree/bindings/mips/brcm/bmips.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Documentation/devicetree/bindings/mips/brcm/bmips.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| * Broadcom MIPS (BMIPS) CPUs | ||||
| 
 | ||||
| Required properties: | ||||
| - compatible: "brcm,bmips3300", "brcm,bmips4350", "brcm,bmips4380", | ||||
|   "brcm,bmips5000" | ||||
| 
 | ||||
| - mips-hpt-frequency: This is common to all CPUs in the system so it lives | ||||
|   under the "cpus" node. | ||||
							
								
								
									
										11
									
								
								Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| * Broadcom cable/DSL platforms | ||||
| 
 | ||||
| SoCs: | ||||
| 
 | ||||
| Required properties: | ||||
| - compatible: "brcm,bcm3384", "brcm,bcm33843" | ||||
| 
 | ||||
| Boards: | ||||
| 
 | ||||
| Required properties: | ||||
| - compatible: "brcm,bcm93384wvg" | ||||
							
								
								
									
										11
									
								
								Documentation/devicetree/bindings/mips/brcm/usb.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Documentation/devicetree/bindings/mips/brcm/usb.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| * Broadcom USB controllers | ||||
| 
 | ||||
| Required properties: | ||||
| - compatible: "brcm,bcm3384-ohci", "brcm,bcm3384-ehci" | ||||
| 
 | ||||
|   These currently use the generic-ohci and generic-ehci drivers.  On some | ||||
|   systems, special handling may be needed in the following cases: | ||||
| 
 | ||||
|   - Restoring state after systemwide power save modes | ||||
|   - Sharing PHYs with the USBD (UDC) hardware | ||||
|   - Figuring out which controllers are disabled on ASIC bondout variants | ||||
|  | @ -1,6 +1,6 @@ | |||
| MIPS CPU interrupt controller | ||||
| 
 | ||||
| On MIPS the mips_cpu_intc_init() helper can be used to initialize the 8 CPU | ||||
| On MIPS the mips_cpu_irq_of_init() helper can be used to initialize the 8 CPU | ||||
| IRQs from a devicetree file and create a irq_domain for IRQ controller. | ||||
| 
 | ||||
| With the irq_domain in place we can describe how the 8 IRQs are wired to the | ||||
|  | @ -36,7 +36,7 @@ Example devicetree: | |||
| 
 | ||||
| Example platform irq.c: | ||||
| static struct of_device_id __initdata of_irq_ids[] = { | ||||
| 	{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, | ||||
| 	{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, | ||||
| 	{ .compatible = "ralink,rt2880-intc", .data = intc_of_init }, | ||||
| 	{}, | ||||
| }; | ||||
|  |  | |||
|  | @ -101,6 +101,7 @@ mitsubishi	Mitsubishi Electric Corporation | |||
| mosaixtech	Mosaix Technologies, Inc. | ||||
| moxa	Moxa | ||||
| mpl	MPL AG | ||||
| mti	Imagination Technologies Ltd. (formerly MIPS Technologies Inc.) | ||||
| mundoreader	Mundo Reader S.L. | ||||
| murata	Murata Manufacturing Co., Ltd. | ||||
| mxicy	Macronix International Co., Ltd. | ||||
|  |  | |||
							
								
								
									
										26
									
								
								MAINTAINERS
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								MAINTAINERS
									
										
									
									
									
								
							|  | @ -2085,6 +2085,14 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git | |||
| S:	Maintained | ||||
| N:	bcm2835 | ||||
| 
 | ||||
| BROADCOM BCM33XX MIPS ARCHITECTURE | ||||
| M:	Kevin Cernekee <cernekee@gmail.com> | ||||
| L:	linux-mips@linux-mips.org | ||||
| S:	Maintained | ||||
| F:	arch/mips/bcm3384/* | ||||
| F:	arch/mips/include/asm/mach-bcm3384/* | ||||
| F:	arch/mips/kernel/*bmips* | ||||
| 
 | ||||
| BROADCOM BCM5301X ARM ARCHITECTURE | ||||
| M:	Hauke Mehrtens <hauke@hauke-m.de> | ||||
| L:	linux-arm-kernel@lists.infradead.org | ||||
|  | @ -2101,6 +2109,12 @@ S:	Maintained | |||
| F:	arch/arm/mach-bcm/bcm63xx.c | ||||
| F:	arch/arm/include/debug/bcm63xx.S | ||||
| 
 | ||||
| BROADCOM BCM63XX/BCM33XX UDC DRIVER | ||||
| M:	Kevin Cernekee <cernekee@gmail.com> | ||||
| L:	linux-usb@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/usb/gadget/udc/bcm63xx_udc.* | ||||
| 
 | ||||
| BROADCOM BCM7XXX ARM ARCHITECTURE | ||||
| M:	Marc Carino <marc.ceeeee@gmail.com> | ||||
| M:	Brian Norris <computersforpeace@gmail.com> | ||||
|  | @ -2112,6 +2126,18 @@ F:	arch/arm/mach-bcm/*brcmstb* | |||
| F:	arch/arm/boot/dts/bcm7*.dts* | ||||
| F:	drivers/bus/brcmstb_gisb.c | ||||
| 
 | ||||
| BROADCOM BMIPS MIPS ARCHITECTURE | ||||
| M:	Kevin Cernekee <cernekee@gmail.com> | ||||
| M:	Florian Fainelli <f.fainelli@gmail.com> | ||||
| L:	linux-mips@linux-mips.org | ||||
| S:	Maintained | ||||
| F:	arch/mips/bmips/* | ||||
| F:	arch/mips/include/asm/mach-bmips/* | ||||
| F:	arch/mips/kernel/*bmips* | ||||
| F:	arch/mips/boot/dts/bcm*.dts* | ||||
| F:	drivers/irqchip/irq-bcm7* | ||||
| F:	drivers/irqchip/irq-brcmstb* | ||||
| 
 | ||||
| BROADCOM TG3 GIGABIT ETHERNET DRIVER | ||||
| M:	Prashant Sreedharan <prashant@broadcom.com> | ||||
| M:	Michael Chan <mchan@broadcom.com> | ||||
|  |  | |||
|  | @ -2,7 +2,9 @@ | |||
| 
 | ||||
| platforms += alchemy | ||||
| platforms += ar7 | ||||
| platforms += ath25 | ||||
| platforms += ath79 | ||||
| platforms += bcm3384 | ||||
| platforms += bcm47xx | ||||
| platforms += bcm63xx | ||||
| platforms += cavium-octeon | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ config MIPS | |||
| 	select HAVE_CC_STACKPROTECTOR | ||||
| 	select CPU_PM if CPU_IDLE | ||||
| 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | ||||
| 	select ARCH_BINFMT_ELF_STATE | ||||
| 
 | ||||
| menu "Machine selection" | ||||
| 
 | ||||
|  | @ -62,7 +63,7 @@ choice | |||
| 
 | ||||
| config MIPS_ALCHEMY | ||||
| 	bool "Alchemy processor based machines" | ||||
| 	select 64BIT_PHYS_ADDR | ||||
| 	select ARCH_PHYS_ADDR_T_64BIT | ||||
| 	select CEVT_R4K | ||||
| 	select CSRC_R4K | ||||
| 	select IRQ_CPU | ||||
|  | @ -96,6 +97,20 @@ config AR7 | |||
| 	  Support for the Texas Instruments AR7 System-on-a-Chip | ||||
| 	  family: TNETD7100, 7200 and 7300. | ||||
| 
 | ||||
| config ATH25 | ||||
| 	bool "Atheros AR231x/AR531x SoC support" | ||||
| 	select CEVT_R4K | ||||
| 	select CSRC_R4K | ||||
| 	select DMA_NONCOHERENT | ||||
| 	select IRQ_CPU | ||||
| 	select IRQ_DOMAIN | ||||
| 	select SYS_HAS_CPU_MIPS32_R1 | ||||
| 	select SYS_SUPPORTS_BIG_ENDIAN | ||||
| 	select SYS_SUPPORTS_32BIT_KERNEL | ||||
| 	select SYS_HAS_EARLY_PRINTK | ||||
| 	help | ||||
| 	  Support for Atheros AR231x and Atheros AR531x based boards | ||||
| 
 | ||||
| config ATH79 | ||||
| 	bool "Atheros AR71XX/AR724X/AR913X based boards" | ||||
| 	select ARCH_REQUIRE_GPIOLIB | ||||
|  | @ -115,6 +130,32 @@ config ATH79 | |||
| 	help | ||||
| 	  Support for the Atheros AR71XX/AR724X/AR913X SoCs. | ||||
| 
 | ||||
| config BCM3384 | ||||
| 	bool "Broadcom BCM3384 based boards" | ||||
| 	select BOOT_RAW | ||||
| 	select NO_EXCEPT_FILL | ||||
| 	select USE_OF | ||||
| 	select CEVT_R4K | ||||
| 	select CSRC_R4K | ||||
| 	select SYNC_R4K | ||||
| 	select COMMON_CLK | ||||
| 	select DMA_NONCOHERENT | ||||
| 	select IRQ_CPU | ||||
| 	select SYS_SUPPORTS_32BIT_KERNEL | ||||
| 	select SYS_SUPPORTS_BIG_ENDIAN | ||||
| 	select SYS_SUPPORTS_HIGHMEM | ||||
| 	select SYS_HAS_CPU_BMIPS5000 | ||||
| 	select SWAP_IO_SPACE | ||||
| 	select USB_EHCI_BIG_ENDIAN_DESC | ||||
| 	select USB_EHCI_BIG_ENDIAN_MMIO | ||||
| 	select USB_OHCI_BIG_ENDIAN_DESC | ||||
| 	select USB_OHCI_BIG_ENDIAN_MMIO | ||||
| 	help | ||||
| 	  Support for BCM3384 based boards.  BCM3384/BCM33843 is a cable modem | ||||
| 	  chipset with a Linux application processor that is often used to | ||||
| 	  provide Samba services, a CUPS print server, and/or advanced routing | ||||
| 	  features. | ||||
| 
 | ||||
| config BCM47XX | ||||
| 	bool "Broadcom BCM47XX based boards" | ||||
| 	select ARCH_WANT_OPTIONAL_GPIOLIB | ||||
|  | @ -269,6 +310,8 @@ config LANTIQ | |||
| 	select USE_OF | ||||
| 	select PINCTRL | ||||
| 	select PINCTRL_LANTIQ | ||||
| 	select ARCH_HAS_RESET_CONTROLLER | ||||
| 	select RESET_CONTROLLER | ||||
| 
 | ||||
| config LASAT | ||||
| 	bool "LASAT Networks platforms" | ||||
|  | @ -315,17 +358,18 @@ config MIPS_MALTA | |||
| 	select BOOT_RAW | ||||
| 	select CEVT_R4K | ||||
| 	select CSRC_R4K | ||||
| 	select CSRC_GIC | ||||
| 	select CLKSRC_MIPS_GIC | ||||
| 	select DMA_MAYBE_COHERENT | ||||
| 	select GENERIC_ISA_DMA | ||||
| 	select HAVE_PCSPKR_PLATFORM | ||||
| 	select IRQ_CPU | ||||
| 	select IRQ_GIC | ||||
| 	select MIPS_GIC | ||||
| 	select HW_HAS_PCI | ||||
| 	select I8253 | ||||
| 	select I8259 | ||||
| 	select MIPS_BONITO64 | ||||
| 	select MIPS_CPU_SCACHE | ||||
| 	select MIPS_L1_CACHE_SHIFT_6 | ||||
| 	select PCI_GT64XXX_PCI0 | ||||
| 	select MIPS_MSC | ||||
| 	select SWAP_IO_SPACE | ||||
|  | @ -340,6 +384,7 @@ config MIPS_MALTA | |||
| 	select SYS_SUPPORTS_64BIT_KERNEL | ||||
| 	select SYS_SUPPORTS_BIG_ENDIAN | ||||
| 	select SYS_SUPPORTS_LITTLE_ENDIAN | ||||
| 	select SYS_SUPPORTS_MICROMIPS | ||||
| 	select SYS_SUPPORTS_MIPS_CMP | ||||
| 	select SYS_SUPPORTS_MIPS_CPS | ||||
| 	select SYS_SUPPORTS_MIPS16 | ||||
|  | @ -357,12 +402,12 @@ config MIPS_SEAD3 | |||
| 	select BUILTIN_DTB | ||||
| 	select CEVT_R4K | ||||
| 	select CSRC_R4K | ||||
| 	select CSRC_GIC | ||||
| 	select CLKSRC_MIPS_GIC | ||||
| 	select CPU_MIPSR2_IRQ_VI | ||||
| 	select CPU_MIPSR2_IRQ_EI | ||||
| 	select DMA_NONCOHERENT | ||||
| 	select IRQ_CPU | ||||
| 	select IRQ_GIC | ||||
| 	select MIPS_GIC | ||||
| 	select LIBFDT | ||||
| 	select MIPS_MSC | ||||
| 	select SYS_HAS_CPU_MIPS32_R1 | ||||
|  | @ -726,7 +771,7 @@ config MIKROTIK_RB532 | |||
| config CAVIUM_OCTEON_SOC | ||||
| 	bool "Cavium Networks Octeon SoC based boards" | ||||
| 	select CEVT_R4K | ||||
| 	select 64BIT_PHYS_ADDR | ||||
| 	select ARCH_PHYS_ADDR_T_64BIT | ||||
| 	select DMA_COHERENT | ||||
| 	select SYS_SUPPORTS_64BIT_KERNEL | ||||
| 	select SYS_SUPPORTS_BIG_ENDIAN | ||||
|  | @ -768,7 +813,7 @@ config NLM_XLR_BOARD | |||
| 	select SWAP_IO_SPACE | ||||
| 	select SYS_SUPPORTS_32BIT_KERNEL | ||||
| 	select SYS_SUPPORTS_64BIT_KERNEL | ||||
| 	select 64BIT_PHYS_ADDR | ||||
| 	select ARCH_PHYS_ADDR_T_64BIT | ||||
| 	select SYS_SUPPORTS_BIG_ENDIAN | ||||
| 	select SYS_SUPPORTS_HIGHMEM | ||||
| 	select DMA_COHERENT | ||||
|  | @ -794,7 +839,7 @@ config NLM_XLP_BOARD | |||
| 	select HW_HAS_PCI | ||||
| 	select SYS_SUPPORTS_32BIT_KERNEL | ||||
| 	select SYS_SUPPORTS_64BIT_KERNEL | ||||
| 	select 64BIT_PHYS_ADDR | ||||
| 	select ARCH_PHYS_ADDR_T_64BIT | ||||
| 	select SYS_SUPPORTS_BIG_ENDIAN | ||||
| 	select SYS_SUPPORTS_LITTLE_ENDIAN | ||||
| 	select SYS_SUPPORTS_HIGHMEM | ||||
|  | @ -835,6 +880,7 @@ config MIPS_PARAVIRT | |||
| endchoice | ||||
| 
 | ||||
| source "arch/mips/alchemy/Kconfig" | ||||
| source "arch/mips/ath25/Kconfig" | ||||
| source "arch/mips/ath79/Kconfig" | ||||
| source "arch/mips/bcm47xx/Kconfig" | ||||
| source "arch/mips/bcm63xx/Kconfig" | ||||
|  | @ -907,10 +953,6 @@ config CEVT_GT641XX | |||
| config CEVT_R4K | ||||
| 	bool | ||||
| 
 | ||||
| config CEVT_GIC | ||||
| 	select MIPS_CM | ||||
| 	bool | ||||
| 
 | ||||
| config CEVT_SB1250 | ||||
| 	bool | ||||
| 
 | ||||
|  | @ -926,10 +968,6 @@ config CSRC_IOASIC | |||
| config CSRC_R4K | ||||
| 	bool | ||||
| 
 | ||||
| config CSRC_GIC | ||||
| 	select MIPS_CM | ||||
| 	bool | ||||
| 
 | ||||
| config CSRC_SB1250 | ||||
| 	bool | ||||
| 
 | ||||
|  | @ -941,7 +979,7 @@ config FW_CFE | |||
| 	bool | ||||
| 
 | ||||
| config ARCH_DMA_ADDR_T_64BIT | ||||
| 	def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT | ||||
| 	def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT | ||||
| 
 | ||||
| config DMA_MAYBE_COHERENT | ||||
| 	select DMA_NONCOHERENT | ||||
|  | @ -975,6 +1013,7 @@ config SYS_SUPPORTS_HOTPLUG_CPU | |||
| 
 | ||||
| config I8259 | ||||
| 	bool | ||||
| 	select IRQ_DOMAIN | ||||
| 
 | ||||
| config MIPS_BONITO64 | ||||
| 	bool | ||||
|  | @ -1055,6 +1094,7 @@ config MIPS_HUGE_TLB_SUPPORT | |||
| 
 | ||||
| config IRQ_CPU | ||||
| 	bool | ||||
| 	select IRQ_DOMAIN | ||||
| 
 | ||||
| config IRQ_CPU_RM7K | ||||
| 	bool | ||||
|  | @ -1071,10 +1111,6 @@ config IRQ_TXX9 | |||
| config IRQ_GT641XX | ||||
| 	bool | ||||
| 
 | ||||
| config IRQ_GIC | ||||
| 	select MIPS_CM | ||||
| 	bool | ||||
| 
 | ||||
| config PCI_GT64XXX_PCI0 | ||||
| 	bool | ||||
| 
 | ||||
|  | @ -1574,6 +1610,7 @@ config CPU_LOONGSON1 | |||
| 	select CPU_HAS_PREFETCH | ||||
| 	select CPU_SUPPORTS_32BIT_KERNEL | ||||
| 	select CPU_SUPPORTS_HIGHMEM | ||||
| 	select CPU_SUPPORTS_CPUFREQ | ||||
| 
 | ||||
| config CPU_BMIPS32_3300 | ||||
| 	select SMP_UP if SMP | ||||
|  | @ -1586,12 +1623,14 @@ config CPU_BMIPS4350 | |||
| 
 | ||||
| config CPU_BMIPS4380 | ||||
| 	bool | ||||
| 	select MIPS_L1_CACHE_SHIFT_6 | ||||
| 	select SYS_SUPPORTS_SMP | ||||
| 	select SYS_SUPPORTS_HOTPLUG_CPU | ||||
| 
 | ||||
| config CPU_BMIPS5000 | ||||
| 	bool | ||||
| 	select MIPS_CPU_SCACHE | ||||
| 	select MIPS_L1_CACHE_SHIFT_7 | ||||
| 	select SYS_SUPPORTS_SMP | ||||
| 	select SYS_SUPPORTS_HOTPLUG_CPU | ||||
| 
 | ||||
|  | @ -1886,15 +1925,6 @@ config FORCE_MAX_ZONEORDER | |||
| 	  The page size is not necessarily 4KB.  Keep this in mind | ||||
| 	  when choosing a value for this option. | ||||
| 
 | ||||
| config CEVT_GIC | ||||
| 	bool "Use GIC global counter for clock events" | ||||
| 	depends on IRQ_GIC && !MIPS_SEAD3 | ||||
| 	help | ||||
| 	  Use the GIC global counter for the clock events. The R4K clock | ||||
| 	  event driver is always present, so if the platform ends up not | ||||
| 	  detecting a GIC, it will fall back to the R4K timer for the | ||||
| 	  generation of clock events. | ||||
| 
 | ||||
| config BOARD_SCACHE | ||||
| 	bool | ||||
| 
 | ||||
|  | @ -1908,7 +1938,6 @@ config IP22_CPU_SCACHE | |||
| config MIPS_CPU_SCACHE | ||||
| 	bool | ||||
| 	select BOARD_SCACHE | ||||
| 	select MIPS_L1_CACHE_SHIFT_6 | ||||
| 
 | ||||
| config R5000_CPU_SCACHE | ||||
| 	bool | ||||
|  | @ -2095,11 +2124,8 @@ config SB1_PASS_2_1_WORKAROUNDS | |||
| 	default y | ||||
| 
 | ||||
| 
 | ||||
| config 64BIT_PHYS_ADDR | ||||
| 	bool | ||||
| 
 | ||||
| config ARCH_PHYS_ADDR_T_64BIT | ||||
|        def_bool 64BIT_PHYS_ADDR | ||||
|        bool | ||||
| 
 | ||||
| choice | ||||
| 	prompt "SmartMIPS or microMIPS ASE support" | ||||
|  | @ -2122,7 +2148,7 @@ config CPU_HAS_SMARTMIPS | |||
| 	  here. | ||||
| 
 | ||||
| config CPU_MICROMIPS | ||||
| 	depends on SYS_SUPPORTS_MICROMIPS | ||||
| 	depends on 32BIT && SYS_SUPPORTS_MICROMIPS | ||||
| 	bool "microMIPS" | ||||
| 	help | ||||
| 	  When this option is enabled the kernel will be built using the | ||||
|  |  | |||
|  | @ -122,4 +122,17 @@ config SPINLOCK_TEST | |||
| 	help | ||||
| 	  Add several files to the debugfs to test spinlock speed. | ||||
| 
 | ||||
| config FP32XX_HYBRID_FPRS | ||||
| 	bool "Run FP32 & FPXX code with hybrid FPRs" | ||||
| 	depends on MIPS_O32_FP64_SUPPORT | ||||
| 	help | ||||
| 	  The hybrid FPR scheme is normally used only when a program needs to | ||||
| 	  execute a mix of FP32 & FP64A code, since the trapping & emulation | ||||
| 	  that it entails is expensive. When enabled, this option will lead | ||||
| 	  to the kernel running programs which use the FP32 & FPXX FP ABIs | ||||
| 	  using the hybrid FPR scheme, which can be useful for debugging | ||||
| 	  purposes. | ||||
| 
 | ||||
| 	  If unsure, say N. | ||||
| 
 | ||||
| endmenu | ||||
|  |  | |||
|  | @ -380,6 +380,7 @@ define archhelp | |||
| 	echo '  vmlinux.ecoff        - ECOFF boot image' | ||||
| 	echo '  vmlinux.bin          - Raw binary boot image' | ||||
| 	echo '  vmlinux.srec         - SREC boot image' | ||||
| 	echo '  vmlinux.32           - 64-bit boot image wrapped in 32bits (IP22/IP32)' | ||||
| 	echo '  vmlinuz              - Compressed boot(zboot) image' | ||||
| 	echo '  vmlinuz.ecoff        - ECOFF zboot image' | ||||
| 	echo '  vmlinuz.bin          - Raw binary zboot image' | ||||
|  |  | |||
|  | @ -37,7 +37,6 @@ | |||
| #include <linux/io.h> | ||||
| #include <linux/clk-provider.h> | ||||
| #include <linux/clkdev.h> | ||||
| #include <linux/clk-private.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/types.h> | ||||
|  | @ -397,10 +396,10 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate, | |||
| 			break; | ||||
| 
 | ||||
| 		/* if this parent is currently unused, remember it.
 | ||||
| 		 * XXX: I know it's a layering violation, but it works | ||||
| 		 * so well.. (if (!clk_has_active_children(pc)) ) | ||||
| 		 * XXX: we would actually want clk_has_active_children() | ||||
| 		 * but this is a good-enough approximation for now. | ||||
| 		 */ | ||||
| 		if (pc->prepare_count == 0) { | ||||
| 		if (!__clk_is_prepared(pc)) { | ||||
| 			if (!free) | ||||
| 				free = pc; | ||||
| 		} | ||||
|  |  | |||
|  | @ -70,9 +70,9 @@ void __init plat_mem_setup(void) | |||
| 	iomem_resource.end = IOMEM_RESOURCE_END; | ||||
| } | ||||
| 
 | ||||
| #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) | ||||
| #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) | ||||
| /* This routine should be valid for all Au1x based boards */ | ||||
| phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | ||||
| phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) | ||||
| { | ||||
| 	unsigned long start = ALCHEMY_PCI_MEMWIN_START; | ||||
| 	unsigned long end = ALCHEMY_PCI_MEMWIN_END; | ||||
|  | @ -83,7 +83,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
| 
 | ||||
| 	/* Check for PCI memory window */ | ||||
| 	if (phys_addr >= start && (phys_addr + size - 1) <= end) | ||||
| 		return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); | ||||
| 		return (phys_addr_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); | ||||
| 
 | ||||
| 	/* default nop */ | ||||
| 	return phys_addr; | ||||
|  |  | |||
|  | @ -311,8 +311,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr) | |||
| 					&dev_addr[0], &dev_addr[1], | ||||
| 					&dev_addr[2], &dev_addr[3], | ||||
| 					&dev_addr[4], &dev_addr[5]) != 6) { | ||||
| 			pr_warning("cannot parse mac address, " | ||||
| 					"using random address\n"); | ||||
| 			pr_warn("cannot parse mac address, using random address\n"); | ||||
| 			eth_random_addr(dev_addr); | ||||
| 		} | ||||
| 	} else | ||||
|  | @ -665,7 +664,7 @@ static int __init ar7_register_devices(void) | |||
| 
 | ||||
| 	res = platform_device_register(&physmap_flash); | ||||
| 	if (res) | ||||
| 		pr_warning("unable to register physmap-flash: %d\n", res); | ||||
| 		pr_warn("unable to register physmap-flash: %d\n", res); | ||||
| 
 | ||||
| 	if (ar7_is_titan()) | ||||
| 		titan_fixup_devices(); | ||||
|  | @ -673,13 +672,13 @@ static int __init ar7_register_devices(void) | |||
| 	ar7_device_disable(vlynq_low_data.reset_bit); | ||||
| 	res = platform_device_register(&vlynq_low); | ||||
| 	if (res) | ||||
| 		pr_warning("unable to register vlynq-low: %d\n", res); | ||||
| 		pr_warn("unable to register vlynq-low: %d\n", res); | ||||
| 
 | ||||
| 	if (ar7_has_high_vlynq()) { | ||||
| 		ar7_device_disable(vlynq_high_data.reset_bit); | ||||
| 		res = platform_device_register(&vlynq_high); | ||||
| 		if (res) | ||||
| 			pr_warning("unable to register vlynq-high: %d\n", res); | ||||
| 			pr_warn("unable to register vlynq-high: %d\n", res); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ar7_has_high_cpmac()) { | ||||
|  | @ -689,9 +688,10 @@ static int __init ar7_register_devices(void) | |||
| 
 | ||||
| 			res = platform_device_register(&cpmac_high); | ||||
| 			if (res) | ||||
| 				pr_warning("unable to register cpmac-high: %d\n", res); | ||||
| 				pr_warn("unable to register cpmac-high: %d\n", | ||||
| 					res); | ||||
| 		} else | ||||
| 			pr_warning("unable to add cpmac-high phy: %d\n", res); | ||||
| 			pr_warn("unable to add cpmac-high phy: %d\n", res); | ||||
| 	} else | ||||
| 		cpmac_low_data.phy_mask = 0xffffffff; | ||||
| 
 | ||||
|  | @ -700,18 +700,18 @@ static int __init ar7_register_devices(void) | |||
| 		cpmac_get_mac(0, cpmac_low_data.dev_addr); | ||||
| 		res = platform_device_register(&cpmac_low); | ||||
| 		if (res) | ||||
| 			pr_warning("unable to register cpmac-low: %d\n", res); | ||||
| 			pr_warn("unable to register cpmac-low: %d\n", res); | ||||
| 	} else | ||||
| 		pr_warning("unable to add cpmac-low phy: %d\n", res); | ||||
| 		pr_warn("unable to add cpmac-low phy: %d\n", res); | ||||
| 
 | ||||
| 	detect_leds(); | ||||
| 	res = platform_device_register(&ar7_gpio_leds); | ||||
| 	if (res) | ||||
| 		pr_warning("unable to register leds: %d\n", res); | ||||
| 		pr_warn("unable to register leds: %d\n", res); | ||||
| 
 | ||||
| 	res = platform_device_register(&ar7_udc); | ||||
| 	if (res) | ||||
| 		pr_warning("unable to register usb slave: %d\n", res); | ||||
| 		pr_warn("unable to register usb slave: %d\n", res); | ||||
| 
 | ||||
| 	/* Register watchdog only if enabled in hardware */ | ||||
| 	bootcr = ioremap_nocache(AR7_REGS_DCL, 4); | ||||
|  | @ -726,7 +726,7 @@ static int __init ar7_register_devices(void) | |||
| 		ar7_wdt_res.end = ar7_wdt_res.start + 0x20; | ||||
| 		res = platform_device_register(&ar7_wdt); | ||||
| 		if (res) | ||||
| 			pr_warning("unable to register watchdog: %d\n", res); | ||||
| 			pr_warn("unable to register watchdog: %d\n", res); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
|  |  | |||
							
								
								
									
										16
									
								
								arch/mips/ath25/Kconfig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								arch/mips/ath25/Kconfig
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| config SOC_AR5312 | ||||
| 	bool "Atheros AR5312/AR2312+ SoC support" | ||||
| 	depends on ATH25 | ||||
| 	default y | ||||
| 
 | ||||
| config SOC_AR2315 | ||||
| 	bool "Atheros AR2315+ SoC support" | ||||
| 	depends on ATH25 | ||||
| 	default y | ||||
| 
 | ||||
| config PCI_AR2315 | ||||
| 	bool "Atheros AR2315 PCI controller support" | ||||
| 	depends on SOC_AR2315 | ||||
| 	select HW_HAS_PCI | ||||
| 	select PCI | ||||
| 	default y | ||||
							
								
								
									
										16
									
								
								arch/mips/ath25/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								arch/mips/ath25/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| #
 | ||||
| # This file is subject to the terms and conditions of the GNU General Public
 | ||||
| # License.  See the file "COPYING" in the main directory of this archive
 | ||||
| # for more details.
 | ||||
| #
 | ||||
| # Copyright (C) 2006 FON Technology, SL.
 | ||||
| # Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
 | ||||
| # Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
 | ||||
| #
 | ||||
| 
 | ||||
| obj-y += board.o prom.o devices.o | ||||
| 
 | ||||
| obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||||
| 
 | ||||
| obj-$(CONFIG_SOC_AR5312) += ar5312.o | ||||
| obj-$(CONFIG_SOC_AR2315) += ar2315.o | ||||
							
								
								
									
										6
									
								
								arch/mips/ath25/Platform
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								arch/mips/ath25/Platform
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| # | ||||
| # Atheros AR531X/AR231X WiSoC | ||||
| # | ||||
| platform-$(CONFIG_ATH25)	+= ath25/ | ||||
| cflags-$(CONFIG_ATH25)		+= -I$(srctree)/arch/mips/include/asm/mach-ath25 | ||||
| load-$(CONFIG_ATH25)		+= 0xffffffff80041000 | ||||
							
								
								
									
										364
									
								
								arch/mips/ath25/ar2315.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								arch/mips/ath25/ar2315.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,364 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved. | ||||
|  * Copyright (C) 2006 FON Technology, SL. | ||||
|  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||||
|  * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||||
|  * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Platform devices for Atheros AR2315 SoCs | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/init.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/irqdomain.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/reboot.h> | ||||
| #include <asm/bootinfo.h> | ||||
| #include <asm/reboot.h> | ||||
| #include <asm/time.h> | ||||
| 
 | ||||
| #include <ath25_platform.h> | ||||
| 
 | ||||
| #include "devices.h" | ||||
| #include "ar2315.h" | ||||
| #include "ar2315_regs.h" | ||||
| 
 | ||||
| static void __iomem *ar2315_rst_base; | ||||
| static struct irq_domain *ar2315_misc_irq_domain; | ||||
| 
 | ||||
| static inline u32 ar2315_rst_reg_read(u32 reg) | ||||
| { | ||||
| 	return __raw_readl(ar2315_rst_base + reg); | ||||
| } | ||||
| 
 | ||||
| static inline void ar2315_rst_reg_write(u32 reg, u32 val) | ||||
| { | ||||
| 	__raw_writel(val, ar2315_rst_base + reg); | ||||
| } | ||||
| 
 | ||||
| static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val) | ||||
| { | ||||
| 	u32 ret = ar2315_rst_reg_read(reg); | ||||
| 
 | ||||
| 	ret &= ~mask; | ||||
| 	ret |= val; | ||||
| 	ar2315_rst_reg_write(reg, ret); | ||||
| } | ||||
| 
 | ||||
| static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id) | ||||
| { | ||||
| 	ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); | ||||
| 	ar2315_rst_reg_read(AR2315_AHB_ERR1); | ||||
| 
 | ||||
| 	pr_emerg("AHB fatal error\n"); | ||||
| 	machine_restart("AHB error"); /* Catastrophic failure */ | ||||
| 
 | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| static struct irqaction ar2315_ahb_err_interrupt  = { | ||||
| 	.handler	= ar2315_ahb_err_handler, | ||||
| 	.name		= "ar2315-ahb-error", | ||||
| }; | ||||
| 
 | ||||
| static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc) | ||||
| { | ||||
| 	u32 pending = ar2315_rst_reg_read(AR2315_ISR) & | ||||
| 		      ar2315_rst_reg_read(AR2315_IMR); | ||||
| 	unsigned nr, misc_irq = 0; | ||||
| 
 | ||||
| 	if (pending) { | ||||
| 		struct irq_domain *domain = irq_get_handler_data(irq); | ||||
| 
 | ||||
| 		nr = __ffs(pending); | ||||
| 		misc_irq = irq_find_mapping(domain, nr); | ||||
| 	} | ||||
| 
 | ||||
| 	if (misc_irq) { | ||||
| 		if (nr == AR2315_MISC_IRQ_GPIO) | ||||
| 			ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO); | ||||
| 		else if (nr == AR2315_MISC_IRQ_WATCHDOG) | ||||
| 			ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD); | ||||
| 		generic_handle_irq(misc_irq); | ||||
| 	} else { | ||||
| 		spurious_interrupt(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void ar2315_misc_irq_unmask(struct irq_data *d) | ||||
| { | ||||
| 	ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq)); | ||||
| } | ||||
| 
 | ||||
| static void ar2315_misc_irq_mask(struct irq_data *d) | ||||
| { | ||||
| 	ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0); | ||||
| } | ||||
| 
 | ||||
| static struct irq_chip ar2315_misc_irq_chip = { | ||||
| 	.name		= "ar2315-misc", | ||||
| 	.irq_unmask	= ar2315_misc_irq_unmask, | ||||
| 	.irq_mask	= ar2315_misc_irq_mask, | ||||
| }; | ||||
| 
 | ||||
| static int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq, | ||||
| 			       irq_hw_number_t hw) | ||||
| { | ||||
| 	irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct irq_domain_ops ar2315_misc_irq_domain_ops = { | ||||
| 	.map = ar2315_misc_irq_map, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * Called when an interrupt is received, this function | ||||
|  * determines exactly which interrupt it was, and it | ||||
|  * invokes the appropriate handler. | ||||
|  * | ||||
|  * Implicitly, we also define interrupt priority by | ||||
|  * choosing which to dispatch first. | ||||
|  */ | ||||
| static void ar2315_irq_dispatch(void) | ||||
| { | ||||
| 	u32 pending = read_c0_status() & read_c0_cause(); | ||||
| 
 | ||||
| 	if (pending & CAUSEF_IP3) | ||||
| 		do_IRQ(AR2315_IRQ_WLAN0); | ||||
| #ifdef CONFIG_PCI_AR2315 | ||||
| 	else if (pending & CAUSEF_IP5) | ||||
| 		do_IRQ(AR2315_IRQ_LCBUS_PCI); | ||||
| #endif | ||||
| 	else if (pending & CAUSEF_IP2) | ||||
| 		do_IRQ(AR2315_IRQ_MISC); | ||||
| 	else if (pending & CAUSEF_IP7) | ||||
| 		do_IRQ(ATH25_IRQ_CPU_CLOCK); | ||||
| 	else | ||||
| 		spurious_interrupt(); | ||||
| } | ||||
| 
 | ||||
| void __init ar2315_arch_init_irq(void) | ||||
| { | ||||
| 	struct irq_domain *domain; | ||||
| 	unsigned irq; | ||||
| 
 | ||||
| 	ath25_irq_dispatch = ar2315_irq_dispatch; | ||||
| 
 | ||||
| 	domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT, | ||||
| 				       &ar2315_misc_irq_domain_ops, NULL); | ||||
| 	if (!domain) | ||||
| 		panic("Failed to add IRQ domain"); | ||||
| 
 | ||||
| 	irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB); | ||||
| 	setup_irq(irq, &ar2315_ahb_err_interrupt); | ||||
| 
 | ||||
| 	irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler); | ||||
| 	irq_set_handler_data(AR2315_IRQ_MISC, domain); | ||||
| 
 | ||||
| 	ar2315_misc_irq_domain = domain; | ||||
| } | ||||
| 
 | ||||
| void __init ar2315_init_devices(void) | ||||
| { | ||||
| 	/* Find board configuration */ | ||||
| 	ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); | ||||
| 
 | ||||
| 	ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); | ||||
| } | ||||
| 
 | ||||
| static void ar2315_restart(char *command) | ||||
| { | ||||
| 	void (*mips_reset_vec)(void) = (void *)0xbfc00000; | ||||
| 
 | ||||
| 	local_irq_disable(); | ||||
| 
 | ||||
| 	/* try reset the system via reset control */ | ||||
| 	ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM); | ||||
| 
 | ||||
| 	/* Cold reset does not work on the AR2315/6, use the GPIO reset bits
 | ||||
| 	 * a workaround. Give it some time to attempt a gpio based hardware | ||||
| 	 * reset (atheros reference design workaround) */ | ||||
| 
 | ||||
| 	/* TODO: implement the GPIO reset workaround */ | ||||
| 
 | ||||
| 	/* Some boards (e.g. Senao EOC-2610) don't implement the reset logic
 | ||||
| 	 * workaround. Attempt to jump to the mips reset location - | ||||
| 	 * the boot loader itself might be able to recover the system */ | ||||
| 	mips_reset_vec(); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * This table is indexed by bits 5..4 of the CLOCKCTL1 register | ||||
|  * to determine the predevisor value. | ||||
|  */ | ||||
| static int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; | ||||
| static int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 }; | ||||
| 
 | ||||
| static unsigned __init ar2315_sys_clk(u32 clock_ctl) | ||||
| { | ||||
| 	unsigned int pllc_ctrl, cpu_div; | ||||
| 	unsigned int pllc_out, refdiv, fdiv, divby2; | ||||
| 	unsigned int clk_div; | ||||
| 
 | ||||
| 	pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL); | ||||
| 	refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV); | ||||
| 	refdiv = clockctl1_predivide_table[refdiv]; | ||||
| 	fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV); | ||||
| 	divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1; | ||||
| 	pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv; | ||||
| 
 | ||||
| 	/* clkm input selected */ | ||||
| 	switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) { | ||||
| 	case 0: | ||||
| 	case 1: | ||||
| 		clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV); | ||||
| 		clk_div = pllc_divide_table[clk_div]; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV); | ||||
| 		clk_div = pllc_divide_table[clk_div]; | ||||
| 		break; | ||||
| 	default: | ||||
| 		pllc_out = 40000000; | ||||
| 		clk_div = 1; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV); | ||||
| 	cpu_div = cpu_div * 2 ?: 1; | ||||
| 
 | ||||
| 	return pllc_out / (clk_div * cpu_div); | ||||
| } | ||||
| 
 | ||||
| static inline unsigned ar2315_cpu_frequency(void) | ||||
| { | ||||
| 	return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK)); | ||||
| } | ||||
| 
 | ||||
| static inline unsigned ar2315_apb_frequency(void) | ||||
| { | ||||
| 	return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK)); | ||||
| } | ||||
| 
 | ||||
| void __init ar2315_plat_time_init(void) | ||||
| { | ||||
| 	mips_hpt_frequency = ar2315_cpu_frequency() / 2; | ||||
| } | ||||
| 
 | ||||
| void __init ar2315_plat_mem_setup(void) | ||||
| { | ||||
| 	void __iomem *sdram_base; | ||||
| 	u32 memsize, memcfg; | ||||
| 	u32 devid; | ||||
| 	u32 config; | ||||
| 
 | ||||
| 	/* Detect memory size */ | ||||
| 	sdram_base = ioremap_nocache(AR2315_SDRAMCTL_BASE, | ||||
| 				     AR2315_SDRAMCTL_SIZE); | ||||
| 	memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG); | ||||
| 	memsize   = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH); | ||||
| 	memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH); | ||||
| 	memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH); | ||||
| 	memsize <<= 3; | ||||
| 	add_memory_region(0, memsize, BOOT_MEM_RAM); | ||||
| 	iounmap(sdram_base); | ||||
| 
 | ||||
| 	ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE); | ||||
| 
 | ||||
| 	/* Detect the hardware based on the device ID */ | ||||
| 	devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP; | ||||
| 	switch (devid) { | ||||
| 	case 0x91:	/* Need to check */ | ||||
| 		ath25_soc = ATH25_SOC_AR2318; | ||||
| 		break; | ||||
| 	case 0x90: | ||||
| 		ath25_soc = ATH25_SOC_AR2317; | ||||
| 		break; | ||||
| 	case 0x87: | ||||
| 		ath25_soc = ATH25_SOC_AR2316; | ||||
| 		break; | ||||
| 	case 0x86: | ||||
| 	default: | ||||
| 		ath25_soc = ATH25_SOC_AR2315; | ||||
| 		break; | ||||
| 	} | ||||
| 	ath25_board.devid = devid; | ||||
| 
 | ||||
| 	/* Clear any lingering AHB errors */ | ||||
| 	config = read_c0_config(); | ||||
| 	write_c0_config(config & ~0x3); | ||||
| 	ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); | ||||
| 	ar2315_rst_reg_read(AR2315_AHB_ERR1); | ||||
| 	ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE); | ||||
| 
 | ||||
| 	_machine_restart = ar2315_restart; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_PCI_AR2315 | ||||
| static struct resource ar2315_pci_res[] = { | ||||
| 	{ | ||||
| 		.name = "ar2315-pci-ctrl", | ||||
| 		.flags = IORESOURCE_MEM, | ||||
| 		.start = AR2315_PCI_BASE, | ||||
| 		.end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "ar2315-pci-ext", | ||||
| 		.flags = IORESOURCE_MEM, | ||||
| 		.start = AR2315_PCI_EXT_BASE, | ||||
| 		.end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "ar2315-pci", | ||||
| 		.flags = IORESOURCE_IRQ, | ||||
| 		.start = AR2315_IRQ_LCBUS_PCI, | ||||
| 		.end = AR2315_IRQ_LCBUS_PCI, | ||||
| 	}, | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| void __init ar2315_arch_init(void) | ||||
| { | ||||
| 	unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, | ||||
| 					  AR2315_MISC_IRQ_UART0); | ||||
| 
 | ||||
| 	ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); | ||||
| 
 | ||||
| #ifdef CONFIG_PCI_AR2315 | ||||
| 	if (ath25_soc == ATH25_SOC_AR2315) { | ||||
| 		/* Reset PCI DMA logic */ | ||||
| 		ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA); | ||||
| 		msleep(20); | ||||
| 		ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0); | ||||
| 		msleep(20); | ||||
| 
 | ||||
| 		/* Configure endians */ | ||||
| 		ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB | | ||||
| 				    AR2315_CONFIG_PCIAHB_BRIDGE); | ||||
| 
 | ||||
| 		/* Configure as PCI host with DMA */ | ||||
| 		ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM | | ||||
| 				  (AR2315_PCICLK_IN_FREQ_DIV_6 << | ||||
| 				   AR2315_PCICLK_DIV_S)); | ||||
| 		ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI); | ||||
| 		ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | | ||||
| 				    AR2315_IF_MASK, AR2315_IF_PCI | | ||||
| 				    AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR | | ||||
| 				    (AR2315_IF_PCI_CLK_OUTPUT_CLK << | ||||
| 				     AR2315_IF_PCI_CLK_SHIFT)); | ||||
| 
 | ||||
| 		platform_device_register_simple("ar2315-pci", -1, | ||||
| 						ar2315_pci_res, | ||||
| 						ARRAY_SIZE(ar2315_pci_res)); | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										22
									
								
								arch/mips/ath25/ar2315.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								arch/mips/ath25/ar2315.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #ifndef __AR2315_H | ||||
| #define __AR2315_H | ||||
| 
 | ||||
| #ifdef CONFIG_SOC_AR2315 | ||||
| 
 | ||||
| void ar2315_arch_init_irq(void); | ||||
| void ar2315_init_devices(void); | ||||
| void ar2315_plat_time_init(void); | ||||
| void ar2315_plat_mem_setup(void); | ||||
| void ar2315_arch_init(void); | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| static inline void ar2315_arch_init_irq(void) {} | ||||
| static inline void ar2315_init_devices(void) {} | ||||
| static inline void ar2315_plat_time_init(void) {} | ||||
| static inline void ar2315_plat_mem_setup(void) {} | ||||
| static inline void ar2315_arch_init(void) {} | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #endif	/* __AR2315_H */ | ||||
							
								
								
									
										410
									
								
								arch/mips/ath25/ar2315_regs.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								arch/mips/ath25/ar2315_regs.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,410 @@ | |||
| /*
 | ||||
|  * Register definitions for AR2315+ | ||||
|  * | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved. | ||||
|  * Copyright (C) 2006 FON Technology, SL. | ||||
|  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||||
|  * Copyright (C) 2006-2008 Felix Fietkau <nbd@openwrt.org> | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_MACH_ATH25_AR2315_REGS_H | ||||
| #define __ASM_MACH_ATH25_AR2315_REGS_H | ||||
| 
 | ||||
| /*
 | ||||
|  * IRQs | ||||
|  */ | ||||
| #define AR2315_IRQ_MISC		(MIPS_CPU_IRQ_BASE + 2)	/* C0_CAUSE: 0x0400 */ | ||||
| #define AR2315_IRQ_WLAN0	(MIPS_CPU_IRQ_BASE + 3)	/* C0_CAUSE: 0x0800 */ | ||||
| #define AR2315_IRQ_ENET0	(MIPS_CPU_IRQ_BASE + 4)	/* C0_CAUSE: 0x1000 */ | ||||
| #define AR2315_IRQ_LCBUS_PCI	(MIPS_CPU_IRQ_BASE + 5)	/* C0_CAUSE: 0x2000 */ | ||||
| #define AR2315_IRQ_WLAN0_POLL	(MIPS_CPU_IRQ_BASE + 6)	/* C0_CAUSE: 0x4000 */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Miscellaneous interrupts, which share IP2. | ||||
|  */ | ||||
| #define AR2315_MISC_IRQ_UART0		0 | ||||
| #define AR2315_MISC_IRQ_I2C_RSVD	1 | ||||
| #define AR2315_MISC_IRQ_SPI		2 | ||||
| #define AR2315_MISC_IRQ_AHB		3 | ||||
| #define AR2315_MISC_IRQ_APB		4 | ||||
| #define AR2315_MISC_IRQ_TIMER		5 | ||||
| #define AR2315_MISC_IRQ_GPIO		6 | ||||
| #define AR2315_MISC_IRQ_WATCHDOG	7 | ||||
| #define AR2315_MISC_IRQ_IR_RSVD		8 | ||||
| #define AR2315_MISC_IRQ_COUNT		9 | ||||
| 
 | ||||
| /*
 | ||||
|  * Address map | ||||
|  */ | ||||
| #define AR2315_SPI_READ_BASE	0x08000000	/* SPI flash */ | ||||
| #define AR2315_SPI_READ_SIZE	0x01000000 | ||||
| #define AR2315_WLAN0_BASE	0x10000000	/* Wireless MMR */ | ||||
| #define AR2315_PCI_BASE		0x10100000	/* PCI MMR */ | ||||
| #define AR2315_PCI_SIZE		0x00001000 | ||||
| #define AR2315_SDRAMCTL_BASE	0x10300000	/* SDRAM MMR */ | ||||
| #define AR2315_SDRAMCTL_SIZE	0x00000020 | ||||
| #define AR2315_LOCAL_BASE	0x10400000	/* Local bus MMR */ | ||||
| #define AR2315_ENET0_BASE	0x10500000	/* Ethernet MMR */ | ||||
| #define AR2315_RST_BASE		0x11000000	/* Reset control MMR */ | ||||
| #define AR2315_RST_SIZE		0x00000100 | ||||
| #define AR2315_UART0_BASE	0x11100000	/* UART MMR */ | ||||
| #define AR2315_SPI_MMR_BASE	0x11300000	/* SPI flash MMR */ | ||||
| #define AR2315_SPI_MMR_SIZE	0x00000010 | ||||
| #define AR2315_PCI_EXT_BASE	0x80000000	/* PCI external */ | ||||
| #define AR2315_PCI_EXT_SIZE	0x40000000 | ||||
| 
 | ||||
| /*
 | ||||
|  * Configuration registers | ||||
|  */ | ||||
| 
 | ||||
| /* Cold reset register */ | ||||
| #define AR2315_COLD_RESET		0x0000 | ||||
| 
 | ||||
| #define AR2315_RESET_COLD_AHB		0x00000001 | ||||
| #define AR2315_RESET_COLD_APB		0x00000002 | ||||
| #define AR2315_RESET_COLD_CPU		0x00000004 | ||||
| #define AR2315_RESET_COLD_CPUWARM	0x00000008 | ||||
| #define AR2315_RESET_SYSTEM		(RESET_COLD_CPU |\ | ||||
| 					 RESET_COLD_APB |\ | ||||
| 					 RESET_COLD_AHB)  /* full system */ | ||||
| #define AR2317_RESET_SYSTEM		0x00000010 | ||||
| 
 | ||||
| /* Reset register */ | ||||
| #define AR2315_RESET			0x0004 | ||||
| 
 | ||||
| #define AR2315_RESET_WARM_WLAN0_MAC	0x00000001  /* warm reset WLAN0 MAC */ | ||||
| #define AR2315_RESET_WARM_WLAN0_BB	0x00000002  /* warm reset WLAN0 BB */ | ||||
| #define AR2315_RESET_MPEGTS_RSVD	0x00000004  /* warm reset MPEG-TS */ | ||||
| #define AR2315_RESET_PCIDMA		0x00000008  /* warm reset PCI ahb/dma */ | ||||
| #define AR2315_RESET_MEMCTL		0x00000010  /* warm reset mem control */ | ||||
| #define AR2315_RESET_LOCAL		0x00000020  /* warm reset local bus */ | ||||
| #define AR2315_RESET_I2C_RSVD		0x00000040  /* warm reset I2C bus */ | ||||
| #define AR2315_RESET_SPI		0x00000080  /* warm reset SPI iface */ | ||||
| #define AR2315_RESET_UART0		0x00000100  /* warm reset UART0 */ | ||||
| #define AR2315_RESET_IR_RSVD		0x00000200  /* warm reset IR iface */ | ||||
| #define AR2315_RESET_EPHY0		0x00000400  /* cold reset ENET0 phy */ | ||||
| #define AR2315_RESET_ENET0		0x00000800  /* cold reset ENET0 MAC */ | ||||
| 
 | ||||
| /* AHB master arbitration control */ | ||||
| #define AR2315_AHB_ARB_CTL		0x0008 | ||||
| 
 | ||||
| #define AR2315_ARB_CPU			0x00000001  /* CPU, default */ | ||||
| #define AR2315_ARB_WLAN			0x00000002  /* WLAN */ | ||||
| #define AR2315_ARB_MPEGTS_RSVD		0x00000004  /* MPEG-TS */ | ||||
| #define AR2315_ARB_LOCAL		0x00000008  /* Local bus */ | ||||
| #define AR2315_ARB_PCI			0x00000010  /* PCI bus */ | ||||
| #define AR2315_ARB_ETHERNET		0x00000020  /* Ethernet */ | ||||
| #define AR2315_ARB_RETRY		0x00000100  /* Retry policy (debug) */ | ||||
| 
 | ||||
| /* Config Register */ | ||||
| #define AR2315_ENDIAN_CTL		0x000c | ||||
| 
 | ||||
| #define AR2315_CONFIG_AHB		0x00000001  /* EC-AHB bridge endian */ | ||||
| #define AR2315_CONFIG_WLAN		0x00000002  /* WLAN byteswap */ | ||||
| #define AR2315_CONFIG_MPEGTS_RSVD	0x00000004  /* MPEG-TS byteswap */ | ||||
| #define AR2315_CONFIG_PCI		0x00000008  /* PCI byteswap */ | ||||
| #define AR2315_CONFIG_MEMCTL		0x00000010  /* Mem controller endian */ | ||||
| #define AR2315_CONFIG_LOCAL		0x00000020  /* Local bus byteswap */ | ||||
| #define AR2315_CONFIG_ETHERNET		0x00000040  /* Ethernet byteswap */ | ||||
| #define AR2315_CONFIG_MERGE		0x00000200  /* CPU write buffer merge */ | ||||
| #define AR2315_CONFIG_CPU		0x00000400  /* CPU big endian */ | ||||
| #define AR2315_CONFIG_BIG		0x00000400 | ||||
| #define AR2315_CONFIG_PCIAHB		0x00000800 | ||||
| #define AR2315_CONFIG_PCIAHB_BRIDGE	0x00001000 | ||||
| #define AR2315_CONFIG_SPI		0x00008000  /* SPI byteswap */ | ||||
| #define AR2315_CONFIG_CPU_DRAM		0x00010000 | ||||
| #define AR2315_CONFIG_CPU_PCI		0x00020000 | ||||
| #define AR2315_CONFIG_CPU_MMR		0x00040000 | ||||
| 
 | ||||
| /* NMI control */ | ||||
| #define AR2315_NMI_CTL			0x0010 | ||||
| 
 | ||||
| #define AR2315_NMI_EN			1 | ||||
| 
 | ||||
| /* Revision Register - Initial value is 0x3010 (WMAC 3.0, AR231X 1.0). */ | ||||
| #define AR2315_SREV			0x0014 | ||||
| 
 | ||||
| #define AR2315_REV_MAJ			0x000000f0 | ||||
| #define AR2315_REV_MAJ_S		4 | ||||
| #define AR2315_REV_MIN			0x0000000f | ||||
| #define AR2315_REV_MIN_S		0 | ||||
| #define AR2315_REV_CHIP			(AR2315_REV_MAJ | AR2315_REV_MIN) | ||||
| 
 | ||||
| /* Interface Enable */ | ||||
| #define AR2315_IF_CTL			0x0018 | ||||
| 
 | ||||
| #define AR2315_IF_MASK			0x00000007 | ||||
| #define AR2315_IF_DISABLED		0		/* Disable all */ | ||||
| #define AR2315_IF_PCI			1		/* PCI */ | ||||
| #define AR2315_IF_TS_LOCAL		2		/* Local bus */ | ||||
| #define AR2315_IF_ALL			3		/* Emulation only */ | ||||
| #define AR2315_IF_LOCAL_HOST		0x00000008 | ||||
| #define AR2315_IF_PCI_HOST		0x00000010 | ||||
| #define AR2315_IF_PCI_INTR		0x00000020 | ||||
| #define AR2315_IF_PCI_CLK_MASK		0x00030000 | ||||
| #define AR2315_IF_PCI_CLK_INPUT		0 | ||||
| #define AR2315_IF_PCI_CLK_OUTPUT_LOW	1 | ||||
| #define AR2315_IF_PCI_CLK_OUTPUT_CLK	2 | ||||
| #define AR2315_IF_PCI_CLK_OUTPUT_HIGH	3 | ||||
| #define AR2315_IF_PCI_CLK_SHIFT		16 | ||||
| 
 | ||||
| /* APB Interrupt control */ | ||||
| #define AR2315_ISR			0x0020 | ||||
| #define AR2315_IMR			0x0024 | ||||
| #define AR2315_GISR			0x0028 | ||||
| 
 | ||||
| #define AR2315_ISR_UART0	0x00000001	/* high speed UART */ | ||||
| #define AR2315_ISR_I2C_RSVD	0x00000002	/* I2C bus */ | ||||
| #define AR2315_ISR_SPI		0x00000004	/* SPI bus */ | ||||
| #define AR2315_ISR_AHB		0x00000008	/* AHB error */ | ||||
| #define AR2315_ISR_APB		0x00000010	/* APB error */ | ||||
| #define AR2315_ISR_TIMER	0x00000020	/* Timer */ | ||||
| #define AR2315_ISR_GPIO		0x00000040	/* GPIO */ | ||||
| #define AR2315_ISR_WD		0x00000080	/* Watchdog */ | ||||
| #define AR2315_ISR_IR_RSVD	0x00000100	/* IR */ | ||||
| 
 | ||||
| #define AR2315_GISR_MISC	0x00000001	/* Misc */ | ||||
| #define AR2315_GISR_WLAN0	0x00000002	/* WLAN0 */ | ||||
| #define AR2315_GISR_MPEGTS_RSVD	0x00000004	/* MPEG-TS */ | ||||
| #define AR2315_GISR_LOCALPCI	0x00000008	/* Local/PCI bus */ | ||||
| #define AR2315_GISR_WMACPOLL	0x00000010 | ||||
| #define AR2315_GISR_TIMER	0x00000020 | ||||
| #define AR2315_GISR_ETHERNET	0x00000040	/* Ethernet */ | ||||
| 
 | ||||
| /* Generic timer */ | ||||
| #define AR2315_TIMER			0x0030 | ||||
| #define AR2315_RELOAD			0x0034 | ||||
| 
 | ||||
| /* Watchdog timer */ | ||||
| #define AR2315_WDT_TIMER		0x0038 | ||||
| #define AR2315_WDT_CTRL			0x003c | ||||
| 
 | ||||
| #define AR2315_WDT_CTRL_IGNORE	0x00000000	/* ignore expiration */ | ||||
| #define AR2315_WDT_CTRL_NMI	0x00000001	/* NMI on watchdog */ | ||||
| #define AR2315_WDT_CTRL_RESET	0x00000002	/* reset on watchdog */ | ||||
| 
 | ||||
| /* CPU Performance Counters */ | ||||
| #define AR2315_PERFCNT0			0x0048 | ||||
| #define AR2315_PERFCNT1			0x004c | ||||
| 
 | ||||
| #define AR2315_PERF0_DATAHIT	0x00000001  /* Count Data Cache Hits */ | ||||
| #define AR2315_PERF0_DATAMISS	0x00000002  /* Count Data Cache Misses */ | ||||
| #define AR2315_PERF0_INSTHIT	0x00000004  /* Count Instruction Cache Hits */ | ||||
| #define AR2315_PERF0_INSTMISS	0x00000008  /* Count Instruction Cache Misses */ | ||||
| #define AR2315_PERF0_ACTIVE	0x00000010  /* Count Active Processor Cycles */ | ||||
| #define AR2315_PERF0_WBHIT	0x00000020  /* Count CPU Write Buffer Hits */ | ||||
| #define AR2315_PERF0_WBMISS	0x00000040  /* Count CPU Write Buffer Misses */ | ||||
| 
 | ||||
| #define AR2315_PERF1_EB_ARDY	0x00000001  /* Count EB_ARdy signal */ | ||||
| #define AR2315_PERF1_EB_AVALID	0x00000002  /* Count EB_AValid signal */ | ||||
| #define AR2315_PERF1_EB_WDRDY	0x00000004  /* Count EB_WDRdy signal */ | ||||
| #define AR2315_PERF1_EB_RDVAL	0x00000008  /* Count EB_RdVal signal */ | ||||
| #define AR2315_PERF1_VRADDR	0x00000010  /* Count valid read address cycles*/ | ||||
| #define AR2315_PERF1_VWADDR	0x00000020  /* Count valid write address cycl.*/ | ||||
| #define AR2315_PERF1_VWDATA	0x00000040  /* Count valid write data cycles */ | ||||
| 
 | ||||
| /* AHB Error Reporting */ | ||||
| #define AR2315_AHB_ERR0			0x0050  /* error  */ | ||||
| #define AR2315_AHB_ERR1			0x0054  /* haddr  */ | ||||
| #define AR2315_AHB_ERR2			0x0058  /* hwdata */ | ||||
| #define AR2315_AHB_ERR3			0x005c  /* hrdata */ | ||||
| #define AR2315_AHB_ERR4			0x0060  /* status */ | ||||
| 
 | ||||
| #define AR2315_AHB_ERROR_DET	1 /* AHB Error has been detected,          */ | ||||
| 				  /* write 1 to clear all bits in ERR0     */ | ||||
| #define AR2315_AHB_ERROR_OVR	2 /* AHB Error overflow has been detected  */ | ||||
| #define AR2315_AHB_ERROR_WDT	4 /* AHB Error due to wdt instead of hresp */ | ||||
| 
 | ||||
| #define AR2315_PROCERR_HMAST		0x0000000f | ||||
| #define AR2315_PROCERR_HMAST_DFLT	0 | ||||
| #define AR2315_PROCERR_HMAST_WMAC	1 | ||||
| #define AR2315_PROCERR_HMAST_ENET	2 | ||||
| #define AR2315_PROCERR_HMAST_PCIENDPT	3 | ||||
| #define AR2315_PROCERR_HMAST_LOCAL	4 | ||||
| #define AR2315_PROCERR_HMAST_CPU	5 | ||||
| #define AR2315_PROCERR_HMAST_PCITGT	6 | ||||
| #define AR2315_PROCERR_HMAST_S		0 | ||||
| #define AR2315_PROCERR_HWRITE		0x00000010 | ||||
| #define AR2315_PROCERR_HSIZE		0x00000060 | ||||
| #define AR2315_PROCERR_HSIZE_S		5 | ||||
| #define AR2315_PROCERR_HTRANS		0x00000180 | ||||
| #define AR2315_PROCERR_HTRANS_S		7 | ||||
| #define AR2315_PROCERR_HBURST		0x00000e00 | ||||
| #define AR2315_PROCERR_HBURST_S		9 | ||||
| 
 | ||||
| /* Clock Control */ | ||||
| #define AR2315_PLLC_CTL			0x0064 | ||||
| #define AR2315_PLLV_CTL			0x0068 | ||||
| #define AR2315_CPUCLK			0x006c | ||||
| #define AR2315_AMBACLK			0x0070 | ||||
| #define AR2315_SYNCCLK			0x0074 | ||||
| #define AR2315_DSL_SLEEP_CTL		0x0080 | ||||
| #define AR2315_DSL_SLEEP_DUR		0x0084 | ||||
| 
 | ||||
| /* PLLc Control fields */ | ||||
| #define AR2315_PLLC_REF_DIV_M		0x00000003 | ||||
| #define AR2315_PLLC_REF_DIV_S		0 | ||||
| #define AR2315_PLLC_FDBACK_DIV_M	0x0000007c | ||||
| #define AR2315_PLLC_FDBACK_DIV_S	2 | ||||
| #define AR2315_PLLC_ADD_FDBACK_DIV_M	0x00000080 | ||||
| #define AR2315_PLLC_ADD_FDBACK_DIV_S	7 | ||||
| #define AR2315_PLLC_CLKC_DIV_M		0x0001c000 | ||||
| #define AR2315_PLLC_CLKC_DIV_S		14 | ||||
| #define AR2315_PLLC_CLKM_DIV_M		0x00700000 | ||||
| #define AR2315_PLLC_CLKM_DIV_S		20 | ||||
| 
 | ||||
| /* CPU CLK Control fields */ | ||||
| #define AR2315_CPUCLK_CLK_SEL_M		0x00000003 | ||||
| #define AR2315_CPUCLK_CLK_SEL_S		0 | ||||
| #define AR2315_CPUCLK_CLK_DIV_M		0x0000000c | ||||
| #define AR2315_CPUCLK_CLK_DIV_S		2 | ||||
| 
 | ||||
| /* AMBA CLK Control fields */ | ||||
| #define AR2315_AMBACLK_CLK_SEL_M	0x00000003 | ||||
| #define AR2315_AMBACLK_CLK_SEL_S	0 | ||||
| #define AR2315_AMBACLK_CLK_DIV_M	0x0000000c | ||||
| #define AR2315_AMBACLK_CLK_DIV_S	2 | ||||
| 
 | ||||
| /* PCI Clock Control */ | ||||
| #define AR2315_PCICLK			0x00a4 | ||||
| 
 | ||||
| #define AR2315_PCICLK_INPUT_M		0x00000003 | ||||
| #define AR2315_PCICLK_INPUT_S		0 | ||||
| #define AR2315_PCICLK_PLLC_CLKM		0 | ||||
| #define AR2315_PCICLK_PLLC_CLKM1	1 | ||||
| #define AR2315_PCICLK_PLLC_CLKC		2 | ||||
| #define AR2315_PCICLK_REF_CLK		3 | ||||
| #define AR2315_PCICLK_DIV_M		0x0000000c | ||||
| #define AR2315_PCICLK_DIV_S		2 | ||||
| #define AR2315_PCICLK_IN_FREQ		0 | ||||
| #define AR2315_PCICLK_IN_FREQ_DIV_6	1 | ||||
| #define AR2315_PCICLK_IN_FREQ_DIV_8	2 | ||||
| #define AR2315_PCICLK_IN_FREQ_DIV_10	3 | ||||
| 
 | ||||
| /* Observation Control Register */ | ||||
| #define AR2315_OCR			0x00b0 | ||||
| 
 | ||||
| #define AR2315_OCR_GPIO0_IRIN		0x00000040 | ||||
| #define AR2315_OCR_GPIO1_IROUT		0x00000080 | ||||
| #define AR2315_OCR_GPIO3_RXCLR		0x00000200 | ||||
| 
 | ||||
| /* General Clock Control */ | ||||
| #define AR2315_MISCCLK			0x00b4 | ||||
| 
 | ||||
| #define AR2315_MISCCLK_PLLBYPASS_EN	0x00000001 | ||||
| #define AR2315_MISCCLK_PROCREFCLK	0x00000002 | ||||
| 
 | ||||
| /*
 | ||||
|  * SDRAM Controller | ||||
|  *   - No read or write buffers are included. | ||||
|  */ | ||||
| #define AR2315_MEM_CFG			0x0000 | ||||
| #define AR2315_MEM_CTRL			0x000c | ||||
| #define AR2315_MEM_REF			0x0010 | ||||
| 
 | ||||
| #define AR2315_MEM_CFG_DATA_WIDTH_M	0x00006000 | ||||
| #define AR2315_MEM_CFG_DATA_WIDTH_S	13 | ||||
| #define AR2315_MEM_CFG_COL_WIDTH_M	0x00001e00 | ||||
| #define AR2315_MEM_CFG_COL_WIDTH_S	9 | ||||
| #define AR2315_MEM_CFG_ROW_WIDTH_M	0x000001e0 | ||||
| #define AR2315_MEM_CFG_ROW_WIDTH_S	5 | ||||
| #define AR2315_MEM_CFG_BANKADDR_BITS_M	0x00000018 | ||||
| #define AR2315_MEM_CFG_BANKADDR_BITS_S	3 | ||||
| 
 | ||||
| /*
 | ||||
|  * Local Bus Interface Registers | ||||
|  */ | ||||
| #define AR2315_LB_CONFIG		0x0000 | ||||
| 
 | ||||
| #define AR2315_LBCONF_OE	0x00000001	/* =1 OE is low-true */ | ||||
| #define AR2315_LBCONF_CS0	0x00000002	/* =1 first CS is low-true */ | ||||
| #define AR2315_LBCONF_CS1	0x00000004	/* =1 2nd CS is low-true */ | ||||
| #define AR2315_LBCONF_RDY	0x00000008	/* =1 RDY is low-true */ | ||||
| #define AR2315_LBCONF_WE	0x00000010	/* =1 Write En is low-true */ | ||||
| #define AR2315_LBCONF_WAIT	0x00000020	/* =1 WAIT is low-true */ | ||||
| #define AR2315_LBCONF_ADS	0x00000040	/* =1 Adr Strobe is low-true */ | ||||
| #define AR2315_LBCONF_MOT	0x00000080	/* =0 Intel, =1 Motorola */ | ||||
| #define AR2315_LBCONF_8CS	0x00000100	/* =1 8 bits CS, 0= 16bits */ | ||||
| #define AR2315_LBCONF_8DS	0x00000200	/* =1 8 bits Data S, 0=16bits */ | ||||
| #define AR2315_LBCONF_ADS_EN	0x00000400	/* =1 Enable ADS */ | ||||
| #define AR2315_LBCONF_ADR_OE	0x00000800	/* =1 Adr cap on OE, WE or DS */ | ||||
| #define AR2315_LBCONF_ADDT_MUX	0x00001000	/* =1 Adr and Data share bus */ | ||||
| #define AR2315_LBCONF_DATA_OE	0x00002000	/* =1 Data cap on OE, WE, DS */ | ||||
| #define AR2315_LBCONF_16DATA	0x00004000	/* =1 Data is 16 bits wide */ | ||||
| #define AR2315_LBCONF_SWAPDT	0x00008000	/* =1 Byte swap data */ | ||||
| #define AR2315_LBCONF_SYNC	0x00010000	/* =1 Bus synchronous to clk */ | ||||
| #define AR2315_LBCONF_INT	0x00020000	/* =1 Intr is low true */ | ||||
| #define AR2315_LBCONF_INT_CTR0	0x00000000	/* GND high-Z, Vdd is high-Z */ | ||||
| #define AR2315_LBCONF_INT_CTR1	0x00040000	/* GND drive, Vdd is high-Z */ | ||||
| #define AR2315_LBCONF_INT_CTR2	0x00080000	/* GND high-Z, Vdd drive */ | ||||
| #define AR2315_LBCONF_INT_CTR3	0x000c0000	/* GND drive, Vdd drive */ | ||||
| #define AR2315_LBCONF_RDY_WAIT	0x00100000	/* =1 RDY is negative of WAIT */ | ||||
| #define AR2315_LBCONF_INT_PULSE	0x00200000	/* =1 Interrupt is a pulse */ | ||||
| #define AR2315_LBCONF_ENABLE	0x00400000	/* =1 Falcon respond to LB */ | ||||
| 
 | ||||
| #define AR2315_LB_CLKSEL		0x0004 | ||||
| 
 | ||||
| #define AR2315_LBCLK_EXT	0x00000001	/* use external clk for lb */ | ||||
| 
 | ||||
| #define AR2315_LB_1MS			0x0008 | ||||
| 
 | ||||
| #define AR2315_LB1MS_MASK	0x0003ffff	/* # of AHB clk cycles in 1ms */ | ||||
| 
 | ||||
| #define AR2315_LB_MISCCFG		0x000c | ||||
| 
 | ||||
| #define AR2315_LBM_TXD_EN	0x00000001	/* Enable TXD for fragments */ | ||||
| #define AR2315_LBM_RX_INTEN	0x00000002	/* Enable LB ints on RX ready */ | ||||
| #define AR2315_LBM_MBOXWR_INTEN	0x00000004	/* Enable LB ints on mbox wr */ | ||||
| #define AR2315_LBM_MBOXRD_INTEN	0x00000008	/* Enable LB ints on mbox rd */ | ||||
| #define AR2315_LMB_DESCSWAP_EN	0x00000010	/* Byte swap desc enable */ | ||||
| #define AR2315_LBM_TIMEOUT_M	0x00ffff80 | ||||
| #define AR2315_LBM_TIMEOUT_S	7 | ||||
| #define AR2315_LBM_PORTMUX	0x07000000 | ||||
| 
 | ||||
| #define AR2315_LB_RXTSOFF		0x0010 | ||||
| 
 | ||||
| #define AR2315_LB_TX_CHAIN_EN		0x0100 | ||||
| 
 | ||||
| #define AR2315_LB_TXEN_0	0x00000001 | ||||
| #define AR2315_LB_TXEN_1	0x00000002 | ||||
| #define AR2315_LB_TXEN_2	0x00000004 | ||||
| #define AR2315_LB_TXEN_3	0x00000008 | ||||
| 
 | ||||
| #define AR2315_LB_TX_CHAIN_DIS		0x0104 | ||||
| #define AR2315_LB_TX_DESC_PTR		0x0200 | ||||
| 
 | ||||
| #define AR2315_LB_RX_CHAIN_EN		0x0400 | ||||
| 
 | ||||
| #define AR2315_LB_RXEN		0x00000001 | ||||
| 
 | ||||
| #define AR2315_LB_RX_CHAIN_DIS		0x0404 | ||||
| #define AR2315_LB_RX_DESC_PTR		0x0408 | ||||
| 
 | ||||
| #define AR2315_LB_INT_STATUS		0x0500 | ||||
| 
 | ||||
| #define AR2315_LB_INT_TX_DESC		0x00000001 | ||||
| #define AR2315_LB_INT_TX_OK		0x00000002 | ||||
| #define AR2315_LB_INT_TX_ERR		0x00000004 | ||||
| #define AR2315_LB_INT_TX_EOF		0x00000008 | ||||
| #define AR2315_LB_INT_RX_DESC		0x00000010 | ||||
| #define AR2315_LB_INT_RX_OK		0x00000020 | ||||
| #define AR2315_LB_INT_RX_ERR		0x00000040 | ||||
| #define AR2315_LB_INT_RX_EOF		0x00000080 | ||||
| #define AR2315_LB_INT_TX_TRUNC		0x00000100 | ||||
| #define AR2315_LB_INT_TX_STARVE		0x00000200 | ||||
| #define AR2315_LB_INT_LB_TIMEOUT	0x00000400 | ||||
| #define AR2315_LB_INT_LB_ERR		0x00000800 | ||||
| #define AR2315_LB_INT_MBOX_WR		0x00001000 | ||||
| #define AR2315_LB_INT_MBOX_RD		0x00002000 | ||||
| 
 | ||||
| /* Bit definitions for INT MASK are the same as INT_STATUS */ | ||||
| #define AR2315_LB_INT_MASK		0x0504 | ||||
| 
 | ||||
| #define AR2315_LB_INT_EN		0x0508 | ||||
| #define AR2315_LB_MBOX			0x0600 | ||||
| 
 | ||||
| #endif /* __ASM_MACH_ATH25_AR2315_REGS_H */ | ||||
							
								
								
									
										393
									
								
								arch/mips/ath25/ar5312.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								arch/mips/ath25/ar5312.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,393 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved. | ||||
|  * Copyright (C) 2006 FON Technology, SL. | ||||
|  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||||
|  * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||||
|  * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Platform devices for Atheros AR5312 SoCs | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/init.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/irqdomain.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/mtd/physmap.h> | ||||
| #include <linux/reboot.h> | ||||
| #include <asm/bootinfo.h> | ||||
| #include <asm/reboot.h> | ||||
| #include <asm/time.h> | ||||
| 
 | ||||
| #include <ath25_platform.h> | ||||
| 
 | ||||
| #include "devices.h" | ||||
| #include "ar5312.h" | ||||
| #include "ar5312_regs.h" | ||||
| 
 | ||||
| static void __iomem *ar5312_rst_base; | ||||
| static struct irq_domain *ar5312_misc_irq_domain; | ||||
| 
 | ||||
| static inline u32 ar5312_rst_reg_read(u32 reg) | ||||
| { | ||||
| 	return __raw_readl(ar5312_rst_base + reg); | ||||
| } | ||||
| 
 | ||||
| static inline void ar5312_rst_reg_write(u32 reg, u32 val) | ||||
| { | ||||
| 	__raw_writel(val, ar5312_rst_base + reg); | ||||
| } | ||||
| 
 | ||||
| static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val) | ||||
| { | ||||
| 	u32 ret = ar5312_rst_reg_read(reg); | ||||
| 
 | ||||
| 	ret &= ~mask; | ||||
| 	ret |= val; | ||||
| 	ar5312_rst_reg_write(reg, ret); | ||||
| } | ||||
| 
 | ||||
| static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id) | ||||
| { | ||||
| 	u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1); | ||||
| 	u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */ | ||||
| 	u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1); | ||||
| 	u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR);   /* clears error */ | ||||
| 
 | ||||
| 	pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n", | ||||
| 		 proc_addr, proc1, dma_addr, dma1); | ||||
| 
 | ||||
| 	machine_restart("AHB error"); /* Catastrophic failure */ | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| static struct irqaction ar5312_ahb_err_interrupt  = { | ||||
| 	.handler = ar5312_ahb_err_handler, | ||||
| 	.name    = "ar5312-ahb-error", | ||||
| }; | ||||
| 
 | ||||
| static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc) | ||||
| { | ||||
| 	u32 pending = ar5312_rst_reg_read(AR5312_ISR) & | ||||
| 		      ar5312_rst_reg_read(AR5312_IMR); | ||||
| 	unsigned nr, misc_irq = 0; | ||||
| 
 | ||||
| 	if (pending) { | ||||
| 		struct irq_domain *domain = irq_get_handler_data(irq); | ||||
| 
 | ||||
| 		nr = __ffs(pending); | ||||
| 		misc_irq = irq_find_mapping(domain, nr); | ||||
| 	} | ||||
| 
 | ||||
| 	if (misc_irq) { | ||||
| 		generic_handle_irq(misc_irq); | ||||
| 		if (nr == AR5312_MISC_IRQ_TIMER) | ||||
| 			ar5312_rst_reg_read(AR5312_TIMER); | ||||
| 	} else { | ||||
| 		spurious_interrupt(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Enable the specified AR5312_MISC_IRQ interrupt */ | ||||
| static void ar5312_misc_irq_unmask(struct irq_data *d) | ||||
| { | ||||
| 	ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq)); | ||||
| } | ||||
| 
 | ||||
| /* Disable the specified AR5312_MISC_IRQ interrupt */ | ||||
| static void ar5312_misc_irq_mask(struct irq_data *d) | ||||
| { | ||||
| 	ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0); | ||||
| 	ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */ | ||||
| } | ||||
| 
 | ||||
| static struct irq_chip ar5312_misc_irq_chip = { | ||||
| 	.name		= "ar5312-misc", | ||||
| 	.irq_unmask	= ar5312_misc_irq_unmask, | ||||
| 	.irq_mask	= ar5312_misc_irq_mask, | ||||
| }; | ||||
| 
 | ||||
| static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq, | ||||
| 			       irq_hw_number_t hw) | ||||
| { | ||||
| 	irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct irq_domain_ops ar5312_misc_irq_domain_ops = { | ||||
| 	.map = ar5312_misc_irq_map, | ||||
| }; | ||||
| 
 | ||||
| static void ar5312_irq_dispatch(void) | ||||
| { | ||||
| 	u32 pending = read_c0_status() & read_c0_cause(); | ||||
| 
 | ||||
| 	if (pending & CAUSEF_IP2) | ||||
| 		do_IRQ(AR5312_IRQ_WLAN0); | ||||
| 	else if (pending & CAUSEF_IP5) | ||||
| 		do_IRQ(AR5312_IRQ_WLAN1); | ||||
| 	else if (pending & CAUSEF_IP6) | ||||
| 		do_IRQ(AR5312_IRQ_MISC); | ||||
| 	else if (pending & CAUSEF_IP7) | ||||
| 		do_IRQ(ATH25_IRQ_CPU_CLOCK); | ||||
| 	else | ||||
| 		spurious_interrupt(); | ||||
| } | ||||
| 
 | ||||
| void __init ar5312_arch_init_irq(void) | ||||
| { | ||||
| 	struct irq_domain *domain; | ||||
| 	unsigned irq; | ||||
| 
 | ||||
| 	ath25_irq_dispatch = ar5312_irq_dispatch; | ||||
| 
 | ||||
| 	domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT, | ||||
| 				       &ar5312_misc_irq_domain_ops, NULL); | ||||
| 	if (!domain) | ||||
| 		panic("Failed to add IRQ domain"); | ||||
| 
 | ||||
| 	irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC); | ||||
| 	setup_irq(irq, &ar5312_ahb_err_interrupt); | ||||
| 
 | ||||
| 	irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler); | ||||
| 	irq_set_handler_data(AR5312_IRQ_MISC, domain); | ||||
| 
 | ||||
| 	ar5312_misc_irq_domain = domain; | ||||
| } | ||||
| 
 | ||||
| static struct physmap_flash_data ar5312_flash_data = { | ||||
| 	.width = 2, | ||||
| }; | ||||
| 
 | ||||
| static struct resource ar5312_flash_resource = { | ||||
| 	.start = AR5312_FLASH_BASE, | ||||
| 	.end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1, | ||||
| 	.flags = IORESOURCE_MEM, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device ar5312_physmap_flash = { | ||||
| 	.name = "physmap-flash", | ||||
| 	.id = 0, | ||||
| 	.dev.platform_data = &ar5312_flash_data, | ||||
| 	.resource = &ar5312_flash_resource, | ||||
| 	.num_resources = 1, | ||||
| }; | ||||
| 
 | ||||
| static void __init ar5312_flash_init(void) | ||||
| { | ||||
| 	void __iomem *flashctl_base; | ||||
| 	u32 ctl; | ||||
| 
 | ||||
| 	flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE, | ||||
| 					AR5312_FLASHCTL_SIZE); | ||||
| 
 | ||||
| 	ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0); | ||||
| 	ctl &= AR5312_FLASHCTL_MW; | ||||
| 
 | ||||
| 	/* fixup flash width */ | ||||
| 	switch (ctl) { | ||||
| 	case AR5312_FLASHCTL_MW16: | ||||
| 		ar5312_flash_data.width = 2; | ||||
| 		break; | ||||
| 	case AR5312_FLASHCTL_MW8: | ||||
| 	default: | ||||
| 		ar5312_flash_data.width = 1; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Configure flash bank 0. | ||||
| 	 * Assume 8M window size. Flash will be aliased if it's smaller | ||||
| 	 */ | ||||
| 	ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE; | ||||
| 	ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S; | ||||
| 	ctl |= 0x07 << AR5312_FLASHCTL_WST1_S; | ||||
| 	ctl |= 0x07 << AR5312_FLASHCTL_WST2_S; | ||||
| 	__raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0); | ||||
| 
 | ||||
| 	/* Disable other flash banks */ | ||||
| 	ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1); | ||||
| 	ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); | ||||
| 	__raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1); | ||||
| 	ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2); | ||||
| 	ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); | ||||
| 	__raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2); | ||||
| 
 | ||||
| 	iounmap(flashctl_base); | ||||
| } | ||||
| 
 | ||||
| void __init ar5312_init_devices(void) | ||||
| { | ||||
| 	struct ath25_boarddata *config; | ||||
| 
 | ||||
| 	ar5312_flash_init(); | ||||
| 
 | ||||
| 	/* Locate board/radio config data */ | ||||
| 	ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE); | ||||
| 	config = ath25_board.config; | ||||
| 
 | ||||
| 	/* AR2313 has CPU minor rev. 10 */ | ||||
| 	if ((current_cpu_data.processor_id & 0xff) == 0x0a) | ||||
| 		ath25_soc = ATH25_SOC_AR2313; | ||||
| 
 | ||||
| 	/* AR2312 shares the same Silicon ID as AR5312 */ | ||||
| 	else if (config->flags & BD_ISCASPER) | ||||
| 		ath25_soc = ATH25_SOC_AR2312; | ||||
| 
 | ||||
| 	/* Everything else is probably AR5312 or compatible */ | ||||
| 	else | ||||
| 		ath25_soc = ATH25_SOC_AR5312; | ||||
| 
 | ||||
| 	platform_device_register(&ar5312_physmap_flash); | ||||
| 
 | ||||
| 	switch (ath25_soc) { | ||||
| 	case ATH25_SOC_AR5312: | ||||
| 		if (!ath25_board.radio) | ||||
| 			return; | ||||
| 
 | ||||
| 		if (!(config->flags & BD_WLAN0)) | ||||
| 			break; | ||||
| 
 | ||||
| 		ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0); | ||||
| 		break; | ||||
| 	case ATH25_SOC_AR2312: | ||||
| 	case ATH25_SOC_AR2313: | ||||
| 		if (!ath25_board.radio) | ||||
| 			return; | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (config->flags & BD_WLAN1) | ||||
| 		ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1); | ||||
| } | ||||
| 
 | ||||
| static void ar5312_restart(char *command) | ||||
| { | ||||
| 	/* reset the system */ | ||||
| 	local_irq_disable(); | ||||
| 	while (1) | ||||
| 		ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * This table is indexed by bits 5..4 of the CLOCKCTL1 register | ||||
|  * to determine the predevisor value. | ||||
|  */ | ||||
| static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; | ||||
| 
 | ||||
| static unsigned __init ar5312_cpu_frequency(void) | ||||
| { | ||||
| 	u32 scratch, devid, clock_ctl1; | ||||
| 	u32 predivide_mask, multiplier_mask, doubler_mask; | ||||
| 	unsigned predivide_shift, multiplier_shift; | ||||
| 	unsigned predivide_select, predivisor, multiplier; | ||||
| 
 | ||||
| 	/* Trust the bootrom's idea of cpu frequency. */ | ||||
| 	scratch = ar5312_rst_reg_read(AR5312_SCRATCH); | ||||
| 	if (scratch) | ||||
| 		return scratch; | ||||
| 
 | ||||
| 	devid = ar5312_rst_reg_read(AR5312_REV); | ||||
| 	devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S; | ||||
| 	if (devid == AR5312_REV_MAJ_AR2313) { | ||||
| 		predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; | ||||
| 		predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; | ||||
| 		multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; | ||||
| 		multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; | ||||
| 		doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; | ||||
| 	} else { /* AR5312 and AR2312 */ | ||||
| 		predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; | ||||
| 		predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; | ||||
| 		multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; | ||||
| 		multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; | ||||
| 		doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Clocking is derived from a fixed 40MHz input clock. | ||||
| 	 * | ||||
| 	 *  cpu_freq = input_clock * MULT (where MULT is PLL multiplier) | ||||
| 	 *  sys_freq = cpu_freq / 4	  (used for APB clock, serial, | ||||
| 	 *				   flash, Timer, Watchdog Timer) | ||||
| 	 * | ||||
| 	 *  cnt_freq = cpu_freq / 2	  (use for CPU count/compare) | ||||
| 	 * | ||||
| 	 * So, for example, with a PLL multiplier of 5, we have | ||||
| 	 * | ||||
| 	 *  cpu_freq = 200MHz | ||||
| 	 *  sys_freq = 50MHz | ||||
| 	 *  cnt_freq = 100MHz | ||||
| 	 * | ||||
| 	 * We compute the CPU frequency, based on PLL settings. | ||||
| 	 */ | ||||
| 
 | ||||
| 	clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1); | ||||
| 	predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift; | ||||
| 	predivisor = clockctl1_predivide_table[predivide_select]; | ||||
| 	multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift; | ||||
| 
 | ||||
| 	if (clock_ctl1 & doubler_mask) | ||||
| 		multiplier <<= 1; | ||||
| 
 | ||||
| 	return (40000000 / predivisor) * multiplier; | ||||
| } | ||||
| 
 | ||||
| static inline unsigned ar5312_sys_frequency(void) | ||||
| { | ||||
| 	return ar5312_cpu_frequency() / 4; | ||||
| } | ||||
| 
 | ||||
| void __init ar5312_plat_time_init(void) | ||||
| { | ||||
| 	mips_hpt_frequency = ar5312_cpu_frequency() / 2; | ||||
| } | ||||
| 
 | ||||
| void __init ar5312_plat_mem_setup(void) | ||||
| { | ||||
| 	void __iomem *sdram_base; | ||||
| 	u32 memsize, memcfg, bank0_ac, bank1_ac; | ||||
| 	u32 devid; | ||||
| 
 | ||||
| 	/* Detect memory size */ | ||||
| 	sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE, | ||||
| 				     AR5312_SDRAMCTL_SIZE); | ||||
| 	memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1); | ||||
| 	bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0); | ||||
| 	bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1); | ||||
| 	memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) + | ||||
| 		  (bank1_ac ? (1 << (bank1_ac + 1)) : 0); | ||||
| 	memsize <<= 20; | ||||
| 	add_memory_region(0, memsize, BOOT_MEM_RAM); | ||||
| 	iounmap(sdram_base); | ||||
| 
 | ||||
| 	ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE); | ||||
| 
 | ||||
| 	devid = ar5312_rst_reg_read(AR5312_REV); | ||||
| 	devid >>= AR5312_REV_WMAC_MIN_S; | ||||
| 	devid &= AR5312_REV_CHIP; | ||||
| 	ath25_board.devid = (u16)devid; | ||||
| 
 | ||||
| 	/* Clear any lingering AHB errors */ | ||||
| 	ar5312_rst_reg_read(AR5312_PROCADDR); | ||||
| 	ar5312_rst_reg_read(AR5312_DMAADDR); | ||||
| 	ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE); | ||||
| 
 | ||||
| 	_machine_restart = ar5312_restart; | ||||
| } | ||||
| 
 | ||||
| void __init ar5312_arch_init(void) | ||||
| { | ||||
| 	unsigned irq = irq_create_mapping(ar5312_misc_irq_domain, | ||||
| 					  AR5312_MISC_IRQ_UART0); | ||||
| 
 | ||||
| 	ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency()); | ||||
| } | ||||
							
								
								
									
										22
									
								
								arch/mips/ath25/ar5312.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								arch/mips/ath25/ar5312.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| #ifndef __AR5312_H | ||||
| #define __AR5312_H | ||||
| 
 | ||||
| #ifdef CONFIG_SOC_AR5312 | ||||
| 
 | ||||
| void ar5312_arch_init_irq(void); | ||||
| void ar5312_init_devices(void); | ||||
| void ar5312_plat_time_init(void); | ||||
| void ar5312_plat_mem_setup(void); | ||||
| void ar5312_arch_init(void); | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| static inline void ar5312_arch_init_irq(void) {} | ||||
| static inline void ar5312_init_devices(void) {} | ||||
| static inline void ar5312_plat_time_init(void) {} | ||||
| static inline void ar5312_plat_mem_setup(void) {} | ||||
| static inline void ar5312_arch_init(void) {} | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #endif	/* __AR5312_H */ | ||||
							
								
								
									
										224
									
								
								arch/mips/ath25/ar5312_regs.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								arch/mips/ath25/ar5312_regs.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,224 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved. | ||||
|  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||||
|  * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_MACH_ATH25_AR5312_REGS_H | ||||
| #define __ASM_MACH_ATH25_AR5312_REGS_H | ||||
| 
 | ||||
| /*
 | ||||
|  * IRQs | ||||
|  */ | ||||
| #define AR5312_IRQ_WLAN0	(MIPS_CPU_IRQ_BASE + 2)	/* C0_CAUSE: 0x0400 */ | ||||
| #define AR5312_IRQ_ENET0	(MIPS_CPU_IRQ_BASE + 3)	/* C0_CAUSE: 0x0800 */ | ||||
| #define AR5312_IRQ_ENET1	(MIPS_CPU_IRQ_BASE + 4)	/* C0_CAUSE: 0x1000 */ | ||||
| #define AR5312_IRQ_WLAN1	(MIPS_CPU_IRQ_BASE + 5)	/* C0_CAUSE: 0x2000 */ | ||||
| #define AR5312_IRQ_MISC		(MIPS_CPU_IRQ_BASE + 6)	/* C0_CAUSE: 0x4000 */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Miscellaneous interrupts, which share IP6. | ||||
|  */ | ||||
| #define AR5312_MISC_IRQ_TIMER		0 | ||||
| #define AR5312_MISC_IRQ_AHB_PROC	1 | ||||
| #define AR5312_MISC_IRQ_AHB_DMA		2 | ||||
| #define AR5312_MISC_IRQ_GPIO		3 | ||||
| #define AR5312_MISC_IRQ_UART0		4 | ||||
| #define AR5312_MISC_IRQ_UART0_DMA	5 | ||||
| #define AR5312_MISC_IRQ_WATCHDOG	6 | ||||
| #define AR5312_MISC_IRQ_LOCAL		7 | ||||
| #define AR5312_MISC_IRQ_SPI		8 | ||||
| #define AR5312_MISC_IRQ_COUNT		9 | ||||
| 
 | ||||
| /*
 | ||||
|  * Address Map | ||||
|  * | ||||
|  * The AR5312 supports 2 enet MACS, even though many reference boards only | ||||
|  * actually use 1 of them (i.e. Only MAC 0 is actually connected to an enet | ||||
|  * PHY or PHY switch. The AR2312 supports 1 enet MAC. | ||||
|  */ | ||||
| #define AR5312_WLAN0_BASE		0x18000000 | ||||
| #define AR5312_ENET0_BASE		0x18100000 | ||||
| #define AR5312_ENET1_BASE		0x18200000 | ||||
| #define AR5312_SDRAMCTL_BASE		0x18300000 | ||||
| #define AR5312_SDRAMCTL_SIZE		0x00000010 | ||||
| #define AR5312_FLASHCTL_BASE		0x18400000 | ||||
| #define AR5312_FLASHCTL_SIZE		0x00000010 | ||||
| #define AR5312_WLAN1_BASE		0x18500000 | ||||
| #define AR5312_UART0_BASE		0x1c000000	/* UART MMR */ | ||||
| #define AR5312_GPIO_BASE		0x1c002000 | ||||
| #define AR5312_GPIO_SIZE		0x00000010 | ||||
| #define AR5312_RST_BASE			0x1c003000 | ||||
| #define AR5312_RST_SIZE			0x00000100 | ||||
| #define AR5312_FLASH_BASE		0x1e000000 | ||||
| #define AR5312_FLASH_SIZE		0x00800000 | ||||
| 
 | ||||
| /*
 | ||||
|  * Need these defines to determine true number of ethernet MACs | ||||
|  */ | ||||
| #define AR5312_AR5312_REV2	0x0052		/* AR5312 WMAC (AP31) */ | ||||
| #define AR5312_AR5312_REV7	0x0057		/* AR5312 WMAC (AP30-040) */ | ||||
| #define AR5312_AR2313_REV8	0x0058		/* AR2313 WMAC (AP43-030) */ | ||||
| 
 | ||||
| /* Reset/Timer Block Address Map */ | ||||
| #define AR5312_TIMER		0x0000 /* countdown timer */ | ||||
| #define AR5312_RELOAD		0x0004 /* timer reload value */ | ||||
| #define AR5312_WDT_CTRL		0x0008 /* watchdog cntrl */ | ||||
| #define AR5312_WDT_TIMER	0x000c /* watchdog timer */ | ||||
| #define AR5312_ISR		0x0010 /* Intr Status Reg */ | ||||
| #define AR5312_IMR		0x0014 /* Intr Mask Reg */ | ||||
| #define AR5312_RESET		0x0020 | ||||
| #define AR5312_CLOCKCTL1	0x0064 | ||||
| #define AR5312_SCRATCH		0x006c | ||||
| #define AR5312_PROCADDR		0x0070 | ||||
| #define AR5312_PROC1		0x0074 | ||||
| #define AR5312_DMAADDR		0x0078 | ||||
| #define AR5312_DMA1		0x007c | ||||
| #define AR5312_ENABLE		0x0080 /* interface enb */ | ||||
| #define AR5312_REV		0x0090 /* revision */ | ||||
| 
 | ||||
| /* AR5312_WDT_CTRL register bit field definitions */ | ||||
| #define AR5312_WDT_CTRL_IGNORE	0x00000000	/* ignore expiration */ | ||||
| #define AR5312_WDT_CTRL_NMI	0x00000001 | ||||
| #define AR5312_WDT_CTRL_RESET	0x00000002 | ||||
| 
 | ||||
| /* AR5312_ISR register bit field definitions */ | ||||
| #define AR5312_ISR_TIMER	0x00000001 | ||||
| #define AR5312_ISR_AHBPROC	0x00000002 | ||||
| #define AR5312_ISR_AHBDMA	0x00000004 | ||||
| #define AR5312_ISR_GPIO		0x00000008 | ||||
| #define AR5312_ISR_UART0	0x00000010 | ||||
| #define AR5312_ISR_UART0DMA	0x00000020 | ||||
| #define AR5312_ISR_WD		0x00000040 | ||||
| #define AR5312_ISR_LOCAL	0x00000080 | ||||
| 
 | ||||
| /* AR5312_RESET register bit field definitions */ | ||||
| #define AR5312_RESET_SYSTEM		0x00000001  /* cold reset full system */ | ||||
| #define AR5312_RESET_PROC		0x00000002  /* cold reset MIPS core */ | ||||
| #define AR5312_RESET_WLAN0		0x00000004  /* cold reset WLAN MAC/BB */ | ||||
| #define AR5312_RESET_EPHY0		0x00000008  /* cold reset ENET0 phy */ | ||||
| #define AR5312_RESET_EPHY1		0x00000010  /* cold reset ENET1 phy */ | ||||
| #define AR5312_RESET_ENET0		0x00000020  /* cold reset ENET0 MAC */ | ||||
| #define AR5312_RESET_ENET1		0x00000040  /* cold reset ENET1 MAC */ | ||||
| #define AR5312_RESET_UART0		0x00000100  /* cold reset UART0 */ | ||||
| #define AR5312_RESET_WLAN1		0x00000200  /* cold reset WLAN MAC/BB */ | ||||
| #define AR5312_RESET_APB		0x00000400  /* cold reset APB ar5312 */ | ||||
| #define AR5312_RESET_WARM_PROC		0x00001000  /* warm reset MIPS core */ | ||||
| #define AR5312_RESET_WARM_WLAN0_MAC	0x00002000  /* warm reset WLAN0 MAC */ | ||||
| #define AR5312_RESET_WARM_WLAN0_BB	0x00004000  /* warm reset WLAN0 BB */ | ||||
| #define AR5312_RESET_NMI		0x00010000  /* send an NMI to the CPU */ | ||||
| #define AR5312_RESET_WARM_WLAN1_MAC	0x00020000  /* warm reset WLAN1 MAC */ | ||||
| #define AR5312_RESET_WARM_WLAN1_BB	0x00040000  /* warm reset WLAN1 BB */ | ||||
| #define AR5312_RESET_LOCAL_BUS		0x00080000  /* reset local bus */ | ||||
| #define AR5312_RESET_WDOG		0x00100000  /* last reset was a wdt */ | ||||
| 
 | ||||
| #define AR5312_RESET_WMAC0_BITS		(AR5312_RESET_WLAN0 |\ | ||||
| 					 AR5312_RESET_WARM_WLAN0_MAC |\ | ||||
| 					 AR5312_RESET_WARM_WLAN0_BB) | ||||
| 
 | ||||
| #define AR5312_RESET_WMAC1_BITS		(AR5312_RESET_WLAN1 |\ | ||||
| 					 AR5312_RESET_WARM_WLAN1_MAC |\ | ||||
| 					 AR5312_RESET_WARM_WLAN1_BB) | ||||
| 
 | ||||
| /* AR5312_CLOCKCTL1 register bit field definitions */ | ||||
| #define AR5312_CLOCKCTL1_PREDIVIDE_MASK		0x00000030 | ||||
| #define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT	4 | ||||
| #define AR5312_CLOCKCTL1_MULTIPLIER_MASK	0x00001f00 | ||||
| #define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT	8 | ||||
| #define AR5312_CLOCKCTL1_DOUBLER_MASK		0x00010000 | ||||
| 
 | ||||
| /* Valid for AR5312 and AR2312 */ | ||||
| #define AR5312_CLOCKCTL1_PREDIVIDE_MASK		0x00000030 | ||||
| #define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT	4 | ||||
| #define AR5312_CLOCKCTL1_MULTIPLIER_MASK	0x00001f00 | ||||
| #define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT	8 | ||||
| #define AR5312_CLOCKCTL1_DOUBLER_MASK		0x00010000 | ||||
| 
 | ||||
| /* Valid for AR2313 */ | ||||
| #define AR2313_CLOCKCTL1_PREDIVIDE_MASK		0x00003000 | ||||
| #define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT	12 | ||||
| #define AR2313_CLOCKCTL1_MULTIPLIER_MASK	0x001f0000 | ||||
| #define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT	16 | ||||
| #define AR2313_CLOCKCTL1_DOUBLER_MASK		0x00000000 | ||||
| 
 | ||||
| /* AR5312_ENABLE register bit field definitions */ | ||||
| #define AR5312_ENABLE_WLAN0			0x00000001 | ||||
| #define AR5312_ENABLE_ENET0			0x00000002 | ||||
| #define AR5312_ENABLE_ENET1			0x00000004 | ||||
| #define AR5312_ENABLE_UART_AND_WLAN1_PIO	0x00000008/* UART & WLAN1 PIO */ | ||||
| #define AR5312_ENABLE_WLAN1_DMA			0x00000010/* WLAN1 DMAs */ | ||||
| #define AR5312_ENABLE_WLAN1		(AR5312_ENABLE_UART_AND_WLAN1_PIO |\ | ||||
| 					 AR5312_ENABLE_WLAN1_DMA) | ||||
| 
 | ||||
| /* AR5312_REV register bit field definitions */ | ||||
| #define AR5312_REV_WMAC_MAJ	0x0000f000 | ||||
| #define AR5312_REV_WMAC_MAJ_S	12 | ||||
| #define AR5312_REV_WMAC_MIN	0x00000f00 | ||||
| #define AR5312_REV_WMAC_MIN_S	8 | ||||
| #define AR5312_REV_MAJ		0x000000f0 | ||||
| #define AR5312_REV_MAJ_S	4 | ||||
| #define AR5312_REV_MIN		0x0000000f | ||||
| #define AR5312_REV_MIN_S	0 | ||||
| #define AR5312_REV_CHIP		(AR5312_REV_MAJ|AR5312_REV_MIN) | ||||
| 
 | ||||
| /* Major revision numbers, bits 7..4 of Revision ID register */ | ||||
| #define AR5312_REV_MAJ_AR5312		0x4 | ||||
| #define AR5312_REV_MAJ_AR2313		0x5 | ||||
| 
 | ||||
| /* Minor revision numbers, bits 3..0 of Revision ID register */ | ||||
| #define AR5312_REV_MIN_DUAL		0x0	/* Dual WLAN version */ | ||||
| #define AR5312_REV_MIN_SINGLE		0x1	/* Single WLAN version */ | ||||
| 
 | ||||
| /*
 | ||||
|  * ARM Flash Controller -- 3 flash banks with either x8 or x16 devices | ||||
|  */ | ||||
| #define AR5312_FLASHCTL0	0x0000 | ||||
| #define AR5312_FLASHCTL1	0x0004 | ||||
| #define AR5312_FLASHCTL2	0x0008 | ||||
| 
 | ||||
| /* AR5312_FLASHCTL register bit field definitions */ | ||||
| #define AR5312_FLASHCTL_IDCY	0x0000000f	/* Idle cycle turnaround time */ | ||||
| #define AR5312_FLASHCTL_IDCY_S	0 | ||||
| #define AR5312_FLASHCTL_WST1	0x000003e0	/* Wait state 1 */ | ||||
| #define AR5312_FLASHCTL_WST1_S	5 | ||||
| #define AR5312_FLASHCTL_RBLE	0x00000400	/* Read byte lane enable */ | ||||
| #define AR5312_FLASHCTL_WST2	0x0000f800	/* Wait state 2 */ | ||||
| #define AR5312_FLASHCTL_WST2_S	11 | ||||
| #define AR5312_FLASHCTL_AC	0x00070000	/* Flash addr check (added) */ | ||||
| #define AR5312_FLASHCTL_AC_S	16 | ||||
| #define AR5312_FLASHCTL_AC_128K	0x00000000 | ||||
| #define AR5312_FLASHCTL_AC_256K	0x00010000 | ||||
| #define AR5312_FLASHCTL_AC_512K	0x00020000 | ||||
| #define AR5312_FLASHCTL_AC_1M	0x00030000 | ||||
| #define AR5312_FLASHCTL_AC_2M	0x00040000 | ||||
| #define AR5312_FLASHCTL_AC_4M	0x00050000 | ||||
| #define AR5312_FLASHCTL_AC_8M	0x00060000 | ||||
| #define AR5312_FLASHCTL_AC_RES	0x00070000	/* 16MB is not supported */ | ||||
| #define AR5312_FLASHCTL_E	0x00080000	/* Flash bank enable (added) */ | ||||
| #define AR5312_FLASHCTL_BUSERR	0x01000000	/* Bus transfer error flag */ | ||||
| #define AR5312_FLASHCTL_WPERR	0x02000000	/* Write protect error flag */ | ||||
| #define AR5312_FLASHCTL_WP	0x04000000	/* Write protect */ | ||||
| #define AR5312_FLASHCTL_BM	0x08000000	/* Burst mode */ | ||||
| #define AR5312_FLASHCTL_MW	0x30000000	/* Mem width */ | ||||
| #define AR5312_FLASHCTL_MW8	0x00000000	/* Mem width x8 */ | ||||
| #define AR5312_FLASHCTL_MW16	0x10000000	/* Mem width x16 */ | ||||
| #define AR5312_FLASHCTL_MW32	0x20000000	/* Mem width x32 (not supp) */ | ||||
| #define AR5312_FLASHCTL_ATNR	0x00000000	/* Access == no retry */ | ||||
| #define AR5312_FLASHCTL_ATR	0x80000000	/* Access == retry every */ | ||||
| #define AR5312_FLASHCTL_ATR4	0xc0000000	/* Access == retry every 4 */ | ||||
| 
 | ||||
| /*
 | ||||
|  * ARM SDRAM Controller -- just enough to determine memory size | ||||
|  */ | ||||
| #define AR5312_MEM_CFG1		0x0004 | ||||
| 
 | ||||
| #define AR5312_MEM_CFG1_AC0_M	0x00000700	/* bank 0: SDRAM addr check */ | ||||
| #define AR5312_MEM_CFG1_AC0_S	8 | ||||
| #define AR5312_MEM_CFG1_AC1_M	0x00007000	/* bank 1: SDRAM addr check */ | ||||
| #define AR5312_MEM_CFG1_AC1_S	12 | ||||
| 
 | ||||
| #endif	/* __ASM_MACH_ATH25_AR5312_REGS_H */ | ||||
							
								
								
									
										234
									
								
								arch/mips/ath25/board.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								arch/mips/ath25/board.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,234 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved. | ||||
|  * Copyright (C) 2006 FON Technology, SL. | ||||
|  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||||
|  * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/init.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <asm/irq_cpu.h> | ||||
| #include <asm/reboot.h> | ||||
| #include <asm/bootinfo.h> | ||||
| #include <asm/time.h> | ||||
| 
 | ||||
| #include <ath25_platform.h> | ||||
| #include "devices.h" | ||||
| #include "ar5312.h" | ||||
| #include "ar2315.h" | ||||
| 
 | ||||
| void (*ath25_irq_dispatch)(void); | ||||
| 
 | ||||
| static inline bool check_radio_magic(const void __iomem *addr) | ||||
| { | ||||
| 	addr += 0x7a; /* offset for flash magic */ | ||||
| 	return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5); | ||||
| } | ||||
| 
 | ||||
| static inline bool check_notempty(const void __iomem *addr) | ||||
| { | ||||
| 	return __raw_readl(addr) != 0xffffffff; | ||||
| } | ||||
| 
 | ||||
| static inline bool check_board_data(const void __iomem *addr, bool broken) | ||||
| { | ||||
| 	/* config magic found */ | ||||
| 	if (__raw_readl(addr) == ATH25_BD_MAGIC) | ||||
| 		return true; | ||||
| 
 | ||||
| 	if (!broken) | ||||
| 		return false; | ||||
| 
 | ||||
| 	/* broken board data detected, use radio data to find the
 | ||||
| 	 * offset, user will fix this */ | ||||
| 
 | ||||
| 	if (check_radio_magic(addr + 0x1000)) | ||||
| 		return true; | ||||
| 	if (check_radio_magic(addr + 0xf8)) | ||||
| 		return true; | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static const void __iomem * __init find_board_config(const void __iomem *limit, | ||||
| 						     const bool broken) | ||||
| { | ||||
| 	const void __iomem *addr; | ||||
| 	const void __iomem *begin = limit - 0x1000; | ||||
| 	const void __iomem *end = limit - 0x30000; | ||||
| 
 | ||||
| 	for (addr = begin; addr >= end; addr -= 0x1000) | ||||
| 		if (check_board_data(addr, broken)) | ||||
| 			return addr; | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| static const void __iomem * __init find_radio_config(const void __iomem *limit, | ||||
| 						     const void __iomem *bcfg) | ||||
| { | ||||
| 	const void __iomem *rcfg, *begin, *end; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Now find the start of Radio Configuration data, using heuristics: | ||||
| 	 * Search forward from Board Configuration data by 0x1000 bytes | ||||
| 	 * at a time until we find non-0xffffffff. | ||||
| 	 */ | ||||
| 	begin = bcfg + 0x1000; | ||||
| 	end = limit; | ||||
| 	for (rcfg = begin; rcfg < end; rcfg += 0x1000) | ||||
| 		if (check_notempty(rcfg) && check_radio_magic(rcfg)) | ||||
| 			return rcfg; | ||||
| 
 | ||||
| 	/* AR2316 relocates radio config to new location */ | ||||
| 	begin = bcfg + 0xf8; | ||||
| 	end = limit - 0x1000 + 0xf8; | ||||
| 	for (rcfg = begin; rcfg < end; rcfg += 0x1000) | ||||
| 		if (check_notempty(rcfg) && check_radio_magic(rcfg)) | ||||
| 			return rcfg; | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * NB: Search region size could be larger than the actual flash size, | ||||
|  * but this shouldn't be a problem here, because the flash | ||||
|  * will simply be mapped multiple times. | ||||
|  */ | ||||
| int __init ath25_find_config(phys_addr_t base, unsigned long size) | ||||
| { | ||||
| 	const void __iomem *flash_base, *flash_limit; | ||||
| 	struct ath25_boarddata *config; | ||||
| 	unsigned int rcfg_size; | ||||
| 	int broken_boarddata = 0; | ||||
| 	const void __iomem *bcfg, *rcfg; | ||||
| 	u8 *board_data; | ||||
| 	u8 *radio_data; | ||||
| 	u8 *mac_addr; | ||||
| 	u32 offset; | ||||
| 
 | ||||
| 	flash_base = ioremap_nocache(base, size); | ||||
| 	flash_limit = flash_base + size; | ||||
| 
 | ||||
| 	ath25_board.config = NULL; | ||||
| 	ath25_board.radio = NULL; | ||||
| 
 | ||||
| 	/* Copy the board and radio data to RAM, because accessing the mapped
 | ||||
| 	 * memory of the flash directly after booting is not safe */ | ||||
| 
 | ||||
| 	/* Try to find valid board and radio data */ | ||||
| 	bcfg = find_board_config(flash_limit, false); | ||||
| 
 | ||||
| 	/* If that fails, try to at least find valid radio data */ | ||||
| 	if (!bcfg) { | ||||
| 		bcfg = find_board_config(flash_limit, true); | ||||
| 		broken_boarddata = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!bcfg) { | ||||
| 		pr_warn("WARNING: No board configuration data found!\n"); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL); | ||||
| 	ath25_board.config = (struct ath25_boarddata *)board_data; | ||||
| 	memcpy_fromio(board_data, bcfg, 0x100); | ||||
| 	if (broken_boarddata) { | ||||
| 		pr_warn("WARNING: broken board data detected\n"); | ||||
| 		config = ath25_board.config; | ||||
| 		if (is_zero_ether_addr(config->enet0_mac)) { | ||||
| 			pr_info("Fixing up empty mac addresses\n"); | ||||
| 			config->reset_config_gpio = 0xffff; | ||||
| 			config->sys_led_gpio = 0xffff; | ||||
| 			random_ether_addr(config->wlan0_mac); | ||||
| 			config->wlan0_mac[0] &= ~0x06; | ||||
| 			random_ether_addr(config->enet0_mac); | ||||
| 			random_ether_addr(config->enet1_mac); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Radio config starts 0x100 bytes after board config, regardless
 | ||||
| 	 * of what the physical layout on the flash chip looks like */ | ||||
| 
 | ||||
| 	rcfg = find_radio_config(flash_limit, bcfg); | ||||
| 	if (!rcfg) { | ||||
| 		pr_warn("WARNING: Could not find Radio Configuration data\n"); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff); | ||||
| 	ath25_board.radio = radio_data; | ||||
| 	offset = radio_data - board_data; | ||||
| 	pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg, | ||||
| 		offset); | ||||
| 	rcfg_size = BOARD_CONFIG_BUFSZ - offset; | ||||
| 	memcpy_fromio(radio_data, rcfg, rcfg_size); | ||||
| 
 | ||||
| 	mac_addr = &radio_data[0x1d * 2]; | ||||
| 	if (is_broadcast_ether_addr(mac_addr)) { | ||||
| 		pr_info("Radio MAC is blank; using board-data\n"); | ||||
| 		ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac); | ||||
| 	} | ||||
| 
 | ||||
| 	iounmap(flash_base); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| error: | ||||
| 	iounmap(flash_base); | ||||
| 	return -ENODEV; | ||||
| } | ||||
| 
 | ||||
| static void ath25_halt(void) | ||||
| { | ||||
| 	local_irq_disable(); | ||||
| 	unreachable(); | ||||
| } | ||||
| 
 | ||||
| void __init plat_mem_setup(void) | ||||
| { | ||||
| 	_machine_halt = ath25_halt; | ||||
| 	pm_power_off = ath25_halt; | ||||
| 
 | ||||
| 	if (is_ar5312()) | ||||
| 		ar5312_plat_mem_setup(); | ||||
| 	else | ||||
| 		ar2315_plat_mem_setup(); | ||||
| 
 | ||||
| 	/* Disable data watchpoints */ | ||||
| 	write_c0_watchlo0(0); | ||||
| } | ||||
| 
 | ||||
| asmlinkage void plat_irq_dispatch(void) | ||||
| { | ||||
| 	ath25_irq_dispatch(); | ||||
| } | ||||
| 
 | ||||
| void __init plat_time_init(void) | ||||
| { | ||||
| 	if (is_ar5312()) | ||||
| 		ar5312_plat_time_init(); | ||||
| 	else | ||||
| 		ar2315_plat_time_init(); | ||||
| } | ||||
| 
 | ||||
| unsigned int __cpuinit get_c0_compare_int(void) | ||||
| { | ||||
| 	return CP0_LEGACY_COMPARE_IRQ; | ||||
| } | ||||
| 
 | ||||
| void __init arch_init_irq(void) | ||||
| { | ||||
| 	clear_c0_status(ST0_IM); | ||||
| 	mips_cpu_irq_init(); | ||||
| 
 | ||||
| 	/* Initialize interrupt controllers */ | ||||
| 	if (is_ar5312()) | ||||
| 		ar5312_arch_init_irq(); | ||||
| 	else | ||||
| 		ar2315_arch_init_irq(); | ||||
| } | ||||
							
								
								
									
										125
									
								
								arch/mips/ath25/devices.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								arch/mips/ath25/devices.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,125 @@ | |||
| #include <linux/kernel.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/serial_8250.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <asm/bootinfo.h> | ||||
| 
 | ||||
| #include <ath25_platform.h> | ||||
| #include "devices.h" | ||||
| #include "ar5312.h" | ||||
| #include "ar2315.h" | ||||
| 
 | ||||
| struct ar231x_board_config ath25_board; | ||||
| enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN; | ||||
| 
 | ||||
| static struct resource ath25_wmac0_res[] = { | ||||
| 	{ | ||||
| 		.name = "wmac0_membase", | ||||
| 		.flags = IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "wmac0_irq", | ||||
| 		.flags = IORESOURCE_IRQ, | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| static struct resource ath25_wmac1_res[] = { | ||||
| 	{ | ||||
| 		.name = "wmac1_membase", | ||||
| 		.flags = IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "wmac1_irq", | ||||
| 		.flags = IORESOURCE_IRQ, | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device ath25_wmac[] = { | ||||
| 	{ | ||||
| 		.id = 0, | ||||
| 		.name = "ar231x-wmac", | ||||
| 		.resource = ath25_wmac0_res, | ||||
| 		.num_resources = ARRAY_SIZE(ath25_wmac0_res), | ||||
| 		.dev.platform_data = &ath25_board, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.id = 1, | ||||
| 		.name = "ar231x-wmac", | ||||
| 		.resource = ath25_wmac1_res, | ||||
| 		.num_resources = ARRAY_SIZE(ath25_wmac1_res), | ||||
| 		.dev.platform_data = &ath25_board, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static const char * const soc_type_strings[] = { | ||||
| 	[ATH25_SOC_AR5312] = "Atheros AR5312", | ||||
| 	[ATH25_SOC_AR2312] = "Atheros AR2312", | ||||
| 	[ATH25_SOC_AR2313] = "Atheros AR2313", | ||||
| 	[ATH25_SOC_AR2315] = "Atheros AR2315", | ||||
| 	[ATH25_SOC_AR2316] = "Atheros AR2316", | ||||
| 	[ATH25_SOC_AR2317] = "Atheros AR2317", | ||||
| 	[ATH25_SOC_AR2318] = "Atheros AR2318", | ||||
| 	[ATH25_SOC_UNKNOWN] = "Atheros (unknown)", | ||||
| }; | ||||
| 
 | ||||
| const char *get_system_type(void) | ||||
| { | ||||
| 	if ((ath25_soc >= ARRAY_SIZE(soc_type_strings)) || | ||||
| 	    !soc_type_strings[ath25_soc]) | ||||
| 		return soc_type_strings[ATH25_SOC_UNKNOWN]; | ||||
| 	return soc_type_strings[ath25_soc]; | ||||
| } | ||||
| 
 | ||||
| void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) | ||||
| { | ||||
| 	struct uart_port s; | ||||
| 
 | ||||
| 	memset(&s, 0, sizeof(s)); | ||||
| 
 | ||||
| 	s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP; | ||||
| 	s.iotype = UPIO_MEM32; | ||||
| 	s.irq = irq; | ||||
| 	s.regshift = 2; | ||||
| 	s.mapbase = mapbase; | ||||
| 	s.uartclk = uartclk; | ||||
| 
 | ||||
| 	early_serial_setup(&s); | ||||
| } | ||||
| 
 | ||||
| int __init ath25_add_wmac(int nr, u32 base, int irq) | ||||
| { | ||||
| 	struct resource *res; | ||||
| 
 | ||||
| 	ath25_wmac[nr].dev.platform_data = &ath25_board; | ||||
| 	res = &ath25_wmac[nr].resource[0]; | ||||
| 	res->start = base; | ||||
| 	res->end = base + 0x10000 - 1; | ||||
| 	res++; | ||||
| 	res->start = irq; | ||||
| 	res->end = irq; | ||||
| 	return platform_device_register(&ath25_wmac[nr]); | ||||
| } | ||||
| 
 | ||||
| static int __init ath25_register_devices(void) | ||||
| { | ||||
| 	if (is_ar5312()) | ||||
| 		ar5312_init_devices(); | ||||
| 	else | ||||
| 		ar2315_init_devices(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| device_initcall(ath25_register_devices); | ||||
| 
 | ||||
| static int __init ath25_arch_init(void) | ||||
| { | ||||
| 	if (is_ar5312()) | ||||
| 		ar5312_arch_init(); | ||||
| 	else | ||||
| 		ar2315_arch_init(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| arch_initcall(ath25_arch_init); | ||||
							
								
								
									
										43
									
								
								arch/mips/ath25/devices.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								arch/mips/ath25/devices.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| #ifndef __ATH25_DEVICES_H | ||||
| #define __ATH25_DEVICES_H | ||||
| 
 | ||||
| #include <linux/cpu.h> | ||||
| 
 | ||||
| #define ATH25_REG_MS(_val, _field)	(((_val) & _field##_M) >> _field##_S) | ||||
| 
 | ||||
| #define ATH25_IRQ_CPU_CLOCK	(MIPS_CPU_IRQ_BASE + 7)	/* C0_CAUSE: 0x8000 */ | ||||
| 
 | ||||
| enum ath25_soc_type { | ||||
| 	/* handled by ar5312.c */ | ||||
| 	ATH25_SOC_AR2312, | ||||
| 	ATH25_SOC_AR2313, | ||||
| 	ATH25_SOC_AR5312, | ||||
| 
 | ||||
| 	/* handled by ar2315.c */ | ||||
| 	ATH25_SOC_AR2315, | ||||
| 	ATH25_SOC_AR2316, | ||||
| 	ATH25_SOC_AR2317, | ||||
| 	ATH25_SOC_AR2318, | ||||
| 
 | ||||
| 	ATH25_SOC_UNKNOWN | ||||
| }; | ||||
| 
 | ||||
| extern enum ath25_soc_type ath25_soc; | ||||
| extern struct ar231x_board_config ath25_board; | ||||
| extern void (*ath25_irq_dispatch)(void); | ||||
| 
 | ||||
| int ath25_find_config(phys_addr_t offset, unsigned long size); | ||||
| void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); | ||||
| int ath25_add_wmac(int nr, u32 base, int irq); | ||||
| 
 | ||||
| static inline bool is_ar2315(void) | ||||
| { | ||||
| 	return (current_cpu_data.cputype == CPU_4KEC); | ||||
| } | ||||
| 
 | ||||
| static inline bool is_ar5312(void) | ||||
| { | ||||
| 	return !is_ar2315(); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										44
									
								
								arch/mips/ath25/early_printk.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								arch/mips/ath25/early_printk.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/mm.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/serial_reg.h> | ||||
| 
 | ||||
| #include "devices.h" | ||||
| #include "ar2315_regs.h" | ||||
| #include "ar5312_regs.h" | ||||
| 
 | ||||
| static inline void prom_uart_wr(void __iomem *base, unsigned reg, | ||||
| 				unsigned char ch) | ||||
| { | ||||
| 	__raw_writel(ch, base + 4 * reg); | ||||
| } | ||||
| 
 | ||||
| static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg) | ||||
| { | ||||
| 	return __raw_readl(base + 4 * reg); | ||||
| } | ||||
| 
 | ||||
| void prom_putchar(unsigned char ch) | ||||
| { | ||||
| 	static void __iomem *base; | ||||
| 
 | ||||
| 	if (unlikely(base == NULL)) { | ||||
| 		if (is_ar2315()) | ||||
| 			base = (void __iomem *)(KSEG1ADDR(AR2315_UART0_BASE)); | ||||
| 		else | ||||
| 			base = (void __iomem *)(KSEG1ADDR(AR5312_UART0_BASE)); | ||||
| 	} | ||||
| 
 | ||||
| 	while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) | ||||
| 		; | ||||
| 	prom_uart_wr(base, UART_TX, ch); | ||||
| 	while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) | ||||
| 		; | ||||
| } | ||||
							
								
								
									
										26
									
								
								arch/mips/ath25/prom.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								arch/mips/ath25/prom.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright MontaVista Software Inc | ||||
|  * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved. | ||||
|  * Copyright (C) 2006 FON Technology, SL. | ||||
|  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||||
|  * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Prom setup file for AR5312/AR231x SoCs | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/init.h> | ||||
| #include <asm/bootinfo.h> | ||||
| 
 | ||||
| void __init prom_init(void) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void __init prom_free_prom_memory(void) | ||||
| { | ||||
| } | ||||
|  | @ -359,7 +359,6 @@ void __init arch_init_irq(void) | |||
| 		BUG(); | ||||
| 	} | ||||
| 
 | ||||
| 	cp0_perfcount_irq = ATH79_MISC_IRQ(5); | ||||
| 	mips_cpu_irq_init(); | ||||
| 	ath79_misc_irq_init(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,42 +13,24 @@ | |||
| #include <linux/init.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/initrd.h> | ||||
| 
 | ||||
| #include <asm/bootinfo.h> | ||||
| #include <asm/addrspace.h> | ||||
| #include <asm/fw/fw.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| 
 | ||||
| static inline int is_valid_ram_addr(void *addr) | ||||
| { | ||||
| 	if (((u32) addr > KSEG0) && | ||||
| 	    ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX))) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if (((u32) addr > KSEG1) && | ||||
| 	    ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX))) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static __init void ath79_prom_init_cmdline(int argc, char **argv) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	if (!is_valid_ram_addr(argv)) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (i = 0; i < argc; i++) | ||||
| 		if (is_valid_ram_addr(argv[i])) { | ||||
| 			strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); | ||||
| 			strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); | ||||
| 		} | ||||
| } | ||||
| 
 | ||||
| void __init prom_init(void) | ||||
| { | ||||
| 	ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); | ||||
| 	fw_init_cmdline(); | ||||
| 
 | ||||
| 	/* Read the initrd address from the firmware environment */ | ||||
| 	initrd_start = fw_getenvl("initrd_start"); | ||||
| 	if (initrd_start) { | ||||
| 		initrd_start = KSEG0ADDR(initrd_start); | ||||
| 		initrd_end = initrd_start + fw_getenvl("initrd_size"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void __init prom_free_prom_memory(void) | ||||
|  |  | |||
|  | @ -182,6 +182,11 @@ const char *get_system_type(void) | |||
| 	return ath79_sys_type; | ||||
| } | ||||
| 
 | ||||
| int get_c0_perfcount_int(void) | ||||
| { | ||||
| 	return ATH79_MISC_IRQ(5); | ||||
| } | ||||
| 
 | ||||
| unsigned int get_c0_compare_int(void) | ||||
| { | ||||
| 	return CP0_LEGACY_COMPARE_IRQ; | ||||
|  |  | |||
							
								
								
									
										1
									
								
								arch/mips/bcm3384/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								arch/mips/bcm3384/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| obj-y		+= setup.o irq.o dma.o | ||||
							
								
								
									
										7
									
								
								arch/mips/bcm3384/Platform
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								arch/mips/bcm3384/Platform
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| # | ||||
| # Broadcom BCM3384 boards | ||||
| # | ||||
| platform-$(CONFIG_BCM3384)	+= bcm3384/ | ||||
| cflags-$(CONFIG_BCM3384)	+=					\ | ||||
| 		-I$(srctree)/arch/mips/include/asm/mach-bcm3384/ | ||||
| load-$(CONFIG_BCM3384)		:= 0xffffffff80010000 | ||||
							
								
								
									
										81
									
								
								arch/mips/bcm3384/dma.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								arch/mips/bcm3384/dma.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,81 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/device.h> | ||||
| #include <linux/dma-direction.h> | ||||
| #include <linux/dma-mapping.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/mm.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/pci.h> | ||||
| #include <linux/types.h> | ||||
| #include <dma-coherence.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * BCM3384 has configurable address translation windows which allow the | ||||
|  * peripherals' DMA addresses to be different from the Zephyr-visible | ||||
|  * physical addresses.  e.g. usb_dma_addr = zephyr_pa ^ 0x08000000 | ||||
|  * | ||||
|  * If our DT "memory" node has a "dma-xor-mask" property we will enable this | ||||
|  * translation using the provided offset. | ||||
|  */ | ||||
| static u32 bcm3384_dma_xor_mask; | ||||
| static u32 bcm3384_dma_xor_limit = 0xffffffff; | ||||
| 
 | ||||
| /*
 | ||||
|  * PCI collapses the memory hole at 0x10000000 - 0x1fffffff. | ||||
|  * On systems with a dma-xor-mask, this range is guaranteed to live above | ||||
|  * the dma-xor-limit. | ||||
|  */ | ||||
| #define BCM3384_MEM_HOLE_PA	0x10000000 | ||||
| #define BCM3384_MEM_HOLE_SIZE	0x10000000 | ||||
| 
 | ||||
| static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa) | ||||
| { | ||||
| 	if (dev && dev_is_pci(dev) && | ||||
| 	    pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE)) | ||||
| 		return pa - BCM3384_MEM_HOLE_SIZE; | ||||
| 	if (pa <= bcm3384_dma_xor_limit) | ||||
| 		return pa ^ bcm3384_dma_xor_mask; | ||||
| 	return pa; | ||||
| } | ||||
| 
 | ||||
| dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||||
| { | ||||
| 	return bcm3384_phys_to_dma(dev, virt_to_phys(addr)); | ||||
| } | ||||
| 
 | ||||
| dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) | ||||
| { | ||||
| 	return bcm3384_phys_to_dma(dev, page_to_phys(page)); | ||||
| } | ||||
| 
 | ||||
| unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) | ||||
| { | ||||
| 	if (dev && dev_is_pci(dev) && | ||||
| 	    dma_addr >= BCM3384_MEM_HOLE_PA) | ||||
| 		return dma_addr + BCM3384_MEM_HOLE_SIZE; | ||||
| 	if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit) | ||||
| 		return dma_addr ^ bcm3384_dma_xor_mask; | ||||
| 	return dma_addr; | ||||
| } | ||||
| 
 | ||||
| static int __init bcm3384_init_dma_xor(void) | ||||
| { | ||||
| 	struct device_node *np = of_find_node_by_type(NULL, "memory"); | ||||
| 
 | ||||
| 	if (!np) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask); | ||||
| 	of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit); | ||||
| 
 | ||||
| 	of_node_put(np); | ||||
| 	return 0; | ||||
| } | ||||
| arch_initcall(bcm3384_init_dma_xor); | ||||
							
								
								
									
										193
									
								
								arch/mips/bcm3384/irq.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								arch/mips/bcm3384/irq.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,193 @@ | |||
| /*
 | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms of the GNU General Public License version 2 as published | ||||
|  * by the Free Software Foundation. | ||||
|  * | ||||
|  * Partially based on arch/mips/ralink/irq.c | ||||
|  * | ||||
|  * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||||
|  * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/io.h> | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/of_platform.h> | ||||
| #include <linux/of_address.h> | ||||
| #include <linux/of_irq.h> | ||||
| #include <linux/irqdomain.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/spinlock.h> | ||||
| 
 | ||||
| #include <asm/bmips.h> | ||||
| #include <asm/irq_cpu.h> | ||||
| #include <asm/mipsregs.h> | ||||
| 
 | ||||
| /* INTC register offsets */ | ||||
| #define INTC_REG_ENABLE		0x00 | ||||
| #define INTC_REG_STATUS		0x04 | ||||
| 
 | ||||
| #define MAX_WORDS		2 | ||||
| #define IRQS_PER_WORD		32 | ||||
| 
 | ||||
| struct bcm3384_intc { | ||||
| 	int			n_words; | ||||
| 	void __iomem		*reg[MAX_WORDS]; | ||||
| 	u32			enable[MAX_WORDS]; | ||||
| 	spinlock_t		lock; | ||||
| }; | ||||
| 
 | ||||
| static void bcm3384_intc_irq_unmask(struct irq_data *d) | ||||
| { | ||||
| 	struct bcm3384_intc *priv = d->domain->host_data; | ||||
| 	unsigned long flags; | ||||
| 	int idx = d->hwirq / IRQS_PER_WORD; | ||||
| 	int bit = d->hwirq % IRQS_PER_WORD; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 	priv->enable[idx] |= BIT(bit); | ||||
| 	__raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
| } | ||||
| 
 | ||||
| static void bcm3384_intc_irq_mask(struct irq_data *d) | ||||
| { | ||||
| 	struct bcm3384_intc *priv = d->domain->host_data; | ||||
| 	unsigned long flags; | ||||
| 	int idx = d->hwirq / IRQS_PER_WORD; | ||||
| 	int bit = d->hwirq % IRQS_PER_WORD; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 	priv->enable[idx] &= ~BIT(bit); | ||||
| 	__raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
| } | ||||
| 
 | ||||
| static struct irq_chip bcm3384_intc_irq_chip = { | ||||
| 	.name		= "INTC", | ||||
| 	.irq_unmask	= bcm3384_intc_irq_unmask, | ||||
| 	.irq_mask	= bcm3384_intc_irq_mask, | ||||
| 	.irq_mask_ack	= bcm3384_intc_irq_mask, | ||||
| }; | ||||
| 
 | ||||
| unsigned int get_c0_compare_int(void) | ||||
| { | ||||
| 	return CP0_LEGACY_COMPARE_IRQ; | ||||
| } | ||||
| 
 | ||||
| static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc) | ||||
| { | ||||
| 	struct irq_domain *domain = irq_get_handler_data(irq); | ||||
| 	struct bcm3384_intc *priv = domain->host_data; | ||||
| 	unsigned long flags; | ||||
| 	unsigned int idx; | ||||
| 
 | ||||
| 	for (idx = 0; idx < priv->n_words; idx++) { | ||||
| 		unsigned long pending; | ||||
| 		int hwirq; | ||||
| 
 | ||||
| 		spin_lock_irqsave(&priv->lock, flags); | ||||
| 		pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) & | ||||
| 			  priv->enable[idx]; | ||||
| 		spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 
 | ||||
| 		for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { | ||||
| 			generic_handle_irq(irq_find_mapping(domain, | ||||
| 					   hwirq + idx * IRQS_PER_WORD)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| asmlinkage void plat_irq_dispatch(void) | ||||
| { | ||||
| 	unsigned long pending = | ||||
| 		(read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0; | ||||
| 	int bit; | ||||
| 
 | ||||
| 	for_each_set_bit(bit, &pending, 8) | ||||
| 		do_IRQ(MIPS_CPU_IRQ_BASE + bit); | ||||
| } | ||||
| 
 | ||||
| static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | ||||
| { | ||||
| 	irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct irq_domain_ops irq_domain_ops = { | ||||
| 	.xlate = irq_domain_xlate_onecell, | ||||
| 	.map = intc_map, | ||||
| }; | ||||
| 
 | ||||
| static int __init ioremap_one_pair(struct bcm3384_intc *priv, | ||||
| 				   struct device_node *node, | ||||
| 				   int idx) | ||||
| { | ||||
| 	struct resource res; | ||||
| 
 | ||||
| 	if (of_address_to_resource(node, idx, &res)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (request_mem_region(res.start, resource_size(&res), | ||||
| 			       res.name) < 0) | ||||
| 		pr_err("Failed to request INTC register region\n"); | ||||
| 
 | ||||
| 	priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res)); | ||||
| 	if (!priv->reg[idx]) | ||||
| 		panic("Failed to ioremap INTC register range"); | ||||
| 
 | ||||
| 	/* start up with everything masked before we hook the parent IRQ */ | ||||
| 	__raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE); | ||||
| 	priv->enable[idx] = 0; | ||||
| 
 | ||||
| 	return IRQS_PER_WORD; | ||||
| } | ||||
| 
 | ||||
| static int __init intc_of_init(struct device_node *node, | ||||
| 			       struct device_node *parent) | ||||
| { | ||||
| 	struct irq_domain *domain; | ||||
| 	unsigned int parent_irq, n_irqs = 0; | ||||
| 	struct bcm3384_intc *priv; | ||||
| 
 | ||||
| 	priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||||
| 	if (!priv) | ||||
| 		panic("Failed to allocate bcm3384_intc struct"); | ||||
| 
 | ||||
| 	spin_lock_init(&priv->lock); | ||||
| 
 | ||||
| 	parent_irq = irq_of_parse_and_map(node, 0); | ||||
| 	if (!parent_irq) | ||||
| 		panic("Failed to get INTC IRQ"); | ||||
| 
 | ||||
| 	n_irqs += ioremap_one_pair(priv, node, 0); | ||||
| 	n_irqs += ioremap_one_pair(priv, node, 1); | ||||
| 
 | ||||
| 	if (!n_irqs) | ||||
| 		panic("Failed to map INTC registers"); | ||||
| 
 | ||||
| 	priv->n_words = n_irqs / IRQS_PER_WORD; | ||||
| 	domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv); | ||||
| 	if (!domain) | ||||
| 		panic("Failed to add irqdomain"); | ||||
| 
 | ||||
| 	irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler); | ||||
| 	irq_set_handler_data(parent_irq, domain); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct of_device_id of_irq_ids[] __initdata = { | ||||
| 	{ .compatible = "mti,cpu-interrupt-controller", | ||||
| 	  .data = mips_cpu_intc_init }, | ||||
| 	{ .compatible = "brcm,bcm3384-intc", | ||||
| 	  .data = intc_of_init }, | ||||
| 	{}, | ||||
| }; | ||||
| 
 | ||||
| void __init arch_init_irq(void) | ||||
| { | ||||
| 	bmips_tp1_irqs = 0; | ||||
| 	of_irq_init(of_irq_ids); | ||||
| } | ||||
							
								
								
									
										97
									
								
								arch/mips/bcm3384/setup.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								arch/mips/bcm3384/setup.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,97 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> | ||||
|  * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/init.h> | ||||
| #include <linux/bootmem.h> | ||||
| #include <linux/clk-provider.h> | ||||
| #include <linux/ioport.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_fdt.h> | ||||
| #include <linux/of_platform.h> | ||||
| #include <linux/smp.h> | ||||
| #include <asm/addrspace.h> | ||||
| #include <asm/bmips.h> | ||||
| #include <asm/bootinfo.h> | ||||
| #include <asm/prom.h> | ||||
| #include <asm/smp-ops.h> | ||||
| #include <asm/time.h> | ||||
| 
 | ||||
| void __init prom_init(void) | ||||
| { | ||||
| 	register_bmips_smp_ops(); | ||||
| } | ||||
| 
 | ||||
| void __init prom_free_prom_memory(void) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| const char *get_system_type(void) | ||||
| { | ||||
| 	return "BCM3384"; | ||||
| } | ||||
| 
 | ||||
| void __init plat_time_init(void) | ||||
| { | ||||
| 	struct device_node *np; | ||||
| 	u32 freq; | ||||
| 
 | ||||
| 	np = of_find_node_by_name(NULL, "cpus"); | ||||
| 	if (!np) | ||||
| 		panic("missing 'cpus' DT node"); | ||||
| 	if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0) | ||||
| 		panic("missing 'mips-hpt-frequency' property"); | ||||
| 	of_node_put(np); | ||||
| 
 | ||||
| 	mips_hpt_frequency = freq; | ||||
| } | ||||
| 
 | ||||
| void __init plat_mem_setup(void) | ||||
| { | ||||
| 	void *dtb = __dtb_start; | ||||
| 
 | ||||
| 	set_io_port_base(0); | ||||
| 	ioport_resource.start = 0; | ||||
| 	ioport_resource.end = ~0; | ||||
| 
 | ||||
| 	/* intended to somewhat resemble ARM; see Documentation/arm/Booting */ | ||||
| 	if (fw_arg0 == 0 && fw_arg1 == 0xffffffff) | ||||
| 		dtb = phys_to_virt(fw_arg2); | ||||
| 
 | ||||
| 	__dt_setup_arch(dtb); | ||||
| 
 | ||||
| 	strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||||
| } | ||||
| 
 | ||||
| void __init device_tree_init(void) | ||||
| { | ||||
| 	struct device_node *np; | ||||
| 
 | ||||
| 	unflatten_and_copy_device_tree(); | ||||
| 
 | ||||
| 	/* Disable SMP boot unless both CPUs are listed in DT and !disabled */ | ||||
| 	np = of_find_node_by_name(NULL, "cpus"); | ||||
| 	if (np && of_get_available_child_count(np) <= 1) | ||||
| 		bmips_smp_enabled = 0; | ||||
| 	of_node_put(np); | ||||
| } | ||||
| 
 | ||||
| int __init plat_of_setup(void) | ||||
| { | ||||
| 	return __dt_register_buses("brcm,bcm3384", "simple-bus"); | ||||
| } | ||||
| 
 | ||||
| arch_initcall(plat_of_setup); | ||||
| 
 | ||||
| static int __init plat_dev_init(void) | ||||
| { | ||||
| 	of_clk_init(NULL); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| device_initcall(plat_dev_init); | ||||
|  | @ -6,12 +6,18 @@ | |||
| /* prom.c */ | ||||
| void __init bcm47xx_prom_highmem_init(void); | ||||
| 
 | ||||
| /* sprom.c */ | ||||
| void bcm47xx_sprom_register_fallbacks(void); | ||||
| 
 | ||||
| /* buttons.c */ | ||||
| int __init bcm47xx_buttons_register(void); | ||||
| 
 | ||||
| /* leds.c */ | ||||
| void __init bcm47xx_leds_register(void); | ||||
| 
 | ||||
| /* setup.c */ | ||||
| void __init bcm47xx_bus_setup(void); | ||||
| 
 | ||||
| /* workarounds.c */ | ||||
| void __init bcm47xx_workarounds(void); | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,6 +22,8 @@ | |||
|  *  675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
| 
 | ||||
| #include "bcm47xx_private.h" | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/irq.h> | ||||
|  | @ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7) | |||
| 
 | ||||
| void __init arch_init_irq(void) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * This is the first arch callback after mm_init (we can use kmalloc), | ||||
| 	 * so let's finish bus initialization now. | ||||
| 	 */ | ||||
| 	bcm47xx_bus_setup(); | ||||
| 
 | ||||
| #ifdef CONFIG_BCM47XX_BCMA | ||||
| 	if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | ||||
| 		bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, | ||||
|  |  | |||
|  | @ -13,24 +13,35 @@ | |||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/ssb/ssb.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/string.h> | ||||
| #include <asm/addrspace.h> | ||||
| #include <linux/mtd/mtd.h> | ||||
| #include <bcm47xx_nvram.h> | ||||
| #include <asm/mach-bcm47xx/bcm47xx.h> | ||||
| 
 | ||||
| #define NVRAM_MAGIC		0x48534C46	/* 'FLSH' */ | ||||
| #define NVRAM_SPACE		0x8000 | ||||
| 
 | ||||
| #define FLASH_MIN		0x00020000	/* Minimum flash size */ | ||||
| 
 | ||||
| struct nvram_header { | ||||
| 	u32 magic; | ||||
| 	u32 len; | ||||
| 	u32 crc_ver_init;	/* 0:7 crc, 8:15 ver, 16:31 sdram_init */ | ||||
| 	u32 config_refresh;	/* 0:15 sdram_config, 16:31 sdram_refresh */ | ||||
| 	u32 config_ncdl;	/* ncdl values for memc */ | ||||
| }; | ||||
| 
 | ||||
| static char nvram_buf[NVRAM_SPACE]; | ||||
| static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; | ||||
| 
 | ||||
| static u32 find_nvram_size(u32 end) | ||||
| static u32 find_nvram_size(void __iomem *end) | ||||
| { | ||||
| 	struct nvram_header *header; | ||||
| 	struct nvram_header __iomem *header; | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { | ||||
| 		header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); | ||||
| 		if (header->magic == NVRAM_HEADER) | ||||
| 		header = (struct nvram_header *)(end - nvram_sizes[i]); | ||||
| 		if (header->magic == NVRAM_MAGIC) | ||||
| 			return nvram_sizes[i]; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -38,36 +49,40 @@ static u32 find_nvram_size(u32 end) | |||
| } | ||||
| 
 | ||||
| /* Probe for NVRAM header */ | ||||
| static int nvram_find_and_copy(u32 base, u32 lim) | ||||
| static int nvram_find_and_copy(void __iomem *iobase, u32 lim) | ||||
| { | ||||
| 	struct nvram_header *header; | ||||
| 	struct nvram_header __iomem *header; | ||||
| 	int i; | ||||
| 	u32 off; | ||||
| 	u32 *src, *dst; | ||||
| 	u32 size; | ||||
| 
 | ||||
| 	if (nvram_buf[0]) { | ||||
| 		pr_warn("nvram already initialized\n"); | ||||
| 		return -EEXIST; | ||||
| 	} | ||||
| 
 | ||||
| 	/* TODO: when nvram is on nand flash check for bad blocks first. */ | ||||
| 	off = FLASH_MIN; | ||||
| 	while (off <= lim) { | ||||
| 		/* Windowed flash access */ | ||||
| 		size = find_nvram_size(base + off); | ||||
| 		size = find_nvram_size(iobase + off); | ||||
| 		if (size) { | ||||
| 			header = (struct nvram_header *)KSEG1ADDR(base + off - | ||||
| 								  size); | ||||
| 			header = (struct nvram_header *)(iobase + off - size); | ||||
| 			goto found; | ||||
| 		} | ||||
| 		off <<= 1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ | ||||
| 	header = (struct nvram_header *) KSEG1ADDR(base + 4096); | ||||
| 	if (header->magic == NVRAM_HEADER) { | ||||
| 	header = (struct nvram_header *)(iobase + 4096); | ||||
| 	if (header->magic == NVRAM_MAGIC) { | ||||
| 		size = NVRAM_SPACE; | ||||
| 		goto found; | ||||
| 	} | ||||
| 
 | ||||
| 	header = (struct nvram_header *) KSEG1ADDR(base + 1024); | ||||
| 	if (header->magic == NVRAM_HEADER) { | ||||
| 	header = (struct nvram_header *)(iobase + 1024); | ||||
| 	if (header->magic == NVRAM_MAGIC) { | ||||
| 		size = NVRAM_SPACE; | ||||
| 		goto found; | ||||
| 	} | ||||
|  | @ -94,71 +109,73 @@ found: | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_BCM47XX_SSB | ||||
| static int nvram_init_ssb(void) | ||||
| /*
 | ||||
|  * On bcm47xx we need access to the NVRAM very early, so we can't use mtd | ||||
|  * subsystem to access flash. We can't even use platform device / driver to | ||||
|  * store memory offset. | ||||
|  * To handle this we provide following symbol. It's supposed to be called as | ||||
|  * soon as we get info about flash device, before any NVRAM entry is needed. | ||||
|  */ | ||||
| int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) | ||||
| { | ||||
| 	struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; | ||||
| 	u32 base; | ||||
| 	u32 lim; | ||||
| 	void __iomem *iobase; | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (mcore->pflash.present) { | ||||
| 		base = mcore->pflash.window; | ||||
| 		lim = mcore->pflash.window_size; | ||||
| 	} else { | ||||
| 		pr_err("Couldn't find supported flash memory\n"); | ||||
| 		return -ENXIO; | ||||
| 	} | ||||
| 	iobase = ioremap_nocache(base, lim); | ||||
| 	if (!iobase) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	return nvram_find_and_copy(base, lim); | ||||
| 	err = nvram_find_and_copy(iobase, lim); | ||||
| 
 | ||||
| 	iounmap(iobase); | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_BCM47XX_BCMA | ||||
| static int nvram_init_bcma(void) | ||||
| { | ||||
| 	struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc; | ||||
| 	u32 base; | ||||
| 	u32 lim; | ||||
| 
 | ||||
| #ifdef CONFIG_BCMA_NFLASH | ||||
| 	if (cc->nflash.boot) { | ||||
| 		base = BCMA_SOC_FLASH1; | ||||
| 		lim = BCMA_SOC_FLASH1_SZ; | ||||
| 	} else | ||||
| #endif | ||||
| 	if (cc->pflash.present) { | ||||
| 		base = cc->pflash.window; | ||||
| 		lim = cc->pflash.window_size; | ||||
| #ifdef CONFIG_BCMA_SFLASH | ||||
| 	} else if (cc->sflash.present) { | ||||
| 		base = cc->sflash.window; | ||||
| 		lim = cc->sflash.size; | ||||
| #endif | ||||
| 	} else { | ||||
| 		pr_err("Couldn't find supported flash memory\n"); | ||||
| 		return -ENXIO; | ||||
| 	} | ||||
| 
 | ||||
| 	return nvram_find_and_copy(base, lim); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static int nvram_init(void) | ||||
| { | ||||
| 	switch (bcm47xx_bus_type) { | ||||
| #ifdef CONFIG_BCM47XX_SSB | ||||
| 	case BCM47XX_BUS_TYPE_SSB: | ||||
| 		return nvram_init_ssb(); | ||||
| #endif | ||||
| #ifdef CONFIG_BCM47XX_BCMA | ||||
| 	case BCM47XX_BUS_TYPE_BCMA: | ||||
| 		return nvram_init_bcma(); | ||||
| #endif | ||||
| #ifdef CONFIG_MTD | ||||
| 	struct mtd_info *mtd; | ||||
| 	struct nvram_header header; | ||||
| 	size_t bytes_read; | ||||
| 	int err, i; | ||||
| 
 | ||||
| 	mtd = get_mtd_device_nm("nvram"); | ||||
| 	if (IS_ERR(mtd)) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { | ||||
| 		loff_t from = mtd->size - nvram_sizes[i]; | ||||
| 
 | ||||
| 		if (from < 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		err = mtd_read(mtd, from, sizeof(header), &bytes_read, | ||||
| 			       (uint8_t *)&header); | ||||
| 		if (!err && header.magic == NVRAM_MAGIC) { | ||||
| 			u8 *dst = (uint8_t *)nvram_buf; | ||||
| 			size_t len = header.len; | ||||
| 
 | ||||
| 			if (header.len > NVRAM_SPACE) { | ||||
| 				pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", | ||||
| 				       header.len, NVRAM_SPACE); | ||||
| 				len = NVRAM_SPACE; | ||||
| 			} | ||||
| 
 | ||||
| 			err = mtd_read(mtd, from, len, &bytes_read, dst); | ||||
| 			if (err) | ||||
| 				return err; | ||||
| 			memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read); | ||||
| 
 | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	return -ENXIO; | ||||
| } | ||||
| 
 | ||||
| int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) | ||||
| int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) | ||||
| { | ||||
| 	char *var, *value, *end, *eq; | ||||
| 	int err; | ||||
|  |  | |||
|  | @ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void) | |||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_BCM47XX_SSB | ||||
| static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | ||||
| { | ||||
| 	char prefix[10]; | ||||
| 
 | ||||
| 	if (bus->bustype == SSB_BUSTYPE_PCI) { | ||||
| 		memset(out, 0, sizeof(struct ssb_sprom)); | ||||
| 		snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||||
| 			 bus->host_pci->bus->number + 1, | ||||
| 			 PCI_SLOT(bus->host_pci->devfn)); | ||||
| 		bcm47xx_fill_sprom(out, prefix, false); | ||||
| 		return 0; | ||||
| 	} else { | ||||
| 		printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int bcm47xx_get_invariants(struct ssb_bus *bus, | ||||
| 				  struct ssb_init_invariants *iv) | ||||
| { | ||||
|  | @ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void) | |||
| 	char buf[100]; | ||||
| 	struct ssb_mipscore *mcore; | ||||
| 
 | ||||
| 	err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); | ||||
| 	if (err) | ||||
| 		printk(KERN_WARNING "bcm47xx: someone else already registered" | ||||
| 			" a ssb SPROM callback handler (err %d)\n", err); | ||||
| 
 | ||||
| 	err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, | ||||
| 				      bcm47xx_get_invariants); | ||||
| 	if (err) | ||||
|  | @ -171,56 +149,21 @@ static void __init bcm47xx_register_ssb(void) | |||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_BCM47XX_BCMA | ||||
| static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | ||||
| { | ||||
| 	char prefix[10]; | ||||
| 	struct bcma_device *core; | ||||
| 
 | ||||
| 	switch (bus->hosttype) { | ||||
| 	case BCMA_HOSTTYPE_PCI: | ||||
| 		memset(out, 0, sizeof(struct ssb_sprom)); | ||||
| 		snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||||
| 			 bus->host_pci->bus->number + 1, | ||||
| 			 PCI_SLOT(bus->host_pci->devfn)); | ||||
| 		bcm47xx_fill_sprom(out, prefix, false); | ||||
| 		return 0; | ||||
| 	case BCMA_HOSTTYPE_SOC: | ||||
| 		memset(out, 0, sizeof(struct ssb_sprom)); | ||||
| 		core = bcma_find_core(bus, BCMA_CORE_80211); | ||||
| 		if (core) { | ||||
| 			snprintf(prefix, sizeof(prefix), "sb/%u/", | ||||
| 				 core->core_index); | ||||
| 			bcm47xx_fill_sprom(out, prefix, true); | ||||
| 		} else { | ||||
| 			bcm47xx_fill_sprom(out, NULL, false); | ||||
| 		} | ||||
| 		return 0; | ||||
| 	default: | ||||
| 		pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void __init bcm47xx_register_bcma(void) | ||||
| { | ||||
| 	int err; | ||||
| 
 | ||||
| 	err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); | ||||
| 	if (err) | ||||
| 		pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); | ||||
| 
 | ||||
| 	err = bcma_host_soc_register(&bcm47xx_bus.bcma); | ||||
| 	if (err) | ||||
| 		panic("Failed to register BCMA bus (err %d)", err); | ||||
| 
 | ||||
| 	err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||||
| 	if (err) | ||||
| 		panic("Failed to initialize BCMA bus (err %d)", err); | ||||
| 
 | ||||
| 	bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed | ||||
|  * to detect memory and record it with add_memory_region. | ||||
|  * Any extra initializaion performed here must not use kmalloc or bootmem. | ||||
|  */ | ||||
| void __init plat_mem_setup(void) | ||||
| { | ||||
| 	struct cpuinfo_mips *c = ¤t_cpu_data; | ||||
|  | @ -229,6 +172,7 @@ void __init plat_mem_setup(void) | |||
| 		printk(KERN_INFO "bcm47xx: using bcma bus\n"); | ||||
| #ifdef CONFIG_BCM47XX_BCMA | ||||
| 		bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; | ||||
| 		bcm47xx_sprom_register_fallbacks(); | ||||
| 		bcm47xx_register_bcma(); | ||||
| 		bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); | ||||
| #ifdef CONFIG_HIGHMEM | ||||
|  | @ -239,6 +183,7 @@ void __init plat_mem_setup(void) | |||
| 		printk(KERN_INFO "bcm47xx: using ssb bus\n"); | ||||
| #ifdef CONFIG_BCM47XX_SSB | ||||
| 		bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; | ||||
| 		bcm47xx_sprom_register_fallbacks(); | ||||
| 		bcm47xx_register_ssb(); | ||||
| 		bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); | ||||
| #endif | ||||
|  | @ -247,6 +192,28 @@ void __init plat_mem_setup(void) | |||
| 	_machine_restart = bcm47xx_machine_restart; | ||||
| 	_machine_halt = bcm47xx_machine_halt; | ||||
| 	pm_power_off = bcm47xx_machine_halt; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * This finishes bus initialization doing things that were not possible without | ||||
|  * kmalloc. Make sure to call it late enough (after mm_init). | ||||
|  */ | ||||
| void __init bcm47xx_bus_setup(void) | ||||
| { | ||||
| #ifdef CONFIG_BCM47XX_BCMA | ||||
| 	if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | ||||
| 		int err; | ||||
| 
 | ||||
| 		err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||||
| 		if (err) | ||||
| 			panic("Failed to initialize BCMA bus (err %d)", err); | ||||
| 
 | ||||
| 		bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, | ||||
| 					    NULL); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	/* With bus initialized we can access NVRAM and detect the board */ | ||||
| 	bcm47xx_board_detect(); | ||||
| 	mips_set_machine_name(bcm47xx_board_get_name()); | ||||
| } | ||||
|  |  | |||
|  | @ -136,6 +136,20 @@ static void nvram_read_leddc(const char *prefix, const char *name, | |||
| 	*leddc_off_time = (val >> 16) & 0xff; | ||||
| } | ||||
| 
 | ||||
| static void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) | ||||
| { | ||||
| 	if (strchr(buf, ':')) | ||||
| 		sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | ||||
| 			&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||||
| 			&macaddr[5]); | ||||
| 	else if (strchr(buf, '-')) | ||||
| 		sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], | ||||
| 			&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||||
| 			&macaddr[5]); | ||||
| 	else | ||||
| 		pr_warn("Can not parse mac address: %s\n", buf); | ||||
| } | ||||
| 
 | ||||
| static void nvram_read_macaddr(const char *prefix, const char *name, | ||||
| 			       u8 val[6], bool fallback) | ||||
| { | ||||
|  | @ -801,3 +815,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, | |||
| 	nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_BCM47XX_SSB) | ||||
| static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | ||||
| { | ||||
| 	char prefix[10]; | ||||
| 
 | ||||
| 	if (bus->bustype == SSB_BUSTYPE_PCI) { | ||||
| 		memset(out, 0, sizeof(struct ssb_sprom)); | ||||
| 		snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||||
| 			 bus->host_pci->bus->number + 1, | ||||
| 			 PCI_SLOT(bus->host_pci->devfn)); | ||||
| 		bcm47xx_fill_sprom(out, prefix, false); | ||||
| 		return 0; | ||||
| 	} else { | ||||
| 		pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_BCM47XX_BCMA) | ||||
| static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | ||||
| { | ||||
| 	char prefix[10]; | ||||
| 	struct bcma_device *core; | ||||
| 
 | ||||
| 	switch (bus->hosttype) { | ||||
| 	case BCMA_HOSTTYPE_PCI: | ||||
| 		memset(out, 0, sizeof(struct ssb_sprom)); | ||||
| 		snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||||
| 			 bus->host_pci->bus->number + 1, | ||||
| 			 PCI_SLOT(bus->host_pci->devfn)); | ||||
| 		bcm47xx_fill_sprom(out, prefix, false); | ||||
| 		return 0; | ||||
| 	case BCMA_HOSTTYPE_SOC: | ||||
| 		memset(out, 0, sizeof(struct ssb_sprom)); | ||||
| 		core = bcma_find_core(bus, BCMA_CORE_80211); | ||||
| 		if (core) { | ||||
| 			snprintf(prefix, sizeof(prefix), "sb/%u/", | ||||
| 				 core->core_index); | ||||
| 			bcm47xx_fill_sprom(out, prefix, true); | ||||
| 		} else { | ||||
| 			bcm47xx_fill_sprom(out, NULL, false); | ||||
| 		} | ||||
| 		return 0; | ||||
| 	default: | ||||
| 		pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * On bcm47xx we need to register SPROM fallback handler very early, so we can't | ||||
|  * use anything like platform device / driver for this. | ||||
|  */ | ||||
| void bcm47xx_sprom_register_fallbacks(void) | ||||
| { | ||||
| #if defined(CONFIG_BCM47XX_SSB) | ||||
| 	if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) | ||||
| 		pr_warn("Failed to registered ssb SPROM handler\n"); | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_BCM47XX_BCMA) | ||||
| 	if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) | ||||
| 		pr_warn("Failed to registered bcma SPROM handler\n"); | ||||
| #endif | ||||
| } | ||||
|  |  | |||
|  | @ -263,7 +263,7 @@ static unsigned int detect_memory_size(void) | |||
| 
 | ||||
| 	if (BCMCPU_IS_6345()) { | ||||
| 		val = bcm_sdram_readl(SDRAM_MBASE_REG); | ||||
| 		return (val * 8 * 1024 * 1024); | ||||
| 		return val * 8 * 1024 * 1024; | ||||
| 	} | ||||
| 
 | ||||
| 	if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| dtb-$(CONFIG_BCM3384)			+= bcm93384wvg.dtb | ||||
| dtb-$(CONFIG_CAVIUM_OCTEON_SOC)		+= octeon_3xxx.dtb octeon_68xx.dtb | ||||
| dtb-$(CONFIG_DT_EASY50712)		+= easy50712.dtb | ||||
| dtb-$(CONFIG_DT_XLP_EVP)		+= xlp_evp.dtb | ||||
|  |  | |||
							
								
								
									
										109
									
								
								arch/mips/boot/dts/bcm3384.dtsi
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								arch/mips/boot/dts/bcm3384.dtsi
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,109 @@ | |||
| / { | ||||
| 	#address-cells = <1>; | ||||
| 	#size-cells = <1>; | ||||
| 	compatible = "brcm,bcm3384", "brcm,bcm33843"; | ||||
| 
 | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 
 | ||||
| 		/* On BMIPS5000 this is 1/8th of the CPU core clock */ | ||||
| 		mips-hpt-frequency = <100000000>; | ||||
| 
 | ||||
| 		cpu@0 { | ||||
| 			compatible = "brcm,bmips5000"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <0>; | ||||
| 		}; | ||||
| 
 | ||||
| 		cpu@1 { | ||||
| 			compatible = "brcm,bmips5000"; | ||||
| 			device_type = "cpu"; | ||||
| 			reg = <1>; | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 	clocks { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 
 | ||||
| 		periph_clk: periph_clk@0 { | ||||
| 			compatible = "fixed-clock"; | ||||
| 			#clock-cells = <0>; | ||||
| 			clock-frequency = <54000000>; | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 	aliases { | ||||
| 		uart0 = &uart0; | ||||
| 	}; | ||||
| 
 | ||||
| 	cpu_intc: cpu_intc@0 { | ||||
| 		#address-cells = <0>; | ||||
| 		compatible = "mti,cpu-interrupt-controller"; | ||||
| 
 | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 	}; | ||||
| 
 | ||||
| 	periph_intc: periph_intc@14e00038 { | ||||
| 		compatible = "brcm,bcm3384-intc"; | ||||
| 		reg = <0x14e00038 0x8 0x14e00340 0x8>; | ||||
| 
 | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 
 | ||||
| 		interrupt-parent = <&cpu_intc>; | ||||
| 		interrupts = <4>; | ||||
| 	}; | ||||
| 
 | ||||
| 	zmips_intc: zmips_intc@104b0060 { | ||||
| 		compatible = "brcm,bcm3384-intc"; | ||||
| 		reg = <0x104b0060 0x8>; | ||||
| 
 | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 
 | ||||
| 		interrupt-parent = <&periph_intc>; | ||||
| 		interrupts = <29>; | ||||
| 	}; | ||||
| 
 | ||||
| 	iop_intc: iop_intc@14e00058 { | ||||
| 		compatible = "brcm,bcm3384-intc"; | ||||
| 		reg = <0x14e00058 0x8>; | ||||
| 
 | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <1>; | ||||
| 
 | ||||
| 		interrupt-parent = <&cpu_intc>; | ||||
| 		interrupts = <6>; | ||||
| 	}; | ||||
| 
 | ||||
| 	uart0: serial@14e00520 { | ||||
| 		compatible = "brcm,bcm6345-uart"; | ||||
| 		reg = <0x14e00520 0x18>; | ||||
| 		interrupt-parent = <&periph_intc>; | ||||
| 		interrupts = <2>; | ||||
| 		clocks = <&periph_clk>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
| 
 | ||||
| 	ehci0: usb@15400300 { | ||||
| 		compatible = "brcm,bcm3384-ehci", "generic-ehci"; | ||||
| 		reg = <0x15400300 0x100>; | ||||
| 		big-endian; | ||||
| 		interrupt-parent = <&periph_intc>; | ||||
| 		interrupts = <41>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
| 
 | ||||
| 	ohci0: usb@15400400 { | ||||
| 		compatible = "brcm,bcm3384-ohci", "generic-ohci"; | ||||
| 		reg = <0x15400400 0x100>; | ||||
| 		big-endian; | ||||
| 		no-big-frame-no; | ||||
| 		interrupt-parent = <&periph_intc>; | ||||
| 		interrupts = <40>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										32
									
								
								arch/mips/boot/dts/bcm93384wvg.dts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								arch/mips/boot/dts/bcm93384wvg.dts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| /dts-v1/; | ||||
| 
 | ||||
| /include/ "bcm3384.dtsi" | ||||
| 
 | ||||
| / { | ||||
| 	compatible = "brcm,bcm93384wvg", "brcm,bcm3384"; | ||||
| 	model = "Broadcom BCM93384WVG"; | ||||
| 
 | ||||
| 	chosen { | ||||
| 		bootargs = "console=ttyS0,115200"; | ||||
| 		stdout-path = &uart0; | ||||
| 	}; | ||||
| 
 | ||||
| 	memory@0 { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0x0 0x04000000>; | ||||
| 		dma-xor-mask = <0x08000000>; | ||||
| 		dma-xor-limit = <0x0fffffff>; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
| 
 | ||||
| &ehci0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
| 
 | ||||
| &ohci0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | @ -262,8 +262,8 @@ char *octeon_swiotlb; | |||
| void __init plat_swiotlb_setup(void) | ||||
| { | ||||
| 	int i; | ||||
| 	phys_t max_addr; | ||||
| 	phys_t addr_size; | ||||
| 	phys_addr_t max_addr; | ||||
| 	phys_addr_t addr_size; | ||||
| 	size_t swiotlbsize; | ||||
| 	unsigned long swiotlb_nslabs; | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,22 +28,23 @@ | |||
| #include <asm/octeon/octeon.h> | ||||
| 
 | ||||
| /**
 | ||||
|  * Given the chip processor ID from COP0, this function returns a | ||||
|  * string representing the chip model number. The string is of the | ||||
|  * form CNXXXXpX.X-FREQ-SUFFIX. | ||||
|  * - XXXX = The chip model number | ||||
|  * - X.X = Chip pass number | ||||
|  * - FREQ = Current frequency in Mhz | ||||
|  * - SUFFIX = NSP, EXP, SCP, SSP, or CP | ||||
|  * Read a byte of fuse data | ||||
|  * @byte_addr:	 address to read | ||||
|  * | ||||
|  * @chip_id: Chip ID | ||||
|  * | ||||
|  * Returns Model string | ||||
|  * Returns fuse value: 0 or 1 | ||||
|  */ | ||||
| const char *octeon_model_get_string(uint32_t chip_id) | ||||
| static uint8_t __init cvmx_fuse_read_byte(int byte_addr) | ||||
| { | ||||
| 	static char buffer[32]; | ||||
| 	return octeon_model_get_string_buffer(chip_id, buffer); | ||||
| 	union cvmx_mio_fus_rcmd read_cmd; | ||||
| 
 | ||||
| 	read_cmd.u64 = 0; | ||||
| 	read_cmd.s.addr = byte_addr; | ||||
| 	read_cmd.s.pend = 1; | ||||
| 	cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); | ||||
| 	while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) | ||||
| 	       && read_cmd.s.pend) | ||||
| 		; | ||||
| 	return read_cmd.s.dat; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -51,7 +52,8 @@ const char *octeon_model_get_string(uint32_t chip_id) | |||
|  * as running early in u-boot static/global variables don't work when | ||||
|  * running from flash. | ||||
|  */ | ||||
| const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) | ||||
| static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, | ||||
| 							 char *buffer) | ||||
| { | ||||
| 	const char *family; | ||||
| 	const char *core_model; | ||||
|  | @ -407,3 +409,22 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) | |||
| 	sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); | ||||
| 	return buffer; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Given the chip processor ID from COP0, this function returns a | ||||
|  * string representing the chip model number. The string is of the | ||||
|  * form CNXXXXpX.X-FREQ-SUFFIX. | ||||
|  * - XXXX = The chip model number | ||||
|  * - X.X = Chip pass number | ||||
|  * - FREQ = Current frequency in Mhz | ||||
|  * - SUFFIX = NSP, EXP, SCP, SSP, or CP | ||||
|  * | ||||
|  * @chip_id: Chip ID | ||||
|  * | ||||
|  * Returns Model string | ||||
|  */ | ||||
| const char *__init octeon_model_get_string(uint32_t chip_id) | ||||
| { | ||||
| 	static char buffer[32]; | ||||
| 	return octeon_model_get_string_buffer(chip_id, buffer); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										78
									
								
								arch/mips/configs/bcm3384_defconfig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								arch/mips/configs/bcm3384_defconfig
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,78 @@ | |||
| CONFIG_BCM3384=y | ||||
| CONFIG_HIGHMEM=y | ||||
| CONFIG_SMP=y | ||||
| CONFIG_NR_CPUS=4 | ||||
| # CONFIG_SECCOMP is not set | ||||
| CONFIG_MIPS_O32_FP64_SUPPORT=y | ||||
| # CONFIG_LOCALVERSION_AUTO is not set | ||||
| # CONFIG_SWAP is not set | ||||
| CONFIG_NO_HZ=y | ||||
| CONFIG_BLK_DEV_INITRD=y | ||||
| # CONFIG_RD_GZIP is not set | ||||
| CONFIG_EXPERT=y | ||||
| # CONFIG_VM_EVENT_COUNTERS is not set | ||||
| # CONFIG_SLUB_DEBUG is not set | ||||
| # CONFIG_BLK_DEV_BSG is not set | ||||
| # CONFIG_IOSCHED_DEADLINE is not set | ||||
| # CONFIG_IOSCHED_CFQ is not set | ||||
| CONFIG_NET=y | ||||
| CONFIG_PACKET=y | ||||
| CONFIG_PACKET_DIAG=y | ||||
| CONFIG_UNIX=y | ||||
| CONFIG_INET=y | ||||
| # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||||
| # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||||
| # CONFIG_INET_XFRM_MODE_BEET is not set | ||||
| # CONFIG_INET_LRO is not set | ||||
| # CONFIG_INET_DIAG is not set | ||||
| CONFIG_CFG80211=y | ||||
| CONFIG_NL80211_TESTMODE=y | ||||
| CONFIG_MAC80211=y | ||||
| CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||||
| CONFIG_DEVTMPFS=y | ||||
| CONFIG_DEVTMPFS_MOUNT=y | ||||
| # CONFIG_STANDALONE is not set | ||||
| # CONFIG_PREVENT_FIRMWARE_BUILD is not set | ||||
| CONFIG_MTD=y | ||||
| CONFIG_MTD_CFI=y | ||||
| CONFIG_MTD_CFI_INTELEXT=y | ||||
| CONFIG_MTD_CFI_AMDSTD=y | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| # CONFIG_BLK_DEV is not set | ||||
| CONFIG_SCSI=y | ||||
| CONFIG_BLK_DEV_SD=y | ||||
| # CONFIG_SCSI_LOWLEVEL is not set | ||||
| CONFIG_NETDEVICES=y | ||||
| CONFIG_USB_USBNET=y | ||||
| # CONFIG_INPUT is not set | ||||
| # CONFIG_SERIO is not set | ||||
| # CONFIG_VT is not set | ||||
| # CONFIG_DEVKMEM is not set | ||||
| CONFIG_SERIAL_EARLYCON_FORCE=y | ||||
| CONFIG_SERIAL_BCM63XX=y | ||||
| CONFIG_SERIAL_BCM63XX_CONSOLE=y | ||||
| # CONFIG_HW_RANDOM is not set | ||||
| # CONFIG_HWMON is not set | ||||
| CONFIG_USB=y | ||||
| CONFIG_USB_EHCI_HCD=y | ||||
| # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||||
| CONFIG_USB_EHCI_HCD_PLATFORM=y | ||||
| CONFIG_USB_OHCI_HCD=y | ||||
| CONFIG_USB_OHCI_HCD_PLATFORM=y | ||||
| CONFIG_USB_STORAGE=y | ||||
| CONFIG_EXT4_FS=y | ||||
| CONFIG_EXT4_FS_POSIX_ACL=y | ||||
| CONFIG_EXT4_FS_SECURITY=y | ||||
| # CONFIG_DNOTIFY is not set | ||||
| CONFIG_FUSE_FS=y | ||||
| CONFIG_VFAT_FS=y | ||||
| CONFIG_PROC_KCORE=y | ||||
| CONFIG_TMPFS=y | ||||
| CONFIG_NFS_FS=y | ||||
| CONFIG_CIFS=y | ||||
| CONFIG_NLS_CODEPAGE_437=y | ||||
| CONFIG_NLS_ASCII=y | ||||
| CONFIG_NLS_ISO8859_1=y | ||||
| CONFIG_DEBUG_FS=y | ||||
| CONFIG_MAGIC_SYSRQ=y | ||||
| # CONFIG_CRYPTO_HW is not set | ||||
|  | @ -68,7 +68,7 @@ char *fw_getenv(char *envname) | |||
| 					result = fw_envp(index + 1); | ||||
| 					break; | ||||
| 				} else if (fw_envp(index)[i] == '=') { | ||||
| 					result = (fw_envp(index + 1) + i); | ||||
| 					result = fw_envp(index) + i + 1; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
|  | @ -88,13 +88,13 @@ unsigned long fw_getenvl(char *envname) | |||
| { | ||||
| 	unsigned long envl = 0UL; | ||||
| 	char *str; | ||||
| 	long val; | ||||
| 	int tmp; | ||||
| 
 | ||||
| 	str = fw_getenv(envname); | ||||
| 	if (str) { | ||||
| 		tmp = kstrtol(str, 0, &val); | ||||
| 		envl = (unsigned long)val; | ||||
| 		tmp = kstrtoul(str, 0, &envl); | ||||
| 		if (tmp) | ||||
| 			envl = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return envl; | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| #include <linux/irqflags.h> | ||||
| #include <linux/types.h> | ||||
| #include <asm/barrier.h> | ||||
| #include <asm/compiler.h> | ||||
| #include <asm/cpu-features.h> | ||||
| #include <asm/cmpxchg.h> | ||||
| #include <asm/war.h> | ||||
|  | @ -40,95 +41,97 @@ | |||
|  */ | ||||
| #define atomic_set(v, i)		((v)->counter = (i)) | ||||
| 
 | ||||
| #define ATOMIC_OP(op, c_op, asm_op)						\ | ||||
| static __inline__ void atomic_##op(int i, atomic_t * v)				\ | ||||
| {										\ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {				\ | ||||
| 		int temp;							\ | ||||
| 										\ | ||||
| 		__asm__ __volatile__(						\ | ||||
| 		"	.set	arch=r4000				\n"	\ | ||||
| 		"1:	ll	%0, %1		# atomic_" #op "	\n"	\ | ||||
| 		"	" #asm_op " %0, %2				\n"	\ | ||||
| 		"	sc	%0, %1					\n"	\ | ||||
| 		"	beqzl	%0, 1b					\n"	\ | ||||
| 		"	.set	mips0					\n"	\ | ||||
| 		: "=&r" (temp), "+m" (v->counter)				\ | ||||
| 		: "Ir" (i));							\ | ||||
| 	} else if (kernel_uses_llsc) {						\ | ||||
| 		int temp;							\ | ||||
| 										\ | ||||
| 		do {								\ | ||||
| 			__asm__ __volatile__(					\ | ||||
| 			"	.set	arch=r4000			\n"	\ | ||||
| 			"	ll	%0, %1		# atomic_" #op "\n"	\ | ||||
| 			"	" #asm_op " %0, %2			\n"	\ | ||||
| 			"	sc	%0, %1				\n"	\ | ||||
| 			"	.set	mips0				\n"	\ | ||||
| 			: "=&r" (temp), "+m" (v->counter)			\ | ||||
| 			: "Ir" (i));						\ | ||||
| 		} while (unlikely(!temp));					\ | ||||
| 	} else {								\ | ||||
| 		unsigned long flags;						\ | ||||
| 										\ | ||||
| 		raw_local_irq_save(flags);					\ | ||||
| 		v->counter c_op i;						\ | ||||
| 		raw_local_irq_restore(flags);					\ | ||||
| 	}									\ | ||||
| }										\ | ||||
| 
 | ||||
| #define ATOMIC_OP_RETURN(op, c_op, asm_op)					\ | ||||
| static __inline__ int atomic_##op##_return(int i, atomic_t * v)			\ | ||||
| {										\ | ||||
| 	int result;								\ | ||||
| 										\ | ||||
| 	smp_mb__before_llsc();							\ | ||||
| 										\ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {				\ | ||||
| 		int temp;							\ | ||||
| 										\ | ||||
| 		__asm__ __volatile__(						\ | ||||
| 		"	.set	arch=r4000				\n"	\ | ||||
| 		"1:	ll	%1, %2		# atomic_" #op "_return	\n"	\ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"	\ | ||||
| 		"	sc	%0, %2					\n"	\ | ||||
| 		"	beqzl	%0, 1b					\n"	\ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"	\ | ||||
| 		"	.set	mips0					\n"	\ | ||||
| 		: "=&r" (result), "=&r" (temp), "+m" (v->counter)		\ | ||||
| 		: "Ir" (i));							\ | ||||
| 	} else if (kernel_uses_llsc) {						\ | ||||
| 		int temp;							\ | ||||
| 										\ | ||||
| 		do {								\ | ||||
| 			__asm__ __volatile__(					\ | ||||
| 			"	.set	arch=r4000			\n"	\ | ||||
| 			"	ll	%1, %2	# atomic_" #op "_return	\n"	\ | ||||
| 			"	" #asm_op " %0, %1, %3			\n"	\ | ||||
| 			"	sc	%0, %2				\n"	\ | ||||
| 			"	.set	mips0				\n"	\ | ||||
| 			: "=&r" (result), "=&r" (temp), "+m" (v->counter)	\ | ||||
| 			: "Ir" (i));						\ | ||||
| 		} while (unlikely(!result));					\ | ||||
| 										\ | ||||
| 		result = temp; result c_op i;					\ | ||||
| 	} else {								\ | ||||
| 		unsigned long flags;						\ | ||||
| 										\ | ||||
| 		raw_local_irq_save(flags);					\ | ||||
| 		result = v->counter;						\ | ||||
| 		result c_op i;							\ | ||||
| 		v->counter = result;						\ | ||||
| 		raw_local_irq_restore(flags);					\ | ||||
| 	}									\ | ||||
| 										\ | ||||
| 	smp_llsc_mb();								\ | ||||
| 										\ | ||||
| 	return result;								\ | ||||
| #define ATOMIC_OP(op, c_op, asm_op)					      \ | ||||
| static __inline__ void atomic_##op(int i, atomic_t * v)			      \ | ||||
| {									      \ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {			      \ | ||||
| 		int temp;						      \ | ||||
| 									      \ | ||||
| 		__asm__ __volatile__(					      \ | ||||
| 		"	.set	arch=r4000				\n"   \ | ||||
| 		"1:	ll	%0, %1		# atomic_" #op "	\n"   \ | ||||
| 		"	" #asm_op " %0, %2				\n"   \ | ||||
| 		"	sc	%0, %1					\n"   \ | ||||
| 		"	beqzl	%0, 1b					\n"   \ | ||||
| 		"	.set	mips0					\n"   \ | ||||
| 		: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter)	      \ | ||||
| 		: "Ir" (i));						      \ | ||||
| 	} else if (kernel_uses_llsc) {					      \ | ||||
| 		int temp;						      \ | ||||
| 									      \ | ||||
| 		do {							      \ | ||||
| 			__asm__ __volatile__(				      \ | ||||
| 			"	.set	arch=r4000			\n"   \ | ||||
| 			"	ll	%0, %1		# atomic_" #op "\n"   \ | ||||
| 			"	" #asm_op " %0, %2			\n"   \ | ||||
| 			"	sc	%0, %1				\n"   \ | ||||
| 			"	.set	mips0				\n"   \ | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter)      \ | ||||
| 			: "Ir" (i));					      \ | ||||
| 		} while (unlikely(!temp));				      \ | ||||
| 	} else {							      \ | ||||
| 		unsigned long flags;					      \ | ||||
| 									      \ | ||||
| 		raw_local_irq_save(flags);				      \ | ||||
| 		v->counter c_op i;					      \ | ||||
| 		raw_local_irq_restore(flags);				      \ | ||||
| 	}								      \ | ||||
| } | ||||
| 
 | ||||
| #define ATOMIC_OPS(op, c_op, asm_op)						\ | ||||
| 	ATOMIC_OP(op, c_op, asm_op)						\ | ||||
| #define ATOMIC_OP_RETURN(op, c_op, asm_op)				      \ | ||||
| static __inline__ int atomic_##op##_return(int i, atomic_t * v)		      \ | ||||
| {									      \ | ||||
| 	int result;							      \ | ||||
| 									      \ | ||||
| 	smp_mb__before_llsc();						      \ | ||||
| 									      \ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {			      \ | ||||
| 		int temp;						      \ | ||||
| 									      \ | ||||
| 		__asm__ __volatile__(					      \ | ||||
| 		"	.set	arch=r4000				\n"   \ | ||||
| 		"1:	ll	%1, %2		# atomic_" #op "_return	\n"   \ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"   \ | ||||
| 		"	sc	%0, %2					\n"   \ | ||||
| 		"	beqzl	%0, 1b					\n"   \ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"   \ | ||||
| 		"	.set	mips0					\n"   \ | ||||
| 		: "=&r" (result), "=&r" (temp),				      \ | ||||
| 		  "+" GCC_OFF12_ASM() (v->counter)			      \ | ||||
| 		: "Ir" (i));						      \ | ||||
| 	} else if (kernel_uses_llsc) {					      \ | ||||
| 		int temp;						      \ | ||||
| 									      \ | ||||
| 		do {							      \ | ||||
| 			__asm__ __volatile__(				      \ | ||||
| 			"	.set	arch=r4000			\n"   \ | ||||
| 			"	ll	%1, %2	# atomic_" #op "_return	\n"   \ | ||||
| 			"	" #asm_op " %0, %1, %3			\n"   \ | ||||
| 			"	sc	%0, %2				\n"   \ | ||||
| 			"	.set	mips0				\n"   \ | ||||
| 			: "=&r" (result), "=&r" (temp),			      \ | ||||
| 			  "+" GCC_OFF12_ASM() (v->counter)		      \ | ||||
| 			: "Ir" (i));					      \ | ||||
| 		} while (unlikely(!result));				      \ | ||||
| 									      \ | ||||
| 		result = temp; result c_op i;				      \ | ||||
| 	} else {							      \ | ||||
| 		unsigned long flags;					      \ | ||||
| 									      \ | ||||
| 		raw_local_irq_save(flags);				      \ | ||||
| 		result = v->counter;					      \ | ||||
| 		result c_op i;						      \ | ||||
| 		v->counter = result;					      \ | ||||
| 		raw_local_irq_restore(flags);				      \ | ||||
| 	}								      \ | ||||
| 									      \ | ||||
| 	smp_llsc_mb();							      \ | ||||
| 									      \ | ||||
| 	return result;							      \ | ||||
| } | ||||
| 
 | ||||
| #define ATOMIC_OPS(op, c_op, asm_op)					      \ | ||||
| 	ATOMIC_OP(op, c_op, asm_op)					      \ | ||||
| 	ATOMIC_OP_RETURN(op, c_op, asm_op) | ||||
| 
 | ||||
| ATOMIC_OPS(add, +=, addu) | ||||
|  | @ -167,8 +170,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
| 		"	.set	reorder					\n" | ||||
| 		"1:							\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (result), "=&r" (temp), "+m" (v->counter) | ||||
| 		: "Ir" (i), "m" (v->counter) | ||||
| 		: "=&r" (result), "=&r" (temp), | ||||
| 		  "+" GCC_OFF12_ASM() (v->counter) | ||||
| 		: "Ir" (i), GCC_OFF12_ASM() (v->counter) | ||||
| 		: "memory"); | ||||
| 	} else if (kernel_uses_llsc) { | ||||
| 		int temp; | ||||
|  | @ -185,7 +189,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
| 		"	.set	reorder					\n" | ||||
| 		"1:							\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (result), "=&r" (temp), "+m" (v->counter) | ||||
| 		: "=&r" (result), "=&r" (temp), | ||||
| 		  "+" GCC_OFF12_ASM() (v->counter) | ||||
| 		: "Ir" (i)); | ||||
| 	} else { | ||||
| 		unsigned long flags; | ||||
|  | @ -315,96 +320,98 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
|  */ | ||||
| #define atomic64_set(v, i)	((v)->counter = (i)) | ||||
| 
 | ||||
| #define ATOMIC64_OP(op, c_op, asm_op)						\ | ||||
| static __inline__ void atomic64_##op(long i, atomic64_t * v)			\ | ||||
| {										\ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {				\ | ||||
| 		long temp;							\ | ||||
| 										\ | ||||
| 		__asm__ __volatile__(						\ | ||||
| 		"	.set	arch=r4000				\n"	\ | ||||
| 		"1:	lld	%0, %1		# atomic64_" #op "	\n"	\ | ||||
| 		"	" #asm_op " %0, %2				\n"	\ | ||||
| 		"	scd	%0, %1					\n"	\ | ||||
| 		"	beqzl	%0, 1b					\n"	\ | ||||
| 		"	.set	mips0					\n"	\ | ||||
| 		: "=&r" (temp), "+m" (v->counter)				\ | ||||
| 		: "Ir" (i));							\ | ||||
| 	} else if (kernel_uses_llsc) {						\ | ||||
| 		long temp;							\ | ||||
| 										\ | ||||
| 		do {								\ | ||||
| 			__asm__ __volatile__(					\ | ||||
| 			"	.set	arch=r4000			\n"	\ | ||||
| 			"	lld	%0, %1		# atomic64_" #op "\n"	\ | ||||
| 			"	" #asm_op " %0, %2			\n"	\ | ||||
| 			"	scd	%0, %1				\n"	\ | ||||
| 			"	.set	mips0				\n"	\ | ||||
| 			: "=&r" (temp), "+m" (v->counter)			\ | ||||
| 			: "Ir" (i));						\ | ||||
| 		} while (unlikely(!temp));					\ | ||||
| 	} else {								\ | ||||
| 		unsigned long flags;						\ | ||||
| 										\ | ||||
| 		raw_local_irq_save(flags);					\ | ||||
| 		v->counter c_op i;						\ | ||||
| 		raw_local_irq_restore(flags);					\ | ||||
| 	}									\ | ||||
| }										\ | ||||
| 
 | ||||
| #define ATOMIC64_OP_RETURN(op, c_op, asm_op)					\ | ||||
| static __inline__ long atomic64_##op##_return(long i, atomic64_t * v)		\ | ||||
| {										\ | ||||
| 	long result;								\ | ||||
| 										\ | ||||
| 	smp_mb__before_llsc();							\ | ||||
| 										\ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {				\ | ||||
| 		long temp;							\ | ||||
| 										\ | ||||
| 		__asm__ __volatile__(						\ | ||||
| 		"	.set	arch=r4000				\n"	\ | ||||
| 		"1:	lld	%1, %2		# atomic64_" #op "_return\n"	\ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"	\ | ||||
| 		"	scd	%0, %2					\n"	\ | ||||
| 		"	beqzl	%0, 1b					\n"	\ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"	\ | ||||
| 		"	.set	mips0					\n"	\ | ||||
| 		: "=&r" (result), "=&r" (temp), "+m" (v->counter)		\ | ||||
| 		: "Ir" (i));							\ | ||||
| 	} else if (kernel_uses_llsc) {						\ | ||||
| 		long temp;							\ | ||||
| 										\ | ||||
| 		do {								\ | ||||
| 			__asm__ __volatile__(					\ | ||||
| 			"	.set	arch=r4000			\n"	\ | ||||
| 			"	lld	%1, %2	# atomic64_" #op "_return\n"	\ | ||||
| 			"	" #asm_op " %0, %1, %3			\n"	\ | ||||
| 			"	scd	%0, %2				\n"	\ | ||||
| 			"	.set	mips0				\n"	\ | ||||
| 			: "=&r" (result), "=&r" (temp), "=m" (v->counter)	\ | ||||
| 			: "Ir" (i), "m" (v->counter)				\ | ||||
| 			: "memory");						\ | ||||
| 		} while (unlikely(!result));					\ | ||||
| 										\ | ||||
| 		result = temp; result c_op i;					\ | ||||
| 	} else {								\ | ||||
| 		unsigned long flags;						\ | ||||
| 										\ | ||||
| 		raw_local_irq_save(flags);					\ | ||||
| 		result = v->counter;						\ | ||||
| 		result c_op i;							\ | ||||
| 		v->counter = result;						\ | ||||
| 		raw_local_irq_restore(flags);					\ | ||||
| 	}									\ | ||||
| 										\ | ||||
| 	smp_llsc_mb();								\ | ||||
| 										\ | ||||
| 	return result;								\ | ||||
| #define ATOMIC64_OP(op, c_op, asm_op)					      \ | ||||
| static __inline__ void atomic64_##op(long i, atomic64_t * v)		      \ | ||||
| {									      \ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {			      \ | ||||
| 		long temp;						      \ | ||||
| 									      \ | ||||
| 		__asm__ __volatile__(					      \ | ||||
| 		"	.set	arch=r4000				\n"   \ | ||||
| 		"1:	lld	%0, %1		# atomic64_" #op "	\n"   \ | ||||
| 		"	" #asm_op " %0, %2				\n"   \ | ||||
| 		"	scd	%0, %1					\n"   \ | ||||
| 		"	beqzl	%0, 1b					\n"   \ | ||||
| 		"	.set	mips0					\n"   \ | ||||
| 		: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter)	      \ | ||||
| 		: "Ir" (i));						      \ | ||||
| 	} else if (kernel_uses_llsc) {					      \ | ||||
| 		long temp;						      \ | ||||
| 									      \ | ||||
| 		do {							      \ | ||||
| 			__asm__ __volatile__(				      \ | ||||
| 			"	.set	arch=r4000			\n"   \ | ||||
| 			"	lld	%0, %1		# atomic64_" #op "\n" \ | ||||
| 			"	" #asm_op " %0, %2			\n"   \ | ||||
| 			"	scd	%0, %1				\n"   \ | ||||
| 			"	.set	mips0				\n"   \ | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter)      \ | ||||
| 			: "Ir" (i));					      \ | ||||
| 		} while (unlikely(!temp));				      \ | ||||
| 	} else {							      \ | ||||
| 		unsigned long flags;					      \ | ||||
| 									      \ | ||||
| 		raw_local_irq_save(flags);				      \ | ||||
| 		v->counter c_op i;					      \ | ||||
| 		raw_local_irq_restore(flags);				      \ | ||||
| 	}								      \ | ||||
| } | ||||
| 
 | ||||
| #define ATOMIC64_OPS(op, c_op, asm_op)						\ | ||||
| 	ATOMIC64_OP(op, c_op, asm_op)						\ | ||||
| #define ATOMIC64_OP_RETURN(op, c_op, asm_op)				      \ | ||||
| static __inline__ long atomic64_##op##_return(long i, atomic64_t * v)	      \ | ||||
| {									      \ | ||||
| 	long result;							      \ | ||||
| 									      \ | ||||
| 	smp_mb__before_llsc();						      \ | ||||
| 									      \ | ||||
| 	if (kernel_uses_llsc && R10000_LLSC_WAR) {			      \ | ||||
| 		long temp;						      \ | ||||
| 									      \ | ||||
| 		__asm__ __volatile__(					      \ | ||||
| 		"	.set	arch=r4000				\n"   \ | ||||
| 		"1:	lld	%1, %2		# atomic64_" #op "_return\n"  \ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"   \ | ||||
| 		"	scd	%0, %2					\n"   \ | ||||
| 		"	beqzl	%0, 1b					\n"   \ | ||||
| 		"	" #asm_op " %0, %1, %3				\n"   \ | ||||
| 		"	.set	mips0					\n"   \ | ||||
| 		: "=&r" (result), "=&r" (temp),				      \ | ||||
| 		  "+" GCC_OFF12_ASM() (v->counter)			      \ | ||||
| 		: "Ir" (i));						      \ | ||||
| 	} else if (kernel_uses_llsc) {					      \ | ||||
| 		long temp;						      \ | ||||
| 									      \ | ||||
| 		do {							      \ | ||||
| 			__asm__ __volatile__(				      \ | ||||
| 			"	.set	arch=r4000			\n"   \ | ||||
| 			"	lld	%1, %2	# atomic64_" #op "_return\n"  \ | ||||
| 			"	" #asm_op " %0, %1, %3			\n"   \ | ||||
| 			"	scd	%0, %2				\n"   \ | ||||
| 			"	.set	mips0				\n"   \ | ||||
| 			: "=&r" (result), "=&r" (temp),			      \ | ||||
| 			  "=" GCC_OFF12_ASM() (v->counter)		      \ | ||||
| 			: "Ir" (i), GCC_OFF12_ASM() (v->counter)	      \ | ||||
| 			: "memory");					      \ | ||||
| 		} while (unlikely(!result));				      \ | ||||
| 									      \ | ||||
| 		result = temp; result c_op i;				      \ | ||||
| 	} else {							      \ | ||||
| 		unsigned long flags;					      \ | ||||
| 									      \ | ||||
| 		raw_local_irq_save(flags);				      \ | ||||
| 		result = v->counter;					      \ | ||||
| 		result c_op i;						      \ | ||||
| 		v->counter = result;					      \ | ||||
| 		raw_local_irq_restore(flags);				      \ | ||||
| 	}								      \ | ||||
| 									      \ | ||||
| 	smp_llsc_mb();							      \ | ||||
| 									      \ | ||||
| 	return result;							      \ | ||||
| } | ||||
| 
 | ||||
| #define ATOMIC64_OPS(op, c_op, asm_op)					      \ | ||||
| 	ATOMIC64_OP(op, c_op, asm_op)					      \ | ||||
| 	ATOMIC64_OP_RETURN(op, c_op, asm_op) | ||||
| 
 | ||||
| ATOMIC64_OPS(add, +=, daddu) | ||||
|  | @ -415,7 +422,8 @@ ATOMIC64_OPS(sub, -=, dsubu) | |||
| #undef ATOMIC64_OP | ||||
| 
 | ||||
| /*
 | ||||
|  * atomic64_sub_if_positive - conditionally subtract integer from atomic variable | ||||
|  * atomic64_sub_if_positive - conditionally subtract integer from atomic | ||||
|  *                            variable | ||||
|  * @i: integer value to subtract | ||||
|  * @v: pointer of type atomic64_t | ||||
|  * | ||||
|  | @ -443,8 +451,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
| 		"	.set	reorder					\n" | ||||
| 		"1:							\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (result), "=&r" (temp), "=m" (v->counter) | ||||
| 		: "Ir" (i), "m" (v->counter) | ||||
| 		: "=&r" (result), "=&r" (temp), | ||||
| 		  "=" GCC_OFF12_ASM() (v->counter) | ||||
| 		: "Ir" (i), GCC_OFF12_ASM() (v->counter) | ||||
| 		: "memory"); | ||||
| 	} else if (kernel_uses_llsc) { | ||||
| 		long temp; | ||||
|  | @ -461,7 +470,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
| 		"	.set	reorder					\n" | ||||
| 		"1:							\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (result), "=&r" (temp), "+m" (v->counter) | ||||
| 		: "=&r" (result), "=&r" (temp), | ||||
| 		  "+" GCC_OFF12_ASM() (v->counter) | ||||
| 		: "Ir" (i)); | ||||
| 	} else { | ||||
| 		unsigned long flags; | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| #include <linux/types.h> | ||||
| #include <asm/barrier.h> | ||||
| #include <asm/byteorder.h>		/* sigh ... */ | ||||
| #include <asm/compiler.h> | ||||
| #include <asm/cpu-features.h> | ||||
| #include <asm/sgidefs.h> | ||||
| #include <asm/war.h> | ||||
|  | @ -78,8 +79,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 		"	" __SC	"%0, %1					\n" | ||||
| 		"	beqzl	%0, 1b					\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (temp), "=m" (*m) | ||||
| 		: "ir" (1UL << bit), "m" (*m)); | ||||
| 		: "=&r" (temp), "=" GCC_OFF12_ASM() (*m) | ||||
| 		: "ir" (1UL << bit), GCC_OFF12_ASM() (*m)); | ||||
| #ifdef CONFIG_CPU_MIPSR2 | ||||
| 	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) { | ||||
| 		do { | ||||
|  | @ -87,7 +88,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 			"	" __LL "%0, %1		# set_bit	\n" | ||||
| 			"	" __INS "%0, %3, %2, 1			\n" | ||||
| 			"	" __SC "%0, %1				\n" | ||||
| 			: "=&r" (temp), "+m" (*m) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m) | ||||
| 			: "ir" (bit), "r" (~0)); | ||||
| 		} while (unlikely(!temp)); | ||||
| #endif /* CONFIG_CPU_MIPSR2 */ | ||||
|  | @ -99,7 +100,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 			"	or	%0, %2				\n" | ||||
| 			"	" __SC	"%0, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (temp), "+m" (*m) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m) | ||||
| 			: "ir" (1UL << bit)); | ||||
| 		} while (unlikely(!temp)); | ||||
| 	} else | ||||
|  | @ -130,7 +131,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 		"	" __SC "%0, %1					\n" | ||||
| 		"	beqzl	%0, 1b					\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (temp), "+m" (*m) | ||||
| 		: "=&r" (temp), "+" GCC_OFF12_ASM() (*m) | ||||
| 		: "ir" (~(1UL << bit))); | ||||
| #ifdef CONFIG_CPU_MIPSR2 | ||||
| 	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) { | ||||
|  | @ -139,7 +140,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 			"	" __LL "%0, %1		# clear_bit	\n" | ||||
| 			"	" __INS "%0, $0, %2, 1			\n" | ||||
| 			"	" __SC "%0, %1				\n" | ||||
| 			: "=&r" (temp), "+m" (*m) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m) | ||||
| 			: "ir" (bit)); | ||||
| 		} while (unlikely(!temp)); | ||||
| #endif /* CONFIG_CPU_MIPSR2 */ | ||||
|  | @ -151,7 +152,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 			"	and	%0, %2				\n" | ||||
| 			"	" __SC "%0, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (temp), "+m" (*m) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m) | ||||
| 			: "ir" (~(1UL << bit))); | ||||
| 		} while (unlikely(!temp)); | ||||
| 	} else | ||||
|  | @ -196,7 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 		"	" __SC	"%0, %1				\n" | ||||
| 		"	beqzl	%0, 1b				\n" | ||||
| 		"	.set	mips0				\n" | ||||
| 		: "=&r" (temp), "+m" (*m) | ||||
| 		: "=&r" (temp), "+" GCC_OFF12_ASM() (*m) | ||||
| 		: "ir" (1UL << bit)); | ||||
| 	} else if (kernel_uses_llsc) { | ||||
| 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | ||||
|  | @ -209,7 +210,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 			"	xor	%0, %2				\n" | ||||
| 			"	" __SC	"%0, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (temp), "+m" (*m) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m) | ||||
| 			: "ir" (1UL << bit)); | ||||
| 		} while (unlikely(!temp)); | ||||
| 	} else | ||||
|  | @ -244,7 +245,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
| 		"	beqzl	%2, 1b					\n" | ||||
| 		"	and	%2, %0, %3				\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 		: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 		: "r" (1UL << bit) | ||||
| 		: "memory"); | ||||
| 	} else if (kernel_uses_llsc) { | ||||
|  | @ -258,7 +259,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
| 			"	or	%2, %0, %3			\n" | ||||
| 			"	" __SC	"%2, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 			: "r" (1UL << bit) | ||||
| 			: "memory"); | ||||
| 		} while (unlikely(!res)); | ||||
|  | @ -312,7 +313,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, | |||
| 			"	or	%2, %0, %3			\n" | ||||
| 			"	" __SC	"%2, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 			: "r" (1UL << bit) | ||||
| 			: "memory"); | ||||
| 		} while (unlikely(!res)); | ||||
|  | @ -354,7 +355,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 		"	beqzl	%2, 1b					\n" | ||||
| 		"	and	%2, %0, %3				\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 		: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 		: "r" (1UL << bit) | ||||
| 		: "memory"); | ||||
| #ifdef CONFIG_CPU_MIPSR2 | ||||
|  | @ -368,7 +369,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 			"	" __EXT "%2, %0, %3, 1			\n" | ||||
| 			"	" __INS "%0, $0, %3, 1			\n" | ||||
| 			"	" __SC	"%0, %1				\n" | ||||
| 			: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 			: "ir" (bit) | ||||
| 			: "memory"); | ||||
| 		} while (unlikely(!temp)); | ||||
|  | @ -385,7 +386,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 			"	xor	%2, %3				\n" | ||||
| 			"	" __SC	"%2, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 			: "r" (1UL << bit) | ||||
| 			: "memory"); | ||||
| 		} while (unlikely(!res)); | ||||
|  | @ -427,7 +428,7 @@ static inline int test_and_change_bit(unsigned long nr, | |||
| 		"	beqzl	%2, 1b					\n" | ||||
| 		"	and	%2, %0, %3				\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 		: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 		: "r" (1UL << bit) | ||||
| 		: "memory"); | ||||
| 	} else if (kernel_uses_llsc) { | ||||
|  | @ -441,7 +442,7 @@ static inline int test_and_change_bit(unsigned long nr, | |||
| 			"	xor	%2, %0, %3			\n" | ||||
| 			"	" __SC	"\t%2, %1			\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (temp), "+m" (*m), "=&r" (res) | ||||
| 			: "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) | ||||
| 			: "r" (1UL << bit) | ||||
| 			: "memory"); | ||||
| 		} while (unlikely(!res)); | ||||
|  |  | |||
|  | @ -84,6 +84,7 @@ extern char bmips_smp_int_vec_end; | |||
| extern int bmips_smp_enabled; | ||||
| extern int bmips_cpu_offset; | ||||
| extern cpumask_t bmips_booted_mask; | ||||
| extern unsigned long bmips_tp1_irqs; | ||||
| 
 | ||||
| extern void bmips_ebase_setup(void); | ||||
| extern asmlinkage void plat_wired_tlb_setup(void); | ||||
|  |  | |||
|  | @ -70,10 +70,7 @@ enum loongson_machine_type { | |||
| 	MACH_DEXXON_GDIUM2F10, | ||||
| 	MACH_LEMOTE_NAS, | ||||
| 	MACH_LEMOTE_LL2F, | ||||
| 	MACH_LEMOTE_A1004, | ||||
| 	MACH_LEMOTE_A1101, | ||||
| 	MACH_LEMOTE_A1201, | ||||
| 	MACH_LEMOTE_A1205, | ||||
| 	MACH_LOONGSON_GENERIC, | ||||
| 	MACH_LOONGSON_END | ||||
| }; | ||||
| 
 | ||||
|  | @ -101,16 +98,16 @@ extern unsigned long mips_machtype; | |||
| struct boot_mem_map { | ||||
| 	int nr_map; | ||||
| 	struct boot_mem_map_entry { | ||||
| 		phys_t addr;	/* start of memory segment */ | ||||
| 		phys_t size;	/* size of memory segment */ | ||||
| 		phys_addr_t addr;	/* start of memory segment */ | ||||
| 		phys_addr_t size;	/* size of memory segment */ | ||||
| 		long type;		/* type of memory segment */ | ||||
| 	} map[BOOT_MEM_MAP_MAX]; | ||||
| }; | ||||
| 
 | ||||
| extern struct boot_mem_map boot_mem_map; | ||||
| 
 | ||||
| extern void add_memory_region(phys_t start, phys_t size, long type); | ||||
| extern void detect_memory_region(phys_t start, phys_t sz_min,  phys_t sz_max); | ||||
| extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type); | ||||
| extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min,  phys_addr_t sz_max); | ||||
| 
 | ||||
| extern void prom_init(void); | ||||
| extern void prom_free_prom_memory(void); | ||||
|  |  | |||
|  | @ -35,9 +35,6 @@ struct clk { | |||
| #define CLK_ALWAYS_ENABLED	(1 << 0) | ||||
| #define CLK_RATE_PROPAGATES	(1 << 1) | ||||
| 
 | ||||
| /* Should be defined by processor-specific code */ | ||||
| void arch_init_clk_ops(struct clk_ops **, int type); | ||||
| 
 | ||||
| int clk_init(void); | ||||
| 
 | ||||
| int __clk_enable(struct clk *); | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| 
 | ||||
| #include <linux/bug.h> | ||||
| #include <linux/irqflags.h> | ||||
| #include <asm/compiler.h> | ||||
| #include <asm/war.h> | ||||
| 
 | ||||
| static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | ||||
|  | @ -30,8 +31,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
| 		"	sc	%2, %1					\n" | ||||
| 		"	beqzl	%2, 1b					\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (retval), "=m" (*m), "=&r" (dummy) | ||||
| 		: "R" (*m), "Jr" (val) | ||||
| 		: "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) | ||||
| 		: GCC_OFF12_ASM() (*m), "Jr" (val) | ||||
| 		: "memory"); | ||||
| 	} else if (kernel_uses_llsc) { | ||||
| 		unsigned long dummy; | ||||
|  | @ -45,8 +46,9 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
| 			"	.set	arch=r4000			\n" | ||||
| 			"	sc	%2, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (retval), "=m" (*m), "=&r" (dummy) | ||||
| 			: "R" (*m), "Jr" (val) | ||||
| 			: "=&r" (retval), "=" GCC_OFF12_ASM() (*m), | ||||
| 			  "=&r" (dummy) | ||||
| 			: GCC_OFF12_ASM() (*m), "Jr" (val) | ||||
| 			: "memory"); | ||||
| 		} while (unlikely(!dummy)); | ||||
| 	} else { | ||||
|  | @ -80,8 +82,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
| 		"	scd	%2, %1					\n" | ||||
| 		"	beqzl	%2, 1b					\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (retval), "=m" (*m), "=&r" (dummy) | ||||
| 		: "R" (*m), "Jr" (val) | ||||
| 		: "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) | ||||
| 		: GCC_OFF12_ASM() (*m), "Jr" (val) | ||||
| 		: "memory"); | ||||
| 	} else if (kernel_uses_llsc) { | ||||
| 		unsigned long dummy; | ||||
|  | @ -93,8 +95,9 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
| 			"	move	%2, %z4				\n" | ||||
| 			"	scd	%2, %1				\n" | ||||
| 			"	.set	mips0				\n" | ||||
| 			: "=&r" (retval), "=m" (*m), "=&r" (dummy) | ||||
| 			: "R" (*m), "Jr" (val) | ||||
| 			: "=&r" (retval), "=" GCC_OFF12_ASM() (*m), | ||||
| 			  "=&r" (dummy) | ||||
| 			: GCC_OFF12_ASM() (*m), "Jr" (val) | ||||
| 			: "memory"); | ||||
| 		} while (unlikely(!dummy)); | ||||
| 	} else { | ||||
|  | @ -155,8 +158,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
| 		"	beqzl	$1, 1b				\n"	\ | ||||
| 		"2:						\n"	\ | ||||
| 		"	.set	pop				\n"	\ | ||||
| 		: "=&r" (__ret), "=R" (*m)				\ | ||||
| 		: "R" (*m), "Jr" (old), "Jr" (new)			\ | ||||
| 		: "=&r" (__ret), "=" GCC_OFF12_ASM() (*m)		\ | ||||
| 		: GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new)		\ | ||||
| 		: "memory");						\ | ||||
| 	} else if (kernel_uses_llsc) {					\ | ||||
| 		__asm__ __volatile__(					\ | ||||
|  | @ -172,8 +175,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
| 		"	beqz	$1, 1b				\n"	\ | ||||
| 		"	.set	pop				\n"	\ | ||||
| 		"2:						\n"	\ | ||||
| 		: "=&r" (__ret), "=R" (*m)				\ | ||||
| 		: "R" (*m), "Jr" (old), "Jr" (new)			\ | ||||
| 		: "=&r" (__ret), "=" GCC_OFF12_ASM() (*m)		\ | ||||
| 		: GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new)		\ | ||||
| 		: "memory");						\ | ||||
| 	} else {							\ | ||||
| 		unsigned long __flags;					\ | ||||
|  |  | |||
|  | @ -16,4 +16,12 @@ | |||
| #define GCC_REG_ACCUM "accum" | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_CPU_MICROMIPS | ||||
| #define GCC_OFF12_ASM() "R" | ||||
| #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) | ||||
| #define GCC_OFF12_ASM() "ZC" | ||||
| #else | ||||
| #error "microMIPS compilation unsupported with GCC older than 4.9" | ||||
| #endif | ||||
| 
 | ||||
| #endif /* _ASM_COMPILER_H */ | ||||
|  |  | |||
|  | @ -344,4 +344,8 @@ | |||
| # define cpu_has_msa		0 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef cpu_has_fre | ||||
| # define cpu_has_fre		(cpu_data[0].options & MIPS_CPU_FRE) | ||||
| #endif | ||||
| 
 | ||||
| #endif /* __ASM_CPU_FEATURES_H */ | ||||
|  |  | |||
|  | @ -142,6 +142,7 @@ | |||
| #define PRID_IMP_BMIPS3300_BUG	0x0000 | ||||
| #define PRID_IMP_BMIPS43XX	0xa000 | ||||
| #define PRID_IMP_BMIPS5000	0x5a00 | ||||
| #define PRID_IMP_BMIPS5200	0x5b00 | ||||
| 
 | ||||
| #define PRID_REV_BMIPS4380_LO	0x0040 | ||||
| #define PRID_REV_BMIPS4380_HI	0x006f | ||||
|  | @ -368,6 +369,7 @@ enum cpu_type_enum { | |||
| #define MIPS_CPU_HTW		0x100000000ull /* CPU support Hardware Page Table Walker */ | ||||
| #define MIPS_CPU_RIXIEX		0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ | ||||
| #define MIPS_CPU_MAAR		0x400000000ull /* MAAR(I) registers are present */ | ||||
| #define MIPS_CPU_FRE		0x800000000ull /* FRE & UFE bits implemented */ | ||||
| 
 | ||||
| /*
 | ||||
|  * CPU ASE encodings | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #ifndef ASM_EDAC_H | ||||
| #define ASM_EDAC_H | ||||
| 
 | ||||
| #include <asm/compiler.h> | ||||
| 
 | ||||
| /* ECC atomic, DMA, SMP and interrupt safe scrub function */ | ||||
| 
 | ||||
| static inline void atomic_scrub(void *va, u32 size) | ||||
|  | @ -24,8 +26,8 @@ static inline void atomic_scrub(void *va, u32 size) | |||
| 		"	sc	%0, %1					\n" | ||||
| 		"	beqz	%0, 1b					\n" | ||||
| 		"	.set	mips0					\n" | ||||
| 		: "=&r" (temp), "=m" (*virt_addr) | ||||
| 		: "m" (*virt_addr)); | ||||
| 		: "=&r" (temp), "=" GCC_OFF12_ASM() (*virt_addr) | ||||
| 		: GCC_OFF12_ASM() (*virt_addr)); | ||||
| 
 | ||||
| 		virt_addr++; | ||||
| 	} | ||||
|  |  | |||
|  | @ -8,6 +8,8 @@ | |||
| #ifndef _ASM_ELF_H | ||||
| #define _ASM_ELF_H | ||||
| 
 | ||||
| #include <linux/fs.h> | ||||
| #include <uapi/linux/elf.h> | ||||
| 
 | ||||
| /* ELF header e_flags defines. */ | ||||
| /* MIPS architecture level. */ | ||||
|  | @ -28,6 +30,7 @@ | |||
| #define PT_MIPS_REGINFO		0x70000000 | ||||
| #define PT_MIPS_RTPROC		0x70000001 | ||||
| #define PT_MIPS_OPTIONS		0x70000002 | ||||
| #define PT_MIPS_ABIFLAGS	0x70000003 | ||||
| 
 | ||||
| /* Flags in the e_flags field of the header */ | ||||
| #define EF_MIPS_NOREORDER	0x00000001 | ||||
|  | @ -174,6 +177,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | |||
| typedef double elf_fpreg_t; | ||||
| typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | ||||
| 
 | ||||
| struct mips_elf_abiflags_v0 { | ||||
| 	uint16_t version;	/* Version of flags structure */ | ||||
| 	uint8_t isa_level;	/* The level of the ISA: 1-5, 32, 64 */ | ||||
| 	uint8_t isa_rev;	/* The revision of ISA: 0 for MIPS V and below,
 | ||||
| 				   1-n otherwise */ | ||||
| 	uint8_t gpr_size;	/* The size of general purpose registers */ | ||||
| 	uint8_t cpr1_size;	/* The size of co-processor 1 registers */ | ||||
| 	uint8_t cpr2_size;	/* The size of co-processor 2 registers */ | ||||
| 	uint8_t fp_abi;		/* The floating-point ABI */ | ||||
| 	uint32_t isa_ext;	/* Mask of processor-specific extensions */ | ||||
| 	uint32_t ases;		/* Mask of ASEs used */ | ||||
| 	uint32_t flags1;	/* Mask of general flags */ | ||||
| 	uint32_t flags2; | ||||
| }; | ||||
| 
 | ||||
| #define MIPS_ABI_FP_ANY		0	/* FP ABI doesn't matter */ | ||||
| #define MIPS_ABI_FP_DOUBLE	1	/* -mdouble-float */ | ||||
| #define MIPS_ABI_FP_SINGLE	2	/* -msingle-float */ | ||||
| #define MIPS_ABI_FP_SOFT	3	/* -msoft-float */ | ||||
| #define MIPS_ABI_FP_OLD_64	4	/* -mips32r2 -mfp64 */ | ||||
| #define MIPS_ABI_FP_XX		5	/* -mfpxx */ | ||||
| #define MIPS_ABI_FP_64		6	/* -mips32r2 -mfp64 */ | ||||
| #define MIPS_ABI_FP_64A		7	/* -mips32r2 -mfp64 -mno-odd-spreg */ | ||||
| 
 | ||||
| #ifdef CONFIG_32BIT | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -262,16 +289,13 @@ extern struct mips_abi mips_abi_n32; | |||
| 
 | ||||
| #ifdef CONFIG_32BIT | ||||
| 
 | ||||
| #define SET_PERSONALITY(ex)						\ | ||||
| #define SET_PERSONALITY2(ex, state)					\ | ||||
| do {									\ | ||||
| 	if ((ex).e_flags & EF_MIPS_FP64)				\ | ||||
| 		clear_thread_flag(TIF_32BIT_FPREGS);			\ | ||||
| 	else								\ | ||||
| 		set_thread_flag(TIF_32BIT_FPREGS);			\ | ||||
| 									\ | ||||
| 	if (personality(current->personality) != PER_LINUX)		\ | ||||
| 		set_personality(PER_LINUX);				\ | ||||
| 									\ | ||||
| 	mips_set_personality_fp(state);					\ | ||||
| 									\ | ||||
| 	current->thread.abi = &mips_abi;				\ | ||||
| } while (0) | ||||
| 
 | ||||
|  | @ -291,44 +315,44 @@ do {									\ | |||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS32_O32 | ||||
| #define __SET_PERSONALITY32_O32(ex)					\ | ||||
| #define __SET_PERSONALITY32_O32(ex, state)				\ | ||||
| 	do {								\ | ||||
| 		set_thread_flag(TIF_32BIT_REGS);			\ | ||||
| 		set_thread_flag(TIF_32BIT_ADDR);			\ | ||||
| 									\ | ||||
| 		if (!((ex).e_flags & EF_MIPS_FP64))			\ | ||||
| 			set_thread_flag(TIF_32BIT_FPREGS);		\ | ||||
| 		mips_set_personality_fp(state);				\ | ||||
| 									\ | ||||
| 		current->thread.abi = &mips_abi_32;			\ | ||||
| 	} while (0) | ||||
| #else | ||||
| #define __SET_PERSONALITY32_O32(ex)					\ | ||||
| #define __SET_PERSONALITY32_O32(ex, state)				\ | ||||
| 	do { } while (0) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS32_COMPAT | ||||
| #define __SET_PERSONALITY32(ex)						\ | ||||
| #define __SET_PERSONALITY32(ex, state)					\ | ||||
| do {									\ | ||||
| 	if ((((ex).e_flags & EF_MIPS_ABI2) != 0) &&			\ | ||||
| 	     ((ex).e_flags & EF_MIPS_ABI) == 0)				\ | ||||
| 		__SET_PERSONALITY32_N32();				\ | ||||
| 	else								\ | ||||
| 		__SET_PERSONALITY32_O32(ex);                            \ | ||||
| 		__SET_PERSONALITY32_O32(ex, state);			\ | ||||
| } while (0) | ||||
| #else | ||||
| #define __SET_PERSONALITY32(ex) do { } while (0) | ||||
| #define __SET_PERSONALITY32(ex, state) do { } while (0) | ||||
| #endif | ||||
| 
 | ||||
| #define SET_PERSONALITY(ex)						\ | ||||
| #define SET_PERSONALITY2(ex, state)					\ | ||||
| do {									\ | ||||
| 	unsigned int p;							\ | ||||
| 									\ | ||||
| 	clear_thread_flag(TIF_32BIT_REGS);				\ | ||||
| 	clear_thread_flag(TIF_32BIT_FPREGS);				\ | ||||
| 	clear_thread_flag(TIF_HYBRID_FPREGS);				\ | ||||
| 	clear_thread_flag(TIF_32BIT_ADDR);				\ | ||||
| 									\ | ||||
| 	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)			\ | ||||
| 		__SET_PERSONALITY32(ex);				\ | ||||
| 		__SET_PERSONALITY32(ex, state);				\ | ||||
| 	else								\ | ||||
| 		current->thread.abi = &mips_abi;			\ | ||||
| 									\ | ||||
|  | @ -390,4 +414,24 @@ struct mm_struct; | |||
| extern unsigned long arch_randomize_brk(struct mm_struct *mm); | ||||
| #define arch_randomize_brk arch_randomize_brk | ||||
| 
 | ||||
| struct arch_elf_state { | ||||
| 	int fp_abi; | ||||
| 	int interp_fp_abi; | ||||
| 	int overall_abi; | ||||
| }; | ||||
| 
 | ||||
| #define INIT_ARCH_ELF_STATE {			\ | ||||
| 	.fp_abi = -1,				\ | ||||
| 	.interp_fp_abi = -1,			\ | ||||
| 	.overall_abi = -1,			\ | ||||
| } | ||||
| 
 | ||||
| extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, | ||||
| 			    bool is_interp, struct arch_elf_state *state); | ||||
| 
 | ||||
| extern int arch_check_elf(void *ehdr, bool has_interpreter, | ||||
| 			  struct arch_elf_state *state); | ||||
| 
 | ||||
| extern void mips_set_personality_fp(struct arch_elf_state *state); | ||||
| 
 | ||||
| #endif /* _ASM_ELF_H */ | ||||
|  |  | |||
|  | @ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *); | |||
| 
 | ||||
| /*
 | ||||
|  * This enum specifies a mode in which we want the FPU to operate, for cores | ||||
|  * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT | ||||
|  * purposefully have the values 0 & 1 respectively, so that an integer value | ||||
|  * of Status.FR can be trivially casted to the corresponding enum fpu_mode. | ||||
|  * which implement the Status.FR bit. Note that the bottom bit of the value | ||||
|  * purposefully matches the desired value of the Status.FR bit. | ||||
|  */ | ||||
| enum fpu_mode { | ||||
| 	FPU_32BIT = 0,		/* FR = 0 */ | ||||
| 	FPU_64BIT,		/* FR = 1 */ | ||||
| 	FPU_64BIT,		/* FR = 1, FRE = 0 */ | ||||
| 	FPU_AS_IS, | ||||
| 	FPU_HYBRID,		/* FR = 1, FRE = 1 */ | ||||
| 
 | ||||
| #define FPU_FR_MASK		0x1 | ||||
| }; | ||||
| 
 | ||||
| static inline int __enable_fpu(enum fpu_mode mode) | ||||
|  | @ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode) | |||
| 		enable_fpu_hazard(); | ||||
| 		return 0; | ||||
| 
 | ||||
| 	case FPU_HYBRID: | ||||
| 		if (!cpu_has_fre) | ||||
| 			return SIGFPE; | ||||
| 
 | ||||
| 		/* set FRE */ | ||||
| 		write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE); | ||||
| 		goto fr_common; | ||||
| 
 | ||||
| 	case FPU_64BIT: | ||||
| #if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) | ||||
| 		/* we only have a 32-bit FPU */ | ||||
|  | @ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode) | |||
| #endif | ||||
| 		/* fall through */ | ||||
| 	case FPU_32BIT: | ||||
| 		/* clear FRE */ | ||||
| 		write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE); | ||||
| fr_common: | ||||
| 		/* set CU1 & change FR appropriately */ | ||||
| 		fr = (int)mode; | ||||
| 		fr = (int)mode & FPU_FR_MASK; | ||||
| 		change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); | ||||
| 		enable_fpu_hazard(); | ||||
| 
 | ||||
|  | @ -102,13 +115,17 @@ static inline int __own_fpu(void) | |||
| 	enum fpu_mode mode; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	mode = !test_thread_flag(TIF_32BIT_FPREGS); | ||||
| 	if (test_thread_flag(TIF_HYBRID_FPREGS)) | ||||
| 		mode = FPU_HYBRID; | ||||
| 	else | ||||
| 		mode = !test_thread_flag(TIF_32BIT_FPREGS); | ||||
| 
 | ||||
| 	ret = __enable_fpu(mode); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	KSTK_STATUS(current) |= ST0_CU1; | ||||
| 	if (mode == FPU_64BIT) | ||||
| 	if (mode == FPU_64BIT || mode == FPU_HYBRID) | ||||
| 		KSTK_STATUS(current) |= ST0_FR; | ||||
| 	else /* mode == FPU_32BIT */ | ||||
| 		KSTK_STATUS(current) &= ~ST0_FR; | ||||
|  | @ -166,8 +183,24 @@ static inline int init_fpu(void) | |||
| 
 | ||||
| 	if (cpu_has_fpu) { | ||||
| 		ret = __own_fpu(); | ||||
| 		if (!ret) | ||||
| 		if (!ret) { | ||||
| 			unsigned int config5 = read_c0_config5(); | ||||
| 
 | ||||
| 			/*
 | ||||
| 			 * Ensure FRE is clear whilst running _init_fpu, since | ||||
| 			 * single precision FP instructions are used. If FRE | ||||
| 			 * was set then we'll just end up initialising all 32 | ||||
| 			 * 64b registers. | ||||
| 			 */ | ||||
| 			write_c0_config5(config5 & ~MIPS_CONF5_FRE); | ||||
| 			enable_fpu_hazard(); | ||||
| 
 | ||||
| 			_init_fpu(); | ||||
| 
 | ||||
| 			/* Restore FRE */ | ||||
| 			write_c0_config5(config5); | ||||
| 			enable_fpu_hazard(); | ||||
| 		} | ||||
| 	} else | ||||
| 		fpu_emulator_init_fpu(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ | |||
| #include <linux/uaccess.h> | ||||
| #include <asm/asm-eva.h> | ||||
| #include <asm/barrier.h> | ||||
| #include <asm/compiler.h> | ||||
| #include <asm/errno.h> | ||||
| #include <asm/war.h> | ||||
| 
 | ||||
|  | @ -32,6 +33,7 @@ | |||
| 		"	beqzl	$1, 1b				\n"	\ | ||||
| 		__WEAK_LLSC_MB						\ | ||||
| 		"3:						\n"	\ | ||||
| 		"	.insn					\n"	\ | ||||
| 		"	.set	pop				\n"	\ | ||||
| 		"	.set	mips0				\n"	\ | ||||
| 		"	.section .fixup,\"ax\"			\n"	\ | ||||
|  | @ -42,8 +44,10 @@ | |||
| 		"	"__UA_ADDR "\t1b, 4b			\n"	\ | ||||
| 		"	"__UA_ADDR "\t2b, 4b			\n"	\ | ||||
| 		"	.previous				\n"	\ | ||||
| 		: "=r" (ret), "=&r" (oldval), "=R" (*uaddr)		\ | ||||
| 		: "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT)	\ | ||||
| 		: "=r" (ret), "=&r" (oldval),				\ | ||||
| 		  "=" GCC_OFF12_ASM() (*uaddr)				\ | ||||
| 		: "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg),	\ | ||||
| 		  "i" (-EFAULT)						\ | ||||
| 		: "memory");						\ | ||||
| 	} else if (cpu_has_llsc) {					\ | ||||
| 		__asm__ __volatile__(					\ | ||||
|  | @ -58,6 +62,7 @@ | |||
| 		"	beqz	$1, 1b				\n"	\ | ||||
| 		__WEAK_LLSC_MB						\ | ||||
| 		"3:						\n"	\ | ||||
| 		"	.insn					\n"	\ | ||||
| 		"	.set	pop				\n"	\ | ||||
| 		"	.set	mips0				\n"	\ | ||||
| 		"	.section .fixup,\"ax\"			\n"	\ | ||||
|  | @ -68,8 +73,10 @@ | |||
| 		"	"__UA_ADDR "\t1b, 4b			\n"	\ | ||||
| 		"	"__UA_ADDR "\t2b, 4b			\n"	\ | ||||
| 		"	.previous				\n"	\ | ||||
| 		: "=r" (ret), "=&r" (oldval), "=R" (*uaddr)		\ | ||||
| 		: "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT)	\ | ||||
| 		: "=r" (ret), "=&r" (oldval),				\ | ||||
| 		  "=" GCC_OFF12_ASM() (*uaddr)				\ | ||||
| 		: "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg),	\ | ||||
| 		  "i" (-EFAULT)						\ | ||||
| 		: "memory");						\ | ||||
| 	} else								\ | ||||
| 		ret = -ENOSYS;						\ | ||||
|  | @ -157,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 		"	beqzl	$1, 1b					\n" | ||||
| 		__WEAK_LLSC_MB | ||||
| 		"3:							\n" | ||||
| 		"	.insn						\n" | ||||
| 		"	.set	pop					\n" | ||||
| 		"	.section .fixup,\"ax\"				\n" | ||||
| 		"4:	li	%0, %6					\n" | ||||
|  | @ -166,8 +174,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 		"	"__UA_ADDR "\t1b, 4b				\n" | ||||
| 		"	"__UA_ADDR "\t2b, 4b				\n" | ||||
| 		"	.previous					\n" | ||||
| 		: "+r" (ret), "=&r" (val), "=R" (*uaddr) | ||||
| 		: "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) | ||||
| 		: "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) | ||||
| 		: GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), | ||||
| 		  "i" (-EFAULT) | ||||
| 		: "memory"); | ||||
| 	} else if (cpu_has_llsc) { | ||||
| 		__asm__ __volatile__( | ||||
|  | @ -184,6 +193,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 		"	beqz	$1, 1b					\n" | ||||
| 		__WEAK_LLSC_MB | ||||
| 		"3:							\n" | ||||
| 		"	.insn						\n" | ||||
| 		"	.set	pop					\n" | ||||
| 		"	.section .fixup,\"ax\"				\n" | ||||
| 		"4:	li	%0, %6					\n" | ||||
|  | @ -193,8 +203,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 		"	"__UA_ADDR "\t1b, 4b				\n" | ||||
| 		"	"__UA_ADDR "\t2b, 4b				\n" | ||||
| 		"	.previous					\n" | ||||
| 		: "+r" (ret), "=&r" (val), "=R" (*uaddr) | ||||
| 		: "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) | ||||
| 		: "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) | ||||
| 		: GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), | ||||
| 		  "i" (-EFAULT) | ||||
| 		: "memory"); | ||||
| 	} else | ||||
| 		return -ENOSYS; | ||||
|  |  | |||
							
								
								
									
										73
									
								
								arch/mips/include/asm/hpet.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								arch/mips/include/asm/hpet.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| #ifndef _ASM_HPET_H | ||||
| #define _ASM_HPET_H | ||||
| 
 | ||||
| #ifdef CONFIG_RS780_HPET | ||||
| 
 | ||||
| #define HPET_MMAP_SIZE		1024 | ||||
| 
 | ||||
| #define HPET_ID			0x000 | ||||
| #define HPET_PERIOD		0x004 | ||||
| #define HPET_CFG		0x010 | ||||
| #define HPET_STATUS		0x020 | ||||
| #define HPET_COUNTER	0x0f0 | ||||
| 
 | ||||
| #define HPET_Tn_CFG(n)		(0x100 + 0x20 * n) | ||||
| #define HPET_Tn_CMP(n)		(0x108 + 0x20 * n) | ||||
| #define HPET_Tn_ROUTE(n)	(0x110 + 0x20 * n) | ||||
| 
 | ||||
| #define HPET_T0_IRS		0x001 | ||||
| #define HPET_T1_IRS		0x002 | ||||
| #define HPET_T3_IRS		0x004 | ||||
| 
 | ||||
| #define HPET_T0_CFG		0x100 | ||||
| #define HPET_T0_CMP		0x108 | ||||
| #define HPET_T0_ROUTE	0x110 | ||||
| #define HPET_T1_CFG		0x120 | ||||
| #define HPET_T1_CMP		0x128 | ||||
| #define HPET_T1_ROUTE	0x130 | ||||
| #define HPET_T2_CFG		0x140 | ||||
| #define HPET_T2_CMP		0x148 | ||||
| #define HPET_T2_ROUTE	0x150 | ||||
| 
 | ||||
| #define HPET_ID_REV			0x000000ff | ||||
| #define HPET_ID_NUMBER		0x00001f00 | ||||
| #define HPET_ID_64BIT		0x00002000 | ||||
| #define HPET_ID_LEGSUP		0x00008000 | ||||
| #define HPET_ID_VENDOR		0xffff0000 | ||||
| #define HPET_ID_NUMBER_SHIFT	8 | ||||
| #define HPET_ID_VENDOR_SHIFT	16 | ||||
| 
 | ||||
| #define HPET_CFG_ENABLE		0x001 | ||||
| #define HPET_CFG_LEGACY		0x002 | ||||
| #define HPET_LEGACY_8254		2 | ||||
| #define HPET_LEGACY_RTC		8 | ||||
| 
 | ||||
| #define HPET_TN_LEVEL		0x0002 | ||||
| #define HPET_TN_ENABLE		0x0004 | ||||
| #define HPET_TN_PERIODIC	0x0008 | ||||
| #define HPET_TN_PERIODIC_CAP	0x0010 | ||||
| #define HPET_TN_64BIT_CAP	0x0020 | ||||
| #define HPET_TN_SETVAL		0x0040 | ||||
| #define HPET_TN_32BIT		0x0100 | ||||
| #define HPET_TN_ROUTE		0x3e00 | ||||
| #define HPET_TN_FSB			0x4000 | ||||
| #define HPET_TN_FSB_CAP		0x8000 | ||||
| #define HPET_TN_ROUTE_SHIFT	9 | ||||
| 
 | ||||
| /* Max HPET Period is 10^8 femto sec as in HPET spec */ | ||||
| #define HPET_MAX_PERIOD		100000000UL | ||||
| /*
 | ||||
|  * Min HPET period is 10^5 femto sec just for safety. If it is less than this, | ||||
|  * then 32 bit HPET counter wrapsaround in less than 0.5 sec. | ||||
|  */ | ||||
| #define HPET_MIN_PERIOD		100000UL | ||||
| 
 | ||||
| #define HPET_ADDR		0x20000 | ||||
| #define HPET_MMIO_ADDR	0x90000e0000020000 | ||||
| #define HPET_FREQ		14318780 | ||||
| #define HPET_COMPARE_VAL	((HPET_FREQ + HZ / 2) / HZ) | ||||
| #define HPET_T0_IRQ		0 | ||||
| 
 | ||||
| extern void __init setup_hpet_timer(void); | ||||
| #endif /* CONFIG_RS780_HPET */ | ||||
| #endif /* _ASM_HPET_H */ | ||||
|  | @ -167,7 +167,7 @@ static inline void * isa_bus_to_virt(unsigned long address) | |||
|  */ | ||||
| #define page_to_phys(page)	((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) | ||||
| 
 | ||||
| extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); | ||||
| extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags); | ||||
| extern void __iounmap(const volatile void __iomem *addr); | ||||
| 
 | ||||
| #ifndef CONFIG_PCI | ||||
|  | @ -175,7 +175,7 @@ struct pci_dev; | |||
| static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} | ||||
| #endif | ||||
| 
 | ||||
| static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | ||||
| static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size, | ||||
| 	unsigned long flags) | ||||
| { | ||||
| 	void __iomem *addr = plat_ioremap(offset, size, flags); | ||||
|  | @ -183,7 +183,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
| 	if (addr) | ||||
| 		return addr; | ||||
| 
 | ||||
| #define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) | ||||
| #define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL)) | ||||
| 
 | ||||
| 	if (cpu_has_64bit_addresses) { | ||||
| 		u64 base = UNCAC_BASE; | ||||
|  | @ -197,7 +197,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
| 		return (void __iomem *) (unsigned long) (base + offset); | ||||
| 	} else if (__builtin_constant_p(offset) && | ||||
| 		   __builtin_constant_p(size) && __builtin_constant_p(flags)) { | ||||
| 		phys_t phys_addr, last_addr; | ||||
| 		phys_addr_t phys_addr, last_addr; | ||||
| 
 | ||||
| 		phys_addr = fixup_bigphys_addr(offset, size); | ||||
| 
 | ||||
|  |  | |||
|  | @ -48,4 +48,7 @@ extern int cp0_compare_irq; | |||
| extern int cp0_compare_irq_shift; | ||||
| extern int cp0_perfcount_irq; | ||||
| 
 | ||||
| void arch_trigger_all_cpu_backtrace(bool); | ||||
| #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace | ||||
| 
 | ||||
| #endif /* _ASM_IRQ_H */ | ||||
|  |  | |||
|  | @ -19,8 +19,8 @@ extern void rm9k_cpu_irq_init(void); | |||
| 
 | ||||
| #ifdef CONFIG_IRQ_DOMAIN | ||||
| struct device_node; | ||||
| extern int mips_cpu_intc_init(struct device_node *of_node, | ||||
| 			      struct device_node *parent); | ||||
| extern int mips_cpu_irq_of_init(struct device_node *of_node, | ||||
| 				struct device_node *parent); | ||||
| #endif | ||||
| 
 | ||||
| #endif /* _ASM_IRQ_CPU_H */ | ||||
|  |  | |||
							
								
								
									
										73
									
								
								arch/mips/include/asm/mach-ath25/ath25_platform.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								arch/mips/include/asm/mach-ath25/ath25_platform.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| #ifndef __ASM_MACH_ATH25_PLATFORM_H | ||||
| #define __ASM_MACH_ATH25_PLATFORM_H | ||||
| 
 | ||||
| #include <linux/etherdevice.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * This is board-specific data that is stored in a "fixed" location in flash. | ||||
|  * It is shared across operating systems, so it should not be changed lightly. | ||||
|  * The main reason we need it is in order to extract the ethernet MAC | ||||
|  * address(es). | ||||
|  */ | ||||
| struct ath25_boarddata { | ||||
| 	u32 magic;                   /* board data is valid */ | ||||
| #define ATH25_BD_MAGIC 0x35333131    /* "5311", for all 531x/231x platforms */ | ||||
| 	u16 cksum;                   /* checksum (starting with BD_REV 2) */ | ||||
| 	u16 rev;                     /* revision of this struct */ | ||||
| #define BD_REV 4 | ||||
| 	char board_name[64];         /* Name of board */ | ||||
| 	u16 major;                   /* Board major number */ | ||||
| 	u16 minor;                   /* Board minor number */ | ||||
| 	u32 flags;                   /* Board configuration */ | ||||
| #define BD_ENET0        0x00000001   /* ENET0 is stuffed */ | ||||
| #define BD_ENET1        0x00000002   /* ENET1 is stuffed */ | ||||
| #define BD_UART1        0x00000004   /* UART1 is stuffed */ | ||||
| #define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */ | ||||
| #define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */ | ||||
| #define BD_SYSLED       0x00000020   /* System LED stuffed */ | ||||
| #define BD_EXTUARTCLK   0x00000040   /* External UART clock */ | ||||
| #define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */ | ||||
| #define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */ | ||||
| #define BD_WLAN0        0x00000200   /* Enable WLAN0 */ | ||||
| #define BD_MEMCAP       0x00000400   /* CAP SDRAM @ mem_cap for testing */ | ||||
| #define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */ | ||||
| #define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */ | ||||
| #define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */ | ||||
| #define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */ | ||||
| #define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */ | ||||
| #define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */ | ||||
| #define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */ | ||||
| 	u16 reset_config_gpio;       /* Reset factory GPIO pin */ | ||||
| 	u16 sys_led_gpio;            /* System LED GPIO pin */ | ||||
| 
 | ||||
| 	u32 cpu_freq;                /* CPU core frequency in Hz */ | ||||
| 	u32 sys_freq;                /* System frequency in Hz */ | ||||
| 	u32 cnt_freq;                /* Calculated C0_COUNT frequency */ | ||||
| 
 | ||||
| 	u8  wlan0_mac[ETH_ALEN]; | ||||
| 	u8  enet0_mac[ETH_ALEN]; | ||||
| 	u8  enet1_mac[ETH_ALEN]; | ||||
| 
 | ||||
| 	u16 pci_id;                  /* Pseudo PCIID for common code */ | ||||
| 	u16 mem_cap;                 /* cap bank1 in MB */ | ||||
| 
 | ||||
| 	/* version 3 */ | ||||
| 	u8  wlan1_mac[ETH_ALEN];     /* (ar5212) */ | ||||
| }; | ||||
| 
 | ||||
| #define BOARD_CONFIG_BUFSZ		0x1000 | ||||
| 
 | ||||
| /*
 | ||||
|  * Platform device information for the Wireless MAC | ||||
|  */ | ||||
| struct ar231x_board_config { | ||||
| 	u16 devid; | ||||
| 
 | ||||
| 	/* board config data */ | ||||
| 	struct ath25_boarddata *config; | ||||
| 
 | ||||
| 	/* radio calibration data */ | ||||
| 	const char *radio; | ||||
| }; | ||||
| 
 | ||||
| #endif /* __ASM_MACH_ATH25_PLATFORM_H */ | ||||
							
								
								
									
										64
									
								
								arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | |||
| /*
 | ||||
|  *  Atheros AR231x/AR531x SoC specific CPU feature overrides | ||||
|  * | ||||
|  *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> | ||||
|  * | ||||
|  *  This file was derived from: include/asm-mips/cpu-features.h | ||||
|  *	Copyright (C) 2003, 2004 Ralf Baechle | ||||
|  *	Copyright (C) 2004 Maciej W. Rozycki | ||||
|  * | ||||
|  *  This program is free software; you can redistribute it and/or modify it | ||||
|  *  under the terms of the GNU General Public License version 2 as published | ||||
|  *  by the Free Software Foundation. | ||||
|  * | ||||
|  */ | ||||
| #ifndef __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H | ||||
| #define __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H | ||||
| 
 | ||||
| /*
 | ||||
|  * The Atheros AR531x/AR231x SoCs have MIPS 4Kc/4KEc core. | ||||
|  */ | ||||
| #define cpu_has_tlb			1 | ||||
| #define cpu_has_4kex			1 | ||||
| #define cpu_has_3k_cache		0 | ||||
| #define cpu_has_4k_cache		1 | ||||
| #define cpu_has_tx39_cache		0 | ||||
| #define cpu_has_sb1_cache		0 | ||||
| #define cpu_has_fpu			0 | ||||
| #define cpu_has_32fpr			0 | ||||
| #define cpu_has_counter			1 | ||||
| #define cpu_has_ejtag			1 | ||||
| 
 | ||||
| #if !defined(CONFIG_SOC_AR5312) | ||||
| #  define cpu_has_llsc			1 | ||||
| #else | ||||
| /*
 | ||||
|  * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the | ||||
|  * ll/sc instructions. | ||||
|  */ | ||||
| #  define cpu_has_llsc			0 | ||||
| #endif | ||||
| 
 | ||||
| #define cpu_has_mips16			0 | ||||
| #define cpu_has_mdmx			0 | ||||
| #define cpu_has_mips3d			0 | ||||
| #define cpu_has_smartmips		0 | ||||
| 
 | ||||
| #define cpu_has_mips32r1		1 | ||||
| 
 | ||||
| #if !defined(CONFIG_SOC_AR5312) | ||||
| #  define cpu_has_mips32r2		1 | ||||
| #endif | ||||
| 
 | ||||
| #define cpu_has_mips64r1		0 | ||||
| #define cpu_has_mips64r2		0 | ||||
| 
 | ||||
| #define cpu_has_dsp			0 | ||||
| #define cpu_has_mipsmt			0 | ||||
| 
 | ||||
| #define cpu_has_64bits			0 | ||||
| #define cpu_has_64bit_zero_reg		0 | ||||
| #define cpu_has_64bit_gp_regs		0 | ||||
| #define cpu_has_64bit_addresses		0 | ||||
| 
 | ||||
| #endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */ | ||||
							
								
								
									
										82
									
								
								arch/mips/include/asm/mach-ath25/dma-coherence.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								arch/mips/include/asm/mach-ath25/dma-coherence.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,82 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org> | ||||
|  * Copyright (C) 2007  Felix Fietkau <nbd@openwrt.org> | ||||
|  * | ||||
|  */ | ||||
| #ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H | ||||
| #define __ASM_MACH_ATH25_DMA_COHERENCE_H | ||||
| 
 | ||||
| #include <linux/device.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * We need some arbitrary non-zero value to be programmed to the BAR1 register | ||||
|  * of PCI host controller to enable DMA. The same value should be used as the | ||||
|  * offset to calculate the physical address of DMA buffer for PCI devices. | ||||
|  */ | ||||
| #define AR2315_PCI_HOST_SDRAM_BASEADDR	0x20000000 | ||||
| 
 | ||||
| static inline dma_addr_t ath25_dev_offset(struct device *dev) | ||||
| { | ||||
| #ifdef CONFIG_PCI | ||||
| 	extern struct bus_type pci_bus_type; | ||||
| 
 | ||||
| 	if (dev && dev->bus == &pci_bus_type) | ||||
| 		return AR2315_PCI_HOST_SDRAM_BASEADDR; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static inline dma_addr_t | ||||
| plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||||
| { | ||||
| 	return virt_to_phys(addr) + ath25_dev_offset(dev); | ||||
| } | ||||
| 
 | ||||
| static inline dma_addr_t | ||||
| plat_map_dma_mem_page(struct device *dev, struct page *page) | ||||
| { | ||||
| 	return page_to_phys(page) + ath25_dev_offset(dev); | ||||
| } | ||||
| 
 | ||||
| static inline unsigned long | ||||
| plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) | ||||
| { | ||||
| 	return dma_addr - ath25_dev_offset(dev); | ||||
| } | ||||
| 
 | ||||
| static inline void | ||||
| plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size, | ||||
| 		   enum dma_data_direction direction) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline int plat_dma_supported(struct device *dev, u64 mask) | ||||
| { | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static inline void plat_extra_sync_for_device(struct device *dev) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline int plat_dma_mapping_error(struct device *dev, | ||||
| 					 dma_addr_t dma_addr) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static inline int plat_device_is_coherent(struct device *dev) | ||||
| { | ||||
| #ifdef CONFIG_DMA_COHERENT | ||||
| 	return 1; | ||||
| #endif | ||||
| #ifdef CONFIG_DMA_NONCOHERENT | ||||
| 	return 0; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */ | ||||
							
								
								
									
										16
									
								
								arch/mips/include/asm/mach-ath25/gpio.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								arch/mips/include/asm/mach-ath25/gpio.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| #ifndef __ASM_MACH_ATH25_GPIO_H | ||||
| #define __ASM_MACH_ATH25_GPIO_H | ||||
| 
 | ||||
| #include <asm-generic/gpio.h> | ||||
| 
 | ||||
| #define gpio_get_value __gpio_get_value | ||||
| #define gpio_set_value __gpio_set_value | ||||
| #define gpio_cansleep __gpio_cansleep | ||||
| #define gpio_to_irq __gpio_to_irq | ||||
| 
 | ||||
| static inline int irq_to_gpio(unsigned irq) | ||||
| { | ||||
| 	return -EINVAL; | ||||
| } | ||||
| 
 | ||||
| #endif	/* __ASM_MACH_ATH25_GPIO_H */ | ||||
							
								
								
									
										25
									
								
								arch/mips/include/asm/mach-ath25/war.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								arch/mips/include/asm/mach-ath25/war.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> | ||||
|  */ | ||||
| #ifndef __ASM_MACH_ATH25_WAR_H | ||||
| #define __ASM_MACH_ATH25_WAR_H | ||||
| 
 | ||||
| #define R4600_V1_INDEX_ICACHEOP_WAR	0 | ||||
| #define R4600_V1_HIT_CACHEOP_WAR	0 | ||||
| #define R4600_V2_HIT_CACHEOP_WAR	0 | ||||
| #define R5432_CP0_INTERRUPT_WAR		0 | ||||
| #define BCM1250_M3_WAR			0 | ||||
| #define SIBYTE_1956_WAR			0 | ||||
| #define MIPS4K_ICACHE_REFILL_WAR	0 | ||||
| #define MIPS_CACHE_SYNC_WAR		0 | ||||
| #define TX49XX_ICACHE_INDEX_INV_WAR	0 | ||||
| #define RM9000_CDEX_SMP_WAR		0 | ||||
| #define ICACHE_REFILLS_WORKAROUND_WAR	0 | ||||
| #define R10000_LLSC_WAR			0 | ||||
| #define MIPS34K_MISSED_ITLB_WAR		0 | ||||
| 
 | ||||
| #endif /* __ASM_MACH_ATH25_WAR_H */ | ||||
|  | @ -11,10 +11,10 @@ | |||
| 
 | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) | ||||
| extern phys_t __fixup_bigphys_addr(phys_t, phys_t); | ||||
| #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) | ||||
| extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t); | ||||
| #else | ||||
| static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | ||||
| static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) | ||||
| { | ||||
| 	return phys_addr; | ||||
| } | ||||
|  | @ -23,12 +23,12 @@ static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
| /*
 | ||||
|  * Allow physical addresses to be fixed up to help 36-bit peripherals. | ||||
|  */ | ||||
| static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | ||||
| static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) | ||||
| { | ||||
| 	return __fixup_bigphys_addr(phys_addr, size); | ||||
| } | ||||
| 
 | ||||
| static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | ||||
| static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, | ||||
| 	unsigned long flags) | ||||
| { | ||||
| 	return NULL; | ||||
|  |  | |||
							
								
								
									
										48
									
								
								arch/mips/include/asm/mach-bcm3384/dma-coherence.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								arch/mips/include/asm/mach-bcm3384/dma-coherence.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | |||
| /*
 | ||||
|  * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||||
|  * Copyright (C) 2009 Broadcom Corporation | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H | ||||
| #define __ASM_MACH_BCM3384_DMA_COHERENCE_H | ||||
| 
 | ||||
| struct device; | ||||
| 
 | ||||
| extern dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size); | ||||
| extern dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page); | ||||
| extern unsigned long plat_dma_addr_to_phys(struct device *dev, | ||||
| 	dma_addr_t dma_addr); | ||||
| 
 | ||||
| static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, | ||||
| 	size_t size, enum dma_data_direction direction) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline int plat_dma_supported(struct device *dev, u64 mask) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * we fall back to GFP_DMA when the mask isn't all 1s, | ||||
| 	 * so we can't guarantee allocations that must be | ||||
| 	 * within a tighter range than GFP_DMA.. | ||||
| 	 */ | ||||
| 	if (mask < DMA_BIT_MASK(24)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static inline int plat_device_is_coherent(struct device *dev) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */ | ||||
							
								
								
									
										24
									
								
								arch/mips/include/asm/mach-bcm3384/war.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								arch/mips/include/asm/mach-bcm3384/war.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | ||||
|  */ | ||||
| #ifndef __ASM_MIPS_MACH_BCM3384_WAR_H | ||||
| #define __ASM_MIPS_MACH_BCM3384_WAR_H | ||||
| 
 | ||||
| #define R4600_V1_INDEX_ICACHEOP_WAR	0 | ||||
| #define R4600_V1_HIT_CACHEOP_WAR	0 | ||||
| #define R4600_V2_HIT_CACHEOP_WAR	0 | ||||
| #define R5432_CP0_INTERRUPT_WAR		0 | ||||
| #define BCM1250_M3_WAR			0 | ||||
| #define SIBYTE_1956_WAR			0 | ||||
| #define MIPS4K_ICACHE_REFILL_WAR	0 | ||||
| #define MIPS_CACHE_SYNC_WAR		0 | ||||
| #define TX49XX_ICACHE_INDEX_INV_WAR	0 | ||||
| #define ICACHE_REFILLS_WORKAROUND_WAR	0 | ||||
| #define R10000_LLSC_WAR			0 | ||||
| #define MIPS34K_MISSED_ITLB_WAR		0 | ||||
| 
 | ||||
| #endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */ | ||||
|  | @ -14,40 +14,8 @@ | |||
| #include <linux/types.h> | ||||
| #include <linux/kernel.h> | ||||
| 
 | ||||
| struct nvram_header { | ||||
| 	u32 magic; | ||||
| 	u32 len; | ||||
| 	u32 crc_ver_init;	/* 0:7 crc, 8:15 ver, 16:31 sdram_init */ | ||||
| 	u32 config_refresh;	/* 0:15 sdram_config, 16:31 sdram_refresh */ | ||||
| 	u32 config_ncdl;	/* ncdl values for memc */ | ||||
| }; | ||||
| 
 | ||||
| #define NVRAM_HEADER		0x48534C46	/* 'FLSH' */ | ||||
| #define NVRAM_VERSION		1 | ||||
| #define NVRAM_HEADER_SIZE	20 | ||||
| #define NVRAM_SPACE		0x8000 | ||||
| 
 | ||||
| #define FLASH_MIN		0x00020000	/* Minimum flash size */ | ||||
| 
 | ||||
| #define NVRAM_MAX_VALUE_LEN 255 | ||||
| #define NVRAM_MAX_PARAM_LEN 64 | ||||
| 
 | ||||
| extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); | ||||
| 
 | ||||
| static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) | ||||
| { | ||||
| 	if (strchr(buf, ':')) | ||||
| 		sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | ||||
| 			&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||||
| 			&macaddr[5]); | ||||
| 	else if (strchr(buf, '-')) | ||||
| 		sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], | ||||
| 			&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||||
| 			&macaddr[5]); | ||||
| 	else | ||||
| 		printk(KERN_WARNING "Can not parse mac address: %s\n", buf); | ||||
| } | ||||
| 
 | ||||
| int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); | ||||
| int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); | ||||
| int bcm47xx_nvram_gpio_pin(const char *name); | ||||
| 
 | ||||
| #endif /* __BCM47XX_NVRAM_H */ | ||||
|  |  | |||
|  | @ -3,12 +3,12 @@ | |||
| 
 | ||||
| #include <bcm63xx_cpu.h> | ||||
| 
 | ||||
| static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | ||||
| static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) | ||||
| { | ||||
| 	return phys_addr; | ||||
| } | ||||
| 
 | ||||
| static inline int is_bcm63xx_internal_registers(phys_t offset) | ||||
| static inline int is_bcm63xx_internal_registers(phys_addr_t offset) | ||||
| { | ||||
| 	switch (bcm63xx_get_cpu_id()) { | ||||
| 	case BCM3368_CPU_ID: | ||||
|  | @ -32,7 +32,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | ||||
| static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, | ||||
| 					 unsigned long flags) | ||||
| { | ||||
| 	if (is_bcm63xx_internal_registers(offset)) | ||||
|  |  | |||
|  | @ -15,12 +15,12 @@ | |||
|  * Allow physical addresses to be fixed up to help peripherals located | ||||
|  * outside the low 32-bit range -- generic pass-through version. | ||||
|  */ | ||||
| static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | ||||
| static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) | ||||
| { | ||||
| 	return phys_addr; | ||||
| } | ||||
| 
 | ||||
| static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | ||||
| static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, | ||||
| 	unsigned long flags) | ||||
| { | ||||
| 	return NULL; | ||||
|  |  | |||
|  | @ -36,4 +36,10 @@ | |||
| 
 | ||||
| #endif /* CONFIG_IRQ_CPU */ | ||||
| 
 | ||||
| #ifdef CONFIG_MIPS_GIC | ||||
| #ifndef MIPS_GIC_IRQ_BASE | ||||
| #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | ||||
| #endif | ||||
| #endif /* CONFIG_MIPS_GIC */ | ||||
| 
 | ||||
| #endif /* __ASM_MACH_GENERIC_IRQ_H */ | ||||
|  |  | |||
|  | @ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void); | |||
| extern unsigned char ltq_boot_select(void); | ||||
| /* find out what caused the last cpu reset */ | ||||
| extern int ltq_reset_cause(void); | ||||
| /* find out the soc type */ | ||||
| extern int ltq_soc_type(void); | ||||
| 
 | ||||
| #define IOPORT_RESOURCE_START	0x10000000 | ||||
| #define IOPORT_RESOURCE_END	0xffffffff | ||||
|  |  | |||
|  | @ -10,7 +10,8 @@ | |||
| #define VIDEO_ROM		7 | ||||
| #define ADAPTER_ROM		8 | ||||
| #define ACPI_TABLE		9 | ||||
| #define MAX_MEMORY_TYPE		10 | ||||
| #define SMBIOS_TABLE		10 | ||||
| #define MAX_MEMORY_TYPE		11 | ||||
| 
 | ||||
| #define LOONGSON3_BOOT_MEM_MAP_MAX 128 | ||||
| struct efi_memory_map_loongson { | ||||
|  | @ -42,15 +43,49 @@ struct efi_cpuinfo_loongson { | |||
| 	u32 processor_id; /* PRID, e.g. 6305, 6306 */ | ||||
| 	u32 cputype;  /* Loongson_3A/3B, etc. */ | ||||
| 	u32 total_node;   /* num of total numa nodes */ | ||||
| 	u32 cpu_startup_core_id; /* Core id */ | ||||
| 	u16 cpu_startup_core_id; /* Boot core id */ | ||||
| 	u16 reserved_cores_mask; | ||||
| 	u32 cpu_clock_freq; /* cpu_clock */ | ||||
| 	u32 nr_cpus; | ||||
| } __packed; | ||||
| 
 | ||||
| #define MAX_UARTS 64 | ||||
| struct uart_device { | ||||
| 	u32 iotype; /* see include/linux/serial_core.h */ | ||||
| 	u32 uartclk; | ||||
| 	u32 int_offset; | ||||
| 	u64 uart_base; | ||||
| } __packed; | ||||
| 
 | ||||
| #define MAX_SENSORS 64 | ||||
| #define SENSOR_TEMPER  0x00000001 | ||||
| #define SENSOR_VOLTAGE 0x00000002 | ||||
| #define SENSOR_FAN     0x00000004 | ||||
| struct sensor_device { | ||||
| 	char name[32];  /* a formal name */ | ||||
| 	char label[64]; /* a flexible description */ | ||||
| 	u32 type;       /* SENSOR_* */ | ||||
| 	u32 id;         /* instance id of a sensor-class */ | ||||
| 	u32 fan_policy; /* see loongson_hwmon.h */ | ||||
| 	u32 fan_percent;/* only for constant speed policy */ | ||||
| 	u64 base_addr;  /* base address of device registers */ | ||||
| } __packed; | ||||
| 
 | ||||
| struct system_loongson { | ||||
| 	u16 vers;     /* version of system_loongson */ | ||||
| 	u32 ccnuma_smp; /* 0: no numa; 1: has numa */ | ||||
| 	u32 sing_double_channel; /* 1:single; 2:double */ | ||||
| 	u32 nr_uarts; | ||||
| 	struct uart_device uarts[MAX_UARTS]; | ||||
| 	u32 nr_sensors; | ||||
| 	struct sensor_device sensors[MAX_SENSORS]; | ||||
| 	char has_ec; | ||||
| 	char ec_name[32]; | ||||
| 	u64 ec_base_addr; | ||||
| 	char has_tcm; | ||||
| 	char tcm_name[32]; | ||||
| 	u64 tcm_base_addr; | ||||
| 	u64 workarounds; /* see workarounds.h */ | ||||
| } __packed; | ||||
| 
 | ||||
| struct irq_source_routing_table { | ||||
|  | @ -149,6 +184,8 @@ struct loongson_system_configuration { | |||
| 	u32 nr_nodes; | ||||
| 	int cores_per_node; | ||||
| 	int cores_per_package; | ||||
| 	u16 boot_cpu_id; | ||||
| 	u16 reserved_cpus_mask; | ||||
| 	enum loongson_cpu_type cputype; | ||||
| 	u64 ht_control_base; | ||||
| 	u64 pci_mem_start_addr; | ||||
|  | @ -159,9 +196,15 @@ struct loongson_system_configuration { | |||
| 	u64 suspend_addr; | ||||
| 	u64 vgabios_addr; | ||||
| 	u32 dma_mask_bits; | ||||
| 	char ecname[32]; | ||||
| 	u32 nr_uarts; | ||||
| 	struct uart_device uarts[MAX_UARTS]; | ||||
| 	u32 nr_sensors; | ||||
| 	struct sensor_device sensors[MAX_SENSORS]; | ||||
| 	u64 workarounds; | ||||
| }; | ||||
| 
 | ||||
| extern struct efi_memory_map_loongson *loongson_memmap; | ||||
| extern struct loongson_system_configuration loongson_sysconf; | ||||
| extern int cpuhotplug_workaround; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, | |||
| 					  size_t size) | ||||
| { | ||||
| #ifdef CONFIG_CPU_LOONGSON3 | ||||
| 	return virt_to_phys(addr); | ||||
| 	return phys_to_dma(dev, virt_to_phys(addr)); | ||||
| #else | ||||
| 	return virt_to_phys(addr) | 0x80000000; | ||||
| #endif | ||||
|  | @ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, | |||
| 					       struct page *page) | ||||
| { | ||||
| #ifdef CONFIG_CPU_LOONGSON3 | ||||
| 	return page_to_phys(page); | ||||
| 	return phys_to_dma(dev, page_to_phys(page)); | ||||
| #else | ||||
| 	return page_to_phys(page) | 0x80000000; | ||||
| #endif | ||||
|  | @ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev, | |||
| 	dma_addr_t dma_addr) | ||||
| { | ||||
| #if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) | ||||
| 	return dma_addr; | ||||
| 	return dma_to_phys(dev, dma_addr); | ||||
| #elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) | ||||
| 	return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); | ||||
| #else | ||||
|  |  | |||
|  | @ -32,8 +32,7 @@ | |||
| #define LOONGSON_INT_ROUTER_LPC		LOONGSON_INT_ROUTER_ENTRY(0x0a) | ||||
| #define LOONGSON_INT_ROUTER_HT1(n)	LOONGSON_INT_ROUTER_ENTRY(n + 0x18) | ||||
| 
 | ||||
| #define LOONGSON_INT_CORE0_INT0		0x11 /* route to int 0 of core 0 */ | ||||
| #define LOONGSON_INT_CORE0_INT1		0x21 /* route to int 1 of core 0 */ | ||||
| #define LOONGSON_INT_COREx_INTy(x, y)	(1<<(x) | 1<<(y+4))	/* route to int y of core x */ | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void); | |||
| extern void __init prom_init_machtype(void); | ||||
| extern void __init prom_init_env(void); | ||||
| #ifdef CONFIG_LOONGSON_UART_BASE | ||||
| extern unsigned long _loongson_uart_base, loongson_uart_base; | ||||
| extern unsigned long _loongson_uart_base[], loongson_uart_base[]; | ||||
| extern void prom_init_loongson_uart_base(void); | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										55
									
								
								arch/mips/include/asm/mach-loongson/loongson_hwmon.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								arch/mips/include/asm/mach-loongson/loongson_hwmon.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,55 @@ | |||
| #ifndef __LOONGSON_HWMON_H_ | ||||
| #define __LOONGSON_HWMON_H_ | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| #define MIN_TEMP	0 | ||||
| #define MAX_TEMP	255 | ||||
| #define NOT_VALID_TEMP	999 | ||||
| 
 | ||||
| typedef int (*get_temp_fun)(int); | ||||
| extern int loongson3_cpu_temp(int); | ||||
| 
 | ||||
| /* 0:Max speed, 1:Manual, 2:Auto */ | ||||
| enum fan_control_mode { | ||||
| 	FAN_FULL_MODE = 0, | ||||
| 	FAN_MANUAL_MODE = 1, | ||||
| 	FAN_AUTO_MODE = 2, | ||||
| 	FAN_MODE_END | ||||
| }; | ||||
| 
 | ||||
| struct temp_range { | ||||
| 	u8 low; | ||||
| 	u8 high; | ||||
| 	u8 level; | ||||
| }; | ||||
| 
 | ||||
| #define CONSTANT_SPEED_POLICY	0  /* at constent speed */ | ||||
| #define STEP_SPEED_POLICY	1  /* use up/down arrays to describe policy */ | ||||
| #define KERNEL_HELPER_POLICY	2  /* kernel as a helper to fan control */ | ||||
| 
 | ||||
| #define MAX_STEP_NUM	16 | ||||
| #define MAX_FAN_LEVEL	255 | ||||
| 
 | ||||
| /* loongson_fan_policy works when fan work at FAN_AUTO_MODE */ | ||||
| struct loongson_fan_policy { | ||||
| 	u8	type; | ||||
| 
 | ||||
| 	/* percent only used when type is CONSTANT_SPEED_POLICY */ | ||||
| 	u8	percent; | ||||
| 
 | ||||
| 	/* period between two check. (Unit: S) */ | ||||
| 	u8	adjust_period; | ||||
| 
 | ||||
| 	/* fan adjust usually depend on a temprature input */ | ||||
| 	get_temp_fun	depend_temp; | ||||
| 
 | ||||
| 	/* up_step/down_step used when type is STEP_SPEED_POLICY */ | ||||
| 	u8	up_step_num; | ||||
| 	u8	down_step_num; | ||||
| 	struct temp_range up_step[MAX_STEP_NUM]; | ||||
| 	struct temp_range down_step[MAX_STEP_NUM]; | ||||
| 	struct delayed_work work; | ||||
| }; | ||||
| 
 | ||||
| #endif /* __LOONGSON_HWMON_H_*/ | ||||
|  | @ -26,7 +26,7 @@ | |||
| 
 | ||||
| #ifdef CONFIG_LOONGSON_MACH3X | ||||
| 
 | ||||
| #define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 | ||||
| #define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC | ||||
| 
 | ||||
| #endif /* CONFIG_LOONGSON_MACH3X */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 
 | ||||
| #ifdef CONFIG_NUMA | ||||
| 
 | ||||
| #define cpu_to_node(cpu)	((cpu) >> 2) | ||||
| #define cpu_to_node(cpu)	(cpu_logical_map(cpu) >> 2) | ||||
| #define parent_node(node)	(node) | ||||
| #define cpumask_of_node(node)	(&__node_data[(node)]->cpumask) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										7
									
								
								arch/mips/include/asm/mach-loongson/workarounds.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								arch/mips/include/asm/mach-loongson/workarounds.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_ | ||||
| #define __ASM_MACH_LOONGSON_WORKAROUNDS_H_ | ||||
| 
 | ||||
| #define WORKAROUND_CPUFREQ	0x00000001 | ||||
| #define WORKAROUND_CPUHOTPLUG	0x00000002 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										23
									
								
								arch/mips/include/asm/mach-loongson1/cpufreq.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								arch/mips/include/asm/mach-loongson1/cpufreq.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||||
|  * | ||||
|  * Loongson 1 CPUFreq platform support. | ||||
|  * | ||||
|  * This program is free software; you can redistribute	it and/or modify it | ||||
|  * under  the terms of	the GNU General	 Public License as published by the | ||||
|  * Free Software Foundation;  either version 2 of the  License, or (at your | ||||
|  * option) any later version. | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H | ||||
| #define __ASM_MACH_LOONGSON1_CPUFREQ_H | ||||
| 
 | ||||
| struct plat_ls1x_cpufreq { | ||||
| 	const char	*clk_name;	/* CPU clk */ | ||||
| 	const char	*osc_clk_name;	/* OSC clk */ | ||||
| 	unsigned int	max_freq;	/* in kHz */ | ||||
| 	unsigned int	min_freq;	/* in kHz */ | ||||
| }; | ||||
| 
 | ||||
| #endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */ | ||||
|  | @ -16,6 +16,7 @@ | |||
| #define DEFAULT_MEMSIZE			256	/* If no memsize provided */ | ||||
| 
 | ||||
| /* Loongson 1 Register Bases */ | ||||
| #define LS1X_MUX_BASE			0x1fd00420 | ||||
| #define LS1X_INTC_BASE			0x1fd01040 | ||||
| #define LS1X_EHCI_BASE			0x1fe00000 | ||||
| #define LS1X_OHCI_BASE			0x1fe08000 | ||||
|  | @ -31,7 +32,10 @@ | |||
| #define LS1X_I2C0_BASE			0x1fe58000 | ||||
| #define LS1X_I2C1_BASE			0x1fe68000 | ||||
| #define LS1X_I2C2_BASE			0x1fe70000 | ||||
| #define LS1X_PWM_BASE			0x1fe5c000 | ||||
| #define LS1X_PWM0_BASE			0x1fe5c000 | ||||
| #define LS1X_PWM1_BASE			0x1fe5c010 | ||||
| #define LS1X_PWM2_BASE			0x1fe5c020 | ||||
| #define LS1X_PWM3_BASE			0x1fe5c030 | ||||
| #define LS1X_WDT_BASE			0x1fe5c060 | ||||
| #define LS1X_RTC_BASE			0x1fe64000 | ||||
| #define LS1X_AC97_BASE			0x1fe74000 | ||||
|  | @ -39,6 +43,8 @@ | |||
| #define LS1X_CLK_BASE			0x1fe78030 | ||||
| 
 | ||||
| #include <regs-clk.h> | ||||
| #include <regs-mux.h> | ||||
| #include <regs-pwm.h> | ||||
| #include <regs-wdt.h> | ||||
| 
 | ||||
| #endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ | ||||
|  |  | |||
|  | @ -13,10 +13,12 @@ | |||
| 
 | ||||
| #include <linux/platform_device.h> | ||||
| 
 | ||||
| extern struct platform_device ls1x_uart_device; | ||||
| extern struct platform_device ls1x_eth0_device; | ||||
| extern struct platform_device ls1x_ehci_device; | ||||
| extern struct platform_device ls1x_rtc_device; | ||||
| extern struct platform_device ls1x_uart_pdev; | ||||
| extern struct platform_device ls1x_cpufreq_pdev; | ||||
| extern struct platform_device ls1x_eth0_pdev; | ||||
| extern struct platform_device ls1x_eth1_pdev; | ||||
| extern struct platform_device ls1x_ehci_pdev; | ||||
| extern struct platform_device ls1x_rtc_pdev; | ||||
| 
 | ||||
| extern void __init ls1x_clk_init(void); | ||||
| extern void __init ls1x_serial_setup(struct platform_device *pdev); | ||||
|  |  | |||
|  | @ -20,15 +20,32 @@ | |||
| 
 | ||||
| /* Clock PLL Divisor Register Bits */ | ||||
| #define DIV_DC_EN			(0x1 << 31) | ||||
| #define DIV_DC_RST			(0x1 << 30) | ||||
| #define DIV_CPU_EN			(0x1 << 25) | ||||
| #define DIV_CPU_RST			(0x1 << 24) | ||||
| #define DIV_DDR_EN			(0x1 << 19) | ||||
| #define DIV_DDR_RST			(0x1 << 18) | ||||
| #define RST_DC_EN			(0x1 << 5) | ||||
| #define RST_DC				(0x1 << 4) | ||||
| #define RST_DDR_EN			(0x1 << 3) | ||||
| #define RST_DDR				(0x1 << 2) | ||||
| #define RST_CPU_EN			(0x1 << 1) | ||||
| #define RST_CPU				0x1 | ||||
| 
 | ||||
| #define DIV_DC_SHIFT			26 | ||||
| #define DIV_CPU_SHIFT			20 | ||||
| #define DIV_DDR_SHIFT			14 | ||||
| 
 | ||||
| #define DIV_DC_WIDTH			5 | ||||
| #define DIV_CPU_WIDTH			5 | ||||
| #define DIV_DDR_WIDTH			5 | ||||
| #define DIV_DC_WIDTH			4 | ||||
| #define DIV_CPU_WIDTH			4 | ||||
| #define DIV_DDR_WIDTH			4 | ||||
| 
 | ||||
| #define BYPASS_DC_SHIFT			12 | ||||
| #define BYPASS_DDR_SHIFT		10 | ||||
| #define BYPASS_CPU_SHIFT		8 | ||||
| 
 | ||||
| #define BYPASS_DC_WIDTH			1 | ||||
| #define BYPASS_DDR_WIDTH		1 | ||||
| #define BYPASS_CPU_WIDTH		1 | ||||
| 
 | ||||
| #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ | ||||
|  |  | |||
							
								
								
									
										67
									
								
								arch/mips/include/asm/mach-loongson1/regs-mux.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								arch/mips/include/asm/mach-loongson1/regs-mux.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,67 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||||
|  * | ||||
|  * Loongson 1 MUX Register Definitions. | ||||
|  * | ||||
|  * This program is free software; you can redistribute	it and/or modify it | ||||
|  * under  the terms of	the GNU General	 Public License as published by the | ||||
|  * Free Software Foundation;  either version 2 of the  License, or (at your | ||||
|  * option) any later version. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H | ||||
| #define __ASM_MACH_LOONGSON1_REGS_MUX_H | ||||
| 
 | ||||
| #define LS1X_MUX_REG(x) \ | ||||
| 		((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x))) | ||||
| 
 | ||||
| #define LS1X_MUX_CTRL0			LS1X_MUX_REG(0x0) | ||||
| #define LS1X_MUX_CTRL1			LS1X_MUX_REG(0x4) | ||||
| 
 | ||||
| /* MUX CTRL0 Register Bits */ | ||||
| #define UART0_USE_PWM23			(0x1 << 28) | ||||
| #define UART0_USE_PWM01			(0x1 << 27) | ||||
| #define UART1_USE_LCD0_5_6_11		(0x1 << 26) | ||||
| #define I2C2_USE_CAN1			(0x1 << 25) | ||||
| #define I2C1_USE_CAN0			(0x1 << 24) | ||||
| #define NAND3_USE_UART5			(0x1 << 23) | ||||
| #define NAND3_USE_UART4			(0x1 << 22) | ||||
| #define NAND3_USE_UART1_DAT		(0x1 << 21) | ||||
| #define NAND3_USE_UART1_CTS		(0x1 << 20) | ||||
| #define NAND3_USE_PWM23			(0x1 << 19) | ||||
| #define NAND3_USE_PWM01			(0x1 << 18) | ||||
| #define NAND2_USE_UART5			(0x1 << 17) | ||||
| #define NAND2_USE_UART4			(0x1 << 16) | ||||
| #define NAND2_USE_UART1_DAT		(0x1 << 15) | ||||
| #define NAND2_USE_UART1_CTS		(0x1 << 14) | ||||
| #define NAND2_USE_PWM23			(0x1 << 13) | ||||
| #define NAND2_USE_PWM01			(0x1 << 12) | ||||
| #define NAND1_USE_UART5			(0x1 << 11) | ||||
| #define NAND1_USE_UART4			(0x1 << 10) | ||||
| #define NAND1_USE_UART1_DAT		(0x1 << 9) | ||||
| #define NAND1_USE_UART1_CTS		(0x1 << 8) | ||||
| #define NAND1_USE_PWM23			(0x1 << 7) | ||||
| #define NAND1_USE_PWM01			(0x1 << 6) | ||||
| #define GMAC1_USE_UART1			(0x1 << 4) | ||||
| #define GMAC1_USE_UART0			(0x1 << 3) | ||||
| #define LCD_USE_UART0_DAT		(0x1 << 2) | ||||
| #define LCD_USE_UART15			(0x1 << 1) | ||||
| #define LCD_USE_UART0			0x1 | ||||
| 
 | ||||
| /* MUX CTRL1 Register Bits */ | ||||
| #define USB_RESET			(0x1 << 31) | ||||
| #define SPI1_CS_USE_PWM01		(0x1 << 24) | ||||
| #define SPI1_USE_CAN			(0x1 << 23) | ||||
| #define DISABLE_DDR_CONFSPACE		(0x1 << 20) | ||||
| #define DDR32TO16EN			(0x1 << 16) | ||||
| #define GMAC1_SHUT			(0x1 << 13) | ||||
| #define GMAC0_SHUT			(0x1 << 12) | ||||
| #define USB_SHUT			(0x1 << 11) | ||||
| #define UART1_3_USE_CAN1		(0x1 << 5) | ||||
| #define UART1_2_USE_CAN0		(0x1 << 4) | ||||
| #define GMAC1_USE_TXCLK			(0x1 << 3) | ||||
| #define GMAC0_USE_TXCLK			(0x1 << 2) | ||||
| #define GMAC1_USE_PWM23			(0x1 << 1) | ||||
| #define GMAC0_USE_PWM01			0x1 | ||||
| 
 | ||||
| #endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */ | ||||
							
								
								
									
										29
									
								
								arch/mips/include/asm/mach-loongson1/regs-pwm.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								arch/mips/include/asm/mach-loongson1/regs-pwm.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||||
|  * | ||||
|  * Loongson 1 PWM Register Definitions. | ||||
|  * | ||||
|  * This program is free software; you can redistribute	it and/or modify it | ||||
|  * under  the terms of	the GNU General	 Public License as published by the | ||||
|  * Free Software Foundation;  either version 2 of the  License, or (at your | ||||
|  * option) any later version. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H | ||||
| #define __ASM_MACH_LOONGSON1_REGS_PWM_H | ||||
| 
 | ||||
| /* Loongson 1 PWM Timer Register Definitions */ | ||||
| #define PWM_CNT			0x0 | ||||
| #define PWM_HRC			0x4 | ||||
| #define PWM_LRC			0x8 | ||||
| #define PWM_CTRL		0xc | ||||
| 
 | ||||
| /* PWM Control Register Bits */ | ||||
| #define CNT_RST			(0x1 << 7) | ||||
| #define INT_SR			(0x1 << 6) | ||||
| #define INT_EN			(0x1 << 5) | ||||
| #define PWM_SINGLE		(0x1 << 4) | ||||
| #define PWM_OE			(0x1 << 3) | ||||
| #define CNT_EN			0x1 | ||||
| 
 | ||||
| #endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */ | ||||
|  | @ -1,7 +1,7 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||||
|  * | ||||
|  * Loongson 1 watchdog register definitions. | ||||
|  * Loongson 1 Watchdog Register Definitions. | ||||
|  * | ||||
|  * This program is free software; you can redistribute	it and/or modify it | ||||
|  * under  the terms of	the GNU General	 Public License as published by the | ||||
|  | @ -12,11 +12,8 @@ | |||
| #ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H | ||||
| #define __ASM_MACH_LOONGSON1_REGS_WDT_H | ||||
| 
 | ||||
| #define LS1X_WDT_REG(x) \ | ||||
| 		((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x))) | ||||
| 
 | ||||
| #define LS1X_WDT_EN			LS1X_WDT_REG(0x0) | ||||
| #define LS1X_WDT_SET			LS1X_WDT_REG(0x4) | ||||
| #define LS1X_WDT_TIMER			LS1X_WDT_REG(0x8) | ||||
| #define WDT_EN			0x0 | ||||
| #define WDT_TIMER		0x4 | ||||
| #define WDT_SET			0x8 | ||||
| 
 | ||||
| #endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| #define __ASM_MACH_MIPS_IRQ_H | ||||
| 
 | ||||
| 
 | ||||
| #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||||
| #define NR_IRQS 256 | ||||
| 
 | ||||
| #include_next <irq.h> | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ | |||
| 
 | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| #include <asm/compiler.h> | ||||
| #include <asm/war.h> | ||||
| 
 | ||||
| #ifndef R10000_LLSC_WAR | ||||
|  | @ -84,8 +85,8 @@ static inline void set_value_reg32(volatile u32 *const addr, | |||
| 	"	"__beqz"%0, 1b				\n" | ||||
| 	"	nop					\n" | ||||
| 	"	.set	pop				\n" | ||||
| 	: "=&r" (temp), "=m" (*addr) | ||||
| 	: "ir" (~mask), "ir" (value), "m" (*addr)); | ||||
| 	: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) | ||||
| 	: "ir" (~mask), "ir" (value), GCC_OFF12_ASM() (*addr)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -105,8 +106,8 @@ static inline void set_reg32(volatile u32 *const addr, | |||
| 	"	"__beqz"%0, 1b				\n" | ||||
| 	"	nop					\n" | ||||
| 	"	.set	pop				\n" | ||||
| 	: "=&r" (temp), "=m" (*addr) | ||||
| 	: "ir" (mask), "m" (*addr)); | ||||
| 	: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) | ||||
| 	: "ir" (mask), GCC_OFF12_ASM() (*addr)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -126,8 +127,8 @@ static inline void clear_reg32(volatile u32 *const addr, | |||
| 	"	"__beqz"%0, 1b				\n" | ||||
| 	"	nop					\n" | ||||
| 	"	.set	pop				\n" | ||||
| 	: "=&r" (temp), "=m" (*addr) | ||||
| 	: "ir" (~mask), "m" (*addr)); | ||||
| 	: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) | ||||
| 	: "ir" (~mask), GCC_OFF12_ASM() (*addr)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -147,8 +148,8 @@ static inline void toggle_reg32(volatile u32 *const addr, | |||
| 	"	"__beqz"%0, 1b				\n" | ||||
| 	"	nop					\n" | ||||
| 	"	.set	pop				\n" | ||||
| 	: "=&r" (temp), "=m" (*addr) | ||||
| 	: "ir" (mask), "m" (*addr)); | ||||
| 	: "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) | ||||
| 	: "ir" (mask), GCC_OFF12_ASM() (*addr)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -219,8 +220,8 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) | |||
| 	"	.set	arch=r4000			\n"	\ | ||||
| 	"1:	ll	%0, %1	#custom_read_reg32	\n"	\ | ||||
| 	"	.set	pop				\n"	\ | ||||
| 	: "=r" (tmp), "=m" (*address)				\ | ||||
| 	: "m" (*address)) | ||||
| 	: "=r" (tmp), "=" GCC_OFF12_ASM() (*address)		\ | ||||
| 	: GCC_OFF12_ASM() (*address)) | ||||
| 
 | ||||
| #define custom_write_reg32(address, tmp)			\ | ||||
| 	__asm__ __volatile__(					\ | ||||
|  | @ -230,7 +231,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) | |||
| 	"	"__beqz"%0, 1b				\n"	\ | ||||
| 	"	nop					\n"	\ | ||||
| 	"	.set	pop				\n"	\ | ||||
| 	: "=&r" (tmp), "=m" (*address)				\ | ||||
| 	: "0" (tmp), "m" (*address)) | ||||
| 	: "=&r" (tmp), "=" GCC_OFF12_ASM() (*address)		\ | ||||
| 	: "0" (tmp), GCC_OFF12_ASM() (*address)) | ||||
| 
 | ||||
| #endif	/* __ASM_REGOPS_H__ */ | ||||
|  |  | |||
|  | @ -13,6 +13,13 @@ | |||
| #ifndef _MT7620_REGS_H_ | ||||
| #define _MT7620_REGS_H_ | ||||
| 
 | ||||
| enum mt762x_soc_type { | ||||
| 	MT762X_SOC_UNKNOWN = 0, | ||||
| 	MT762X_SOC_MT7620A, | ||||
| 	MT762X_SOC_MT7620N, | ||||
| 	MT762X_SOC_MT7628AN, | ||||
| }; | ||||
| 
 | ||||
| #define MT7620_SYSC_BASE		0x10000000 | ||||
| 
 | ||||
| #define SYSC_REG_CHIP_NAME0		0x00 | ||||
|  | @ -25,11 +32,9 @@ | |||
| #define SYSC_REG_CPLL_CONFIG0		0x54 | ||||
| #define SYSC_REG_CPLL_CONFIG1		0x58 | ||||
| 
 | ||||
| #define MT7620N_CHIP_NAME0		0x33365452 | ||||
| #define MT7620N_CHIP_NAME1		0x20203235 | ||||
| 
 | ||||
| #define MT7620A_CHIP_NAME0		0x3637544d | ||||
| #define MT7620A_CHIP_NAME1		0x20203032 | ||||
| #define MT7620_CHIP_NAME0		0x3637544d | ||||
| #define MT7620_CHIP_NAME1		0x20203032 | ||||
| #define MT7628_CHIP_NAME1		0x20203832 | ||||
| 
 | ||||
| #define SYSCFG0_XTAL_FREQ_SEL		BIT(6) | ||||
| 
 | ||||
|  | @ -74,6 +79,9 @@ | |||
| #define SYSCFG0_DRAM_TYPE_DDR1		1 | ||||
| #define SYSCFG0_DRAM_TYPE_DDR2		2 | ||||
| 
 | ||||
| #define SYSCFG0_DRAM_TYPE_DDR2_MT7628	0 | ||||
| #define SYSCFG0_DRAM_TYPE_DDR1_MT7628	1 | ||||
| 
 | ||||
| #define MT7620_DRAM_BASE		0x0 | ||||
| #define MT7620_SDRAM_SIZE_MIN		2 | ||||
| #define MT7620_SDRAM_SIZE_MAX		64 | ||||
|  | @ -82,7 +90,6 @@ | |||
| #define MT7620_DDR2_SIZE_MIN		32 | ||||
| #define MT7620_DDR2_SIZE_MAX		256 | ||||
| 
 | ||||
| #define MT7620_GPIO_MODE_I2C		BIT(0) | ||||
| #define MT7620_GPIO_MODE_UART0_SHIFT	2 | ||||
| #define MT7620_GPIO_MODE_UART0_MASK	0x7 | ||||
| #define MT7620_GPIO_MODE_UART0(x)	((x) << MT7620_GPIO_MODE_UART0_SHIFT) | ||||
|  | @ -94,15 +101,40 @@ | |||
| #define MT7620_GPIO_MODE_GPIO_UARTF	0x5 | ||||
| #define MT7620_GPIO_MODE_GPIO_I2S	0x6 | ||||
| #define MT7620_GPIO_MODE_GPIO		0x7 | ||||
| #define MT7620_GPIO_MODE_UART1		BIT(5) | ||||
| #define MT7620_GPIO_MODE_MDIO		BIT(8) | ||||
| #define MT7620_GPIO_MODE_RGMII1		BIT(9) | ||||
| #define MT7620_GPIO_MODE_RGMII2		BIT(10) | ||||
| #define MT7620_GPIO_MODE_SPI		BIT(11) | ||||
| #define MT7620_GPIO_MODE_SPI_REF_CLK	BIT(12) | ||||
| #define MT7620_GPIO_MODE_WLED		BIT(13) | ||||
| #define MT7620_GPIO_MODE_JTAG		BIT(15) | ||||
| #define MT7620_GPIO_MODE_EPHY		BIT(15) | ||||
| #define MT7620_GPIO_MODE_WDT		BIT(22) | ||||
| 
 | ||||
| #define MT7620_GPIO_MODE_NAND		0 | ||||
| #define MT7620_GPIO_MODE_SD		1 | ||||
| #define MT7620_GPIO_MODE_ND_SD_GPIO	2 | ||||
| #define MT7620_GPIO_MODE_ND_SD_MASK	0x3 | ||||
| #define MT7620_GPIO_MODE_ND_SD_SHIFT	18 | ||||
| 
 | ||||
| #define MT7620_GPIO_MODE_PCIE_RST	0 | ||||
| #define MT7620_GPIO_MODE_PCIE_REF	1 | ||||
| #define MT7620_GPIO_MODE_PCIE_GPIO	2 | ||||
| #define MT7620_GPIO_MODE_PCIE_MASK	0x3 | ||||
| #define MT7620_GPIO_MODE_PCIE_SHIFT	16 | ||||
| 
 | ||||
| #define MT7620_GPIO_MODE_WDT_RST	0 | ||||
| #define MT7620_GPIO_MODE_WDT_REF	1 | ||||
| #define MT7620_GPIO_MODE_WDT_GPIO	2 | ||||
| #define MT7620_GPIO_MODE_WDT_MASK	0x3 | ||||
| #define MT7620_GPIO_MODE_WDT_SHIFT	21 | ||||
| 
 | ||||
| #define MT7620_GPIO_MODE_I2C		0 | ||||
| #define MT7620_GPIO_MODE_UART1		5 | ||||
| #define MT7620_GPIO_MODE_MDIO		8 | ||||
| #define MT7620_GPIO_MODE_RGMII1		9 | ||||
| #define MT7620_GPIO_MODE_RGMII2		10 | ||||
| #define MT7620_GPIO_MODE_SPI		11 | ||||
| #define MT7620_GPIO_MODE_SPI_REF_CLK	12 | ||||
| #define MT7620_GPIO_MODE_WLED		13 | ||||
| #define MT7620_GPIO_MODE_JTAG		15 | ||||
| #define MT7620_GPIO_MODE_EPHY		15 | ||||
| #define MT7620_GPIO_MODE_PA		20 | ||||
| 
 | ||||
| static inline int mt7620_get_eco(void) | ||||
| { | ||||
| 	return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										55
									
								
								arch/mips/include/asm/mach-ralink/pinmux.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								arch/mips/include/asm/mach-ralink/pinmux.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,55 @@ | |||
| /*
 | ||||
|  *  This program is free software; you can redistribute it and/or modify | ||||
|  *  it under the terms of the GNU General Public License version 2 as | ||||
|  *  publishhed by the Free Software Foundation. | ||||
|  * | ||||
|  *  Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _RT288X_PINMUX_H__ | ||||
| #define _RT288X_PINMUX_H__ | ||||
| 
 | ||||
| #define FUNC(name, value, pin_first, pin_count) \ | ||||
| 	{ name, value, pin_first, pin_count } | ||||
| 
 | ||||
| #define GRP(_name, _func, _mask, _shift) \ | ||||
| 	{ .name = _name, .mask = _mask, .shift = _shift, \ | ||||
| 	  .func = _func, .gpio = _mask, \ | ||||
| 	  .func_count = ARRAY_SIZE(_func) } | ||||
| 
 | ||||
| #define GRP_G(_name, _func, _mask, _gpio, _shift) \ | ||||
| 	{ .name = _name, .mask = _mask, .shift = _shift, \ | ||||
| 	  .func = _func, .gpio = _gpio, \ | ||||
| 	  .func_count = ARRAY_SIZE(_func) } | ||||
| 
 | ||||
| struct rt2880_pmx_group; | ||||
| 
 | ||||
| struct rt2880_pmx_func { | ||||
| 	const char *name; | ||||
| 	const char value; | ||||
| 
 | ||||
| 	int pin_first; | ||||
| 	int pin_count; | ||||
| 	int *pins; | ||||
| 
 | ||||
| 	int *groups; | ||||
| 	int group_count; | ||||
| 
 | ||||
| 	int enabled; | ||||
| }; | ||||
| 
 | ||||
| struct rt2880_pmx_group { | ||||
| 	const char *name; | ||||
| 	int enabled; | ||||
| 
 | ||||
| 	const u32 shift; | ||||
| 	const char mask; | ||||
| 	const char gpio; | ||||
| 
 | ||||
| 	struct rt2880_pmx_func *func; | ||||
| 	int func_count; | ||||
| }; | ||||
| 
 | ||||
| extern struct rt2880_pmx_group *rt2880_pinmux_data; | ||||
| 
 | ||||
| #endif | ||||
|  | @ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg) | |||
| 	return __raw_readl(rt_sysc_membase + reg); | ||||
| } | ||||
| 
 | ||||
| static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg) | ||||
| { | ||||
| 	u32 val = rt_sysc_r32(reg) & ~clr; | ||||
| 
 | ||||
| 	__raw_writel(val | set, rt_sysc_membase + reg); | ||||
| } | ||||
| 
 | ||||
| static inline void rt_memc_w32(u32 val, unsigned reg) | ||||
| { | ||||
| 	__raw_writel(val, rt_memc_membase + reg); | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Linus Torvalds
				Linus Torvalds