From 2623899459da55a0bbec247a5e3664cb798be241 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 12 May 2015 13:05:18 +0200 Subject: MIPS: BCM47xx: Read board info for all bcma buses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extra bcma buses may be totally different models, see following dump: boardtype=0x0646 pci/1/1/boardtype=0x0545 pci/2/1/boardtype=0x62b We need to detect them properly to allow drivers apply some board specific hacks. [ralf@linux-mips.org: folded in Rafal's fix.] Signed-off-by: Rafał Miłecki Cc: linux-mips@linux-mips.org Cc: Hauke Mehrtens Patchwork: https://patchwork.linux-mips.org/patch/10028/ Patchwork: https://patchwork.linux-mips.org/patch/10048/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index 8ed77f618940..1461c10c1c4c 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -52,10 +52,6 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, const char *prefix); #endif -#ifdef CONFIG_BCM47XX_BCMA -void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, - const char *prefix); -#endif void bcm47xx_set_system_type(u16 chip_id); -- cgit v1.2.3 From e50f0e313548854c2709a5ba9c61623cf189a9a1 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 19 May 2015 09:50:30 +0100 Subject: MIPS: hazards: Add hazard macros for tlb read Add hazard macros to for the following hazards around tlbr (TLB read) instructions, which are used in TLB dumping code and some KVM TLB management code: - mtc0_tlbr_hazard Between mtc0 (Index) and tlbr. This is copied from mtc0_tlbw_hazard in all cases on the assumption that tlbr always has similar data user timings to tlbw. - tlb_read_hazard Between tlbr and mfc0 (various TLB registers). This is copied from tlbw_use_hazard in all cases on the assumption that tlbr has similar data writer characteristics to tlbw, and mfc0 has similar data user characteristics to loads and stores. Signed-off-by: James Hogan Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10078/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/hazards.h | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h index 4087b47ad1cb..7b99efd31074 100644 --- a/arch/mips/include/asm/hazards.h +++ b/arch/mips/include/asm/hazards.h @@ -31,9 +31,15 @@ #define __mtc0_tlbw_hazard \ ___ehb +#define __mtc0_tlbr_hazard \ + ___ehb + #define __tlbw_use_hazard \ ___ehb +#define __tlb_read_hazard \ + ___ehb + #define __tlb_probe_hazard \ ___ehb @@ -80,12 +86,23 @@ do { \ ___ssnop; \ ___ehb +#define __mtc0_tlbr_hazard \ + ___ssnop; \ + ___ssnop; \ + ___ehb + #define __tlbw_use_hazard \ ___ssnop; \ ___ssnop; \ ___ssnop; \ ___ehb +#define __tlb_read_hazard \ + ___ssnop; \ + ___ssnop; \ + ___ssnop; \ + ___ehb + #define __tlb_probe_hazard \ ___ssnop; \ ___ssnop; \ @@ -147,8 +164,12 @@ do { \ #define __mtc0_tlbw_hazard +#define __mtc0_tlbr_hazard + #define __tlbw_use_hazard +#define __tlb_read_hazard + #define __tlb_probe_hazard #define __irq_enable_hazard @@ -166,8 +187,12 @@ do { \ */ #define __mtc0_tlbw_hazard +#define __mtc0_tlbr_hazard + #define __tlbw_use_hazard +#define __tlb_read_hazard + #define __tlb_probe_hazard #define __irq_enable_hazard @@ -196,11 +221,20 @@ do { \ nop; \ nop +#define __mtc0_tlbr_hazard \ + nop; \ + nop + #define __tlbw_use_hazard \ nop; \ nop; \ nop +#define __tlb_read_hazard \ + nop; \ + nop; \ + nop + #define __tlb_probe_hazard \ nop; \ nop; \ @@ -267,7 +301,9 @@ do { \ #define _ssnop ___ssnop #define _ehb ___ehb #define mtc0_tlbw_hazard __mtc0_tlbw_hazard +#define mtc0_tlbr_hazard __mtc0_tlbr_hazard #define tlbw_use_hazard __tlbw_use_hazard +#define tlb_read_hazard __tlb_read_hazard #define tlb_probe_hazard __tlb_probe_hazard #define irq_enable_hazard __irq_enable_hazard #define irq_disable_hazard __irq_disable_hazard @@ -300,6 +336,14 @@ do { \ } while (0) +#define mtc0_tlbr_hazard() \ +do { \ + __asm__ __volatile__( \ + __stringify(__mtc0_tlbr_hazard) \ + ); \ +} while (0) + + #define tlbw_use_hazard() \ do { \ __asm__ __volatile__( \ @@ -308,6 +352,14 @@ do { \ } while (0) +#define tlb_read_hazard() \ +do { \ + __asm__ __volatile__( \ + __stringify(__tlb_read_hazard) \ + ); \ +} while (0) + + #define tlb_probe_hazard() \ do { \ __asm__ __volatile__( \ -- cgit v1.2.3 From 8ab6abcb6aa475f458a3a81a69cca17840daafd1 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 19 May 2015 09:50:31 +0100 Subject: MIPS: mipsregs.h: Add EntryLo bit definitions Add definitions for EntryLo register bits in mipsregs.h. The R4000 compatible ones are prefixed MIPS_ENTRYLO_ and the R3000 compatible ones are prefixed R3K_ENTRYLO_. These will be used in later patches. Signed-off-by: James Hogan Cc: linux-mips@linux-mips.org Cc: Maciej W. Rozycki Patchwork: https://patchwork.linux-mips.org/patch/10073/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mipsregs.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 764e2756b54d..3b5a145af659 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -589,6 +589,28 @@ /* EntryHI bit definition */ #define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10) +/* R3000 EntryLo bit definitions */ +#define R3K_ENTRYLO_G (_ULCAST_(1) << 8) +#define R3K_ENTRYLO_V (_ULCAST_(1) << 9) +#define R3K_ENTRYLO_D (_ULCAST_(1) << 10) +#define R3K_ENTRYLO_N (_ULCAST_(1) << 11) + +/* R4000 compatible EntryLo bit definitions */ +#define MIPS_ENTRYLO_G (_ULCAST_(1) << 0) +#define MIPS_ENTRYLO_V (_ULCAST_(1) << 1) +#define MIPS_ENTRYLO_D (_ULCAST_(1) << 2) +#define MIPS_ENTRYLO_C_SHIFT 3 +#define MIPS_ENTRYLO_C (_ULCAST_(7) << MIPS_ENTRYLO_C_SHIFT) +#ifdef CONFIG_64BIT +/* as read by dmfc0 */ +#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 62) +#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 63) +#else +/* as read by mfc0 */ +#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 30) +#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 31) +#endif + /* CMGCRBase bit definitions */ #define MIPS_CMGCRB_BASE 11 #define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1)) -- cgit v1.2.3 From bc4f12e639da2b2c3a432900aca1952497fb066b Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 27 May 2015 14:15:31 +0100 Subject: MIPS: DEC: Update CPU overrides Update CPU overrides for the DEC port with the recent additions, shaving off some effectively dead code: text data bss dec hex filename 5586952 233132 5990368 11810452 b43694 vmlinux.32-old 5581248 233140 5990368 11804756 b42054 vmlinux.32-new text data bss dec hex filename 6036936 356648 10756544 17150128 105b0b0 vmlinux.64-old 6029896 360752 10756544 17147192 105a538 vmlinux.64-new The data size increase is due to the special alignment requirement of `init_thread_union' aka `.data..init_task' moving it up to the nearest page boundary and making the amount of padding at its front rely on how far within a page text ends. Signed-off-by: Maciej W. Rozycki Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10197/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-dec/cpu-feature-overrides.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h index bdf045fb00c8..21eae03d752a 100644 --- a/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-dec/cpu-feature-overrides.h @@ -14,6 +14,13 @@ /* Generic ones first. */ #define cpu_has_tlb 1 +#define cpu_has_tlbinv 0 +#define cpu_has_segments 0 +#define cpu_has_eva 0 +#define cpu_has_htw 0 +#define cpu_has_rixiex 0 +#define cpu_has_maar 0 +#define cpu_has_rw_llb 0 #define cpu_has_tx39_cache 0 #define cpu_has_divec 0 #define cpu_has_prefetch 0 @@ -24,6 +31,7 @@ #define cpu_has_mips3d 0 #define cpu_has_smartmips 0 #define cpu_has_rixi 0 +#define cpu_has_xpa 0 #define cpu_has_vtag_icache 0 #define cpu_has_ic_fills_f_dc 0 #define cpu_has_pindexed_dcache 0 @@ -36,11 +44,18 @@ #define cpu_has_mips64r1 0 #define cpu_has_mips64r2 0 #define cpu_has_dsp 0 +#define cpu_has_dsp2 0 #define cpu_has_mipsmt 0 #define cpu_has_userlocal 0 +#define cpu_hwrena_impl_bits 0 +#define cpu_has_perf_cntr_intr_bit 0 +#define cpu_has_vz 0 +#define cpu_has_fre 0 +#define cpu_has_cdmm 0 /* R3k-specific ones. */ #ifdef CONFIG_CPU_R3000 +#define cpu_has_3kex 1 #define cpu_has_4kex 0 #define cpu_has_3k_cache 1 #define cpu_has_4k_cache 0 @@ -63,6 +78,7 @@ /* R4k-specific ones. */ #ifdef CONFIG_CPU_R4X00 +#define cpu_has_3kex 0 #define cpu_has_4kex 1 #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 -- cgit v1.2.3 From 252617a4ab714db824876e3f9b2b2ede6623e9dc Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:14 +0100 Subject: MIPS: ingenic: Add newer vendor IDs Ingenic have actually varied the vendor/company ID of the XBurst cores across their range of SoCs, whilst keeping the product ID & revision constant... Add definitions for vendor IDs known to be used in some of Ingenic's newer SoCs, and handle them in the same way as the existing Ingenic vendor ID from the JZ4740. Signed-off-by: Paul Burton Co-authored-by: Paul Cercueil Cc: Lars-Peter Clausen Cc: linux-mips@linux-mips.org Cc: Steven J. Hill Cc: Joshua Kinard Cc: Leonid Yegoshin Cc: Maciej W. Rozycki Cc: linux-kernel@vger.kernel.org Cc: Huacai Chen Cc: Markos Chandras Patchwork: https://patchwork.linux-mips.org/patch/10128/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/cpu.h | 6 ++++-- arch/mips/kernel/cpu-probe.c | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index e3adca1d0b99..73dd35787d1a 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -42,7 +42,9 @@ #define PRID_COMP_LEXRA 0x0b0000 #define PRID_COMP_NETLOGIC 0x0c0000 #define PRID_COMP_CAVIUM 0x0d0000 -#define PRID_COMP_INGENIC 0xd00000 +#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */ +#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */ +#define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */ /* * Assigned Processor ID (implementation) values for bits 15:8 of the PRId @@ -168,7 +170,7 @@ #define PRID_IMP_CAVIUM_CN70XX 0x9600 /* - * These are the PRID's for when 23:16 == PRID_COMP_INGENIC + * These are the PRID's for when 23:16 == PRID_COMP_INGENIC_* */ #define PRID_IMP_JZRISC 0x0200 diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 209e5b76c1bc..f89eaa79785a 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1443,7 +1443,9 @@ void cpu_probe(void) case PRID_COMP_CAVIUM: cpu_probe_cavium(c, cpu); break; - case PRID_COMP_INGENIC: + case PRID_COMP_INGENIC_D0: + case PRID_COMP_INGENIC_D1: + case PRID_COMP_INGENIC_E1: cpu_probe_ingenic(c, cpu); break; case PRID_COMP_NETLOGIC: -- cgit v1.2.3 From 67e38cf2933e904426b428431961e4880d6d4b90 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 26 May 2015 18:20:06 +0200 Subject: MIPS/IRQCHIP: Move irq_chip from arch/mips to drivers/irqchip. While at it, rename it because in drivers/irqchip no longer every CPU is a MIPS. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 60 +++++------ arch/mips/include/asm/irqflags.h | 4 +- arch/mips/include/asm/mach-generic/irq.h | 4 +- arch/mips/include/asm/txx9irq.h | 2 +- arch/mips/kernel/Makefile | 1 - arch/mips/kernel/irq_cpu.c | 169 ------------------------------- arch/mips/loongson/Kconfig | 6 +- arch/mips/loongson1/Kconfig | 2 +- arch/mips/sibyte/Kconfig | 16 +-- arch/mips/txx9/Kconfig | 2 +- arch/mips/vr41xx/Kconfig | 10 +- drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-mips-cpu.c | 169 +++++++++++++++++++++++++++++++ 14 files changed, 226 insertions(+), 225 deletions(-) delete mode 100644 arch/mips/kernel/irq_cpu.c create mode 100644 drivers/irqchip/irq-mips-cpu.c (limited to 'arch/mips/include') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9501d814ded5..5fcfc6d989f4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -71,7 +71,7 @@ config MIPS_ALCHEMY select ARCH_PHYS_ADDR_T_64BIT select CEVT_R4K select CSRC_R4K - select IRQ_CPU + select IRQ_MIPS_CPU select DMA_MAYBE_COHERENT # Au1000,1500,1100 aren't, rest is select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL @@ -86,7 +86,7 @@ config AR7 select DMA_NONCOHERENT select CEVT_R4K select CSRC_R4K - select IRQ_CPU + select IRQ_MIPS_CPU select NO_EXCEPT_FILL select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 @@ -107,7 +107,7 @@ config ATH25 select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select IRQ_DOMAIN select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_BIG_ENDIAN @@ -125,7 +125,7 @@ config ATH79 select DMA_NONCOHERENT select HAVE_CLK select CLKDEV_LOOKUP - select IRQ_CPU + select IRQ_MIPS_CPU select MIPS_MACHINE select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_EARLY_PRINTK @@ -147,7 +147,7 @@ config BMIPS_GENERIC select BCM7038_L1_IRQ select BCM7120_L2_IRQ select BRCMSTB_L2_IRQ - select IRQ_CPU + select IRQ_MIPS_CPU select RAW_IRQ_ACCESSORS select DMA_NONCOHERENT select SYS_SUPPORTS_32BIT_KERNEL @@ -177,7 +177,7 @@ config BCM47XX select CSRC_R4K select DMA_NONCOHERENT select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select SYS_HAS_CPU_MIPS32_R1 select NO_EXCEPT_FILL select SYS_SUPPORTS_32BIT_KERNEL @@ -197,7 +197,7 @@ config BCM63XX select CSRC_R4K select SYNC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_HAS_EARLY_PRINTK @@ -217,7 +217,7 @@ config MIPS_COBALT select HW_HAS_PCI select I8253 select I8259 - select IRQ_CPU + select IRQ_MIPS_CPU select IRQ_GT641XX select PCI_GT64XXX_PCI0 select PCI @@ -240,7 +240,7 @@ config MACH_DECSTATION select CPU_R4400_WORKAROUNDS if 64BIT select DMA_NONCOHERENT select NO_IOPORT_MAP - select IRQ_CPU + select IRQ_MIPS_CPU select SYS_HAS_CPU_R3000 select SYS_HAS_CPU_R4X00 select SYS_SUPPORTS_32BIT_KERNEL @@ -275,7 +275,7 @@ config MACH_JAZZ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN select GENERIC_ISA_DMA select HAVE_PCSPKR_PLATFORM - select IRQ_CPU + select IRQ_MIPS_CPU select I8253 select I8259 select ISA @@ -295,7 +295,7 @@ config MACH_INGENIC select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_ZBOOT_UART16550 select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select ARCH_REQUIRE_GPIOLIB select SYS_HAS_EARLY_PRINTK select HAVE_CLK @@ -306,7 +306,7 @@ config MACH_INGENIC config LANTIQ bool "Lantiq based platforms" select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select CEVT_R4K select CSRC_R4K select SYS_HAS_CPU_MIPS32_R1 @@ -335,7 +335,7 @@ config LASAT select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select PCI_GT64XXX_PCI0 select MIPS_NILE4 select R5000_CPU_SCACHE @@ -375,7 +375,7 @@ config MACH_PISTACHIO select COMMON_CLK select CSRC_R4K select DMA_MAYBE_COHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select LIBFDT select MFD_SYSCON select MIPS_CPU_SCACHE @@ -403,7 +403,7 @@ config MIPS_MALTA select DMA_MAYBE_COHERENT select GENERIC_ISA_DMA select HAVE_PCSPKR_PLATFORM - select IRQ_CPU + select IRQ_MIPS_CPU select MIPS_GIC select HW_HAS_PCI select I8253 @@ -451,7 +451,7 @@ config MIPS_SEAD3 select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select MIPS_GIC select LIBFDT select MIPS_MSC @@ -514,7 +514,7 @@ config PMC_MSP select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 - select IRQ_CPU + select IRQ_MIPS_CPU select SERIAL_8250 select SERIAL_8250_CONSOLE select USB_EHCI_BIG_ENDIAN_MMIO @@ -531,7 +531,7 @@ config RALINK select CSRC_R4K select BOOT_RAW select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select USE_OF select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 @@ -557,7 +557,7 @@ config SGI_IP22 select I8253 select I8259 select IP22_CPU_SCACHE - select IRQ_CPU + select IRQ_MIPS_CPU select GENERIC_ISA_DMA_SUPPORT_BROKEN select SGI_HAS_I8042 select SGI_HAS_INDYDOG @@ -616,7 +616,7 @@ config SGI_IP28 select DEFAULT_SGI_PARTITION select DMA_NONCOHERENT select GENERIC_ISA_DMA_SUPPORT_BROKEN - select IRQ_CPU + select IRQ_MIPS_CPU select HW_HAS_EISA select I8253 select I8259 @@ -652,7 +652,7 @@ config SGI_IP32 select CSRC_R4K select DMA_NONCOHERENT select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select R5000_CPU_SCACHE select RM7000_CPU_SCACHE select SYS_HAS_CPU_R5000 @@ -768,7 +768,7 @@ config SNI_RM select HAVE_PCSPKR_PLATFORM select HW_HAS_EISA select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select I8253 select I8259 select ISA @@ -801,7 +801,7 @@ config MIKROTIK_RB532 select CSRC_R4K select DMA_NONCOHERENT select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -867,7 +867,7 @@ config NLM_XLR_BOARD select NR_CPUS_DEFAULT_32 select CEVT_R4K select CSRC_R4K - select IRQ_CPU + select IRQ_MIPS_CPU select ZONE_DMA32 if 64BIT select SYNC_R4K select SYS_HAS_EARLY_PRINTK @@ -894,7 +894,7 @@ config NLM_XLP_BOARD select NR_CPUS_DEFAULT_32 select CEVT_R4K select CSRC_R4K - select IRQ_CPU + select IRQ_MIPS_CPU select ZONE_DMA32 if 64BIT select SYNC_R4K select SYS_HAS_EARLY_PRINTK @@ -1143,10 +1143,6 @@ config SYS_SUPPORTS_HUGETLBFS config MIPS_HUGE_TLB_SUPPORT def_bool HUGETLB_PAGE || TRANSPARENT_HUGEPAGE -config IRQ_CPU - bool - select IRQ_DOMAIN - config IRQ_CPU_RM7K bool @@ -1173,7 +1169,7 @@ config SOC_EMMA2RH select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select SWAP_IO_SPACE select SYS_HAS_CPU_R5500 select SYS_SUPPORTS_32BIT_KERNEL @@ -1184,7 +1180,7 @@ config SOC_PNX833X bool select CEVT_R4K select CSRC_R4K - select IRQ_CPU + select IRQ_MIPS_CPU select DMA_NONCOHERENT select SYS_HAS_CPU_MIPS32_R2 select SYS_SUPPORTS_32BIT_KERNEL @@ -1588,7 +1584,7 @@ config CPU_BMIPS select CPU_BMIPS5000 if SYS_HAS_CPU_BMIPS5000 select CPU_SUPPORTS_32BIT_KERNEL select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select SWAP_IO_SPACE select WEAK_ORDERING select CPU_SUPPORTS_HIGHMEM diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index d60cc68fa31e..e7b138b4b3d3 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -60,7 +60,7 @@ static inline void arch_local_irq_restore(unsigned long flags) " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_IRQ_CPU) +#if defined(CONFIG_IRQ_MIPS_CPU) /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. @@ -90,7 +90,7 @@ static inline void __arch_local_irq_restore(unsigned long flags) " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_IRQ_CPU) +#if defined(CONFIG_IRQ_MIPS_CPU) /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h index 050e18bb1a04..be546a0f65fa 100644 --- a/arch/mips/include/asm/mach-generic/irq.h +++ b/arch/mips/include/asm/mach-generic/irq.h @@ -18,7 +18,7 @@ #endif #endif -#ifdef CONFIG_IRQ_CPU +#ifdef CONFIG_IRQ_MIPS_CPU #ifndef MIPS_CPU_IRQ_BASE #ifdef CONFIG_I8259 @@ -34,7 +34,7 @@ #endif #endif -#endif /* CONFIG_IRQ_CPU */ +#endif /* CONFIG_IRQ_MIPS_CPU */ #ifdef CONFIG_MIPS_GIC #ifndef MIPS_GIC_IRQ_BASE diff --git a/arch/mips/include/asm/txx9irq.h b/arch/mips/include/asm/txx9irq.h index 5620879be37f..68a6650a4025 100644 --- a/arch/mips/include/asm/txx9irq.h +++ b/arch/mips/include/asm/txx9irq.h @@ -11,7 +11,7 @@ #include -#ifdef CONFIG_IRQ_CPU +#ifdef CONFIG_IRQ_MIPS_CPU #define TXX9_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) #else #ifdef CONFIG_I8259 diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index a2debcbedb6d..3f5cf8aff6f3 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -62,7 +62,6 @@ obj-$(CONFIG_MIPS_VPE_APSP_API_CMP) += rtlx-cmp.o obj-$(CONFIG_MIPS_VPE_APSP_API_MT) += rtlx-mt.o obj-$(CONFIG_I8259) += i8259.o -obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o obj-$(CONFIG_MIPS_MSC) += irq-msc01.o obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c deleted file mode 100644 index 6eb7a3f515fc..000000000000 --- a/arch/mips/kernel/irq_cpu.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * Copyright (C) 2001 Ralf Baechle - * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. - * Author: Maciej W. Rozycki - * - * This file define the irq handler for MIPS CPU interrupts. - * - * 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. - */ - -/* - * Almost all MIPS CPUs define 8 interrupt sources. They are typically - * level triggered (i.e., cannot be cleared from CPU; must be cleared from - * device). The first two are software interrupts which we don't really - * use or support. The last one is usually the CPU timer interrupt if - * counter register is present or, for CPUs with an external FPU, by - * convention it's the FPU exception interrupt. - * - * Don't even think about using this on SMP. You have been warned. - * - * This file exports one global function: - * void mips_cpu_irq_init(void); - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static inline void unmask_mips_irq(struct irq_data *d) -{ - set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); - irq_enable_hazard(); -} - -static inline void mask_mips_irq(struct irq_data *d) -{ - clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); - irq_disable_hazard(); -} - -static struct irq_chip mips_cpu_irq_controller = { - .name = "MIPS", - .irq_ack = mask_mips_irq, - .irq_mask = mask_mips_irq, - .irq_mask_ack = mask_mips_irq, - .irq_unmask = unmask_mips_irq, - .irq_eoi = unmask_mips_irq, - .irq_disable = mask_mips_irq, - .irq_enable = unmask_mips_irq, -}; - -/* - * Basically the same as above but taking care of all the MT stuff - */ - -static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d) -{ - unsigned int vpflags = dvpe(); - - clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); - evpe(vpflags); - unmask_mips_irq(d); - return 0; -} - -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for mips_cpu_irq_end. - */ -static void mips_mt_cpu_irq_ack(struct irq_data *d) -{ - unsigned int vpflags = dvpe(); - clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); - evpe(vpflags); - mask_mips_irq(d); -} - -static struct irq_chip mips_mt_cpu_irq_controller = { - .name = "MIPS", - .irq_startup = mips_mt_cpu_irq_startup, - .irq_ack = mips_mt_cpu_irq_ack, - .irq_mask = mask_mips_irq, - .irq_mask_ack = mips_mt_cpu_irq_ack, - .irq_unmask = unmask_mips_irq, - .irq_eoi = unmask_mips_irq, - .irq_disable = mask_mips_irq, - .irq_enable = unmask_mips_irq, -}; - -asmlinkage void __weak plat_irq_dispatch(void) -{ - unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM; - int irq; - - if (!pending) { - spurious_interrupt(); - return; - } - - pending >>= CAUSEB_IP; - while (pending) { - irq = fls(pending) - 1; - do_IRQ(MIPS_CPU_IRQ_BASE + irq); - pending &= ~BIT(irq); - } -} - -static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) -{ - static struct irq_chip *chip; - - if (hw < 2 && cpu_has_mipsmt) { - /* Software interrupts are used for MT/CMT IPI */ - chip = &mips_mt_cpu_irq_controller; - } else { - chip = &mips_cpu_irq_controller; - } - - if (cpu_has_vint) - set_vi_handler(hw, plat_irq_dispatch); - - irq_set_chip_and_handler(irq, chip, handle_percpu_irq); - - return 0; -} - -static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = { - .map = mips_cpu_intc_map, - .xlate = irq_domain_xlate_onecell, -}; - -static void __init __mips_cpu_irq_init(struct device_node *of_node) -{ - struct irq_domain *domain; - - /* Mask interrupts. */ - clear_c0_status(ST0_IM); - clear_c0_cause(CAUSEF_IP); - - domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0, - &mips_cpu_intc_irq_domain_ops, NULL); - if (!domain) - panic("Failed to add irqdomain for MIPS CPU"); -} - -void __init mips_cpu_irq_init(void) -{ - __mips_cpu_irq_init(NULL); -} - -int __init mips_cpu_irq_of_init(struct device_node *of_node, - struct device_node *parent) -{ - __mips_cpu_irq_init(of_node); - return 0; -} diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 156de85b82cd..506414915463 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig @@ -15,7 +15,7 @@ config LEMOTE_FULOONG2E select HW_HAS_PCI select I8259 select ISA - select IRQ_CPU + select IRQ_MIPS_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -44,7 +44,7 @@ config LEMOTE_MACH2F select HAVE_CLK select HW_HAS_PCI select I8259 - select IRQ_CPU + select IRQ_MIPS_CPU select ISA select SYS_HAS_CPU_LOONGSON2F select SYS_HAS_EARLY_PRINTK @@ -73,7 +73,7 @@ config LOONGSON_MACH3X select ISA select HT_PCI select I8259 - select IRQ_CPU + select IRQ_MIPS_CPU select NR_CPUS_DEFAULT_4 select SYS_HAS_CPU_LOONGSON3 select SYS_HAS_EARLY_PRINTK diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig index a2b796eaf3c3..aeecdd9fac9f 100644 --- a/arch/mips/loongson1/Kconfig +++ b/arch/mips/loongson1/Kconfig @@ -10,7 +10,7 @@ config LOONGSON1_LS1B select SYS_HAS_CPU_LOONGSON1B select DMA_NONCOHERENT select BOOT_ELF32 - select IRQ_CPU + select IRQ_MIPS_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index 5fbd3605d24f..a8bb972fd9fd 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -3,7 +3,7 @@ config SIBYTE_SB1250 select CEVT_SB1250 select CSRC_SB1250 select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select SIBYTE_ENABLE_LDT_IF_PCI select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC @@ -13,7 +13,7 @@ config SIBYTE_BCM1120 bool select CEVT_SB1250 select CSRC_SB1250 - select IRQ_CPU + select IRQ_MIPS_CPU select SIBYTE_BCM112X select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC @@ -23,7 +23,7 @@ config SIBYTE_BCM1125 select CEVT_SB1250 select CSRC_SB1250 select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select SIBYTE_BCM112X select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC @@ -33,7 +33,7 @@ config SIBYTE_BCM1125H select CEVT_SB1250 select CSRC_SB1250 select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select SIBYTE_BCM112X select SIBYTE_ENABLE_LDT_IF_PCI select SIBYTE_HAS_ZBUS_PROFILING @@ -43,7 +43,7 @@ config SIBYTE_BCM112X bool select CEVT_SB1250 select CSRC_SB1250 - select IRQ_CPU + select IRQ_MIPS_CPU select SIBYTE_SB1xxx_SOC select SIBYTE_HAS_ZBUS_PROFILING @@ -52,7 +52,7 @@ config SIBYTE_BCM1x80 select CEVT_BCM1480 select CSRC_BCM1480 select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC select SYS_SUPPORTS_SMP @@ -62,7 +62,7 @@ config SIBYTE_BCM1x55 select CEVT_BCM1480 select CSRC_BCM1480 select HW_HAS_PCI - select IRQ_CPU + select IRQ_MIPS_CPU select SIBYTE_SB1xxx_SOC select SIBYTE_HAS_ZBUS_PROFILING select SYS_SUPPORTS_SMP @@ -70,7 +70,7 @@ config SIBYTE_BCM1x55 config SIBYTE_SB1xxx_SOC bool select DMA_COHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select SWAP_IO_SPACE select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 6d40bc783459..8c337d60f790 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -8,7 +8,7 @@ config MACH_TX49XX select MACH_TXX9 select CEVT_R4K select CSRC_R4K - select IRQ_CPU + select IRQ_MIPS_CPU select SYS_HAS_CPU_TX49XX select SYS_SUPPORTS_64BIT_KERNEL diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index c1be6b37fb2a..74927b4d4f0b 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig @@ -8,7 +8,7 @@ config CASIO_E55 select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -18,7 +18,7 @@ config IBM_WORKPAD select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -28,7 +28,7 @@ config TANBAC_TB022X select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select HW_HAS_PCI select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -44,7 +44,7 @@ config VICTOR_MPC30X select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select HW_HAS_PCI select PCI_VR41XX select SYS_SUPPORTS_32BIT_KERNEL @@ -55,7 +55,7 @@ config ZAO_CAPCELLA select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT - select IRQ_CPU + select IRQ_MIPS_CPU select HW_HAS_PCI select PCI_VR41XX select SYS_SUPPORTS_32BIT_KERNEL diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 6de62a96e79c..2b7531e0e84c 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -85,6 +85,11 @@ config IMGPDC_IRQ select GENERIC_IRQ_CHIP select IRQ_DOMAIN +config IRQ_MIPS_CPU + bool + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN + config CLPS711X_IRQCHIP bool depends on ARCH_CLPS711X diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index dda4927e47a6..129cde1ff5a7 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_ARM_VIC) += irq-vic.o obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o +obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c new file mode 100644 index 000000000000..6eb7a3f515fc --- /dev/null +++ b/drivers/irqchip/irq-mips-cpu.c @@ -0,0 +1,169 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2001 Ralf Baechle + * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. + * Author: Maciej W. Rozycki + * + * This file define the irq handler for MIPS CPU interrupts. + * + * 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. + */ + +/* + * Almost all MIPS CPUs define 8 interrupt sources. They are typically + * level triggered (i.e., cannot be cleared from CPU; must be cleared from + * device). The first two are software interrupts which we don't really + * use or support. The last one is usually the CPU timer interrupt if + * counter register is present or, for CPUs with an external FPU, by + * convention it's the FPU exception interrupt. + * + * Don't even think about using this on SMP. You have been warned. + * + * This file exports one global function: + * void mips_cpu_irq_init(void); + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static inline void unmask_mips_irq(struct irq_data *d) +{ + set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); + irq_enable_hazard(); +} + +static inline void mask_mips_irq(struct irq_data *d) +{ + clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); + irq_disable_hazard(); +} + +static struct irq_chip mips_cpu_irq_controller = { + .name = "MIPS", + .irq_ack = mask_mips_irq, + .irq_mask = mask_mips_irq, + .irq_mask_ack = mask_mips_irq, + .irq_unmask = unmask_mips_irq, + .irq_eoi = unmask_mips_irq, + .irq_disable = mask_mips_irq, + .irq_enable = unmask_mips_irq, +}; + +/* + * Basically the same as above but taking care of all the MT stuff + */ + +static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d) +{ + unsigned int vpflags = dvpe(); + + clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); + evpe(vpflags); + unmask_mips_irq(d); + return 0; +} + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for mips_cpu_irq_end. + */ +static void mips_mt_cpu_irq_ack(struct irq_data *d) +{ + unsigned int vpflags = dvpe(); + clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); + evpe(vpflags); + mask_mips_irq(d); +} + +static struct irq_chip mips_mt_cpu_irq_controller = { + .name = "MIPS", + .irq_startup = mips_mt_cpu_irq_startup, + .irq_ack = mips_mt_cpu_irq_ack, + .irq_mask = mask_mips_irq, + .irq_mask_ack = mips_mt_cpu_irq_ack, + .irq_unmask = unmask_mips_irq, + .irq_eoi = unmask_mips_irq, + .irq_disable = mask_mips_irq, + .irq_enable = unmask_mips_irq, +}; + +asmlinkage void __weak plat_irq_dispatch(void) +{ + unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM; + int irq; + + if (!pending) { + spurious_interrupt(); + return; + } + + pending >>= CAUSEB_IP; + while (pending) { + irq = fls(pending) - 1; + do_IRQ(MIPS_CPU_IRQ_BASE + irq); + pending &= ~BIT(irq); + } +} + +static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + static struct irq_chip *chip; + + if (hw < 2 && cpu_has_mipsmt) { + /* Software interrupts are used for MT/CMT IPI */ + chip = &mips_mt_cpu_irq_controller; + } else { + chip = &mips_cpu_irq_controller; + } + + if (cpu_has_vint) + set_vi_handler(hw, plat_irq_dispatch); + + irq_set_chip_and_handler(irq, chip, handle_percpu_irq); + + return 0; +} + +static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = { + .map = mips_cpu_intc_map, + .xlate = irq_domain_xlate_onecell, +}; + +static void __init __mips_cpu_irq_init(struct device_node *of_node) +{ + struct irq_domain *domain; + + /* Mask interrupts. */ + clear_c0_status(ST0_IM); + clear_c0_cause(CAUSEF_IP); + + domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0, + &mips_cpu_intc_irq_domain_ops, NULL); + if (!domain) + panic("Failed to add irqdomain for MIPS CPU"); +} + +void __init mips_cpu_irq_init(void) +{ + __mips_cpu_irq_init(NULL); +} + +int __init mips_cpu_irq_of_init(struct device_node *of_node, + struct device_node *parent) +{ + __mips_cpu_irq_init(of_node); + return 0; +} -- cgit v1.2.3 From 0e81db8f5b1abd7245e13b585458ea2fb9826bdd Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:19 +0100 Subject: MIPS: JZ4740: Move arch_init_irq out of arch/mips/jz4740/irq.c In preparation for moving the JZ4740 interrupt controller driver to drivers/irqchip, move arch_init_irq into setup.c such that everything remaining in irq.c is related to said JZ4740 interrupt controller. Signed-off-by: Paul Burton Cc: Lars-Peter Clausen Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: Brian Norris Patchwork: https://patchwork.linux-mips.org/patch/10136/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-jz4740/irq.h | 2 ++ arch/mips/jz4740/irq.c | 5 +---- arch/mips/jz4740/setup.c | 8 ++++++++ 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h index df50736749c1..5ce430218e42 100644 --- a/arch/mips/include/asm/mach-jz4740/irq.h +++ b/arch/mips/include/asm/mach-jz4740/irq.h @@ -54,4 +54,6 @@ #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6) +extern void __init jz4740_intc_init(void); + #endif diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c index a2452bb80e1d..bac1f52d327f 100644 --- a/arch/mips/jz4740/irq.c +++ b/arch/mips/jz4740/irq.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -78,13 +77,11 @@ static struct irqaction jz4740_cascade_action = { .name = "JZ4740 cascade interrupt", }; -void __init arch_init_irq(void) +void __init jz4740_intc_init(void) { struct irq_chip_generic *gc; struct irq_chip_type *ct; - irqchip_init(); - jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14); /* Mask all irqs */ diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index d6bb7a39fafe..480873031007 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include +#include #include "reset.h" @@ -78,3 +80,9 @@ const char *get_system_type(void) { return "JZ4740"; } + +void __init arch_init_irq(void) +{ + irqchip_init(); + jz4740_intc_init(); +} -- cgit v1.2.3 From adbdce77ccc345e6ae86f6887212af13983a626e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:21 +0100 Subject: MIPS: JZ4740: probe interrupt controller via DT Declare the JZ4740 interrupt controller for probe via DT using the standard irqchip_init function, and make use of that function to probe the controller by adding the appropriate node to the JZ4740 dtsi. Signed-off-by: Paul Burton Cc: Ian Campbell Cc: Jason Cooper Cc: Kumar Gala Cc: Lars-Peter Clausen Cc: Mark Rutland Cc: Pawel Moll Cc: Rob Herring Cc: Thomas Gleixner Cc: devicetree@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: Brian Norris Patchwork: https://patchwork.linux-mips.org/patch/10135/ Signed-off-by: Ralf Baechle --- arch/mips/boot/dts/ingenic/jz4740.dtsi | 11 +++++++++++ arch/mips/include/asm/mach-jz4740/irq.h | 2 -- arch/mips/jz4740/irq.c | 8 +++++++- arch/mips/jz4740/setup.c | 2 -- 4 files changed, 18 insertions(+), 5 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi index dd3642fb924d..ba0e7e965b97 100644 --- a/arch/mips/boot/dts/ingenic/jz4740.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi @@ -9,4 +9,15 @@ interrupt-controller; compatible = "mti,cpu-interrupt-controller"; }; + + intc: interrupt-controller@10001000 { + compatible = "ingenic,jz4740-intc"; + reg = <0x10001000 0x14>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; }; diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h index 5ce430218e42..df50736749c1 100644 --- a/arch/mips/include/asm/mach-jz4740/irq.h +++ b/arch/mips/include/asm/mach-jz4740/irq.h @@ -54,6 +54,4 @@ #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6) -extern void __init jz4740_intc_init(void); - #endif diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c index bac1f52d327f..43e000aa8a2e 100644 --- a/arch/mips/jz4740/irq.c +++ b/arch/mips/jz4740/irq.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,8 @@ #include "irq.h" +#include "../../drivers/irqchip/irqchip.h" + static void __iomem *jz_intc_base; #define JZ_REG_INTC_STATUS 0x00 @@ -77,7 +80,8 @@ static struct irqaction jz4740_cascade_action = { .name = "JZ4740 cascade interrupt", }; -void __init jz4740_intc_init(void) +static int __init jz4740_intc_of_init(struct device_node *node, + struct device_node *parent) { struct irq_chip_generic *gc; struct irq_chip_type *ct; @@ -105,7 +109,9 @@ void __init jz4740_intc_init(void) irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL); setup_irq(2, &jz4740_cascade_action); + return 0; } +IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init); #ifdef CONFIG_DEBUG_FS diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 480873031007..8c08d7dcda66 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c @@ -25,7 +25,6 @@ #include #include -#include #include "reset.h" @@ -84,5 +83,4 @@ const char *get_system_type(void) void __init arch_init_irq(void) { irqchip_init(); - jz4740_intc_init(); } -- cgit v1.2.3 From ad68f8d3c2a1f61ce98665d6d0c1a2e52a75ea77 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:27 +0100 Subject: MIPS: JZ4740: define IRQ numbers based on number of intc IRQs For interrupts numbered after those of the interrupt controller, define their numbers based upon the number of interrupts provided by the SoC interrupt controller. This is in preparation for supporting newer Ingenic SoCs which provide more interrupts. Signed-off-by: Paul Burton Cc: Lars-Peter Clausen Cc: Thomas Gleixner Cc: Jason Cooper Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/10143/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-jz4740/irq.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h index df50736749c1..b218f76f55c4 100644 --- a/arch/mips/include/asm/mach-jz4740/irq.h +++ b/arch/mips/include/asm/mach-jz4740/irq.h @@ -19,6 +19,10 @@ #define MIPS_CPU_IRQ_BASE 0 #define JZ4740_IRQ_BASE 8 +#ifdef CONFIG_MACH_JZ4740 +# define NR_INTC_IRQS 32 +#endif + /* 1st-level interrupts */ #define JZ4740_IRQ(x) (JZ4740_IRQ_BASE + (x)) #define JZ4740_IRQ_I2C JZ4740_IRQ(1) @@ -45,12 +49,12 @@ #define JZ4740_IRQ_LCD JZ4740_IRQ(30) /* 2nd-level interrupts */ -#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (x)) +#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(NR_INTC_IRQS) + (x)) #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x)) -#define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x)) +#define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(NR_INTC_IRQS + 16) + (x)) -#define JZ4740_IRQ_ADC_BASE JZ4740_IRQ(176) +#define JZ4740_IRQ_ADC_BASE JZ4740_IRQ(NR_INTC_IRQS + 144) #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6) -- cgit v1.2.3 From 1f4b840983ffbd7053b5c2219deaf62b4b8a3c12 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:32 +0100 Subject: MIPS: JZ4740: Call jz4740_clock_init earlier Call jz4740_clock_init before any uses of jz4740_clock_bdata occur. This is in preparation for replacing uses of that struct with calls to clk_get_rate, which will allow the clocks to be migrated towards common clock framework & devicetree. Signed-off-by: Paul Burton Cc: Lars-Peter Clausen Cc: linux-mips@linux-mips.org Cc: Deng-Cheng Zhu Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/10148/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-jz4740/clock.h | 2 ++ arch/mips/jz4740/clock.c | 3 +-- arch/mips/jz4740/time.c | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h index 16659cd76d4e..01d846845f53 100644 --- a/arch/mips/include/asm/mach-jz4740/clock.h +++ b/arch/mips/include/asm/mach-jz4740/clock.h @@ -20,6 +20,8 @@ enum jz4740_wait_mode { JZ4740_WAIT_MODE_SLEEP, }; +int jz4740_clock_init(void); + void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode); void jz4740_clock_udc_enable_auto_suspend(void); diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c index 1b5f55426cad..c257073577a2 100644 --- a/arch/mips/jz4740/clock.c +++ b/arch/mips/jz4740/clock.c @@ -889,7 +889,7 @@ void jz4740_clock_resume(void) JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0); } -static int jz4740_clock_init(void) +int jz4740_clock_init(void) { uint32_t val; @@ -921,4 +921,3 @@ static int jz4740_clock_init(void) return 0; } -arch_initcall(jz4740_clock_init); diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index 72b0cecbc17c..78ed7652ef67 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -115,6 +116,7 @@ void __init plat_time_init(void) uint32_t clk_rate; uint16_t ctrl; + jz4740_clock_init(); jz4740_timer_init(); clk_rate = jz4740_clock_bdata.ext_rate >> 4; -- cgit v1.2.3 From 50d893ff7218e2298d91c0a637845d195d72ebcc Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:39 +0100 Subject: MIPS, clk: move jz4740 clock suspend, resume functions to jz4740-cgu The jz4740-cgu driver already has access to the CGU, so it makes sense to move the few remaining accesses to the CGU from arch/mips/jz4740 there too. Move the jz4740_clock_{suspend,resume} functions there for such consistency. The arch/mips/jz4740/clock.c file now contains nothing more of use & so is removed. Signed-off-by: Paul Burton Cc: Lars-Peter Clausen Cc: Mike Turquette Cc: Stephen Boyd Cc: linux-clk@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: Deng-Cheng Zhu Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/10158/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-jz4740/clock.h | 2 - arch/mips/jz4740/Makefile | 2 +- arch/mips/jz4740/clock.c | 95 ------------------------------- arch/mips/jz4740/time.c | 1 - drivers/clk/ingenic/jz4740-cgu.c | 37 ++++++++++++ 5 files changed, 38 insertions(+), 99 deletions(-) delete mode 100644 arch/mips/jz4740/clock.c (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h index 01d846845f53..16659cd76d4e 100644 --- a/arch/mips/include/asm/mach-jz4740/clock.h +++ b/arch/mips/include/asm/mach-jz4740/clock.h @@ -20,8 +20,6 @@ enum jz4740_wait_mode { JZ4740_WAIT_MODE_SLEEP, }; -int jz4740_clock_init(void); - void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode); void jz4740_clock_udc_enable_auto_suspend(void); diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index fdb12efc54a1..7636432af6ee 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile @@ -5,7 +5,7 @@ # Object file lists. obj-y += prom.o time.o reset.o setup.o \ - gpio.o clock.o platform.o timer.o serial.o + gpio.o platform.o timer.o serial.o # board specific support diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c deleted file mode 100644 index 2a1082920f46..000000000000 --- a/arch/mips/jz4740/clock.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen - * JZ4740 SoC clock 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "clock.h" - -#define JZ_REG_CLOCK_PLL 0x10 -#define JZ_REG_CLOCK_GATE 0x20 - -#define JZ_CLOCK_GATE_UART0 BIT(0) -#define JZ_CLOCK_GATE_TCU BIT(1) -#define JZ_CLOCK_GATE_DMAC BIT(12) - -#define JZ_CLOCK_PLL_STABLE BIT(10) -#define JZ_CLOCK_PLL_ENABLED BIT(8) - -static void __iomem *jz_clock_base; - -static uint32_t jz_clk_reg_read(int reg) -{ - return readl(jz_clock_base + reg); -} - -static void jz_clk_reg_set_bits(int reg, uint32_t mask) -{ - uint32_t val; - - val = readl(jz_clock_base + reg); - val |= mask; - writel(val, jz_clock_base + reg); -} - -static void jz_clk_reg_clear_bits(int reg, uint32_t mask) -{ - uint32_t val; - - val = readl(jz_clock_base + reg); - val &= ~mask; - writel(val, jz_clock_base + reg); -} - -void jz4740_clock_suspend(void) -{ - jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, - JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0); - - jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED); -} - -void jz4740_clock_resume(void) -{ - uint32_t pll; - - jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED); - - do { - pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL); - } while (!(pll & JZ_CLOCK_PLL_STABLE)); - - jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, - JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0); -} - -int jz4740_clock_init(void) -{ - jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100); - if (!jz_clock_base) - return -EBUSY; - - return 0; -} diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index be9b0a3a5c40..917255368db8 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c @@ -120,7 +120,6 @@ void __init plat_time_init(void) struct clk *ext_clk; of_clk_init(NULL); - jz4740_clock_init(); jz4740_timer_init(); ext_clk = clk_get(NULL, "ext"); diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 0e692ed632e5..305a26c2a800 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -264,3 +264,40 @@ void jz4740_clock_udc_enable_auto_suspend(void) writel(clkgr, cgu->base + CGU_REG_CLKGR); } EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend); + +#define JZ_CLOCK_GATE_UART0 BIT(0) +#define JZ_CLOCK_GATE_TCU BIT(1) +#define JZ_CLOCK_GATE_DMAC BIT(12) + +void jz4740_clock_suspend(void) +{ + uint32_t clkgr, cppcr; + + clkgr = readl(cgu->base + CGU_REG_CLKGR); + clkgr |= JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0; + writel(clkgr, cgu->base + CGU_REG_CLKGR); + + cppcr = readl(cgu->base + CGU_REG_CPPCR); + cppcr &= ~BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit); + writel(cppcr, cgu->base + CGU_REG_CPPCR); +} + +void jz4740_clock_resume(void) +{ + uint32_t clkgr, cppcr, stable; + + cppcr = readl(cgu->base + CGU_REG_CPPCR); + cppcr |= BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit); + writel(cppcr, cgu->base + CGU_REG_CPPCR); + + stable = BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.stable_bit); + do { + cppcr = readl(cgu->base + CGU_REG_CPPCR); + } while (!(cppcr & stable)); + + clkgr = readl(cgu->base + CGU_REG_CLKGR); + clkgr &= ~JZ_CLOCK_GATE_TCU; + clkgr &= ~JZ_CLOCK_GATE_DMAC; + clkgr &= ~JZ_CLOCK_GATE_UART0; + writel(clkgr, cgu->base + CGU_REG_CLKGR); +} -- cgit v1.2.3 From 1237496af309bc0551949418fb06f63d3b1f45b5 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:41 +0100 Subject: MIPS: JZ4740: remove clock.h The only thing remaining in arch/mips/jz4740/clock.h is declarations of the jz4740_clock_{suspend,resume} functions. Move these to arch/mips/include/asm/mach-jz4740/clock.h for consistency with similar functions, and remove the redundant arch/mips/jz4740/clock.h header. Signed-off-by: Paul Burton Cc: Lars-Peter Clausen Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/10156/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-jz4740/clock.h | 3 +++ arch/mips/jz4740/clock.h | 25 ------------------------- arch/mips/jz4740/pm.c | 2 -- 3 files changed, 3 insertions(+), 27 deletions(-) delete mode 100644 arch/mips/jz4740/clock.h (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h index 16659cd76d4e..104d2dfe1e36 100644 --- a/arch/mips/include/asm/mach-jz4740/clock.h +++ b/arch/mips/include/asm/mach-jz4740/clock.h @@ -22,6 +22,9 @@ enum jz4740_wait_mode { void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode); +void jz4740_clock_suspend(void); +void jz4740_clock_resume(void); + void jz4740_clock_udc_enable_auto_suspend(void); void jz4740_clock_udc_disable_auto_suspend(void); diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h deleted file mode 100644 index 86a3e010fa9c..000000000000 --- a/arch/mips/jz4740/clock.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen - * JZ4740 SoC clock 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef __MIPS_JZ4740_CLOCK_H__ -#define __MIPS_JZ4740_CLOCK_H__ - -#include -#include - -void jz4740_clock_suspend(void); -void jz4740_clock_resume(void); - -#endif diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c index d8e213010169..2d8653f2fc61 100644 --- a/arch/mips/jz4740/pm.c +++ b/arch/mips/jz4740/pm.c @@ -20,8 +20,6 @@ #include -#include "clock.h" - static int jz4740_pm_enter(suspend_state_t state) { jz4740_clock_suspend(); -- cgit v1.2.3 From 8838245d76b9bb2e20c9a7a977487d72c0117b9a Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:45 +0100 Subject: MIPS: JZ4740: use Ingenic SoC UART driver Remove the serial support from arch/mips/jz4740 & make use of the new Ingenic SoC UART driver. This is done for both regular & early console output. Signed-off-by: Paul Burton Cc: Ian Campbell Cc: Kumar Gala Cc: Lars-Peter Clausen Cc: Mark Rutland Cc: Pawel Moll Cc: Rob Herring Cc: devicetree@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: Linus Walleij Cc: Stephen Warren Cc: linux-kernel@vger.kernel.org Cc: Brian Norris Cc: Apelete Seketeli Cc: Alexandre Courbot Patchwork: https://patchwork.linux-mips.org/patch/10160/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 - arch/mips/boot/dts/ingenic/jz4740.dtsi | 22 ++++++++++++++ arch/mips/boot/dts/ingenic/qi_lb60.dts | 4 +++ arch/mips/configs/qi_lb60_defconfig | 1 + arch/mips/include/asm/mach-jz4740/platform.h | 2 -- arch/mips/jz4740/Makefile | 2 +- arch/mips/jz4740/board-qi_lb60.c | 2 -- arch/mips/jz4740/platform.c | 45 ---------------------------- arch/mips/jz4740/prom.c | 13 -------- arch/mips/jz4740/serial.c | 33 -------------------- arch/mips/jz4740/serial.h | 23 -------------- 11 files changed, 28 insertions(+), 120 deletions(-) delete mode 100644 arch/mips/jz4740/serial.c delete mode 100644 arch/mips/jz4740/serial.h (limited to 'arch/mips/include') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d5acb9e96d59..be384d6a58bb 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -297,7 +297,6 @@ config MACH_INGENIC select DMA_NONCOHERENT select IRQ_MIPS_CPU select ARCH_REQUIRE_GPIOLIB - select SYS_HAS_EARLY_PRINTK select COMMON_CLK select GENERIC_IRQ_CHIP select BUILTIN_DTB diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi index be0a86f15636..8b2437cd019f 100644 --- a/arch/mips/boot/dts/ingenic/jz4740.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi @@ -43,4 +43,26 @@ #clock-cells = <1>; }; + + uart0: serial@10030000 { + compatible = "ingenic,jz4740-uart"; + reg = <0x10030000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <9>; + + clocks = <&ext>, <&cgu JZ4740_CLK_UART0>; + clock-names = "baud", "module"; + }; + + uart1: serial@10031000 { + compatible = "ingenic,jz4740-uart"; + reg = <0x10031000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <8>; + + clocks = <&ext>, <&cgu JZ4740_CLK_UART1>; + clock-names = "baud", "module"; + }; }; diff --git a/arch/mips/boot/dts/ingenic/qi_lb60.dts b/arch/mips/boot/dts/ingenic/qi_lb60.dts index 106d13cce11b..2414d63ae818 100644 --- a/arch/mips/boot/dts/ingenic/qi_lb60.dts +++ b/arch/mips/boot/dts/ingenic/qi_lb60.dts @@ -4,6 +4,10 @@ / { compatible = "qi,lb60", "ingenic,jz4740"; + + chosen { + stdout-path = &uart0; + }; }; &ext { diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig index 1139b899f96a..d7bb8cce1068 100644 --- a/arch/mips/configs/qi_lb60_defconfig +++ b/arch/mips/configs/qi_lb60_defconfig @@ -66,6 +66,7 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_DMA is not set CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_INGENIC=y # CONFIG_HW_RANDOM is not set CONFIG_SPI=y CONFIG_SPI_GPIO=y diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h index 069b43a9da6f..32cfbe6a191b 100644 --- a/arch/mips/include/asm/mach-jz4740/platform.h +++ b/arch/mips/include/asm/mach-jz4740/platform.h @@ -35,6 +35,4 @@ extern struct platform_device jz4740_wdt_device; extern struct platform_device jz4740_pwm_device; extern struct platform_device jz4740_dma_device; -void jz4740_serial_device_register(void); - #endif diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index 70a9578cc6db..89ce40143854 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile @@ -5,7 +5,7 @@ # Object file lists. obj-y += prom.o time.o reset.o setup.o \ - gpio.o platform.o timer.o serial.o + gpio.o platform.o timer.o CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 21b034cea864..4e62bf85d0b0 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -482,8 +482,6 @@ static int __init qi_lb60_init_platform_devices(void) gpiod_add_lookup_table(&qi_lb60_audio_gpio_table); gpiod_add_lookup_table(&qi_lb60_nand_gpio_table); - jz4740_serial_device_register(); - spi_register_board_info(qi_lb60_spi_board_info, ARRAY_SIZE(qi_lb60_spi_board_info)); diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index 2a5c7c7d0735..e8a463b9b663 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c @@ -30,7 +30,6 @@ #include #include -#include "serial.h" #include "clock.h" /* OHCI controller */ @@ -280,50 +279,6 @@ struct platform_device jz4740_adc_device = { .resource = jz4740_adc_resources, }; -/* Serial */ -#define JZ4740_UART_DATA(_id) \ - { \ - .flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \ - .iotype = UPIO_MEM, \ - .regshift = 2, \ - .serial_out = jz4740_serial_out, \ - .type = PORT_16550, \ - .mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \ - .irq = JZ4740_IRQ_UART ## _id, \ - } - -static struct plat_serial8250_port jz4740_uart_data[] = { - JZ4740_UART_DATA(0), - JZ4740_UART_DATA(1), - {}, -}; - -static struct platform_device jz4740_uart_device = { - .name = "serial8250", - .id = 0, - .dev = { - .platform_data = jz4740_uart_data, - }, -}; - -void jz4740_serial_device_register(void) -{ - struct plat_serial8250_port *p; - struct clk *ext_clk; - unsigned long ext_rate; - - ext_clk = clk_get(NULL, "ext"); - if (IS_ERR(ext_clk)) - panic("unable to get ext clock"); - ext_rate = clk_get_rate(ext_clk); - clk_put(ext_clk); - - for (p = jz4740_uart_data; p->flags != 0; ++p) - p->uartclk = ext_rate; - - platform_device_register(&jz4740_uart_device); -} - /* Watchdog */ static struct resource jz4740_wdt_resources[] = { { diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c index 5a93f381590d..6984683c90d0 100644 --- a/arch/mips/jz4740/prom.c +++ b/arch/mips/jz4740/prom.c @@ -53,16 +53,3 @@ void __init prom_init(void) void __init prom_free_prom_memory(void) { } - -#define UART_REG(_reg) ((void __iomem *)CKSEG1ADDR(JZ4740_UART0_BASE_ADDR + (_reg << 2))) - -void prom_putchar(char c) -{ - uint8_t lsr; - - do { - lsr = readb(UART_REG(UART_LSR)); - } while ((lsr & UART_LSR_TEMT) == 0); - - writeb(c, UART_REG(UART_TX)); -} diff --git a/arch/mips/jz4740/serial.c b/arch/mips/jz4740/serial.c deleted file mode 100644 index d23de45826d1..000000000000 --- a/arch/mips/jz4740/serial.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen - * JZ4740 serial 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include - -void jz4740_serial_out(struct uart_port *p, int offset, int value) -{ - switch (offset) { - case UART_FCR: - value |= 0x10; /* Enable uart module */ - break; - case UART_IER: - value |= (value & 0x4) << 2; - break; - default: - break; - } - writeb(value, p->membase + (offset << p->regshift)); -} diff --git a/arch/mips/jz4740/serial.h b/arch/mips/jz4740/serial.h deleted file mode 100644 index 8eb715bb1ea8..000000000000 --- a/arch/mips/jz4740/serial.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen - * JZ4740 serial 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef __MIPS_JZ4740_SERIAL_H__ -#define __MIPS_JZ4740_SERIAL_H__ - -struct uart_port; - -void jz4740_serial_out(struct uart_port *p, int offset, int value); - -#endif -- cgit v1.2.3 From 5b9cdd2449098b3cd519a02dfed7588fd2becd0e Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:11:46 +0100 Subject: MIPS: ingenic: Initial JZ4780 support Support the Ingenic JZ4780 SoC using the existing code under arch/mips/jz4740 now that it has been generalised sufficiently. Signed-off-by: Paul Burton Cc: Ian Campbell Cc: Kumar Gala Cc: Lars-Peter Clausen Cc: Mark Rutland Cc: Pawel Moll Cc: Rob Herring Cc: devicetree@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: Joshua Kinard Cc: Leonid Yegoshin Cc: Deng-Cheng Zhu Cc: linux-kernel@vger.kernel.org Cc: Markos Chandras Cc: Andreas Herrmann Patchwork: https://patchwork.linux-mips.org/patch/10164/ Signed-off-by: Ralf Baechle --- arch/mips/boot/dts/ingenic/jz4780.dtsi | 111 +++++++++++++++++++++ arch/mips/include/asm/cpu-type.h | 2 +- .../asm/mach-jz4740/cpu-feature-overrides.h | 3 - arch/mips/include/asm/mach-jz4740/irq.h | 4 + arch/mips/jz4740/Kconfig | 6 ++ arch/mips/jz4740/Makefile | 4 +- arch/mips/jz4740/setup.c | 3 + arch/mips/jz4740/time.c | 7 +- 8 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 arch/mips/boot/dts/ingenic/jz4780.dtsi (limited to 'arch/mips/include') diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi new file mode 100644 index 000000000000..65389f602733 --- /dev/null +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi @@ -0,0 +1,111 @@ +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ingenic,jz4780"; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + intc: interrupt-controller@10001000 { + compatible = "ingenic,jz4780-intc"; + reg = <0x10001000 0x50>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + ext: ext { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + rtc: rtc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + cgu: jz4780-cgu@10000000 { + compatible = "ingenic,jz4780-cgu"; + reg = <0x10000000 0x100>; + + clocks = <&ext>, <&rtc>; + clock-names = "ext", "rtc"; + + #clock-cells = <1>; + }; + + uart0: serial@10030000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10030000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <51>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART0>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart1: serial@10031000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10031000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <50>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART1>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart2: serial@10032000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10032000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <49>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART2>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart3: serial@10033000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10033000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <48>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART3>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart4: serial@10034000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10034000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <34>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART4>; + clock-names = "baud", "module"; + + status = "disabled"; + }; +}; diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index 33f3cab9e689..d41e8e284825 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -32,12 +32,12 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_4KC: case CPU_ALCHEMY: case CPU_PR4450: - case CPU_JZRISC: #endif #if defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) || \ defined(CONFIG_SYS_HAS_CPU_MIPS32_R2) case CPU_4KEC: + case CPU_JZRISC: #endif #ifdef CONFIG_SYS_HAS_CPU_MIPS32_R2 diff --git a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h index a225baaa215d..0933f94a1e69 100644 --- a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h @@ -12,8 +12,6 @@ #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 #define cpu_has_tx39_cache 0 -#define cpu_has_fpu 0 -#define cpu_has_32fpr 0 #define cpu_has_counter 0 #define cpu_has_watch 1 #define cpu_has_divec 1 @@ -34,7 +32,6 @@ #define cpu_has_ic_fills_f_dc 0 #define cpu_has_pindexed_dcache 0 #define cpu_has_mips32r1 1 -#define cpu_has_mips32r2 0 #define cpu_has_mips64r1 0 #define cpu_has_mips64r2 0 #define cpu_has_dsp 0 diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h index b218f76f55c4..9b439fc218bd 100644 --- a/arch/mips/include/asm/mach-jz4740/irq.h +++ b/arch/mips/include/asm/mach-jz4740/irq.h @@ -21,6 +21,8 @@ #ifdef CONFIG_MACH_JZ4740 # define NR_INTC_IRQS 32 +#else +# define NR_INTC_IRQS 64 #endif /* 1st-level interrupts */ @@ -48,6 +50,8 @@ #define JZ4740_IRQ_IPU JZ4740_IRQ(29) #define JZ4740_IRQ_LCD JZ4740_IRQ(30) +#define JZ4780_IRQ_TCU2 JZ4740_IRQ(25) + /* 2nd-level interrupts */ #define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(NR_INTC_IRQS) + (x)) diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig index dff0966284c4..21adcea73d63 100644 --- a/arch/mips/jz4740/Kconfig +++ b/arch/mips/jz4740/Kconfig @@ -12,3 +12,9 @@ endchoice config MACH_JZ4740 bool select SYS_HAS_CPU_MIPS32_R1 + +config MACH_JZ4780 + bool + select MIPS_CPU_SCACHE + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_HIGHMEM diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index 89ce40143854..39d70bde8cfe 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile @@ -5,7 +5,9 @@ # Object file lists. obj-y += prom.o time.o reset.o setup.o \ - gpio.o platform.o timer.o + platform.o timer.o + +obj-$(CONFIG_MACH_JZ4740) += gpio.o CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 1bed3cb062b3..510fc0d962f2 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c @@ -83,6 +83,9 @@ arch_initcall(populate_machine); const char *get_system_type(void) { + if (config_enabled(CONFIG_MACH_JZ4780)) + return "JZ4780"; + return "JZ4740"; } diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index 917255368db8..7ab47fee1be8 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c @@ -102,7 +102,12 @@ static struct clock_event_device jz4740_clockevent = { .set_next_event = jz4740_clockevent_set_next, .set_mode = jz4740_clockevent_set_mode, .rating = 200, +#ifdef CONFIG_MACH_JZ4740 .irq = JZ4740_IRQ_TCU0, +#endif +#ifdef CONFIG_MACH_JZ4780 + .irq = JZ4780_IRQ_TCU2, +#endif }; static struct irqaction timer_irqaction = { @@ -144,7 +149,7 @@ void __init plat_time_init(void) sched_clock_register(jz4740_read_sched_clock, 16, clk_rate); - setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction); + setup_irq(jz4740_clockevent.irq, &timer_irqaction); ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT; -- cgit v1.2.3 From 09a50cc7279650c494be39de37ce8afa56989df1 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 4 May 2015 12:09:43 -0700 Subject: MIPS: BMIPS: Define BMIPS_FIXADDR_TOP in asm/bmips-spaces.h The FIXADDR_TOP value used by mach-bmips is in fact required whenever we run on BMIPS3300 BMIPS CPUs, and is not machine, but CPU-specific, move this constant to asm/bmips-spaces.h and use it in mach-bmips/spaces.h. Signed-off-by: Florian Fainelli Cc: linux-mips@linux-mips.org Cc: blogic@openwrt.org Cc: cernekee@chromium.org Cc: jogo@openwrt.org Patchwork: https://patchwork.linux-mips.org/patch/9968/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/bmips-spaces.h | 7 +++++++ arch/mips/include/asm/mach-bmips/spaces.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 arch/mips/include/asm/bmips-spaces.h (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/bmips-spaces.h b/arch/mips/include/asm/bmips-spaces.h new file mode 100644 index 000000000000..eb96541ae67e --- /dev/null +++ b/arch/mips/include/asm/bmips-spaces.h @@ -0,0 +1,7 @@ +#ifndef __ASM_BMIPS_SPACES_H +#define __ASM_BMIPS_SPACES_H + +/* Avoid collisions with system base register (SBR) region on BMIPS3300 */ +#define FIXADDR_TOP ((unsigned long)(long)(int)0xff000000) + +#endif /* __ASM_BMIPS_SPACES_H */ diff --git a/arch/mips/include/asm/mach-bmips/spaces.h b/arch/mips/include/asm/mach-bmips/spaces.h index 1b05bddc8ec5..c59b28fd9e1d 100644 --- a/arch/mips/include/asm/mach-bmips/spaces.h +++ b/arch/mips/include/asm/mach-bmips/spaces.h @@ -11,7 +11,7 @@ #define _ASM_BMIPS_SPACES_H /* Avoid collisions with system base register (SBR) region on BMIPS3300 */ -#define FIXADDR_TOP ((unsigned long)(long)(int)0xff000000) +#include #include -- cgit v1.2.3 From 3fbbb2ee36e73b175402a90eecb12ebb4f0bf0a6 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 4 May 2015 12:09:44 -0700 Subject: MIPS: BCM63xx: Utilize asm/bmips-spaces.h Since BCM63xx runs on BMIPS3300 which requires the use of a FIXADDR_TOP to avoid collisions with the SBR, utilize asm/bmips-spaces.h which defines FIXADDR_TOP for us now. Signed-off-by: Florian Fainelli Cc: linux-mips@linux-mips.org Cc: blogic@openwrt.org Cc: cernekee@chromium.org Cc: jogo@openwrt.org Patchwork: https://patchwork.linux-mips.org/patch/9969/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-bcm63xx/spaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-bcm63xx/spaces.h b/arch/mips/include/asm/mach-bcm63xx/spaces.h index 61e750fb4653..1410ed0da4df 100644 --- a/arch/mips/include/asm/mach-bcm63xx/spaces.h +++ b/arch/mips/include/asm/mach-bcm63xx/spaces.h @@ -10,7 +10,7 @@ #ifndef _ASM_BCM63XX_SPACES_H #define _ASM_BCM63XX_SPACES_H -#define FIXADDR_TOP ((unsigned long)(long)(int)0xff000000) +#include #include -- cgit v1.2.3 From b1f7e1129097cdb5cf2d6ef5d365dc94d13e3c76 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 27 Apr 2015 18:47:56 -0400 Subject: MIPS: BCM77xx: Remove legacy __cpuinit{,data} sections that crept in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We removed __cpuinit support (leaving no-op stubs) quite some time ago. However a few more crept in as of commit 6ee1d93455384cef8a0426effe85da2 ("MIPS: BCM47XX: Detect more then 128 MiB of RAM (HIGHMEM)") Since we want to clobber the stubs soon, get this removed now. Signed-off-by: Paul Gortmaker Cc: Rafał Miłecki Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/9892/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/prom.c | 2 +- arch/mips/include/asm/pgtable-32.h | 2 +- arch/mips/mm/tlb-r4k.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index ab698bad6d62..135a5407f015 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c @@ -126,7 +126,7 @@ void __init prom_free_prom_memory(void) /* Stripped version of tlb_init, with the call to build_tlb_refill_handler * dropped. Calling it at this stage causes a hang. */ -void __cpuinit early_tlb_init(void) +void early_tlb_init(void) { write_c0_pagemask(PM_DEFAULT_MASK); write_c0_wired(0); diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index 7d56686c0e62..832e2167d00f 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h @@ -18,7 +18,7 @@ #include -extern int temp_tlb_entry __cpuinitdata; +extern int temp_tlb_entry; /* * - add_temporary_entry() add a temporary TLB entry. We use TLB entries diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 08318ecb803a..5037d5868cef 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -423,7 +423,7 @@ int __init has_transparent_hugepage(void) * lifetime of the system */ -int temp_tlb_entry __cpuinitdata; +int temp_tlb_entry; __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask) -- cgit v1.2.3 From 626a0695a6d98338063c528d113d9ee4ba00cd78 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sun, 19 Apr 2015 14:30:02 +0200 Subject: MIPS: ath79: Correctly name the defines for the PLL_FB register This register is named PLL_FB and is not a divider but a multiplier. To make things less confusing rename the ARxxxx_PLL_DIV_SHIFT and ARxxxx_PLL_DIV_MASK macros to ARxxxx_PLL_FB_SHIFT and ARxxxx_PLL_FB_MASK. Signed-off-by: Alban Bedel Cc: linux-mips@linux-mips.org Cc: Andrew Bresticker Cc: Qais Yousef Cc: Wolfram Sang Cc: Sergey Ryazanov Cc: Gabor Juhos Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/9772/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/clock.c | 6 +++--- arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 26479f437675..226ddf0a0a97 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -62,7 +62,7 @@ static void __init ar71xx_clocks_init(void) pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); - div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; + div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; freq = div * ref_rate; div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; @@ -96,7 +96,7 @@ static void __init ar724x_clocks_init(void) ref_rate = AR724X_BASE_FREQ; pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); - div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); + div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); freq = div * ref_rate; div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); @@ -132,7 +132,7 @@ static void __init ar913x_clocks_init(void) ref_rate = AR913X_BASE_FREQ; pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); - div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); + div = ((pll >> AR913X_PLL_FB_SHIFT) & AR913X_PLL_FB_MASK); freq = div * ref_rate; cpu_rate = freq; diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index cd41e93bc1d8..aa3800c82332 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -157,8 +157,8 @@ #define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 #define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 -#define AR71XX_PLL_DIV_SHIFT 3 -#define AR71XX_PLL_DIV_MASK 0x1f +#define AR71XX_PLL_FB_SHIFT 3 +#define AR71XX_PLL_FB_MASK 0x1f #define AR71XX_CPU_DIV_SHIFT 16 #define AR71XX_CPU_DIV_MASK 0x3 #define AR71XX_DDR_DIV_SHIFT 18 @@ -169,8 +169,8 @@ #define AR724X_PLL_REG_CPU_CONFIG 0x00 #define AR724X_PLL_REG_PCIE_CONFIG 0x18 -#define AR724X_PLL_DIV_SHIFT 0 -#define AR724X_PLL_DIV_MASK 0x3ff +#define AR724X_PLL_FB_SHIFT 0 +#define AR724X_PLL_FB_MASK 0x3ff #define AR724X_PLL_REF_DIV_SHIFT 10 #define AR724X_PLL_REF_DIV_MASK 0xf #define AR724X_AHB_DIV_SHIFT 19 @@ -183,8 +183,8 @@ #define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14 #define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18 -#define AR913X_PLL_DIV_SHIFT 0 -#define AR913X_PLL_DIV_MASK 0x3ff +#define AR913X_PLL_FB_SHIFT 0 +#define AR913X_PLL_FB_MASK 0x3ff #define AR913X_DDR_DIV_SHIFT 22 #define AR913X_DDR_DIV_MASK 0x3 #define AR913X_AHB_DIV_SHIFT 19 -- cgit v1.2.3 From 24b0e3e84fbf460ea904f4eb85e414e6001c8f37 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Sun, 19 Apr 2015 14:30:03 +0200 Subject: MIPS: ath79: Improve the DDR controller interface The DDR controller need to be used by the IRQ controller to flush the write buffer of some devices before running the IRQ handler. It is also used by the PCI controller to setup the PCI memory windows. The current interface used to access the DDR controller doesn't provides any useful abstraction and simply rely on a shared global pointer. Replace this by a simple API to setup the PCI memory windows and use the write buffer flush independently of the SoC type. That remove the need for the shared global pointer, simplify the IRQ handler code. [ralf@linux-mips.org: Folded in Alban Bedel's follup fix.] Signed-off-by: Alban Bedel Cc: linux-mips@linux-mips.org Cc: Andrew Bresticker Cc: Qais Yousef Cc: Wolfram Sang Cc: Sergey Ryazanov Cc: Gabor Juhos Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/9773/ Patchwork: http://patchwork.linux-mips.org/patch/10543/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/common.c | 35 +++++++- arch/mips/ath79/common.h | 1 + arch/mips/ath79/irq.c | 137 +++++++------------------------ arch/mips/ath79/setup.c | 3 +- arch/mips/include/asm/mach-ath79/ath79.h | 3 +- arch/mips/pci/pci-ar71xx.c | 12 +-- 6 files changed, 66 insertions(+), 125 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c index eb3966cd8cfc..3cedd1f95e0f 100644 --- a/arch/mips/ath79/common.c +++ b/arch/mips/ath79/common.c @@ -38,11 +38,27 @@ unsigned int ath79_soc_rev; void __iomem *ath79_pll_base; void __iomem *ath79_reset_base; EXPORT_SYMBOL_GPL(ath79_reset_base); -void __iomem *ath79_ddr_base; +static void __iomem *ath79_ddr_base; +static void __iomem *ath79_ddr_wb_flush_base; +static void __iomem *ath79_ddr_pci_win_base; + +void ath79_ddr_ctrl_init(void) +{ + ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, + AR71XX_DDR_CTRL_SIZE); + if (soc_is_ar71xx() || soc_is_ar934x()) { + ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; + ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; + } else { + ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; + ath79_ddr_pci_win_base = 0; + } +} +EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); void ath79_ddr_wb_flush(u32 reg) { - void __iomem *flush_reg = ath79_ddr_base + reg; + void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg; /* Flush the DDR write buffer. */ __raw_writel(0x1, flush_reg); @@ -56,6 +72,21 @@ void ath79_ddr_wb_flush(u32 reg) } EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush); +void ath79_ddr_set_pci_windows(void) +{ + BUG_ON(!ath79_ddr_pci_win_base); + + __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0); + __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 1); + __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 2); + __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 3); + __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 4); + __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 5); + __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 6); + __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 7); +} +EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows); + void ath79_device_reset_set(u32 mask) { unsigned long flags; diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h index c39de61f9b36..e5ea71277f0c 100644 --- a/arch/mips/ath79/common.h +++ b/arch/mips/ath79/common.h @@ -22,6 +22,7 @@ void ath79_clocks_init(void); unsigned long ath79_get_sys_clk_rate(const char *id); +void ath79_ddr_ctrl_init(void); void ath79_ddr_wb_flush(unsigned int reg); void ath79_gpio_function_enable(u32 mask); diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 6adae366f11a..2c3991a4e512 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c @@ -24,9 +24,6 @@ #include #include "common.h" -static void (*ath79_ip2_handler)(void); -static void (*ath79_ip3_handler)(void); - static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *base = ath79_reset_base; @@ -129,10 +126,10 @@ static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { - ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE); + ath79_ddr_wb_flush(3); generic_handle_irq(ATH79_IP2_IRQ(0)); } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { - ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC); + ath79_ddr_wb_flush(4); generic_handle_irq(ATH79_IP2_IRQ(1)); } else { spurious_interrupt(); @@ -235,128 +232,50 @@ static void qca955x_irq_init(void) irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); } -asmlinkage void plat_irq_dispatch(void) -{ - unsigned long pending; - - pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUSF_IP7) - do_IRQ(ATH79_CPU_IRQ(7)); - - else if (pending & STATUSF_IP2) - ath79_ip2_handler(); - - else if (pending & STATUSF_IP4) - do_IRQ(ATH79_CPU_IRQ(4)); - - else if (pending & STATUSF_IP5) - do_IRQ(ATH79_CPU_IRQ(5)); - - else if (pending & STATUSF_IP3) - ath79_ip3_handler(); - - else if (pending & STATUSF_IP6) - do_IRQ(ATH79_CPU_IRQ(6)); - - else - spurious_interrupt(); -} - /* * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for * these devices typically allocate coherent DMA memory, however the * DMA controller may still have some unsynchronized data in the FIFO. * Issue a flush in the handlers to ensure that the driver sees * the update. + * + * This array map the interrupt lines to the DDR write buffer channels. */ -static void ath79_default_ip2_handler(void) -{ - do_IRQ(ATH79_CPU_IRQ(2)); -} - -static void ath79_default_ip3_handler(void) -{ - do_IRQ(ATH79_CPU_IRQ(3)); -} - -static void ar71xx_ip2_handler(void) -{ - ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); - do_IRQ(ATH79_CPU_IRQ(2)); -} - -static void ar724x_ip2_handler(void) -{ - ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE); - do_IRQ(ATH79_CPU_IRQ(2)); -} - -static void ar913x_ip2_handler(void) -{ - ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC); - do_IRQ(ATH79_CPU_IRQ(2)); -} - -static void ar933x_ip2_handler(void) -{ - ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); - do_IRQ(ATH79_CPU_IRQ(2)); -} - -static void ar71xx_ip3_handler(void) -{ - ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ(3)); -} +static unsigned irq_wb_chan[8] = { + -1, -1, -1, -1, -1, -1, -1, -1, +}; -static void ar724x_ip3_handler(void) +asmlinkage void plat_irq_dispatch(void) { - ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ(3)); -} + unsigned long pending; + int irq; -static void ar913x_ip3_handler(void) -{ - ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ(3)); -} + pending = read_c0_status() & read_c0_cause() & ST0_IM; -static void ar933x_ip3_handler(void) -{ - ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ(3)); -} + if (!pending) { + spurious_interrupt(); + return; + } -static void ar934x_ip3_handler(void) -{ - ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB); - do_IRQ(ATH79_CPU_IRQ(3)); + pending >>= CAUSEB_IP; + while (pending) { + irq = fls(pending) - 1; + if (irq < ARRAY_SIZE(irq_wb_chan) && irq_wb_chan[irq] != -1) + ath79_ddr_wb_flush(irq_wb_chan[irq]); + do_IRQ(MIPS_CPU_IRQ_BASE + irq); + pending &= ~BIT(irq); + } } void __init arch_init_irq(void) { - if (soc_is_ar71xx()) { - ath79_ip2_handler = ar71xx_ip2_handler; - ath79_ip3_handler = ar71xx_ip3_handler; - } else if (soc_is_ar724x()) { - ath79_ip2_handler = ar724x_ip2_handler; - ath79_ip3_handler = ar724x_ip3_handler; - } else if (soc_is_ar913x()) { - ath79_ip2_handler = ar913x_ip2_handler; - ath79_ip3_handler = ar913x_ip3_handler; - } else if (soc_is_ar933x()) { - ath79_ip2_handler = ar933x_ip2_handler; - ath79_ip3_handler = ar933x_ip3_handler; + if (soc_is_ar71xx() || soc_is_ar724x() || + soc_is_ar913x() || soc_is_ar933x()) { + irq_wb_chan[2] = 3; + irq_wb_chan[3] = 2; } else if (soc_is_ar934x()) { - ath79_ip2_handler = ath79_default_ip2_handler; - ath79_ip3_handler = ar934x_ip3_handler; - } else if (soc_is_qca955x()) { - ath79_ip2_handler = ath79_default_ip2_handler; - ath79_ip3_handler = ath79_default_ip3_handler; - } else { - BUG(); + irq_wb_chan[3] = 2; } mips_cpu_irq_init(); diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 7fc8397d16f2..74f1af7eeefc 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -200,8 +200,7 @@ void __init plat_mem_setup(void) AR71XX_RESET_SIZE); ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); - ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, - AR71XX_DDR_CTRL_SIZE); + ath79_ddr_ctrl_init(); ath79_detect_sys_type(); detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h index 1557934aaca9..4eee221b0cf0 100644 --- a/arch/mips/include/asm/mach-ath79/ath79.h +++ b/arch/mips/include/asm/mach-ath79/ath79.h @@ -115,7 +115,8 @@ static inline int soc_is_qca955x(void) return soc_is_qca9556() || soc_is_qca9558(); } -extern void __iomem *ath79_ddr_base; +void ath79_ddr_set_pci_windows(void); + extern void __iomem *ath79_pll_base; extern void __iomem *ath79_reset_base; diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index dac6a07c45bf..283157f8dc64 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -318,23 +318,13 @@ static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc) static void ar71xx_pci_reset(void) { - void __iomem *ddr_base = ath79_ddr_base; - ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE); mdelay(100); ath79_device_reset_clear(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE); mdelay(100); - __raw_writel(AR71XX_PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); - __raw_writel(AR71XX_PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1); - __raw_writel(AR71XX_PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2); - __raw_writel(AR71XX_PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3); - __raw_writel(AR71XX_PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4); - __raw_writel(AR71XX_PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5); - __raw_writel(AR71XX_PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6); - __raw_writel(AR71XX_PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7); - + ath79_ddr_set_pci_windows(); mdelay(100); } -- cgit v1.2.3 From 24f2970fd32134ff8eb3387a54a1ef7ccac3f28f Mon Sep 17 00:00:00 2001 From: Dan Haab Date: Wed, 22 Apr 2015 13:58:33 -0600 Subject: MIPS: BCM47XX: Support Luxul XWR-1750 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Dan Haab Acked-by: Rafał Miłecki Cc: linux-mips@linux-mips.org Cc: Hauke Mehrtens Cc: Dan Haab Patchwork: https://patchwork.linux-mips.org/patch/9831/ Signed-off-by: Ralf Baechle --- arch/mips/bcm47xx/board.c | 1 + arch/mips/bcm47xx/buttons.c | 11 +++++++++++ arch/mips/bcm47xx/leds.c | 14 ++++++++++++++ arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | 2 ++ 4 files changed, 28 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index bd56415f2f3b..a88975a55c4d 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c @@ -149,6 +149,7 @@ struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = { /* board_id */ static const struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = { + {{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"}, {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"}, {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"}, {{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"}, diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c index 276276a8c6d7..08a4abf09a33 100644 --- a/arch/mips/bcm47xx/buttons.c +++ b/arch/mips/bcm47xx/buttons.c @@ -299,6 +299,13 @@ bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = { BCM47XX_GPIO_KEY(6, KEY_RESTART), }; +/* Luxul */ + +static const struct gpio_keys_button +bcm47xx_buttons_luxul_xwr_1750_v1[] = { + BCM47XX_GPIO_KEY(14, BTN_TASK), +}; + /* Microsoft */ static const struct gpio_keys_button @@ -555,6 +562,10 @@ int __init bcm47xx_buttons_register(void) err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs); break; + case BCM47XX_BOARD_LUXUL_XWR_1750_V1: + err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xwr_1750_v1); + break; + case BCM47XX_BOARD_MICROSOFT_MN700: err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700); break; diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c index 0e4ade342333..d20ae63eb3c2 100644 --- a/arch/mips/bcm47xx/leds.c +++ b/arch/mips/bcm47xx/leds.c @@ -370,6 +370,16 @@ bcm47xx_leds_linksys_wrtsl54gs[] __initconst = { BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), }; +/* Luxul */ + +static const struct gpio_led +bcm47xx_leds_luxul_xwr_1750_v1[] __initconst = { + BCM47XX_GPIO_LED(5, "green", "5ghz", 0, LEDS_GPIO_DEFSTATE_OFF), + BCM47XX_GPIO_LED(12, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), + BCM47XX_GPIO_LED_TRIGGER(13, "green", "status", 0, "timer"), + BCM47XX_GPIO_LED(15, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), +}; + /* Microsoft */ static const struct gpio_led @@ -623,6 +633,10 @@ void __init bcm47xx_leds_register(void) bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs); break; + case BCM47XX_BOARD_LUXUL_XWR_1750_V1: + bcm47xx_set_pdata(bcm47xx_leds_luxul_xwr_1750_v1); + break; + case BCM47XX_BOARD_MICROSOFT_MN700: bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700); break; diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h index c41d1dce1062..2afb84072ad0 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h @@ -80,6 +80,8 @@ enum bcm47xx_board { BCM47XX_BOARD_LINKSYS_WRT610NV2, BCM47XX_BOARD_LINKSYS_WRTSL54GS, + BCM47XX_BOARD_LUXUL_XWR_1750_V1, + BCM47XX_BOARD_MICROSOFT_MN700, BCM47XX_BOARD_MOTOROLA_WE800G, -- cgit v1.2.3 From 8e748c8d09a9314eedb5c6367d9acfaacddcdc88 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 27 Apr 2015 15:07:16 +0100 Subject: MIPS: Fix KVM guest fixmap address KVM guest kernels for trap & emulate run in user mode, with a modified set of kernel memory segments. However the fixmap address is still in the normal KSeg3 region at 0xfffe0000 regardless, causing problems when cache alias handling makes use of them when handling copy on write. Therefore define FIXADDR_TOP as 0x7ffe0000 in the guest kernel mapped region when CONFIG_KVM_GUEST is defined. Signed-off-by: James Hogan Cc: linux-mips@linux-mips.org Cc: # v3.10+ Patchwork: https://patchwork.linux-mips.org/patch/9887/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-generic/spaces.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index 9488fa5f8866..afc96ecb9004 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -94,7 +94,11 @@ #endif #ifndef FIXADDR_TOP +#ifdef CONFIG_KVM_GUEST +#define FIXADDR_TOP ((unsigned long)(long)(int)0x7ffe0000) +#else #define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) #endif +#endif #endif /* __ASM_MACH_GENERIC_SPACES_H */ -- cgit v1.2.3 From 30ad29bb48881ee11f5daf30c6fc50292ae08c57 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 21 Apr 2015 10:00:35 +0800 Subject: MIPS: Loongson: Naming style cleanup and rework Currently, code of Loongson-2/3 is under loongson directory and code of Loongson-1 is under loongson1 directory. Besides, there are Kconfig options such as MACH_LOONGSON and MACH_LOONGSON1. This naming style is very ugly and confusing. Since Loongson-2/3 are both 64-bit general- purpose CPU while Loongson-1 is 32-bit SoC, we rename both file names and Kconfig symbols from loongson/loongson1 to loongson64/loongson32. [ralf@linux-mips.org: Resolve a number of simple conflicts.] Signed-off-by: Huacai Chen Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang Cc: Zhangjin Wu Cc: Kelvin Cheung Patchwork: https://patchwork.linux-mips.org/patch/9790/ Signed-off-by: Ralf Baechle --- arch/mips/Kbuild.platforms | 4 +- arch/mips/Kconfig | 34 +- arch/mips/boot/compressed/uart-16550.c | 2 +- arch/mips/configs/fuloong2e_defconfig | 2 +- arch/mips/configs/lemote2f_defconfig | 2 +- arch/mips/configs/loongson3_defconfig | 2 +- arch/mips/configs/ls1b_defconfig | 2 +- arch/mips/include/asm/mach-loongson/boot_param.h | 210 ------- .../asm/mach-loongson/cpu-feature-overrides.h | 61 -- .../mips/include/asm/mach-loongson/cs5536/cs5536.h | 305 ---------- .../asm/mach-loongson/cs5536/cs5536_mfgpt.h | 35 -- .../include/asm/mach-loongson/cs5536/cs5536_pci.h | 153 ----- .../include/asm/mach-loongson/cs5536/cs5536_vsm.h | 31 - .../mips/include/asm/mach-loongson/dma-coherence.h | 85 --- arch/mips/include/asm/mach-loongson/gpio.h | 36 -- arch/mips/include/asm/mach-loongson/irq.h | 43 -- .../include/asm/mach-loongson/kernel-entry-init.h | 52 -- arch/mips/include/asm/mach-loongson/loongson.h | 360 ------------ .../include/asm/mach-loongson/loongson_hwmon.h | 55 -- arch/mips/include/asm/mach-loongson/machine.h | 33 -- arch/mips/include/asm/mach-loongson/mc146818rtc.h | 36 -- arch/mips/include/asm/mach-loongson/mem.h | 41 -- arch/mips/include/asm/mach-loongson/mmzone.h | 53 -- arch/mips/include/asm/mach-loongson/pci.h | 55 -- arch/mips/include/asm/mach-loongson/spaces.h | 9 - arch/mips/include/asm/mach-loongson/topology.h | 23 - arch/mips/include/asm/mach-loongson/workarounds.h | 7 - arch/mips/include/asm/mach-loongson1/cpufreq.h | 23 - arch/mips/include/asm/mach-loongson1/irq.h | 73 --- arch/mips/include/asm/mach-loongson1/loongson1.h | 50 -- arch/mips/include/asm/mach-loongson1/platform.h | 26 - arch/mips/include/asm/mach-loongson1/prom.h | 24 - arch/mips/include/asm/mach-loongson1/regs-clk.h | 51 -- arch/mips/include/asm/mach-loongson1/regs-mux.h | 67 --- arch/mips/include/asm/mach-loongson1/regs-pwm.h | 29 - arch/mips/include/asm/mach-loongson1/regs-wdt.h | 19 - arch/mips/include/asm/mach-loongson32/cpufreq.h | 23 + arch/mips/include/asm/mach-loongson32/irq.h | 73 +++ arch/mips/include/asm/mach-loongson32/loongson1.h | 50 ++ arch/mips/include/asm/mach-loongson32/platform.h | 26 + arch/mips/include/asm/mach-loongson32/prom.h | 24 + arch/mips/include/asm/mach-loongson32/regs-clk.h | 51 ++ arch/mips/include/asm/mach-loongson32/regs-mux.h | 67 +++ arch/mips/include/asm/mach-loongson32/regs-pwm.h | 29 + arch/mips/include/asm/mach-loongson32/regs-wdt.h | 19 + arch/mips/include/asm/mach-loongson64/boot_param.h | 210 +++++++ .../asm/mach-loongson64/cpu-feature-overrides.h | 61 ++ .../include/asm/mach-loongson64/cs5536/cs5536.h | 305 ++++++++++ .../asm/mach-loongson64/cs5536/cs5536_mfgpt.h | 35 ++ .../asm/mach-loongson64/cs5536/cs5536_pci.h | 153 +++++ .../asm/mach-loongson64/cs5536/cs5536_vsm.h | 31 + .../include/asm/mach-loongson64/dma-coherence.h | 85 +++ arch/mips/include/asm/mach-loongson64/gpio.h | 36 ++ arch/mips/include/asm/mach-loongson64/irq.h | 43 ++ .../asm/mach-loongson64/kernel-entry-init.h | 52 ++ arch/mips/include/asm/mach-loongson64/loongson.h | 360 ++++++++++++ .../include/asm/mach-loongson64/loongson_hwmon.h | 55 ++ arch/mips/include/asm/mach-loongson64/machine.h | 33 ++ .../mips/include/asm/mach-loongson64/mc146818rtc.h | 36 ++ arch/mips/include/asm/mach-loongson64/mem.h | 41 ++ arch/mips/include/asm/mach-loongson64/mmzone.h | 53 ++ arch/mips/include/asm/mach-loongson64/pci.h | 55 ++ arch/mips/include/asm/mach-loongson64/spaces.h | 9 + arch/mips/include/asm/mach-loongson64/topology.h | 23 + .../mips/include/asm/mach-loongson64/workarounds.h | 7 + arch/mips/loongson/Kconfig | 158 ----- arch/mips/loongson/Makefile | 23 - arch/mips/loongson/Platform | 33 -- arch/mips/loongson/common/Makefile | 31 - arch/mips/loongson/common/bonito-irq.c | 53 -- arch/mips/loongson/common/cmdline.c | 48 -- arch/mips/loongson/common/cs5536/Makefile | 11 - arch/mips/loongson/common/cs5536/cs5536_acc.c | 140 ----- arch/mips/loongson/common/cs5536/cs5536_ehci.c | 160 ----- arch/mips/loongson/common/cs5536/cs5536_ide.c | 192 ------ arch/mips/loongson/common/cs5536/cs5536_isa.c | 330 ----------- arch/mips/loongson/common/cs5536/cs5536_mfgpt.c | 213 ------- arch/mips/loongson/common/cs5536/cs5536_ohci.c | 149 ----- arch/mips/loongson/common/cs5536/cs5536_pci.c | 88 --- arch/mips/loongson/common/dma-swiotlb.c | 150 ----- arch/mips/loongson/common/early_printk.c | 41 -- arch/mips/loongson/common/env.c | 200 ------- arch/mips/loongson/common/init.c | 47 -- arch/mips/loongson/common/irq.c | 67 --- arch/mips/loongson/common/machtype.c | 67 --- arch/mips/loongson/common/mem.c | 161 ----- arch/mips/loongson/common/pci.c | 101 ---- arch/mips/loongson/common/platform.c | 31 - arch/mips/loongson/common/pm.c | 161 ----- arch/mips/loongson/common/reset.c | 92 --- arch/mips/loongson/common/rtc.c | 43 -- arch/mips/loongson/common/serial.c | 112 ---- arch/mips/loongson/common/setup.c | 54 -- arch/mips/loongson/common/time.c | 36 -- arch/mips/loongson/common/uart_base.c | 50 -- arch/mips/loongson/fuloong-2e/Makefile | 5 - arch/mips/loongson/fuloong-2e/irq.c | 69 --- arch/mips/loongson/fuloong-2e/reset.c | 23 - arch/mips/loongson/lemote-2f/Makefile | 11 - arch/mips/loongson/lemote-2f/clock.c | 140 ----- arch/mips/loongson/lemote-2f/ec_kb3310b.c | 128 ---- arch/mips/loongson/lemote-2f/ec_kb3310b.h | 188 ------ arch/mips/loongson/lemote-2f/irq.c | 129 ---- arch/mips/loongson/lemote-2f/machtype.c | 45 -- arch/mips/loongson/lemote-2f/pm.c | 149 ----- arch/mips/loongson/lemote-2f/reset.c | 159 ----- arch/mips/loongson/loongson-3/Makefile | 10 - arch/mips/loongson/loongson-3/cop2-ex.c | 63 -- arch/mips/loongson/loongson-3/hpet.c | 257 -------- arch/mips/loongson/loongson-3/irq.c | 143 ----- arch/mips/loongson/loongson-3/numa.c | 296 ---------- arch/mips/loongson/loongson-3/platform.c | 43 -- arch/mips/loongson/loongson-3/smp.c | 652 --------------------- arch/mips/loongson/loongson-3/smp.h | 30 - arch/mips/loongson1/Kconfig | 61 -- arch/mips/loongson1/Makefile | 11 - arch/mips/loongson1/Platform | 7 - arch/mips/loongson1/common/Makefile | 5 - arch/mips/loongson1/common/irq.c | 147 ----- arch/mips/loongson1/common/platform.c | 234 -------- arch/mips/loongson1/common/prom.c | 83 --- arch/mips/loongson1/common/reset.c | 54 -- arch/mips/loongson1/common/setup.c | 29 - arch/mips/loongson1/common/time.c | 226 ------- arch/mips/loongson1/ls1b/Makefile | 5 - arch/mips/loongson1/ls1b/board.c | 32 - arch/mips/loongson32/Kconfig | 61 ++ arch/mips/loongson32/Makefile | 11 + arch/mips/loongson32/Platform | 7 + arch/mips/loongson32/common/Makefile | 5 + arch/mips/loongson32/common/irq.c | 147 +++++ arch/mips/loongson32/common/platform.c | 234 ++++++++ arch/mips/loongson32/common/prom.c | 83 +++ arch/mips/loongson32/common/reset.c | 54 ++ arch/mips/loongson32/common/setup.c | 29 + arch/mips/loongson32/common/time.c | 226 +++++++ arch/mips/loongson32/ls1b/Makefile | 5 + arch/mips/loongson32/ls1b/board.c | 32 + arch/mips/loongson64/Kconfig | 158 +++++ arch/mips/loongson64/Makefile | 23 + arch/mips/loongson64/Platform | 33 ++ arch/mips/loongson64/common/Makefile | 31 + arch/mips/loongson64/common/bonito-irq.c | 53 ++ arch/mips/loongson64/common/cmdline.c | 48 ++ arch/mips/loongson64/common/cs5536/Makefile | 11 + arch/mips/loongson64/common/cs5536/cs5536_acc.c | 140 +++++ arch/mips/loongson64/common/cs5536/cs5536_ehci.c | 160 +++++ arch/mips/loongson64/common/cs5536/cs5536_ide.c | 192 ++++++ arch/mips/loongson64/common/cs5536/cs5536_isa.c | 330 +++++++++++ arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c | 213 +++++++ arch/mips/loongson64/common/cs5536/cs5536_ohci.c | 149 +++++ arch/mips/loongson64/common/cs5536/cs5536_pci.c | 88 +++ arch/mips/loongson64/common/dma-swiotlb.c | 150 +++++ arch/mips/loongson64/common/early_printk.c | 41 ++ arch/mips/loongson64/common/env.c | 200 +++++++ arch/mips/loongson64/common/init.c | 47 ++ arch/mips/loongson64/common/irq.c | 67 +++ arch/mips/loongson64/common/machtype.c | 67 +++ arch/mips/loongson64/common/mem.c | 161 +++++ arch/mips/loongson64/common/pci.c | 101 ++++ arch/mips/loongson64/common/platform.c | 31 + arch/mips/loongson64/common/pm.c | 161 +++++ arch/mips/loongson64/common/reset.c | 92 +++ arch/mips/loongson64/common/rtc.c | 43 ++ arch/mips/loongson64/common/serial.c | 112 ++++ arch/mips/loongson64/common/setup.c | 54 ++ arch/mips/loongson64/common/time.c | 36 ++ arch/mips/loongson64/common/uart_base.c | 50 ++ arch/mips/loongson64/fuloong-2e/Makefile | 5 + arch/mips/loongson64/fuloong-2e/irq.c | 69 +++ arch/mips/loongson64/fuloong-2e/reset.c | 23 + arch/mips/loongson64/lemote-2f/Makefile | 11 + arch/mips/loongson64/lemote-2f/clock.c | 140 +++++ arch/mips/loongson64/lemote-2f/ec_kb3310b.c | 128 ++++ arch/mips/loongson64/lemote-2f/ec_kb3310b.h | 188 ++++++ arch/mips/loongson64/lemote-2f/irq.c | 129 ++++ arch/mips/loongson64/lemote-2f/machtype.c | 45 ++ arch/mips/loongson64/lemote-2f/pm.c | 149 +++++ arch/mips/loongson64/lemote-2f/reset.c | 159 +++++ arch/mips/loongson64/loongson-3/Makefile | 10 + arch/mips/loongson64/loongson-3/cop2-ex.c | 63 ++ arch/mips/loongson64/loongson-3/hpet.c | 257 ++++++++ arch/mips/loongson64/loongson-3/irq.c | 143 +++++ arch/mips/loongson64/loongson-3/numa.c | 296 ++++++++++ arch/mips/loongson64/loongson-3/platform.c | 43 ++ arch/mips/loongson64/loongson-3/smp.c | 652 +++++++++++++++++++++ arch/mips/loongson64/loongson-3/smp.h | 30 + drivers/clk/Makefile | 2 +- drivers/cpufreq/ls1x-cpufreq.c | 4 +- drivers/rtc/Kconfig | 2 +- drivers/rtc/rtc-ls1x.c | 2 +- 191 files changed, 8551 insertions(+), 8549 deletions(-) delete mode 100644 arch/mips/include/asm/mach-loongson/boot_param.h delete mode 100644 arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h delete mode 100644 arch/mips/include/asm/mach-loongson/cs5536/cs5536.h delete mode 100644 arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h delete mode 100644 arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h delete mode 100644 arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h delete mode 100644 arch/mips/include/asm/mach-loongson/dma-coherence.h delete mode 100644 arch/mips/include/asm/mach-loongson/gpio.h delete mode 100644 arch/mips/include/asm/mach-loongson/irq.h delete mode 100644 arch/mips/include/asm/mach-loongson/kernel-entry-init.h delete mode 100644 arch/mips/include/asm/mach-loongson/loongson.h delete mode 100644 arch/mips/include/asm/mach-loongson/loongson_hwmon.h delete mode 100644 arch/mips/include/asm/mach-loongson/machine.h delete mode 100644 arch/mips/include/asm/mach-loongson/mc146818rtc.h delete mode 100644 arch/mips/include/asm/mach-loongson/mem.h delete mode 100644 arch/mips/include/asm/mach-loongson/mmzone.h delete mode 100644 arch/mips/include/asm/mach-loongson/pci.h delete mode 100644 arch/mips/include/asm/mach-loongson/spaces.h delete mode 100644 arch/mips/include/asm/mach-loongson/topology.h delete mode 100644 arch/mips/include/asm/mach-loongson/workarounds.h delete mode 100644 arch/mips/include/asm/mach-loongson1/cpufreq.h delete mode 100644 arch/mips/include/asm/mach-loongson1/irq.h delete mode 100644 arch/mips/include/asm/mach-loongson1/loongson1.h delete mode 100644 arch/mips/include/asm/mach-loongson1/platform.h delete mode 100644 arch/mips/include/asm/mach-loongson1/prom.h delete mode 100644 arch/mips/include/asm/mach-loongson1/regs-clk.h delete mode 100644 arch/mips/include/asm/mach-loongson1/regs-mux.h delete mode 100644 arch/mips/include/asm/mach-loongson1/regs-pwm.h delete mode 100644 arch/mips/include/asm/mach-loongson1/regs-wdt.h create mode 100644 arch/mips/include/asm/mach-loongson32/cpufreq.h create mode 100644 arch/mips/include/asm/mach-loongson32/irq.h create mode 100644 arch/mips/include/asm/mach-loongson32/loongson1.h create mode 100644 arch/mips/include/asm/mach-loongson32/platform.h create mode 100644 arch/mips/include/asm/mach-loongson32/prom.h create mode 100644 arch/mips/include/asm/mach-loongson32/regs-clk.h create mode 100644 arch/mips/include/asm/mach-loongson32/regs-mux.h create mode 100644 arch/mips/include/asm/mach-loongson32/regs-pwm.h create mode 100644 arch/mips/include/asm/mach-loongson32/regs-wdt.h create mode 100644 arch/mips/include/asm/mach-loongson64/boot_param.h create mode 100644 arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h create mode 100644 arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h create mode 100644 arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h create mode 100644 arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h create mode 100644 arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h create mode 100644 arch/mips/include/asm/mach-loongson64/dma-coherence.h create mode 100644 arch/mips/include/asm/mach-loongson64/gpio.h create mode 100644 arch/mips/include/asm/mach-loongson64/irq.h create mode 100644 arch/mips/include/asm/mach-loongson64/kernel-entry-init.h create mode 100644 arch/mips/include/asm/mach-loongson64/loongson.h create mode 100644 arch/mips/include/asm/mach-loongson64/loongson_hwmon.h create mode 100644 arch/mips/include/asm/mach-loongson64/machine.h create mode 100644 arch/mips/include/asm/mach-loongson64/mc146818rtc.h create mode 100644 arch/mips/include/asm/mach-loongson64/mem.h create mode 100644 arch/mips/include/asm/mach-loongson64/mmzone.h create mode 100644 arch/mips/include/asm/mach-loongson64/pci.h create mode 100644 arch/mips/include/asm/mach-loongson64/spaces.h create mode 100644 arch/mips/include/asm/mach-loongson64/topology.h create mode 100644 arch/mips/include/asm/mach-loongson64/workarounds.h delete mode 100644 arch/mips/loongson/Kconfig delete mode 100644 arch/mips/loongson/Makefile delete mode 100644 arch/mips/loongson/Platform delete mode 100644 arch/mips/loongson/common/Makefile delete mode 100644 arch/mips/loongson/common/bonito-irq.c delete mode 100644 arch/mips/loongson/common/cmdline.c delete mode 100644 arch/mips/loongson/common/cs5536/Makefile delete mode 100644 arch/mips/loongson/common/cs5536/cs5536_acc.c delete mode 100644 arch/mips/loongson/common/cs5536/cs5536_ehci.c delete mode 100644 arch/mips/loongson/common/cs5536/cs5536_ide.c delete mode 100644 arch/mips/loongson/common/cs5536/cs5536_isa.c delete mode 100644 arch/mips/loongson/common/cs5536/cs5536_mfgpt.c delete mode 100644 arch/mips/loongson/common/cs5536/cs5536_ohci.c delete mode 100644 arch/mips/loongson/common/cs5536/cs5536_pci.c delete mode 100644 arch/mips/loongson/common/dma-swiotlb.c delete mode 100644 arch/mips/loongson/common/early_printk.c delete mode 100644 arch/mips/loongson/common/env.c delete mode 100644 arch/mips/loongson/common/init.c delete mode 100644 arch/mips/loongson/common/irq.c delete mode 100644 arch/mips/loongson/common/machtype.c delete mode 100644 arch/mips/loongson/common/mem.c delete mode 100644 arch/mips/loongson/common/pci.c delete mode 100644 arch/mips/loongson/common/platform.c delete mode 100644 arch/mips/loongson/common/pm.c delete mode 100644 arch/mips/loongson/common/reset.c delete mode 100644 arch/mips/loongson/common/rtc.c delete mode 100644 arch/mips/loongson/common/serial.c delete mode 100644 arch/mips/loongson/common/setup.c delete mode 100644 arch/mips/loongson/common/time.c delete mode 100644 arch/mips/loongson/common/uart_base.c delete mode 100644 arch/mips/loongson/fuloong-2e/Makefile delete mode 100644 arch/mips/loongson/fuloong-2e/irq.c delete mode 100644 arch/mips/loongson/fuloong-2e/reset.c delete mode 100644 arch/mips/loongson/lemote-2f/Makefile delete mode 100644 arch/mips/loongson/lemote-2f/clock.c delete mode 100644 arch/mips/loongson/lemote-2f/ec_kb3310b.c delete mode 100644 arch/mips/loongson/lemote-2f/ec_kb3310b.h delete mode 100644 arch/mips/loongson/lemote-2f/irq.c delete mode 100644 arch/mips/loongson/lemote-2f/machtype.c delete mode 100644 arch/mips/loongson/lemote-2f/pm.c delete mode 100644 arch/mips/loongson/lemote-2f/reset.c delete mode 100644 arch/mips/loongson/loongson-3/Makefile delete mode 100644 arch/mips/loongson/loongson-3/cop2-ex.c delete mode 100644 arch/mips/loongson/loongson-3/hpet.c delete mode 100644 arch/mips/loongson/loongson-3/irq.c delete mode 100644 arch/mips/loongson/loongson-3/numa.c delete mode 100644 arch/mips/loongson/loongson-3/platform.c delete mode 100644 arch/mips/loongson/loongson-3/smp.c delete mode 100644 arch/mips/loongson/loongson-3/smp.h delete mode 100644 arch/mips/loongson1/Kconfig delete mode 100644 arch/mips/loongson1/Makefile delete mode 100644 arch/mips/loongson1/Platform delete mode 100644 arch/mips/loongson1/common/Makefile delete mode 100644 arch/mips/loongson1/common/irq.c delete mode 100644 arch/mips/loongson1/common/platform.c delete mode 100644 arch/mips/loongson1/common/prom.c delete mode 100644 arch/mips/loongson1/common/reset.c delete mode 100644 arch/mips/loongson1/common/setup.c delete mode 100644 arch/mips/loongson1/common/time.c delete mode 100644 arch/mips/loongson1/ls1b/Makefile delete mode 100644 arch/mips/loongson1/ls1b/board.c create mode 100644 arch/mips/loongson32/Kconfig create mode 100644 arch/mips/loongson32/Makefile create mode 100644 arch/mips/loongson32/Platform create mode 100644 arch/mips/loongson32/common/Makefile create mode 100644 arch/mips/loongson32/common/irq.c create mode 100644 arch/mips/loongson32/common/platform.c create mode 100644 arch/mips/loongson32/common/prom.c create mode 100644 arch/mips/loongson32/common/reset.c create mode 100644 arch/mips/loongson32/common/setup.c create mode 100644 arch/mips/loongson32/common/time.c create mode 100644 arch/mips/loongson32/ls1b/Makefile create mode 100644 arch/mips/loongson32/ls1b/board.c create mode 100644 arch/mips/loongson64/Kconfig create mode 100644 arch/mips/loongson64/Makefile create mode 100644 arch/mips/loongson64/Platform create mode 100644 arch/mips/loongson64/common/Makefile create mode 100644 arch/mips/loongson64/common/bonito-irq.c create mode 100644 arch/mips/loongson64/common/cmdline.c create mode 100644 arch/mips/loongson64/common/cs5536/Makefile create mode 100644 arch/mips/loongson64/common/cs5536/cs5536_acc.c create mode 100644 arch/mips/loongson64/common/cs5536/cs5536_ehci.c create mode 100644 arch/mips/loongson64/common/cs5536/cs5536_ide.c create mode 100644 arch/mips/loongson64/common/cs5536/cs5536_isa.c create mode 100644 arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c create mode 100644 arch/mips/loongson64/common/cs5536/cs5536_ohci.c create mode 100644 arch/mips/loongson64/common/cs5536/cs5536_pci.c create mode 100644 arch/mips/loongson64/common/dma-swiotlb.c create mode 100644 arch/mips/loongson64/common/early_printk.c create mode 100644 arch/mips/loongson64/common/env.c create mode 100644 arch/mips/loongson64/common/init.c create mode 100644 arch/mips/loongson64/common/irq.c create mode 100644 arch/mips/loongson64/common/machtype.c create mode 100644 arch/mips/loongson64/common/mem.c create mode 100644 arch/mips/loongson64/common/pci.c create mode 100644 arch/mips/loongson64/common/platform.c create mode 100644 arch/mips/loongson64/common/pm.c create mode 100644 arch/mips/loongson64/common/reset.c create mode 100644 arch/mips/loongson64/common/rtc.c create mode 100644 arch/mips/loongson64/common/serial.c create mode 100644 arch/mips/loongson64/common/setup.c create mode 100644 arch/mips/loongson64/common/time.c create mode 100644 arch/mips/loongson64/common/uart_base.c create mode 100644 arch/mips/loongson64/fuloong-2e/Makefile create mode 100644 arch/mips/loongson64/fuloong-2e/irq.c create mode 100644 arch/mips/loongson64/fuloong-2e/reset.c create mode 100644 arch/mips/loongson64/lemote-2f/Makefile create mode 100644 arch/mips/loongson64/lemote-2f/clock.c create mode 100644 arch/mips/loongson64/lemote-2f/ec_kb3310b.c create mode 100644 arch/mips/loongson64/lemote-2f/ec_kb3310b.h create mode 100644 arch/mips/loongson64/lemote-2f/irq.c create mode 100644 arch/mips/loongson64/lemote-2f/machtype.c create mode 100644 arch/mips/loongson64/lemote-2f/pm.c create mode 100644 arch/mips/loongson64/lemote-2f/reset.c create mode 100644 arch/mips/loongson64/loongson-3/Makefile create mode 100644 arch/mips/loongson64/loongson-3/cop2-ex.c create mode 100644 arch/mips/loongson64/loongson-3/hpet.c create mode 100644 arch/mips/loongson64/loongson-3/irq.c create mode 100644 arch/mips/loongson64/loongson-3/numa.c create mode 100644 arch/mips/loongson64/loongson-3/platform.c create mode 100644 arch/mips/loongson64/loongson-3/smp.c create mode 100644 arch/mips/loongson64/loongson-3/smp.h (limited to 'arch/mips/include') diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index 39cf40da5f14..a424e46b50af 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -15,8 +15,8 @@ platforms += jazz platforms += jz4740 platforms += lantiq platforms += lasat -platforms += loongson -platforms += loongson1 +platforms += loongson32 +platforms += loongson64 platforms += mti-malta platforms += mti-sead3 platforms += netlogic diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0ee59e8cdb57..733f6ac97f28 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -26,7 +26,7 @@ config MIPS select HAVE_SYSCALL_TRACEPOINTS select ARCH_HAS_ELF_RANDOMIZE select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT - select RTC_LIB if !MACH_LOONGSON + select RTC_LIB if !MACH_LOONGSON64 select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select HAVE_DMA_ATTRS @@ -346,26 +346,28 @@ config LASAT select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_LITTLE_ENDIAN -config MACH_LOONGSON - bool "Loongson family of machines" +config MACH_LOONGSON32 + bool "Loongson-1 family of machines" select SYS_SUPPORTS_ZBOOT help - This enables the support of Loongson family of machines. + This enables support for the Loongson-1 family of machines. - Loongson is a family of general-purpose MIPS-compatible CPUs. - developed at Institute of Computing Technology (ICT), - Chinese Academy of Sciences (CAS) in the People's Republic - of China. The chief architect is Professor Weiwu Hu. + Loongson-1 is a family of 32-bit MIPS-compatible SoCs developed by + the Institute of Computing Technology (ICT), Chinese Academy of + Sciences (CAS). -config MACH_LOONGSON1 - bool "Loongson 1 family of machines" +config MACH_LOONGSON64 + bool "Loongson-2/3 family of machines" select SYS_SUPPORTS_ZBOOT help - This enables support for the Loongson 1 based machines. + This enables the support of Loongson-2/3 family of machines. - Loongson 1 is a family of 32-bit MIPS-compatible SoCs developed by - the ICT (Institute of Computing Technology) and the Chinese Academy - of Sciences. + Loongson-2 is a family of single-core CPUs and Loongson-3 is a + family of multi-core CPUs. They are both 64-bit general-purpose + MIPS-compatible CPUs. Loongson-2/3 are developed by the Institute + of Computing Technology (ICT), Chinese Academy of Sciences (CAS) + in the People's Republic of China. The chief architect is Professor + Weiwu Hu. config MACH_PISTACHIO bool "IMG Pistachio SoC based boards" @@ -948,8 +950,8 @@ source "arch/mips/sibyte/Kconfig" source "arch/mips/txx9/Kconfig" source "arch/mips/vr41xx/Kconfig" source "arch/mips/cavium-octeon/Kconfig" -source "arch/mips/loongson/Kconfig" -source "arch/mips/loongson1/Kconfig" +source "arch/mips/loongson32/Kconfig" +source "arch/mips/loongson64/Kconfig" source "arch/mips/netlogic/Kconfig" source "arch/mips/paravirt/Kconfig" diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c index 237494b7a21a..408799a839b4 100644 --- a/arch/mips/boot/compressed/uart-16550.c +++ b/arch/mips/boot/compressed/uart-16550.c @@ -7,7 +7,7 @@ #include -#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA) +#if defined(CONFIG_MACH_LOONGSON64) || defined(CONFIG_MIPS_MALTA) #define UART_BASE 0x1fd003f8 #define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset)) #endif diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index b2a577ebce0b..a75c65da08b4 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON=y +CONFIG_MACH_LOONGSON64=y CONFIG_64BIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 0cbc9863c7c8..54cc3853d259 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON=y +CONFIG_MACH_LOONGSON64=y CONFIG_LEMOTE_MACH2F=y CONFIG_CS5536_MFGPT=y CONFIG_64BIT=y diff --git a/arch/mips/configs/loongson3_defconfig b/arch/mips/configs/loongson3_defconfig index c8442997477b..f8bf915c6d6b 100644 --- a/arch/mips/configs/loongson3_defconfig +++ b/arch/mips/configs/loongson3_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON=y +CONFIG_MACH_LOONGSON64=y CONFIG_SWIOTLB=y CONFIG_LOONGSON_MACH3X=y CONFIG_CPU_LOONGSON3=y diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/ls1b_defconfig index 7eb75543ca1a..1b2cc1fb26a1 100644 --- a/arch/mips/configs/ls1b_defconfig +++ b/arch/mips/configs/ls1b_defconfig @@ -1,4 +1,4 @@ -CONFIG_MACH_LOONGSON1=y +CONFIG_MACH_LOONGSON32=y CONFIG_PREEMPT=y # CONFIG_SECCOMP is not set CONFIG_EXPERIMENTAL=y diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h deleted file mode 100644 index fa802926523f..000000000000 --- a/arch/mips/include/asm/mach-loongson/boot_param.h +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_BOOT_PARAM_H_ -#define __ASM_MACH_LOONGSON_BOOT_PARAM_H_ - -#define SYSTEM_RAM_LOW 1 -#define SYSTEM_RAM_HIGH 2 -#define MEM_RESERVED 3 -#define PCI_IO 4 -#define PCI_MEM 5 -#define LOONGSON_CFG_REG 6 -#define VIDEO_ROM 7 -#define ADAPTER_ROM 8 -#define ACPI_TABLE 9 -#define SMBIOS_TABLE 10 -#define MAX_MEMORY_TYPE 11 - -#define LOONGSON3_BOOT_MEM_MAP_MAX 128 -struct efi_memory_map_loongson { - u16 vers; /* version of efi_memory_map */ - u32 nr_map; /* number of memory_maps */ - u32 mem_freq; /* memory frequence */ - struct mem_map { - u32 node_id; /* node_id which memory attached to */ - u32 mem_type; /* system memory, pci memory, pci io, etc. */ - u64 mem_start; /* memory map start address */ - u32 mem_size; /* each memory_map size, not the total size */ - } map[LOONGSON3_BOOT_MEM_MAP_MAX]; -} __packed; - -enum loongson_cpu_type { - Loongson_2E = 0, - Loongson_2F = 1, - Loongson_3A = 2, - Loongson_3B = 3, - Loongson_1A = 4, - Loongson_1B = 5 -}; - -/* - * Capability and feature descriptor structure for MIPS CPU - */ -struct efi_cpuinfo_loongson { - u16 vers; /* version of 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 */ - 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 { - u16 vers; - u16 size; - u16 rtr_bus; - u16 rtr_devfn; - u32 vendor; - u32 device; - u32 PIC_type; /* conform use HT or PCI to route to CPU-PIC */ - u64 ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ - u64 ht_enable; /* irqs used in this PIC */ - u32 node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ - u64 pci_mem_start_addr; - u64 pci_mem_end_addr; - u64 pci_io_start_addr; - u64 pci_io_end_addr; - u64 pci_config_addr; - u32 dma_mask_bits; -} __packed; - -struct interface_info { - u16 vers; /* version of the specificition */ - u16 size; - u8 flag; - char description[64]; -} __packed; - -#define MAX_RESOURCE_NUMBER 128 -struct resource_loongson { - u64 start; /* resource start address */ - u64 end; /* resource end address */ - char name[64]; - u32 flags; -}; - -struct archdev_data {}; /* arch specific additions */ - -struct board_devices { - char name[64]; /* hold the device name */ - u32 num_resources; /* number of device_resource */ - /* for each device's resource */ - struct resource_loongson resource[MAX_RESOURCE_NUMBER]; - /* arch specific additions */ - struct archdev_data archdata; -}; - -struct loongson_special_attribute { - u16 vers; /* version of this special */ - char special_name[64]; /* special_atribute_name */ - u32 loongson_special_type; /* type of special device */ - /* for each device's resource */ - struct resource_loongson resource[MAX_RESOURCE_NUMBER]; -}; - -struct loongson_params { - u64 memory_offset; /* efi_memory_map_loongson struct offset */ - u64 cpu_offset; /* efi_cpuinfo_loongson struct offset */ - u64 system_offset; /* system_loongson struct offset */ - u64 irq_offset; /* irq_source_routing_table struct offset */ - u64 interface_offset; /* interface_info struct offset */ - u64 special_offset; /* loongson_special_attribute struct offset */ - u64 boarddev_table_offset; /* board_devices offset */ -}; - -struct smbios_tables { - u16 vers; /* version of smbios */ - u64 vga_bios; /* vga_bios address */ - struct loongson_params lp; -}; - -struct efi_reset_system_t { - u64 ResetCold; - u64 ResetWarm; - u64 ResetType; - u64 Shutdown; - u64 DoSuspend; /* NULL if not support */ -}; - -struct efi_loongson { - u64 mps; /* MPS table */ - u64 acpi; /* ACPI table (IA64 ext 0.71) */ - u64 acpi20; /* ACPI table (ACPI 2.0) */ - struct smbios_tables smbios; /* SM BIOS table */ - u64 sal_systab; /* SAL system table */ - u64 boot_info; /* boot info table */ -}; - -struct boot_params { - struct efi_loongson efi; - struct efi_reset_system_t reset_system; -}; - -struct loongson_system_configuration { - u32 nr_cpus; - 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; - u64 pci_mem_end_addr; - u64 pci_io_base; - u64 restart_addr; - u64 poweroff_addr; - 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; - -#endif diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h deleted file mode 100644 index acc376897e46..000000000000 --- a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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) 2009 Wu Zhangjin - * Copyright (C) 2009 Philippe Vachon - * Copyright (C) 2009 Zhang Le - * - * reference: /proc/cpuinfo, - * arch/mips/kernel/cpu-probe.c(cpu_probe_legacy), - * arch/mips/kernel/proc.c(show_cpuinfo), - * loongson2f user manual. - */ - -#ifndef __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#define cpu_scache_line_size() 32 - - -#define cpu_has_32fpr 1 -#define cpu_has_3k_cache 0 -#define cpu_has_4k_cache 1 -#define cpu_has_4kex 1 -#define cpu_has_64bits 1 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_counter 1 -#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) -#define cpu_has_divec 0 -#define cpu_has_dsp 0 -#define cpu_has_dsp2 0 -#define cpu_has_ejtag 0 -#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_inclusive_pcaches 1 -#define cpu_has_llsc 1 -#define cpu_has_mcheck 0 -#define cpu_has_mdmx 0 -#define cpu_has_mips16 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips3d 0 -#define cpu_has_mips64r2 0 -#define cpu_has_mipsmt 0 -#define cpu_has_prefetch 0 -#define cpu_has_smartmips 0 -#define cpu_has_tlb 1 -#define cpu_has_tx39_cache 0 -#define cpu_has_userlocal 0 -#define cpu_has_vce 0 -#define cpu_has_veic 0 -#define cpu_has_vint 0 -#define cpu_has_vtag_icache 0 -#define cpu_has_watch 1 -#define cpu_has_local_ebase 0 - -#define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) - -#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h deleted file mode 100644 index a0ee0cb775ad..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * The header file of cs5536 south bridge. - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu - */ - -#ifndef _CS5536_H -#define _CS5536_H - -#include - -extern void _rdmsr(u32 msr, u32 *hi, u32 *lo); -extern void _wrmsr(u32 msr, u32 hi, u32 lo); - -/* - * MSR module base - */ -#define CS5536_SB_MSR_BASE (0x00000000) -#define CS5536_GLIU_MSR_BASE (0x10000000) -#define CS5536_ILLEGAL_MSR_BASE (0x20000000) -#define CS5536_USB_MSR_BASE (0x40000000) -#define CS5536_IDE_MSR_BASE (0x60000000) -#define CS5536_DIVIL_MSR_BASE (0x80000000) -#define CS5536_ACC_MSR_BASE (0xa0000000) -#define CS5536_UNUSED_MSR_BASE (0xc0000000) -#define CS5536_GLCP_MSR_BASE (0xe0000000) - -#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | (offset)) -#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | (offset)) -#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset)) -#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | (offset)) -#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | (offset)) -#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | (offset)) -#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | (offset)) -#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset)) -#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | (offset)) - -/* - * BAR SPACE OF VIRTUAL PCI : - * range for pci probe use, length is the actual size. - */ -/* IO space for all DIVIL modules */ -#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */ -#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */ -#define CS5536_SMB_RANGE 0xfffffff8 -#define CS5536_SMB_LENGTH 0x08 -#define CS5536_GPIO_RANGE 0xffffff00 -#define CS5536_GPIO_LENGTH 0x100 -#define CS5536_MFGPT_RANGE 0xffffffc0 -#define CS5536_MFGPT_LENGTH 0x40 -#define CS5536_ACPI_RANGE 0xffffffe0 -#define CS5536_ACPI_LENGTH 0x20 -#define CS5536_PMS_RANGE 0xffffff80 -#define CS5536_PMS_LENGTH 0x80 -/* IO space for IDE */ -#define CS5536_IDE_RANGE 0xfffffff0 -#define CS5536_IDE_LENGTH 0x10 -/* IO space for ACC */ -#define CS5536_ACC_RANGE 0xffffff80 -#define CS5536_ACC_LENGTH 0x80 -/* MEM space for ALL USB modules */ -#define CS5536_OHCI_RANGE 0xfffff000 -#define CS5536_OHCI_LENGTH 0x1000 -#define CS5536_EHCI_RANGE 0xfffff000 -#define CS5536_EHCI_LENGTH 0x1000 - -/* - * PCI MSR ACCESS - */ -#define PCI_MSR_CTRL 0xF0 -#define PCI_MSR_ADDR 0xF4 -#define PCI_MSR_DATA_LO 0xF8 -#define PCI_MSR_DATA_HI 0xFC - -/**************** MSR *****************************/ - -/* - * GLIU STANDARD MSR - */ -#define GLIU_CAP 0x00 -#define GLIU_CONFIG 0x01 -#define GLIU_SMI 0x02 -#define GLIU_ERROR 0x03 -#define GLIU_PM 0x04 -#define GLIU_DIAG 0x05 - -/* - * GLIU SPEC. MSR - */ -#define GLIU_P2D_BM0 0x20 -#define GLIU_P2D_BM1 0x21 -#define GLIU_P2D_BM2 0x22 -#define GLIU_P2D_BMK0 0x23 -#define GLIU_P2D_BMK1 0x24 -#define GLIU_P2D_BM3 0x25 -#define GLIU_P2D_BM4 0x26 -#define GLIU_COH 0x80 -#define GLIU_PAE 0x81 -#define GLIU_ARB 0x82 -#define GLIU_ASMI 0x83 -#define GLIU_AERR 0x84 -#define GLIU_DEBUG 0x85 -#define GLIU_PHY_CAP 0x86 -#define GLIU_NOUT_RESP 0x87 -#define GLIU_NOUT_WDATA 0x88 -#define GLIU_WHOAMI 0x8B -#define GLIU_SLV_DIS 0x8C -#define GLIU_IOD_BM0 0xE0 -#define GLIU_IOD_BM1 0xE1 -#define GLIU_IOD_BM2 0xE2 -#define GLIU_IOD_BM3 0xE3 -#define GLIU_IOD_BM4 0xE4 -#define GLIU_IOD_BM5 0xE5 -#define GLIU_IOD_BM6 0xE6 -#define GLIU_IOD_BM7 0xE7 -#define GLIU_IOD_BM8 0xE8 -#define GLIU_IOD_BM9 0xE9 -#define GLIU_IOD_SC0 0xEA -#define GLIU_IOD_SC1 0xEB -#define GLIU_IOD_SC2 0xEC -#define GLIU_IOD_SC3 0xED -#define GLIU_IOD_SC4 0xEE -#define GLIU_IOD_SC5 0xEF -#define GLIU_IOD_SC6 0xF0 -#define GLIU_IOD_SC7 0xF1 - -/* - * SB STANDARD - */ -#define SB_CAP 0x00 -#define SB_CONFIG 0x01 -#define SB_SMI 0x02 -#define SB_ERROR 0x03 -#define SB_MAR_ERR_EN 0x00000001 -#define SB_TAR_ERR_EN 0x00000002 -#define SB_RSVD_BIT1 0x00000004 -#define SB_EXCEP_ERR_EN 0x00000008 -#define SB_SYSE_ERR_EN 0x00000010 -#define SB_PARE_ERR_EN 0x00000020 -#define SB_TAS_ERR_EN 0x00000040 -#define SB_MAR_ERR_FLAG 0x00010000 -#define SB_TAR_ERR_FLAG 0x00020000 -#define SB_RSVD_BIT2 0x00040000 -#define SB_EXCEP_ERR_FLAG 0x00080000 -#define SB_SYSE_ERR_FLAG 0x00100000 -#define SB_PARE_ERR_FLAG 0x00200000 -#define SB_TAS_ERR_FLAG 0x00400000 -#define SB_PM 0x04 -#define SB_DIAG 0x05 - -/* - * SB SPEC. - */ -#define SB_CTRL 0x10 -#define SB_R0 0x20 -#define SB_R1 0x21 -#define SB_R2 0x22 -#define SB_R3 0x23 -#define SB_R4 0x24 -#define SB_R5 0x25 -#define SB_R6 0x26 -#define SB_R7 0x27 -#define SB_R8 0x28 -#define SB_R9 0x29 -#define SB_R10 0x2A -#define SB_R11 0x2B -#define SB_R12 0x2C -#define SB_R13 0x2D -#define SB_R14 0x2E -#define SB_R15 0x2F - -/* - * GLCP STANDARD - */ -#define GLCP_CAP 0x00 -#define GLCP_CONFIG 0x01 -#define GLCP_SMI 0x02 -#define GLCP_ERROR 0x03 -#define GLCP_PM 0x04 -#define GLCP_DIAG 0x05 - -/* - * GLCP SPEC. - */ -#define GLCP_CLK_DIS_DELAY 0x08 -#define GLCP_PM_CLK_DISABLE 0x09 -#define GLCP_GLB_PM 0x0B -#define GLCP_DBG_OUT 0x0C -#define GLCP_RSVD1 0x0D -#define GLCP_SOFT_COM 0x0E -#define SOFT_BAR_SMB_FLAG 0x00000001 -#define SOFT_BAR_GPIO_FLAG 0x00000002 -#define SOFT_BAR_MFGPT_FLAG 0x00000004 -#define SOFT_BAR_IRQ_FLAG 0x00000008 -#define SOFT_BAR_PMS_FLAG 0x00000010 -#define SOFT_BAR_ACPI_FLAG 0x00000020 -#define SOFT_BAR_IDE_FLAG 0x00000400 -#define SOFT_BAR_ACC_FLAG 0x00000800 -#define SOFT_BAR_OHCI_FLAG 0x00001000 -#define SOFT_BAR_EHCI_FLAG 0x00002000 -#define GLCP_RSVD2 0x0F -#define GLCP_CLK_OFF 0x10 -#define GLCP_CLK_ACTIVE 0x11 -#define GLCP_CLK_DISABLE 0x12 -#define GLCP_CLK4ACK 0x13 -#define GLCP_SYS_RST 0x14 -#define GLCP_RSVD3 0x15 -#define GLCP_DBG_CLK_CTRL 0x16 -#define GLCP_CHIP_REV_ID 0x17 - -/* PIC */ -#define PIC_YSEL_LOW 0x20 -#define PIC_YSEL_LOW_USB_SHIFT 8 -#define PIC_YSEL_LOW_ACC_SHIFT 16 -#define PIC_YSEL_LOW_FLASH_SHIFT 24 -#define PIC_YSEL_HIGH 0x21 -#define PIC_ZSEL_LOW 0x22 -#define PIC_ZSEL_HIGH 0x23 -#define PIC_IRQM_PRIM 0x24 -#define PIC_IRQM_LPC 0x25 -#define PIC_XIRR_STS_LOW 0x26 -#define PIC_XIRR_STS_HIGH 0x27 -#define PCI_SHDW 0x34 - -/* - * DIVIL STANDARD - */ -#define DIVIL_CAP 0x00 -#define DIVIL_CONFIG 0x01 -#define DIVIL_SMI 0x02 -#define DIVIL_ERROR 0x03 -#define DIVIL_PM 0x04 -#define DIVIL_DIAG 0x05 - -/* - * DIVIL SPEC. - */ -#define DIVIL_LBAR_IRQ 0x08 -#define DIVIL_LBAR_KEL 0x09 -#define DIVIL_LBAR_SMB 0x0B -#define DIVIL_LBAR_GPIO 0x0C -#define DIVIL_LBAR_MFGPT 0x0D -#define DIVIL_LBAR_ACPI 0x0E -#define DIVIL_LBAR_PMS 0x0F -#define DIVIL_LEG_IO 0x14 -#define DIVIL_BALL_OPTS 0x15 -#define DIVIL_SOFT_IRQ 0x16 -#define DIVIL_SOFT_RESET 0x17 - -/* MFGPT */ -#define MFGPT_IRQ 0x28 - -/* - * IDE STANDARD - */ -#define IDE_CAP 0x00 -#define IDE_CONFIG 0x01 -#define IDE_SMI 0x02 -#define IDE_ERROR 0x03 -#define IDE_PM 0x04 -#define IDE_DIAG 0x05 - -/* - * IDE SPEC. - */ -#define IDE_IO_BAR 0x08 -#define IDE_CFG 0x10 -#define IDE_DTC 0x12 -#define IDE_CAST 0x13 -#define IDE_ETC 0x14 -#define IDE_INTERNAL_PM 0x15 - -/* - * ACC STANDARD - */ -#define ACC_CAP 0x00 -#define ACC_CONFIG 0x01 -#define ACC_SMI 0x02 -#define ACC_ERROR 0x03 -#define ACC_PM 0x04 -#define ACC_DIAG 0x05 - -/* - * USB STANDARD - */ -#define USB_CAP 0x00 -#define USB_CONFIG 0x01 -#define USB_SMI 0x02 -#define USB_ERROR 0x03 -#define USB_PM 0x04 -#define USB_DIAG 0x05 - -/* - * USB SPEC. - */ -#define USB_OHCI 0x08 -#define USB_EHCI 0x09 - -/****************** NATIVE ***************************/ -/* GPIO : I/O SPACE; REG : 32BITS */ -#define GPIOL_OUT_VAL 0x00 -#define GPIOL_OUT_EN 0x04 - -#endif /* _CS5536_H */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h deleted file mode 100644 index 021d0172dad6..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * cs5536 mfgpt header file - */ - -#ifndef _CS5536_MFGPT_H -#define _CS5536_MFGPT_H - -#include -#include - -#ifdef CONFIG_CS5536_MFGPT -extern void setup_mfgpt0_timer(void); -extern void disable_mfgpt0_counter(void); -extern void enable_mfgpt0_counter(void); -#else -static inline void __maybe_unused setup_mfgpt0_timer(void) -{ -} -static inline void __maybe_unused disable_mfgpt0_counter(void) -{ -} -static inline void __maybe_unused enable_mfgpt0_counter(void) -{ -} -#endif - -#define MFGPT_TICK_RATE 14318000 -#define COMPARE ((MFGPT_TICK_RATE + HZ/2) / HZ) - -#define MFGPT_BASE mfgpt_base -#define MFGPT0_CMP2 (MFGPT_BASE + 2) -#define MFGPT0_CNT (MFGPT_BASE + 4) -#define MFGPT0_SETUP (MFGPT_BASE + 6) - -#endif /*!_CS5536_MFGPT_H */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h deleted file mode 100644 index 8a7ecb4d5c64..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * the definition file of cs5536 Virtual Support Module(VSM). - * pci configuration space can be accessed through the VSM, so - * there is no need of the MSR read/write now, except the spec. - * MSR registers which are not implemented yet. - * - * Copyright (C) 2007 Lemote Inc. - * Author : jlliu, liujl@lemote.com - */ - -#ifndef _CS5536_PCI_H -#define _CS5536_PCI_H - -#include -#include - -extern void cs5536_pci_conf_write4(int function, int reg, u32 value); -extern u32 cs5536_pci_conf_read4(int function, int reg); - -#define CS5536_ACC_INTR 9 -#define CS5536_IDE_INTR 14 -#define CS5536_USB_INTR 11 -#define CS5536_MFGPT_INTR 5 -#define CS5536_UART1_INTR 4 -#define CS5536_UART2_INTR 3 - -/************** PCI BUS DEVICE FUNCTION ***************/ - -/* - * PCI bus device function - */ -#define PCI_BUS_CS5536 0 -#define PCI_IDSEL_CS5536 14 - -/********** STANDARD PCI-2.2 EXPANSION ****************/ - -/* - * PCI configuration space - * we have to virtualize the PCI configure space head, so we should - * define the necessary IDs and some others. - */ - -/* CONFIG of PCI VENDOR ID*/ -#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \ - (((mod_dev_id) << 16) | (sys_vendor_id)) - -/* VENDOR ID */ -#define CS5536_VENDOR_ID 0x1022 - -/* DEVICE ID */ -#define CS5536_ISA_DEVICE_ID 0x2090 -#define CS5536_IDE_DEVICE_ID 0x209a -#define CS5536_ACC_DEVICE_ID 0x2093 -#define CS5536_OHCI_DEVICE_ID 0x2094 -#define CS5536_EHCI_DEVICE_ID 0x2095 - -/* CLASS CODE : CLASS SUB-CLASS INTERFACE */ -#define CS5536_ISA_CLASS_CODE 0x060100 -#define CS5536_IDE_CLASS_CODE 0x010180 -#define CS5536_ACC_CLASS_CODE 0x040100 -#define CS5536_OHCI_CLASS_CODE 0x0C0310 -#define CS5536_EHCI_CLASS_CODE 0x0C0320 - -/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */ - -#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer) \ - ((PCI_NONE_BIST << 24) | ((header_type) << 16) \ - | ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE); - -#define PCI_NONE_BIST 0x00 /* RO not implemented yet. */ -#define PCI_BRIDGE_HEADER_TYPE 0x80 /* RO */ -#define PCI_NORMAL_HEADER_TYPE 0x00 -#define PCI_NORMAL_LATENCY_TIMER 0x00 -#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 /* RW */ - -/* BAR */ -#define PCI_BAR0_REG 0x10 -#define PCI_BAR1_REG 0x14 -#define PCI_BAR2_REG 0x18 -#define PCI_BAR3_REG 0x1c -#define PCI_BAR4_REG 0x20 -#define PCI_BAR5_REG 0x24 -#define PCI_BAR_COUNT 6 -#define PCI_BAR_RANGE_MASK 0xFFFFFFFF - -/* CARDBUS CIS POINTER */ -#define PCI_CARDBUS_CIS_POINTER 0x00000000 - -/* SUBSYSTEM VENDOR ID */ -#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID - -/* SUBSYSTEM ID */ -#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID -#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID -#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID -#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID -#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID - -/* EXPANSION ROM BAR */ -#define PCI_EXPANSION_ROM_BAR 0x00000000 - -/* CAPABILITIES POINTER */ -#define PCI_CAPLIST_POINTER 0x00000000 -#define PCI_CAPLIST_USB_POINTER 0x40 -/* INTERRUPT */ - -#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \ - ((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \ - ((pin) << 8) | (mod_intr)) - -#define PCI_MAX_LATENCY 0x40 -#define PCI_MIN_GRANT 0x00 -#define PCI_DEFAULT_PIN 0x01 - -/*********** EXPANSION PCI REG ************************/ - -/* - * ISA EXPANSION - */ -#define PCI_UART1_INT_REG 0x50 -#define PCI_UART2_INT_REG 0x54 -#define PCI_ISA_FIXUP_REG 0x58 - -/* - * IDE EXPANSION - */ -#define PCI_IDE_CFG_REG 0x40 -#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF -#define PCI_IDE_DTC_REG 0x48 -#define PCI_IDE_CAST_REG 0x4C -#define PCI_IDE_ETC_REG 0x50 -#define PCI_IDE_PM_REG 0x54 -#define PCI_IDE_INT_REG 0x60 - -/* - * ACC EXPANSION - */ -#define PCI_ACC_INT_REG 0x50 - -/* - * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI - */ -#define PCI_OHCI_PM_REG 0x40 -#define PCI_OHCI_INT_REG 0x50 - -/* - * EHCI EXPANSION - */ -#define PCI_EHCI_LEGSMIEN_REG 0x50 -#define PCI_EHCI_LEGSMISTS_REG 0x54 -#define PCI_EHCI_FLADJ_REG 0x60 - -#endif /* _CS5536_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h deleted file mode 100644 index 1f17c1815ee5..000000000000 --- a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * the read/write interfaces for Virtual Support Module(VSM) - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - */ - -#ifndef _CS5536_VSM_H -#define _CS5536_VSM_H - -#include - -typedef void (*cs5536_pci_vsm_write)(int reg, u32 value); -typedef u32 (*cs5536_pci_vsm_read)(int reg); - -#define DECLARE_CS5536_MODULE(name) \ -extern void pci_##name##_write_reg(int reg, u32 value); \ -extern u32 pci_##name##_read_reg(int reg); - -/* ide module */ -DECLARE_CS5536_MODULE(ide) -/* acc module */ -DECLARE_CS5536_MODULE(acc) -/* ohci module */ -DECLARE_CS5536_MODULE(ohci) -/* isa module */ -DECLARE_CS5536_MODULE(isa) -/* ehci module */ -DECLARE_CS5536_MODULE(ehci) - -#endif /* _CS5536_VSM_H */ diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h deleted file mode 100644 index 4bf4e19f72e8..000000000000 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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, 07 Ralf Baechle - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - */ -#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H -#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H - -#ifdef CONFIG_SWIOTLB -#include -#endif - -struct device; - -extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); -extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr); -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ -#ifdef CONFIG_CPU_LOONGSON3 - return phys_to_dma(dev, virt_to_phys(addr)); -#else - return virt_to_phys(addr) | 0x80000000; -#endif -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ -#ifdef CONFIG_CPU_LOONGSON3 - return phys_to_dma(dev, page_to_phys(page)); -#else - return page_to_phys(page) | 0x80000000; -#endif -} - -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_to_phys(dev, dma_addr); -#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) - return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); -#else - return dma_addr & 0x7fffffff; -#endif -} - -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) -{ -#ifdef CONFIG_DMA_NONCOHERENT - return 0; -#else - return 1; -#endif /* CONFIG_DMA_NONCOHERENT */ -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - -#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-loongson/gpio.h b/arch/mips/include/asm/mach-loongson/gpio.h deleted file mode 100644 index b3b216904a9a..000000000000 --- a/arch/mips/include/asm/mach-loongson/gpio.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Loongson GPIO Support - * - * Copyright (c) 2008 Richard Liu, STMicroelectronics - * Copyright (c) 2008-2010 Arnaud Patard - * Copyright (c) 2014 Huacai Chen - * - * 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 __LOONGSON_GPIO_H -#define __LOONGSON_GPIO_H - -#include - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value -#define gpio_cansleep __gpio_cansleep - -/* The chip can do interrupt - * but it has not been tested and doc not clear - */ -static inline int gpio_to_irq(int gpio) -{ - return -EINVAL; -} - -static inline int irq_to_gpio(int gpio) -{ - return -EINVAL; -} - -#endif /* __LOONGSON_GPIO_H */ diff --git a/arch/mips/include/asm/mach-loongson/irq.h b/arch/mips/include/asm/mach-loongson/irq.h deleted file mode 100644 index a281cca5f2fb..000000000000 --- a/arch/mips/include/asm/mach-loongson/irq.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_IRQ_H_ -#define __ASM_MACH_LOONGSON_IRQ_H_ - -#include - -#ifdef CONFIG_CPU_LOONGSON3 - -/* cpu core interrupt numbers */ -#define MIPS_CPU_IRQ_BASE 56 - -#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */ -#define LOONGSON_HT1_IRQ (MIPS_CPU_IRQ_BASE + 3) /* HT1 */ -#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */ - -#define LOONGSON_HT1_CFG_BASE loongson_sysconf.ht_control_base -#define LOONGSON_HT1_INT_VECTOR_BASE (LOONGSON_HT1_CFG_BASE + 0x80) -#define LOONGSON_HT1_INT_EN_BASE (LOONGSON_HT1_CFG_BASE + 0xa0) -#define LOONGSON_HT1_INT_VECTOR(n) \ - LOONGSON3_REG32(LOONGSON_HT1_INT_VECTOR_BASE, 4 * (n)) -#define LOONGSON_HT1_INTN_EN(n) \ - LOONGSON3_REG32(LOONGSON_HT1_INT_EN_BASE, 4 * (n)) - -#define LOONGSON_INT_ROUTER_OFFSET 0x1400 -#define LOONGSON_INT_ROUTER_INTEN \ - LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x24) -#define LOONGSON_INT_ROUTER_INTENSET \ - LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x28) -#define LOONGSON_INT_ROUTER_INTENCLR \ - LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x2c) -#define LOONGSON_INT_ROUTER_ENTRY(n) \ - LOONGSON3_REG8(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + n) -#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_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */ - -#endif - -extern void fixup_irqs(void); -extern void loongson3_ipi_interrupt(struct pt_regs *regs); - -#include_next -#endif /* __ASM_MACH_LOONGSON_IRQ_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson/kernel-entry-init.h deleted file mode 100644 index df5fca8eeb80..000000000000 --- a/arch/mips/include/asm/mach-loongson/kernel-entry-init.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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) 2005 Embedded Alley Solutions, Inc - * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) - * Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn) - * Copyright (C) 2012 Huacai Chen (chenhc@lemote.com) - */ -#ifndef __ASM_MACH_LOONGSON_KERNEL_ENTRY_H -#define __ASM_MACH_LOONGSON_KERNEL_ENTRY_H - -/* - * Override macros used in arch/mips/kernel/head.S. - */ - .macro kernel_entry_setup -#ifdef CONFIG_CPU_LOONGSON3 - .set push - .set mips64 - /* Set LPA on LOONGSON3 config3 */ - mfc0 t0, $16, 3 - or t0, (0x1 << 7) - mtc0 t0, $16, 3 - /* Set ELPA on LOONGSON3 pagegrain */ - li t0, (0x1 << 29) - mtc0 t0, $5, 1 - _ehb - .set pop -#endif - .endm - -/* - * Do SMP slave processor setup. - */ - .macro smp_slave_setup -#ifdef CONFIG_CPU_LOONGSON3 - .set push - .set mips64 - /* Set LPA on LOONGSON3 config3 */ - mfc0 t0, $16, 3 - or t0, (0x1 << 7) - mtc0 t0, $16, 3 - /* Set ELPA on LOONGSON3 pagegrain */ - li t0, (0x1 << 29) - mtc0 t0, $5, 1 - _ehb - .set pop -#endif - .endm - -#endif /* __ASM_MACH_LOONGSON_KERNEL_ENTRY_H */ diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h deleted file mode 100644 index 9783103fd6f6..000000000000 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - * - * 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_LOONGSON_LOONGSON_H -#define __ASM_MACH_LOONGSON_LOONGSON_H - -#include -#include -#include -#include -#include - -/* loongson internal northbridge initialization */ -extern void bonito_irq_init(void); - -/* machine-specific reboot/halt operation */ -extern void mach_prepare_reboot(void); -extern void mach_prepare_shutdown(void); - -/* environment arguments from bootloader */ -extern u32 cpu_clock_freq; -extern u32 memsize, highmemsize; -extern struct plat_smp_ops loongson3_smp_ops; - -/* loongson-specific command line, env and memory initialization */ -extern void __init prom_init_memory(void); -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 void prom_init_loongson_uart_base(void); -#endif - -static inline void prom_init_uart_base(void) -{ -#ifdef CONFIG_LOONGSON_UART_BASE - prom_init_loongson_uart_base(); -#endif -} - -/* irq operation functions */ -extern void bonito_irqdispatch(void); -extern void __init bonito_irq_init(void); -extern void __init mach_init_irq(void); -extern void mach_irq_dispatch(unsigned int pending); -extern int mach_i8259_irq(void); - -/* We need this in some places... */ -#define delay() ({ \ - int x; \ - for (x = 0; x < 100000; x++) \ - __asm__ __volatile__(""); \ -}) - -#define LOONGSON_REG(x) \ - (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x))) - -#define LOONGSON3_REG8(base, x) \ - (*(volatile u8 *)((char *)TO_UNCAC(base) + (x))) - -#define LOONGSON3_REG32(base, x) \ - (*(volatile u32 *)((char *)TO_UNCAC(base) + (x))) - -#define LOONGSON_IRQ_BASE 32 -#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */ - -#include -static inline void do_perfcnt_IRQ(void) -{ -#if IS_ENABLED(CONFIG_OPROFILE) - do_IRQ(LOONGSON2_PERFCNT_IRQ); -#endif -} - -#define LOONGSON_FLASH_BASE 0x1c000000 -#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */ -#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1) - -#define LOONGSON_LIO0_BASE 0x1e000000 -#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */ -#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1) - -#define LOONGSON_BOOT_BASE 0x1fc00000 -#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */ -#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1) -#define LOONGSON_REG_BASE 0x1fe00000 -#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */ -#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1) -/* Loongson-3 specific registers */ -#define LOONGSON3_REG_BASE 0x3ff00000 -#define LOONGSON3_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */ -#define LOONGSON3_REG_TOP (LOONGSON3_REG_BASE+LOONGSON3_REG_SIZE-1) - -#define LOONGSON_LIO1_BASE 0x1ff00000 -#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */ -#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1) - -#define LOONGSON_PCILO0_BASE 0x10000000 -#define LOONGSON_PCILO1_BASE 0x14000000 -#define LOONGSON_PCILO2_BASE 0x18000000 -#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE -#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */ -#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1) - -#define LOONGSON_PCICFG_BASE 0x1fe80000 -#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */ -#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1) - -#if defined(CONFIG_HT_PCI) -#define LOONGSON_PCIIO_BASE loongson_sysconf.pci_io_base -#else -#define LOONGSON_PCIIO_BASE 0x1fd00000 -#endif - -#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */ -#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1) - -/* Loongson Register Bases */ - -#define LOONGSON_PCICONFIGBASE 0x00 -#define LOONGSON_REGBASE 0x100 - -/* PCI Configuration Registers */ - -#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x)) -#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00) -#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04) -#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08) -#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c) -#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10) -#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14) -#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18) -#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c) -#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20) -#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30) -#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c) - -#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c) - -#define LOONGSON_PCICMD_PERR_CLR 0x80000000 -#define LOONGSON_PCICMD_SERR_CLR 0x40000000 -#define LOONGSON_PCICMD_MABORT_CLR 0x20000000 -#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000 -#define LOONGSON_PCICMD_TABORT_CLR 0x08000000 -#define LOONGSON_PCICMD_MPERR_CLR 0x01000000 -#define LOONGSON_PCICMD_PERRRESPEN 0x00000040 -#define LOONGSON_PCICMD_ASTEPEN 0x00000080 -#define LOONGSON_PCICMD_SERREN 0x00000100 -#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00 -#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8 - -/* Loongson h/w Configuration */ - -#define LOONGSON_GENCFG_OFFSET 0x4 -#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET) - -#define LOONGSON_GENCFG_DEBUGMODE 0x00000001 -#define LOONGSON_GENCFG_SNOOPEN 0x00000002 -#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004 - -#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008 -#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010 -#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020 -#define LOONGSON_GENCFG_BYTESWAP 0x00000040 - -#define LOONGSON_GENCFG_UNCACHED 0x00000080 -#define LOONGSON_GENCFG_PREFETCHEN 0x00000100 -#define LOONGSON_GENCFG_WBEHINDEN 0x00000200 -#define LOONGSON_GENCFG_CACHEALG 0x00000c00 -#define LOONGSON_GENCFG_CACHEALG_SHIFT 10 -#define LOONGSON_GENCFG_PCIQUEUE 0x00001000 -#define LOONGSON_GENCFG_CACHESTOP 0x00002000 -#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000 -#define LOONGSON_GENCFG_BUSERREN 0x00008000 -#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000 -#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000 - -/* PCI address map control */ - -#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10) -#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14) -#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18) - -/* GPIO Regs - r/w */ - -#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c) -#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20) - -/* ICU Configuration Regs - r/w */ - -#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24) -#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28) -#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c) - -/* ICU Enable Regs - IntEn & IntISR are r/o. */ - -#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30) -#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34) -#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38) -#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c) - -/* ICU */ -#define LOONGSON_ICU_MBOXES 0x0000000f -#define LOONGSON_ICU_MBOXES_SHIFT 0 -#define LOONGSON_ICU_DMARDY 0x00000010 -#define LOONGSON_ICU_DMAEMPTY 0x00000020 -#define LOONGSON_ICU_COPYRDY 0x00000040 -#define LOONGSON_ICU_COPYEMPTY 0x00000080 -#define LOONGSON_ICU_COPYERR 0x00000100 -#define LOONGSON_ICU_PCIIRQ 0x00000200 -#define LOONGSON_ICU_MASTERERR 0x00000400 -#define LOONGSON_ICU_SYSTEMERR 0x00000800 -#define LOONGSON_ICU_DRAMPERR 0x00001000 -#define LOONGSON_ICU_RETRYERR 0x00002000 -#define LOONGSON_ICU_GPIOS 0x01ff0000 -#define LOONGSON_ICU_GPIOS_SHIFT 16 -#define LOONGSON_ICU_GPINS 0x7e000000 -#define LOONGSON_ICU_GPINS_SHIFT 25 -#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N))) -#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N))) -#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N))) - -/* PCI prefetch window base & mask */ - -#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40) -#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44) -#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48) -#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c) - -/* PCI_Hit*_Sel_* */ - -#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50) -#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54) -#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58) -#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c) -#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60) -#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64) - -/* PXArb Config & Status */ - -#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68) -#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c) - -#define MAX_PACKAGES 4 - -/* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */ -extern u64 loongson_chipcfg[MAX_PACKAGES]; -#define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id])) - -/* Chip Temperature registor of each physical cpu package, PRid >= Loongson-3A */ -extern u64 loongson_chiptemp[MAX_PACKAGES]; -#define LOONGSON_CHIPTEMP(id) (*(volatile u32 *)(loongson_chiptemp[id])) - -/* Freq Control register of each physical cpu package, PRid >= Loongson-3B */ -extern u64 loongson_freqctrl[MAX_PACKAGES]; -#define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id])) - -/* pcimap */ - -#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f -#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0 -#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0 -#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6 -#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000 -#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12 -#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000 -#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \ - ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) - -#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ -#include -extern struct cpufreq_frequency_table loongson2_clockmod_table[]; -#endif - -/* - * address windows configuration module - * - * loongson2e do not have this module - */ -#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG - -/* address window config module base address */ -#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul -#define LOONGSON_ADDRWINCFG_SIZE 0x180 - -extern unsigned long _loongson_addrwincfg_base; -#define LOONGSON_ADDRWINCFG(offset) \ - (*(volatile u64 *)(_loongson_addrwincfg_base + (offset))) - -#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00) -#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08) -#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10) -#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18) - -#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20) -#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28) -#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30) -#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38) - -#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40) -#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48) -#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50) -#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58) - -#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60) -#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68) -#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70) -#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78) - -#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80) -#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88) -#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90) -#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98) - -#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0) -#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8) -#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0) -#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8) - -#define ADDRWIN_WIN0 0 -#define ADDRWIN_WIN1 1 -#define ADDRWIN_WIN2 2 -#define ADDRWIN_WIN3 3 - -#define ADDRWIN_MAP_DST_DDR 0 -#define ADDRWIN_MAP_DST_PCI 1 -#define ADDRWIN_MAP_DST_LIO 1 - -/* - * s: CPU, PCIDMA - * d: DDR, PCI, LIO - * win: 0, 1, 2, 3 - * src: map source - * dst: map destination - * size: ~mask + 1 - */ -#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\ - s##_WIN##w##_BASE = (src); \ - s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \ - s##_WIN##w##_MASK = ~(size-1); \ -} while (0) - -#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \ - LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size) -#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \ - LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size) -#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \ - LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size) - -#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */ - -#endif /* __ASM_MACH_LOONGSON_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h deleted file mode 100644 index 4431fc54a36c..000000000000 --- a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __LOONGSON_HWMON_H_ -#define __LOONGSON_HWMON_H_ - -#include - -#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_*/ diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h deleted file mode 100644 index cb2b60249cd2..000000000000 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - * - * 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_LOONGSON_MACHINE_H -#define __ASM_MACH_LOONGSON_MACHINE_H - -#ifdef CONFIG_LEMOTE_FULOONG2E - -#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E - -#endif - -/* use fuloong2f as the default machine of LEMOTE_MACH2F */ -#ifdef CONFIG_LEMOTE_MACH2F - -#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F - -#endif - -#ifdef CONFIG_LOONGSON_MACH3X - -#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC - -#endif /* CONFIG_LOONGSON_MACH3X */ - -#endif /* __ASM_MACH_LOONGSON_MACHINE_H */ diff --git a/arch/mips/include/asm/mach-loongson/mc146818rtc.h b/arch/mips/include/asm/mach-loongson/mc146818rtc.h deleted file mode 100644 index ed7fe978335a..000000000000 --- a/arch/mips/include/asm/mach-loongson/mc146818rtc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org) - * - * RTC routines for PC style attached Dallas chip. - */ -#ifndef __ASM_MACH_LOONGSON_MC146818RTC_H -#define __ASM_MACH_LOONGSON_MC146818RTC_H - -#include - -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_IRQ 8 - -static inline unsigned char CMOS_READ(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - return inb_p(RTC_PORT(1)); -} - -static inline void CMOS_WRITE(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -#define RTC_ALWAYS_BCD 0 - -#ifndef mc146818_decode_year -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) -#endif - -#endif /* __ASM_MACH_LOONGSON_MC146818RTC_H */ diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h deleted file mode 100644 index f4a36d7dbfab..000000000000 --- a/arch/mips/include/asm/mach-loongson/mem.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin - * - * 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_LOONGSON_MEM_H -#define __ASM_MACH_LOONGSON_MEM_H - -/* - * high memory space - * - * in loongson2e, starts from 512M - * in loongson2f, starts from 2G 256M - */ -#ifdef CONFIG_CPU_LOONGSON2E -#define LOONGSON_HIGHMEM_START 0x20000000 -#else -#define LOONGSON_HIGHMEM_START 0x90000000 -#endif - -/* - * the peripheral registers(MMIO): - * - * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000. - * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000. - */ - -#define LOONGSON_MMIO_MEM_START 0x10000000 - -#ifdef CONFIG_CPU_LOONGSON2E -#define LOONGSON_MMIO_MEM_END 0x20000000 -#else -#define LOONGSON_MMIO_MEM_END 0x80000000 -#endif - -#endif /* __ASM_MACH_LOONGSON_MEM_H */ diff --git a/arch/mips/include/asm/mach-loongson/mmzone.h b/arch/mips/include/asm/mach-loongson/mmzone.h deleted file mode 100644 index 37c08a27b4f0..000000000000 --- a/arch/mips/include/asm/mach-loongson/mmzone.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & - * Insititute of Computing Technology - * Author: Xiang Gao, gaoxiang@ict.ac.cn - * Huacai Chen, chenhc@lemote.com - * Xiaofu Meng, Shuangshuang Zhang - * - * 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_MMZONE_H -#define _ASM_MACH_MMZONE_H - -#include -#define NODE_ADDRSPACE_SHIFT 44 -#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL -#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL -#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL -#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL - -#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT) - -#define LEVELS_PER_SLICE 128 - -struct slice_data { - unsigned long irq_enable_mask[2]; - int level_to_irq[LEVELS_PER_SLICE]; -}; - -struct hub_data { - cpumask_t h_cpus; - unsigned long slice_map; - unsigned long irq_alloc_mask[2]; - struct slice_data slice[2]; -}; - -struct node_data { - struct pglist_data pglist; - struct hub_data hub; - cpumask_t cpumask; -}; - -extern struct node_data *__node_data[]; - -#define NODE_DATA(n) (&__node_data[(n)]->pglist) -#define hub_data(n) (&__node_data[(n)]->hub) - -extern void setup_zero_pages(void); -extern void __init prom_init_numa_memory(void); - -#endif /* _ASM_MACH_MMZONE_H */ diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h deleted file mode 100644 index 1212774f66ef..000000000000 --- a/arch/mips/include/asm/mach-loongson/pci.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2008 Zhang Le - * Copyright (c) 2009 Wu Zhangjin - * - * 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_LOONGSON_PCI_H_ -#define __ASM_MACH_LOONGSON_PCI_H_ - -extern struct pci_ops loongson_pci_ops; - -/* this is an offset from mips_io_port_base */ -#define LOONGSON_PCI_IO_START 0x00004000UL - -#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG - -/* - * we use address window2 to map cpu address space to pci space - * window2: cpu [1G, 2G] -> pci [1G, 2G] - * why not use window 0 & 1? because they are used by cpu when booting. - * window0: cpu [0, 256M] -> ddr [0, 256M] - * window1: cpu [256M, 512M] -> pci [256M, 512M] - */ - -/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */ -#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */ -#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC - -#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST -#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */ - -#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \ - LOONGSON_PCI_MEM_START + 1) - -#else /* loongson2f/32bit & loongson2e */ - -/* this pci memory space is mapped by pcimap in pci.c */ -#ifdef CONFIG_CPU_LOONGSON3 -#define LOONGSON_PCI_MEM_START 0x40000000UL -#define LOONGSON_PCI_MEM_END 0x7effffffUL -#else -#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE -#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2) -#endif -/* this is an offset from mips_io_port_base */ -#define LOONGSON_PCI_IO_START 0x00004000UL - -#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ - -#endif /* !__ASM_MACH_LOONGSON_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-loongson/spaces.h b/arch/mips/include/asm/mach-loongson/spaces.h deleted file mode 100644 index e2506ee90044..000000000000 --- a/arch/mips/include/asm/mach-loongson/spaces.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_SPACES_H_ -#define __ASM_MACH_LOONGSON_SPACES_H_ - -#if defined(CONFIG_64BIT) -#define CAC_BASE _AC(0x9800000000000000, UL) -#endif /* CONFIG_64BIT */ - -#include -#endif diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h deleted file mode 100644 index 0d8f3b55bdbc..000000000000 --- a/arch/mips/include/asm/mach-loongson/topology.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _ASM_MACH_TOPOLOGY_H -#define _ASM_MACH_TOPOLOGY_H - -#ifdef CONFIG_NUMA - -#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) -#define parent_node(node) (node) -#define cpumask_of_node(node) (&__node_data[(node)]->cpumask) - -struct pci_bus; -extern int pcibus_to_node(struct pci_bus *); - -#define cpumask_of_pcibus(bus) (cpu_online_mask) - -extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; - -#define node_distance(from, to) (__node_distances[(from)][(to)]) - -#endif - -#include - -#endif /* _ASM_MACH_TOPOLOGY_H */ diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h deleted file mode 100644 index e180c1422eae..000000000000 --- a/arch/mips/include/asm/mach-loongson/workarounds.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_ -#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_ - -#define WORKAROUND_CPUFREQ 0x00000001 -#define WORKAROUND_CPUHOTPLUG 0x00000002 - -#endif diff --git a/arch/mips/include/asm/mach-loongson1/cpufreq.h b/arch/mips/include/asm/mach-loongson1/cpufreq.h deleted file mode 100644 index e7765ce30bcf..000000000000 --- a/arch/mips/include/asm/mach-loongson1/cpufreq.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * 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 */ diff --git a/arch/mips/include/asm/mach-loongson1/irq.h b/arch/mips/include/asm/mach-loongson1/irq.h deleted file mode 100644 index 96bfb1c1c73d..000000000000 --- a/arch/mips/include/asm/mach-loongson1/irq.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * IRQ mappings for Loongson 1 - * - * 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_IRQ_H -#define __ASM_MACH_LOONGSON1_IRQ_H - -/* - * CPU core Interrupt Numbers - */ -#define MIPS_CPU_IRQ_BASE 0 -#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x)) - -#define SOFTINT0_IRQ MIPS_CPU_IRQ(0) -#define SOFTINT1_IRQ MIPS_CPU_IRQ(1) -#define INT0_IRQ MIPS_CPU_IRQ(2) -#define INT1_IRQ MIPS_CPU_IRQ(3) -#define INT2_IRQ MIPS_CPU_IRQ(4) -#define INT3_IRQ MIPS_CPU_IRQ(5) -#define INT4_IRQ MIPS_CPU_IRQ(6) -#define TIMER_IRQ MIPS_CPU_IRQ(7) /* cpu timer */ - -#define MIPS_CPU_IRQS (MIPS_CPU_IRQ(7) + 1 - MIPS_CPU_IRQ_BASE) - -/* - * INT0~3 Interrupt Numbers - */ -#define LS1X_IRQ_BASE MIPS_CPU_IRQS -#define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x)) - -#define LS1X_UART0_IRQ LS1X_IRQ(0, 2) -#define LS1X_UART1_IRQ LS1X_IRQ(0, 3) -#define LS1X_UART2_IRQ LS1X_IRQ(0, 4) -#define LS1X_UART3_IRQ LS1X_IRQ(0, 5) -#define LS1X_CAN0_IRQ LS1X_IRQ(0, 6) -#define LS1X_CAN1_IRQ LS1X_IRQ(0, 7) -#define LS1X_SPI0_IRQ LS1X_IRQ(0, 8) -#define LS1X_SPI1_IRQ LS1X_IRQ(0, 9) -#define LS1X_AC97_IRQ LS1X_IRQ(0, 10) -#define LS1X_DMA0_IRQ LS1X_IRQ(0, 13) -#define LS1X_DMA1_IRQ LS1X_IRQ(0, 14) -#define LS1X_DMA2_IRQ LS1X_IRQ(0, 15) -#define LS1X_PWM0_IRQ LS1X_IRQ(0, 17) -#define LS1X_PWM1_IRQ LS1X_IRQ(0, 18) -#define LS1X_PWM2_IRQ LS1X_IRQ(0, 19) -#define LS1X_PWM3_IRQ LS1X_IRQ(0, 20) -#define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21) -#define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22) -#define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23) -#define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24) -#define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25) -#define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26) -#define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27) -#define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28) - -#define LS1X_EHCI_IRQ LS1X_IRQ(1, 0) -#define LS1X_OHCI_IRQ LS1X_IRQ(1, 1) -#define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2) -#define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3) - -#define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE) - -#define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS) - -#endif /* __ASM_MACH_LOONGSON1_IRQ_H */ diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h deleted file mode 100644 index 20e0c2b155dd..000000000000 --- a/arch/mips/include/asm/mach-loongson1/loongson1.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * Register mappings for Loongson 1 - * - * 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_LOONGSON1_H -#define __ASM_MACH_LOONGSON1_LOONGSON1_H - -#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 -#define LS1X_GMAC0_BASE 0x1fe10000 -#define LS1X_GMAC1_BASE 0x1fe20000 - -#define LS1X_UART0_BASE 0x1fe40000 -#define LS1X_UART1_BASE 0x1fe44000 -#define LS1X_UART2_BASE 0x1fe48000 -#define LS1X_UART3_BASE 0x1fe4c000 -#define LS1X_CAN0_BASE 0x1fe50000 -#define LS1X_CAN1_BASE 0x1fe54000 -#define LS1X_I2C0_BASE 0x1fe58000 -#define LS1X_I2C1_BASE 0x1fe68000 -#define LS1X_I2C2_BASE 0x1fe70000 -#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 -#define LS1X_NAND_BASE 0x1fe78000 -#define LS1X_CLK_BASE 0x1fe78030 - -#include -#include -#include -#include - -#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h deleted file mode 100644 index 47de55e0c835..000000000000 --- a/arch/mips/include/asm/mach-loongson1/platform.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * 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_PLATFORM_H -#define __ASM_MACH_LOONGSON1_PLATFORM_H - -#include - -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); - -#endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */ diff --git a/arch/mips/include/asm/mach-loongson1/prom.h b/arch/mips/include/asm/mach-loongson1/prom.h deleted file mode 100644 index 34859a4d4ac4..000000000000 --- a/arch/mips/include/asm/mach-loongson1/prom.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * 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_PROM_H -#define __ASM_MACH_LOONGSON1_PROM_H - -#include -#include -#include - -/* environment arguments from bootloader */ -extern unsigned long memsize, highmemsize; - -/* loongson-specific command line, env and memory initialization */ -extern char *prom_getenv(char *name); -extern void __init prom_init_cmdline(void); - -#endif /* __ASM_MACH_LOONGSON1_PROM_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h deleted file mode 100644 index ee2445b10fc3..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-clk.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * Loongson 1 Clock 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_CLK_H -#define __ASM_MACH_LOONGSON1_REGS_CLK_H - -#define LS1X_CLK_REG(x) \ - ((void __iomem *)KSEG1ADDR(LS1X_CLK_BASE + (x))) - -#define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0) -#define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) - -/* 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 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 */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-mux.h b/arch/mips/include/asm/mach-loongson1/regs-mux.h deleted file mode 100644 index fb1e36efaa19..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-mux.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * 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 */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-pwm.h b/arch/mips/include/asm/mach-loongson1/regs-pwm.h deleted file mode 100644 index 99f2bcc586f0..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-pwm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * 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 */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h deleted file mode 100644 index c39ee982ad3b..000000000000 --- a/arch/mips/include/asm/mach-loongson1/regs-wdt.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * 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 - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H -#define __ASM_MACH_LOONGSON1_REGS_WDT_H - -#define WDT_EN 0x0 -#define WDT_TIMER 0x4 -#define WDT_SET 0x8 - -#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ diff --git a/arch/mips/include/asm/mach-loongson32/cpufreq.h b/arch/mips/include/asm/mach-loongson32/cpufreq.h new file mode 100644 index 000000000000..6843fa1a608d --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/cpufreq.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * 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_LOONGSON32_CPUFREQ_H +#define __ASM_MACH_LOONGSON32_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_LOONGSON32_CPUFREQ_H */ diff --git a/arch/mips/include/asm/mach-loongson32/irq.h b/arch/mips/include/asm/mach-loongson32/irq.h new file mode 100644 index 000000000000..0d35b994e8d2 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/irq.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * IRQ mappings for Loongson 1 + * + * 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_LOONGSON32_IRQ_H +#define __ASM_MACH_LOONGSON32_IRQ_H + +/* + * CPU core Interrupt Numbers + */ +#define MIPS_CPU_IRQ_BASE 0 +#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x)) + +#define SOFTINT0_IRQ MIPS_CPU_IRQ(0) +#define SOFTINT1_IRQ MIPS_CPU_IRQ(1) +#define INT0_IRQ MIPS_CPU_IRQ(2) +#define INT1_IRQ MIPS_CPU_IRQ(3) +#define INT2_IRQ MIPS_CPU_IRQ(4) +#define INT3_IRQ MIPS_CPU_IRQ(5) +#define INT4_IRQ MIPS_CPU_IRQ(6) +#define TIMER_IRQ MIPS_CPU_IRQ(7) /* cpu timer */ + +#define MIPS_CPU_IRQS (MIPS_CPU_IRQ(7) + 1 - MIPS_CPU_IRQ_BASE) + +/* + * INT0~3 Interrupt Numbers + */ +#define LS1X_IRQ_BASE MIPS_CPU_IRQS +#define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x)) + +#define LS1X_UART0_IRQ LS1X_IRQ(0, 2) +#define LS1X_UART1_IRQ LS1X_IRQ(0, 3) +#define LS1X_UART2_IRQ LS1X_IRQ(0, 4) +#define LS1X_UART3_IRQ LS1X_IRQ(0, 5) +#define LS1X_CAN0_IRQ LS1X_IRQ(0, 6) +#define LS1X_CAN1_IRQ LS1X_IRQ(0, 7) +#define LS1X_SPI0_IRQ LS1X_IRQ(0, 8) +#define LS1X_SPI1_IRQ LS1X_IRQ(0, 9) +#define LS1X_AC97_IRQ LS1X_IRQ(0, 10) +#define LS1X_DMA0_IRQ LS1X_IRQ(0, 13) +#define LS1X_DMA1_IRQ LS1X_IRQ(0, 14) +#define LS1X_DMA2_IRQ LS1X_IRQ(0, 15) +#define LS1X_PWM0_IRQ LS1X_IRQ(0, 17) +#define LS1X_PWM1_IRQ LS1X_IRQ(0, 18) +#define LS1X_PWM2_IRQ LS1X_IRQ(0, 19) +#define LS1X_PWM3_IRQ LS1X_IRQ(0, 20) +#define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21) +#define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22) +#define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23) +#define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24) +#define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25) +#define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26) +#define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27) +#define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28) + +#define LS1X_EHCI_IRQ LS1X_IRQ(1, 0) +#define LS1X_OHCI_IRQ LS1X_IRQ(1, 1) +#define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2) +#define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3) + +#define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE) + +#define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS) + +#endif /* __ASM_MACH_LOONGSON32_IRQ_H */ diff --git a/arch/mips/include/asm/mach-loongson32/loongson1.h b/arch/mips/include/asm/mach-loongson32/loongson1.h new file mode 100644 index 000000000000..12aa129aad80 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/loongson1.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * Register mappings for Loongson 1 + * + * 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_LOONGSON32_LOONGSON1_H +#define __ASM_MACH_LOONGSON32_LOONGSON1_H + +#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 +#define LS1X_GMAC0_BASE 0x1fe10000 +#define LS1X_GMAC1_BASE 0x1fe20000 + +#define LS1X_UART0_BASE 0x1fe40000 +#define LS1X_UART1_BASE 0x1fe44000 +#define LS1X_UART2_BASE 0x1fe48000 +#define LS1X_UART3_BASE 0x1fe4c000 +#define LS1X_CAN0_BASE 0x1fe50000 +#define LS1X_CAN1_BASE 0x1fe54000 +#define LS1X_I2C0_BASE 0x1fe58000 +#define LS1X_I2C1_BASE 0x1fe68000 +#define LS1X_I2C2_BASE 0x1fe70000 +#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 +#define LS1X_NAND_BASE 0x1fe78000 +#define LS1X_CLK_BASE 0x1fe78030 + +#include +#include +#include +#include + +#endif /* __ASM_MACH_LOONGSON32_LOONGSON1_H */ diff --git a/arch/mips/include/asm/mach-loongson32/platform.h b/arch/mips/include/asm/mach-loongson32/platform.h new file mode 100644 index 000000000000..c32f03f3f72c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/platform.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * 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_LOONGSON32_PLATFORM_H +#define __ASM_MACH_LOONGSON32_PLATFORM_H + +#include + +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); + +#endif /* __ASM_MACH_LOONGSON32_PLATFORM_H */ diff --git a/arch/mips/include/asm/mach-loongson32/prom.h b/arch/mips/include/asm/mach-loongson32/prom.h new file mode 100644 index 000000000000..a08503c0ba20 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/prom.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * 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_LOONGSON32_PROM_H +#define __ASM_MACH_LOONGSON32_PROM_H + +#include +#include +#include + +/* environment arguments from bootloader */ +extern unsigned long memsize, highmemsize; + +/* loongson-specific command line, env and memory initialization */ +extern char *prom_getenv(char *name); +extern void __init prom_init_cmdline(void); + +#endif /* __ASM_MACH_LOONGSON32_PROM_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-clk.h b/arch/mips/include/asm/mach-loongson32/regs-clk.h new file mode 100644 index 000000000000..1f5a715ac841 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-clk.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * Loongson 1 Clock 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_LOONGSON32_REGS_CLK_H +#define __ASM_MACH_LOONGSON32_REGS_CLK_H + +#define LS1X_CLK_REG(x) \ + ((void __iomem *)KSEG1ADDR(LS1X_CLK_BASE + (x))) + +#define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0) +#define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) + +/* 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 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_LOONGSON32_REGS_CLK_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-mux.h b/arch/mips/include/asm/mach-loongson32/regs-mux.h new file mode 100644 index 000000000000..8302d92f2da2 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-mux.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * 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_LOONGSON32_REGS_MUX_H +#define __ASM_MACH_LOONGSON32_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_LOONGSON32_REGS_MUX_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-pwm.h b/arch/mips/include/asm/mach-loongson32/regs-pwm.h new file mode 100644 index 000000000000..69f174ed13a4 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-pwm.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * 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_LOONGSON32_REGS_PWM_H +#define __ASM_MACH_LOONGSON32_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_LOONGSON32_REGS_PWM_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-wdt.h b/arch/mips/include/asm/mach-loongson32/regs-wdt.h new file mode 100644 index 000000000000..6644ab6d3391 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson32/regs-wdt.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASM_MACH_LOONGSON32_REGS_WDT_H +#define __ASM_MACH_LOONGSON32_REGS_WDT_H + +#define WDT_EN 0x0 +#define WDT_TIMER 0x4 +#define WDT_SET 0x8 + +#endif /* __ASM_MACH_LOONGSON32_REGS_WDT_H */ diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h new file mode 100644 index 000000000000..d3f3258b7cd4 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h @@ -0,0 +1,210 @@ +#ifndef __ASM_MACH_LOONGSON64_BOOT_PARAM_H_ +#define __ASM_MACH_LOONGSON64_BOOT_PARAM_H_ + +#define SYSTEM_RAM_LOW 1 +#define SYSTEM_RAM_HIGH 2 +#define MEM_RESERVED 3 +#define PCI_IO 4 +#define PCI_MEM 5 +#define LOONGSON_CFG_REG 6 +#define VIDEO_ROM 7 +#define ADAPTER_ROM 8 +#define ACPI_TABLE 9 +#define SMBIOS_TABLE 10 +#define MAX_MEMORY_TYPE 11 + +#define LOONGSON3_BOOT_MEM_MAP_MAX 128 +struct efi_memory_map_loongson { + u16 vers; /* version of efi_memory_map */ + u32 nr_map; /* number of memory_maps */ + u32 mem_freq; /* memory frequence */ + struct mem_map { + u32 node_id; /* node_id which memory attached to */ + u32 mem_type; /* system memory, pci memory, pci io, etc. */ + u64 mem_start; /* memory map start address */ + u32 mem_size; /* each memory_map size, not the total size */ + } map[LOONGSON3_BOOT_MEM_MAP_MAX]; +} __packed; + +enum loongson_cpu_type { + Loongson_2E = 0, + Loongson_2F = 1, + Loongson_3A = 2, + Loongson_3B = 3, + Loongson_1A = 4, + Loongson_1B = 5 +}; + +/* + * Capability and feature descriptor structure for MIPS CPU + */ +struct efi_cpuinfo_loongson { + u16 vers; /* version of 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 */ + 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 { + u16 vers; + u16 size; + u16 rtr_bus; + u16 rtr_devfn; + u32 vendor; + u32 device; + u32 PIC_type; /* conform use HT or PCI to route to CPU-PIC */ + u64 ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ + u64 ht_enable; /* irqs used in this PIC */ + u32 node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ + u64 pci_mem_start_addr; + u64 pci_mem_end_addr; + u64 pci_io_start_addr; + u64 pci_io_end_addr; + u64 pci_config_addr; + u32 dma_mask_bits; +} __packed; + +struct interface_info { + u16 vers; /* version of the specificition */ + u16 size; + u8 flag; + char description[64]; +} __packed; + +#define MAX_RESOURCE_NUMBER 128 +struct resource_loongson { + u64 start; /* resource start address */ + u64 end; /* resource end address */ + char name[64]; + u32 flags; +}; + +struct archdev_data {}; /* arch specific additions */ + +struct board_devices { + char name[64]; /* hold the device name */ + u32 num_resources; /* number of device_resource */ + /* for each device's resource */ + struct resource_loongson resource[MAX_RESOURCE_NUMBER]; + /* arch specific additions */ + struct archdev_data archdata; +}; + +struct loongson_special_attribute { + u16 vers; /* version of this special */ + char special_name[64]; /* special_atribute_name */ + u32 loongson_special_type; /* type of special device */ + /* for each device's resource */ + struct resource_loongson resource[MAX_RESOURCE_NUMBER]; +}; + +struct loongson_params { + u64 memory_offset; /* efi_memory_map_loongson struct offset */ + u64 cpu_offset; /* efi_cpuinfo_loongson struct offset */ + u64 system_offset; /* system_loongson struct offset */ + u64 irq_offset; /* irq_source_routing_table struct offset */ + u64 interface_offset; /* interface_info struct offset */ + u64 special_offset; /* loongson_special_attribute struct offset */ + u64 boarddev_table_offset; /* board_devices offset */ +}; + +struct smbios_tables { + u16 vers; /* version of smbios */ + u64 vga_bios; /* vga_bios address */ + struct loongson_params lp; +}; + +struct efi_reset_system_t { + u64 ResetCold; + u64 ResetWarm; + u64 ResetType; + u64 Shutdown; + u64 DoSuspend; /* NULL if not support */ +}; + +struct efi_loongson { + u64 mps; /* MPS table */ + u64 acpi; /* ACPI table (IA64 ext 0.71) */ + u64 acpi20; /* ACPI table (ACPI 2.0) */ + struct smbios_tables smbios; /* SM BIOS table */ + u64 sal_systab; /* SAL system table */ + u64 boot_info; /* boot info table */ +}; + +struct boot_params { + struct efi_loongson efi; + struct efi_reset_system_t reset_system; +}; + +struct loongson_system_configuration { + u32 nr_cpus; + 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; + u64 pci_mem_end_addr; + u64 pci_io_base; + u64 restart_addr; + u64 poweroff_addr; + 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; + +#endif diff --git a/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h new file mode 100644 index 000000000000..98963c2c7be4 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h @@ -0,0 +1,61 @@ +/* + * 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) 2009 Wu Zhangjin + * Copyright (C) 2009 Philippe Vachon + * Copyright (C) 2009 Zhang Le + * + * reference: /proc/cpuinfo, + * arch/mips/kernel/cpu-probe.c(cpu_probe_legacy), + * arch/mips/kernel/proc.c(show_cpuinfo), + * loongson2f user manual. + */ + +#ifndef __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H + +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 32 +#define cpu_scache_line_size() 32 + + +#define cpu_has_32fpr 1 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 1 +#define cpu_has_4kex 1 +#define cpu_has_64bits 1 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_counter 1 +#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) +#define cpu_has_divec 0 +#define cpu_has_dsp 0 +#define cpu_has_dsp2 0 +#define cpu_has_ejtag 0 +#define cpu_has_ic_fills_f_dc 0 +#define cpu_has_inclusive_pcaches 1 +#define cpu_has_llsc 1 +#define cpu_has_mcheck 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips16 0 +#define cpu_has_mips32r2 0 +#define cpu_has_mips3d 0 +#define cpu_has_mips64r2 0 +#define cpu_has_mipsmt 0 +#define cpu_has_prefetch 0 +#define cpu_has_smartmips 0 +#define cpu_has_tlb 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_userlocal 0 +#define cpu_has_vce 0 +#define cpu_has_veic 0 +#define cpu_has_vint 0 +#define cpu_has_vtag_icache 0 +#define cpu_has_watch 1 +#define cpu_has_local_ebase 0 + +#define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) + +#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h new file mode 100644 index 000000000000..a0ee0cb775ad --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h @@ -0,0 +1,305 @@ +/* + * The header file of cs5536 south bridge. + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu + */ + +#ifndef _CS5536_H +#define _CS5536_H + +#include + +extern void _rdmsr(u32 msr, u32 *hi, u32 *lo); +extern void _wrmsr(u32 msr, u32 hi, u32 lo); + +/* + * MSR module base + */ +#define CS5536_SB_MSR_BASE (0x00000000) +#define CS5536_GLIU_MSR_BASE (0x10000000) +#define CS5536_ILLEGAL_MSR_BASE (0x20000000) +#define CS5536_USB_MSR_BASE (0x40000000) +#define CS5536_IDE_MSR_BASE (0x60000000) +#define CS5536_DIVIL_MSR_BASE (0x80000000) +#define CS5536_ACC_MSR_BASE (0xa0000000) +#define CS5536_UNUSED_MSR_BASE (0xc0000000) +#define CS5536_GLCP_MSR_BASE (0xe0000000) + +#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | (offset)) +#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | (offset)) +#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset)) +#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | (offset)) +#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | (offset)) +#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | (offset)) +#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | (offset)) +#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset)) +#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | (offset)) + +/* + * BAR SPACE OF VIRTUAL PCI : + * range for pci probe use, length is the actual size. + */ +/* IO space for all DIVIL modules */ +#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */ +#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */ +#define CS5536_SMB_RANGE 0xfffffff8 +#define CS5536_SMB_LENGTH 0x08 +#define CS5536_GPIO_RANGE 0xffffff00 +#define CS5536_GPIO_LENGTH 0x100 +#define CS5536_MFGPT_RANGE 0xffffffc0 +#define CS5536_MFGPT_LENGTH 0x40 +#define CS5536_ACPI_RANGE 0xffffffe0 +#define CS5536_ACPI_LENGTH 0x20 +#define CS5536_PMS_RANGE 0xffffff80 +#define CS5536_PMS_LENGTH 0x80 +/* IO space for IDE */ +#define CS5536_IDE_RANGE 0xfffffff0 +#define CS5536_IDE_LENGTH 0x10 +/* IO space for ACC */ +#define CS5536_ACC_RANGE 0xffffff80 +#define CS5536_ACC_LENGTH 0x80 +/* MEM space for ALL USB modules */ +#define CS5536_OHCI_RANGE 0xfffff000 +#define CS5536_OHCI_LENGTH 0x1000 +#define CS5536_EHCI_RANGE 0xfffff000 +#define CS5536_EHCI_LENGTH 0x1000 + +/* + * PCI MSR ACCESS + */ +#define PCI_MSR_CTRL 0xF0 +#define PCI_MSR_ADDR 0xF4 +#define PCI_MSR_DATA_LO 0xF8 +#define PCI_MSR_DATA_HI 0xFC + +/**************** MSR *****************************/ + +/* + * GLIU STANDARD MSR + */ +#define GLIU_CAP 0x00 +#define GLIU_CONFIG 0x01 +#define GLIU_SMI 0x02 +#define GLIU_ERROR 0x03 +#define GLIU_PM 0x04 +#define GLIU_DIAG 0x05 + +/* + * GLIU SPEC. MSR + */ +#define GLIU_P2D_BM0 0x20 +#define GLIU_P2D_BM1 0x21 +#define GLIU_P2D_BM2 0x22 +#define GLIU_P2D_BMK0 0x23 +#define GLIU_P2D_BMK1 0x24 +#define GLIU_P2D_BM3 0x25 +#define GLIU_P2D_BM4 0x26 +#define GLIU_COH 0x80 +#define GLIU_PAE 0x81 +#define GLIU_ARB 0x82 +#define GLIU_ASMI 0x83 +#define GLIU_AERR 0x84 +#define GLIU_DEBUG 0x85 +#define GLIU_PHY_CAP 0x86 +#define GLIU_NOUT_RESP 0x87 +#define GLIU_NOUT_WDATA 0x88 +#define GLIU_WHOAMI 0x8B +#define GLIU_SLV_DIS 0x8C +#define GLIU_IOD_BM0 0xE0 +#define GLIU_IOD_BM1 0xE1 +#define GLIU_IOD_BM2 0xE2 +#define GLIU_IOD_BM3 0xE3 +#define GLIU_IOD_BM4 0xE4 +#define GLIU_IOD_BM5 0xE5 +#define GLIU_IOD_BM6 0xE6 +#define GLIU_IOD_BM7 0xE7 +#define GLIU_IOD_BM8 0xE8 +#define GLIU_IOD_BM9 0xE9 +#define GLIU_IOD_SC0 0xEA +#define GLIU_IOD_SC1 0xEB +#define GLIU_IOD_SC2 0xEC +#define GLIU_IOD_SC3 0xED +#define GLIU_IOD_SC4 0xEE +#define GLIU_IOD_SC5 0xEF +#define GLIU_IOD_SC6 0xF0 +#define GLIU_IOD_SC7 0xF1 + +/* + * SB STANDARD + */ +#define SB_CAP 0x00 +#define SB_CONFIG 0x01 +#define SB_SMI 0x02 +#define SB_ERROR 0x03 +#define SB_MAR_ERR_EN 0x00000001 +#define SB_TAR_ERR_EN 0x00000002 +#define SB_RSVD_BIT1 0x00000004 +#define SB_EXCEP_ERR_EN 0x00000008 +#define SB_SYSE_ERR_EN 0x00000010 +#define SB_PARE_ERR_EN 0x00000020 +#define SB_TAS_ERR_EN 0x00000040 +#define SB_MAR_ERR_FLAG 0x00010000 +#define SB_TAR_ERR_FLAG 0x00020000 +#define SB_RSVD_BIT2 0x00040000 +#define SB_EXCEP_ERR_FLAG 0x00080000 +#define SB_SYSE_ERR_FLAG 0x00100000 +#define SB_PARE_ERR_FLAG 0x00200000 +#define SB_TAS_ERR_FLAG 0x00400000 +#define SB_PM 0x04 +#define SB_DIAG 0x05 + +/* + * SB SPEC. + */ +#define SB_CTRL 0x10 +#define SB_R0 0x20 +#define SB_R1 0x21 +#define SB_R2 0x22 +#define SB_R3 0x23 +#define SB_R4 0x24 +#define SB_R5 0x25 +#define SB_R6 0x26 +#define SB_R7 0x27 +#define SB_R8 0x28 +#define SB_R9 0x29 +#define SB_R10 0x2A +#define SB_R11 0x2B +#define SB_R12 0x2C +#define SB_R13 0x2D +#define SB_R14 0x2E +#define SB_R15 0x2F + +/* + * GLCP STANDARD + */ +#define GLCP_CAP 0x00 +#define GLCP_CONFIG 0x01 +#define GLCP_SMI 0x02 +#define GLCP_ERROR 0x03 +#define GLCP_PM 0x04 +#define GLCP_DIAG 0x05 + +/* + * GLCP SPEC. + */ +#define GLCP_CLK_DIS_DELAY 0x08 +#define GLCP_PM_CLK_DISABLE 0x09 +#define GLCP_GLB_PM 0x0B +#define GLCP_DBG_OUT 0x0C +#define GLCP_RSVD1 0x0D +#define GLCP_SOFT_COM 0x0E +#define SOFT_BAR_SMB_FLAG 0x00000001 +#define SOFT_BAR_GPIO_FLAG 0x00000002 +#define SOFT_BAR_MFGPT_FLAG 0x00000004 +#define SOFT_BAR_IRQ_FLAG 0x00000008 +#define SOFT_BAR_PMS_FLAG 0x00000010 +#define SOFT_BAR_ACPI_FLAG 0x00000020 +#define SOFT_BAR_IDE_FLAG 0x00000400 +#define SOFT_BAR_ACC_FLAG 0x00000800 +#define SOFT_BAR_OHCI_FLAG 0x00001000 +#define SOFT_BAR_EHCI_FLAG 0x00002000 +#define GLCP_RSVD2 0x0F +#define GLCP_CLK_OFF 0x10 +#define GLCP_CLK_ACTIVE 0x11 +#define GLCP_CLK_DISABLE 0x12 +#define GLCP_CLK4ACK 0x13 +#define GLCP_SYS_RST 0x14 +#define GLCP_RSVD3 0x15 +#define GLCP_DBG_CLK_CTRL 0x16 +#define GLCP_CHIP_REV_ID 0x17 + +/* PIC */ +#define PIC_YSEL_LOW 0x20 +#define PIC_YSEL_LOW_USB_SHIFT 8 +#define PIC_YSEL_LOW_ACC_SHIFT 16 +#define PIC_YSEL_LOW_FLASH_SHIFT 24 +#define PIC_YSEL_HIGH 0x21 +#define PIC_ZSEL_LOW 0x22 +#define PIC_ZSEL_HIGH 0x23 +#define PIC_IRQM_PRIM 0x24 +#define PIC_IRQM_LPC 0x25 +#define PIC_XIRR_STS_LOW 0x26 +#define PIC_XIRR_STS_HIGH 0x27 +#define PCI_SHDW 0x34 + +/* + * DIVIL STANDARD + */ +#define DIVIL_CAP 0x00 +#define DIVIL_CONFIG 0x01 +#define DIVIL_SMI 0x02 +#define DIVIL_ERROR 0x03 +#define DIVIL_PM 0x04 +#define DIVIL_DIAG 0x05 + +/* + * DIVIL SPEC. + */ +#define DIVIL_LBAR_IRQ 0x08 +#define DIVIL_LBAR_KEL 0x09 +#define DIVIL_LBAR_SMB 0x0B +#define DIVIL_LBAR_GPIO 0x0C +#define DIVIL_LBAR_MFGPT 0x0D +#define DIVIL_LBAR_ACPI 0x0E +#define DIVIL_LBAR_PMS 0x0F +#define DIVIL_LEG_IO 0x14 +#define DIVIL_BALL_OPTS 0x15 +#define DIVIL_SOFT_IRQ 0x16 +#define DIVIL_SOFT_RESET 0x17 + +/* MFGPT */ +#define MFGPT_IRQ 0x28 + +/* + * IDE STANDARD + */ +#define IDE_CAP 0x00 +#define IDE_CONFIG 0x01 +#define IDE_SMI 0x02 +#define IDE_ERROR 0x03 +#define IDE_PM 0x04 +#define IDE_DIAG 0x05 + +/* + * IDE SPEC. + */ +#define IDE_IO_BAR 0x08 +#define IDE_CFG 0x10 +#define IDE_DTC 0x12 +#define IDE_CAST 0x13 +#define IDE_ETC 0x14 +#define IDE_INTERNAL_PM 0x15 + +/* + * ACC STANDARD + */ +#define ACC_CAP 0x00 +#define ACC_CONFIG 0x01 +#define ACC_SMI 0x02 +#define ACC_ERROR 0x03 +#define ACC_PM 0x04 +#define ACC_DIAG 0x05 + +/* + * USB STANDARD + */ +#define USB_CAP 0x00 +#define USB_CONFIG 0x01 +#define USB_SMI 0x02 +#define USB_ERROR 0x03 +#define USB_PM 0x04 +#define USB_DIAG 0x05 + +/* + * USB SPEC. + */ +#define USB_OHCI 0x08 +#define USB_EHCI 0x09 + +/****************** NATIVE ***************************/ +/* GPIO : I/O SPACE; REG : 32BITS */ +#define GPIOL_OUT_VAL 0x00 +#define GPIOL_OUT_EN 0x04 + +#endif /* _CS5536_H */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h new file mode 100644 index 000000000000..021d0172dad6 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h @@ -0,0 +1,35 @@ +/* + * cs5536 mfgpt header file + */ + +#ifndef _CS5536_MFGPT_H +#define _CS5536_MFGPT_H + +#include +#include + +#ifdef CONFIG_CS5536_MFGPT +extern void setup_mfgpt0_timer(void); +extern void disable_mfgpt0_counter(void); +extern void enable_mfgpt0_counter(void); +#else +static inline void __maybe_unused setup_mfgpt0_timer(void) +{ +} +static inline void __maybe_unused disable_mfgpt0_counter(void) +{ +} +static inline void __maybe_unused enable_mfgpt0_counter(void) +{ +} +#endif + +#define MFGPT_TICK_RATE 14318000 +#define COMPARE ((MFGPT_TICK_RATE + HZ/2) / HZ) + +#define MFGPT_BASE mfgpt_base +#define MFGPT0_CMP2 (MFGPT_BASE + 2) +#define MFGPT0_CNT (MFGPT_BASE + 4) +#define MFGPT0_SETUP (MFGPT_BASE + 6) + +#endif /*!_CS5536_MFGPT_H */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h new file mode 100644 index 000000000000..8a7ecb4d5c64 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h @@ -0,0 +1,153 @@ +/* + * the definition file of cs5536 Virtual Support Module(VSM). + * pci configuration space can be accessed through the VSM, so + * there is no need of the MSR read/write now, except the spec. + * MSR registers which are not implemented yet. + * + * Copyright (C) 2007 Lemote Inc. + * Author : jlliu, liujl@lemote.com + */ + +#ifndef _CS5536_PCI_H +#define _CS5536_PCI_H + +#include +#include + +extern void cs5536_pci_conf_write4(int function, int reg, u32 value); +extern u32 cs5536_pci_conf_read4(int function, int reg); + +#define CS5536_ACC_INTR 9 +#define CS5536_IDE_INTR 14 +#define CS5536_USB_INTR 11 +#define CS5536_MFGPT_INTR 5 +#define CS5536_UART1_INTR 4 +#define CS5536_UART2_INTR 3 + +/************** PCI BUS DEVICE FUNCTION ***************/ + +/* + * PCI bus device function + */ +#define PCI_BUS_CS5536 0 +#define PCI_IDSEL_CS5536 14 + +/********** STANDARD PCI-2.2 EXPANSION ****************/ + +/* + * PCI configuration space + * we have to virtualize the PCI configure space head, so we should + * define the necessary IDs and some others. + */ + +/* CONFIG of PCI VENDOR ID*/ +#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \ + (((mod_dev_id) << 16) | (sys_vendor_id)) + +/* VENDOR ID */ +#define CS5536_VENDOR_ID 0x1022 + +/* DEVICE ID */ +#define CS5536_ISA_DEVICE_ID 0x2090 +#define CS5536_IDE_DEVICE_ID 0x209a +#define CS5536_ACC_DEVICE_ID 0x2093 +#define CS5536_OHCI_DEVICE_ID 0x2094 +#define CS5536_EHCI_DEVICE_ID 0x2095 + +/* CLASS CODE : CLASS SUB-CLASS INTERFACE */ +#define CS5536_ISA_CLASS_CODE 0x060100 +#define CS5536_IDE_CLASS_CODE 0x010180 +#define CS5536_ACC_CLASS_CODE 0x040100 +#define CS5536_OHCI_CLASS_CODE 0x0C0310 +#define CS5536_EHCI_CLASS_CODE 0x0C0320 + +/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */ + +#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer) \ + ((PCI_NONE_BIST << 24) | ((header_type) << 16) \ + | ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE); + +#define PCI_NONE_BIST 0x00 /* RO not implemented yet. */ +#define PCI_BRIDGE_HEADER_TYPE 0x80 /* RO */ +#define PCI_NORMAL_HEADER_TYPE 0x00 +#define PCI_NORMAL_LATENCY_TIMER 0x00 +#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 /* RW */ + +/* BAR */ +#define PCI_BAR0_REG 0x10 +#define PCI_BAR1_REG 0x14 +#define PCI_BAR2_REG 0x18 +#define PCI_BAR3_REG 0x1c +#define PCI_BAR4_REG 0x20 +#define PCI_BAR5_REG 0x24 +#define PCI_BAR_COUNT 6 +#define PCI_BAR_RANGE_MASK 0xFFFFFFFF + +/* CARDBUS CIS POINTER */ +#define PCI_CARDBUS_CIS_POINTER 0x00000000 + +/* SUBSYSTEM VENDOR ID */ +#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID + +/* SUBSYSTEM ID */ +#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID +#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID +#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID +#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID +#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID + +/* EXPANSION ROM BAR */ +#define PCI_EXPANSION_ROM_BAR 0x00000000 + +/* CAPABILITIES POINTER */ +#define PCI_CAPLIST_POINTER 0x00000000 +#define PCI_CAPLIST_USB_POINTER 0x40 +/* INTERRUPT */ + +#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \ + ((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \ + ((pin) << 8) | (mod_intr)) + +#define PCI_MAX_LATENCY 0x40 +#define PCI_MIN_GRANT 0x00 +#define PCI_DEFAULT_PIN 0x01 + +/*********** EXPANSION PCI REG ************************/ + +/* + * ISA EXPANSION + */ +#define PCI_UART1_INT_REG 0x50 +#define PCI_UART2_INT_REG 0x54 +#define PCI_ISA_FIXUP_REG 0x58 + +/* + * IDE EXPANSION + */ +#define PCI_IDE_CFG_REG 0x40 +#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF +#define PCI_IDE_DTC_REG 0x48 +#define PCI_IDE_CAST_REG 0x4C +#define PCI_IDE_ETC_REG 0x50 +#define PCI_IDE_PM_REG 0x54 +#define PCI_IDE_INT_REG 0x60 + +/* + * ACC EXPANSION + */ +#define PCI_ACC_INT_REG 0x50 + +/* + * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI + */ +#define PCI_OHCI_PM_REG 0x40 +#define PCI_OHCI_INT_REG 0x50 + +/* + * EHCI EXPANSION + */ +#define PCI_EHCI_LEGSMIEN_REG 0x50 +#define PCI_EHCI_LEGSMISTS_REG 0x54 +#define PCI_EHCI_FLADJ_REG 0x60 + +#endif /* _CS5536_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h new file mode 100644 index 000000000000..1f17c1815ee5 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h @@ -0,0 +1,31 @@ +/* + * the read/write interfaces for Virtual Support Module(VSM) + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + */ + +#ifndef _CS5536_VSM_H +#define _CS5536_VSM_H + +#include + +typedef void (*cs5536_pci_vsm_write)(int reg, u32 value); +typedef u32 (*cs5536_pci_vsm_read)(int reg); + +#define DECLARE_CS5536_MODULE(name) \ +extern void pci_##name##_write_reg(int reg, u32 value); \ +extern u32 pci_##name##_read_reg(int reg); + +/* ide module */ +DECLARE_CS5536_MODULE(ide) +/* acc module */ +DECLARE_CS5536_MODULE(acc) +/* ohci module */ +DECLARE_CS5536_MODULE(ohci) +/* isa module */ +DECLARE_CS5536_MODULE(isa) +/* ehci module */ +DECLARE_CS5536_MODULE(ehci) + +#endif /* _CS5536_VSM_H */ diff --git a/arch/mips/include/asm/mach-loongson64/dma-coherence.h b/arch/mips/include/asm/mach-loongson64/dma-coherence.h new file mode 100644 index 000000000000..1602a9e9e8c2 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/dma-coherence.h @@ -0,0 +1,85 @@ +/* + * 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, 07 Ralf Baechle + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + */ +#ifndef __ASM_MACH_LOONGSON64_DMA_COHERENCE_H +#define __ASM_MACH_LOONGSON64_DMA_COHERENCE_H + +#ifdef CONFIG_SWIOTLB +#include +#endif + +struct device; + +extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); +extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr); +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) +{ +#ifdef CONFIG_CPU_LOONGSON3 + return phys_to_dma(dev, virt_to_phys(addr)); +#else + return virt_to_phys(addr) | 0x80000000; +#endif +} + +static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, + struct page *page) +{ +#ifdef CONFIG_CPU_LOONGSON3 + return phys_to_dma(dev, page_to_phys(page)); +#else + return page_to_phys(page) | 0x80000000; +#endif +} + +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_to_phys(dev, dma_addr); +#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); +#else + return dma_addr & 0x7fffffff; +#endif +} + +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) +{ +#ifdef CONFIG_DMA_NONCOHERENT + return 0; +#else + return 1; +#endif /* CONFIG_DMA_NONCOHERENT */ +} + +static inline void plat_post_dma_flush(struct device *dev) +{ +} + +#endif /* __ASM_MACH_LOONGSON64_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-loongson64/gpio.h b/arch/mips/include/asm/mach-loongson64/gpio.h new file mode 100644 index 000000000000..b3b216904a9a --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/gpio.h @@ -0,0 +1,36 @@ +/* + * Loongson GPIO Support + * + * Copyright (c) 2008 Richard Liu, STMicroelectronics + * Copyright (c) 2008-2010 Arnaud Patard + * Copyright (c) 2014 Huacai Chen + * + * 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 __LOONGSON_GPIO_H +#define __LOONGSON_GPIO_H + +#include + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep + +/* The chip can do interrupt + * but it has not been tested and doc not clear + */ +static inline int gpio_to_irq(int gpio) +{ + return -EINVAL; +} + +static inline int irq_to_gpio(int gpio) +{ + return -EINVAL; +} + +#endif /* __LOONGSON_GPIO_H */ diff --git a/arch/mips/include/asm/mach-loongson64/irq.h b/arch/mips/include/asm/mach-loongson64/irq.h new file mode 100644 index 000000000000..d18c45c7c394 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/irq.h @@ -0,0 +1,43 @@ +#ifndef __ASM_MACH_LOONGSON64_IRQ_H_ +#define __ASM_MACH_LOONGSON64_IRQ_H_ + +#include + +#ifdef CONFIG_CPU_LOONGSON3 + +/* cpu core interrupt numbers */ +#define MIPS_CPU_IRQ_BASE 56 + +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */ +#define LOONGSON_HT1_IRQ (MIPS_CPU_IRQ_BASE + 3) /* HT1 */ +#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */ + +#define LOONGSON_HT1_CFG_BASE loongson_sysconf.ht_control_base +#define LOONGSON_HT1_INT_VECTOR_BASE (LOONGSON_HT1_CFG_BASE + 0x80) +#define LOONGSON_HT1_INT_EN_BASE (LOONGSON_HT1_CFG_BASE + 0xa0) +#define LOONGSON_HT1_INT_VECTOR(n) \ + LOONGSON3_REG32(LOONGSON_HT1_INT_VECTOR_BASE, 4 * (n)) +#define LOONGSON_HT1_INTN_EN(n) \ + LOONGSON3_REG32(LOONGSON_HT1_INT_EN_BASE, 4 * (n)) + +#define LOONGSON_INT_ROUTER_OFFSET 0x1400 +#define LOONGSON_INT_ROUTER_INTEN \ + LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x24) +#define LOONGSON_INT_ROUTER_INTENSET \ + LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x28) +#define LOONGSON_INT_ROUTER_INTENCLR \ + LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x2c) +#define LOONGSON_INT_ROUTER_ENTRY(n) \ + LOONGSON3_REG8(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + n) +#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_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */ + +#endif + +extern void fixup_irqs(void); +extern void loongson3_ipi_interrupt(struct pt_regs *regs); + +#include_next +#endif /* __ASM_MACH_LOONGSON64_IRQ_H_ */ diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h new file mode 100644 index 000000000000..3f2f84f6c401 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h @@ -0,0 +1,52 @@ +/* + * 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) 2005 Embedded Alley Solutions, Inc + * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn) + * Copyright (C) 2012 Huacai Chen (chenhc@lemote.com) + */ +#ifndef __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H +#define __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H + +/* + * Override macros used in arch/mips/kernel/head.S. + */ + .macro kernel_entry_setup +#ifdef CONFIG_CPU_LOONGSON3 + .set push + .set mips64 + /* Set LPA on LOONGSON3 config3 */ + mfc0 t0, $16, 3 + or t0, (0x1 << 7) + mtc0 t0, $16, 3 + /* Set ELPA on LOONGSON3 pagegrain */ + li t0, (0x1 << 29) + mtc0 t0, $5, 1 + _ehb + .set pop +#endif + .endm + +/* + * Do SMP slave processor setup. + */ + .macro smp_slave_setup +#ifdef CONFIG_CPU_LOONGSON3 + .set push + .set mips64 + /* Set LPA on LOONGSON3 config3 */ + mfc0 t0, $16, 3 + or t0, (0x1 << 7) + mtc0 t0, $16, 3 + /* Set ELPA on LOONGSON3 pagegrain */ + li t0, (0x1 << 29) + mtc0 t0, $5, 1 + _ehb + .set pop +#endif + .endm + +#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */ diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h new file mode 100644 index 000000000000..d1ff774ac4b6 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/loongson.h @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + * + * 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_LOONGSON64_LOONGSON_H +#define __ASM_MACH_LOONGSON64_LOONGSON_H + +#include +#include +#include +#include +#include + +/* loongson internal northbridge initialization */ +extern void bonito_irq_init(void); + +/* machine-specific reboot/halt operation */ +extern void mach_prepare_reboot(void); +extern void mach_prepare_shutdown(void); + +/* environment arguments from bootloader */ +extern u32 cpu_clock_freq; +extern u32 memsize, highmemsize; +extern struct plat_smp_ops loongson3_smp_ops; + +/* loongson-specific command line, env and memory initialization */ +extern void __init prom_init_memory(void); +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 void prom_init_loongson_uart_base(void); +#endif + +static inline void prom_init_uart_base(void) +{ +#ifdef CONFIG_LOONGSON_UART_BASE + prom_init_loongson_uart_base(); +#endif +} + +/* irq operation functions */ +extern void bonito_irqdispatch(void); +extern void __init bonito_irq_init(void); +extern void __init mach_init_irq(void); +extern void mach_irq_dispatch(unsigned int pending); +extern int mach_i8259_irq(void); + +/* We need this in some places... */ +#define delay() ({ \ + int x; \ + for (x = 0; x < 100000; x++) \ + __asm__ __volatile__(""); \ +}) + +#define LOONGSON_REG(x) \ + (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x))) + +#define LOONGSON3_REG8(base, x) \ + (*(volatile u8 *)((char *)TO_UNCAC(base) + (x))) + +#define LOONGSON3_REG32(base, x) \ + (*(volatile u32 *)((char *)TO_UNCAC(base) + (x))) + +#define LOONGSON_IRQ_BASE 32 +#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */ + +#include +static inline void do_perfcnt_IRQ(void) +{ +#if IS_ENABLED(CONFIG_OPROFILE) + do_IRQ(LOONGSON2_PERFCNT_IRQ); +#endif +} + +#define LOONGSON_FLASH_BASE 0x1c000000 +#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */ +#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1) + +#define LOONGSON_LIO0_BASE 0x1e000000 +#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */ +#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1) + +#define LOONGSON_BOOT_BASE 0x1fc00000 +#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */ +#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1) +#define LOONGSON_REG_BASE 0x1fe00000 +#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */ +#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1) +/* Loongson-3 specific registers */ +#define LOONGSON3_REG_BASE 0x3ff00000 +#define LOONGSON3_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */ +#define LOONGSON3_REG_TOP (LOONGSON3_REG_BASE+LOONGSON3_REG_SIZE-1) + +#define LOONGSON_LIO1_BASE 0x1ff00000 +#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */ +#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1) + +#define LOONGSON_PCILO0_BASE 0x10000000 +#define LOONGSON_PCILO1_BASE 0x14000000 +#define LOONGSON_PCILO2_BASE 0x18000000 +#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE +#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */ +#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1) + +#define LOONGSON_PCICFG_BASE 0x1fe80000 +#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */ +#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1) + +#if defined(CONFIG_HT_PCI) +#define LOONGSON_PCIIO_BASE loongson_sysconf.pci_io_base +#else +#define LOONGSON_PCIIO_BASE 0x1fd00000 +#endif + +#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */ +#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1) + +/* Loongson Register Bases */ + +#define LOONGSON_PCICONFIGBASE 0x00 +#define LOONGSON_REGBASE 0x100 + +/* PCI Configuration Registers */ + +#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x)) +#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00) +#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04) +#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08) +#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c) +#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10) +#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14) +#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18) +#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c) +#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20) +#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30) +#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c) + +#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c) + +#define LOONGSON_PCICMD_PERR_CLR 0x80000000 +#define LOONGSON_PCICMD_SERR_CLR 0x40000000 +#define LOONGSON_PCICMD_MABORT_CLR 0x20000000 +#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000 +#define LOONGSON_PCICMD_TABORT_CLR 0x08000000 +#define LOONGSON_PCICMD_MPERR_CLR 0x01000000 +#define LOONGSON_PCICMD_PERRRESPEN 0x00000040 +#define LOONGSON_PCICMD_ASTEPEN 0x00000080 +#define LOONGSON_PCICMD_SERREN 0x00000100 +#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00 +#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8 + +/* Loongson h/w Configuration */ + +#define LOONGSON_GENCFG_OFFSET 0x4 +#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET) + +#define LOONGSON_GENCFG_DEBUGMODE 0x00000001 +#define LOONGSON_GENCFG_SNOOPEN 0x00000002 +#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004 + +#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008 +#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010 +#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020 +#define LOONGSON_GENCFG_BYTESWAP 0x00000040 + +#define LOONGSON_GENCFG_UNCACHED 0x00000080 +#define LOONGSON_GENCFG_PREFETCHEN 0x00000100 +#define LOONGSON_GENCFG_WBEHINDEN 0x00000200 +#define LOONGSON_GENCFG_CACHEALG 0x00000c00 +#define LOONGSON_GENCFG_CACHEALG_SHIFT 10 +#define LOONGSON_GENCFG_PCIQUEUE 0x00001000 +#define LOONGSON_GENCFG_CACHESTOP 0x00002000 +#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000 +#define LOONGSON_GENCFG_BUSERREN 0x00008000 +#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000 +#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000 + +/* PCI address map control */ + +#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10) +#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14) +#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18) + +/* GPIO Regs - r/w */ + +#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c) +#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20) + +/* ICU Configuration Regs - r/w */ + +#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24) +#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28) +#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c) + +/* ICU Enable Regs - IntEn & IntISR are r/o. */ + +#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30) +#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34) +#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38) +#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c) + +/* ICU */ +#define LOONGSON_ICU_MBOXES 0x0000000f +#define LOONGSON_ICU_MBOXES_SHIFT 0 +#define LOONGSON_ICU_DMARDY 0x00000010 +#define LOONGSON_ICU_DMAEMPTY 0x00000020 +#define LOONGSON_ICU_COPYRDY 0x00000040 +#define LOONGSON_ICU_COPYEMPTY 0x00000080 +#define LOONGSON_ICU_COPYERR 0x00000100 +#define LOONGSON_ICU_PCIIRQ 0x00000200 +#define LOONGSON_ICU_MASTERERR 0x00000400 +#define LOONGSON_ICU_SYSTEMERR 0x00000800 +#define LOONGSON_ICU_DRAMPERR 0x00001000 +#define LOONGSON_ICU_RETRYERR 0x00002000 +#define LOONGSON_ICU_GPIOS 0x01ff0000 +#define LOONGSON_ICU_GPIOS_SHIFT 16 +#define LOONGSON_ICU_GPINS 0x7e000000 +#define LOONGSON_ICU_GPINS_SHIFT 25 +#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N))) +#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N))) +#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N))) + +/* PCI prefetch window base & mask */ + +#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40) +#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44) +#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48) +#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c) + +/* PCI_Hit*_Sel_* */ + +#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50) +#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54) +#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58) +#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c) +#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60) +#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64) + +/* PXArb Config & Status */ + +#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68) +#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c) + +#define MAX_PACKAGES 4 + +/* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */ +extern u64 loongson_chipcfg[MAX_PACKAGES]; +#define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id])) + +/* Chip Temperature registor of each physical cpu package, PRid >= Loongson-3A */ +extern u64 loongson_chiptemp[MAX_PACKAGES]; +#define LOONGSON_CHIPTEMP(id) (*(volatile u32 *)(loongson_chiptemp[id])) + +/* Freq Control register of each physical cpu package, PRid >= Loongson-3B */ +extern u64 loongson_freqctrl[MAX_PACKAGES]; +#define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id])) + +/* pcimap */ + +#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f +#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0 +#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0 +#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6 +#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000 +#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12 +#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000 +#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \ + ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) + +#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ +#include +extern struct cpufreq_frequency_table loongson2_clockmod_table[]; +#endif + +/* + * address windows configuration module + * + * loongson2e do not have this module + */ +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG + +/* address window config module base address */ +#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul +#define LOONGSON_ADDRWINCFG_SIZE 0x180 + +extern unsigned long _loongson_addrwincfg_base; +#define LOONGSON_ADDRWINCFG(offset) \ + (*(volatile u64 *)(_loongson_addrwincfg_base + (offset))) + +#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00) +#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08) +#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10) +#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18) + +#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20) +#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28) +#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30) +#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38) + +#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40) +#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48) +#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50) +#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58) + +#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60) +#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68) +#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70) +#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78) + +#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80) +#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88) +#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90) +#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98) + +#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0) +#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8) +#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0) +#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8) + +#define ADDRWIN_WIN0 0 +#define ADDRWIN_WIN1 1 +#define ADDRWIN_WIN2 2 +#define ADDRWIN_WIN3 3 + +#define ADDRWIN_MAP_DST_DDR 0 +#define ADDRWIN_MAP_DST_PCI 1 +#define ADDRWIN_MAP_DST_LIO 1 + +/* + * s: CPU, PCIDMA + * d: DDR, PCI, LIO + * win: 0, 1, 2, 3 + * src: map source + * dst: map destination + * size: ~mask + 1 + */ +#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\ + s##_WIN##w##_BASE = (src); \ + s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \ + s##_WIN##w##_MASK = ~(size-1); \ +} while (0) + +#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size) +#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size) +#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \ + LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size) + +#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */ + +#endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h new file mode 100644 index 000000000000..4431fc54a36c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h @@ -0,0 +1,55 @@ +#ifndef __LOONGSON_HWMON_H_ +#define __LOONGSON_HWMON_H_ + +#include + +#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_*/ diff --git a/arch/mips/include/asm/mach-loongson64/machine.h b/arch/mips/include/asm/mach-loongson64/machine.h new file mode 100644 index 000000000000..c52549bb4e56 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/machine.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + * + * 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_LOONGSON64_MACHINE_H +#define __ASM_MACH_LOONGSON64_MACHINE_H + +#ifdef CONFIG_LEMOTE_FULOONG2E + +#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E + +#endif + +/* use fuloong2f as the default machine of LEMOTE_MACH2F */ +#ifdef CONFIG_LEMOTE_MACH2F + +#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F + +#endif + +#ifdef CONFIG_LOONGSON_MACH3X + +#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC + +#endif /* CONFIG_LOONGSON_MACH3X */ + +#endif /* __ASM_MACH_LOONGSON64_MACHINE_H */ diff --git a/arch/mips/include/asm/mach-loongson64/mc146818rtc.h b/arch/mips/include/asm/mach-loongson64/mc146818rtc.h new file mode 100644 index 000000000000..ebdccfee50be --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/mc146818rtc.h @@ -0,0 +1,36 @@ +/* + * 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) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org) + * + * RTC routines for PC style attached Dallas chip. + */ +#ifndef __ASM_MACH_LOONGSON64_MC146818RTC_H +#define __ASM_MACH_LOONGSON64_MC146818RTC_H + +#include + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_IRQ 8 + +static inline unsigned char CMOS_READ(unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + return inb_p(RTC_PORT(1)); +} + +static inline void CMOS_WRITE(unsigned char data, unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + outb_p(data, RTC_PORT(1)); +} + +#define RTC_ALWAYS_BCD 0 + +#ifndef mc146818_decode_year +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) +#endif + +#endif /* __ASM_MACH_LOONGSON64_MC146818RTC_H */ diff --git a/arch/mips/include/asm/mach-loongson64/mem.h b/arch/mips/include/asm/mach-loongson64/mem.h new file mode 100644 index 000000000000..75c16bead536 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/mem.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin + * + * 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_LOONGSON64_MEM_H +#define __ASM_MACH_LOONGSON64_MEM_H + +/* + * high memory space + * + * in loongson2e, starts from 512M + * in loongson2f, starts from 2G 256M + */ +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_HIGHMEM_START 0x20000000 +#else +#define LOONGSON_HIGHMEM_START 0x90000000 +#endif + +/* + * the peripheral registers(MMIO): + * + * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000. + * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000. + */ + +#define LOONGSON_MMIO_MEM_START 0x10000000 + +#ifdef CONFIG_CPU_LOONGSON2E +#define LOONGSON_MMIO_MEM_END 0x20000000 +#else +#define LOONGSON_MMIO_MEM_END 0x80000000 +#endif + +#endif /* __ASM_MACH_LOONGSON64_MEM_H */ diff --git a/arch/mips/include/asm/mach-loongson64/mmzone.h b/arch/mips/include/asm/mach-loongson64/mmzone.h new file mode 100644 index 000000000000..37c08a27b4f0 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/mmzone.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & + * Insititute of Computing Technology + * Author: Xiang Gao, gaoxiang@ict.ac.cn + * Huacai Chen, chenhc@lemote.com + * Xiaofu Meng, Shuangshuang Zhang + * + * 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_MMZONE_H +#define _ASM_MACH_MMZONE_H + +#include +#define NODE_ADDRSPACE_SHIFT 44 +#define NODE0_ADDRSPACE_OFFSET 0x000000000000UL +#define NODE1_ADDRSPACE_OFFSET 0x100000000000UL +#define NODE2_ADDRSPACE_OFFSET 0x200000000000UL +#define NODE3_ADDRSPACE_OFFSET 0x300000000000UL + +#define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT) + +#define LEVELS_PER_SLICE 128 + +struct slice_data { + unsigned long irq_enable_mask[2]; + int level_to_irq[LEVELS_PER_SLICE]; +}; + +struct hub_data { + cpumask_t h_cpus; + unsigned long slice_map; + unsigned long irq_alloc_mask[2]; + struct slice_data slice[2]; +}; + +struct node_data { + struct pglist_data pglist; + struct hub_data hub; + cpumask_t cpumask; +}; + +extern struct node_data *__node_data[]; + +#define NODE_DATA(n) (&__node_data[(n)]->pglist) +#define hub_data(n) (&__node_data[(n)]->hub) + +extern void setup_zero_pages(void); +extern void __init prom_init_numa_memory(void); + +#endif /* _ASM_MACH_MMZONE_H */ diff --git a/arch/mips/include/asm/mach-loongson64/pci.h b/arch/mips/include/asm/mach-loongson64/pci.h new file mode 100644 index 000000000000..3401f557434a --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/pci.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008 Zhang Le + * Copyright (c) 2009 Wu Zhangjin + * + * 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_LOONGSON64_PCI_H_ +#define __ASM_MACH_LOONGSON64_PCI_H_ + +extern struct pci_ops loongson_pci_ops; + +/* this is an offset from mips_io_port_base */ +#define LOONGSON_PCI_IO_START 0x00004000UL + +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG + +/* + * we use address window2 to map cpu address space to pci space + * window2: cpu [1G, 2G] -> pci [1G, 2G] + * why not use window 0 & 1? because they are used by cpu when booting. + * window0: cpu [0, 256M] -> ddr [0, 256M] + * window1: cpu [256M, 512M] -> pci [256M, 512M] + */ + +/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */ +#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */ +#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC + +#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST +#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */ + +#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \ + LOONGSON_PCI_MEM_START + 1) + +#else /* loongson2f/32bit & loongson2e */ + +/* this pci memory space is mapped by pcimap in pci.c */ +#ifdef CONFIG_CPU_LOONGSON3 +#define LOONGSON_PCI_MEM_START 0x40000000UL +#define LOONGSON_PCI_MEM_END 0x7effffffUL +#else +#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE +#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2) +#endif +/* this is an offset from mips_io_port_base */ +#define LOONGSON_PCI_IO_START 0x00004000UL + +#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ + +#endif /* !__ASM_MACH_LOONGSON64_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-loongson64/spaces.h b/arch/mips/include/asm/mach-loongson64/spaces.h new file mode 100644 index 000000000000..c6040b9fcf94 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/spaces.h @@ -0,0 +1,9 @@ +#ifndef __ASM_MACH_LOONGSON64_SPACES_H_ +#define __ASM_MACH_LOONGSON64_SPACES_H_ + +#if defined(CONFIG_64BIT) +#define CAC_BASE _AC(0x9800000000000000, UL) +#endif /* CONFIG_64BIT */ + +#include +#endif diff --git a/arch/mips/include/asm/mach-loongson64/topology.h b/arch/mips/include/asm/mach-loongson64/topology.h new file mode 100644 index 000000000000..0d8f3b55bdbc --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/topology.h @@ -0,0 +1,23 @@ +#ifndef _ASM_MACH_TOPOLOGY_H +#define _ASM_MACH_TOPOLOGY_H + +#ifdef CONFIG_NUMA + +#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) +#define parent_node(node) (node) +#define cpumask_of_node(node) (&__node_data[(node)]->cpumask) + +struct pci_bus; +extern int pcibus_to_node(struct pci_bus *); + +#define cpumask_of_pcibus(bus) (cpu_online_mask) + +extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; + +#define node_distance(from, to) (__node_distances[(from)][(to)]) + +#endif + +#include + +#endif /* _ASM_MACH_TOPOLOGY_H */ diff --git a/arch/mips/include/asm/mach-loongson64/workarounds.h b/arch/mips/include/asm/mach-loongson64/workarounds.h new file mode 100644 index 000000000000..e659f041e116 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson64/workarounds.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_LOONGSON64_WORKAROUNDS_H_ +#define __ASM_MACH_LOONGSON64_WORKAROUNDS_H_ + +#define WORKAROUND_CPUFREQ 0x00000001 +#define WORKAROUND_CPUHOTPLUG 0x00000002 + +#endif diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig deleted file mode 100644 index 506414915463..000000000000 --- a/arch/mips/loongson/Kconfig +++ /dev/null @@ -1,158 +0,0 @@ -if MACH_LOONGSON - -choice - prompt "Machine Type" - -config LEMOTE_FULOONG2E - bool "Lemote Fuloong(2e) mini-PC" - select ARCH_SPARSEMEM_ENABLE - select CEVT_R4K - select CSRC_R4K - select SYS_HAS_CPU_LOONGSON2E - select DMA_NONCOHERENT - select BOOT_ELF32 - select BOARD_SCACHE - select HW_HAS_PCI - select I8259 - select ISA - select IRQ_MIPS_CPU - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_HIGHMEM - select SYS_HAS_EARLY_PRINTK - select GENERIC_ISA_DMA_SUPPORT_BROKEN - select CPU_HAS_WB - select LOONGSON_MC146818 - help - Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and - an FPGA northbridge - - Lemote Fuloong(2e) mini PC have a VIA686B south bridge. - -config LEMOTE_MACH2F - bool "Lemote Loongson 2F family machines" - select ARCH_SPARSEMEM_ENABLE - select BOARD_SCACHE - select BOOT_ELF32 - select CEVT_R4K if ! MIPS_EXTERNAL_TIMER - select CPU_HAS_WB - select CS5536 - select CSRC_R4K if ! MIPS_EXTERNAL_TIMER - select DMA_NONCOHERENT - select GENERIC_ISA_DMA_SUPPORT_BROKEN - select HAVE_CLK - select HW_HAS_PCI - select I8259 - select IRQ_MIPS_CPU - select ISA - select SYS_HAS_CPU_LOONGSON2F - select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_HIGHMEM - select SYS_SUPPORTS_LITTLE_ENDIAN - select LOONGSON_MC146818 - help - Lemote Loongson 2F family machines utilize the 2F revision of - Loongson processor and the AMD CS5536 south bridge. - - These family machines include fuloong2f mini PC, yeeloong2f notebook, - LingLoong allinone PC and so forth. - -config LOONGSON_MACH3X - bool "Generic Loongson 3 family machines" - select ARCH_SPARSEMEM_ENABLE - select GENERIC_ISA_DMA_SUPPORT_BROKEN - select BOOT_ELF32 - select BOARD_SCACHE - select CSRC_R4K - select CEVT_R4K - select CPU_HAS_WB - select HW_HAS_PCI - select ISA - select HT_PCI - select I8259 - select IRQ_MIPS_CPU - select NR_CPUS_DEFAULT_4 - select SYS_HAS_CPU_LOONGSON3 - select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_SMP - select SYS_SUPPORTS_HOTPLUG_CPU - select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_HIGHMEM - select SYS_SUPPORTS_LITTLE_ENDIAN - select LOONGSON_MC146818 - select ZONE_DMA32 - select LEFI_FIRMWARE_INTERFACE - select PHYS48_TO_HT40 - help - Generic Loongson 3 family machines utilize the 3A/3B revision - of Loongson processor and RS780/SBX00 chipset. -endchoice - -config CS5536 - bool - -config CS5536_MFGPT - bool "CS5536 MFGPT Timer" - depends on CS5536 && !HIGH_RES_TIMERS - select MIPS_EXTERNAL_TIMER - help - This option enables the mfgpt0 timer of AMD CS5536. With this timer - switched on you can not use high resolution timers. - - If you want to enable the Loongson2 CPUFreq Driver, Please enable - this option at first, otherwise, You will get wrong system time. - - If unsure, say Yes. - -config RS780_HPET - bool "RS780/SBX00 HPET Timer" - depends on LOONGSON_MACH3X - select MIPS_EXTERNAL_TIMER - help - This option enables the hpet timer of AMD RS780/SBX00. - - If you want to enable the Loongson3 CPUFreq Driver, Please enable - this option at first, otherwise, You will get wrong system time. - - If unsure, say Yes. - -config LOONGSON_SUSPEND - bool - default y - depends on CPU_SUPPORTS_CPUFREQ && SUSPEND - -config LOONGSON_UART_BASE - bool - default y - depends on EARLY_PRINTK || SERIAL_8250 - -config IOMMU_HELPER - bool - -config NEED_SG_DMA_LENGTH - bool - -config SWIOTLB - bool "Soft IOMMU Support for All-Memory DMA" - default y - depends on CPU_LOONGSON3 - select IOMMU_HELPER - select NEED_SG_DMA_LENGTH - select NEED_DMA_MAP_STATE - -config PHYS48_TO_HT40 - bool - default y if CPU_LOONGSON3 - -config LOONGSON_MC146818 - bool - default n - -config LEFI_FIRMWARE_INTERFACE - bool - -endif # MACH_LOONGSON diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile deleted file mode 100644 index 7429994e7604..000000000000 --- a/arch/mips/loongson/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Common code for all Loongson based systems -# - -obj-$(CONFIG_MACH_LOONGSON) += common/ - -# -# Lemote Fuloong mini-PC (Loongson 2E-based) -# - -obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/ - -# -# Lemote loongson2f family machines -# - -obj-$(CONFIG_LEMOTE_MACH2F) += lemote-2f/ - -# -# All Loongson-3 family machines -# - -obj-$(CONFIG_CPU_LOONGSON3) += loongson-3/ diff --git a/arch/mips/loongson/Platform b/arch/mips/loongson/Platform deleted file mode 100644 index 0ac20eb84ecc..000000000000 --- a/arch/mips/loongson/Platform +++ /dev/null @@ -1,33 +0,0 @@ -# -# Loongson Processors' Support -# - -# Only gcc >= 4.4 have Loongson specific support -cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap -cflags-$(CONFIG_CPU_LOONGSON2E) += \ - $(call cc-option,-march=loongson2e,-march=r4600) -cflags-$(CONFIG_CPU_LOONGSON2F) += \ - $(call cc-option,-march=loongson2f,-march=r4600) -# Enable the workarounds for Loongson2f -ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS - ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),) - $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop) - else - cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop - endif - ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),) - $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump) - else - cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump - endif -endif - -# -# Loongson Machines' Support -# - -platform-$(CONFIG_MACH_LOONGSON) += loongson/ -cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely -load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000 -load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000 -load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000 diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile deleted file mode 100644 index f2e8153e44f5..000000000000 --- a/arch/mips/loongson/common/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# Makefile for loongson based machines. -# - -obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ - bonito-irq.o mem.o machtype.o platform.o serial.o -obj-$(CONFIG_PCI) += pci.o - -# -# Serial port support -# -obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o -obj-$(CONFIG_LOONGSON_MC146818) += rtc.o - -# -# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure -# space -# -obj-$(CONFIG_CS5536) += cs5536/ - -# -# Suspend Support -# - -obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o - -# -# Big Memory (SWIOTLB) Support -# -obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c deleted file mode 100644 index cc0e4fd548e6..000000000000 --- a/arch/mips/loongson/common/bonito-irq.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include - -static inline void bonito_irq_enable(struct irq_data *d) -{ - LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE)); - mmiowb(); -} - -static inline void bonito_irq_disable(struct irq_data *d) -{ - LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE)); - mmiowb(); -} - -static struct irq_chip bonito_irq_type = { - .name = "bonito_irq", - .irq_mask = bonito_irq_disable, - .irq_unmask = bonito_irq_enable, -}; - -static struct irqaction __maybe_unused dma_timeout_irqaction = { - .handler = no_action, - .name = "dma_timeout", -}; - -void bonito_irq_init(void) -{ - u32 i; - - for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) - irq_set_chip_and_handler(i, &bonito_irq_type, - handle_level_irq); - -#ifdef CONFIG_CPU_LOONGSON2E - setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction); -#endif -} diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c deleted file mode 100644 index 72fed003a536..000000000000 --- a/arch/mips/loongson/common/cmdline.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Based on Ocelot Linux port, which is - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright 2003 ICT CAS - * Author: Michael Guo - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include - -void __init prom_init_cmdline(void) -{ - int prom_argc; - /* pmon passes arguments in 32bit pointers */ - int *_prom_argv; - int i; - long l; - - /* firmware arguments are initialized in head.S */ - prom_argc = fw_arg0; - _prom_argv = (int *)fw_arg1; - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - for (i = 1; i < prom_argc; i++) { - l = (long)_prom_argv[i]; - if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) - >= sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, ((char *)l)); - strcat(arcs_cmdline, " "); - } - - prom_init_machtype(); -} diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile deleted file mode 100644 index f12e64007347..000000000000 --- a/arch/mips/loongson/common/cs5536/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for CS5536 support. -# - -obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \ - cs5536_isa.o cs5536_ehci.o - -# -# Enable cs5536 mfgpt Timer -# -obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o diff --git a/arch/mips/loongson/common/cs5536/cs5536_acc.c b/arch/mips/loongson/common/cs5536/cs5536_acc.c deleted file mode 100644 index ab4d6cc57384..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_acc.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * the ACC Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_acc_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - lo |= (0x03 << 8); - else - lo &= ~(0x03 << 8); - _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_BAR0_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_ACC_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if (value & 0x01) { - value &= 0xfffffffc; - hi = 0xA0000000 | ((value & 0x000ff000) >> 12); - lo = 0x000fff80 | ((value & 0x00000fff) << 20); - _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); - } - break; - case PCI_ACC_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); - /* disable all the usb interrupt in PIC */ - lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); - if (value) /* enable all the acc interrupt in PIC */ - lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); - break; - default: - break; - } -} - -u32 pci_acc_read_reg(int reg) -{ - u32 hi, lo; - u32 conf_data = 0; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); - if (((lo & 0xfff00000) || (hi & 0x000000ff)) - && ((hi & 0xf0000000) == 0xa0000000)) - conf_data |= PCI_COMMAND_IO; - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if ((lo & 0x300) == 0x300) - conf_data |= PCI_COMMAND_MASTER; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_ACC_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - conf_data = - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, - PCI_NORMAL_LATENCY_TIMER); - break; - case PCI_BAR0_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_ACC_FLAG) { - conf_data = CS5536_ACC_RANGE | - PCI_BASE_ADDRESS_SPACE_IO; - lo &= ~SOFT_BAR_ACC_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); - conf_data = (hi & 0x000000ff) << 12; - conf_data |= (lo & 0xfff00000) >> 20; - conf_data |= 0x01; - conf_data &= ~0x02; - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_USB_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR); - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_ehci.c b/arch/mips/loongson/common/cs5536/cs5536_ehci.c deleted file mode 100644 index ec2e360267a8..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_ehci.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * the EHCI Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_ehci_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - hi |= PCI_COMMAND_MASTER; - else - hi &= ~PCI_COMMAND_MASTER; - - if (value & PCI_COMMAND_MEMORY) - hi |= PCI_COMMAND_MEMORY; - else - hi &= ~PCI_COMMAND_MEMORY; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_BAR0_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_EHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if ((value & 0x01) == 0x00) { - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - lo = value; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - - value &= 0xfffffff0; - hi = 0x40000000 | ((value & 0xff000000) >> 24); - lo = 0x000fffff | ((value & 0x00fff000) << 8); - _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); - } - break; - case PCI_EHCI_LEGSMIEN_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - hi &= 0x003f0000; - hi |= (value & 0x3f) << 16; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - break; - case PCI_EHCI_FLADJ_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - hi &= ~0x00003f00; - hi |= value & 0x00003f00; - _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); - break; - default: - break; - } -} - -u32 pci_ehci_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - if (hi & PCI_COMMAND_MASTER) - conf_data |= PCI_COMMAND_MASTER; - if (hi & PCI_COMMAND_MEMORY) - conf_data |= PCI_COMMAND_MEMORY; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_EHCI_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - conf_data = - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, - PCI_NORMAL_LATENCY_TIMER); - break; - case PCI_BAR0_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_EHCI_FLAG) { - conf_data = CS5536_EHCI_RANGE | - PCI_BASE_ADDRESS_SPACE_MEMORY; - lo &= ~SOFT_BAR_EHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = lo & 0xfffff000; - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_USB_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); - break; - case PCI_EHCI_LEGSMIEN_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = (hi & 0x003f0000) >> 16; - break; - case PCI_EHCI_LEGSMISTS_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = (hi & 0x3f000000) >> 24; - break; - case PCI_EHCI_FLADJ_REG: - _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); - conf_data = hi & 0x00003f00; - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_ide.c b/arch/mips/loongson/common/cs5536/cs5536_ide.c deleted file mode 100644 index a73414d9ee51..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_ide.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * the IDE Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_ide_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - lo |= (0x03 << 4); - else - lo &= ~(0x03 << 4); - _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_CACHE_LINE_SIZE: - value &= 0x0000ff00; - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0xffffff00; - hi |= (value >> 8); - _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); - break; - case PCI_BAR4_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_IDE_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if (value & 0x01) { - _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); - lo = (value & 0xfffffff0) | 0x1; - _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); - - value &= 0xfffffffc; - hi = 0x60000000 | ((value & 0x000ff000) >> 12); - lo = 0x000ffff0 | ((value & 0x00000fff) << 20); - _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); - } - break; - case PCI_IDE_CFG_REG: - if (value == CS5536_IDE_FLASH_SIGNATURE) { - _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); - lo |= 0x01; - _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); - } else { - _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); - } - break; - case PCI_IDE_DTC_REG: - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); - break; - case PCI_IDE_CAST_REG: - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); - break; - case PCI_IDE_ETC_REG: - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); - break; - case PCI_IDE_PM_REG: - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); - lo = value; - _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); - break; - default: - break; - } -} - -u32 pci_ide_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); - if (lo & 0xfffffff0) - conf_data |= PCI_COMMAND_IO; - _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); - if ((lo & 0x30) == 0x30) - conf_data |= PCI_COMMAND_MASTER; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_IDE_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0x000000f8; - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); - break; - case PCI_BAR4_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_IDE_FLAG) { - conf_data = CS5536_IDE_RANGE | - PCI_BASE_ADDRESS_SPACE_IO; - lo &= ~SOFT_BAR_IDE_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); - conf_data = lo & 0xfffffff0; - conf_data |= 0x01; - conf_data &= ~0x02; - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); - break; - case PCI_IDE_CFG_REG: - _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_DTC_REG: - _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_CAST_REG: - _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_ETC_REG: - _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); - conf_data = lo; - break; - case PCI_IDE_PM_REG: - _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); - conf_data = lo; - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c b/arch/mips/loongson/common/cs5536/cs5536_isa.c deleted file mode 100644 index 924be39e7733..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_isa.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * the ISA Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -/* common variables for PCI_ISA_READ/WRITE_BAR */ -static const u32 divil_msr_reg[6] = { - DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO), - DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ), - DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI), -}; - -static const u32 soft_bar_flag[6] = { - SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG, - SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG, -}; - -static const u32 sb_msr_reg[6] = { - SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2), - SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5), -}; - -static const u32 bar_space_range[6] = { - CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE, - CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE, -}; - -static const int bar_space_len[6] = { - CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH, - CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH, -}; - -/* - * enable the divil module bar space. - * - * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg - * and the RCONFx(0~5) reg to use the modules. - */ -static void divil_lbar_enable(void) -{ - u32 hi, lo; - int offset; - - /* - * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. - */ - - for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { - _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); - hi |= 0x01; - _wrmsr(DIVIL_MSR_REG(offset), hi, lo); - } -} - -/* - * disable the divil module bar space. - */ -static void divil_lbar_disable(void) -{ - u32 hi, lo; - int offset; - - for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { - _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); - hi &= ~0x01; - _wrmsr(DIVIL_MSR_REG(offset), hi, lo); - } -} - -/* - * BAR write: write value to the n BAR - */ - -void pci_isa_write_bar(int n, u32 value) -{ - u32 hi = 0, lo = value; - - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= soft_bar_flag[n]; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if (value & 0x01) { - /* NATIVE reg */ - hi = 0x0000f001; - lo &= bar_space_range[n]; - _wrmsr(divil_msr_reg[n], hi, lo); - - /* RCONFx is 4bytes in units for I/O space */ - hi = ((value & 0x000ffffc) << 12) | - ((bar_space_len[n] - 4) << 12) | 0x01; - lo = ((value & 0x000ffffc) << 12) | 0x01; - _wrmsr(sb_msr_reg[n], hi, lo); - } -} - -/* - * BAR read: read the n BAR - */ - -u32 pci_isa_read_bar(int n) -{ - u32 conf_data = 0; - u32 hi, lo; - - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & soft_bar_flag[n]) { - conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO; - lo &= ~soft_bar_flag[n]; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(divil_msr_reg[n], &hi, &lo); - conf_data = lo & bar_space_range[n]; - conf_data |= 0x01; - conf_data &= ~0x02; - } - return conf_data; -} - -/* - * isa_write: ISA write transfer - * - * We assume that this is not a bus master transfer. - */ -void pci_isa_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - u32 temp; - - switch (reg) { - case PCI_COMMAND: - if (value & PCI_COMMAND_IO) - divil_lbar_enable(); - else - divil_lbar_disable(); - break; - case PCI_STATUS: - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - temp = lo & 0x0000ffff; - if ((value & PCI_STATUS_SIG_TARGET_ABORT) && - (lo & SB_TAS_ERR_EN)) - temp |= SB_TAS_ERR_FLAG; - - if ((value & PCI_STATUS_REC_TARGET_ABORT) && - (lo & SB_TAR_ERR_EN)) - temp |= SB_TAR_ERR_FLAG; - - if ((value & PCI_STATUS_REC_MASTER_ABORT) - && (lo & SB_MAR_ERR_EN)) - temp |= SB_MAR_ERR_FLAG; - - if ((value & PCI_STATUS_DETECTED_PARITY) - && (lo & SB_PARE_ERR_EN)) - temp |= SB_PARE_ERR_FLAG; - - lo = temp; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - break; - case PCI_CACHE_LINE_SIZE: - value &= 0x0000ff00; - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0xffffff00; - hi |= (value >> 8); - _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); - break; - case PCI_BAR0_REG: - pci_isa_write_bar(0, value); - break; - case PCI_BAR1_REG: - pci_isa_write_bar(1, value); - break; - case PCI_BAR2_REG: - pci_isa_write_bar(2, value); - break; - case PCI_BAR3_REG: - pci_isa_write_bar(3, value); - break; - case PCI_BAR4_REG: - pci_isa_write_bar(4, value); - break; - case PCI_BAR5_REG: - pci_isa_write_bar(5, value); - break; - case PCI_UART1_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); - /* disable uart1 interrupt in PIC */ - lo &= ~(0xf << 24); - if (value) /* enable uart1 interrupt in PIC */ - lo |= (CS5536_UART1_INTR << 24); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); - break; - case PCI_UART2_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); - /* disable uart2 interrupt in PIC */ - lo &= ~(0xf << 28); - if (value) /* enable uart2 interrupt in PIC */ - lo |= (CS5536_UART2_INTR << 28); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); - break; - case PCI_ISA_FIXUP_REG: - if (value) { - /* enable the TARGET ABORT/MASTER ABORT etc. */ - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - lo |= 0x00000063; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - - default: - /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ - break; - } -} - -/* - * isa_read: ISA read transfers - * - * We assume that this is not a bus master transfer. - */ -u32 pci_isa_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - /* we just check the first LBAR for the IO enable bit, */ - /* maybe we should changed later. */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); - if (hi & 0x01) - conf_data |= PCI_COMMAND_IO; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - conf_data |= PCI_STATUS_FAST_BACK; - - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_TAS_ERR_FLAG) - conf_data |= PCI_STATUS_SIG_TARGET_ABORT; - if (lo & SB_TAR_ERR_FLAG) - conf_data |= PCI_STATUS_REC_TARGET_ABORT; - if (lo & SB_MAR_ERR_FLAG) - conf_data |= PCI_STATUS_REC_MASTER_ABORT; - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_DETECTED_PARITY; - break; - case PCI_CLASS_REVISION: - _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_ISA_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); - hi &= 0x000000f8; - conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi); - break; - /* - * we only use the LBAR of DIVIL, no RCONF used. - * all of them are IO space. - */ - case PCI_BAR0_REG: - return pci_isa_read_bar(0); - break; - case PCI_BAR1_REG: - return pci_isa_read_bar(1); - break; - case PCI_BAR2_REG: - return pci_isa_read_bar(2); - break; - case PCI_BAR3_REG: - break; - case PCI_BAR4_REG: - return pci_isa_read_bar(4); - break; - case PCI_BAR5_REG: - return pci_isa_read_bar(5); - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_POINTER; - break; - case PCI_INTERRUPT_LINE: - /* no interrupt used here */ - conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00); - break; - default: - break; - } - - return conf_data; -} - -/* - * The mfgpt timer interrupt is running early, so we must keep the south bridge - * mmio always enabled. Otherwise we may race with the PCI configuration which - * may temporarily disable it. When that happens and the timer interrupt fires, - * we are not able to clear it and the system will hang. - */ -static void cs5536_isa_mmio_always_on(struct pci_dev *dev) -{ - dev->mmio_always_on = 1; -} -DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, - PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on); diff --git a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c deleted file mode 100644 index 12c75db23420..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * CS5536 General timer functions - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Yanhua, yanh@lemote.com - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu zhangjin, wuzhangjin@gmail.com - * - * Reference: AMD Geode(TM) CS5536 Companion Device Data Book - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static DEFINE_RAW_SPINLOCK(mfgpt_lock); - -static u32 mfgpt_base; - -/* - * Initialize the MFGPT timer. - * - * This is also called after resume to bring the MFGPT into operation again. - */ - -/* disable counter */ -void disable_mfgpt0_counter(void) -{ - outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP); -} -EXPORT_SYMBOL(disable_mfgpt0_counter); - -/* enable counter, comparator2 to event mode, 14.318MHz clock */ -void enable_mfgpt0_counter(void) -{ - outw(0xe310, MFGPT0_SETUP); -} -EXPORT_SYMBOL(enable_mfgpt0_counter); - -static void init_mfgpt_timer(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - raw_spin_lock(&mfgpt_lock); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */ - outw(0, MFGPT0_CNT); /* set counter to 0 */ - enable_mfgpt0_counter(); - break; - - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - if (evt->mode == CLOCK_EVT_MODE_PERIODIC || - evt->mode == CLOCK_EVT_MODE_ONESHOT) - disable_mfgpt0_counter(); - break; - - case CLOCK_EVT_MODE_ONESHOT: - /* The oneshot mode have very high deviation, Not use it! */ - break; - - case CLOCK_EVT_MODE_RESUME: - /* Nothing to do here */ - break; - } - raw_spin_unlock(&mfgpt_lock); -} - -static struct clock_event_device mfgpt_clockevent = { - .name = "mfgpt", - .features = CLOCK_EVT_FEAT_PERIODIC, - .set_mode = init_mfgpt_timer, - .irq = CS5536_MFGPT_INTR, -}; - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - u32 basehi; - - /* - * get MFGPT base address - * - * NOTE: do not remove me, it's need for the value of mfgpt_base is - * variable - */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); - - /* ack */ - outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP); - - mfgpt_clockevent.event_handler(&mfgpt_clockevent); - - return IRQ_HANDLED; -} - -static struct irqaction irq5 = { - .handler = timer_interrupt, - .flags = IRQF_NOBALANCING | IRQF_TIMER, - .name = "timer" -}; - -/* - * Initialize the conversion factor and the min/max deltas of the clock event - * structure and register the clock event source with the framework. - */ -void __init setup_mfgpt0_timer(void) -{ - u32 basehi; - struct clock_event_device *cd = &mfgpt_clockevent; - unsigned int cpu = smp_processor_id(); - - cd->cpumask = cpumask_of(cpu); - clockevent_set_clock(cd, MFGPT_TICK_RATE); - cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0xf, cd); - - /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ - _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); - - /* Enable Interrupt Gate 5 */ - _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000); - - /* get MFGPT base address */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); - - clockevents_register_device(cd); - - setup_irq(CS5536_MFGPT_INTR, &irq5); -} - -/* - * Since the MFGPT overflows every tick, its not very useful - * to just read by itself. So use jiffies to emulate a free - * running counter: - */ -static cycle_t mfgpt_read(struct clocksource *cs) -{ - unsigned long flags; - int count; - u32 jifs; - static int old_count; - static u32 old_jifs; - - raw_spin_lock_irqsave(&mfgpt_lock, flags); - /* - * Although our caller may have the read side of xtime_lock, - * this is now a seqlock, and we are cheating in this routine - * by having side effects on state that we cannot undo if - * there is a collision on the seqlock and our caller has to - * retry. (Namely, old_jifs and old_count.) So we must treat - * jiffies as volatile despite the lock. We read jiffies - * before latching the timer count to guarantee that although - * the jiffies value might be older than the count (that is, - * the counter may underflow between the last point where - * jiffies was incremented and the point where we latch the - * count), it cannot be newer. - */ - jifs = jiffies; - /* read the count */ - count = inw(MFGPT0_CNT); - - /* - * It's possible for count to appear to go the wrong way for this - * reason: - * - * The timer counter underflows, but we haven't handled the resulting - * interrupt and incremented jiffies yet. - * - * Previous attempts to handle these cases intelligently were buggy, so - * we just do the simple thing now. - */ - if (count < old_count && jifs == old_jifs) - count = old_count; - - old_count = count; - old_jifs = jifs; - - raw_spin_unlock_irqrestore(&mfgpt_lock, flags); - - return (cycle_t) (jifs * COMPARE) + count; -} - -static struct clocksource clocksource_mfgpt = { - .name = "mfgpt", - .rating = 120, /* Functional for real use, but not desired */ - .read = mfgpt_read, - .mask = CLOCKSOURCE_MASK(32), -}; - -int __init init_mfgpt_clocksource(void) -{ - if (num_possible_cpus() > 1) /* MFGPT does not scale! */ - return 0; - - return clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE); -} - -arch_initcall(init_mfgpt_clocksource); diff --git a/arch/mips/loongson/common/cs5536/cs5536_ohci.c b/arch/mips/loongson/common/cs5536/cs5536_ohci.c deleted file mode 100644 index f7c905e50dc4..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_ohci.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * the OHCI Virtual Support Module of AMD CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -void pci_ohci_write_reg(int reg, u32 value) -{ - u32 hi = 0, lo = value; - - switch (reg) { - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - if (value & PCI_COMMAND_MASTER) - hi |= PCI_COMMAND_MASTER; - else - hi &= ~PCI_COMMAND_MASTER; - - if (value & PCI_COMMAND_MEMORY) - hi |= PCI_COMMAND_MEMORY; - else - hi &= ~PCI_COMMAND_MEMORY; - _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); - break; - case PCI_STATUS: - if (value & PCI_STATUS_PARITY) { - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) { - lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; - _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); - } - } - break; - case PCI_BAR0_REG: - if (value == PCI_BAR_RANGE_MASK) { - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - lo |= SOFT_BAR_OHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else if ((value & 0x01) == 0x00) { - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - lo = value; - _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); - - value &= 0xfffffff0; - hi = 0x40000000 | ((value & 0xff000000) >> 24); - lo = 0x000fffff | ((value & 0x00fff000) << 8); - _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); - } - break; - case PCI_OHCI_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); - lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT); - if (value) /* enable all the usb interrupt in PIC */ - lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT); - _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); - break; - default: - break; - } -} - -u32 pci_ohci_read_reg(int reg) -{ - u32 conf_data = 0; - u32 hi, lo; - - switch (reg) { - case PCI_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID); - break; - case PCI_COMMAND: - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - if (hi & PCI_COMMAND_MASTER) - conf_data |= PCI_COMMAND_MASTER; - if (hi & PCI_COMMAND_MEMORY) - conf_data |= PCI_COMMAND_MEMORY; - break; - case PCI_STATUS: - conf_data |= PCI_STATUS_66MHZ; - conf_data |= PCI_STATUS_FAST_BACK; - _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); - if (lo & SB_PARE_ERR_FLAG) - conf_data |= PCI_STATUS_PARITY; - conf_data |= PCI_STATUS_DEVSEL_MEDIUM; - break; - case PCI_CLASS_REVISION: - _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); - conf_data = lo & 0x000000ff; - conf_data |= (CS5536_OHCI_CLASS_CODE << 8); - break; - case PCI_CACHE_LINE_SIZE: - conf_data = - CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, - PCI_NORMAL_LATENCY_TIMER); - break; - case PCI_BAR0_REG: - _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); - if (lo & SOFT_BAR_OHCI_FLAG) { - conf_data = CS5536_OHCI_RANGE | - PCI_BASE_ADDRESS_SPACE_MEMORY; - lo &= ~SOFT_BAR_OHCI_FLAG; - _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); - } else { - _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); - conf_data = lo & 0xffffff00; - conf_data &= ~0x0000000f; /* 32bit mem */ - } - break; - case PCI_CARDBUS_CIS: - conf_data = PCI_CARDBUS_CIS_POINTER; - break; - case PCI_SUBSYSTEM_VENDOR_ID: - conf_data = - CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID); - break; - case PCI_ROM_ADDRESS: - conf_data = PCI_EXPANSION_ROM_BAR; - break; - case PCI_CAPABILITY_LIST: - conf_data = PCI_CAPLIST_USB_POINTER; - break; - case PCI_INTERRUPT_LINE: - conf_data = - CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); - break; - case PCI_OHCI_INT_REG: - _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); - if ((lo & 0x00000f00) == CS5536_USB_INTR) - conf_data = 1; - break; - default: - break; - } - - return conf_data; -} diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c deleted file mode 100644 index b739723205f8..000000000000 --- a/arch/mips/loongson/common/cs5536/cs5536_pci.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * read/write operation to the PCI config space of CS5536 - * - * Copyright (C) 2007 Lemote, Inc. - * Author : jlliu, liujl@lemote.com - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * 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. - * - * the Virtual Support Module(VSM) for virtulizing the PCI - * configure space are defined in cs5536_modulename.c respectively, - * - * after this virtulizing, user can access the PCI configure space - * directly as a normal multi-function PCI device which follows - * the PCI-2.2 spec. - */ - -#include -#include -#include - -enum { - CS5536_FUNC_START = -1, - CS5536_ISA_FUNC, - reserved_func, - CS5536_IDE_FUNC, - CS5536_ACC_FUNC, - CS5536_OHCI_FUNC, - CS5536_EHCI_FUNC, - CS5536_FUNC_END, -}; - -static const cs5536_pci_vsm_write vsm_conf_write[] = { - [CS5536_ISA_FUNC] = pci_isa_write_reg, - [reserved_func] = NULL, - [CS5536_IDE_FUNC] = pci_ide_write_reg, - [CS5536_ACC_FUNC] = pci_acc_write_reg, - [CS5536_OHCI_FUNC] = pci_ohci_write_reg, - [CS5536_EHCI_FUNC] = pci_ehci_write_reg, -}; - -static const cs5536_pci_vsm_read vsm_conf_read[] = { - [CS5536_ISA_FUNC] = pci_isa_read_reg, - [reserved_func] = NULL, - [CS5536_IDE_FUNC] = pci_ide_read_reg, - [CS5536_ACC_FUNC] = pci_acc_read_reg, - [CS5536_OHCI_FUNC] = pci_ohci_read_reg, - [CS5536_EHCI_FUNC] = pci_ehci_read_reg, -}; - -/* - * write to PCI config space and transfer it to MSR write. - */ -void cs5536_pci_conf_write4(int function, int reg, u32 value) -{ - if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) - return; - if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) - return; - - if (vsm_conf_write[function] != NULL) - vsm_conf_write[function](reg, value); -} - -/* - * read PCI config space and transfer it to MSR access. - */ -u32 cs5536_pci_conf_read4(int function, int reg) -{ - u32 data = 0; - - if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) - return 0; - if ((reg < 0) || ((reg & 0x03) != 0)) - return 0; - if (reg > 0x100) - return 0xffffffff; - - if (vsm_conf_read[function] != NULL) - data = vsm_conf_read[function](reg); - - return data; -} diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c deleted file mode 100644 index 2c6b989c1bc4..000000000000 --- a/arch/mips/loongson/common/dma-swiotlb.c +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static void *loongson_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) -{ - void *ret; - - if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) - return ret; - - /* ignore region specifiers */ - gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); - -#ifdef CONFIG_ISA - if (dev == NULL) - gfp |= __GFP_DMA; - else -#endif -#ifdef CONFIG_ZONE_DMA - if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) - gfp |= __GFP_DMA; - else -#endif -#ifdef CONFIG_ZONE_DMA32 - if (dev->coherent_dma_mask < DMA_BIT_MASK(40)) - gfp |= __GFP_DMA32; - else -#endif - ; - gfp |= __GFP_NORETRY; - - ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp); - mb(); - return ret; -} - -static void loongson_dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) -{ - int order = get_order(size); - - if (dma_release_from_coherent(dev, order, vaddr)) - return; - - swiotlb_free_coherent(dev, size, vaddr, dma_handle); -} - -static dma_addr_t loongson_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size, - dir, attrs); - mb(); - return daddr; -} - -static int loongson_dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - int r = swiotlb_map_sg_attrs(dev, sg, nents, dir, NULL); - mb(); - - return r; -} - -static void loongson_dma_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) -{ - swiotlb_sync_single_for_device(dev, dma_handle, size, dir); - mb(); -} - -static void loongson_dma_sync_sg_for_device(struct device *dev, - struct scatterlist *sg, int nents, - enum dma_data_direction dir) -{ - swiotlb_sync_sg_for_device(dev, sg, nents, dir); - mb(); -} - -static int loongson_dma_set_mask(struct device *dev, u64 mask) -{ - if (mask > DMA_BIT_MASK(loongson_sysconf.dma_mask_bits)) { - *dev->dma_mask = DMA_BIT_MASK(loongson_sysconf.dma_mask_bits); - return -EIO; - } - - *dev->dma_mask = mask; - - return 0; -} - -dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) -{ - long nid; -#ifdef CONFIG_PHYS48_TO_HT40 - /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from - * Loongson-3's 48bit address space and embed it into 40bit */ - nid = (paddr >> 44) & 0x3; - paddr = ((nid << 44) ^ paddr) | (nid << 37); -#endif - return paddr; -} - -phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) -{ - long nid; -#ifdef CONFIG_PHYS48_TO_HT40 - /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from - * Loongson-3's 48bit address space and embed it into 40bit */ - nid = (daddr >> 37) & 0x3; - daddr = ((nid << 37) ^ daddr) | (nid << 44); -#endif - return daddr; -} - -static struct dma_map_ops loongson_dma_map_ops = { - .alloc = loongson_dma_alloc_coherent, - .free = loongson_dma_free_coherent, - .map_page = loongson_dma_map_page, - .unmap_page = swiotlb_unmap_page, - .map_sg = loongson_dma_map_sg, - .unmap_sg = swiotlb_unmap_sg_attrs, - .sync_single_for_cpu = swiotlb_sync_single_for_cpu, - .sync_single_for_device = loongson_dma_sync_single_for_device, - .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, - .sync_sg_for_device = loongson_dma_sync_sg_for_device, - .mapping_error = swiotlb_dma_mapping_error, - .dma_supported = swiotlb_dma_supported, - .set_dma_mask = loongson_dma_set_mask -}; - -void __init plat_swiotlb_setup(void) -{ - swiotlb_init(1); - mips_dma_map_ops = &loongson_dma_map_ops; -} diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c deleted file mode 100644 index 6ca632e529dc..000000000000 --- a/arch/mips/loongson/common/early_printk.c +++ /dev/null @@ -1,41 +0,0 @@ -/* early printk support - * - * Copyright (c) 2009 Philippe Vachon - * Copyright (c) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include - -#define PORT(base, offset) (u8 *)(base + offset) - -static inline unsigned int serial_in(unsigned char *base, int offset) -{ - return readb(PORT(base, offset)); -} - -static inline void serial_out(unsigned char *base, int offset, int value) -{ - writeb(value, PORT(base, offset)); -} - -void prom_putchar(char c) -{ - int timeout; - unsigned char *uart_base; - - uart_base = (unsigned char *)_loongson_uart_base[0]; - timeout = 1024; - - while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && - (timeout-- > 0)) - ; - - serial_out(uart_base, UART_TX, c); -} diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c deleted file mode 100644 index 22f04ca2ff3e..000000000000 --- a/arch/mips/loongson/common/env.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Based on Ocelot Linux port, which is - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * Copyright 2003 ICT CAS - * Author: Michael Guo - * - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include - -u32 cpu_clock_freq; -EXPORT_SYMBOL(cpu_clock_freq); -struct efi_memory_map_loongson *loongson_memmap; -struct loongson_system_configuration loongson_sysconf; - -u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; -u64 loongson_chiptemp[MAX_PACKAGES]; -u64 loongson_freqctrl[MAX_PACKAGES]; - -unsigned long long smp_group[4]; - -#define parse_even_earlier(res, option, p) \ -do { \ - unsigned int tmp __maybe_unused; \ - \ - if (strncmp(option, (char *)p, strlen(option)) == 0) \ - tmp = kstrtou32((char *)p + strlen(option"="), 10, &res); \ -} while (0) - -void __init prom_init_env(void) -{ - /* pmon passes arguments in 32bit pointers */ - unsigned int processor_id; - -#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE - int *_prom_envp; - long l; - - /* firmware arguments are initialized in head.S */ - _prom_envp = (int *)fw_arg2; - - l = (long)*_prom_envp; - while (l != 0) { - parse_even_earlier(cpu_clock_freq, "cpuclock", l); - parse_even_earlier(memsize, "memsize", l); - parse_even_earlier(highmemsize, "highmemsize", l); - _prom_envp++; - l = (long)*_prom_envp; - } - if (memsize == 0) - memsize = 256; - pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize); -#else - struct boot_params *boot_p; - struct loongson_params *loongson_p; - struct system_loongson *esys; - struct efi_cpuinfo_loongson *ecpu; - struct irq_source_routing_table *eirq_source; - - /* firmware arguments are initialized in head.S */ - boot_p = (struct boot_params *)fw_arg2; - loongson_p = &(boot_p->efi.smbios.lp); - - esys = (struct system_loongson *) - ((u64)loongson_p + loongson_p->system_offset); - ecpu = (struct efi_cpuinfo_loongson *) - ((u64)loongson_p + loongson_p->cpu_offset); - eirq_source = (struct irq_source_routing_table *) - ((u64)loongson_p + loongson_p->irq_offset); - loongson_memmap = (struct efi_memory_map_loongson *) - ((u64)loongson_p + loongson_p->memory_offset); - - cpu_clock_freq = ecpu->cpu_clock_freq; - loongson_sysconf.cputype = ecpu->cputype; - if (ecpu->cputype == Loongson_3A) { - loongson_sysconf.cores_per_node = 4; - loongson_sysconf.cores_per_package = 4; - smp_group[0] = 0x900000003ff01000; - smp_group[1] = 0x900010003ff01000; - smp_group[2] = 0x900020003ff01000; - smp_group[3] = 0x900030003ff01000; - loongson_chipcfg[0] = 0x900000001fe00180; - loongson_chipcfg[1] = 0x900010001fe00180; - loongson_chipcfg[2] = 0x900020001fe00180; - loongson_chipcfg[3] = 0x900030001fe00180; - loongson_chiptemp[0] = 0x900000001fe0019c; - loongson_chiptemp[1] = 0x900010001fe0019c; - loongson_chiptemp[2] = 0x900020001fe0019c; - loongson_chiptemp[3] = 0x900030001fe0019c; - loongson_sysconf.ht_control_base = 0x90000EFDFB000000; - loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; - } else if (ecpu->cputype == Loongson_3B) { - loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ - loongson_sysconf.cores_per_package = 8; - smp_group[0] = 0x900000003ff01000; - smp_group[1] = 0x900010003ff05000; - smp_group[2] = 0x900020003ff09000; - smp_group[3] = 0x900030003ff0d000; - loongson_chipcfg[0] = 0x900000001fe00180; - loongson_chipcfg[1] = 0x900020001fe00180; - loongson_chipcfg[2] = 0x900040001fe00180; - loongson_chipcfg[3] = 0x900060001fe00180; - loongson_chiptemp[0] = 0x900000001fe0019c; - loongson_chiptemp[1] = 0x900020001fe0019c; - loongson_chiptemp[2] = 0x900040001fe0019c; - loongson_chiptemp[3] = 0x900060001fe0019c; - loongson_freqctrl[0] = 0x900000001fe001d0; - loongson_freqctrl[1] = 0x900020001fe001d0; - loongson_freqctrl[2] = 0x900040001fe001d0; - loongson_freqctrl[3] = 0x900060001fe001d0; - loongson_sysconf.ht_control_base = 0x90001EFDFB000000; - loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG; - } else { - loongson_sysconf.cores_per_node = 1; - loongson_sysconf.cores_per_package = 1; - loongson_chipcfg[0] = 0x900000001fe00180; - } - - loongson_sysconf.nr_cpus = ecpu->nr_cpus; - loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id; - loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask; - if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) - loongson_sysconf.nr_cpus = NR_CPUS; - loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + - loongson_sysconf.cores_per_node - 1) / - loongson_sysconf.cores_per_node; - - loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr; - loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr; - loongson_sysconf.pci_io_base = eirq_source->pci_io_start_addr; - loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; - if (loongson_sysconf.dma_mask_bits < 32 || - loongson_sysconf.dma_mask_bits > 64) - loongson_sysconf.dma_mask_bits = 32; - - loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; - loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; - loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend; - - loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios; - pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", - loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, - loongson_sysconf.vgabios_addr); - - memset(loongson_sysconf.ecname, 0, 32); - if (esys->has_ec) - memcpy(loongson_sysconf.ecname, esys->ec_name, 32); - loongson_sysconf.workarounds |= esys->workarounds; - - loongson_sysconf.nr_uarts = esys->nr_uarts; - if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS) - loongson_sysconf.nr_uarts = 1; - memcpy(loongson_sysconf.uarts, esys->uarts, - sizeof(struct uart_device) * loongson_sysconf.nr_uarts); - - loongson_sysconf.nr_sensors = esys->nr_sensors; - if (loongson_sysconf.nr_sensors > MAX_SENSORS) - loongson_sysconf.nr_sensors = 0; - if (loongson_sysconf.nr_sensors) - memcpy(loongson_sysconf.sensors, esys->sensors, - sizeof(struct sensor_device) * loongson_sysconf.nr_sensors); -#endif - if (cpu_clock_freq == 0) { - processor_id = (¤t_cpu_data)->processor_id; - switch (processor_id & PRID_REV_MASK) { - case PRID_REV_LOONGSON2E: - cpu_clock_freq = 533080000; - break; - case PRID_REV_LOONGSON2F: - cpu_clock_freq = 797000000; - break; - case PRID_REV_LOONGSON3A: - cpu_clock_freq = 900000000; - break; - case PRID_REV_LOONGSON3B_R1: - case PRID_REV_LOONGSON3B_R2: - cpu_clock_freq = 1000000000; - break; - default: - cpu_clock_freq = 100000000; - break; - } - } - pr_info("CpuClock = %u\n", cpu_clock_freq); -} diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c deleted file mode 100644 index 9b987fe98b5b..000000000000 --- a/arch/mips/loongson/common/init.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include - -/* Loongson CPU address windows config space base address */ -unsigned long __maybe_unused _loongson_addrwincfg_base; - -void __init prom_init(void) -{ -#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG - _loongson_addrwincfg_base = (unsigned long) - ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE); -#endif - - prom_init_cmdline(); - prom_init_env(); - - /* init base address of io space */ - set_io_port_base((unsigned long) - ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); - -#ifdef CONFIG_NUMA - prom_init_numa_memory(); -#else - prom_init_memory(); -#endif - - /*init the uart base address */ - prom_init_uart_base(); - register_smp_ops(&loongson3_smp_ops); -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c deleted file mode 100644 index 687003b19b45..000000000000 --- a/arch/mips/loongson/common/irq.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include -/* - * the first level int-handler will jump here if it is a bonito irq - */ -void bonito_irqdispatch(void) -{ - u32 int_status; - int i; - - /* workaround the IO dma problem: let cpu looping to allow DMA finish */ - int_status = LOONGSON_INTISR; - while (int_status & (1 << 10)) { - udelay(1); - int_status = LOONGSON_INTISR; - } - - /* Get pending sources, masked by current enables */ - int_status = LOONGSON_INTISR & LOONGSON_INTEN; - - if (int_status) { - i = __ffs(int_status); - do_IRQ(LOONGSON_IRQ_BASE + i); - } -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending; - - pending = read_c0_cause() & read_c0_status() & ST0_IM; - - /* machine-specific plat_irq_dispatch */ - mach_irq_dispatch(pending); -} - -void __init arch_init_irq(void) -{ - /* - * Clear all of the interrupts while we change the able around a bit. - * int-handler is not on bootstrap - */ - clear_c0_status(ST0_IM | ST0_BEV); - - /* no steer */ - LOONGSON_INTSTEER = 0; - - /* - * Mask out all interrupt by writing "1" to all bit position in - * the interrupt reset reg. - */ - LOONGSON_INTENCLR = ~0; - - /* machine specific irq init */ - mach_init_irq(); -} diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c deleted file mode 100644 index f2807bc662a3..000000000000 --- a/arch/mips/loongson/common/machtype.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * Copyright (c) 2009 Zhang Le - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include - -#include -#include - -/* please ensure the length of the machtype string is less than 50 */ -#define MACHTYPE_LEN 50 - -static const char *system_types[] = { - [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine", - [MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box", - [MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box", - [MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches", - [MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches", - [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f", - [MACH_LEMOTE_NAS] = "lemote-nas-2f", - [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f", - [MACH_LOONGSON_GENERIC] = "generic-loongson-machine", - [MACH_LOONGSON_END] = NULL, -}; - -const char *get_system_type(void) -{ - return system_types[mips_machtype]; -} - -void __weak __init mach_prom_init_machtype(void) -{ -} - -void __init prom_init_machtype(void) -{ - char *p, str[MACHTYPE_LEN + 1]; - int machtype = MACH_LEMOTE_FL2E; - - mips_machtype = LOONGSON_MACHTYPE; - - p = strstr(arcs_cmdline, "machtype="); - if (!p) { - mach_prom_init_machtype(); - return; - } - p += strlen("machtype="); - strncpy(str, p, MACHTYPE_LEN); - str[MACHTYPE_LEN] = '\0'; - p = strstr(str, " "); - if (p) - *p = '\0'; - - for (; system_types[machtype]; machtype++) - if (strstr(system_types[machtype], str)) { - mips_machtype = machtype; - break; - } -} diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c deleted file mode 100644 index b01d52473da8..000000000000 --- a/arch/mips/loongson/common/mem.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -#include - -#include -#include -#include -#include - -#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE - -u32 memsize, highmemsize; - -void __init prom_init_memory(void) -{ - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); - - add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << - 20), BOOT_MEM_RESERVED); - -#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG - { - int bit; - - bit = fls(memsize + highmemsize); - if (bit != ffs(memsize + highmemsize)) - bit += 20; - else - bit = bit + 20 - 1; - - /* set cpu window3 to map CPU to DDR: 2G -> 2G */ - LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul, - 0x80000000ul, (1 << bit)); - mmiowb(); - } -#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ - -#ifdef CONFIG_64BIT - if (highmemsize > 0) - add_memory_region(LOONGSON_HIGHMEM_START, - highmemsize << 20, BOOT_MEM_RAM); - - add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - - LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); - -#endif /* !CONFIG_64BIT */ -} - -#else /* CONFIG_LEFI_FIRMWARE_INTERFACE */ - -void __init prom_init_memory(void) -{ - int i; - u32 node_id; - u32 mem_type; - - /* parse memory information */ - for (i = 0; i < loongson_memmap->nr_map; i++) { - node_id = loongson_memmap->map[i].node_id; - mem_type = loongson_memmap->map[i].mem_type; - - if (node_id == 0) { - switch (mem_type) { - case SYSTEM_RAM_LOW: - add_memory_region(loongson_memmap->map[i].mem_start, - (u64)loongson_memmap->map[i].mem_size << 20, - BOOT_MEM_RAM); - break; - case SYSTEM_RAM_HIGH: - add_memory_region(loongson_memmap->map[i].mem_start, - (u64)loongson_memmap->map[i].mem_size << 20, - BOOT_MEM_RAM); - break; - case MEM_RESERVED: - add_memory_region(loongson_memmap->map[i].mem_start, - (u64)loongson_memmap->map[i].mem_size << 20, - BOOT_MEM_RESERVED); - break; - } - } - } -} - -#endif /* CONFIG_LEFI_FIRMWARE_INTERFACE */ - -/* override of arch/mips/mm/cache.c: __uncached_access */ -int __uncached_access(struct file *file, unsigned long addr) -{ - if (file->f_flags & O_DSYNC) - return 1; - - return addr >= __pa(high_memory) || - ((addr >= LOONGSON_MMIO_MEM_START) && - (addr < LOONGSON_MMIO_MEM_END)); -} - -#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED - -#include -#include -#include - -static unsigned long uca_start, uca_end; - -pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, - unsigned long size, pgprot_t vma_prot) -{ - unsigned long offset = pfn << PAGE_SHIFT; - unsigned long end = offset + size; - - if (__uncached_access(file, offset)) { - if (uca_start && (offset >= uca_start) && - (end <= uca_end)) - return __pgprot((pgprot_val(vma_prot) & - ~_CACHE_MASK) | - _CACHE_UNCACHED_ACCELERATED); - else - return pgprot_noncached(vma_prot); - } - return vma_prot; -} - -static int __init find_vga_mem_init(void) -{ - struct pci_dev *dev = 0; - struct resource *r; - int idx; - - if (uca_start) - return 0; - - for_each_pci_dev(dev) { - if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { - for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) - continue; - if (r->flags & IORESOURCE_IO) - continue; - if (r->flags & IORESOURCE_MEM) { - uca_start = r->start; - uca_end = r->end; - return 0; - } - } - } - } - - return 0; -} - -late_initcall(find_vga_mem_init); -#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */ diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c deleted file mode 100644 index 4e2575643781..000000000000 --- a/arch/mips/loongson/common/pci.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include -#include -#include - -static struct resource loongson_pci_mem_resource = { - .name = "pci memory space", - .start = LOONGSON_PCI_MEM_START, - .end = LOONGSON_PCI_MEM_END, - .flags = IORESOURCE_MEM, -}; - -static struct resource loongson_pci_io_resource = { - .name = "pci io space", - .start = LOONGSON_PCI_IO_START, - .end = IO_SPACE_LIMIT, - .flags = IORESOURCE_IO, -}; - -static struct pci_controller loongson_pci_controller = { - .pci_ops = &loongson_pci_ops, - .io_resource = &loongson_pci_io_resource, - .mem_resource = &loongson_pci_mem_resource, - .mem_offset = 0x00000000UL, - .io_offset = 0x00000000UL, -}; - -static void __init setup_pcimap(void) -{ - /* - * local to PCI mapping for CPU accessing PCI space - * CPU address space [256M,448M] is window for accessing pci space - * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M] - * - * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0 - * [<2G] [384M,448M] [320M,384M] [0M,64M] - */ - LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 | - LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) | - LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) | - LOONGSON_PCIMAP_WIN(0, 0); - - /* - * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M] - */ - LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */ - /* size: 256M, burst transmission, pre-fetch enable, 64bit */ - LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul; - LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful; - LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */ - LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul; - LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */ - LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul; - - /* avoid deadlock of PCI reading/writing lock operation */ - LOONGSON_PCI_ISR4C = 0xd2000001ul; - - /* can not change gnt to break pci transfer when device's gnt not - deassert for some broken device */ - LOONGSON_PXARB_CFG = 0x00fe0105ul; - -#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG - /* - * set cpu addr window2 to map CPU address space to PCI address space - */ - LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC, - LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE); -#endif -} - -extern int sbx00_acpi_init(void); - -static int __init pcibios_init(void) -{ - setup_pcimap(); - - loongson_pci_controller.io_map_base = mips_io_port_base; -#ifdef CONFIG_LEFI_FIRMWARE_INTERFACE - loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr; - loongson_pci_mem_resource.end = loongson_sysconf.pci_mem_end_addr; -#endif - register_pci_controller(&loongson_pci_controller); - -#ifdef CONFIG_CPU_LOONGSON3 - sbx00_acpi_init(); -#endif - - return 0; -} - -arch_initcall(pcibios_init); diff --git a/arch/mips/loongson/common/platform.c b/arch/mips/loongson/common/platform.c deleted file mode 100644 index 0ed38321a9a2..000000000000 --- a/arch/mips/loongson/common/platform.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -static struct platform_device loongson2_cpufreq_device = { - .name = "loongson2_cpufreq", - .id = -1, -}; - -static int __init loongson2_cpufreq_init(void) -{ - struct cpuinfo_mips *c = ¤t_cpu_data; - - /* Only 2F revision and it's successors support CPUFreq */ - if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F) - return platform_device_register(&loongson2_cpufreq_device); - - return -ENODEV; -} - -arch_initcall(loongson2_cpufreq_init); diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c deleted file mode 100644 index a6b67ccfc811..000000000000 --- a/arch/mips/loongson/common/pm.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * loongson-specific suspend support - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#include -#include -#include - -#include -#include - -#include - -static unsigned int __maybe_unused cached_master_mask; /* i8259A */ -static unsigned int __maybe_unused cached_slave_mask; -static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */ - -void arch_suspend_disable_irqs(void) -{ - /* disable all mips events */ - local_irq_disable(); - -#ifdef CONFIG_I8259 - /* disable all events of i8259A */ - cached_slave_mask = inb(PIC_SLAVE_IMR); - cached_master_mask = inb(PIC_MASTER_IMR); - - outb(0xff, PIC_SLAVE_IMR); - inb(PIC_SLAVE_IMR); - outb(0xff, PIC_MASTER_IMR); - inb(PIC_MASTER_IMR); -#endif - /* disable all events of bonito */ - cached_bonito_irq_mask = LOONGSON_INTEN; - LOONGSON_INTENCLR = 0xffff; - (void)LOONGSON_INTENCLR; -} - -void arch_suspend_enable_irqs(void) -{ - /* enable all mips events */ - local_irq_enable(); -#ifdef CONFIG_I8259 - /* only enable the cached events of i8259A */ - outb(cached_slave_mask, PIC_SLAVE_IMR); - outb(cached_master_mask, PIC_MASTER_IMR); -#endif - /* enable all cached events of bonito */ - LOONGSON_INTENSET = cached_bonito_irq_mask; - (void)LOONGSON_INTENSET; -} - -/* - * Setup the board-specific events for waking up loongson from wait mode - */ -void __weak setup_wakeup_events(void) -{ -} - -/* - * Check wakeup events - */ -int __weak wakeup_loongson(void) -{ - return 1; -} - -/* - * If the events are really what we want to wakeup the CPU, wake it up - * otherwise put the CPU asleep again. - */ -static void wait_for_wakeup_events(void) -{ - while (!wakeup_loongson()) - LOONGSON_CHIPCFG(0) &= ~0x7; -} - -/* - * Stop all perf counters - * - * $24 is the control register of Loongson perf counter - */ -static inline void stop_perf_counters(void) -{ - __write_64bit_c0_register($24, 0, 0); -} - - -static void loongson_suspend_enter(void) -{ - static unsigned int cached_cpu_freq; - - /* setup wakeup events via enabling the IRQs */ - setup_wakeup_events(); - - stop_perf_counters(); - - cached_cpu_freq = LOONGSON_CHIPCFG(0); - - /* Put CPU into wait mode */ - LOONGSON_CHIPCFG(0) &= ~0x7; - - /* wait for the given events to wakeup cpu from wait mode */ - wait_for_wakeup_events(); - - LOONGSON_CHIPCFG(0) = cached_cpu_freq; - mmiowb(); -} - -void __weak mach_suspend(void) -{ -} - -void __weak mach_resume(void) -{ -} - -static int loongson_pm_enter(suspend_state_t state) -{ - mach_suspend(); - - /* processor specific suspend */ - loongson_suspend_enter(); - - mach_resume(); - - return 0; -} - -static int loongson_pm_valid_state(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_ON: - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - return 1; - - default: - return 0; - } -} - -static const struct platform_suspend_ops loongson_pm_ops = { - .valid = loongson_pm_valid_state, - .enter = loongson_pm_enter, -}; - -static int __init loongson_pm_init(void) -{ - suspend_set_ops(&loongson_pm_ops); - - return 0; -} -arch_initcall(loongson_pm_init); diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c deleted file mode 100644 index a60715e11306..000000000000 --- a/arch/mips/loongson/common/reset.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * Copyright (C) 2009 Lemote, Inc. - * Author: Zhangjin Wu, wuzhangjin@gmail.com - */ -#include -#include - -#include -#include - -#include -#include - -static inline void loongson_reboot(void) -{ -#ifndef CONFIG_CPU_JUMP_WORKAROUNDS - ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); -#else - void (*func)(void); - - func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4); - - __asm__ __volatile__( - " .set noat \n" - " jr %[func] \n" - " .set at \n" - : /* No outputs */ - : [func] "r" (func)); -#endif -} - -static void loongson_restart(char *command) -{ -#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE - /* do preparation for reboot */ - mach_prepare_reboot(); - - /* reboot via jumping to boot base address */ - loongson_reboot(); -#else - void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr; - - fw_restart(); - while (1) { - if (cpu_wait) - cpu_wait(); - } -#endif -} - -static void loongson_poweroff(void) -{ -#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE - mach_prepare_shutdown(); - unreachable(); -#else - void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; - - fw_poweroff(); - while (1) { - if (cpu_wait) - cpu_wait(); - } -#endif -} - -static void loongson_halt(void) -{ - pr_notice("\n\n** You can safely turn off the power now **\n\n"); - while (1) { - if (cpu_wait) - cpu_wait(); - } -} - -static int __init mips_reboot_setup(void) -{ - _machine_restart = loongson_restart; - _machine_halt = loongson_halt; - pm_power_off = loongson_poweroff; - - return 0; -} - -arch_initcall(mips_reboot_setup); diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c deleted file mode 100644 index b5709af09f7f..000000000000 --- a/arch/mips/loongson/common/rtc.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Lemote Fuloong platform support - * - * Copyright(c) 2010 Arnaud Patard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include - -static struct resource loongson_rtc_resources[] = { - { - .start = RTC_PORT(0), - .end = RTC_PORT(1), - .flags = IORESOURCE_IO, - }, { - .start = RTC_IRQ, - .end = RTC_IRQ, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device loongson_rtc_device = { - .name = "rtc_cmos", - .id = -1, - .resource = loongson_rtc_resources, - .num_resources = ARRAY_SIZE(loongson_rtc_resources), -}; - - -static int __init loongson_rtc_platform_init(void) -{ - platform_device_register(&loongson_rtc_device); - return 0; -} - -device_initcall(loongson_rtc_platform_init); diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c deleted file mode 100644 index c23fa1373729..000000000000 --- a/arch/mips/loongson/common/serial.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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) 2007 Ralf Baechle (ralf@linux-mips.org) - * - * Copyright (C) 2009 Lemote, Inc. - * Author: Yan hua (yanhua@lemote.com) - * Author: Wu Zhangjin (wuzhangjin@gmail.com) - */ - -#include -#include -#include - -#include - -#include -#include - -#define PORT(int, clk) \ -{ \ - .irq = int, \ - .uartclk = clk, \ - .iotype = UPIO_PORT, \ - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ - .regshift = 0, \ -} - -#define PORT_M(int, clk) \ -{ \ - .irq = MIPS_CPU_IRQ_BASE + (int), \ - .uartclk = clk, \ - .iotype = UPIO_MEM, \ - .membase = (void __iomem *)NULL, \ - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ - .regshift = 0, \ -} - -static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = { - [MACH_LOONGSON_UNKNOWN] = {}, - [MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} }, - [MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} }, - [MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} }, - [MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} }, - [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} }, - [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} }, - [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} }, - [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} }, - [MACH_LOONGSON_END] = {}, -}; - -static struct platform_device uart8250_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, -}; - -static int __init serial_init(void) -{ - int i; - unsigned char iotype; - - iotype = uart8250_data[mips_machtype][0].iotype; - - if (UPIO_MEM == iotype) { - uart8250_data[mips_machtype][0].mapbase = - loongson_uart_base[0]; - uart8250_data[mips_machtype][0].membase = - (void __iomem *)_loongson_uart_base[0]; - } - else if (UPIO_PORT == iotype) - uart8250_data[mips_machtype][0].iobase = - loongson_uart_base[0] - LOONGSON_PCIIO_BASE; - - if (loongson_sysconf.uarts[0].uartclk) - uart8250_data[mips_machtype][0].uartclk = - loongson_sysconf.uarts[0].uartclk; - - for (i = 1; i < loongson_sysconf.nr_uarts; i++) { - iotype = loongson_sysconf.uarts[i].iotype; - uart8250_data[mips_machtype][i].iotype = iotype; - loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base; - - if (UPIO_MEM == iotype) { - uart8250_data[mips_machtype][i].irq = - MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset; - uart8250_data[mips_machtype][i].mapbase = - loongson_uart_base[i]; - uart8250_data[mips_machtype][i].membase = - ioremap_nocache(loongson_uart_base[i], 8); - } else if (UPIO_PORT == iotype) { - uart8250_data[mips_machtype][i].irq = - loongson_sysconf.uarts[i].int_offset; - uart8250_data[mips_machtype][i].iobase = - loongson_uart_base[i] - LOONGSON_PCIIO_BASE; - } - - uart8250_data[mips_machtype][i].uartclk = - loongson_sysconf.uarts[i].uartclk; - uart8250_data[mips_machtype][i].flags = - UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; - } - - memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts], - 0, sizeof(struct plat_serial8250_port)); - uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; - - return platform_device_register(&uart8250_device); -} - -device_initcall(serial_init); diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c deleted file mode 100644 index d477dd6bb326..000000000000 --- a/arch/mips/loongson/common/setup.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include -#include - -#include - -#ifdef CONFIG_VT -#include -#include -#endif - -static void wbflush_loongson(void) -{ - asm(".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set mips3\n\t" - "sync\n\t" - "nop\n\t" - ".set\tpop\n\t" - ".set mips0\n\t"); -} - -void (*__wbflush)(void) = wbflush_loongson; -EXPORT_SYMBOL(__wbflush); - -void __init plat_mem_setup(void) -{ -#ifdef CONFIG_VT -#if defined(CONFIG_VGA_CONSOLE) - conswitchp = &vga_con; - - screen_info = (struct screen_info) { - .orig_x = 0, - .orig_y = 25, - .orig_video_cols = 80, - .orig_video_lines = 25, - .orig_video_isVGA = VIDEO_TYPE_VGAC, - .orig_video_points = 16, - }; -#elif defined(CONFIG_DUMMY_CONSOLE) - conswitchp = &dummy_con; -#endif -#endif -} diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c deleted file mode 100644 index e1a5382ad47e..000000000000 --- a/arch/mips/loongson/common/time.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include - -#include -#include - -void __init plat_time_init(void) -{ - /* setup mips r4k timer */ - mips_hpt_frequency = cpu_clock_freq / 2; - -#ifdef CONFIG_RS780_HPET - setup_hpet_timer(); -#else - setup_mfgpt0_timer(); -#endif -} - -void read_persistent_clock(struct timespec *ts) -{ - ts->tv_sec = mc146818_get_cmos_time(); - ts->tv_nsec = 0; -} diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c deleted file mode 100644 index 9de559d58e1f..000000000000 --- a/arch/mips/loongson/common/uart_base.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include - -/* raw */ -unsigned long loongson_uart_base[MAX_UARTS] = {}; -/* ioremapped */ -unsigned long _loongson_uart_base[MAX_UARTS] = {}; - -EXPORT_SYMBOL(loongson_uart_base); -EXPORT_SYMBOL(_loongson_uart_base); - -void prom_init_loongson_uart_base(void) -{ - switch (mips_machtype) { - case MACH_LOONGSON_GENERIC: - /* The CPU provided serial port (CPU) */ - loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0; - break; - case MACH_LEMOTE_FL2E: - loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8; - break; - case MACH_LEMOTE_FL2F: - case MACH_LEMOTE_LL2F: - loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8; - break; - case MACH_LEMOTE_ML2F7: - case MACH_LEMOTE_YL2F89: - case MACH_DEXXON_GDIUM2F10: - case MACH_LEMOTE_NAS: - default: - /* The CPU provided serial port (LPC) */ - loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8; - break; - } - - _loongson_uart_base[0] = - (unsigned long)ioremap_nocache(loongson_uart_base[0], 8); -} diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile deleted file mode 100644 index b7622720c1ad..000000000000 --- a/arch/mips/loongson/fuloong-2e/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for Lemote Fuloong2e mini-PC board. -# - -obj-y += irq.o reset.o diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c deleted file mode 100644 index ef5ec8f3de5f..000000000000 --- a/arch/mips/loongson/fuloong-2e/irq.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include -#include - -#include - -static void i8259_irqdispatch(void) -{ - int irq; - - irq = i8259_irq(); - if (irq >= 0) - do_IRQ(irq); - else - spurious_interrupt(); -} - -asmlinkage void mach_irq_dispatch(unsigned int pending) -{ - if (pending & CAUSEF_IP7) - do_IRQ(MIPS_CPU_IRQ_BASE + 7); - else if (pending & CAUSEF_IP6) /* perf counter loverflow */ - do_perfcnt_IRQ(); - else if (pending & CAUSEF_IP5) - i8259_irqdispatch(); - else if (pending & CAUSEF_IP2) - bonito_irqdispatch(); - else - spurious_interrupt(); -} - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", - .flags = IRQF_NO_THREAD, -}; - -void __init mach_init_irq(void) -{ - /* init all controller - * 0-15 ------> i8259 interrupt - * 16-23 ------> mips cpu interrupt - * 32-63 ------> bonito irq - */ - - /* most bonito irq should be level triggered */ - LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | - LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; - - /* Sets the first-level interrupt dispatcher. */ - mips_cpu_irq_init(); - init_i8259_irqs(); - bonito_irq_init(); - - /* bonito irq at IP2 */ - setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); - /* 8259 irq at IP5 */ - setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); -} diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c deleted file mode 100644 index da4d2ae2a1f8..000000000000 --- a/arch/mips/loongson/fuloong-2e/reset.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Board-specific reboot/shutdown routines - * Copyright (c) 2009 Philippe Vachon - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include - -void mach_prepare_reboot(void) -{ - LOONGSON_GENCFG &= ~(1 << 2); - LOONGSON_GENCFG |= (1 << 2); -} - -void mach_prepare_shutdown(void) -{ -} diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile deleted file mode 100644 index 4f9eaa328a16..000000000000 --- a/arch/mips/loongson/lemote-2f/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for lemote loongson2f family machines -# - -obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o - -# -# Suspend Support -# - -obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o diff --git a/arch/mips/loongson/lemote-2f/clock.c b/arch/mips/loongson/lemote-2f/clock.c deleted file mode 100644 index 462e34d46b4a..000000000000 --- a/arch/mips/loongson/lemote-2f/clock.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology - * Author: Yanhua, yanh@lemote.com - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static LIST_HEAD(clock_list); -static DEFINE_SPINLOCK(clock_lock); -static DEFINE_MUTEX(clock_list_sem); - -/* Minimum CLK support */ -enum { - DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT, - DC_87PT, DC_DISABLE, DC_RESV -}; - -struct cpufreq_frequency_table loongson2_clockmod_table[] = { - {0, DC_RESV, CPUFREQ_ENTRY_INVALID}, - {0, DC_ZERO, CPUFREQ_ENTRY_INVALID}, - {0, DC_25PT, 0}, - {0, DC_37PT, 0}, - {0, DC_50PT, 0}, - {0, DC_62PT, 0}, - {0, DC_75PT, 0}, - {0, DC_87PT, 0}, - {0, DC_DISABLE, 0}, - {0, DC_RESV, CPUFREQ_TABLE_END}, -}; -EXPORT_SYMBOL_GPL(loongson2_clockmod_table); - -static struct clk cpu_clk = { - .name = "cpu_clk", - .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, - .rate = 800000000, -}; - -struct clk *clk_get(struct device *dev, const char *id) -{ - return &cpu_clk; -} -EXPORT_SYMBOL(clk_get); - -static void propagate_rate(struct clk *clk) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &clock_list, node) { - if (likely(clkp->parent != clk)) - continue; - if (likely(clkp->ops && clkp->ops->recalc)) - clkp->ops->recalc(clkp); - if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clkp); - } -} - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int rate_khz = rate / 1000; - struct cpufreq_frequency_table *pos; - int ret = 0; - int regval; - - if (likely(clk->ops && clk->ops->set_rate)) { - unsigned long flags; - - spin_lock_irqsave(&clock_lock, flags); - ret = clk->ops->set_rate(clk, rate, 0); - spin_unlock_irqrestore(&clock_lock, flags); - } - - if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) - propagate_rate(clk); - - cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table) - if (rate_khz == pos->frequency) - break; - if (rate_khz != pos->frequency) - return -ENOTSUPP; - - clk->rate = rate; - - regval = LOONGSON_CHIPCFG(0); - regval = (regval & ~0x7) | (pos->driver_data - 1); - LOONGSON_CHIPCFG(0) = regval; - - return ret; -} -EXPORT_SYMBOL_GPL(clk_set_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (likely(clk->ops && clk->ops->round_rate)) { - unsigned long flags, rounded; - - spin_lock_irqsave(&clock_lock, flags); - rounded = clk->ops->round_rate(clk, rate); - spin_unlock_irqrestore(&clock_lock, flags); - - return rounded; - } - - return rate; -} -EXPORT_SYMBOL_GPL(clk_round_rate); diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.c b/arch/mips/loongson/lemote-2f/ec_kb3310b.c deleted file mode 100644 index 2b666d3a3947..000000000000 --- a/arch/mips/loongson/lemote-2f/ec_kb3310b.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook - * - * Copyright (C) 2008 Lemote Inc. - * Author: liujl , 2008-04-20 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include - -#include "ec_kb3310b.h" - -static DEFINE_SPINLOCK(index_access_lock); -static DEFINE_SPINLOCK(port_access_lock); - -unsigned char ec_read(unsigned short addr) -{ - unsigned char value; - unsigned long flags; - - spin_lock_irqsave(&index_access_lock, flags); - outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); - outb((addr & 0x00ff), EC_IO_PORT_LOW); - value = inb(EC_IO_PORT_DATA); - spin_unlock_irqrestore(&index_access_lock, flags); - - return value; -} -EXPORT_SYMBOL_GPL(ec_read); - -void ec_write(unsigned short addr, unsigned char val) -{ - unsigned long flags; - - spin_lock_irqsave(&index_access_lock, flags); - outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); - outb((addr & 0x00ff), EC_IO_PORT_LOW); - outb(val, EC_IO_PORT_DATA); - /* flush the write action */ - inb(EC_IO_PORT_DATA); - spin_unlock_irqrestore(&index_access_lock, flags); -} -EXPORT_SYMBOL_GPL(ec_write); - -/* - * This function is used for EC command writes and corresponding status queries. - */ -int ec_query_seq(unsigned char cmd) -{ - int timeout; - unsigned char status; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&port_access_lock, flags); - - /* make chip goto reset mode */ - udelay(EC_REG_DELAY); - outb(cmd, EC_CMD_PORT); - udelay(EC_REG_DELAY); - - /* check if the command is received by ec */ - timeout = EC_CMD_TIMEOUT; - status = inb(EC_STS_PORT); - while (timeout-- && (status & (1 << 1))) { - status = inb(EC_STS_PORT); - udelay(EC_REG_DELAY); - } - - spin_unlock_irqrestore(&port_access_lock, flags); - - if (timeout <= 0) { - printk(KERN_ERR "%s: deadable error : timeout...\n", __func__); - ret = -EINVAL; - } else - printk(KERN_INFO - "(%x/%d)ec issued command %d status : 0x%x\n", - timeout, EC_CMD_TIMEOUT - timeout, cmd, status); - - return ret; -} -EXPORT_SYMBOL_GPL(ec_query_seq); - -/* - * Send query command to EC to get the proper event number - */ -int ec_query_event_num(void) -{ - return ec_query_seq(CMD_GET_EVENT_NUM); -} -EXPORT_SYMBOL(ec_query_event_num); - -/* - * Get event number from EC - * - * NOTE: This routine must follow the query_event_num function in the - * interrupt. - */ -int ec_get_event_num(void) -{ - int timeout = 100; - unsigned char value; - unsigned char status; - - udelay(EC_REG_DELAY); - status = inb(EC_STS_PORT); - udelay(EC_REG_DELAY); - while (timeout-- && !(status & (1 << 0))) { - status = inb(EC_STS_PORT); - udelay(EC_REG_DELAY); - } - if (timeout <= 0) { - pr_info("%s: get event number timeout.\n", __func__); - - return -EINVAL; - } - value = inb(EC_DAT_PORT); - udelay(EC_REG_DELAY); - - return value; -} -EXPORT_SYMBOL(ec_get_event_num); diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.h b/arch/mips/loongson/lemote-2f/ec_kb3310b.h deleted file mode 100644 index 5a3f1860d4d2..000000000000 --- a/arch/mips/loongson/lemote-2f/ec_kb3310b.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * KB3310B Embedded Controller - * - * Copyright (C) 2008 Lemote Inc. - * Author: liujl , 2008-03-14 - * - * 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 _EC_KB3310B_H -#define _EC_KB3310B_H - -extern unsigned char ec_read(unsigned short addr); -extern void ec_write(unsigned short addr, unsigned char val); -extern int ec_query_seq(unsigned char cmd); -extern int ec_query_event_num(void); -extern int ec_get_event_num(void); - -typedef int (*sci_handler) (int status); -extern sci_handler yeeloong_report_lid_status; - -#define SCI_IRQ_NUM 0x0A - -/* - * The following registers are determined by the EC index configuration. - * 1, fill the PORT_HIGH as EC register high part. - * 2, fill the PORT_LOW as EC register low part. - * 3, fill the PORT_DATA as EC register write data or get the data from it. - */ -#define EC_IO_PORT_HIGH 0x0381 -#define EC_IO_PORT_LOW 0x0382 -#define EC_IO_PORT_DATA 0x0383 - -/* - * EC delay time is 500us for register and status access - */ -#define EC_REG_DELAY 500 /* unit : us */ -#define EC_CMD_TIMEOUT 0x1000 - -/* - * EC access port for SCI communication - */ -#define EC_CMD_PORT 0x66 -#define EC_STS_PORT 0x66 -#define EC_DAT_PORT 0x62 -#define CMD_INIT_IDLE_MODE 0xdd -#define CMD_EXIT_IDLE_MODE 0xdf -#define CMD_INIT_RESET_MODE 0xd8 -#define CMD_REBOOT_SYSTEM 0x8c -#define CMD_GET_EVENT_NUM 0x84 -#define CMD_PROGRAM_PIECE 0xda - -/* temperature & fan registers */ -#define REG_TEMPERATURE_VALUE 0xF458 -#define REG_FAN_AUTO_MAN_SWITCH 0xF459 -#define BIT_FAN_AUTO 0 -#define BIT_FAN_MANUAL 1 -#define REG_FAN_CONTROL 0xF4D2 -#define BIT_FAN_CONTROL_ON (1 << 0) -#define BIT_FAN_CONTROL_OFF (0 << 0) -#define REG_FAN_STATUS 0xF4DA -#define BIT_FAN_STATUS_ON (1 << 0) -#define BIT_FAN_STATUS_OFF (0 << 0) -#define REG_FAN_SPEED_HIGH 0xFE22 -#define REG_FAN_SPEED_LOW 0xFE23 -#define REG_FAN_SPEED_LEVEL 0xF4CC -/* fan speed divider */ -#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/ - -/* battery registers */ -#define REG_BAT_DESIGN_CAP_HIGH 0xF77D -#define REG_BAT_DESIGN_CAP_LOW 0xF77E -#define REG_BAT_FULLCHG_CAP_HIGH 0xF780 -#define REG_BAT_FULLCHG_CAP_LOW 0xF781 -#define REG_BAT_DESIGN_VOL_HIGH 0xF782 -#define REG_BAT_DESIGN_VOL_LOW 0xF783 -#define REG_BAT_CURRENT_HIGH 0xF784 -#define REG_BAT_CURRENT_LOW 0xF785 -#define REG_BAT_VOLTAGE_HIGH 0xF786 -#define REG_BAT_VOLTAGE_LOW 0xF787 -#define REG_BAT_TEMPERATURE_HIGH 0xF788 -#define REG_BAT_TEMPERATURE_LOW 0xF789 -#define REG_BAT_RELATIVE_CAP_HIGH 0xF492 -#define REG_BAT_RELATIVE_CAP_LOW 0xF493 -#define REG_BAT_VENDOR 0xF4C4 -#define FLAG_BAT_VENDOR_SANYO 0x01 -#define FLAG_BAT_VENDOR_SIMPLO 0x02 -#define REG_BAT_CELL_COUNT 0xF4C6 -#define FLAG_BAT_CELL_3S1P 0x03 -#define FLAG_BAT_CELL_3S2P 0x06 -#define REG_BAT_CHARGE 0xF4A2 -#define FLAG_BAT_CHARGE_DISCHARGE 0x01 -#define FLAG_BAT_CHARGE_CHARGE 0x02 -#define FLAG_BAT_CHARGE_ACPOWER 0x00 -#define REG_BAT_STATUS 0xF4B0 -#define BIT_BAT_STATUS_LOW (1 << 5) -#define BIT_BAT_STATUS_DESTROY (1 << 2) -#define BIT_BAT_STATUS_FULL (1 << 1) -#define BIT_BAT_STATUS_IN (1 << 0) -#define REG_BAT_CHARGE_STATUS 0xF4B1 -#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2) -#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1) -#define REG_BAT_STATE 0xF482 -#define BIT_BAT_STATE_CHARGING (1 << 1) -#define BIT_BAT_STATE_DISCHARGING (1 << 0) -#define REG_BAT_POWER 0xF440 -#define BIT_BAT_POWER_S3 (1 << 2) -#define BIT_BAT_POWER_ON (1 << 1) -#define BIT_BAT_POWER_ACIN (1 << 0) - -/* other registers */ -/* Audio: rd/wr */ -#define REG_AUDIO_VOLUME 0xF46C -#define REG_AUDIO_MUTE 0xF4E7 -#define REG_AUDIO_BEEP 0xF4D0 -/* USB port power or not: rd/wr */ -#define REG_USB0_FLAG 0xF461 -#define REG_USB1_FLAG 0xF462 -#define REG_USB2_FLAG 0xF463 -#define BIT_USB_FLAG_ON 1 -#define BIT_USB_FLAG_OFF 0 -/* LID */ -#define REG_LID_DETECT 0xF4BD -#define BIT_LID_DETECT_ON 1 -#define BIT_LID_DETECT_OFF 0 -/* CRT */ -#define REG_CRT_DETECT 0xF4AD -#define BIT_CRT_DETECT_PLUG 1 -#define BIT_CRT_DETECT_UNPLUG 0 -/* LCD backlight brightness adjust: 9 levels */ -#define REG_DISPLAY_BRIGHTNESS 0xF4F5 -/* Black screen Status */ -#define BIT_DISPLAY_LCD_ON 1 -#define BIT_DISPLAY_LCD_OFF 0 -/* LCD backlight control: off/restore */ -#define REG_BACKLIGHT_CTRL 0xF7BD -#define BIT_BACKLIGHT_ON 1 -#define BIT_BACKLIGHT_OFF 0 -/* Reset the machine auto-clear: rd/wr */ -#define REG_RESET 0xF4EC -#define BIT_RESET_ON 1 -/* Light the led: rd/wr */ -#define REG_LED 0xF4C8 -#define BIT_LED_RED_POWER (1 << 0) -#define BIT_LED_ORANGE_POWER (1 << 1) -#define BIT_LED_GREEN_CHARGE (1 << 2) -#define BIT_LED_RED_CHARGE (1 << 3) -#define BIT_LED_NUMLOCK (1 << 4) -/* Test led mode, all led on/off */ -#define REG_LED_TEST 0xF4C2 -#define BIT_LED_TEST_IN 1 -#define BIT_LED_TEST_OUT 0 -/* Camera on/off */ -#define REG_CAMERA_STATUS 0xF46A -#define BIT_CAMERA_STATUS_ON 1 -#define BIT_CAMERA_STATUS_OFF 0 -#define REG_CAMERA_CONTROL 0xF7B7 -#define BIT_CAMERA_CONTROL_OFF 0 -#define BIT_CAMERA_CONTROL_ON 1 -/* Wlan Status */ -#define REG_WLAN 0xF4FA -#define BIT_WLAN_ON 1 -#define BIT_WLAN_OFF 0 -#define REG_DISPLAY_LCD 0xF79F - -/* SCI Event Number from EC */ -enum { - EVENT_LID = 0x23, /* LID open/close */ - EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */ - EVENT_SLEEP, /* Fn+F1 for entering sleep mode */ - EVENT_OVERTEMP, /* Over-temperature happened */ - EVENT_CRT_DETECT, /* CRT is connected */ - EVENT_CAMERA, /* Camera on/off */ - EVENT_USB_OC2, /* USB2 Over Current occurred */ - EVENT_USB_OC0, /* USB0 Over Current occurred */ - EVENT_BLACK_SCREEN, /* Turn on/off backlight */ - EVENT_AUDIO_MUTE, /* Mute on/off */ - EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */ - EVENT_AC_BAT, /* AC & Battery relative issue */ - EVENT_AUDIO_VOLUME, /* Volume adjust */ - EVENT_WLAN, /* Wlan on/off */ - EVENT_END -}; - -#endif /* !_EC_KB3310B_H */ diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c deleted file mode 100644 index cab5f43e0e29..000000000000 --- a/arch/mips/loongson/lemote-2f/irq.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2007 Lemote Inc. - * Author: Fuxin Zhang, zhangfx@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include -#include -#include - -#include -#include - -#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */ -#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */ -#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */ -#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */ - -#define LOONGSON_INT_BIT_INT0 (1 << 11) -#define LOONGSON_INT_BIT_INT1 (1 << 12) - -/* - * The generic i8259_irq() make the kernel hang on booting. Since we cannot - * get the irq via the IRR directly, we access the ISR instead. - */ -int mach_i8259_irq(void) -{ - int irq, isr; - - irq = -1; - - if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { - raw_spin_lock(&i8259A_lock); - isr = inb(PIC_MASTER_CMD) & - ~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR); - if (!isr) - isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8; - irq = ffs(isr) - 1; - if (unlikely(irq == 7)) { - /* - * This may be a spurious interrupt. - * - * Read the interrupt status register (ISR). If the most - * significant bit is not set then there is no valid - * interrupt. - */ - outb(0x0B, PIC_MASTER_ISR); /* ISR register */ - if (~inb(PIC_MASTER_ISR) & 0x80) - irq = -1; - } - raw_spin_unlock(&i8259A_lock); - } - - return irq; -} -EXPORT_SYMBOL(mach_i8259_irq); - -static void i8259_irqdispatch(void) -{ - int irq; - - irq = mach_i8259_irq(); - if (irq >= 0) - do_IRQ(irq); - else - spurious_interrupt(); -} - -void mach_irq_dispatch(unsigned int pending) -{ - if (pending & CAUSEF_IP7) - do_IRQ(LOONGSON_TIMER_IRQ); - else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */ - do_perfcnt_IRQ(); - bonito_irqdispatch(); - } else if (pending & CAUSEF_IP3) /* CPU UART */ - do_IRQ(LOONGSON_UART_IRQ); - else if (pending & CAUSEF_IP2) /* South Bridge */ - i8259_irqdispatch(); - else - spurious_interrupt(); -} - -static irqreturn_t ip6_action(int cpl, void *dev_id) -{ - return IRQ_HANDLED; -} - -static struct irqaction ip6_irqaction = { - .handler = ip6_action, - .name = "cascade", - .flags = IRQF_SHARED | IRQF_NO_THREAD, -}; - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", - .flags = IRQF_NO_THREAD, -}; - -void __init mach_init_irq(void) -{ - /* init all controller - * 0-15 ------> i8259 interrupt - * 16-23 ------> mips cpu interrupt - * 32-63 ------> bonito irq - */ - - /* setup cs5536 as high level trigger */ - LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; - LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); - - /* Sets the first-level interrupt dispatcher. */ - mips_cpu_irq_init(); - init_i8259_irqs(); - bonito_irq_init(); - - /* setup north bridge irq (bonito) */ - setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction); - /* setup source bridge irq (i8259) */ - setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction); -} diff --git a/arch/mips/loongson/lemote-2f/machtype.c b/arch/mips/loongson/lemote-2f/machtype.c deleted file mode 100644 index b55e6eece5e0..000000000000 --- a/arch/mips/loongson/lemote-2f/machtype.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include - -#include - -void __init mach_prom_init_machtype(void) -{ - /* We share the same kernel image file among Lemote 2F family - * of machines, and provide the machtype= kernel command line - * to users to indicate their machine, this command line will - * be passed by the latest PMON automatically. and fortunately, - * up to now, we can get the machine type from the PMON_VER= - * commandline directly except the NAS machine, In the old - * machines, this will help the users a lot. - * - * If no "machtype=" passed, get machine type from "PMON_VER=". - * PMON_VER=LM8089 Lemote 8.9'' netbook - * LM8101 Lemote 10.1'' netbook - * (The above two netbooks have the same kernel support) - * LM6XXX Lemote FuLoong(2F) box series - * LM9XXX Lemote LynLoong PC series - */ - if (strstr(arcs_cmdline, "PMON_VER=LM")) { - if (strstr(arcs_cmdline, "PMON_VER=LM8")) - mips_machtype = MACH_LEMOTE_YL2F89; - else if (strstr(arcs_cmdline, "PMON_VER=LM6")) - mips_machtype = MACH_LEMOTE_FL2F; - else if (strstr(arcs_cmdline, "PMON_VER=LM9")) - mips_machtype = MACH_LEMOTE_LL2F; - else - mips_machtype = MACH_LEMOTE_NAS; - - strcat(arcs_cmdline, " machtype="); - strcat(arcs_cmdline, get_system_type()); - strcat(arcs_cmdline, " "); - } -} diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c deleted file mode 100644 index cac4d382ea73..000000000000 --- a/arch/mips/loongson/lemote-2f/pm.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Lemote loongson2f family machines' specific suspend support - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include "ec_kb3310b.h" - -#define I8042_KBD_IRQ 1 -#define I8042_CTR_KBDINT 0x01 -#define I8042_CTR_KBDDIS 0x10 - -static unsigned char i8042_ctr; - -static int i8042_enable_kbd_port(void) -{ - if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { - pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port." - "\n"); - return -EIO; - } - - i8042_ctr &= ~I8042_CTR_KBDDIS; - i8042_ctr |= I8042_CTR_KBDINT; - - if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { - i8042_ctr &= ~I8042_CTR_KBDINT; - i8042_ctr |= I8042_CTR_KBDDIS; - pr_err("i8042.c: Failed to enable KBD port.\n"); - - return -EIO; - } - - return 0; -} - -void setup_wakeup_events(void) -{ - int irq_mask; - - switch (mips_machtype) { - case MACH_LEMOTE_ML2F7: - case MACH_LEMOTE_YL2F89: - /* open the keyboard irq in i8259A */ - outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR); - irq_mask = inb(PIC_MASTER_IMR); - - /* enable keyboard port */ - i8042_enable_kbd_port(); - - /* Wakeup CPU via SCI lid open event */ - outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR); - inb(PIC_MASTER_IMR); - outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR); - inb(PIC_SLAVE_IMR); - - break; - - default: - break; - } -} - -static struct delayed_work lid_task; -static int initialized; -/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */ -sci_handler yeeloong_report_lid_status; -EXPORT_SYMBOL(yeeloong_report_lid_status); -static void yeeloong_lid_update_task(struct work_struct *work) -{ - if (yeeloong_report_lid_status) - yeeloong_report_lid_status(BIT_LID_DETECT_ON); -} - -int wakeup_loongson(void) -{ - int irq; - - /* query the interrupt number */ - irq = mach_i8259_irq(); - if (irq < 0) - return 0; - - printk(KERN_INFO "%s: irq = %d\n", __func__, irq); - - if (irq == I8042_KBD_IRQ) - return 1; - else if (irq == SCI_IRQ_NUM) { - int ret, sci_event; - /* query the event number */ - ret = ec_query_seq(CMD_GET_EVENT_NUM); - if (ret < 0) - return 0; - sci_event = ec_get_event_num(); - if (sci_event < 0) - return 0; - if (sci_event == EVENT_LID) { - int lid_status; - /* check the LID status */ - lid_status = ec_read(REG_LID_DETECT); - /* wakeup cpu when people open the LID */ - if (lid_status == BIT_LID_DETECT_ON) { - /* If we call it directly here, the WARNING - * will be sent out by getnstimeofday - * via "WARN_ON(timekeeping_suspended);" - * because we can not schedule in suspend mode. - */ - if (initialized == 0) { - INIT_DELAYED_WORK(&lid_task, - yeeloong_lid_update_task); - initialized = 1; - } - schedule_delayed_work(&lid_task, 1); - return 1; - } - } - } - - return 0; -} - -void __weak mach_suspend(void) -{ - disable_mfgpt0_counter(); -} - -void __weak mach_resume(void) -{ - enable_mfgpt0_counter(); -} diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c deleted file mode 100644 index a26ca7fcd7e0..000000000000 --- a/arch/mips/loongson/lemote-2f/reset.c +++ /dev/null @@ -1,159 +0,0 @@ -/* Board-specific reboot/shutdown routines - * - * Copyright (c) 2009 Philippe Vachon - * - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include - -#include - -#include -#include "ec_kb3310b.h" - -static void reset_cpu(void) -{ - /* - * reset cpu to full speed, this is needed when enabling cpu frequency - * scalling - */ - LOONGSON_CHIPCFG(0) |= 0x7; -} - -/* reset support for fuloong2f */ - -static void fl2f_reboot(void) -{ - reset_cpu(); - - /* send a reset signal to south bridge. - * - * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset - * normally with this reset operation and it will not work in PMON, but - * you can type halt command and then reboot, seems the hardware reset - * logic not work normally. - */ - { - u32 hi, lo; - _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); - lo |= 0x00000001; - _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); - } -} - -static void fl2f_shutdown(void) -{ - u32 hi, lo, val; - int gpio_base; - - /* get gpio base */ - _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); - gpio_base = lo & 0xff00; - - /* make cs5536 gpio13 output enable */ - val = inl(gpio_base + GPIOL_OUT_EN); - val &= ~(1 << (16 + 13)); - val |= (1 << 13); - outl(val, gpio_base + GPIOL_OUT_EN); - mmiowb(); - /* make cs5536 gpio13 output low level voltage. */ - val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13)); - val |= (1 << (16 + 13)); - outl(val, gpio_base + GPIOL_OUT_VAL); - mmiowb(); -} - -/* reset support for yeeloong2f and mengloong2f notebook */ - -static void ml2f_reboot(void) -{ - reset_cpu(); - - /* sending an reset signal to EC(embedded controller) */ - ec_write(REG_RESET, BIT_RESET_ON); -} - -#define yl2f89_reboot ml2f_reboot - -/* menglong(7inches) laptop has different shutdown logic from 8.9inches */ -#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d -#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e -#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f -#define REG_SHUTDOWN_HIGH 0xFC -#define REG_SHUTDOWN_LOW 0x29 -#define BIT_SHUTDOWN_ON (1 << 1) - -static void ml2f_shutdown(void) -{ - u8 val; - u64 i; - - outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH); - outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW); - mmiowb(); - val = inb(EC_SHUTDOWN_IO_PORT_DATA); - outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA); - mmiowb(); - /* need enough wait here... how many microseconds needs? */ - for (i = 0; i < 0x10000; i++) - delay(); - outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA); - mmiowb(); -} - -static void yl2f89_shutdown(void) -{ - /* cpu-gpio0 output low */ - LOONGSON_GPIODATA &= ~0x00000001; - /* cpu-gpio0 as output */ - LOONGSON_GPIOIE &= ~0x00000001; -} - -void mach_prepare_reboot(void) -{ - switch (mips_machtype) { - case MACH_LEMOTE_FL2F: - case MACH_LEMOTE_NAS: - case MACH_LEMOTE_LL2F: - fl2f_reboot(); - break; - case MACH_LEMOTE_ML2F7: - ml2f_reboot(); - break; - case MACH_LEMOTE_YL2F89: - yl2f89_reboot(); - break; - default: - break; - } -} - -void mach_prepare_shutdown(void) -{ - switch (mips_machtype) { - case MACH_LEMOTE_FL2F: - case MACH_LEMOTE_NAS: - case MACH_LEMOTE_LL2F: - fl2f_shutdown(); - break; - case MACH_LEMOTE_ML2F7: - ml2f_shutdown(); - break; - case MACH_LEMOTE_YL2F89: - yl2f89_shutdown(); - break; - default: - break; - } -} diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile deleted file mode 100644 index 622fead5ebc9..000000000000 --- a/arch/mips/loongson/loongson-3/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for Loongson-3 family machines -# -obj-y += irq.o cop2-ex.o platform.o - -obj-$(CONFIG_SMP) += smp.o - -obj-$(CONFIG_NUMA) += numa.o - -obj-$(CONFIG_RS780_HPET) += hpet.o diff --git a/arch/mips/loongson/loongson-3/cop2-ex.c b/arch/mips/loongson/loongson-3/cop2-ex.c deleted file mode 100644 index ea13764d0a03..000000000000 --- a/arch/mips/loongson/loongson-3/cop2-ex.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 Lemote Corporation. - * written by Huacai Chen - * - * based on arch/mips/cavium-octeon/cpu.c - * Copyright (C) 2009 Wind River Systems, - * written by Ralf Baechle - */ -#include -#include -#include - -#include -#include -#include -#include - -static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, - void *data) -{ - int fpu_owned; - int fr = !test_thread_flag(TIF_32BIT_FPREGS); - - switch (action) { - case CU2_EXCEPTION: - preempt_disable(); - fpu_owned = __is_fpu_owner(); - if (!fr) - set_c0_status(ST0_CU1 | ST0_CU2); - else - set_c0_status(ST0_CU1 | ST0_CU2 | ST0_FR); - enable_fpu_hazard(); - KSTK_STATUS(current) |= (ST0_CU1 | ST0_CU2); - if (fr) - KSTK_STATUS(current) |= ST0_FR; - else - KSTK_STATUS(current) &= ~ST0_FR; - /* If FPU is owned, we needn't init or restore fp */ - if (!fpu_owned) { - set_thread_flag(TIF_USEDFPU); - if (!used_math()) { - _init_fpu(current->thread.fpu.fcr31); - set_used_math(); - } else - _restore_fp(current); - } - preempt_enable(); - - return NOTIFY_STOP; /* Don't call default notifier */ - } - - return NOTIFY_OK; /* Let default notifier send signals */ -} - -static int __init loongson_cu2_setup(void) -{ - return cu2_notifier(loongson_cu2_call, 0); -} -early_initcall(loongson_cu2_setup); diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c deleted file mode 100644 index 5c21cd3bd339..000000000000 --- a/arch/mips/loongson/loongson-3/hpet.c +++ /dev/null @@ -1,257 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -#define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000) -#define SMBUS_PCI_REG40 0x40 -#define SMBUS_PCI_REG64 0x64 -#define SMBUS_PCI_REGB4 0xb4 - -static DEFINE_SPINLOCK(hpet_lock); -DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); - -static unsigned int smbus_read(int offset) -{ - return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset); -} - -static void smbus_write(int offset, int data) -{ - *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data; -} - -static void smbus_enable(int offset, int bit) -{ - unsigned int cfg = smbus_read(offset); - - cfg |= bit; - smbus_write(offset, cfg); -} - -static int hpet_read(int offset) -{ - return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset); -} - -static void hpet_write(int offset, int data) -{ - *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data; -} - -static void hpet_start_counter(void) -{ - unsigned int cfg = hpet_read(HPET_CFG); - - cfg |= HPET_CFG_ENABLE; - hpet_write(HPET_CFG, cfg); -} - -static void hpet_stop_counter(void) -{ - unsigned int cfg = hpet_read(HPET_CFG); - - cfg &= ~HPET_CFG_ENABLE; - hpet_write(HPET_CFG, cfg); -} - -static void hpet_reset_counter(void) -{ - hpet_write(HPET_COUNTER, 0); - hpet_write(HPET_COUNTER + 4, 0); -} - -static void hpet_restart_counter(void) -{ - hpet_stop_counter(); - hpet_reset_counter(); - hpet_start_counter(); -} - -static void hpet_enable_legacy_int(void) -{ - /* Do nothing on Loongson-3 */ -} - -static void hpet_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - int cfg = 0; - - spin_lock(&hpet_lock); - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - pr_info("set clock event to periodic mode!\n"); - /* stop counter */ - hpet_stop_counter(); - - /* enables the timer0 to generate a periodic interrupt */ - cfg = hpet_read(HPET_T0_CFG); - cfg &= ~HPET_TN_LEVEL; - cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | - HPET_TN_SETVAL | HPET_TN_32BIT; - hpet_write(HPET_T0_CFG, cfg); - - /* set the comparator */ - hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); - udelay(1); - hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); - - /* start counter */ - hpet_start_counter(); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - cfg = hpet_read(HPET_T0_CFG); - cfg &= ~HPET_TN_ENABLE; - hpet_write(HPET_T0_CFG, cfg); - break; - case CLOCK_EVT_MODE_ONESHOT: - pr_info("set clock event to one shot mode!\n"); - cfg = hpet_read(HPET_T0_CFG); - /* set timer0 type - * 1 : periodic interrupt - * 0 : non-periodic(oneshot) interrupt - */ - cfg &= ~HPET_TN_PERIODIC; - cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; - hpet_write(HPET_T0_CFG, cfg); - break; - case CLOCK_EVT_MODE_RESUME: - hpet_enable_legacy_int(); - break; - } - spin_unlock(&hpet_lock); -} - -static int hpet_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - unsigned int cnt; - int res; - - cnt = hpet_read(HPET_COUNTER); - cnt += delta; - hpet_write(HPET_T0_CMP, cnt); - - res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; - return res; -} - -static irqreturn_t hpet_irq_handler(int irq, void *data) -{ - int is_irq; - struct clock_event_device *cd; - unsigned int cpu = smp_processor_id(); - - is_irq = hpet_read(HPET_STATUS); - if (is_irq & HPET_T0_IRS) { - /* clear the TIMER0 irq status register */ - hpet_write(HPET_STATUS, HPET_T0_IRS); - cd = &per_cpu(hpet_clockevent_device, cpu); - cd->event_handler(cd); - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -static struct irqaction hpet_irq = { - .handler = hpet_irq_handler, - .flags = IRQF_NOBALANCING | IRQF_TIMER, - .name = "hpet", -}; - -/* - * hpet address assignation and irq setting should be done in bios. - * but pmon don't do this, we just setup here directly. - * The operation under is normal. unfortunately, hpet_setup process - * is before pci initialize. - * - * { - * struct pci_dev *pdev; - * - * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); - * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR); - * - * ... - * } - */ -static void hpet_setup(void) -{ - /* set hpet base address */ - smbus_write(SMBUS_PCI_REGB4, HPET_ADDR); - - /* enable decodeing of access to HPET MMIO*/ - smbus_enable(SMBUS_PCI_REG40, (1 << 28)); - - /* HPET irq enable */ - smbus_enable(SMBUS_PCI_REG64, (1 << 10)); - - hpet_enable_legacy_int(); -} - -void __init setup_hpet_timer(void) -{ - unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - - hpet_setup(); - - cd = &per_cpu(hpet_clockevent_device, cpu); - cd->name = "hpet"; - cd->rating = 320; - cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; - cd->set_mode = hpet_set_mode; - cd->set_next_event = hpet_next_event; - cd->irq = HPET_T0_IRQ; - cd->cpumask = cpumask_of(cpu); - clockevent_set_clock(cd, HPET_FREQ); - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = 5000; - - clockevents_register_device(cd); - setup_irq(HPET_T0_IRQ, &hpet_irq); - pr_info("hpet clock event device register\n"); -} - -static cycle_t hpet_read_counter(struct clocksource *cs) -{ - return (cycle_t)hpet_read(HPET_COUNTER); -} - -static void hpet_suspend(struct clocksource *cs) -{ -} - -static void hpet_resume(struct clocksource *cs) -{ - hpet_setup(); - hpet_restart_counter(); -} - -static struct clocksource csrc_hpet = { - .name = "hpet", - /* mips clocksource rating is less than 300, so hpet is better. */ - .rating = 300, - .read = hpet_read_counter, - .mask = CLOCKSOURCE_MASK(32), - /* oneshot mode work normal with this flag */ - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - .suspend = hpet_suspend, - .resume = hpet_resume, - .mult = 0, - .shift = 10, -}; - -int __init init_hpet_clocksource(void) -{ - csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift); - return clocksource_register_hz(&csrc_hpet, HPET_FREQ); -} - -arch_initcall(init_hpet_clocksource); diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c deleted file mode 100644 index 0f75b6b3d218..000000000000 --- a/arch/mips/loongson/loongson-3/irq.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include - -#include "smp.h" - -unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; - -static void ht_irqdispatch(void) -{ - unsigned int i, irq; - - irq = LOONGSON_HT1_INT_VECTOR(0); - LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */ - - for (i = 0; i < ARRAY_SIZE(ht_irq); i++) { - if (irq & (0x1 << ht_irq[i])) - do_IRQ(ht_irq[i]); - } -} - -void mach_irq_dispatch(unsigned int pending) -{ - if (pending & CAUSEF_IP7) - do_IRQ(LOONGSON_TIMER_IRQ); -#if defined(CONFIG_SMP) - else if (pending & CAUSEF_IP6) - loongson3_ipi_interrupt(NULL); -#endif - else if (pending & CAUSEF_IP3) - ht_irqdispatch(); - else if (pending & CAUSEF_IP2) - do_IRQ(LOONGSON_UART_IRQ); - else { - pr_err("%s : spurious interrupt\n", __func__); - spurious_interrupt(); - } -} - -static struct irqaction cascade_irqaction = { - .handler = no_action, - .flags = IRQF_NO_SUSPEND, - .name = "cascade", -}; - -static inline void mask_loongson_irq(struct irq_data *d) -{ - clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); - irq_disable_hazard(); - - /* Workaround: UART IRQ may deliver to any core */ - if (d->irq == LOONGSON_UART_IRQ) { - int cpu = smp_processor_id(); - int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; - int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; - u64 intenclr_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_INTENCLR); - u64 introuter_lpc_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_LPC); - - *(volatile u32 *)intenclr_addr = 1 << 10; - *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq == LOONGSON_UART_IRQ) { - int cpu = smp_processor_id(); - int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; - int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; - u64 intenset_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_INTENSET); - u64 introuter_lpc_addr = smp_group[node_id] | - (u64)(&LOONGSON_INT_ROUTER_LPC); - - *(volatile u32 *)intenset_addr = 1 << 10; - *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq - MIPS_CPU_IRQ_BASE)); - irq_enable_hazard(); -} - - /* For MIPS IRQs which shared by all cores */ -static struct irq_chip loongson_irq_chip = { - .name = "Loongson", - .irq_ack = mask_loongson_irq, - .irq_mask = mask_loongson_irq, - .irq_mask_ack = mask_loongson_irq, - .irq_unmask = unmask_loongson_irq, - .irq_eoi = unmask_loongson_irq, -}; - -void irq_router_init(void) -{ - int i; - - /* route LPC int to cpu core0 int 0 */ - LOONGSON_INT_ROUTER_LPC = - LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); - /* route HT1 int0 ~ int7 to cpu core0 INT1*/ - for (i = 0; i < 8; i++) - LOONGSON_INT_ROUTER_HT1(i) = - LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); - /* enable HT1 interrupt */ - LOONGSON_HT1_INTN_EN(0) = 0xffffffff; - /* enable router interrupt intenset */ - LOONGSON_INT_ROUTER_INTENSET = - LOONGSON_INT_ROUTER_INTEN | (0xffff << 16) | 0x1 << 10; -} - -void __init mach_init_irq(void) -{ - clear_c0_status(ST0_IM | ST0_BEV); - - irq_router_init(); - mips_cpu_irq_init(); - init_i8259_irqs(); - irq_set_chip_and_handler(LOONGSON_UART_IRQ, - &loongson_irq_chip, handle_level_irq); - - /* setup HT1 irq */ - setup_irq(LOONGSON_HT1_IRQ, &cascade_irqaction); - - set_c0_status(STATUSF_IP2 | STATUSF_IP6); -} - -#ifdef CONFIG_HOTPLUG_CPU - -void fixup_irqs(void) -{ - irq_cpu_offline(); - clear_c0_status(ST0_IM); -} - -#endif diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c deleted file mode 100644 index 12d14ed48778..000000000000 --- a/arch/mips/loongson/loongson-3/numa.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & - * Insititute of Computing Technology - * Author: Xiang Gao, gaoxiang@ict.ac.cn - * Huacai Chen, chenhc@lemote.com - * Xiaofu Meng, Shuangshuang Zhang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct node_data prealloc__node_data[MAX_NUMNODES]; -unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; -EXPORT_SYMBOL(__node_distances); -struct node_data *__node_data[MAX_NUMNODES]; -EXPORT_SYMBOL(__node_data); - -static void enable_lpa(void) -{ - unsigned long value; - - value = __read_32bit_c0_register($16, 3); - value |= 0x00000080; - __write_32bit_c0_register($16, 3, value); - value = __read_32bit_c0_register($16, 3); - pr_info("CP0_Config3: CP0 16.3 (0x%lx)\n", value); - - value = __read_32bit_c0_register($5, 1); - value |= 0x20000000; - __write_32bit_c0_register($5, 1, value); - value = __read_32bit_c0_register($5, 1); - pr_info("CP0_PageGrain: CP0 5.1 (0x%lx)\n", value); -} - -static void cpu_node_probe(void) -{ - int i; - - nodes_clear(node_possible_map); - nodes_clear(node_online_map); - for (i = 0; i < loongson_sysconf.nr_nodes; i++) { - node_set_state(num_online_nodes(), N_POSSIBLE); - node_set_online(num_online_nodes()); - } - - pr_info("NUMA: Discovered %d cpus on %d nodes\n", - loongson_sysconf.nr_cpus, num_online_nodes()); -} - -static int __init compute_node_distance(int row, int col) -{ - int package_row = row * loongson_sysconf.cores_per_node / - loongson_sysconf.cores_per_package; - int package_col = col * loongson_sysconf.cores_per_node / - loongson_sysconf.cores_per_package; - - if (col == row) - return 0; - else if (package_row == package_col) - return 40; - else - return 100; -} - -static void __init init_topology_matrix(void) -{ - int row, col; - - for (row = 0; row < MAX_NUMNODES; row++) - for (col = 0; col < MAX_NUMNODES; col++) - __node_distances[row][col] = -1; - - for_each_online_node(row) { - for_each_online_node(col) { - __node_distances[row][col] = - compute_node_distance(row, col); - } - } -} - -static unsigned long nid_to_addroffset(unsigned int nid) -{ - unsigned long result; - switch (nid) { - case 0: - default: - result = NODE0_ADDRSPACE_OFFSET; - break; - case 1: - result = NODE1_ADDRSPACE_OFFSET; - break; - case 2: - result = NODE2_ADDRSPACE_OFFSET; - break; - case 3: - result = NODE3_ADDRSPACE_OFFSET; - break; - } - return result; -} - -static void __init szmem(unsigned int node) -{ - u32 i, mem_type; - static unsigned long num_physpages = 0; - u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; - - /* Parse memory information and activate */ - for (i = 0; i < loongson_memmap->nr_map; i++) { - node_id = loongson_memmap->map[i].node_id; - if (node_id != node) - continue; - - mem_type = loongson_memmap->map[i].mem_type; - mem_size = loongson_memmap->map[i].mem_size; - mem_start = loongson_memmap->map[i].mem_start; - - switch (mem_type) { - case SYSTEM_RAM_LOW: - start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; - node_psize = (mem_size << 20) >> PAGE_SHIFT; - end_pfn = start_pfn + node_psize; - num_physpages += node_psize; - pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", - (u32)node_id, mem_type, mem_start, mem_size); - pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", - start_pfn, end_pfn, num_physpages); - add_memory_region((node_id << 44) + mem_start, - (u64)mem_size << 20, BOOT_MEM_RAM); - memblock_add_node(PFN_PHYS(start_pfn), - PFN_PHYS(end_pfn - start_pfn), node); - break; - case SYSTEM_RAM_HIGH: - start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; - node_psize = (mem_size << 20) >> PAGE_SHIFT; - end_pfn = start_pfn + node_psize; - num_physpages += node_psize; - pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", - (u32)node_id, mem_type, mem_start, mem_size); - pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", - start_pfn, end_pfn, num_physpages); - add_memory_region((node_id << 44) + mem_start, - (u64)mem_size << 20, BOOT_MEM_RAM); - memblock_add_node(PFN_PHYS(start_pfn), - PFN_PHYS(end_pfn - start_pfn), node); - break; - case MEM_RESERVED: - pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", - (u32)node_id, mem_type, mem_start, mem_size); - add_memory_region((node_id << 44) + mem_start, - (u64)mem_size << 20, BOOT_MEM_RESERVED); - memblock_reserve(((node_id << 44) + mem_start), - mem_size << 20); - break; - } - } -} - -static void __init node_mem_init(unsigned int node) -{ - unsigned long bootmap_size; - unsigned long node_addrspace_offset; - unsigned long start_pfn, end_pfn, freepfn; - - node_addrspace_offset = nid_to_addroffset(node); - pr_info("Node%d's addrspace_offset is 0x%lx\n", - node, node_addrspace_offset); - - get_pfn_range_for_nid(node, &start_pfn, &end_pfn); - freepfn = start_pfn; - if (node == 0) - freepfn = PFN_UP(__pa_symbol(&_end)); /* kernel end address */ - pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx, freepfn=0x%lx\n", - node, start_pfn, end_pfn, freepfn); - - __node_data[node] = prealloc__node_data + node; - - NODE_DATA(node)->bdata = &bootmem_node_data[node]; - NODE_DATA(node)->node_start_pfn = start_pfn; - NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; - - bootmap_size = init_bootmem_node(NODE_DATA(node), freepfn, - start_pfn, end_pfn); - free_bootmem_with_active_regions(node, end_pfn); - if (node == 0) /* used by finalize_initrd() */ - max_low_pfn = end_pfn; - - /* This is reserved for the kernel and bdata->node_bootmem_map */ - reserve_bootmem_node(NODE_DATA(node), start_pfn << PAGE_SHIFT, - ((freepfn - start_pfn) << PAGE_SHIFT) + bootmap_size, - BOOTMEM_DEFAULT); - - if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { - /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */ - reserve_bootmem_node(NODE_DATA(node), - (node_addrspace_offset | 0xff800000), - 8 << 20, BOOTMEM_DEFAULT); - } - - sparse_memory_present_with_active_regions(node); -} - -static __init void prom_meminit(void) -{ - unsigned int node, cpu, active_cpu = 0; - - cpu_node_probe(); - init_topology_matrix(); - - for (node = 0; node < loongson_sysconf.nr_nodes; node++) { - if (node_online(node)) { - szmem(node); - node_mem_init(node); - cpumask_clear(&__node_data[(node)]->cpumask); - } - } - for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { - node = cpu / loongson_sysconf.cores_per_node; - if (node >= num_online_nodes()) - node = 0; - - if (loongson_sysconf.reserved_cpus_mask & (1<cpumask); - pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); - - active_cpu++; - } -} - -void __init paging_init(void) -{ - unsigned node; - unsigned long zones_size[MAX_NR_ZONES] = {0, }; - - pagetable_init(); - - for_each_online_node(node) { - unsigned long start_pfn, end_pfn; - - get_pfn_range_for_nid(node, &start_pfn, &end_pfn); - - if (end_pfn > max_low_pfn) - max_low_pfn = end_pfn; - } -#ifdef CONFIG_ZONE_DMA32 - zones_size[ZONE_DMA32] = MAX_DMA32_PFN; -#endif - zones_size[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(zones_size); -} - -void __init mem_init(void) -{ - high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); - free_all_bootmem(); - setup_zero_pages(); /* This comes from node 0 */ - mem_init_print_info(NULL); -} - -/* All PCI device belongs to logical Node-0 */ -int pcibus_to_node(struct pci_bus *bus) -{ - return 0; -} -EXPORT_SYMBOL(pcibus_to_node); - -void __init prom_init_numa_memory(void) -{ - enable_lpa(); - prom_meminit(); -} -EXPORT_SYMBOL(prom_init_numa_memory); diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c deleted file mode 100644 index 25a97cc0ee33..000000000000 --- a/arch/mips/loongson/loongson-3/platform.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2009 Lemote Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com - * Xiang Yu, xiangy@lemote.com - * Chen Huacai, chenhc@lemote.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include - -static int __init loongson3_platform_init(void) -{ - int i; - struct platform_device *pdev; - - if (loongson_sysconf.ecname[0] != '\0') - platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0); - - for (i = 0; i < loongson_sysconf.nr_sensors; i++) { - if (loongson_sysconf.sensors[i].type > SENSOR_FAN) - continue; - - pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); - pdev->name = loongson_sysconf.sensors[i].name; - pdev->id = loongson_sysconf.sensors[i].id; - pdev->dev.platform_data = &loongson_sysconf.sensors[i]; - platform_device_register(pdev); - } - - return 0; -} - -arch_initcall(loongson3_platform_init); diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c deleted file mode 100644 index 509877c6e9d9..000000000000 --- a/arch/mips/loongson/loongson-3/smp.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (C) 2010, 2011, 2012, Lemote, Inc. - * Author: Chen Huacai, chenhc@lemote.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "smp.h" - -DEFINE_PER_CPU(int, cpu_state); -DEFINE_PER_CPU(uint32_t, core0_c0count); - -static void *ipi_set0_regs[16]; -static void *ipi_clear0_regs[16]; -static void *ipi_status0_regs[16]; -static void *ipi_en0_regs[16]; -static void *ipi_mailbox_buf[16]; - -/* read a 32bit value from ipi register */ -#define loongson3_ipi_read32(addr) readl(addr) -/* read a 64bit value from ipi register */ -#define loongson3_ipi_read64(addr) readq(addr) -/* write a 32bit value to ipi register */ -#define loongson3_ipi_write32(action, addr) \ - do { \ - writel(action, addr); \ - __wbflush(); \ - } while (0) -/* write a 64bit value to ipi register */ -#define loongson3_ipi_write64(action, addr) \ - do { \ - writeq(action, addr); \ - __wbflush(); \ - } while (0) - -static void ipi_set0_regs_init(void) -{ - ipi_set0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0); - ipi_set0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0); - ipi_set0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0); - ipi_set0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0); - ipi_set0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0); -} - -static void ipi_clear0_regs_init(void) -{ - ipi_clear0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0); - ipi_clear0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0); - ipi_clear0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0); - ipi_clear0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0); - ipi_clear0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0); -} - -static void ipi_status0_regs_init(void) -{ - ipi_status0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0); - ipi_status0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0); - ipi_status0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0); - ipi_status0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0); - ipi_status0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0); -} - -static void ipi_en0_regs_init(void) -{ - ipi_en0_regs[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0); - ipi_en0_regs[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0); - ipi_en0_regs[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0); - ipi_en0_regs[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0); - ipi_en0_regs[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0); -} - -static void ipi_mailbox_buf_init(void) -{ - ipi_mailbox_buf[0] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[1] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[2] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[3] = (void *) - (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[4] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[5] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[6] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[7] = (void *) - (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[8] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[9] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[10] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[11] = (void *) - (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF); - ipi_mailbox_buf[12] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF); - ipi_mailbox_buf[13] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF); - ipi_mailbox_buf[14] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF); - ipi_mailbox_buf[15] = (void *) - (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF); -} - -/* - * Simple enough, just poke the appropriate ipi register - */ -static void loongson3_send_ipi_single(int cpu, unsigned int action) -{ - loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]); -} - -static void -loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) -{ - unsigned int i; - - for_each_cpu(i, mask) - loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]); -} - -void loongson3_ipi_interrupt(struct pt_regs *regs) -{ - int i, cpu = smp_processor_id(); - unsigned int action, c0count; - - /* Load the ipi register to figure out what we're supposed to do */ - action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); - - /* Clear the ipi register to clear the interrupt */ - loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]); - - if (action & SMP_RESCHEDULE_YOURSELF) - scheduler_ipi(); - - if (action & SMP_CALL_FUNCTION) - smp_call_function_interrupt(); - - if (action & SMP_ASK_C0COUNT) { - BUG_ON(cpu != 0); - c0count = read_c0_count(); - for (i = 1; i < num_possible_cpus(); i++) - per_cpu(core0_c0count, i) = c0count; - } -} - -#define MAX_LOOPS 1111 -/* - * SMP init and finish on secondary CPUs - */ -static void loongson3_init_secondary(void) -{ - int i; - uint32_t initcount; - unsigned int cpu = smp_processor_id(); - unsigned int imask = STATUSF_IP7 | STATUSF_IP6 | - STATUSF_IP3 | STATUSF_IP2; - - /* Set interrupt mask, but don't enable */ - change_c0_status(ST0_IM, imask); - - for (i = 0; i < num_possible_cpus(); i++) - loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); - - per_cpu(cpu_state, cpu) = CPU_ONLINE; - cpu_data[cpu].core = - cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; - cpu_data[cpu].package = - cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; - - i = 0; - __this_cpu_write(core0_c0count, 0); - loongson3_send_ipi_single(0, SMP_ASK_C0COUNT); - while (!__this_cpu_read(core0_c0count)) { - i++; - cpu_relax(); - } - - if (i > MAX_LOOPS) - i = MAX_LOOPS; - initcount = __this_cpu_read(core0_c0count) + i; - write_c0_count(initcount); -} - -static void loongson3_smp_finish(void) -{ - int cpu = smp_processor_id(); - - write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); - local_irq_enable(); - loongson3_ipi_write64(0, - (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); - pr_info("CPU#%d finished, CP0_ST=%x\n", - smp_processor_id(), read_c0_status()); -} - -static void __init loongson3_smp_setup(void) -{ - int i = 0, num = 0; /* i: physical id, num: logical id */ - - init_cpu_possible(cpu_none_mask); - - /* For unified kernel, NR_CPUS is the maximum possible value, - * loongson_sysconf.nr_cpus is the really present value */ - while (i < loongson_sysconf.nr_cpus) { - if (loongson_sysconf.reserved_cpus_mask & (1< - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include -#include - -#define LS1X_INTC_REG(n, x) \ - ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x))) - -#define LS1X_INTC_INTISR(n) LS1X_INTC_REG(n, 0x0) -#define LS1X_INTC_INTIEN(n) LS1X_INTC_REG(n, 0x4) -#define LS1X_INTC_INTSET(n) LS1X_INTC_REG(n, 0x8) -#define LS1X_INTC_INTCLR(n) LS1X_INTC_REG(n, 0xc) -#define LS1X_INTC_INTPOL(n) LS1X_INTC_REG(n, 0x10) -#define LS1X_INTC_INTEDGE(n) LS1X_INTC_REG(n, 0x14) - -static void ls1x_irq_ack(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) - | (1 << bit), LS1X_INTC_INTCLR(n)); -} - -static void ls1x_irq_mask(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) - & ~(1 << bit), LS1X_INTC_INTIEN(n)); -} - -static void ls1x_irq_mask_ack(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) - & ~(1 << bit), LS1X_INTC_INTIEN(n)); - __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) - | (1 << bit), LS1X_INTC_INTCLR(n)); -} - -static void ls1x_irq_unmask(struct irq_data *d) -{ - unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; - unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; - - __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) - | (1 << bit), LS1X_INTC_INTIEN(n)); -} - -static struct irq_chip ls1x_irq_chip = { - .name = "LS1X-INTC", - .irq_ack = ls1x_irq_ack, - .irq_mask = ls1x_irq_mask, - .irq_mask_ack = ls1x_irq_mask_ack, - .irq_unmask = ls1x_irq_unmask, -}; - -static void ls1x_irq_dispatch(int n) -{ - u32 int_status, irq; - - /* Get pending sources, masked by current enables */ - int_status = __raw_readl(LS1X_INTC_INTISR(n)) & - __raw_readl(LS1X_INTC_INTIEN(n)); - - if (int_status) { - irq = LS1X_IRQ(n, __ffs(int_status)); - do_IRQ(irq); - } -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending; - - pending = read_c0_cause() & read_c0_status() & ST0_IM; - - if (pending & CAUSEF_IP7) - do_IRQ(TIMER_IRQ); - else if (pending & CAUSEF_IP2) - ls1x_irq_dispatch(0); /* INT0 */ - else if (pending & CAUSEF_IP3) - ls1x_irq_dispatch(1); /* INT1 */ - else if (pending & CAUSEF_IP4) - ls1x_irq_dispatch(2); /* INT2 */ - else if (pending & CAUSEF_IP5) - ls1x_irq_dispatch(3); /* INT3 */ - else if (pending & CAUSEF_IP6) - ls1x_irq_dispatch(4); /* INT4 */ - else - spurious_interrupt(); - -} - -struct irqaction cascade_irqaction = { - .handler = no_action, - .name = "cascade", - .flags = IRQF_NO_THREAD, -}; - -static void __init ls1x_irq_init(int base) -{ - int n; - - /* Disable interrupts and clear pending, - * setup all IRQs as high level triggered - */ - for (n = 0; n < 4; n++) { - __raw_writel(0x0, LS1X_INTC_INTIEN(n)); - __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n)); - __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n)); - /* set DMA0, DMA1 and DMA2 to edge trigger */ - __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n)); - } - - - for (n = base; n < LS1X_IRQS; n++) { - irq_set_chip_and_handler(n, &ls1x_irq_chip, - handle_level_irq); - } - - setup_irq(INT0_IRQ, &cascade_irqaction); - setup_irq(INT1_IRQ, &cascade_irqaction); - setup_irq(INT2_IRQ, &cascade_irqaction); - setup_irq(INT3_IRQ, &cascade_irqaction); -} - -void __init arch_init_irq(void) -{ - mips_cpu_irq_init(); - ls1x_irq_init(LS1X_IRQ_BASE); -} diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c deleted file mode 100644 index ddf1d4cbf31e..000000000000 --- a/arch/mips/loongson1/common/platform.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* 8250/16550 compatible UART */ -#define LS1X_UART(_id) \ - { \ - .mapbase = LS1X_UART ## _id ## _BASE, \ - .irq = LS1X_UART ## _id ## _IRQ, \ - .iotype = UPIO_MEM, \ - .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \ - .type = PORT_16550A, \ - } - -static struct plat_serial8250_port ls1x_serial8250_pdata[] = { - LS1X_UART(0), - LS1X_UART(1), - LS1X_UART(2), - LS1X_UART(3), - {}, -}; - -struct platform_device ls1x_uart_pdev = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = ls1x_serial8250_pdata, - }, -}; - -void __init ls1x_serial_setup(struct platform_device *pdev) -{ - struct clk *clk; - struct plat_serial8250_port *p; - - clk = clk_get(&pdev->dev, pdev->name); - if (IS_ERR(clk)) { - pr_err("unable to get %s clock, err=%ld", - pdev->name, PTR_ERR(clk)); - return; - } - clk_prepare_enable(clk); - - for (p = pdev->dev.platform_data; p->flags != 0; ++p) - p->uartclk = clk_get_rate(clk); -} - -/* CPUFreq */ -static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { - .clk_name = "cpu_clk", - .osc_clk_name = "osc_33m_clk", - .max_freq = 266 * 1000, - .min_freq = 33 * 1000, -}; - -struct platform_device ls1x_cpufreq_pdev = { - .name = "ls1x-cpufreq", - .dev = { - .platform_data = &ls1x_cpufreq_pdata, - }, -}; - -/* Synopsys Ethernet GMAC */ -static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { - .phy_mask = 0, -}; - -static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { - .pbl = 1, -}; - -int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) -{ - struct plat_stmmacenet_data *plat_dat = NULL; - u32 val; - - val = __raw_readl(LS1X_MUX_CTRL1); - - plat_dat = dev_get_platdata(&pdev->dev); - if (plat_dat->bus_id) { - __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | - GMAC1_USE_UART0, LS1X_MUX_CTRL0); - switch (plat_dat->interface) { - case PHY_INTERFACE_MODE_RGMII: - val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); - break; - case PHY_INTERFACE_MODE_MII: - val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); - break; - default: - pr_err("unsupported mii mode %d\n", - plat_dat->interface); - return -ENOTSUPP; - } - val &= ~GMAC1_SHUT; - } else { - switch (plat_dat->interface) { - case PHY_INTERFACE_MODE_RGMII: - val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); - break; - case PHY_INTERFACE_MODE_MII: - val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); - break; - default: - pr_err("unsupported mii mode %d\n", - plat_dat->interface); - return -ENOTSUPP; - } - val &= ~GMAC0_SHUT; - } - __raw_writel(val, LS1X_MUX_CTRL1); - - return 0; -} - -static struct plat_stmmacenet_data ls1x_eth0_pdata = { - .bus_id = 0, - .phy_addr = -1, - .interface = PHY_INTERFACE_MODE_MII, - .mdio_bus_data = &ls1x_mdio_bus_data, - .dma_cfg = &ls1x_eth_dma_cfg, - .has_gmac = 1, - .tx_coe = 1, - .init = ls1x_eth_mux_init, -}; - -static struct resource ls1x_eth0_resources[] = { - [0] = { - .start = LS1X_GMAC0_BASE, - .end = LS1X_GMAC0_BASE + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "macirq", - .start = LS1X_GMAC0_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device ls1x_eth0_pdev = { - .name = "stmmaceth", - .id = 0, - .num_resources = ARRAY_SIZE(ls1x_eth0_resources), - .resource = ls1x_eth0_resources, - .dev = { - .platform_data = &ls1x_eth0_pdata, - }, -}; - -static struct plat_stmmacenet_data ls1x_eth1_pdata = { - .bus_id = 1, - .phy_addr = -1, - .interface = PHY_INTERFACE_MODE_MII, - .mdio_bus_data = &ls1x_mdio_bus_data, - .dma_cfg = &ls1x_eth_dma_cfg, - .has_gmac = 1, - .tx_coe = 1, - .init = ls1x_eth_mux_init, -}; - -static struct resource ls1x_eth1_resources[] = { - [0] = { - .start = LS1X_GMAC1_BASE, - .end = LS1X_GMAC1_BASE + SZ_64K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "macirq", - .start = LS1X_GMAC1_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device ls1x_eth1_pdev = { - .name = "stmmaceth", - .id = 1, - .num_resources = ARRAY_SIZE(ls1x_eth1_resources), - .resource = ls1x_eth1_resources, - .dev = { - .platform_data = &ls1x_eth1_pdata, - }, -}; - -/* USB EHCI */ -static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); - -static struct resource ls1x_ehci_resources[] = { - [0] = { - .start = LS1X_EHCI_BASE, - .end = LS1X_EHCI_BASE + SZ_32K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = LS1X_EHCI_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct usb_ehci_pdata ls1x_ehci_pdata = { -}; - -struct platform_device ls1x_ehci_pdev = { - .name = "ehci-platform", - .id = -1, - .num_resources = ARRAY_SIZE(ls1x_ehci_resources), - .resource = ls1x_ehci_resources, - .dev = { - .dma_mask = &ls1x_ehci_dmamask, - .platform_data = &ls1x_ehci_pdata, - }, -}; - -/* Real Time Clock */ -struct platform_device ls1x_rtc_pdev = { - .name = "ls1x-rtc", - .id = -1, -}; diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c deleted file mode 100644 index 68600980ea49..000000000000 --- a/arch/mips/loongson1/common/prom.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * Modified from arch/mips/pnx833x/common/prom.c. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include -#include - -int prom_argc; -char **prom_argv, **prom_envp; -unsigned long memsize, highmemsize; - -char *prom_getenv(char *envname) -{ - char **env = prom_envp; - int i; - - i = strlen(envname); - - while (*env) { - if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=') - return *env + i + 1; - env++; - } - - return 0; -} - -static inline unsigned long env_or_default(char *env, unsigned long dfl) -{ - char *str = prom_getenv(env); - return str ? simple_strtol(str, 0, 0) : dfl; -} - -void __init prom_init_cmdline(void) -{ - char *c = &(arcs_cmdline[0]); - int i; - - for (i = 1; i < prom_argc; i++) { - strcpy(c, prom_argv[i]); - c += strlen(prom_argv[i]); - if (i < prom_argc - 1) - *c++ = ' '; - } - *c = 0; -} - -void __init prom_init(void) -{ - void __iomem *uart_base; - prom_argc = fw_arg0; - prom_argv = (char **)fw_arg1; - prom_envp = (char **)fw_arg2; - - prom_init_cmdline(); - - memsize = env_or_default("memsize", DEFAULT_MEMSIZE); - highmemsize = env_or_default("highmemsize", 0x0); - - if (strstr(arcs_cmdline, "console=ttyS3")) - uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f); - else if (strstr(arcs_cmdline, "console=ttyS2")) - uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f); - else if (strstr(arcs_cmdline, "console=ttyS1")) - uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f); - else - uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f); - setup_8250_early_printk_port((unsigned long)uart_base, 0, 0); -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c deleted file mode 100644 index c41e4ca56ab4..000000000000 --- a/arch/mips/loongson1/common/reset.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include - -#include - -static void __iomem *wdt_base; - -static void ls1x_halt(void) -{ - while (1) { - if (cpu_wait) - cpu_wait(); - } -} - -static void ls1x_restart(char *command) -{ - __raw_writel(0x1, wdt_base + WDT_EN); - __raw_writel(0x1, wdt_base + WDT_TIMER); - __raw_writel(0x1, wdt_base + WDT_SET); - - ls1x_halt(); -} - -static void ls1x_power_off(void) -{ - ls1x_halt(); -} - -static int __init ls1x_reboot_setup(void) -{ - wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); - if (!wdt_base) - panic("Failed to remap watchdog registers"); - - _machine_restart = ls1x_restart; - _machine_halt = ls1x_halt; - pm_power_off = ls1x_power_off; - - return 0; -} - -arch_initcall(ls1x_reboot_setup); diff --git a/arch/mips/loongson1/common/setup.c b/arch/mips/loongson1/common/setup.c deleted file mode 100644 index 62f41afee241..000000000000 --- a/arch/mips/loongson1/common/setup.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include - -#include - -void __init plat_mem_setup(void) -{ - add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); -} - -const char *get_system_type(void) -{ - unsigned int processor_id = (¤t_cpu_data)->processor_id; - - switch (processor_id & PRID_REV_MASK) { - case PRID_REV_LOONGSON1B: - return "LOONGSON LS1B"; - default: - return "LOONGSON (unknown)"; - } -} diff --git a/arch/mips/loongson1/common/time.c b/arch/mips/loongson1/common/time.c deleted file mode 100644 index df0f850d6a5f..000000000000 --- a/arch/mips/loongson1/common/time.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2014 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include - -#include -#include - -#ifdef CONFIG_CEVT_CSRC_LS1X - -#if defined(CONFIG_TIMER_USE_PWM1) -#define LS1X_TIMER_BASE LS1X_PWM1_BASE -#define LS1X_TIMER_IRQ LS1X_PWM1_IRQ - -#elif defined(CONFIG_TIMER_USE_PWM2) -#define LS1X_TIMER_BASE LS1X_PWM2_BASE -#define LS1X_TIMER_IRQ LS1X_PWM2_IRQ - -#elif defined(CONFIG_TIMER_USE_PWM3) -#define LS1X_TIMER_BASE LS1X_PWM3_BASE -#define LS1X_TIMER_IRQ LS1X_PWM3_IRQ - -#else -#define LS1X_TIMER_BASE LS1X_PWM0_BASE -#define LS1X_TIMER_IRQ LS1X_PWM0_IRQ -#endif - -DEFINE_RAW_SPINLOCK(ls1x_timer_lock); - -static void __iomem *timer_base; -static uint32_t ls1x_jiffies_per_tick; - -static inline void ls1x_pwmtimer_set_period(uint32_t period) -{ - __raw_writel(period, timer_base + PWM_HRC); - __raw_writel(period, timer_base + PWM_LRC); -} - -static inline void ls1x_pwmtimer_restart(void) -{ - __raw_writel(0x0, timer_base + PWM_CNT); - __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); -} - -void __init ls1x_pwmtimer_init(void) -{ - timer_base = ioremap(LS1X_TIMER_BASE, 0xf); - if (!timer_base) - panic("Failed to remap timer registers"); - - ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); - - ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); - ls1x_pwmtimer_restart(); -} - -static cycle_t ls1x_clocksource_read(struct clocksource *cs) -{ - unsigned long flags; - int count; - u32 jifs; - static int old_count; - static u32 old_jifs; - - raw_spin_lock_irqsave(&ls1x_timer_lock, flags); - /* - * Although our caller may have the read side of xtime_lock, - * this is now a seqlock, and we are cheating in this routine - * by having side effects on state that we cannot undo if - * there is a collision on the seqlock and our caller has to - * retry. (Namely, old_jifs and old_count.) So we must treat - * jiffies as volatile despite the lock. We read jiffies - * before latching the timer count to guarantee that although - * the jiffies value might be older than the count (that is, - * the counter may underflow between the last point where - * jiffies was incremented and the point where we latch the - * count), it cannot be newer. - */ - jifs = jiffies; - /* read the count */ - count = __raw_readl(timer_base + PWM_CNT); - - /* - * It's possible for count to appear to go the wrong way for this - * reason: - * - * The timer counter underflows, but we haven't handled the resulting - * interrupt and incremented jiffies yet. - * - * Previous attempts to handle these cases intelligently were buggy, so - * we just do the simple thing now. - */ - if (count < old_count && jifs == old_jifs) - count = old_count; - - old_count = count; - old_jifs = jifs; - - raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags); - - return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count; -} - -static struct clocksource ls1x_clocksource = { - .name = "ls1x-pwmtimer", - .read = ls1x_clocksource_read, - .mask = CLOCKSOURCE_MASK(24), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) -{ - struct clock_event_device *cd = devid; - - ls1x_pwmtimer_restart(); - cd->event_handler(cd); - - return IRQ_HANDLED; -} - -static void ls1x_clockevent_set_mode(enum clock_event_mode mode, - struct clock_event_device *cd) -{ - raw_spin_lock(&ls1x_timer_lock); - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); - ls1x_pwmtimer_restart(); - case CLOCK_EVT_MODE_RESUME: - __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); - break; - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_SHUTDOWN: - __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, - timer_base + PWM_CTRL); - break; - default: - break; - } - raw_spin_unlock(&ls1x_timer_lock); -} - -static int ls1x_clockevent_set_next(unsigned long evt, - struct clock_event_device *cd) -{ - raw_spin_lock(&ls1x_timer_lock); - ls1x_pwmtimer_set_period(evt); - ls1x_pwmtimer_restart(); - raw_spin_unlock(&ls1x_timer_lock); - - return 0; -} - -static struct clock_event_device ls1x_clockevent = { - .name = "ls1x-pwmtimer", - .features = CLOCK_EVT_FEAT_PERIODIC, - .rating = 300, - .irq = LS1X_TIMER_IRQ, - .set_next_event = ls1x_clockevent_set_next, - .set_mode = ls1x_clockevent_set_mode, -}; - -static struct irqaction ls1x_pwmtimer_irqaction = { - .name = "ls1x-pwmtimer", - .handler = ls1x_clockevent_isr, - .dev_id = &ls1x_clockevent, - .flags = IRQF_PERCPU | IRQF_TIMER, -}; - -static void __init ls1x_time_init(void) -{ - struct clock_event_device *cd = &ls1x_clockevent; - int ret; - - if (!mips_hpt_frequency) - panic("Invalid timer clock rate"); - - ls1x_pwmtimer_init(); - - clockevent_set_clock(cd, mips_hpt_frequency); - cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); - cd->cpumask = cpumask_of(smp_processor_id()); - clockevents_register_device(cd); - - ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; - ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); - if (ret) - panic(KERN_ERR "Failed to register clocksource: %d\n", ret); - - setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); -} -#endif /* CONFIG_CEVT_CSRC_LS1X */ - -void __init plat_time_init(void) -{ - struct clk *clk = NULL; - - /* initialize LS1X clocks */ - ls1x_clk_init(); - -#ifdef CONFIG_CEVT_CSRC_LS1X - /* setup LS1X PWM timer */ - clk = clk_get(NULL, "ls1x_pwmtimer"); - if (IS_ERR(clk)) - panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); - - mips_hpt_frequency = clk_get_rate(clk); - ls1x_time_init(); -#else - /* setup mips r4k timer */ - clk = clk_get(NULL, "cpu_clk"); - if (IS_ERR(clk)) - panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); - - mips_hpt_frequency = clk_get_rate(clk) / 2; -#endif /* CONFIG_CEVT_CSRC_LS1X */ -} diff --git a/arch/mips/loongson1/ls1b/Makefile b/arch/mips/loongson1/ls1b/Makefile deleted file mode 100644 index 891eac482b82..000000000000 --- a/arch/mips/loongson1/ls1b/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for loongson1B based machines. -# - -obj-y += board.o diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c deleted file mode 100644 index 58daeea25739..000000000000 --- a/arch/mips/loongson1/ls1b/board.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011 Zhang, Keguang - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include - -static struct platform_device *ls1b_platform_devices[] __initdata = { - &ls1x_uart_pdev, - &ls1x_cpufreq_pdev, - &ls1x_eth0_pdev, - &ls1x_eth1_pdev, - &ls1x_ehci_pdev, - &ls1x_rtc_pdev, -}; - -static int __init ls1b_platform_init(void) -{ - int err; - - ls1x_serial_setup(&ls1x_uart_pdev); - - err = platform_add_devices(ls1b_platform_devices, - ARRAY_SIZE(ls1b_platform_devices)); - return err; -} - -arch_initcall(ls1b_platform_init); diff --git a/arch/mips/loongson32/Kconfig b/arch/mips/loongson32/Kconfig new file mode 100644 index 000000000000..7704f20529d6 --- /dev/null +++ b/arch/mips/loongson32/Kconfig @@ -0,0 +1,61 @@ +if MACH_LOONGSON32 + +choice + prompt "Machine Type" + +config LOONGSON1_LS1B + bool "Loongson LS1B board" + select CEVT_R4K if !MIPS_EXTERNAL_TIMER + select CSRC_R4K if !MIPS_EXTERNAL_TIMER + select SYS_HAS_CPU_LOONGSON1B + select DMA_NONCOHERENT + select BOOT_ELF32 + select IRQ_MIPS_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_MIPS16 + select SYS_HAS_EARLY_PRINTK + select USE_GENERIC_EARLY_PRINTK_8250 + select COMMON_CLK + +endchoice + +menuconfig CEVT_CSRC_LS1X + bool "Use PWM Timer for clockevent/clocksource" + select MIPS_EXTERNAL_TIMER + depends on CPU_LOONGSON1 + help + This option changes the default clockevent/clocksource to PWM Timer, + and is required by Loongson1 CPUFreq support. + + If unsure, say N. + +choice + prompt "Select clockevent/clocksource" + depends on CEVT_CSRC_LS1X + default TIMER_USE_PWM0 + +config TIMER_USE_PWM0 + bool "Use PWM Timer 0" + help + Use PWM Timer 0 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM1 + bool "Use PWM Timer 1" + help + Use PWM Timer 1 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM2 + bool "Use PWM Timer 2" + help + Use PWM Timer 2 as the default clockevent/clocksourcer. + +config TIMER_USE_PWM3 + bool "Use PWM Timer 3" + help + Use PWM Timer 3 as the default clockevent/clocksourcer. + +endchoice + +endif # MACH_LOONGSON32 diff --git a/arch/mips/loongson32/Makefile b/arch/mips/loongson32/Makefile new file mode 100644 index 000000000000..5f4bd6e071ca --- /dev/null +++ b/arch/mips/loongson32/Makefile @@ -0,0 +1,11 @@ +# +# Common code for all Loongson 1 based systems +# + +obj-$(CONFIG_MACH_LOONGSON32) += common/ + +# +# Loongson LS1B board +# + +obj-$(CONFIG_LOONGSON1_LS1B) += ls1b/ diff --git a/arch/mips/loongson32/Platform b/arch/mips/loongson32/Platform new file mode 100644 index 000000000000..ebb6dc290f0a --- /dev/null +++ b/arch/mips/loongson32/Platform @@ -0,0 +1,7 @@ +cflags-$(CONFIG_CPU_LOONGSON1) += \ + $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ + -Wa,-mips32r2 -Wa,--trap + +platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ +cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32 +load-$(CONFIG_LOONGSON1_LS1B) += 0xffffffff80100000 diff --git a/arch/mips/loongson32/common/Makefile b/arch/mips/loongson32/common/Makefile new file mode 100644 index 000000000000..723b4ce3b8f0 --- /dev/null +++ b/arch/mips/loongson32/common/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for common code of loongson1 based machines. +# + +obj-y += time.o irq.o platform.o prom.o reset.o setup.o diff --git a/arch/mips/loongson32/common/irq.c b/arch/mips/loongson32/common/irq.c new file mode 100644 index 000000000000..455a7704a90f --- /dev/null +++ b/arch/mips/loongson32/common/irq.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include +#include + +#define LS1X_INTC_REG(n, x) \ + ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x))) + +#define LS1X_INTC_INTISR(n) LS1X_INTC_REG(n, 0x0) +#define LS1X_INTC_INTIEN(n) LS1X_INTC_REG(n, 0x4) +#define LS1X_INTC_INTSET(n) LS1X_INTC_REG(n, 0x8) +#define LS1X_INTC_INTCLR(n) LS1X_INTC_REG(n, 0xc) +#define LS1X_INTC_INTPOL(n) LS1X_INTC_REG(n, 0x10) +#define LS1X_INTC_INTEDGE(n) LS1X_INTC_REG(n, 0x14) + +static void ls1x_irq_ack(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) + | (1 << bit), LS1X_INTC_INTCLR(n)); +} + +static void ls1x_irq_mask(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) + & ~(1 << bit), LS1X_INTC_INTIEN(n)); +} + +static void ls1x_irq_mask_ack(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) + & ~(1 << bit), LS1X_INTC_INTIEN(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n)) + | (1 << bit), LS1X_INTC_INTCLR(n)); +} + +static void ls1x_irq_unmask(struct irq_data *d) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n)) + | (1 << bit), LS1X_INTC_INTIEN(n)); +} + +static struct irq_chip ls1x_irq_chip = { + .name = "LS1X-INTC", + .irq_ack = ls1x_irq_ack, + .irq_mask = ls1x_irq_mask, + .irq_mask_ack = ls1x_irq_mask_ack, + .irq_unmask = ls1x_irq_unmask, +}; + +static void ls1x_irq_dispatch(int n) +{ + u32 int_status, irq; + + /* Get pending sources, masked by current enables */ + int_status = __raw_readl(LS1X_INTC_INTISR(n)) & + __raw_readl(LS1X_INTC_INTIEN(n)); + + if (int_status) { + irq = LS1X_IRQ(n, __ffs(int_status)); + do_IRQ(irq); + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & CAUSEF_IP7) + do_IRQ(TIMER_IRQ); + else if (pending & CAUSEF_IP2) + ls1x_irq_dispatch(0); /* INT0 */ + else if (pending & CAUSEF_IP3) + ls1x_irq_dispatch(1); /* INT1 */ + else if (pending & CAUSEF_IP4) + ls1x_irq_dispatch(2); /* INT2 */ + else if (pending & CAUSEF_IP5) + ls1x_irq_dispatch(3); /* INT3 */ + else if (pending & CAUSEF_IP6) + ls1x_irq_dispatch(4); /* INT4 */ + else + spurious_interrupt(); + +} + +struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", + .flags = IRQF_NO_THREAD, +}; + +static void __init ls1x_irq_init(int base) +{ + int n; + + /* Disable interrupts and clear pending, + * setup all IRQs as high level triggered + */ + for (n = 0; n < 4; n++) { + __raw_writel(0x0, LS1X_INTC_INTIEN(n)); + __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n)); + __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n)); + /* set DMA0, DMA1 and DMA2 to edge trigger */ + __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n)); + } + + + for (n = base; n < LS1X_IRQS; n++) { + irq_set_chip_and_handler(n, &ls1x_irq_chip, + handle_level_irq); + } + + setup_irq(INT0_IRQ, &cascade_irqaction); + setup_irq(INT1_IRQ, &cascade_irqaction); + setup_irq(INT2_IRQ, &cascade_irqaction); + setup_irq(INT3_IRQ, &cascade_irqaction); +} + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); + ls1x_irq_init(LS1X_IRQ_BASE); +} diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c new file mode 100644 index 000000000000..ddf1d4cbf31e --- /dev/null +++ b/arch/mips/loongson32/common/platform.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* 8250/16550 compatible UART */ +#define LS1X_UART(_id) \ + { \ + .mapbase = LS1X_UART ## _id ## _BASE, \ + .irq = LS1X_UART ## _id ## _IRQ, \ + .iotype = UPIO_MEM, \ + .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \ + .type = PORT_16550A, \ + } + +static struct plat_serial8250_port ls1x_serial8250_pdata[] = { + LS1X_UART(0), + LS1X_UART(1), + LS1X_UART(2), + LS1X_UART(3), + {}, +}; + +struct platform_device ls1x_uart_pdev = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = ls1x_serial8250_pdata, + }, +}; + +void __init ls1x_serial_setup(struct platform_device *pdev) +{ + struct clk *clk; + struct plat_serial8250_port *p; + + clk = clk_get(&pdev->dev, pdev->name); + if (IS_ERR(clk)) { + pr_err("unable to get %s clock, err=%ld", + pdev->name, PTR_ERR(clk)); + return; + } + clk_prepare_enable(clk); + + for (p = pdev->dev.platform_data; p->flags != 0; ++p) + p->uartclk = clk_get_rate(clk); +} + +/* CPUFreq */ +static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { + .clk_name = "cpu_clk", + .osc_clk_name = "osc_33m_clk", + .max_freq = 266 * 1000, + .min_freq = 33 * 1000, +}; + +struct platform_device ls1x_cpufreq_pdev = { + .name = "ls1x-cpufreq", + .dev = { + .platform_data = &ls1x_cpufreq_pdata, + }, +}; + +/* Synopsys Ethernet GMAC */ +static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { + .phy_mask = 0, +}; + +static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { + .pbl = 1, +}; + +int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) +{ + struct plat_stmmacenet_data *plat_dat = NULL; + u32 val; + + val = __raw_readl(LS1X_MUX_CTRL1); + + plat_dat = dev_get_platdata(&pdev->dev); + if (plat_dat->bus_id) { + __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | + GMAC1_USE_UART0, LS1X_MUX_CTRL0); + switch (plat_dat->interface) { + case PHY_INTERFACE_MODE_RGMII: + val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); + break; + case PHY_INTERFACE_MODE_MII: + val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); + break; + default: + pr_err("unsupported mii mode %d\n", + plat_dat->interface); + return -ENOTSUPP; + } + val &= ~GMAC1_SHUT; + } else { + switch (plat_dat->interface) { + case PHY_INTERFACE_MODE_RGMII: + val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); + break; + case PHY_INTERFACE_MODE_MII: + val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); + break; + default: + pr_err("unsupported mii mode %d\n", + plat_dat->interface); + return -ENOTSUPP; + } + val &= ~GMAC0_SHUT; + } + __raw_writel(val, LS1X_MUX_CTRL1); + + return 0; +} + +static struct plat_stmmacenet_data ls1x_eth0_pdata = { + .bus_id = 0, + .phy_addr = -1, + .interface = PHY_INTERFACE_MODE_MII, + .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, + .has_gmac = 1, + .tx_coe = 1, + .init = ls1x_eth_mux_init, +}; + +static struct resource ls1x_eth0_resources[] = { + [0] = { + .start = LS1X_GMAC0_BASE, + .end = LS1X_GMAC0_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "macirq", + .start = LS1X_GMAC0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device ls1x_eth0_pdev = { + .name = "stmmaceth", + .id = 0, + .num_resources = ARRAY_SIZE(ls1x_eth0_resources), + .resource = ls1x_eth0_resources, + .dev = { + .platform_data = &ls1x_eth0_pdata, + }, +}; + +static struct plat_stmmacenet_data ls1x_eth1_pdata = { + .bus_id = 1, + .phy_addr = -1, + .interface = PHY_INTERFACE_MODE_MII, + .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, + .has_gmac = 1, + .tx_coe = 1, + .init = ls1x_eth_mux_init, +}; + +static struct resource ls1x_eth1_resources[] = { + [0] = { + .start = LS1X_GMAC1_BASE, + .end = LS1X_GMAC1_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "macirq", + .start = LS1X_GMAC1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device ls1x_eth1_pdev = { + .name = "stmmaceth", + .id = 1, + .num_resources = ARRAY_SIZE(ls1x_eth1_resources), + .resource = ls1x_eth1_resources, + .dev = { + .platform_data = &ls1x_eth1_pdata, + }, +}; + +/* USB EHCI */ +static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); + +static struct resource ls1x_ehci_resources[] = { + [0] = { + .start = LS1X_EHCI_BASE, + .end = LS1X_EHCI_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = LS1X_EHCI_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct usb_ehci_pdata ls1x_ehci_pdata = { +}; + +struct platform_device ls1x_ehci_pdev = { + .name = "ehci-platform", + .id = -1, + .num_resources = ARRAY_SIZE(ls1x_ehci_resources), + .resource = ls1x_ehci_resources, + .dev = { + .dma_mask = &ls1x_ehci_dmamask, + .platform_data = &ls1x_ehci_pdata, + }, +}; + +/* Real Time Clock */ +struct platform_device ls1x_rtc_pdev = { + .name = "ls1x-rtc", + .id = -1, +}; diff --git a/arch/mips/loongson32/common/prom.c b/arch/mips/loongson32/common/prom.c new file mode 100644 index 000000000000..68600980ea49 --- /dev/null +++ b/arch/mips/loongson32/common/prom.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * Modified from arch/mips/pnx833x/common/prom.c. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +unsigned long memsize, highmemsize; + +char *prom_getenv(char *envname) +{ + char **env = prom_envp; + int i; + + i = strlen(envname); + + while (*env) { + if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=') + return *env + i + 1; + env++; + } + + return 0; +} + +static inline unsigned long env_or_default(char *env, unsigned long dfl) +{ + char *str = prom_getenv(env); + return str ? simple_strtol(str, 0, 0) : dfl; +} + +void __init prom_init_cmdline(void) +{ + char *c = &(arcs_cmdline[0]); + int i; + + for (i = 1; i < prom_argc; i++) { + strcpy(c, prom_argv[i]); + c += strlen(prom_argv[i]); + if (i < prom_argc - 1) + *c++ = ' '; + } + *c = 0; +} + +void __init prom_init(void) +{ + void __iomem *uart_base; + prom_argc = fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; + + prom_init_cmdline(); + + memsize = env_or_default("memsize", DEFAULT_MEMSIZE); + highmemsize = env_or_default("highmemsize", 0x0); + + if (strstr(arcs_cmdline, "console=ttyS3")) + uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f); + else if (strstr(arcs_cmdline, "console=ttyS2")) + uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f); + else if (strstr(arcs_cmdline, "console=ttyS1")) + uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f); + else + uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f); + setup_8250_early_printk_port((unsigned long)uart_base, 0, 0); +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/loongson32/common/reset.c b/arch/mips/loongson32/common/reset.c new file mode 100644 index 000000000000..c41e4ca56ab4 --- /dev/null +++ b/arch/mips/loongson32/common/reset.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include + +static void __iomem *wdt_base; + +static void ls1x_halt(void) +{ + while (1) { + if (cpu_wait) + cpu_wait(); + } +} + +static void ls1x_restart(char *command) +{ + __raw_writel(0x1, wdt_base + WDT_EN); + __raw_writel(0x1, wdt_base + WDT_TIMER); + __raw_writel(0x1, wdt_base + WDT_SET); + + ls1x_halt(); +} + +static void ls1x_power_off(void) +{ + ls1x_halt(); +} + +static int __init ls1x_reboot_setup(void) +{ + wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); + if (!wdt_base) + panic("Failed to remap watchdog registers"); + + _machine_restart = ls1x_restart; + _machine_halt = ls1x_halt; + pm_power_off = ls1x_power_off; + + return 0; +} + +arch_initcall(ls1x_reboot_setup); diff --git a/arch/mips/loongson32/common/setup.c b/arch/mips/loongson32/common/setup.c new file mode 100644 index 000000000000..62f41afee241 --- /dev/null +++ b/arch/mips/loongson32/common/setup.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +#include + +void __init plat_mem_setup(void) +{ + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); +} + +const char *get_system_type(void) +{ + unsigned int processor_id = (¤t_cpu_data)->processor_id; + + switch (processor_id & PRID_REV_MASK) { + case PRID_REV_LOONGSON1B: + return "LOONGSON LS1B"; + default: + return "LOONGSON (unknown)"; + } +} diff --git a/arch/mips/loongson32/common/time.c b/arch/mips/loongson32/common/time.c new file mode 100644 index 000000000000..df0f850d6a5f --- /dev/null +++ b/arch/mips/loongson32/common/time.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2014 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include +#include + +#ifdef CONFIG_CEVT_CSRC_LS1X + +#if defined(CONFIG_TIMER_USE_PWM1) +#define LS1X_TIMER_BASE LS1X_PWM1_BASE +#define LS1X_TIMER_IRQ LS1X_PWM1_IRQ + +#elif defined(CONFIG_TIMER_USE_PWM2) +#define LS1X_TIMER_BASE LS1X_PWM2_BASE +#define LS1X_TIMER_IRQ LS1X_PWM2_IRQ + +#elif defined(CONFIG_TIMER_USE_PWM3) +#define LS1X_TIMER_BASE LS1X_PWM3_BASE +#define LS1X_TIMER_IRQ LS1X_PWM3_IRQ + +#else +#define LS1X_TIMER_BASE LS1X_PWM0_BASE +#define LS1X_TIMER_IRQ LS1X_PWM0_IRQ +#endif + +DEFINE_RAW_SPINLOCK(ls1x_timer_lock); + +static void __iomem *timer_base; +static uint32_t ls1x_jiffies_per_tick; + +static inline void ls1x_pwmtimer_set_period(uint32_t period) +{ + __raw_writel(period, timer_base + PWM_HRC); + __raw_writel(period, timer_base + PWM_LRC); +} + +static inline void ls1x_pwmtimer_restart(void) +{ + __raw_writel(0x0, timer_base + PWM_CNT); + __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); +} + +void __init ls1x_pwmtimer_init(void) +{ + timer_base = ioremap(LS1X_TIMER_BASE, 0xf); + if (!timer_base) + panic("Failed to remap timer registers"); + + ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); + + ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); + ls1x_pwmtimer_restart(); +} + +static cycle_t ls1x_clocksource_read(struct clocksource *cs) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + raw_spin_lock_irqsave(&ls1x_timer_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + /* read the count */ + count = __raw_readl(timer_base + PWM_CNT); + + /* + * It's possible for count to appear to go the wrong way for this + * reason: + * + * The timer counter underflows, but we haven't handled the resulting + * interrupt and incremented jiffies yet. + * + * Previous attempts to handle these cases intelligently were buggy, so + * we just do the simple thing now. + */ + if (count < old_count && jifs == old_jifs) + count = old_count; + + old_count = count; + old_jifs = jifs; + + raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags); + + return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count; +} + +static struct clocksource ls1x_clocksource = { + .name = "ls1x-pwmtimer", + .read = ls1x_clocksource_read, + .mask = CLOCKSOURCE_MASK(24), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) +{ + struct clock_event_device *cd = devid; + + ls1x_pwmtimer_restart(); + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static void ls1x_clockevent_set_mode(enum clock_event_mode mode, + struct clock_event_device *cd) +{ + raw_spin_lock(&ls1x_timer_lock); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); + ls1x_pwmtimer_restart(); + case CLOCK_EVT_MODE_RESUME: + __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); + break; + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_SHUTDOWN: + __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, + timer_base + PWM_CTRL); + break; + default: + break; + } + raw_spin_unlock(&ls1x_timer_lock); +} + +static int ls1x_clockevent_set_next(unsigned long evt, + struct clock_event_device *cd) +{ + raw_spin_lock(&ls1x_timer_lock); + ls1x_pwmtimer_set_period(evt); + ls1x_pwmtimer_restart(); + raw_spin_unlock(&ls1x_timer_lock); + + return 0; +} + +static struct clock_event_device ls1x_clockevent = { + .name = "ls1x-pwmtimer", + .features = CLOCK_EVT_FEAT_PERIODIC, + .rating = 300, + .irq = LS1X_TIMER_IRQ, + .set_next_event = ls1x_clockevent_set_next, + .set_mode = ls1x_clockevent_set_mode, +}; + +static struct irqaction ls1x_pwmtimer_irqaction = { + .name = "ls1x-pwmtimer", + .handler = ls1x_clockevent_isr, + .dev_id = &ls1x_clockevent, + .flags = IRQF_PERCPU | IRQF_TIMER, +}; + +static void __init ls1x_time_init(void) +{ + struct clock_event_device *cd = &ls1x_clockevent; + int ret; + + if (!mips_hpt_frequency) + panic("Invalid timer clock rate"); + + ls1x_pwmtimer_init(); + + clockevent_set_clock(cd, mips_hpt_frequency); + cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); + cd->cpumask = cpumask_of(smp_processor_id()); + clockevents_register_device(cd); + + ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; + ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); + if (ret) + panic(KERN_ERR "Failed to register clocksource: %d\n", ret); + + setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); +} +#endif /* CONFIG_CEVT_CSRC_LS1X */ + +void __init plat_time_init(void) +{ + struct clk *clk = NULL; + + /* initialize LS1X clocks */ + ls1x_clk_init(); + +#ifdef CONFIG_CEVT_CSRC_LS1X + /* setup LS1X PWM timer */ + clk = clk_get(NULL, "ls1x_pwmtimer"); + if (IS_ERR(clk)) + panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); + + mips_hpt_frequency = clk_get_rate(clk); + ls1x_time_init(); +#else + /* setup mips r4k timer */ + clk = clk_get(NULL, "cpu_clk"); + if (IS_ERR(clk)) + panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); + + mips_hpt_frequency = clk_get_rate(clk) / 2; +#endif /* CONFIG_CEVT_CSRC_LS1X */ +} diff --git a/arch/mips/loongson32/ls1b/Makefile b/arch/mips/loongson32/ls1b/Makefile new file mode 100644 index 000000000000..891eac482b82 --- /dev/null +++ b/arch/mips/loongson32/ls1b/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for loongson1B based machines. +# + +obj-y += board.o diff --git a/arch/mips/loongson32/ls1b/board.c b/arch/mips/loongson32/ls1b/board.c new file mode 100644 index 000000000000..58daeea25739 --- /dev/null +++ b/arch/mips/loongson32/ls1b/board.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +static struct platform_device *ls1b_platform_devices[] __initdata = { + &ls1x_uart_pdev, + &ls1x_cpufreq_pdev, + &ls1x_eth0_pdev, + &ls1x_eth1_pdev, + &ls1x_ehci_pdev, + &ls1x_rtc_pdev, +}; + +static int __init ls1b_platform_init(void) +{ + int err; + + ls1x_serial_setup(&ls1x_uart_pdev); + + err = platform_add_devices(ls1b_platform_devices, + ARRAY_SIZE(ls1b_platform_devices)); + return err; +} + +arch_initcall(ls1b_platform_init); diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig new file mode 100644 index 000000000000..497912b38d8e --- /dev/null +++ b/arch/mips/loongson64/Kconfig @@ -0,0 +1,158 @@ +if MACH_LOONGSON64 + +choice + prompt "Machine Type" + +config LEMOTE_FULOONG2E + bool "Lemote Fuloong(2e) mini-PC" + select ARCH_SPARSEMEM_ENABLE + select CEVT_R4K + select CSRC_R4K + select SYS_HAS_CPU_LOONGSON2E + select DMA_NONCOHERENT + select BOOT_ELF32 + select BOARD_SCACHE + select HW_HAS_PCI + select I8259 + select ISA + select IRQ_MIPS_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_HAS_EARLY_PRINTK + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select CPU_HAS_WB + select LOONGSON_MC146818 + help + Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and + an FPGA northbridge + + Lemote Fuloong(2e) mini PC have a VIA686B south bridge. + +config LEMOTE_MACH2F + bool "Lemote Loongson 2F family machines" + select ARCH_SPARSEMEM_ENABLE + select BOARD_SCACHE + select BOOT_ELF32 + select CEVT_R4K if ! MIPS_EXTERNAL_TIMER + select CPU_HAS_WB + select CS5536 + select CSRC_R4K if ! MIPS_EXTERNAL_TIMER + select DMA_NONCOHERENT + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select HAVE_CLK + select HW_HAS_PCI + select I8259 + select IRQ_MIPS_CPU + select ISA + select SYS_HAS_CPU_LOONGSON2F + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_LITTLE_ENDIAN + select LOONGSON_MC146818 + help + Lemote Loongson 2F family machines utilize the 2F revision of + Loongson processor and the AMD CS5536 south bridge. + + These family machines include fuloong2f mini PC, yeeloong2f notebook, + LingLoong allinone PC and so forth. + +config LOONGSON_MACH3X + bool "Generic Loongson 3 family machines" + select ARCH_SPARSEMEM_ENABLE + select GENERIC_ISA_DMA_SUPPORT_BROKEN + select BOOT_ELF32 + select BOARD_SCACHE + select CSRC_R4K + select CEVT_R4K + select CPU_HAS_WB + select HW_HAS_PCI + select ISA + select HT_PCI + select I8259 + select IRQ_MIPS_CPU + select NR_CPUS_DEFAULT_4 + select SYS_HAS_CPU_LOONGSON3 + select SYS_HAS_EARLY_PRINTK + select SYS_SUPPORTS_SMP + select SYS_SUPPORTS_HOTPLUG_CPU + select SYS_SUPPORTS_NUMA + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_LITTLE_ENDIAN + select LOONGSON_MC146818 + select ZONE_DMA32 + select LEFI_FIRMWARE_INTERFACE + select PHYS48_TO_HT40 + help + Generic Loongson 3 family machines utilize the 3A/3B revision + of Loongson processor and RS780/SBX00 chipset. +endchoice + +config CS5536 + bool + +config CS5536_MFGPT + bool "CS5536 MFGPT Timer" + depends on CS5536 && !HIGH_RES_TIMERS + select MIPS_EXTERNAL_TIMER + help + This option enables the mfgpt0 timer of AMD CS5536. With this timer + switched on you can not use high resolution timers. + + If you want to enable the Loongson2 CPUFreq Driver, Please enable + this option at first, otherwise, You will get wrong system time. + + If unsure, say Yes. + +config RS780_HPET + bool "RS780/SBX00 HPET Timer" + depends on LOONGSON_MACH3X + select MIPS_EXTERNAL_TIMER + help + This option enables the hpet timer of AMD RS780/SBX00. + + If you want to enable the Loongson3 CPUFreq Driver, Please enable + this option at first, otherwise, You will get wrong system time. + + If unsure, say Yes. + +config LOONGSON_SUSPEND + bool + default y + depends on CPU_SUPPORTS_CPUFREQ && SUSPEND + +config LOONGSON_UART_BASE + bool + default y + depends on EARLY_PRINTK || SERIAL_8250 + +config IOMMU_HELPER + bool + +config NEED_SG_DMA_LENGTH + bool + +config SWIOTLB + bool "Soft IOMMU Support for All-Memory DMA" + default y + depends on CPU_LOONGSON3 + select IOMMU_HELPER + select NEED_SG_DMA_LENGTH + select NEED_DMA_MAP_STATE + +config PHYS48_TO_HT40 + bool + default y if CPU_LOONGSON3 + +config LOONGSON_MC146818 + bool + default n + +config LEFI_FIRMWARE_INTERFACE + bool + +endif # MACH_LOONGSON64 diff --git a/arch/mips/loongson64/Makefile b/arch/mips/loongson64/Makefile new file mode 100644 index 000000000000..4fe3d88fc361 --- /dev/null +++ b/arch/mips/loongson64/Makefile @@ -0,0 +1,23 @@ +# +# Common code for all Loongson based systems +# + +obj-$(CONFIG_MACH_LOONGSON64) += common/ + +# +# Lemote Fuloong mini-PC (Loongson 2E-based) +# + +obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/ + +# +# Lemote loongson2f family machines +# + +obj-$(CONFIG_LEMOTE_MACH2F) += lemote-2f/ + +# +# All Loongson-3 family machines +# + +obj-$(CONFIG_CPU_LOONGSON3) += loongson-3/ diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform new file mode 100644 index 000000000000..2e48e83d5524 --- /dev/null +++ b/arch/mips/loongson64/Platform @@ -0,0 +1,33 @@ +# +# Loongson Processors' Support +# + +# Only gcc >= 4.4 have Loongson specific support +cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap +cflags-$(CONFIG_CPU_LOONGSON2E) += \ + $(call cc-option,-march=loongson2e,-march=r4600) +cflags-$(CONFIG_CPU_LOONGSON2F) += \ + $(call cc-option,-march=loongson2f,-march=r4600) +# Enable the workarounds for Loongson2f +ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS + ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),) + $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop) + else + cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop + endif + ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),) + $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump) + else + cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump + endif +endif + +# +# Loongson Machines' Support +# + +platform-$(CONFIG_MACH_LOONGSON64) += loongson64/ +cflags-$(CONFIG_MACH_LOONGSON64) += -I$(srctree)/arch/mips/include/asm/mach-loongson64 -mno-branch-likely +load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000 +load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000 +load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000 diff --git a/arch/mips/loongson64/common/Makefile b/arch/mips/loongson64/common/Makefile new file mode 100644 index 000000000000..f2e8153e44f5 --- /dev/null +++ b/arch/mips/loongson64/common/Makefile @@ -0,0 +1,31 @@ +# +# Makefile for loongson based machines. +# + +obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ + bonito-irq.o mem.o machtype.o platform.o serial.o +obj-$(CONFIG_PCI) += pci.o + +# +# Serial port support +# +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o +obj-$(CONFIG_LOONGSON_MC146818) += rtc.o + +# +# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure +# space +# +obj-$(CONFIG_CS5536) += cs5536/ + +# +# Suspend Support +# + +obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o + +# +# Big Memory (SWIOTLB) Support +# +obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o diff --git a/arch/mips/loongson64/common/bonito-irq.c b/arch/mips/loongson64/common/bonito-irq.c new file mode 100644 index 000000000000..cc0e4fd548e6 --- /dev/null +++ b/arch/mips/loongson64/common/bonito-irq.c @@ -0,0 +1,53 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include + +static inline void bonito_irq_enable(struct irq_data *d) +{ + LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE)); + mmiowb(); +} + +static inline void bonito_irq_disable(struct irq_data *d) +{ + LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE)); + mmiowb(); +} + +static struct irq_chip bonito_irq_type = { + .name = "bonito_irq", + .irq_mask = bonito_irq_disable, + .irq_unmask = bonito_irq_enable, +}; + +static struct irqaction __maybe_unused dma_timeout_irqaction = { + .handler = no_action, + .name = "dma_timeout", +}; + +void bonito_irq_init(void) +{ + u32 i; + + for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++) + irq_set_chip_and_handler(i, &bonito_irq_type, + handle_level_irq); + +#ifdef CONFIG_CPU_LOONGSON2E + setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction); +#endif +} diff --git a/arch/mips/loongson64/common/cmdline.c b/arch/mips/loongson64/common/cmdline.c new file mode 100644 index 000000000000..72fed003a536 --- /dev/null +++ b/arch/mips/loongson64/common/cmdline.c @@ -0,0 +1,48 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include + +void __init prom_init_cmdline(void) +{ + int prom_argc; + /* pmon passes arguments in 32bit pointers */ + int *_prom_argv; + int i; + long l; + + /* firmware arguments are initialized in head.S */ + prom_argc = fw_arg0; + _prom_argv = (int *)fw_arg1; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < prom_argc; i++) { + l = (long)_prom_argv[i]; + if (strlen(arcs_cmdline) + strlen(((char *)l) + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, ((char *)l)); + strcat(arcs_cmdline, " "); + } + + prom_init_machtype(); +} diff --git a/arch/mips/loongson64/common/cs5536/Makefile b/arch/mips/loongson64/common/cs5536/Makefile new file mode 100644 index 000000000000..f12e64007347 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for CS5536 support. +# + +obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \ + cs5536_isa.o cs5536_ehci.o + +# +# Enable cs5536 mfgpt Timer +# +obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o diff --git a/arch/mips/loongson64/common/cs5536/cs5536_acc.c b/arch/mips/loongson64/common/cs5536/cs5536_acc.c new file mode 100644 index 000000000000..ab4d6cc57384 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_acc.c @@ -0,0 +1,140 @@ +/* + * the ACC Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_acc_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 8); + else + lo &= ~(0x03 << 8); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + value &= 0xfffffffc; + hi = 0xA0000000 | ((value & 0x000ff000) >> 12); + lo = 0x000fff80 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo); + } + break; + case PCI_ACC_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + /* disable all the usb interrupt in PIC */ + lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT); + if (value) /* enable all the acc interrupt in PIC */ + lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } +} + +u32 pci_acc_read_reg(int reg) +{ + u32 hi, lo; + u32 conf_data = 0; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + if (((lo & 0xfff00000) || (hi & 0x000000ff)) + && ((hi & 0xf0000000) == 0xa0000000)) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x300) == 0x300) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ACC_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_ACC_FLAG) { + conf_data = CS5536_ACC_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_ACC_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); + conf_data = (hi & 0x000000ff) << 12; + conf_data |= (lo & 0xfff00000) >> 20; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR); + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_ehci.c b/arch/mips/loongson64/common/cs5536/cs5536_ehci.c new file mode 100644 index 000000000000..ec2e360267a8 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_ehci.c @@ -0,0 +1,160 @@ +/* + * the EHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_ehci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo); + } + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= 0x003f0000; + hi |= (value & 0x3f) << 16; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + hi &= ~0x00003f00; + hi |= value & 0x00003f00; + _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo); + break; + default: + break; + } +} + +u32 pci_ehci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_EHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_EHCI_FLAG) { + conf_data = CS5536_EHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_EHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = lo & 0xfffff000; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_EHCI_LEGSMIEN_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x003f0000) >> 16; + break; + case PCI_EHCI_LEGSMISTS_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = (hi & 0x3f000000) >> 24; + break; + case PCI_EHCI_FLADJ_REG: + _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); + conf_data = hi & 0x00003f00; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_ide.c b/arch/mips/loongson64/common/cs5536/cs5536_ide.c new file mode 100644 index 000000000000..a73414d9ee51 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_ide.c @@ -0,0 +1,192 @@ +/* + * the IDE Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_ide_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + lo |= (0x03 << 4); + else + lo &= ~(0x03 << 4); + _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR4_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + lo = (value & 0xfffffff0) | 0x1; + _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo); + + value &= 0xfffffffc; + hi = 0x60000000 | ((value & 0x000ff000) >> 12); + lo = 0x000ffff0 | ((value & 0x00000fff) << 20); + _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo); + } + break; + case PCI_IDE_CFG_REG: + if (value == CS5536_IDE_FLASH_SIGNATURE) { + _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo); + lo |= 0x01; + _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo); + } else { + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); + } + break; + case PCI_IDE_DTC_REG: + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo); + break; + case PCI_IDE_CAST_REG: + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo); + break; + case PCI_IDE_ETC_REG: + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo); + break; + case PCI_IDE_PM_REG: + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + lo = value; + _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo); + break; + default: + break; + } +} + +u32 pci_ide_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + if (lo & 0xfffffff0) + conf_data |= PCI_COMMAND_IO; + _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); + if ((lo & 0x30) == 0x30) + conf_data |= PCI_COMMAND_MASTER; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_IDE_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); + break; + case PCI_BAR4_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_IDE_FLAG) { + conf_data = CS5536_IDE_RANGE | + PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~SOFT_BAR_IDE_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); + conf_data = lo & 0xfffffff0; + conf_data |= 0x01; + conf_data &= ~0x02; + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); + break; + case PCI_IDE_CFG_REG: + _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_DTC_REG: + _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_CAST_REG: + _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_ETC_REG: + _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo); + conf_data = lo; + break; + case PCI_IDE_PM_REG: + _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo); + conf_data = lo; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_isa.c b/arch/mips/loongson64/common/cs5536/cs5536_isa.c new file mode 100644 index 000000000000..924be39e7733 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_isa.c @@ -0,0 +1,330 @@ +/* + * the ISA Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +/* common variables for PCI_ISA_READ/WRITE_BAR */ +static const u32 divil_msr_reg[6] = { + DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO), + DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ), + DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI), +}; + +static const u32 soft_bar_flag[6] = { + SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG, + SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG, +}; + +static const u32 sb_msr_reg[6] = { + SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2), + SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5), +}; + +static const u32 bar_space_range[6] = { + CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE, + CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE, +}; + +static const int bar_space_len[6] = { + CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH, + CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH, +}; + +/* + * enable the divil module bar space. + * + * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg + * and the RCONFx(0~5) reg to use the modules. + */ +static void divil_lbar_enable(void) +{ + u32 hi, lo; + int offset; + + /* + * The DIVIL IRQ is not used yet. and make the RCONF0 reserved. + */ + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi |= 0x01; + _wrmsr(DIVIL_MSR_REG(offset), hi, lo); + } +} + +/* + * disable the divil module bar space. + */ +static void divil_lbar_disable(void) +{ + u32 hi, lo; + int offset; + + for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) { + _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo); + hi &= ~0x01; + _wrmsr(DIVIL_MSR_REG(offset), hi, lo); + } +} + +/* + * BAR write: write value to the n BAR + */ + +void pci_isa_write_bar(int n, u32 value) +{ + u32 hi = 0, lo = value; + + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if (value & 0x01) { + /* NATIVE reg */ + hi = 0x0000f001; + lo &= bar_space_range[n]; + _wrmsr(divil_msr_reg[n], hi, lo); + + /* RCONFx is 4bytes in units for I/O space */ + hi = ((value & 0x000ffffc) << 12) | + ((bar_space_len[n] - 4) << 12) | 0x01; + lo = ((value & 0x000ffffc) << 12) | 0x01; + _wrmsr(sb_msr_reg[n], hi, lo); + } +} + +/* + * BAR read: read the n BAR + */ + +u32 pci_isa_read_bar(int n) +{ + u32 conf_data = 0; + u32 hi, lo; + + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & soft_bar_flag[n]) { + conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO; + lo &= ~soft_bar_flag[n]; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(divil_msr_reg[n], &hi, &lo); + conf_data = lo & bar_space_range[n]; + conf_data |= 0x01; + conf_data &= ~0x02; + } + return conf_data; +} + +/* + * isa_write: ISA write transfer + * + * We assume that this is not a bus master transfer. + */ +void pci_isa_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + u32 temp; + + switch (reg) { + case PCI_COMMAND: + if (value & PCI_COMMAND_IO) + divil_lbar_enable(); + else + divil_lbar_disable(); + break; + case PCI_STATUS: + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + temp = lo & 0x0000ffff; + if ((value & PCI_STATUS_SIG_TARGET_ABORT) && + (lo & SB_TAS_ERR_EN)) + temp |= SB_TAS_ERR_FLAG; + + if ((value & PCI_STATUS_REC_TARGET_ABORT) && + (lo & SB_TAR_ERR_EN)) + temp |= SB_TAR_ERR_FLAG; + + if ((value & PCI_STATUS_REC_MASTER_ABORT) + && (lo & SB_MAR_ERR_EN)) + temp |= SB_MAR_ERR_FLAG; + + if ((value & PCI_STATUS_DETECTED_PARITY) + && (lo & SB_PARE_ERR_EN)) + temp |= SB_PARE_ERR_FLAG; + + lo = temp; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + break; + case PCI_CACHE_LINE_SIZE: + value &= 0x0000ff00; + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0xffffff00; + hi |= (value >> 8); + _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo); + break; + case PCI_BAR0_REG: + pci_isa_write_bar(0, value); + break; + case PCI_BAR1_REG: + pci_isa_write_bar(1, value); + break; + case PCI_BAR2_REG: + pci_isa_write_bar(2, value); + break; + case PCI_BAR3_REG: + pci_isa_write_bar(3, value); + break; + case PCI_BAR4_REG: + pci_isa_write_bar(4, value); + break; + case PCI_BAR5_REG: + pci_isa_write_bar(5, value); + break; + case PCI_UART1_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart1 interrupt in PIC */ + lo &= ~(0xf << 24); + if (value) /* enable uart1 interrupt in PIC */ + lo |= (CS5536_UART1_INTR << 24); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_UART2_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo); + /* disable uart2 interrupt in PIC */ + lo &= ~(0xf << 28); + if (value) /* enable uart2 interrupt in PIC */ + lo |= (CS5536_UART2_INTR << 28); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo); + break; + case PCI_ISA_FIXUP_REG: + if (value) { + /* enable the TARGET ABORT/MASTER ABORT etc. */ + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + lo |= 0x00000063; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + + default: + /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */ + break; + } +} + +/* + * isa_read: ISA read transfers + * + * We assume that this is not a bus master transfer. + */ +u32 pci_isa_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + /* we just check the first LBAR for the IO enable bit, */ + /* maybe we should changed later. */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo); + if (hi & 0x01) + conf_data |= PCI_COMMAND_IO; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + conf_data |= PCI_STATUS_FAST_BACK; + + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_TAS_ERR_FLAG) + conf_data |= PCI_STATUS_SIG_TARGET_ABORT; + if (lo & SB_TAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_TARGET_ABORT; + if (lo & SB_MAR_ERR_FLAG) + conf_data |= PCI_STATUS_REC_MASTER_ABORT; + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_DETECTED_PARITY; + break; + case PCI_CLASS_REVISION: + _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_ISA_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); + hi &= 0x000000f8; + conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi); + break; + /* + * we only use the LBAR of DIVIL, no RCONF used. + * all of them are IO space. + */ + case PCI_BAR0_REG: + return pci_isa_read_bar(0); + break; + case PCI_BAR1_REG: + return pci_isa_read_bar(1); + break; + case PCI_BAR2_REG: + return pci_isa_read_bar(2); + break; + case PCI_BAR3_REG: + break; + case PCI_BAR4_REG: + return pci_isa_read_bar(4); + break; + case PCI_BAR5_REG: + return pci_isa_read_bar(5); + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_POINTER; + break; + case PCI_INTERRUPT_LINE: + /* no interrupt used here */ + conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00); + break; + default: + break; + } + + return conf_data; +} + +/* + * The mfgpt timer interrupt is running early, so we must keep the south bridge + * mmio always enabled. Otherwise we may race with the PCI configuration which + * may temporarily disable it. When that happens and the timer interrupt fires, + * we are not able to clear it and the system will hang. + */ +static void cs5536_isa_mmio_always_on(struct pci_dev *dev) +{ + dev->mmio_always_on = 1; +} +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, + PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on); diff --git a/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c new file mode 100644 index 000000000000..12c75db23420 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c @@ -0,0 +1,213 @@ +/* + * CS5536 General timer functions + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu zhangjin, wuzhangjin@gmail.com + * + * Reference: AMD Geode(TM) CS5536 Companion Device Data Book + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +static DEFINE_RAW_SPINLOCK(mfgpt_lock); + +static u32 mfgpt_base; + +/* + * Initialize the MFGPT timer. + * + * This is also called after resume to bring the MFGPT into operation again. + */ + +/* disable counter */ +void disable_mfgpt0_counter(void) +{ + outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP); +} +EXPORT_SYMBOL(disable_mfgpt0_counter); + +/* enable counter, comparator2 to event mode, 14.318MHz clock */ +void enable_mfgpt0_counter(void) +{ + outw(0xe310, MFGPT0_SETUP); +} +EXPORT_SYMBOL(enable_mfgpt0_counter); + +static void init_mfgpt_timer(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + raw_spin_lock(&mfgpt_lock); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */ + outw(0, MFGPT0_CNT); /* set counter to 0 */ + enable_mfgpt0_counter(); + break; + + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + if (evt->mode == CLOCK_EVT_MODE_PERIODIC || + evt->mode == CLOCK_EVT_MODE_ONESHOT) + disable_mfgpt0_counter(); + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* The oneshot mode have very high deviation, Not use it! */ + break; + + case CLOCK_EVT_MODE_RESUME: + /* Nothing to do here */ + break; + } + raw_spin_unlock(&mfgpt_lock); +} + +static struct clock_event_device mfgpt_clockevent = { + .name = "mfgpt", + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = init_mfgpt_timer, + .irq = CS5536_MFGPT_INTR, +}; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + u32 basehi; + + /* + * get MFGPT base address + * + * NOTE: do not remove me, it's need for the value of mfgpt_base is + * variable + */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); + + /* ack */ + outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP); + + mfgpt_clockevent.event_handler(&mfgpt_clockevent); + + return IRQ_HANDLED; +} + +static struct irqaction irq5 = { + .handler = timer_interrupt, + .flags = IRQF_NOBALANCING | IRQF_TIMER, + .name = "timer" +}; + +/* + * Initialize the conversion factor and the min/max deltas of the clock event + * structure and register the clock event source with the framework. + */ +void __init setup_mfgpt0_timer(void) +{ + u32 basehi; + struct clock_event_device *cd = &mfgpt_clockevent; + unsigned int cpu = smp_processor_id(); + + cd->cpumask = cpumask_of(cpu); + clockevent_set_clock(cd, MFGPT_TICK_RATE); + cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0xf, cd); + + /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ + _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); + + /* Enable Interrupt Gate 5 */ + _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000); + + /* get MFGPT base address */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base); + + clockevents_register_device(cd); + + setup_irq(CS5536_MFGPT_INTR, &irq5); +} + +/* + * Since the MFGPT overflows every tick, its not very useful + * to just read by itself. So use jiffies to emulate a free + * running counter: + */ +static cycle_t mfgpt_read(struct clocksource *cs) +{ + unsigned long flags; + int count; + u32 jifs; + static int old_count; + static u32 old_jifs; + + raw_spin_lock_irqsave(&mfgpt_lock, flags); + /* + * Although our caller may have the read side of xtime_lock, + * this is now a seqlock, and we are cheating in this routine + * by having side effects on state that we cannot undo if + * there is a collision on the seqlock and our caller has to + * retry. (Namely, old_jifs and old_count.) So we must treat + * jiffies as volatile despite the lock. We read jiffies + * before latching the timer count to guarantee that although + * the jiffies value might be older than the count (that is, + * the counter may underflow between the last point where + * jiffies was incremented and the point where we latch the + * count), it cannot be newer. + */ + jifs = jiffies; + /* read the count */ + count = inw(MFGPT0_CNT); + + /* + * It's possible for count to appear to go the wrong way for this + * reason: + * + * The timer counter underflows, but we haven't handled the resulting + * interrupt and incremented jiffies yet. + * + * Previous attempts to handle these cases intelligently were buggy, so + * we just do the simple thing now. + */ + if (count < old_count && jifs == old_jifs) + count = old_count; + + old_count = count; + old_jifs = jifs; + + raw_spin_unlock_irqrestore(&mfgpt_lock, flags); + + return (cycle_t) (jifs * COMPARE) + count; +} + +static struct clocksource clocksource_mfgpt = { + .name = "mfgpt", + .rating = 120, /* Functional for real use, but not desired */ + .read = mfgpt_read, + .mask = CLOCKSOURCE_MASK(32), +}; + +int __init init_mfgpt_clocksource(void) +{ + if (num_possible_cpus() > 1) /* MFGPT does not scale! */ + return 0; + + return clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE); +} + +arch_initcall(init_mfgpt_clocksource); diff --git a/arch/mips/loongson64/common/cs5536/cs5536_ohci.c b/arch/mips/loongson64/common/cs5536/cs5536_ohci.c new file mode 100644 index 000000000000..f7c905e50dc4 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_ohci.c @@ -0,0 +1,149 @@ +/* + * the OHCI Virtual Support Module of AMD CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +void pci_ohci_write_reg(int reg, u32 value) +{ + u32 hi = 0, lo = value; + + switch (reg) { + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (value & PCI_COMMAND_MASTER) + hi |= PCI_COMMAND_MASTER; + else + hi &= ~PCI_COMMAND_MASTER; + + if (value & PCI_COMMAND_MEMORY) + hi |= PCI_COMMAND_MEMORY; + else + hi &= ~PCI_COMMAND_MEMORY; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + break; + case PCI_STATUS: + if (value & PCI_STATUS_PARITY) { + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) { + lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG; + _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo); + } + } + break; + case PCI_BAR0_REG: + if (value == PCI_BAR_RANGE_MASK) { + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + lo |= SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else if ((value & 0x01) == 0x00) { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + lo = value; + _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo); + + value &= 0xfffffff0; + hi = 0x40000000 | ((value & 0xff000000) >> 24); + lo = 0x000fffff | ((value & 0x00fff000) << 8); + _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo); + } + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT); + if (value) /* enable all the usb interrupt in PIC */ + lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT); + _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo); + break; + default: + break; + } +} + +u32 pci_ohci_read_reg(int reg) +{ + u32 conf_data = 0; + u32 hi, lo; + + switch (reg) { + case PCI_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID); + break; + case PCI_COMMAND: + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + if (hi & PCI_COMMAND_MASTER) + conf_data |= PCI_COMMAND_MASTER; + if (hi & PCI_COMMAND_MEMORY) + conf_data |= PCI_COMMAND_MEMORY; + break; + case PCI_STATUS: + conf_data |= PCI_STATUS_66MHZ; + conf_data |= PCI_STATUS_FAST_BACK; + _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); + if (lo & SB_PARE_ERR_FLAG) + conf_data |= PCI_STATUS_PARITY; + conf_data |= PCI_STATUS_DEVSEL_MEDIUM; + break; + case PCI_CLASS_REVISION: + _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo); + conf_data = lo & 0x000000ff; + conf_data |= (CS5536_OHCI_CLASS_CODE << 8); + break; + case PCI_CACHE_LINE_SIZE: + conf_data = + CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, + PCI_NORMAL_LATENCY_TIMER); + break; + case PCI_BAR0_REG: + _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); + if (lo & SOFT_BAR_OHCI_FLAG) { + conf_data = CS5536_OHCI_RANGE | + PCI_BASE_ADDRESS_SPACE_MEMORY; + lo &= ~SOFT_BAR_OHCI_FLAG; + _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); + } else { + _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); + conf_data = lo & 0xffffff00; + conf_data &= ~0x0000000f; /* 32bit mem */ + } + break; + case PCI_CARDBUS_CIS: + conf_data = PCI_CARDBUS_CIS_POINTER; + break; + case PCI_SUBSYSTEM_VENDOR_ID: + conf_data = + CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID); + break; + case PCI_ROM_ADDRESS: + conf_data = PCI_EXPANSION_ROM_BAR; + break; + case PCI_CAPABILITY_LIST: + conf_data = PCI_CAPLIST_USB_POINTER; + break; + case PCI_INTERRUPT_LINE: + conf_data = + CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); + break; + case PCI_OHCI_INT_REG: + _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); + if ((lo & 0x00000f00) == CS5536_USB_INTR) + conf_data = 1; + break; + default: + break; + } + + return conf_data; +} diff --git a/arch/mips/loongson64/common/cs5536/cs5536_pci.c b/arch/mips/loongson64/common/cs5536/cs5536_pci.c new file mode 100644 index 000000000000..b739723205f8 --- /dev/null +++ b/arch/mips/loongson64/common/cs5536/cs5536_pci.c @@ -0,0 +1,88 @@ +/* + * read/write operation to the PCI config space of CS5536 + * + * Copyright (C) 2007 Lemote, Inc. + * Author : jlliu, liujl@lemote.com + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * 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. + * + * the Virtual Support Module(VSM) for virtulizing the PCI + * configure space are defined in cs5536_modulename.c respectively, + * + * after this virtulizing, user can access the PCI configure space + * directly as a normal multi-function PCI device which follows + * the PCI-2.2 spec. + */ + +#include +#include +#include + +enum { + CS5536_FUNC_START = -1, + CS5536_ISA_FUNC, + reserved_func, + CS5536_IDE_FUNC, + CS5536_ACC_FUNC, + CS5536_OHCI_FUNC, + CS5536_EHCI_FUNC, + CS5536_FUNC_END, +}; + +static const cs5536_pci_vsm_write vsm_conf_write[] = { + [CS5536_ISA_FUNC] = pci_isa_write_reg, + [reserved_func] = NULL, + [CS5536_IDE_FUNC] = pci_ide_write_reg, + [CS5536_ACC_FUNC] = pci_acc_write_reg, + [CS5536_OHCI_FUNC] = pci_ohci_write_reg, + [CS5536_EHCI_FUNC] = pci_ehci_write_reg, +}; + +static const cs5536_pci_vsm_read vsm_conf_read[] = { + [CS5536_ISA_FUNC] = pci_isa_read_reg, + [reserved_func] = NULL, + [CS5536_IDE_FUNC] = pci_ide_read_reg, + [CS5536_ACC_FUNC] = pci_acc_read_reg, + [CS5536_OHCI_FUNC] = pci_ohci_read_reg, + [CS5536_EHCI_FUNC] = pci_ehci_read_reg, +}; + +/* + * write to PCI config space and transfer it to MSR write. + */ +void cs5536_pci_conf_write4(int function, int reg, u32 value) +{ + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return; + if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0)) + return; + + if (vsm_conf_write[function] != NULL) + vsm_conf_write[function](reg, value); +} + +/* + * read PCI config space and transfer it to MSR access. + */ +u32 cs5536_pci_conf_read4(int function, int reg) +{ + u32 data = 0; + + if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END)) + return 0; + if ((reg < 0) || ((reg & 0x03) != 0)) + return 0; + if (reg > 0x100) + return 0xffffffff; + + if (vsm_conf_read[function] != NULL) + data = vsm_conf_read[function](reg); + + return data; +} diff --git a/arch/mips/loongson64/common/dma-swiotlb.c b/arch/mips/loongson64/common/dma-swiotlb.c new file mode 100644 index 000000000000..2c6b989c1bc4 --- /dev/null +++ b/arch/mips/loongson64/common/dma-swiotlb.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static void *loongson_dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) +{ + void *ret; + + if (dma_alloc_from_coherent(dev, size, dma_handle, &ret)) + return ret; + + /* ignore region specifiers */ + gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); + +#ifdef CONFIG_ISA + if (dev == NULL) + gfp |= __GFP_DMA; + else +#endif +#ifdef CONFIG_ZONE_DMA + if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) + gfp |= __GFP_DMA; + else +#endif +#ifdef CONFIG_ZONE_DMA32 + if (dev->coherent_dma_mask < DMA_BIT_MASK(40)) + gfp |= __GFP_DMA32; + else +#endif + ; + gfp |= __GFP_NORETRY; + + ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp); + mb(); + return ret; +} + +static void loongson_dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) +{ + int order = get_order(size); + + if (dma_release_from_coherent(dev, order, vaddr)) + return; + + swiotlb_free_coherent(dev, size, vaddr, dma_handle); +} + +static dma_addr_t loongson_dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size, + dir, attrs); + mb(); + return daddr; +} + +static int loongson_dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + int r = swiotlb_map_sg_attrs(dev, sg, nents, dir, NULL); + mb(); + + return r; +} + +static void loongson_dma_sync_single_for_device(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) +{ + swiotlb_sync_single_for_device(dev, dma_handle, size, dir); + mb(); +} + +static void loongson_dma_sync_sg_for_device(struct device *dev, + struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + swiotlb_sync_sg_for_device(dev, sg, nents, dir); + mb(); +} + +static int loongson_dma_set_mask(struct device *dev, u64 mask) +{ + if (mask > DMA_BIT_MASK(loongson_sysconf.dma_mask_bits)) { + *dev->dma_mask = DMA_BIT_MASK(loongson_sysconf.dma_mask_bits); + return -EIO; + } + + *dev->dma_mask = mask; + + return 0; +} + +dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + long nid; +#ifdef CONFIG_PHYS48_TO_HT40 + /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from + * Loongson-3's 48bit address space and embed it into 40bit */ + nid = (paddr >> 44) & 0x3; + paddr = ((nid << 44) ^ paddr) | (nid << 37); +#endif + return paddr; +} + +phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) +{ + long nid; +#ifdef CONFIG_PHYS48_TO_HT40 + /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from + * Loongson-3's 48bit address space and embed it into 40bit */ + nid = (daddr >> 37) & 0x3; + daddr = ((nid << 37) ^ daddr) | (nid << 44); +#endif + return daddr; +} + +static struct dma_map_ops loongson_dma_map_ops = { + .alloc = loongson_dma_alloc_coherent, + .free = loongson_dma_free_coherent, + .map_page = loongson_dma_map_page, + .unmap_page = swiotlb_unmap_page, + .map_sg = loongson_dma_map_sg, + .unmap_sg = swiotlb_unmap_sg_attrs, + .sync_single_for_cpu = swiotlb_sync_single_for_cpu, + .sync_single_for_device = loongson_dma_sync_single_for_device, + .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, + .sync_sg_for_device = loongson_dma_sync_sg_for_device, + .mapping_error = swiotlb_dma_mapping_error, + .dma_supported = swiotlb_dma_supported, + .set_dma_mask = loongson_dma_set_mask +}; + +void __init plat_swiotlb_setup(void) +{ + swiotlb_init(1); + mips_dma_map_ops = &loongson_dma_map_ops; +} diff --git a/arch/mips/loongson64/common/early_printk.c b/arch/mips/loongson64/common/early_printk.c new file mode 100644 index 000000000000..6ca632e529dc --- /dev/null +++ b/arch/mips/loongson64/common/early_printk.c @@ -0,0 +1,41 @@ +/* early printk support + * + * Copyright (c) 2009 Philippe Vachon + * Copyright (c) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include + +#define PORT(base, offset) (u8 *)(base + offset) + +static inline unsigned int serial_in(unsigned char *base, int offset) +{ + return readb(PORT(base, offset)); +} + +static inline void serial_out(unsigned char *base, int offset, int value) +{ + writeb(value, PORT(base, offset)); +} + +void prom_putchar(char c) +{ + int timeout; + unsigned char *uart_base; + + uart_base = (unsigned char *)_loongson_uart_base[0]; + timeout = 1024; + + while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && + (timeout-- > 0)) + ; + + serial_out(uart_base, UART_TX, c); +} diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c new file mode 100644 index 000000000000..22f04ca2ff3e --- /dev/null +++ b/arch/mips/loongson64/common/env.c @@ -0,0 +1,200 @@ +/* + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2003 ICT CAS + * Author: Michael Guo + * + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include + +u32 cpu_clock_freq; +EXPORT_SYMBOL(cpu_clock_freq); +struct efi_memory_map_loongson *loongson_memmap; +struct loongson_system_configuration loongson_sysconf; + +u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; +u64 loongson_chiptemp[MAX_PACKAGES]; +u64 loongson_freqctrl[MAX_PACKAGES]; + +unsigned long long smp_group[4]; + +#define parse_even_earlier(res, option, p) \ +do { \ + unsigned int tmp __maybe_unused; \ + \ + if (strncmp(option, (char *)p, strlen(option)) == 0) \ + tmp = kstrtou32((char *)p + strlen(option"="), 10, &res); \ +} while (0) + +void __init prom_init_env(void) +{ + /* pmon passes arguments in 32bit pointers */ + unsigned int processor_id; + +#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE + int *_prom_envp; + long l; + + /* firmware arguments are initialized in head.S */ + _prom_envp = (int *)fw_arg2; + + l = (long)*_prom_envp; + while (l != 0) { + parse_even_earlier(cpu_clock_freq, "cpuclock", l); + parse_even_earlier(memsize, "memsize", l); + parse_even_earlier(highmemsize, "highmemsize", l); + _prom_envp++; + l = (long)*_prom_envp; + } + if (memsize == 0) + memsize = 256; + pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize); +#else + struct boot_params *boot_p; + struct loongson_params *loongson_p; + struct system_loongson *esys; + struct efi_cpuinfo_loongson *ecpu; + struct irq_source_routing_table *eirq_source; + + /* firmware arguments are initialized in head.S */ + boot_p = (struct boot_params *)fw_arg2; + loongson_p = &(boot_p->efi.smbios.lp); + + esys = (struct system_loongson *) + ((u64)loongson_p + loongson_p->system_offset); + ecpu = (struct efi_cpuinfo_loongson *) + ((u64)loongson_p + loongson_p->cpu_offset); + eirq_source = (struct irq_source_routing_table *) + ((u64)loongson_p + loongson_p->irq_offset); + loongson_memmap = (struct efi_memory_map_loongson *) + ((u64)loongson_p + loongson_p->memory_offset); + + cpu_clock_freq = ecpu->cpu_clock_freq; + loongson_sysconf.cputype = ecpu->cputype; + if (ecpu->cputype == Loongson_3A) { + loongson_sysconf.cores_per_node = 4; + loongson_sysconf.cores_per_package = 4; + smp_group[0] = 0x900000003ff01000; + smp_group[1] = 0x900010003ff01000; + smp_group[2] = 0x900020003ff01000; + smp_group[3] = 0x900030003ff01000; + loongson_chipcfg[0] = 0x900000001fe00180; + loongson_chipcfg[1] = 0x900010001fe00180; + loongson_chipcfg[2] = 0x900020001fe00180; + loongson_chipcfg[3] = 0x900030001fe00180; + loongson_chiptemp[0] = 0x900000001fe0019c; + loongson_chiptemp[1] = 0x900010001fe0019c; + loongson_chiptemp[2] = 0x900020001fe0019c; + loongson_chiptemp[3] = 0x900030001fe0019c; + loongson_sysconf.ht_control_base = 0x90000EFDFB000000; + loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; + } else if (ecpu->cputype == Loongson_3B) { + loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ + loongson_sysconf.cores_per_package = 8; + smp_group[0] = 0x900000003ff01000; + smp_group[1] = 0x900010003ff05000; + smp_group[2] = 0x900020003ff09000; + smp_group[3] = 0x900030003ff0d000; + loongson_chipcfg[0] = 0x900000001fe00180; + loongson_chipcfg[1] = 0x900020001fe00180; + loongson_chipcfg[2] = 0x900040001fe00180; + loongson_chipcfg[3] = 0x900060001fe00180; + loongson_chiptemp[0] = 0x900000001fe0019c; + loongson_chiptemp[1] = 0x900020001fe0019c; + loongson_chiptemp[2] = 0x900040001fe0019c; + loongson_chiptemp[3] = 0x900060001fe0019c; + loongson_freqctrl[0] = 0x900000001fe001d0; + loongson_freqctrl[1] = 0x900020001fe001d0; + loongson_freqctrl[2] = 0x900040001fe001d0; + loongson_freqctrl[3] = 0x900060001fe001d0; + loongson_sysconf.ht_control_base = 0x90001EFDFB000000; + loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG; + } else { + loongson_sysconf.cores_per_node = 1; + loongson_sysconf.cores_per_package = 1; + loongson_chipcfg[0] = 0x900000001fe00180; + } + + loongson_sysconf.nr_cpus = ecpu->nr_cpus; + loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id; + loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask; + if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) + loongson_sysconf.nr_cpus = NR_CPUS; + loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + + loongson_sysconf.cores_per_node - 1) / + loongson_sysconf.cores_per_node; + + loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr; + loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr; + loongson_sysconf.pci_io_base = eirq_source->pci_io_start_addr; + loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; + if (loongson_sysconf.dma_mask_bits < 32 || + loongson_sysconf.dma_mask_bits > 64) + loongson_sysconf.dma_mask_bits = 32; + + loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; + loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; + loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend; + + loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios; + pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", + loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, + loongson_sysconf.vgabios_addr); + + memset(loongson_sysconf.ecname, 0, 32); + if (esys->has_ec) + memcpy(loongson_sysconf.ecname, esys->ec_name, 32); + loongson_sysconf.workarounds |= esys->workarounds; + + loongson_sysconf.nr_uarts = esys->nr_uarts; + if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS) + loongson_sysconf.nr_uarts = 1; + memcpy(loongson_sysconf.uarts, esys->uarts, + sizeof(struct uart_device) * loongson_sysconf.nr_uarts); + + loongson_sysconf.nr_sensors = esys->nr_sensors; + if (loongson_sysconf.nr_sensors > MAX_SENSORS) + loongson_sysconf.nr_sensors = 0; + if (loongson_sysconf.nr_sensors) + memcpy(loongson_sysconf.sensors, esys->sensors, + sizeof(struct sensor_device) * loongson_sysconf.nr_sensors); +#endif + if (cpu_clock_freq == 0) { + processor_id = (¤t_cpu_data)->processor_id; + switch (processor_id & PRID_REV_MASK) { + case PRID_REV_LOONGSON2E: + cpu_clock_freq = 533080000; + break; + case PRID_REV_LOONGSON2F: + cpu_clock_freq = 797000000; + break; + case PRID_REV_LOONGSON3A: + cpu_clock_freq = 900000000; + break; + case PRID_REV_LOONGSON3B_R1: + case PRID_REV_LOONGSON3B_R2: + cpu_clock_freq = 1000000000; + break; + default: + cpu_clock_freq = 100000000; + break; + } + } + pr_info("CpuClock = %u\n", cpu_clock_freq); +} diff --git a/arch/mips/loongson64/common/init.c b/arch/mips/loongson64/common/init.c new file mode 100644 index 000000000000..9b987fe98b5b --- /dev/null +++ b/arch/mips/loongson64/common/init.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include + +/* Loongson CPU address windows config space base address */ +unsigned long __maybe_unused _loongson_addrwincfg_base; + +void __init prom_init(void) +{ +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG + _loongson_addrwincfg_base = (unsigned long) + ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE); +#endif + + prom_init_cmdline(); + prom_init_env(); + + /* init base address of io space */ + set_io_port_base((unsigned long) + ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); + +#ifdef CONFIG_NUMA + prom_init_numa_memory(); +#else + prom_init_memory(); +#endif + + /*init the uart base address */ + prom_init_uart_base(); + register_smp_ops(&loongson3_smp_ops); +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/loongson64/common/irq.c b/arch/mips/loongson64/common/irq.c new file mode 100644 index 000000000000..687003b19b45 --- /dev/null +++ b/arch/mips/loongson64/common/irq.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +/* + * the first level int-handler will jump here if it is a bonito irq + */ +void bonito_irqdispatch(void) +{ + u32 int_status; + int i; + + /* workaround the IO dma problem: let cpu looping to allow DMA finish */ + int_status = LOONGSON_INTISR; + while (int_status & (1 << 10)) { + udelay(1); + int_status = LOONGSON_INTISR; + } + + /* Get pending sources, masked by current enables */ + int_status = LOONGSON_INTISR & LOONGSON_INTEN; + + if (int_status) { + i = __ffs(int_status); + do_IRQ(LOONGSON_IRQ_BASE + i); + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + /* machine-specific plat_irq_dispatch */ + mach_irq_dispatch(pending); +} + +void __init arch_init_irq(void) +{ + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + + /* no steer */ + LOONGSON_INTSTEER = 0; + + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. + */ + LOONGSON_INTENCLR = ~0; + + /* machine specific irq init */ + mach_init_irq(); +} diff --git a/arch/mips/loongson64/common/machtype.c b/arch/mips/loongson64/common/machtype.c new file mode 100644 index 000000000000..f2807bc662a3 --- /dev/null +++ b/arch/mips/loongson64/common/machtype.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * Copyright (c) 2009 Zhang Le + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include + +#include +#include + +/* please ensure the length of the machtype string is less than 50 */ +#define MACHTYPE_LEN 50 + +static const char *system_types[] = { + [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine", + [MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box", + [MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box", + [MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches", + [MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches", + [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f", + [MACH_LEMOTE_NAS] = "lemote-nas-2f", + [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f", + [MACH_LOONGSON_GENERIC] = "generic-loongson-machine", + [MACH_LOONGSON_END] = NULL, +}; + +const char *get_system_type(void) +{ + return system_types[mips_machtype]; +} + +void __weak __init mach_prom_init_machtype(void) +{ +} + +void __init prom_init_machtype(void) +{ + char *p, str[MACHTYPE_LEN + 1]; + int machtype = MACH_LEMOTE_FL2E; + + mips_machtype = LOONGSON_MACHTYPE; + + p = strstr(arcs_cmdline, "machtype="); + if (!p) { + mach_prom_init_machtype(); + return; + } + p += strlen("machtype="); + strncpy(str, p, MACHTYPE_LEN); + str[MACHTYPE_LEN] = '\0'; + p = strstr(str, " "); + if (p) + *p = '\0'; + + for (; system_types[machtype]; machtype++) + if (strstr(system_types[machtype], str)) { + mips_machtype = machtype; + break; + } +} diff --git a/arch/mips/loongson64/common/mem.c b/arch/mips/loongson64/common/mem.c new file mode 100644 index 000000000000..b01d52473da8 --- /dev/null +++ b/arch/mips/loongson64/common/mem.c @@ -0,0 +1,161 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include + +#include +#include +#include +#include + +#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE + +u32 memsize, highmemsize; + +void __init prom_init_memory(void) +{ + add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM); + + add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize << + 20), BOOT_MEM_RESERVED); + +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG + { + int bit; + + bit = fls(memsize + highmemsize); + if (bit != ffs(memsize + highmemsize)) + bit += 20; + else + bit = bit + 20 - 1; + + /* set cpu window3 to map CPU to DDR: 2G -> 2G */ + LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul, + 0x80000000ul, (1 << bit)); + mmiowb(); + } +#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */ + +#ifdef CONFIG_64BIT + if (highmemsize > 0) + add_memory_region(LOONGSON_HIGHMEM_START, + highmemsize << 20, BOOT_MEM_RAM); + + add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START - + LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED); + +#endif /* !CONFIG_64BIT */ +} + +#else /* CONFIG_LEFI_FIRMWARE_INTERFACE */ + +void __init prom_init_memory(void) +{ + int i; + u32 node_id; + u32 mem_type; + + /* parse memory information */ + for (i = 0; i < loongson_memmap->nr_map; i++) { + node_id = loongson_memmap->map[i].node_id; + mem_type = loongson_memmap->map[i].mem_type; + + if (node_id == 0) { + switch (mem_type) { + case SYSTEM_RAM_LOW: + add_memory_region(loongson_memmap->map[i].mem_start, + (u64)loongson_memmap->map[i].mem_size << 20, + BOOT_MEM_RAM); + break; + case SYSTEM_RAM_HIGH: + add_memory_region(loongson_memmap->map[i].mem_start, + (u64)loongson_memmap->map[i].mem_size << 20, + BOOT_MEM_RAM); + break; + case MEM_RESERVED: + add_memory_region(loongson_memmap->map[i].mem_start, + (u64)loongson_memmap->map[i].mem_size << 20, + BOOT_MEM_RESERVED); + break; + } + } + } +} + +#endif /* CONFIG_LEFI_FIRMWARE_INTERFACE */ + +/* override of arch/mips/mm/cache.c: __uncached_access */ +int __uncached_access(struct file *file, unsigned long addr) +{ + if (file->f_flags & O_DSYNC) + return 1; + + return addr >= __pa(high_memory) || + ((addr >= LOONGSON_MMIO_MEM_START) && + (addr < LOONGSON_MMIO_MEM_END)); +} + +#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED + +#include +#include +#include + +static unsigned long uca_start, uca_end; + +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot) +{ + unsigned long offset = pfn << PAGE_SHIFT; + unsigned long end = offset + size; + + if (__uncached_access(file, offset)) { + if (uca_start && (offset >= uca_start) && + (end <= uca_end)) + return __pgprot((pgprot_val(vma_prot) & + ~_CACHE_MASK) | + _CACHE_UNCACHED_ACCELERATED); + else + return pgprot_noncached(vma_prot); + } + return vma_prot; +} + +static int __init find_vga_mem_init(void) +{ + struct pci_dev *dev = 0; + struct resource *r; + int idx; + + if (uca_start) + return 0; + + for_each_pci_dev(dev) { + if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { + for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) + continue; + if (r->flags & IORESOURCE_IO) + continue; + if (r->flags & IORESOURCE_MEM) { + uca_start = r->start; + uca_end = r->end; + return 0; + } + } + } + } + + return 0; +} + +late_initcall(find_vga_mem_init); +#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */ diff --git a/arch/mips/loongson64/common/pci.c b/arch/mips/loongson64/common/pci.c new file mode 100644 index 000000000000..4e2575643781 --- /dev/null +++ b/arch/mips/loongson64/common/pci.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include +#include +#include + +static struct resource loongson_pci_mem_resource = { + .name = "pci memory space", + .start = LOONGSON_PCI_MEM_START, + .end = LOONGSON_PCI_MEM_END, + .flags = IORESOURCE_MEM, +}; + +static struct resource loongson_pci_io_resource = { + .name = "pci io space", + .start = LOONGSON_PCI_IO_START, + .end = IO_SPACE_LIMIT, + .flags = IORESOURCE_IO, +}; + +static struct pci_controller loongson_pci_controller = { + .pci_ops = &loongson_pci_ops, + .io_resource = &loongson_pci_io_resource, + .mem_resource = &loongson_pci_mem_resource, + .mem_offset = 0x00000000UL, + .io_offset = 0x00000000UL, +}; + +static void __init setup_pcimap(void) +{ + /* + * local to PCI mapping for CPU accessing PCI space + * CPU address space [256M,448M] is window for accessing pci space + * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M] + * + * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0 + * [<2G] [384M,448M] [320M,384M] [0M,64M] + */ + LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 | + LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) | + LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) | + LOONGSON_PCIMAP_WIN(0, 0); + + /* + * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M] + */ + LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */ + /* size: 256M, burst transmission, pre-fetch enable, 64bit */ + LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul; + LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful; + LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */ + LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul; + LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */ + LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul; + + /* avoid deadlock of PCI reading/writing lock operation */ + LOONGSON_PCI_ISR4C = 0xd2000001ul; + + /* can not change gnt to break pci transfer when device's gnt not + deassert for some broken device */ + LOONGSON_PXARB_CFG = 0x00fe0105ul; + +#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG + /* + * set cpu addr window2 to map CPU address space to PCI address space + */ + LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC, + LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE); +#endif +} + +extern int sbx00_acpi_init(void); + +static int __init pcibios_init(void) +{ + setup_pcimap(); + + loongson_pci_controller.io_map_base = mips_io_port_base; +#ifdef CONFIG_LEFI_FIRMWARE_INTERFACE + loongson_pci_mem_resource.start = loongson_sysconf.pci_mem_start_addr; + loongson_pci_mem_resource.end = loongson_sysconf.pci_mem_end_addr; +#endif + register_pci_controller(&loongson_pci_controller); + +#ifdef CONFIG_CPU_LOONGSON3 + sbx00_acpi_init(); +#endif + + return 0; +} + +arch_initcall(pcibios_init); diff --git a/arch/mips/loongson64/common/platform.c b/arch/mips/loongson64/common/platform.c new file mode 100644 index 000000000000..0ed38321a9a2 --- /dev/null +++ b/arch/mips/loongson64/common/platform.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +static struct platform_device loongson2_cpufreq_device = { + .name = "loongson2_cpufreq", + .id = -1, +}; + +static int __init loongson2_cpufreq_init(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + /* Only 2F revision and it's successors support CPUFreq */ + if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F) + return platform_device_register(&loongson2_cpufreq_device); + + return -ENODEV; +} + +arch_initcall(loongson2_cpufreq_init); diff --git a/arch/mips/loongson64/common/pm.c b/arch/mips/loongson64/common/pm.c new file mode 100644 index 000000000000..a6b67ccfc811 --- /dev/null +++ b/arch/mips/loongson64/common/pm.c @@ -0,0 +1,161 @@ +/* + * loongson-specific suspend support + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include + +#include +#include + +#include + +static unsigned int __maybe_unused cached_master_mask; /* i8259A */ +static unsigned int __maybe_unused cached_slave_mask; +static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */ + +void arch_suspend_disable_irqs(void) +{ + /* disable all mips events */ + local_irq_disable(); + +#ifdef CONFIG_I8259 + /* disable all events of i8259A */ + cached_slave_mask = inb(PIC_SLAVE_IMR); + cached_master_mask = inb(PIC_MASTER_IMR); + + outb(0xff, PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + outb(0xff, PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); +#endif + /* disable all events of bonito */ + cached_bonito_irq_mask = LOONGSON_INTEN; + LOONGSON_INTENCLR = 0xffff; + (void)LOONGSON_INTENCLR; +} + +void arch_suspend_enable_irqs(void) +{ + /* enable all mips events */ + local_irq_enable(); +#ifdef CONFIG_I8259 + /* only enable the cached events of i8259A */ + outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(cached_master_mask, PIC_MASTER_IMR); +#endif + /* enable all cached events of bonito */ + LOONGSON_INTENSET = cached_bonito_irq_mask; + (void)LOONGSON_INTENSET; +} + +/* + * Setup the board-specific events for waking up loongson from wait mode + */ +void __weak setup_wakeup_events(void) +{ +} + +/* + * Check wakeup events + */ +int __weak wakeup_loongson(void) +{ + return 1; +} + +/* + * If the events are really what we want to wakeup the CPU, wake it up + * otherwise put the CPU asleep again. + */ +static void wait_for_wakeup_events(void) +{ + while (!wakeup_loongson()) + LOONGSON_CHIPCFG(0) &= ~0x7; +} + +/* + * Stop all perf counters + * + * $24 is the control register of Loongson perf counter + */ +static inline void stop_perf_counters(void) +{ + __write_64bit_c0_register($24, 0, 0); +} + + +static void loongson_suspend_enter(void) +{ + static unsigned int cached_cpu_freq; + + /* setup wakeup events via enabling the IRQs */ + setup_wakeup_events(); + + stop_perf_counters(); + + cached_cpu_freq = LOONGSON_CHIPCFG(0); + + /* Put CPU into wait mode */ + LOONGSON_CHIPCFG(0) &= ~0x7; + + /* wait for the given events to wakeup cpu from wait mode */ + wait_for_wakeup_events(); + + LOONGSON_CHIPCFG(0) = cached_cpu_freq; + mmiowb(); +} + +void __weak mach_suspend(void) +{ +} + +void __weak mach_resume(void) +{ +} + +static int loongson_pm_enter(suspend_state_t state) +{ + mach_suspend(); + + /* processor specific suspend */ + loongson_suspend_enter(); + + mach_resume(); + + return 0; +} + +static int loongson_pm_valid_state(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_ON: + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + return 1; + + default: + return 0; + } +} + +static const struct platform_suspend_ops loongson_pm_ops = { + .valid = loongson_pm_valid_state, + .enter = loongson_pm_enter, +}; + +static int __init loongson_pm_init(void) +{ + suspend_set_ops(&loongson_pm_ops); + + return 0; +} +arch_initcall(loongson_pm_init); diff --git a/arch/mips/loongson64/common/reset.c b/arch/mips/loongson64/common/reset.c new file mode 100644 index 000000000000..a60715e11306 --- /dev/null +++ b/arch/mips/loongson64/common/reset.c @@ -0,0 +1,92 @@ +/* + * 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. + * + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * Copyright (C) 2009 Lemote, Inc. + * Author: Zhangjin Wu, wuzhangjin@gmail.com + */ +#include +#include + +#include +#include + +#include +#include + +static inline void loongson_reboot(void) +{ +#ifndef CONFIG_CPU_JUMP_WORKAROUNDS + ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); +#else + void (*func)(void); + + func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4); + + __asm__ __volatile__( + " .set noat \n" + " jr %[func] \n" + " .set at \n" + : /* No outputs */ + : [func] "r" (func)); +#endif +} + +static void loongson_restart(char *command) +{ +#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE + /* do preparation for reboot */ + mach_prepare_reboot(); + + /* reboot via jumping to boot base address */ + loongson_reboot(); +#else + void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr; + + fw_restart(); + while (1) { + if (cpu_wait) + cpu_wait(); + } +#endif +} + +static void loongson_poweroff(void) +{ +#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE + mach_prepare_shutdown(); + unreachable(); +#else + void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; + + fw_poweroff(); + while (1) { + if (cpu_wait) + cpu_wait(); + } +#endif +} + +static void loongson_halt(void) +{ + pr_notice("\n\n** You can safely turn off the power now **\n\n"); + while (1) { + if (cpu_wait) + cpu_wait(); + } +} + +static int __init mips_reboot_setup(void) +{ + _machine_restart = loongson_restart; + _machine_halt = loongson_halt; + pm_power_off = loongson_poweroff; + + return 0; +} + +arch_initcall(mips_reboot_setup); diff --git a/arch/mips/loongson64/common/rtc.c b/arch/mips/loongson64/common/rtc.c new file mode 100644 index 000000000000..b5709af09f7f --- /dev/null +++ b/arch/mips/loongson64/common/rtc.c @@ -0,0 +1,43 @@ +/* + * Lemote Fuloong platform support + * + * Copyright(c) 2010 Arnaud Patard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include + +static struct resource loongson_rtc_resources[] = { + { + .start = RTC_PORT(0), + .end = RTC_PORT(1), + .flags = IORESOURCE_IO, + }, { + .start = RTC_IRQ, + .end = RTC_IRQ, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device loongson_rtc_device = { + .name = "rtc_cmos", + .id = -1, + .resource = loongson_rtc_resources, + .num_resources = ARRAY_SIZE(loongson_rtc_resources), +}; + + +static int __init loongson_rtc_platform_init(void) +{ + platform_device_register(&loongson_rtc_device); + return 0; +} + +device_initcall(loongson_rtc_platform_init); diff --git a/arch/mips/loongson64/common/serial.c b/arch/mips/loongson64/common/serial.c new file mode 100644 index 000000000000..c23fa1373729 --- /dev/null +++ b/arch/mips/loongson64/common/serial.c @@ -0,0 +1,112 @@ +/* + * 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) 2007 Ralf Baechle (ralf@linux-mips.org) + * + * Copyright (C) 2009 Lemote, Inc. + * Author: Yan hua (yanhua@lemote.com) + * Author: Wu Zhangjin (wuzhangjin@gmail.com) + */ + +#include +#include +#include + +#include + +#include +#include + +#define PORT(int, clk) \ +{ \ + .irq = int, \ + .uartclk = clk, \ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +#define PORT_M(int, clk) \ +{ \ + .irq = MIPS_CPU_IRQ_BASE + (int), \ + .uartclk = clk, \ + .iotype = UPIO_MEM, \ + .membase = (void __iomem *)NULL, \ + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ + .regshift = 0, \ +} + +static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = { + [MACH_LOONGSON_UNKNOWN] = {}, + [MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} }, + [MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} }, + [MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} }, + [MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} }, + [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} }, + [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} }, + [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} }, + [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} }, + [MACH_LOONGSON_END] = {}, +}; + +static struct platform_device uart8250_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, +}; + +static int __init serial_init(void) +{ + int i; + unsigned char iotype; + + iotype = uart8250_data[mips_machtype][0].iotype; + + if (UPIO_MEM == iotype) { + uart8250_data[mips_machtype][0].mapbase = + loongson_uart_base[0]; + uart8250_data[mips_machtype][0].membase = + (void __iomem *)_loongson_uart_base[0]; + } + else if (UPIO_PORT == iotype) + uart8250_data[mips_machtype][0].iobase = + loongson_uart_base[0] - LOONGSON_PCIIO_BASE; + + if (loongson_sysconf.uarts[0].uartclk) + uart8250_data[mips_machtype][0].uartclk = + loongson_sysconf.uarts[0].uartclk; + + for (i = 1; i < loongson_sysconf.nr_uarts; i++) { + iotype = loongson_sysconf.uarts[i].iotype; + uart8250_data[mips_machtype][i].iotype = iotype; + loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base; + + if (UPIO_MEM == iotype) { + uart8250_data[mips_machtype][i].irq = + MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset; + uart8250_data[mips_machtype][i].mapbase = + loongson_uart_base[i]; + uart8250_data[mips_machtype][i].membase = + ioremap_nocache(loongson_uart_base[i], 8); + } else if (UPIO_PORT == iotype) { + uart8250_data[mips_machtype][i].irq = + loongson_sysconf.uarts[i].int_offset; + uart8250_data[mips_machtype][i].iobase = + loongson_uart_base[i] - LOONGSON_PCIIO_BASE; + } + + uart8250_data[mips_machtype][i].uartclk = + loongson_sysconf.uarts[i].uartclk; + uart8250_data[mips_machtype][i].flags = + UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; + } + + memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts], + 0, sizeof(struct plat_serial8250_port)); + uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; + + return platform_device_register(&uart8250_device); +} + +device_initcall(serial_init); diff --git a/arch/mips/loongson64/common/setup.c b/arch/mips/loongson64/common/setup.c new file mode 100644 index 000000000000..d477dd6bb326 --- /dev/null +++ b/arch/mips/loongson64/common/setup.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include +#include + +#include + +#ifdef CONFIG_VT +#include +#include +#endif + +static void wbflush_loongson(void) +{ + asm(".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set mips3\n\t" + "sync\n\t" + "nop\n\t" + ".set\tpop\n\t" + ".set mips0\n\t"); +} + +void (*__wbflush)(void) = wbflush_loongson; +EXPORT_SYMBOL(__wbflush); + +void __init plat_mem_setup(void) +{ +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; + + screen_info = (struct screen_info) { + .orig_x = 0, + .orig_y = 25, + .orig_video_cols = 80, + .orig_video_lines = 25, + .orig_video_isVGA = VIDEO_TYPE_VGAC, + .orig_video_points = 16, + }; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif +#endif +} diff --git a/arch/mips/loongson64/common/time.c b/arch/mips/loongson64/common/time.c new file mode 100644 index 000000000000..e1a5382ad47e --- /dev/null +++ b/arch/mips/loongson64/common/time.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include +#include + +void __init plat_time_init(void) +{ + /* setup mips r4k timer */ + mips_hpt_frequency = cpu_clock_freq / 2; + +#ifdef CONFIG_RS780_HPET + setup_hpet_timer(); +#else + setup_mfgpt0_timer(); +#endif +} + +void read_persistent_clock(struct timespec *ts) +{ + ts->tv_sec = mc146818_get_cmos_time(); + ts->tv_nsec = 0; +} diff --git a/arch/mips/loongson64/common/uart_base.c b/arch/mips/loongson64/common/uart_base.c new file mode 100644 index 000000000000..9de559d58e1f --- /dev/null +++ b/arch/mips/loongson64/common/uart_base.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include + +/* raw */ +unsigned long loongson_uart_base[MAX_UARTS] = {}; +/* ioremapped */ +unsigned long _loongson_uart_base[MAX_UARTS] = {}; + +EXPORT_SYMBOL(loongson_uart_base); +EXPORT_SYMBOL(_loongson_uart_base); + +void prom_init_loongson_uart_base(void) +{ + switch (mips_machtype) { + case MACH_LOONGSON_GENERIC: + /* The CPU provided serial port (CPU) */ + loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0; + break; + case MACH_LEMOTE_FL2E: + loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8; + break; + case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_LL2F: + loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8; + break; + case MACH_LEMOTE_ML2F7: + case MACH_LEMOTE_YL2F89: + case MACH_DEXXON_GDIUM2F10: + case MACH_LEMOTE_NAS: + default: + /* The CPU provided serial port (LPC) */ + loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8; + break; + } + + _loongson_uart_base[0] = + (unsigned long)ioremap_nocache(loongson_uart_base[0], 8); +} diff --git a/arch/mips/loongson64/fuloong-2e/Makefile b/arch/mips/loongson64/fuloong-2e/Makefile new file mode 100644 index 000000000000..b7622720c1ad --- /dev/null +++ b/arch/mips/loongson64/fuloong-2e/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Lemote Fuloong2e mini-PC board. +# + +obj-y += irq.o reset.o diff --git a/arch/mips/loongson64/fuloong-2e/irq.c b/arch/mips/loongson64/fuloong-2e/irq.c new file mode 100644 index 000000000000..ef5ec8f3de5f --- /dev/null +++ b/arch/mips/loongson64/fuloong-2e/irq.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include +#include + +#include + +static void i8259_irqdispatch(void) +{ + int irq; + + irq = i8259_irq(); + if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); +} + +asmlinkage void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + else if (pending & CAUSEF_IP6) /* perf counter loverflow */ + do_perfcnt_IRQ(); + else if (pending & CAUSEF_IP5) + i8259_irqdispatch(); + else if (pending & CAUSEF_IP2) + bonito_irqdispatch(); + else + spurious_interrupt(); +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", + .flags = IRQF_NO_THREAD, +}; + +void __init mach_init_irq(void) +{ + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* most bonito irq should be level triggered */ + LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | + LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* bonito irq at IP2 */ + setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); + /* 8259 irq at IP5 */ + setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); +} diff --git a/arch/mips/loongson64/fuloong-2e/reset.c b/arch/mips/loongson64/fuloong-2e/reset.c new file mode 100644 index 000000000000..da4d2ae2a1f8 --- /dev/null +++ b/arch/mips/loongson64/fuloong-2e/reset.c @@ -0,0 +1,23 @@ +/* Board-specific reboot/shutdown routines + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include + +void mach_prepare_reboot(void) +{ + LOONGSON_GENCFG &= ~(1 << 2); + LOONGSON_GENCFG |= (1 << 2); +} + +void mach_prepare_shutdown(void) +{ +} diff --git a/arch/mips/loongson64/lemote-2f/Makefile b/arch/mips/loongson64/lemote-2f/Makefile new file mode 100644 index 000000000000..4f9eaa328a16 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for lemote loongson2f family machines +# + +obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o + +# +# Suspend Support +# + +obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o diff --git a/arch/mips/loongson64/lemote-2f/clock.c b/arch/mips/loongson64/lemote-2f/clock.c new file mode 100644 index 000000000000..462e34d46b4a --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/clock.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology + * Author: Yanhua, yanh@lemote.com + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static LIST_HEAD(clock_list); +static DEFINE_SPINLOCK(clock_lock); +static DEFINE_MUTEX(clock_list_sem); + +/* Minimum CLK support */ +enum { + DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT, + DC_87PT, DC_DISABLE, DC_RESV +}; + +struct cpufreq_frequency_table loongson2_clockmod_table[] = { + {0, DC_RESV, CPUFREQ_ENTRY_INVALID}, + {0, DC_ZERO, CPUFREQ_ENTRY_INVALID}, + {0, DC_25PT, 0}, + {0, DC_37PT, 0}, + {0, DC_50PT, 0}, + {0, DC_62PT, 0}, + {0, DC_75PT, 0}, + {0, DC_87PT, 0}, + {0, DC_DISABLE, 0}, + {0, DC_RESV, CPUFREQ_TABLE_END}, +}; +EXPORT_SYMBOL_GPL(loongson2_clockmod_table); + +static struct clk cpu_clk = { + .name = "cpu_clk", + .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES, + .rate = 800000000, +}; + +struct clk *clk_get(struct device *dev, const char *id) +{ + return &cpu_clk; +} +EXPORT_SYMBOL(clk_get); + +static void propagate_rate(struct clk *clk) +{ + struct clk *clkp; + + list_for_each_entry(clkp, &clock_list, node) { + if (likely(clkp->parent != clk)) + continue; + if (likely(clkp->ops && clkp->ops->recalc)) + clkp->ops->recalc(clkp); + if (unlikely(clkp->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clkp); + } +} + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int rate_khz = rate / 1000; + struct cpufreq_frequency_table *pos; + int ret = 0; + int regval; + + if (likely(clk->ops && clk->ops->set_rate)) { + unsigned long flags; + + spin_lock_irqsave(&clock_lock, flags); + ret = clk->ops->set_rate(clk, rate, 0); + spin_unlock_irqrestore(&clock_lock, flags); + } + + if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) + propagate_rate(clk); + + cpufreq_for_each_valid_entry(pos, loongson2_clockmod_table) + if (rate_khz == pos->frequency) + break; + if (rate_khz != pos->frequency) + return -ENOTSUPP; + + clk->rate = rate; + + regval = LOONGSON_CHIPCFG(0); + regval = (regval & ~0x7) | (pos->driver_data - 1); + LOONGSON_CHIPCFG(0) = regval; + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (likely(clk->ops && clk->ops->round_rate)) { + unsigned long flags, rounded; + + spin_lock_irqsave(&clock_lock, flags); + rounded = clk->ops->round_rate(clk, rate); + spin_unlock_irqrestore(&clock_lock, flags); + + return rounded; + } + + return rate; +} +EXPORT_SYMBOL_GPL(clk_round_rate); diff --git a/arch/mips/loongson64/lemote-2f/ec_kb3310b.c b/arch/mips/loongson64/lemote-2f/ec_kb3310b.c new file mode 100644 index 000000000000..2b666d3a3947 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/ec_kb3310b.c @@ -0,0 +1,128 @@ +/* + * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook + * + * Copyright (C) 2008 Lemote Inc. + * Author: liujl , 2008-04-20 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include + +#include "ec_kb3310b.h" + +static DEFINE_SPINLOCK(index_access_lock); +static DEFINE_SPINLOCK(port_access_lock); + +unsigned char ec_read(unsigned short addr) +{ + unsigned char value; + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + value = inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); + + return value; +} +EXPORT_SYMBOL_GPL(ec_read); + +void ec_write(unsigned short addr, unsigned char val) +{ + unsigned long flags; + + spin_lock_irqsave(&index_access_lock, flags); + outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH); + outb((addr & 0x00ff), EC_IO_PORT_LOW); + outb(val, EC_IO_PORT_DATA); + /* flush the write action */ + inb(EC_IO_PORT_DATA); + spin_unlock_irqrestore(&index_access_lock, flags); +} +EXPORT_SYMBOL_GPL(ec_write); + +/* + * This function is used for EC command writes and corresponding status queries. + */ +int ec_query_seq(unsigned char cmd) +{ + int timeout; + unsigned char status; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&port_access_lock, flags); + + /* make chip goto reset mode */ + udelay(EC_REG_DELAY); + outb(cmd, EC_CMD_PORT); + udelay(EC_REG_DELAY); + + /* check if the command is received by ec */ + timeout = EC_CMD_TIMEOUT; + status = inb(EC_STS_PORT); + while (timeout-- && (status & (1 << 1))) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + } + + spin_unlock_irqrestore(&port_access_lock, flags); + + if (timeout <= 0) { + printk(KERN_ERR "%s: deadable error : timeout...\n", __func__); + ret = -EINVAL; + } else + printk(KERN_INFO + "(%x/%d)ec issued command %d status : 0x%x\n", + timeout, EC_CMD_TIMEOUT - timeout, cmd, status); + + return ret; +} +EXPORT_SYMBOL_GPL(ec_query_seq); + +/* + * Send query command to EC to get the proper event number + */ +int ec_query_event_num(void) +{ + return ec_query_seq(CMD_GET_EVENT_NUM); +} +EXPORT_SYMBOL(ec_query_event_num); + +/* + * Get event number from EC + * + * NOTE: This routine must follow the query_event_num function in the + * interrupt. + */ +int ec_get_event_num(void) +{ + int timeout = 100; + unsigned char value; + unsigned char status; + + udelay(EC_REG_DELAY); + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + while (timeout-- && !(status & (1 << 0))) { + status = inb(EC_STS_PORT); + udelay(EC_REG_DELAY); + } + if (timeout <= 0) { + pr_info("%s: get event number timeout.\n", __func__); + + return -EINVAL; + } + value = inb(EC_DAT_PORT); + udelay(EC_REG_DELAY); + + return value; +} +EXPORT_SYMBOL(ec_get_event_num); diff --git a/arch/mips/loongson64/lemote-2f/ec_kb3310b.h b/arch/mips/loongson64/lemote-2f/ec_kb3310b.h new file mode 100644 index 000000000000..5a3f1860d4d2 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/ec_kb3310b.h @@ -0,0 +1,188 @@ +/* + * KB3310B Embedded Controller + * + * Copyright (C) 2008 Lemote Inc. + * Author: liujl , 2008-03-14 + * + * 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 _EC_KB3310B_H +#define _EC_KB3310B_H + +extern unsigned char ec_read(unsigned short addr); +extern void ec_write(unsigned short addr, unsigned char val); +extern int ec_query_seq(unsigned char cmd); +extern int ec_query_event_num(void); +extern int ec_get_event_num(void); + +typedef int (*sci_handler) (int status); +extern sci_handler yeeloong_report_lid_status; + +#define SCI_IRQ_NUM 0x0A + +/* + * The following registers are determined by the EC index configuration. + * 1, fill the PORT_HIGH as EC register high part. + * 2, fill the PORT_LOW as EC register low part. + * 3, fill the PORT_DATA as EC register write data or get the data from it. + */ +#define EC_IO_PORT_HIGH 0x0381 +#define EC_IO_PORT_LOW 0x0382 +#define EC_IO_PORT_DATA 0x0383 + +/* + * EC delay time is 500us for register and status access + */ +#define EC_REG_DELAY 500 /* unit : us */ +#define EC_CMD_TIMEOUT 0x1000 + +/* + * EC access port for SCI communication + */ +#define EC_CMD_PORT 0x66 +#define EC_STS_PORT 0x66 +#define EC_DAT_PORT 0x62 +#define CMD_INIT_IDLE_MODE 0xdd +#define CMD_EXIT_IDLE_MODE 0xdf +#define CMD_INIT_RESET_MODE 0xd8 +#define CMD_REBOOT_SYSTEM 0x8c +#define CMD_GET_EVENT_NUM 0x84 +#define CMD_PROGRAM_PIECE 0xda + +/* temperature & fan registers */ +#define REG_TEMPERATURE_VALUE 0xF458 +#define REG_FAN_AUTO_MAN_SWITCH 0xF459 +#define BIT_FAN_AUTO 0 +#define BIT_FAN_MANUAL 1 +#define REG_FAN_CONTROL 0xF4D2 +#define BIT_FAN_CONTROL_ON (1 << 0) +#define BIT_FAN_CONTROL_OFF (0 << 0) +#define REG_FAN_STATUS 0xF4DA +#define BIT_FAN_STATUS_ON (1 << 0) +#define BIT_FAN_STATUS_OFF (0 << 0) +#define REG_FAN_SPEED_HIGH 0xFE22 +#define REG_FAN_SPEED_LOW 0xFE23 +#define REG_FAN_SPEED_LEVEL 0xF4CC +/* fan speed divider */ +#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/ + +/* battery registers */ +#define REG_BAT_DESIGN_CAP_HIGH 0xF77D +#define REG_BAT_DESIGN_CAP_LOW 0xF77E +#define REG_BAT_FULLCHG_CAP_HIGH 0xF780 +#define REG_BAT_FULLCHG_CAP_LOW 0xF781 +#define REG_BAT_DESIGN_VOL_HIGH 0xF782 +#define REG_BAT_DESIGN_VOL_LOW 0xF783 +#define REG_BAT_CURRENT_HIGH 0xF784 +#define REG_BAT_CURRENT_LOW 0xF785 +#define REG_BAT_VOLTAGE_HIGH 0xF786 +#define REG_BAT_VOLTAGE_LOW 0xF787 +#define REG_BAT_TEMPERATURE_HIGH 0xF788 +#define REG_BAT_TEMPERATURE_LOW 0xF789 +#define REG_BAT_RELATIVE_CAP_HIGH 0xF492 +#define REG_BAT_RELATIVE_CAP_LOW 0xF493 +#define REG_BAT_VENDOR 0xF4C4 +#define FLAG_BAT_VENDOR_SANYO 0x01 +#define FLAG_BAT_VENDOR_SIMPLO 0x02 +#define REG_BAT_CELL_COUNT 0xF4C6 +#define FLAG_BAT_CELL_3S1P 0x03 +#define FLAG_BAT_CELL_3S2P 0x06 +#define REG_BAT_CHARGE 0xF4A2 +#define FLAG_BAT_CHARGE_DISCHARGE 0x01 +#define FLAG_BAT_CHARGE_CHARGE 0x02 +#define FLAG_BAT_CHARGE_ACPOWER 0x00 +#define REG_BAT_STATUS 0xF4B0 +#define BIT_BAT_STATUS_LOW (1 << 5) +#define BIT_BAT_STATUS_DESTROY (1 << 2) +#define BIT_BAT_STATUS_FULL (1 << 1) +#define BIT_BAT_STATUS_IN (1 << 0) +#define REG_BAT_CHARGE_STATUS 0xF4B1 +#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2) +#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1) +#define REG_BAT_STATE 0xF482 +#define BIT_BAT_STATE_CHARGING (1 << 1) +#define BIT_BAT_STATE_DISCHARGING (1 << 0) +#define REG_BAT_POWER 0xF440 +#define BIT_BAT_POWER_S3 (1 << 2) +#define BIT_BAT_POWER_ON (1 << 1) +#define BIT_BAT_POWER_ACIN (1 << 0) + +/* other registers */ +/* Audio: rd/wr */ +#define REG_AUDIO_VOLUME 0xF46C +#define REG_AUDIO_MUTE 0xF4E7 +#define REG_AUDIO_BEEP 0xF4D0 +/* USB port power or not: rd/wr */ +#define REG_USB0_FLAG 0xF461 +#define REG_USB1_FLAG 0xF462 +#define REG_USB2_FLAG 0xF463 +#define BIT_USB_FLAG_ON 1 +#define BIT_USB_FLAG_OFF 0 +/* LID */ +#define REG_LID_DETECT 0xF4BD +#define BIT_LID_DETECT_ON 1 +#define BIT_LID_DETECT_OFF 0 +/* CRT */ +#define REG_CRT_DETECT 0xF4AD +#define BIT_CRT_DETECT_PLUG 1 +#define BIT_CRT_DETECT_UNPLUG 0 +/* LCD backlight brightness adjust: 9 levels */ +#define REG_DISPLAY_BRIGHTNESS 0xF4F5 +/* Black screen Status */ +#define BIT_DISPLAY_LCD_ON 1 +#define BIT_DISPLAY_LCD_OFF 0 +/* LCD backlight control: off/restore */ +#define REG_BACKLIGHT_CTRL 0xF7BD +#define BIT_BACKLIGHT_ON 1 +#define BIT_BACKLIGHT_OFF 0 +/* Reset the machine auto-clear: rd/wr */ +#define REG_RESET 0xF4EC +#define BIT_RESET_ON 1 +/* Light the led: rd/wr */ +#define REG_LED 0xF4C8 +#define BIT_LED_RED_POWER (1 << 0) +#define BIT_LED_ORANGE_POWER (1 << 1) +#define BIT_LED_GREEN_CHARGE (1 << 2) +#define BIT_LED_RED_CHARGE (1 << 3) +#define BIT_LED_NUMLOCK (1 << 4) +/* Test led mode, all led on/off */ +#define REG_LED_TEST 0xF4C2 +#define BIT_LED_TEST_IN 1 +#define BIT_LED_TEST_OUT 0 +/* Camera on/off */ +#define REG_CAMERA_STATUS 0xF46A +#define BIT_CAMERA_STATUS_ON 1 +#define BIT_CAMERA_STATUS_OFF 0 +#define REG_CAMERA_CONTROL 0xF7B7 +#define BIT_CAMERA_CONTROL_OFF 0 +#define BIT_CAMERA_CONTROL_ON 1 +/* Wlan Status */ +#define REG_WLAN 0xF4FA +#define BIT_WLAN_ON 1 +#define BIT_WLAN_OFF 0 +#define REG_DISPLAY_LCD 0xF79F + +/* SCI Event Number from EC */ +enum { + EVENT_LID = 0x23, /* LID open/close */ + EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */ + EVENT_SLEEP, /* Fn+F1 for entering sleep mode */ + EVENT_OVERTEMP, /* Over-temperature happened */ + EVENT_CRT_DETECT, /* CRT is connected */ + EVENT_CAMERA, /* Camera on/off */ + EVENT_USB_OC2, /* USB2 Over Current occurred */ + EVENT_USB_OC0, /* USB0 Over Current occurred */ + EVENT_BLACK_SCREEN, /* Turn on/off backlight */ + EVENT_AUDIO_MUTE, /* Mute on/off */ + EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */ + EVENT_AC_BAT, /* AC & Battery relative issue */ + EVENT_AUDIO_VOLUME, /* Volume adjust */ + EVENT_WLAN, /* Wlan on/off */ + EVENT_END +}; + +#endif /* !_EC_KB3310B_H */ diff --git a/arch/mips/loongson64/lemote-2f/irq.c b/arch/mips/loongson64/lemote-2f/irq.c new file mode 100644 index 000000000000..cab5f43e0e29 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/irq.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007 Lemote Inc. + * Author: Fuxin Zhang, zhangfx@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */ +#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */ +#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */ +#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */ + +#define LOONGSON_INT_BIT_INT0 (1 << 11) +#define LOONGSON_INT_BIT_INT1 (1 << 12) + +/* + * The generic i8259_irq() make the kernel hang on booting. Since we cannot + * get the irq via the IRR directly, we access the ISR instead. + */ +int mach_i8259_irq(void) +{ + int irq, isr; + + irq = -1; + + if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) { + raw_spin_lock(&i8259A_lock); + isr = inb(PIC_MASTER_CMD) & + ~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR); + if (!isr) + isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8; + irq = ffs(isr) - 1; + if (unlikely(irq == 7)) { + /* + * This may be a spurious interrupt. + * + * Read the interrupt status register (ISR). If the most + * significant bit is not set then there is no valid + * interrupt. + */ + outb(0x0B, PIC_MASTER_ISR); /* ISR register */ + if (~inb(PIC_MASTER_ISR) & 0x80) + irq = -1; + } + raw_spin_unlock(&i8259A_lock); + } + + return irq; +} +EXPORT_SYMBOL(mach_i8259_irq); + +static void i8259_irqdispatch(void) +{ + int irq; + + irq = mach_i8259_irq(); + if (irq >= 0) + do_IRQ(irq); + else + spurious_interrupt(); +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); + else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */ + do_perfcnt_IRQ(); + bonito_irqdispatch(); + } else if (pending & CAUSEF_IP3) /* CPU UART */ + do_IRQ(LOONGSON_UART_IRQ); + else if (pending & CAUSEF_IP2) /* South Bridge */ + i8259_irqdispatch(); + else + spurious_interrupt(); +} + +static irqreturn_t ip6_action(int cpl, void *dev_id) +{ + return IRQ_HANDLED; +} + +static struct irqaction ip6_irqaction = { + .handler = ip6_action, + .name = "cascade", + .flags = IRQF_SHARED | IRQF_NO_THREAD, +}; + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .name = "cascade", + .flags = IRQF_NO_THREAD, +}; + +void __init mach_init_irq(void) +{ + /* init all controller + * 0-15 ------> i8259 interrupt + * 16-23 ------> mips cpu interrupt + * 32-63 ------> bonito irq + */ + + /* setup cs5536 as high level trigger */ + LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1; + LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1); + + /* Sets the first-level interrupt dispatcher. */ + mips_cpu_irq_init(); + init_i8259_irqs(); + bonito_irq_init(); + + /* setup north bridge irq (bonito) */ + setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction); + /* setup source bridge irq (i8259) */ + setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction); +} diff --git a/arch/mips/loongson64/lemote-2f/machtype.c b/arch/mips/loongson64/lemote-2f/machtype.c new file mode 100644 index 000000000000..b55e6eece5e0 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/machtype.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include + +#include + +void __init mach_prom_init_machtype(void) +{ + /* We share the same kernel image file among Lemote 2F family + * of machines, and provide the machtype= kernel command line + * to users to indicate their machine, this command line will + * be passed by the latest PMON automatically. and fortunately, + * up to now, we can get the machine type from the PMON_VER= + * commandline directly except the NAS machine, In the old + * machines, this will help the users a lot. + * + * If no "machtype=" passed, get machine type from "PMON_VER=". + * PMON_VER=LM8089 Lemote 8.9'' netbook + * LM8101 Lemote 10.1'' netbook + * (The above two netbooks have the same kernel support) + * LM6XXX Lemote FuLoong(2F) box series + * LM9XXX Lemote LynLoong PC series + */ + if (strstr(arcs_cmdline, "PMON_VER=LM")) { + if (strstr(arcs_cmdline, "PMON_VER=LM8")) + mips_machtype = MACH_LEMOTE_YL2F89; + else if (strstr(arcs_cmdline, "PMON_VER=LM6")) + mips_machtype = MACH_LEMOTE_FL2F; + else if (strstr(arcs_cmdline, "PMON_VER=LM9")) + mips_machtype = MACH_LEMOTE_LL2F; + else + mips_machtype = MACH_LEMOTE_NAS; + + strcat(arcs_cmdline, " machtype="); + strcat(arcs_cmdline, get_system_type()); + strcat(arcs_cmdline, " "); + } +} diff --git a/arch/mips/loongson64/lemote-2f/pm.c b/arch/mips/loongson64/lemote-2f/pm.c new file mode 100644 index 000000000000..cac4d382ea73 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/pm.c @@ -0,0 +1,149 @@ +/* + * Lemote loongson2f family machines' specific suspend support + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include "ec_kb3310b.h" + +#define I8042_KBD_IRQ 1 +#define I8042_CTR_KBDINT 0x01 +#define I8042_CTR_KBDDIS 0x10 + +static unsigned char i8042_ctr; + +static int i8042_enable_kbd_port(void) +{ + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { + pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port." + "\n"); + return -EIO; + } + + i8042_ctr &= ~I8042_CTR_KBDDIS; + i8042_ctr |= I8042_CTR_KBDINT; + + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { + i8042_ctr &= ~I8042_CTR_KBDINT; + i8042_ctr |= I8042_CTR_KBDDIS; + pr_err("i8042.c: Failed to enable KBD port.\n"); + + return -EIO; + } + + return 0; +} + +void setup_wakeup_events(void) +{ + int irq_mask; + + switch (mips_machtype) { + case MACH_LEMOTE_ML2F7: + case MACH_LEMOTE_YL2F89: + /* open the keyboard irq in i8259A */ + outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR); + irq_mask = inb(PIC_MASTER_IMR); + + /* enable keyboard port */ + i8042_enable_kbd_port(); + + /* Wakeup CPU via SCI lid open event */ + outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR); + inb(PIC_MASTER_IMR); + outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR); + inb(PIC_SLAVE_IMR); + + break; + + default: + break; + } +} + +static struct delayed_work lid_task; +static int initialized; +/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */ +sci_handler yeeloong_report_lid_status; +EXPORT_SYMBOL(yeeloong_report_lid_status); +static void yeeloong_lid_update_task(struct work_struct *work) +{ + if (yeeloong_report_lid_status) + yeeloong_report_lid_status(BIT_LID_DETECT_ON); +} + +int wakeup_loongson(void) +{ + int irq; + + /* query the interrupt number */ + irq = mach_i8259_irq(); + if (irq < 0) + return 0; + + printk(KERN_INFO "%s: irq = %d\n", __func__, irq); + + if (irq == I8042_KBD_IRQ) + return 1; + else if (irq == SCI_IRQ_NUM) { + int ret, sci_event; + /* query the event number */ + ret = ec_query_seq(CMD_GET_EVENT_NUM); + if (ret < 0) + return 0; + sci_event = ec_get_event_num(); + if (sci_event < 0) + return 0; + if (sci_event == EVENT_LID) { + int lid_status; + /* check the LID status */ + lid_status = ec_read(REG_LID_DETECT); + /* wakeup cpu when people open the LID */ + if (lid_status == BIT_LID_DETECT_ON) { + /* If we call it directly here, the WARNING + * will be sent out by getnstimeofday + * via "WARN_ON(timekeeping_suspended);" + * because we can not schedule in suspend mode. + */ + if (initialized == 0) { + INIT_DELAYED_WORK(&lid_task, + yeeloong_lid_update_task); + initialized = 1; + } + schedule_delayed_work(&lid_task, 1); + return 1; + } + } + } + + return 0; +} + +void __weak mach_suspend(void) +{ + disable_mfgpt0_counter(); +} + +void __weak mach_resume(void) +{ + enable_mfgpt0_counter(); +} diff --git a/arch/mips/loongson64/lemote-2f/reset.c b/arch/mips/loongson64/lemote-2f/reset.c new file mode 100644 index 000000000000..a26ca7fcd7e0 --- /dev/null +++ b/arch/mips/loongson64/lemote-2f/reset.c @@ -0,0 +1,159 @@ +/* Board-specific reboot/shutdown routines + * + * Copyright (c) 2009 Philippe Vachon + * + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include + +#include + +#include +#include "ec_kb3310b.h" + +static void reset_cpu(void) +{ + /* + * reset cpu to full speed, this is needed when enabling cpu frequency + * scalling + */ + LOONGSON_CHIPCFG(0) |= 0x7; +} + +/* reset support for fuloong2f */ + +static void fl2f_reboot(void) +{ + reset_cpu(); + + /* send a reset signal to south bridge. + * + * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset + * normally with this reset operation and it will not work in PMON, but + * you can type halt command and then reboot, seems the hardware reset + * logic not work normally. + */ + { + u32 hi, lo; + _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo); + lo |= 0x00000001; + _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo); + } +} + +static void fl2f_shutdown(void) +{ + u32 hi, lo, val; + int gpio_base; + + /* get gpio base */ + _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo); + gpio_base = lo & 0xff00; + + /* make cs5536 gpio13 output enable */ + val = inl(gpio_base + GPIOL_OUT_EN); + val &= ~(1 << (16 + 13)); + val |= (1 << 13); + outl(val, gpio_base + GPIOL_OUT_EN); + mmiowb(); + /* make cs5536 gpio13 output low level voltage. */ + val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13)); + val |= (1 << (16 + 13)); + outl(val, gpio_base + GPIOL_OUT_VAL); + mmiowb(); +} + +/* reset support for yeeloong2f and mengloong2f notebook */ + +static void ml2f_reboot(void) +{ + reset_cpu(); + + /* sending an reset signal to EC(embedded controller) */ + ec_write(REG_RESET, BIT_RESET_ON); +} + +#define yl2f89_reboot ml2f_reboot + +/* menglong(7inches) laptop has different shutdown logic from 8.9inches */ +#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d +#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e +#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f +#define REG_SHUTDOWN_HIGH 0xFC +#define REG_SHUTDOWN_LOW 0x29 +#define BIT_SHUTDOWN_ON (1 << 1) + +static void ml2f_shutdown(void) +{ + u8 val; + u64 i; + + outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH); + outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW); + mmiowb(); + val = inb(EC_SHUTDOWN_IO_PORT_DATA); + outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA); + mmiowb(); + /* need enough wait here... how many microseconds needs? */ + for (i = 0; i < 0x10000; i++) + delay(); + outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA); + mmiowb(); +} + +static void yl2f89_shutdown(void) +{ + /* cpu-gpio0 output low */ + LOONGSON_GPIODATA &= ~0x00000001; + /* cpu-gpio0 as output */ + LOONGSON_GPIOIE &= ~0x00000001; +} + +void mach_prepare_reboot(void) +{ + switch (mips_machtype) { + case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_NAS: + case MACH_LEMOTE_LL2F: + fl2f_reboot(); + break; + case MACH_LEMOTE_ML2F7: + ml2f_reboot(); + break; + case MACH_LEMOTE_YL2F89: + yl2f89_reboot(); + break; + default: + break; + } +} + +void mach_prepare_shutdown(void) +{ + switch (mips_machtype) { + case MACH_LEMOTE_FL2F: + case MACH_LEMOTE_NAS: + case MACH_LEMOTE_LL2F: + fl2f_shutdown(); + break; + case MACH_LEMOTE_ML2F7: + ml2f_shutdown(); + break; + case MACH_LEMOTE_YL2F89: + yl2f89_shutdown(); + break; + default: + break; + } +} diff --git a/arch/mips/loongson64/loongson-3/Makefile b/arch/mips/loongson64/loongson-3/Makefile new file mode 100644 index 000000000000..622fead5ebc9 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for Loongson-3 family machines +# +obj-y += irq.o cop2-ex.o platform.o + +obj-$(CONFIG_SMP) += smp.o + +obj-$(CONFIG_NUMA) += numa.o + +obj-$(CONFIG_RS780_HPET) += hpet.o diff --git a/arch/mips/loongson64/loongson-3/cop2-ex.c b/arch/mips/loongson64/loongson-3/cop2-ex.c new file mode 100644 index 000000000000..ea13764d0a03 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/cop2-ex.c @@ -0,0 +1,63 @@ +/* + * 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 Lemote Corporation. + * written by Huacai Chen + * + * based on arch/mips/cavium-octeon/cpu.c + * Copyright (C) 2009 Wind River Systems, + * written by Ralf Baechle + */ +#include +#include +#include + +#include +#include +#include +#include + +static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, + void *data) +{ + int fpu_owned; + int fr = !test_thread_flag(TIF_32BIT_FPREGS); + + switch (action) { + case CU2_EXCEPTION: + preempt_disable(); + fpu_owned = __is_fpu_owner(); + if (!fr) + set_c0_status(ST0_CU1 | ST0_CU2); + else + set_c0_status(ST0_CU1 | ST0_CU2 | ST0_FR); + enable_fpu_hazard(); + KSTK_STATUS(current) |= (ST0_CU1 | ST0_CU2); + if (fr) + KSTK_STATUS(current) |= ST0_FR; + else + KSTK_STATUS(current) &= ~ST0_FR; + /* If FPU is owned, we needn't init or restore fp */ + if (!fpu_owned) { + set_thread_flag(TIF_USEDFPU); + if (!used_math()) { + _init_fpu(current->thread.fpu.fcr31); + set_used_math(); + } else + _restore_fp(current); + } + preempt_enable(); + + return NOTIFY_STOP; /* Don't call default notifier */ + } + + return NOTIFY_OK; /* Let default notifier send signals */ +} + +static int __init loongson_cu2_setup(void) +{ + return cu2_notifier(loongson_cu2_call, 0); +} +early_initcall(loongson_cu2_setup); diff --git a/arch/mips/loongson64/loongson-3/hpet.c b/arch/mips/loongson64/loongson-3/hpet.c new file mode 100644 index 000000000000..5c21cd3bd339 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/hpet.c @@ -0,0 +1,257 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000) +#define SMBUS_PCI_REG40 0x40 +#define SMBUS_PCI_REG64 0x64 +#define SMBUS_PCI_REGB4 0xb4 + +static DEFINE_SPINLOCK(hpet_lock); +DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); + +static unsigned int smbus_read(int offset) +{ + return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset); +} + +static void smbus_write(int offset, int data) +{ + *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data; +} + +static void smbus_enable(int offset, int bit) +{ + unsigned int cfg = smbus_read(offset); + + cfg |= bit; + smbus_write(offset, cfg); +} + +static int hpet_read(int offset) +{ + return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset); +} + +static void hpet_write(int offset, int data) +{ + *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data; +} + +static void hpet_start_counter(void) +{ + unsigned int cfg = hpet_read(HPET_CFG); + + cfg |= HPET_CFG_ENABLE; + hpet_write(HPET_CFG, cfg); +} + +static void hpet_stop_counter(void) +{ + unsigned int cfg = hpet_read(HPET_CFG); + + cfg &= ~HPET_CFG_ENABLE; + hpet_write(HPET_CFG, cfg); +} + +static void hpet_reset_counter(void) +{ + hpet_write(HPET_COUNTER, 0); + hpet_write(HPET_COUNTER + 4, 0); +} + +static void hpet_restart_counter(void) +{ + hpet_stop_counter(); + hpet_reset_counter(); + hpet_start_counter(); +} + +static void hpet_enable_legacy_int(void) +{ + /* Do nothing on Loongson-3 */ +} + +static void hpet_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + int cfg = 0; + + spin_lock(&hpet_lock); + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + pr_info("set clock event to periodic mode!\n"); + /* stop counter */ + hpet_stop_counter(); + + /* enables the timer0 to generate a periodic interrupt */ + cfg = hpet_read(HPET_T0_CFG); + cfg &= ~HPET_TN_LEVEL; + cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | + HPET_TN_SETVAL | HPET_TN_32BIT; + hpet_write(HPET_T0_CFG, cfg); + + /* set the comparator */ + hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); + udelay(1); + hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); + + /* start counter */ + hpet_start_counter(); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + cfg = hpet_read(HPET_T0_CFG); + cfg &= ~HPET_TN_ENABLE; + hpet_write(HPET_T0_CFG, cfg); + break; + case CLOCK_EVT_MODE_ONESHOT: + pr_info("set clock event to one shot mode!\n"); + cfg = hpet_read(HPET_T0_CFG); + /* set timer0 type + * 1 : periodic interrupt + * 0 : non-periodic(oneshot) interrupt + */ + cfg &= ~HPET_TN_PERIODIC; + cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; + hpet_write(HPET_T0_CFG, cfg); + break; + case CLOCK_EVT_MODE_RESUME: + hpet_enable_legacy_int(); + break; + } + spin_unlock(&hpet_lock); +} + +static int hpet_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + unsigned int cnt; + int res; + + cnt = hpet_read(HPET_COUNTER); + cnt += delta; + hpet_write(HPET_T0_CMP, cnt); + + res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; + return res; +} + +static irqreturn_t hpet_irq_handler(int irq, void *data) +{ + int is_irq; + struct clock_event_device *cd; + unsigned int cpu = smp_processor_id(); + + is_irq = hpet_read(HPET_STATUS); + if (is_irq & HPET_T0_IRS) { + /* clear the TIMER0 irq status register */ + hpet_write(HPET_STATUS, HPET_T0_IRS); + cd = &per_cpu(hpet_clockevent_device, cpu); + cd->event_handler(cd); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static struct irqaction hpet_irq = { + .handler = hpet_irq_handler, + .flags = IRQF_NOBALANCING | IRQF_TIMER, + .name = "hpet", +}; + +/* + * hpet address assignation and irq setting should be done in bios. + * but pmon don't do this, we just setup here directly. + * The operation under is normal. unfortunately, hpet_setup process + * is before pci initialize. + * + * { + * struct pci_dev *pdev; + * + * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); + * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR); + * + * ... + * } + */ +static void hpet_setup(void) +{ + /* set hpet base address */ + smbus_write(SMBUS_PCI_REGB4, HPET_ADDR); + + /* enable decodeing of access to HPET MMIO*/ + smbus_enable(SMBUS_PCI_REG40, (1 << 28)); + + /* HPET irq enable */ + smbus_enable(SMBUS_PCI_REG64, (1 << 10)); + + hpet_enable_legacy_int(); +} + +void __init setup_hpet_timer(void) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + + hpet_setup(); + + cd = &per_cpu(hpet_clockevent_device, cpu); + cd->name = "hpet"; + cd->rating = 320; + cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; + cd->set_mode = hpet_set_mode; + cd->set_next_event = hpet_next_event; + cd->irq = HPET_T0_IRQ; + cd->cpumask = cpumask_of(cpu); + clockevent_set_clock(cd, HPET_FREQ); + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = 5000; + + clockevents_register_device(cd); + setup_irq(HPET_T0_IRQ, &hpet_irq); + pr_info("hpet clock event device register\n"); +} + +static cycle_t hpet_read_counter(struct clocksource *cs) +{ + return (cycle_t)hpet_read(HPET_COUNTER); +} + +static void hpet_suspend(struct clocksource *cs) +{ +} + +static void hpet_resume(struct clocksource *cs) +{ + hpet_setup(); + hpet_restart_counter(); +} + +static struct clocksource csrc_hpet = { + .name = "hpet", + /* mips clocksource rating is less than 300, so hpet is better. */ + .rating = 300, + .read = hpet_read_counter, + .mask = CLOCKSOURCE_MASK(32), + /* oneshot mode work normal with this flag */ + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .suspend = hpet_suspend, + .resume = hpet_resume, + .mult = 0, + .shift = 10, +}; + +int __init init_hpet_clocksource(void) +{ + csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift); + return clocksource_register_hz(&csrc_hpet, HPET_FREQ); +} + +arch_initcall(init_hpet_clocksource); diff --git a/arch/mips/loongson64/loongson-3/irq.c b/arch/mips/loongson64/loongson-3/irq.c new file mode 100644 index 000000000000..0f75b6b3d218 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/irq.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include "smp.h" + +unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; + +static void ht_irqdispatch(void) +{ + unsigned int i, irq; + + irq = LOONGSON_HT1_INT_VECTOR(0); + LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */ + + for (i = 0; i < ARRAY_SIZE(ht_irq); i++) { + if (irq & (0x1 << ht_irq[i])) + do_IRQ(ht_irq[i]); + } +} + +void mach_irq_dispatch(unsigned int pending) +{ + if (pending & CAUSEF_IP7) + do_IRQ(LOONGSON_TIMER_IRQ); +#if defined(CONFIG_SMP) + else if (pending & CAUSEF_IP6) + loongson3_ipi_interrupt(NULL); +#endif + else if (pending & CAUSEF_IP3) + ht_irqdispatch(); + else if (pending & CAUSEF_IP2) + do_IRQ(LOONGSON_UART_IRQ); + else { + pr_err("%s : spurious interrupt\n", __func__); + spurious_interrupt(); + } +} + +static struct irqaction cascade_irqaction = { + .handler = no_action, + .flags = IRQF_NO_SUSPEND, + .name = "cascade", +}; + +static inline void mask_loongson_irq(struct irq_data *d) +{ + clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); + irq_disable_hazard(); + + /* Workaround: UART IRQ may deliver to any core */ + if (d->irq == LOONGSON_UART_IRQ) { + int cpu = smp_processor_id(); + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; + u64 intenclr_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_INTENCLR); + u64 introuter_lpc_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_LPC); + + *(volatile u32 *)intenclr_addr = 1 << 10; + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq == LOONGSON_UART_IRQ) { + int cpu = smp_processor_id(); + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; + u64 intenset_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_INTENSET); + u64 introuter_lpc_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_LPC); + + *(volatile u32 *)intenset_addr = 1 << 10; + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<irq - MIPS_CPU_IRQ_BASE)); + irq_enable_hazard(); +} + + /* For MIPS IRQs which shared by all cores */ +static struct irq_chip loongson_irq_chip = { + .name = "Loongson", + .irq_ack = mask_loongson_irq, + .irq_mask = mask_loongson_irq, + .irq_mask_ack = mask_loongson_irq, + .irq_unmask = unmask_loongson_irq, + .irq_eoi = unmask_loongson_irq, +}; + +void irq_router_init(void) +{ + int i; + + /* route LPC int to cpu core0 int 0 */ + LOONGSON_INT_ROUTER_LPC = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); + /* route HT1 int0 ~ int7 to cpu core0 INT1*/ + for (i = 0; i < 8; i++) + LOONGSON_INT_ROUTER_HT1(i) = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); + /* enable HT1 interrupt */ + LOONGSON_HT1_INTN_EN(0) = 0xffffffff; + /* enable router interrupt intenset */ + LOONGSON_INT_ROUTER_INTENSET = + LOONGSON_INT_ROUTER_INTEN | (0xffff << 16) | 0x1 << 10; +} + +void __init mach_init_irq(void) +{ + clear_c0_status(ST0_IM | ST0_BEV); + + irq_router_init(); + mips_cpu_irq_init(); + init_i8259_irqs(); + irq_set_chip_and_handler(LOONGSON_UART_IRQ, + &loongson_irq_chip, handle_level_irq); + + /* setup HT1 irq */ + setup_irq(LOONGSON_HT1_IRQ, &cascade_irqaction); + + set_c0_status(STATUSF_IP2 | STATUSF_IP6); +} + +#ifdef CONFIG_HOTPLUG_CPU + +void fixup_irqs(void) +{ + irq_cpu_offline(); + clear_c0_status(ST0_IM); +} + +#endif diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c new file mode 100644 index 000000000000..12d14ed48778 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/numa.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & + * Insititute of Computing Technology + * Author: Xiang Gao, gaoxiang@ict.ac.cn + * Huacai Chen, chenhc@lemote.com + * Xiaofu Meng, Shuangshuang Zhang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct node_data prealloc__node_data[MAX_NUMNODES]; +unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; +EXPORT_SYMBOL(__node_distances); +struct node_data *__node_data[MAX_NUMNODES]; +EXPORT_SYMBOL(__node_data); + +static void enable_lpa(void) +{ + unsigned long value; + + value = __read_32bit_c0_register($16, 3); + value |= 0x00000080; + __write_32bit_c0_register($16, 3, value); + value = __read_32bit_c0_register($16, 3); + pr_info("CP0_Config3: CP0 16.3 (0x%lx)\n", value); + + value = __read_32bit_c0_register($5, 1); + value |= 0x20000000; + __write_32bit_c0_register($5, 1, value); + value = __read_32bit_c0_register($5, 1); + pr_info("CP0_PageGrain: CP0 5.1 (0x%lx)\n", value); +} + +static void cpu_node_probe(void) +{ + int i; + + nodes_clear(node_possible_map); + nodes_clear(node_online_map); + for (i = 0; i < loongson_sysconf.nr_nodes; i++) { + node_set_state(num_online_nodes(), N_POSSIBLE); + node_set_online(num_online_nodes()); + } + + pr_info("NUMA: Discovered %d cpus on %d nodes\n", + loongson_sysconf.nr_cpus, num_online_nodes()); +} + +static int __init compute_node_distance(int row, int col) +{ + int package_row = row * loongson_sysconf.cores_per_node / + loongson_sysconf.cores_per_package; + int package_col = col * loongson_sysconf.cores_per_node / + loongson_sysconf.cores_per_package; + + if (col == row) + return 0; + else if (package_row == package_col) + return 40; + else + return 100; +} + +static void __init init_topology_matrix(void) +{ + int row, col; + + for (row = 0; row < MAX_NUMNODES; row++) + for (col = 0; col < MAX_NUMNODES; col++) + __node_distances[row][col] = -1; + + for_each_online_node(row) { + for_each_online_node(col) { + __node_distances[row][col] = + compute_node_distance(row, col); + } + } +} + +static unsigned long nid_to_addroffset(unsigned int nid) +{ + unsigned long result; + switch (nid) { + case 0: + default: + result = NODE0_ADDRSPACE_OFFSET; + break; + case 1: + result = NODE1_ADDRSPACE_OFFSET; + break; + case 2: + result = NODE2_ADDRSPACE_OFFSET; + break; + case 3: + result = NODE3_ADDRSPACE_OFFSET; + break; + } + return result; +} + +static void __init szmem(unsigned int node) +{ + u32 i, mem_type; + static unsigned long num_physpages = 0; + u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; + + /* Parse memory information and activate */ + for (i = 0; i < loongson_memmap->nr_map; i++) { + node_id = loongson_memmap->map[i].node_id; + if (node_id != node) + continue; + + mem_type = loongson_memmap->map[i].mem_type; + mem_size = loongson_memmap->map[i].mem_size; + mem_start = loongson_memmap->map[i].mem_start; + + switch (mem_type) { + case SYSTEM_RAM_LOW: + start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; + node_psize = (mem_size << 20) >> PAGE_SHIFT; + end_pfn = start_pfn + node_psize; + num_physpages += node_psize; + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", + (u32)node_id, mem_type, mem_start, mem_size); + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", + start_pfn, end_pfn, num_physpages); + add_memory_region((node_id << 44) + mem_start, + (u64)mem_size << 20, BOOT_MEM_RAM); + memblock_add_node(PFN_PHYS(start_pfn), + PFN_PHYS(end_pfn - start_pfn), node); + break; + case SYSTEM_RAM_HIGH: + start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; + node_psize = (mem_size << 20) >> PAGE_SHIFT; + end_pfn = start_pfn + node_psize; + num_physpages += node_psize; + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", + (u32)node_id, mem_type, mem_start, mem_size); + pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", + start_pfn, end_pfn, num_physpages); + add_memory_region((node_id << 44) + mem_start, + (u64)mem_size << 20, BOOT_MEM_RAM); + memblock_add_node(PFN_PHYS(start_pfn), + PFN_PHYS(end_pfn - start_pfn), node); + break; + case MEM_RESERVED: + pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", + (u32)node_id, mem_type, mem_start, mem_size); + add_memory_region((node_id << 44) + mem_start, + (u64)mem_size << 20, BOOT_MEM_RESERVED); + memblock_reserve(((node_id << 44) + mem_start), + mem_size << 20); + break; + } + } +} + +static void __init node_mem_init(unsigned int node) +{ + unsigned long bootmap_size; + unsigned long node_addrspace_offset; + unsigned long start_pfn, end_pfn, freepfn; + + node_addrspace_offset = nid_to_addroffset(node); + pr_info("Node%d's addrspace_offset is 0x%lx\n", + node, node_addrspace_offset); + + get_pfn_range_for_nid(node, &start_pfn, &end_pfn); + freepfn = start_pfn; + if (node == 0) + freepfn = PFN_UP(__pa_symbol(&_end)); /* kernel end address */ + pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx, freepfn=0x%lx\n", + node, start_pfn, end_pfn, freepfn); + + __node_data[node] = prealloc__node_data + node; + + NODE_DATA(node)->bdata = &bootmem_node_data[node]; + NODE_DATA(node)->node_start_pfn = start_pfn; + NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; + + bootmap_size = init_bootmem_node(NODE_DATA(node), freepfn, + start_pfn, end_pfn); + free_bootmem_with_active_regions(node, end_pfn); + if (node == 0) /* used by finalize_initrd() */ + max_low_pfn = end_pfn; + + /* This is reserved for the kernel and bdata->node_bootmem_map */ + reserve_bootmem_node(NODE_DATA(node), start_pfn << PAGE_SHIFT, + ((freepfn - start_pfn) << PAGE_SHIFT) + bootmap_size, + BOOTMEM_DEFAULT); + + if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { + /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */ + reserve_bootmem_node(NODE_DATA(node), + (node_addrspace_offset | 0xff800000), + 8 << 20, BOOTMEM_DEFAULT); + } + + sparse_memory_present_with_active_regions(node); +} + +static __init void prom_meminit(void) +{ + unsigned int node, cpu, active_cpu = 0; + + cpu_node_probe(); + init_topology_matrix(); + + for (node = 0; node < loongson_sysconf.nr_nodes; node++) { + if (node_online(node)) { + szmem(node); + node_mem_init(node); + cpumask_clear(&__node_data[(node)]->cpumask); + } + } + for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { + node = cpu / loongson_sysconf.cores_per_node; + if (node >= num_online_nodes()) + node = 0; + + if (loongson_sysconf.reserved_cpus_mask & (1<cpumask); + pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); + + active_cpu++; + } +} + +void __init paging_init(void) +{ + unsigned node; + unsigned long zones_size[MAX_NR_ZONES] = {0, }; + + pagetable_init(); + + for_each_online_node(node) { + unsigned long start_pfn, end_pfn; + + get_pfn_range_for_nid(node, &start_pfn, &end_pfn); + + if (end_pfn > max_low_pfn) + max_low_pfn = end_pfn; + } +#ifdef CONFIG_ZONE_DMA32 + zones_size[ZONE_DMA32] = MAX_DMA32_PFN; +#endif + zones_size[ZONE_NORMAL] = max_low_pfn; + free_area_init_nodes(zones_size); +} + +void __init mem_init(void) +{ + high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); + free_all_bootmem(); + setup_zero_pages(); /* This comes from node 0 */ + mem_init_print_info(NULL); +} + +/* All PCI device belongs to logical Node-0 */ +int pcibus_to_node(struct pci_bus *bus) +{ + return 0; +} +EXPORT_SYMBOL(pcibus_to_node); + +void __init prom_init_numa_memory(void) +{ + enable_lpa(); + prom_meminit(); +} +EXPORT_SYMBOL(prom_init_numa_memory); diff --git a/arch/mips/loongson64/loongson-3/platform.c b/arch/mips/loongson64/loongson-3/platform.c new file mode 100644 index 000000000000..25a97cc0ee33 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/platform.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Lemote Inc. + * Author: Wu Zhangjin, wuzhangjin@gmail.com + * Xiang Yu, xiangy@lemote.com + * Chen Huacai, chenhc@lemote.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int __init loongson3_platform_init(void) +{ + int i; + struct platform_device *pdev; + + if (loongson_sysconf.ecname[0] != '\0') + platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0); + + for (i = 0; i < loongson_sysconf.nr_sensors; i++) { + if (loongson_sysconf.sensors[i].type > SENSOR_FAN) + continue; + + pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); + pdev->name = loongson_sysconf.sensors[i].name; + pdev->id = loongson_sysconf.sensors[i].id; + pdev->dev.platform_data = &loongson_sysconf.sensors[i]; + platform_device_register(pdev); + } + + return 0; +} + +arch_initcall(loongson3_platform_init); diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c new file mode 100644 index 000000000000..509877c6e9d9 --- /dev/null +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -0,0 +1,652 @@ +/* + * Copyright (C) 2010, 2011, 2012, Lemote, Inc. + * Author: Chen Huacai, chenhc@lemote.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smp.h" + +DEFINE_PER_CPU(int, cpu_state); +DEFINE_PER_CPU(uint32_t, core0_c0count); + +static void *ipi_set0_regs[16]; +static void *ipi_clear0_regs[16]; +static void *ipi_status0_regs[16]; +static void *ipi_en0_regs[16]; +static void *ipi_mailbox_buf[16]; + +/* read a 32bit value from ipi register */ +#define loongson3_ipi_read32(addr) readl(addr) +/* read a 64bit value from ipi register */ +#define loongson3_ipi_read64(addr) readq(addr) +/* write a 32bit value to ipi register */ +#define loongson3_ipi_write32(action, addr) \ + do { \ + writel(action, addr); \ + __wbflush(); \ + } while (0) +/* write a 64bit value to ipi register */ +#define loongson3_ipi_write64(action, addr) \ + do { \ + writeq(action, addr); \ + __wbflush(); \ + } while (0) + +static void ipi_set0_regs_init(void) +{ + ipi_set0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0); + ipi_set0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0); + ipi_set0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0); + ipi_set0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0); + ipi_set0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0); + ipi_set0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0); + ipi_set0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0); +} + +static void ipi_clear0_regs_init(void) +{ + ipi_clear0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0); + ipi_clear0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0); + ipi_clear0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0); + ipi_clear0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0); + ipi_clear0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0); + ipi_clear0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0); + ipi_clear0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0); +} + +static void ipi_status0_regs_init(void) +{ + ipi_status0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0); + ipi_status0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0); + ipi_status0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0); + ipi_status0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0); + ipi_status0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0); + ipi_status0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0); + ipi_status0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0); +} + +static void ipi_en0_regs_init(void) +{ + ipi_en0_regs[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0); + ipi_en0_regs[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0); + ipi_en0_regs[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0); + ipi_en0_regs[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0); + ipi_en0_regs[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0); + ipi_en0_regs[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0); + ipi_en0_regs[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0); +} + +static void ipi_mailbox_buf_init(void) +{ + ipi_mailbox_buf[0] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[1] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[2] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[3] = (void *) + (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF); + ipi_mailbox_buf[4] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[5] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[6] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[7] = (void *) + (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF); + ipi_mailbox_buf[8] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[9] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[10] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[11] = (void *) + (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF); + ipi_mailbox_buf[12] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF); + ipi_mailbox_buf[13] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF); + ipi_mailbox_buf[14] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF); + ipi_mailbox_buf[15] = (void *) + (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF); +} + +/* + * Simple enough, just poke the appropriate ipi register + */ +static void loongson3_send_ipi_single(int cpu, unsigned int action) +{ + loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]); +} + +static void +loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) +{ + unsigned int i; + + for_each_cpu(i, mask) + loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]); +} + +void loongson3_ipi_interrupt(struct pt_regs *regs) +{ + int i, cpu = smp_processor_id(); + unsigned int action, c0count; + + /* Load the ipi register to figure out what we're supposed to do */ + action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); + + /* Clear the ipi register to clear the interrupt */ + loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]); + + if (action & SMP_RESCHEDULE_YOURSELF) + scheduler_ipi(); + + if (action & SMP_CALL_FUNCTION) + smp_call_function_interrupt(); + + if (action & SMP_ASK_C0COUNT) { + BUG_ON(cpu != 0); + c0count = read_c0_count(); + for (i = 1; i < num_possible_cpus(); i++) + per_cpu(core0_c0count, i) = c0count; + } +} + +#define MAX_LOOPS 1111 +/* + * SMP init and finish on secondary CPUs + */ +static void loongson3_init_secondary(void) +{ + int i; + uint32_t initcount; + unsigned int cpu = smp_processor_id(); + unsigned int imask = STATUSF_IP7 | STATUSF_IP6 | + STATUSF_IP3 | STATUSF_IP2; + + /* Set interrupt mask, but don't enable */ + change_c0_status(ST0_IM, imask); + + for (i = 0; i < num_possible_cpus(); i++) + loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); + + per_cpu(cpu_state, cpu) = CPU_ONLINE; + cpu_data[cpu].core = + cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; + cpu_data[cpu].package = + cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; + + i = 0; + __this_cpu_write(core0_c0count, 0); + loongson3_send_ipi_single(0, SMP_ASK_C0COUNT); + while (!__this_cpu_read(core0_c0count)) { + i++; + cpu_relax(); + } + + if (i > MAX_LOOPS) + i = MAX_LOOPS; + initcount = __this_cpu_read(core0_c0count) + i; + write_c0_count(initcount); +} + +static void loongson3_smp_finish(void) +{ + int cpu = smp_processor_id(); + + write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); + local_irq_enable(); + loongson3_ipi_write64(0, + (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); + pr_info("CPU#%d finished, CP0_ST=%x\n", + smp_processor_id(), read_c0_status()); +} + +static void __init loongson3_smp_setup(void) +{ + int i = 0, num = 0; /* i: physical id, num: logical id */ + + init_cpu_possible(cpu_none_mask); + + /* For unified kernel, NR_CPUS is the maximum possible value, + * loongson_sysconf.nr_cpus is the really present value */ + while (i < loongson_sysconf.nr_cpus) { + if (loongson_sysconf.reserved_cpus_mask & (1< #include -#include -#include +#include +#include static struct { struct device *dev; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 0fe4ad8826b2..354b908a03d8 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1484,7 +1484,7 @@ config RTC_DRV_PUV3 config RTC_DRV_LOONGSON1 tristate "loongson1 RTC support" - depends on MACH_LOONGSON1 + depends on MACH_LOONGSON32 help This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year counter) to be used as a RTC. diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c index 8445e564094a..22a9ec4f2b83 100644 --- a/drivers/rtc/rtc-ls1x.c +++ b/drivers/rtc/rtc-ls1x.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #define LS1X_RTC_REG_OFFSET (LS1X_RTC_BASE + 0x20) #define LS1X_RTC_REGS(x) \ -- cgit v1.2.3 From 52ea7bff5ddc3f534aef28b7a20b9b11bf9a4df0 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 1 Jun 2015 00:40:32 +0300 Subject: MIPS: Get rid of 'kgdb_early_setup' cruft. Commit 854700115ecf ([MIPS] kgdb: add arch support for the kernel's kgdb core) added the 'kgdb_early_setup' flag to avoid calling trap_init() and init_IRQ() the second time, however the code that called these functions earlier, from kgdb_arch_init(), had been already removed by that time, so the flag never served any useful purpose. Remove the related code along with ugly #ifdef'ery at last. [ralf@linux-mips.org: Folded in Guenter Roeck's fix.] Signed-off-by: Sergei Shtylyov Patchwork: https://patchwork.linux-mips.org/patch/10501/ Signed-off-by: Guenter Roeck Patchwork: https://patchwork.linux-mips.org/patch/10533/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/kgdb.h | 1 - arch/mips/kernel/irq.c | 14 -------------- arch/mips/kernel/kgdb.c | 4 ---- arch/mips/kernel/traps.c | 5 ----- 4 files changed, 24 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/kgdb.h b/arch/mips/include/asm/kgdb.h index e6c0b0e14ccb..69dc0df94a96 100644 --- a/arch/mips/include/asm/kgdb.h +++ b/arch/mips/include/asm/kgdb.h @@ -33,7 +33,6 @@ #define CACHE_FLUSH_IS_SAFE 0 extern void arch_kgdb_breakpoint(void); -extern int kgdb_early_setup; extern void *saved_vectors[32]; extern void handle_exception(struct pt_regs *regs); extern void breakinst(void); diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 3c8a18a00a65..c3d831a8c479 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -25,10 +25,6 @@ #include #include -#ifdef CONFIG_KGDB -int kgdb_early_setup; -#endif - static DECLARE_BITMAP(irq_map, NR_IRQS); int allocate_irqno(void) @@ -93,20 +89,10 @@ void __init init_IRQ(void) { int i; -#ifdef CONFIG_KGDB - if (kgdb_early_setup) - return; -#endif - for (i = 0; i < NR_IRQS; i++) irq_set_noprobe(i); arch_init_irq(); - -#ifdef CONFIG_KGDB - if (!kgdb_early_setup) - kgdb_early_setup = 1; -#endif } #ifdef CONFIG_DEBUG_STACKOVERFLOW diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 7afcc2f22c0d..de63d36af895 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -378,10 +378,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, struct kgdb_arch arch_kgdb_ops; -/* - * We use kgdb_early_setup so that functions we need to call now don't - * cause trouble when called again later. - */ int kgdb_arch_init(void) { union mips_instruction insn = { diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 1d6dd12fe940..2a7b38ed23f0 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -2185,11 +2185,6 @@ void __init trap_init(void) check_wait(); -#if defined(CONFIG_KGDB) - if (kgdb_early_setup) - return; /* Already done */ -#endif - if (cpu_has_veic || cpu_has_vint) { unsigned long size = 0x200 + VECTORSPACING*64; ebase = (unsigned long) -- cgit v1.2.3 From 0ebb2f4159af24dd4143c8e38a10caa13ddba0c9 Mon Sep 17 00:00:00 2001 From: Joshua Kinard Date: Tue, 2 Jun 2015 18:03:31 -0400 Subject: MIPS: IP27: Update/restructure CPU overrides Inspired by Maciej's recent patch to update DEC cpu-feature-overrides.h, I updated IP27's as well to disable features known to not apply to the IP27 platform or the R10K-series of CPUs. Before: text data bss dec hex filename 8616648 463200 472240 9552088 91c0d8 vmlinux After: text data bss dec hex filename 8592256 471392 472240 9535888 918190 vmlinux I believe the increase in the size of the data section is for the same reasons as in the DEC patch. Signed-off-by: Joshua Kinard Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle --- .../include/asm/mach-ip27/cpu-feature-overrides.h | 92 ++++++++++++++-------- 1 file changed, 57 insertions(+), 35 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h index d6111aa2e886..7449794eade6 100644 --- a/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h @@ -11,47 +11,69 @@ #include /* - * IP27 only comes with R10000 family processors all using the same config + * IP27 only comes with R1x000 family processors, all using the same config */ -#define cpu_has_watch 1 -#define cpu_has_mips16 0 -#define cpu_has_divec 0 -#define cpu_has_vce 0 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_prefetch 1 -#define cpu_has_mcheck 0 -#define cpu_has_ejtag 0 +#define cpu_has_tlb 1 +#define cpu_has_tlbinv 0 +#define cpu_has_segments 0 +#define cpu_has_eva 0 +#define cpu_has_htw 0 +#define cpu_has_rixiex 0 +#define cpu_has_maar 0 +#define cpu_has_rw_llb 0 +#define cpu_has_3kex 0 +#define cpu_has_4kex 1 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 1 +#define cpu_has_6k_cache 0 +#define cpu_has_8k_cache 0 +#define cpu_has_tx39_cache 0 +#define cpu_has_fpu 1 +#define cpu_has_nofpuex 0 +#define cpu_has_32fpr 1 +#define cpu_has_counter 1 +#define cpu_has_watch 1 +#define cpu_has_64bits 1 +#define cpu_has_divec 0 +#define cpu_has_vce 0 +#define cpu_has_cache_cdex_p 0 +#define cpu_has_cache_cdex_s 0 +#define cpu_has_prefetch 1 +#define cpu_has_mcheck 0 +#define cpu_has_ejtag 0 +#define cpu_has_llsc 1 +#define cpu_has_mips16 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 +#define cpu_has_rixi 0 +#define cpu_has_xpa 0 +#define cpu_has_vtag_icache 0 +#define cpu_has_dc_aliases 0 +#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_llsc 1 -#define cpu_has_vtag_icache 0 -#define cpu_has_dc_aliases 0 -#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_dsp 0 -#define cpu_has_dsp2 0 #define cpu_icache_snoops_remote_store 1 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 -#define cpu_has_nofpuex 0 -#define cpu_has_64bits 1 - -#define cpu_has_4kex 1 -#define cpu_has_3k_cache 0 -#define cpu_has_6k_cache 0 -#define cpu_has_4k_cache 1 -#define cpu_has_8k_cache 0 -#define cpu_has_tx39_cache 0 +#define cpu_has_mips32r1 0 +#define cpu_has_mips32r2 0 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 +#define cpu_has_mips32r6 0 +#define cpu_has_mips64r6 0 +#define cpu_has_dsp 0 +#define cpu_has_dsp2 0 +#define cpu_has_mipsmt 0 +#define cpu_has_userlocal 0 #define cpu_has_inclusive_pcaches 1 +#define cpu_hwrena_impl_bits 0 +#define cpu_has_perf_cntr_intr_bit 0 +#define cpu_has_vz 0 +#define cpu_has_fre 0 +#define cpu_has_cdmm 0 -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 64 -#define cpu_scache_line_size() 128 - -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips64r1 0 -#define cpu_has_mips64r2 0 +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 64 +#define cpu_scache_line_size() 128 #endif /* __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H */ -- cgit v1.2.3 From 8d5ded16ee7564736b82c2eae89ba0173b45f157 Mon Sep 17 00:00:00 2001 From: Joshua Kinard Date: Tue, 2 Jun 2015 18:21:33 -0400 Subject: MIPS: R12000: Enable branch prediction global history The R12000 added a new feature to enhance branch prediction called "global history". Per the Vr10000 Series User Manual (U10278EJ4V0UM), Coprocessor 0, Diagnostic Register (22): """ If bit 26 is set, branch prediction uses all eight bits of the global history register. If bit 26 is not set, then bits 25:23 specify a count of the number of bits of global history to be used. Thus if bits 26:23 are all zero, global history is disabled. The global history contains a record of the taken/not-taken status of recently executed branches, and when used is XOR'ed with the PC of a branch being predicted to produce a hashed value for indexing the BPT. Some programs with small "working set of conditional branches" benefit significantly from the use of such hashing, some see slight performance degradation. """ This patch enables global history on R12000 CPUs and up by setting bit 26 in the branch prediction diagnostic register (CP0 $22) to '1'. Bits 25:23 are left alone so that all eight bits of the global history register are available for branch prediction. Signed-off-by: Joshua Kinard Signed-off-by: Ralf Baechle --- arch/mips/include/asm/cpu-features.h | 3 +++ arch/mips/include/asm/cpu.h | 1 + arch/mips/include/asm/mipsregs.h | 13 +++++++++++++ arch/mips/kernel/cpu-probe.c | 8 ++++++-- 4 files changed, 23 insertions(+), 2 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 5aeaf19c26b0..f25de771f7ed 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -108,6 +108,9 @@ #ifndef cpu_has_llsc #define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC) #endif +#ifndef cpu_has_bp_ghist +#define cpu_has_bp_ghist (cpu_data[0].options & MIPS_CPU_BP_GHIST) +#endif #ifndef kernel_uses_llsc #define kernel_uses_llsc cpu_has_llsc #endif diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 73dd35787d1a..e46e40602af3 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -381,6 +381,7 @@ enum cpu_type_enum { #define MIPS_CPU_RW_LLB 0x1000000000ull /* LLADDR/LLB writes are allowed */ #define MIPS_CPU_XPA 0x2000000000ull /* CPU supports Extended Physical Addressing */ #define MIPS_CPU_CDMM 0x4000000000ull /* CPU has Common Device Memory Map */ +#define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */ /* * CPU ASE encodings diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 3b5a145af659..c5b0956a8530 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -707,6 +707,15 @@ #define TX39_CONF_DRSIZE_SHIFT 0 #define TX39_CONF_DRSIZE_MASK 0x00000003 +/* + * Interesting Bits in the R10K CP0 Branch Diagnostic Register + */ +/* Disable Branch Target Address Cache */ +#define R10K_DIAG_D_BTAC (_ULCAST_(1) << 27) +/* Enable Branch Prediction Global History */ +#define R10K_DIAG_E_GHIST (_ULCAST_(1) << 26) +/* Disable Branch Return Cache */ +#define R10K_DIAG_D_BRC (_ULCAST_(1) << 22) /* * Coprocessor 1 (FPU) register names @@ -1269,6 +1278,10 @@ do { \ #define read_c0_diag() __read_32bit_c0_register($22, 0) #define write_c0_diag(val) __write_32bit_c0_register($22, 0, val) +/* R10K CP0 Branch Diagnostic register is 64bits wide */ +#define read_c0_r10k_diag() __read_64bit_c0_register($22, 0) +#define write_c0_r10k_diag(val) __write_64bit_c0_register($22, 0, val) + #define read_c0_diag1() __read_32bit_c0_register($22, 1) #define write_c0_diag1(val) __write_32bit_c0_register($22, 1, val) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index f89eaa79785a..dbe0792fc9c1 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -945,7 +945,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC; + MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST; c->tlbsize = 64; break; case PRID_IMP_R14000: @@ -960,7 +960,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | - MIPS_CPU_LLSC; + MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST; c->tlbsize = 64; break; case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */ @@ -1480,6 +1480,10 @@ void cpu_probe(void) else cpu_set_nofpu_opts(c); + if (cpu_has_bp_ghist) + write_c0_r10k_diag(read_c0_r10k_diag() | + R10K_DIAG_E_GHIST); + if (cpu_has_mips_r2_r6) { c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; /* R2 has Performance Counter Interrupt indicator */ -- cgit v1.2.3 From 01306aeadd75f8202bbeb66bf3da56b431364519 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 2 Jun 2015 17:46:42 -0500 Subject: MIPS: prepare for user enabling of CONFIG_OF In preparation to allow users to enable DeviceTree without arch or machine selecting it, we need to fix build errors on MIPS. When CONFIG_OF is enabled, device_tree_init cannot be resolved. This is trivially fixed by using CONFIG_USE_OF instead of CONFIG_OF for prom.h. Signed-off-by: Rob Herring Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle --- arch/mips/include/asm/prom.h | 2 +- arch/mips/kernel/prom.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index 8ebc2aa5f3e1..0b4b668925f6 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h @@ -11,7 +11,7 @@ #ifndef __ASM_PROM_H #define __ASM_PROM_H -#ifdef CONFIG_OF +#ifdef CONFIG_USE_OF #include #include #include diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index e303cb1ef2f4..b130033838ba 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -18,6 +18,7 @@ #include #include +#include #include #include -- cgit v1.2.3 From 12060666f5c0659d28e31cbf6973af1dfa43c0e7 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 24 May 2015 16:31:44 +0100 Subject: MIPS: Optimise non-EVA kernel user memory accesses Commits ac1d8590d3ae (MIPS: asm: uaccess: Use EVA instructions wrappers), 05c6516005c4 (MIPS: asm: uaccess: Add EVA support to copy_{in, to,from}_user) & e3a9b07a9caf (MIPS: asm: uaccess: Add EVA support for str*_user operations) added checks to various user memory access functions & macros in order to determine whether to perform standard memory accesses or their EVA userspace equivalents. In kernels built without support for EVA these checks are entirely redundant. Avoid emitting them & allow the compiler to optimise out the EVA userspace code in such kernels by checking config_enabled(CONFIG_EVA). This reduces the size of a malta_defconfig kernel built using GCC 4.9.2 by approximately 33KB (from 5995072 to 5962304 bytes). Signed-off-by: Paul Burton Cc: Markos Chandras Cc: Ralf Baechle Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/10165/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/uaccess.h | 47 +++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index bf8b32450ef6..6ed061dfa3ee 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -78,6 +78,21 @@ extern u64 __ua_limit; #define segment_eq(a, b) ((a).seg == (b).seg) +/* + * eva_kernel_access() - determine whether kernel memory access on an EVA system + * + * Determines whether memory accesses should be performed to kernel memory + * on a system using Extended Virtual Addressing (EVA). + * + * Return: true if a kernel memory access on an EVA system, else false. + */ +static inline bool eva_kernel_access(void) +{ + if (!config_enabled(CONFIG_EVA)) + return false; + + return segment_eq(get_fs(), get_ds()); +} /* * Is a address valid? This does a straighforward calculation rather @@ -281,7 +296,7 @@ do { \ ({ \ int __gu_err; \ \ - if (segment_eq(get_fs(), get_ds())) { \ + if (eva_kernel_access()) { \ __get_kernel_common((x), size, ptr); \ } else { \ __chk_user_ptr(ptr); \ @@ -297,7 +312,7 @@ do { \ \ might_fault(); \ if (likely(access_ok(VERIFY_READ, __gu_ptr, size))) { \ - if (segment_eq(get_fs(), get_ds())) \ + if (eva_kernel_access()) \ __get_kernel_common((x), size, __gu_ptr); \ else \ __get_user_common((x), size, __gu_ptr); \ @@ -422,7 +437,7 @@ do { \ int __pu_err = 0; \ \ __pu_val = (x); \ - if (segment_eq(get_fs(), get_ds())) { \ + if (eva_kernel_access()) { \ __put_kernel_common(ptr, size); \ } else { \ __chk_user_ptr(ptr); \ @@ -439,7 +454,7 @@ do { \ \ might_fault(); \ if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) { \ - if (segment_eq(get_fs(), get_ds())) \ + if (eva_kernel_access()) \ __put_kernel_common(__pu_addr, size); \ else \ __put_user_common(__pu_addr, size); \ @@ -833,7 +848,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); __cu_from = (from); \ __cu_len = (n); \ might_fault(); \ - if (segment_eq(get_fs(), get_ds())) \ + if (eva_kernel_access()) \ __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ __cu_len); \ else \ @@ -853,7 +868,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ - if (segment_eq(get_fs(), get_ds())) \ + if (eva_kernel_access()) \ __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ __cu_len); \ else \ @@ -871,7 +886,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ - if (segment_eq(get_fs(), get_ds())) \ + if (eva_kernel_access()) \ __cu_len = __invoke_copy_from_kernel_inatomic(__cu_to, \ __cu_from,\ __cu_len);\ @@ -904,7 +919,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ - if (segment_eq(get_fs(), get_ds())) { \ + if (eva_kernel_access()) { \ __cu_len = __invoke_copy_to_kernel(__cu_to, \ __cu_from, \ __cu_len); \ @@ -1126,7 +1141,7 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ - if (segment_eq(get_fs(), get_ds())) { \ + if (eva_kernel_access()) { \ __cu_len = __invoke_copy_from_kernel(__cu_to, \ __cu_from, \ __cu_len); \ @@ -1150,7 +1165,7 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ - if (segment_eq(get_fs(), get_ds())) { \ + if (eva_kernel_access()) { \ __cu_len = ___invoke_copy_in_kernel(__cu_to, __cu_from, \ __cu_len); \ } else { \ @@ -1170,7 +1185,7 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ - if (segment_eq(get_fs(), get_ds())) { \ + if (eva_kernel_access()) { \ __cu_len = ___invoke_copy_in_kernel(__cu_to,__cu_from, \ __cu_len); \ } else { \ @@ -1250,7 +1265,7 @@ __strncpy_from_user(char *__to, const char __user *__from, long __len) { long res; - if (segment_eq(get_fs(), get_ds())) { + if (eva_kernel_access()) { __asm__ __volatile__( "move\t$4, %1\n\t" "move\t$5, %2\n\t" @@ -1299,7 +1314,7 @@ strncpy_from_user(char *__to, const char __user *__from, long __len) { long res; - if (segment_eq(get_fs(), get_ds())) { + if (eva_kernel_access()) { __asm__ __volatile__( "move\t$4, %1\n\t" "move\t$5, %2\n\t" @@ -1343,7 +1358,7 @@ static inline long strlen_user(const char __user *s) { long res; - if (segment_eq(get_fs(), get_ds())) { + if (eva_kernel_access()) { __asm__ __volatile__( "move\t$4, %1\n\t" __MODULE_JAL(__strlen_kernel_asm) @@ -1370,7 +1385,7 @@ static inline long __strnlen_user(const char __user *s, long n) { long res; - if (segment_eq(get_fs(), get_ds())) { + if (eva_kernel_access()) { __asm__ __volatile__( "move\t$4, %1\n\t" "move\t$5, %2\n\t" @@ -1411,7 +1426,7 @@ static inline long strnlen_user(const char __user *s, long n) long res; might_fault(); - if (segment_eq(get_fs(), get_ds())) { + if (eva_kernel_access()) { __asm__ __volatile__( "move\t$4, %1\n\t" "move\t$5, %2\n\t" -- cgit v1.2.3 From de5792a4ec8abb88ceee83b403b549255146c867 Mon Sep 17 00:00:00 2001 From: Joshua Kinard Date: Mon, 25 May 2015 14:15:10 -0400 Subject: MIPS: Xtalk: Update xwidget.h with known Xtalk device numbers This is the first patch of two to clean up/update the Xtalk detection code used by IP27 with some of the code used in the IP30 port. This specific patch adds Xtalk widget manufacturer and widget device numbers to arch/mips/include/asm/xtalk/widget.h Signed-off-by: Joshua Kinard Cc: Linux MIPS List Patchwork: http://patchwork.linux-mips.org/patch/10174/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/xtalk/xwidget.h | 112 ++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/xtalk/xwidget.h b/arch/mips/include/asm/xtalk/xwidget.h index 32e4e884f9b9..24f121da6a1d 100644 --- a/arch/mips/include/asm/xtalk/xwidget.h +++ b/arch/mips/include/asm/xtalk/xwidget.h @@ -84,6 +84,118 @@ #define WIDGET_LLP_MAXBURST 0x000003ff #define WIDGET_LLP_MAXBURST_SHFT 0 +/* Xtalk Widget Device Mfgr Nums */ +#define WIDGET_XBOW_MFGR_NUM 0x0 /* IP30 XBow Chip */ +#define WIDGET_XXBOW_MFGR_NUM 0x0 /* IP35 Xbow + XBridge Chip */ +#define WIDGET_ODYS_MFGR_NUM 0x023 /* Odyssey / VPro GFX */ +#define WIDGET_TPU_MFGR_NUM 0x024 /* Tensor Processor Unit */ +#define WIDGET_XBRDG_MFGR_NUM 0x024 /* IP35 XBridge Chip */ +#define WIDGET_HEART_MFGR_NUM 0x036 /* IP30 HEART Chip */ +#define WIDGET_BRIDG_MFGR_NUM 0x036 /* PCI Bridge */ +#define WIDGET_HUB_MFGR_NUM 0x036 /* IP27 Hub Chip */ +#define WIDGET_BDRCK_MFGR_NUM 0x036 /* IP35 Bedrock Chip */ +#define WIDGET_IMPCT_MFGR_NUM 0x2aa /* HQ4 / Impact GFX */ +#define WIDGET_KONA_MFGR_NUM 0x2aa /* InfiniteReality3 / Kona GFX */ +#define WIDGET_NULL_MFGR_NUM -1 /* NULL */ + +/* Xtalk Widget Device Part Nums */ +#define WIDGET_XBOW_PART_NUM 0x0000 +#define WIDGET_HEART_PART_NUM 0xc001 +#define WIDGET_BRIDG_PART_NUM 0xc002 +#define WIDGET_IMPCT_PART_NUM 0xc003 +#define WIDGET_ODYS_PART_NUM 0xc013 +#define WIDGET_HUB_PART_NUM 0xc101 +#define WIDGET_KONA_PART_NUM 0xc102 +#define WIDGET_BDRCK_PART_NUM 0xc110 +#define WIDGET_TPU_PART_NUM 0xc202 +#define WIDGET_XXBOW_PART_NUM 0xd000 +#define WIDGET_XBRDG_PART_NUM 0xd002 +#define WIDGET_NULL_PART_NUM -1 + +/* For Xtalk Widget identification */ +struct widget_ident { + u32 mfgr; + u32 part; + char *name; + char *revs[16]; +}; + +/* Known Xtalk Widgets */ +static const struct widget_ident __initconst widget_idents[] = { + { + WIDGET_XBOW_MFGR_NUM, + WIDGET_XBOW_PART_NUM, + "xbow", + {NULL, "1.0", "1.1", "1.2", "1.3", "2.0", NULL}, + }, + { + WIDGET_HEART_MFGR_NUM, + WIDGET_HEART_PART_NUM, + "heart", + {NULL, "A", "B", "C", "D", "E", "F", NULL}, + }, + { + WIDGET_BRIDG_MFGR_NUM, + WIDGET_BRIDG_PART_NUM, + "bridge", + {NULL, "A", "B", "C", "D", NULL}, + }, + { + WIDGET_IMPCT_MFGR_NUM, + WIDGET_IMPCT_PART_NUM, + "impact", + {NULL, "A", "B", NULL}, + }, + { + WIDGET_ODYS_MFGR_NUM, + WIDGET_ODYS_PART_NUM, + "odyssey", + {NULL, "A", "B", NULL}, + }, + { + WIDGET_HUB_MFGR_NUM, + WIDGET_HUB_PART_NUM, + "hub", + {NULL, "1.0", "2.0", "2.1", "2.2", "2.3", "2.4", NULL}, + }, + { + WIDGET_KONA_MFGR_NUM, + WIDGET_KONA_PART_NUM, + "kona", + {NULL}, + }, + { + WIDGET_BDRCK_MFGR_NUM, + WIDGET_BDRCK_PART_NUM, + "bedrock", + {NULL, "1.0", "1.1", NULL}, + }, + { + WIDGET_TPU_MFGR_NUM, + WIDGET_TPU_PART_NUM, + "tpu", + {"0", NULL}, + }, + { + WIDGET_XXBOW_MFGR_NUM, + WIDGET_XXBOW_PART_NUM, + "xxbow", + {NULL, "1.0", "2.0", NULL}, + }, + { + WIDGET_XBRDG_MFGR_NUM, + WIDGET_XBRDG_PART_NUM, + "xbridge", + {NULL, "A", "B", NULL}, + }, + { + WIDGET_NULL_MFGR_NUM, + WIDGET_NULL_PART_NUM, + NULL, + {NULL}, + } +}; + /* * according to the crosstalk spec, only 32-bits access to the widget * configuration registers is allowed. some widgets may allow 64-bits -- cgit v1.2.3 From 921d55e32d31e2503f8f8a16798849ab48fdef2a Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 22 May 2015 16:51:00 +0100 Subject: MIPS: Define GCR_GIC_STATUS register fields Add definitions for the GICEX field in the GCR_GIC_STATUS register to mips-cm.h for use in a later patch. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: James Hogan Cc: linux-kernel@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/10112/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mips-cm.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 59c0901bdd84..1cb11fba59aa 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -216,6 +216,10 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) #define CM_GCR_CPC_BASE_CPCEN_SHF 0 #define CM_GCR_CPC_BASE_CPCEN_MSK (_ULCAST_(0x1) << 0) +/* GCR_GIC_STATUS register fields */ +#define CM_GCR_GIC_STATUS_GICEX_SHF 0 +#define CM_GCR_GIC_STATUS_GICEX_MSK (_ULCAST_(0x1) << 0) + /* GCR_REGn_BASE register fields */ #define CM_GCR_REGn_BASE_BASEADDR_SHF 16 #define CM_GCR_REGn_BASE_BASEADDR_MSK (_ULCAST_(0xffff) << 16) -- cgit v1.2.3 From 56d4c99b848ce3a07cf3643e1f2dc78419f0f954 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 22 May 2015 16:51:01 +0100 Subject: MIPS: include errno.h for ENODEV in mips-cm.h A later patch in this series will include mips-cm.h but does not require errno.h. This leads to a build failure with ENODEV undeclared. Include errno.h from mips-cm.h to pull in the appropriate definition and avoid the build failure. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: James Hogan Cc: linux-kernel@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/10113/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mips-cm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 1cb11fba59aa..edc7ee95269e 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -11,6 +11,7 @@ #ifndef __MIPS_ASM_MIPS_CM_H__ #define __MIPS_ASM_MIPS_CM_H__ +#include #include #include -- cgit v1.2.3 From 5f93ef5cfb867aca400598f69f9ce8af14b0ced0 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 22 May 2015 16:51:03 +0100 Subject: MIPS: i8259: DT support Support probing the i8259 programmable interrupt controller, as found on the Malta board, and using its interrupts via device tree. Signed-off-by: Paul Burton Cc: linux-mips@linux-mips.org Cc: devicetree@vger.kernel.org Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: Qais Yousef Cc: Andrew Bresticker Cc: linux-kernel@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/10114/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/i8259.h | 1 + arch/mips/kernel/i8259.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/i8259.h b/arch/mips/include/asm/i8259.h index c7e278447c0a..a7fbcd6ed13c 100644 --- a/arch/mips/include/asm/i8259.h +++ b/arch/mips/include/asm/i8259.h @@ -41,6 +41,7 @@ extern int i8259A_irq_pending(unsigned int irq); extern void make_8259A_irq(unsigned int irq); extern void init_i8259_irqs(void); +extern int i8259_of_init(struct device_node *node, struct device_node *parent); /* * Do the traditional i8259 interrupt polling thing. This is for the few diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index a74ec3ae557c..74f6752814d3 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,8 @@ #include #include +#include "../../drivers/irqchip/irqchip.h" + /* * This is the 'legacy' 8259A Programmable Interrupt Controller, * present in the majority of PC/AT boxes. @@ -327,7 +330,7 @@ static struct irq_domain_ops i8259A_ops = { * driver compatibility reasons interrupts 0 - 15 to be the i8259 * interrupts even if the hardware uses a different interrupt numbering. */ -void __init init_i8259_irqs(void) +struct irq_domain * __init __init_i8259_irqs(struct device_node *node) { struct irq_domain *domain; @@ -336,10 +339,46 @@ void __init init_i8259_irqs(void) init_8259A(0); - domain = irq_domain_add_legacy(NULL, 16, I8259A_IRQ_BASE, 0, + domain = irq_domain_add_legacy(node, 16, I8259A_IRQ_BASE, 0, &i8259A_ops, NULL); if (!domain) panic("Failed to add i8259 IRQ domain"); setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); + return domain; +} + +void __init init_i8259_irqs(void) +{ + __init_i8259_irqs(NULL); +} + +static void i8259_irq_dispatch(unsigned int irq, struct irq_desc *desc) +{ + struct irq_domain *domain = irq_get_handler_data(irq); + int hwirq = i8259_irq(); + + if (hwirq < 0) + return; + + irq = irq_linear_revmap(domain, hwirq); + generic_handle_irq(irq); +} + +int __init i8259_of_init(struct device_node *node, struct device_node *parent) +{ + struct irq_domain *domain; + unsigned int parent_irq; + + parent_irq = irq_of_parse_and_map(node, 0); + if (!parent_irq) { + pr_err("Failed to map i8259 parent IRQ\n"); + return -ENODEV; + } + + domain = __init_i8259_irqs(node); + irq_set_handler_data(parent_irq, domain); + irq_set_chained_handler(parent_irq, i8259_irq_dispatch); + return 0; } +IRQCHIP_DECLARE(i8259, "intel,i8259", i8259_of_init); -- cgit v1.2.3 From 6f6ed482653723e53da4a57b200348ac1eed5ce9 Mon Sep 17 00:00:00 2001 From: Leonid Yegoshin Date: Mon, 1 Jun 2015 17:09:52 -0700 Subject: MIPS: Replace smp_mb with release barrier function in unlocks. Repleace smp_mb() in arch_write_unlock() and __clear_bit_unlock() to smp_mb__before_llsc() call which does "release" barrier functionality. It seems like it was missed in commit f252ffd50c97dae87b45f1dbad24f71358ccfbd6 during introduction of "acquire" and "release" semantics. [ralf@linux-mips: The original patch submission was labelled a fix but actually it replaces a barrier with another less restrictive type of barrier so it doesn't fix any ill behaviour but rather squeezes out a tad better performance. Further improvments will be possible once smp_release() has been merged.] Signed-off-by: Leonid Yegoshin Cc: linux-mips@linux-mips.org Cc: benh@kernel.crashing.org Cc: will.deacon@arm.com Cc: linux-kernel@vger.kernel.org Cc: markos.chandras@imgtec.com Cc: macro@linux-mips.org Cc: Steven.Hill@imgtec.com Cc: alexander.h.duyck@redhat.com Cc: davem@davemloft.net Patchwork: https://patchwork.linux-mips.org/patch/10507/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/bitops.h | 2 +- arch/mips/include/asm/spinlock.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 0cf29bd5dc5c..ce9666cf1499 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -469,7 +469,7 @@ static inline int test_and_change_bit(unsigned long nr, */ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) { - smp_mb(); + smp_mb__before_llsc(); __clear_bit(nr, addr); } diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 1fca2e0793dc..7c7f3b2bd3de 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -317,7 +317,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw) static inline void arch_write_unlock(arch_rwlock_t *rw) { - smp_mb(); + smp_mb__before_llsc(); __asm__ __volatile__( " # arch_write_unlock \n" -- cgit v1.2.3 From 2bd7bc254ab1f45269db6dd7957d63b713817408 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Thu, 16 Apr 2015 11:05:59 +0100 Subject: MIPS: asmmacro: Ensure 64-bit FP registers are used with MSA This silences warnings like the following one when building with the latest binutils: arch/mips/kernel/genex.S: Assembler messages: arch/mips/kernel/genex.S:438: Warning: the `msa' extension requires 64-bit FPRs [ralf@linux-mips.org: Markos says binutils 2.25 and some 2.24 snapshots are affected.] Signed-off-by: Markos Chandras Reviewed-by: James Hogan Cc: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/9745/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/asmmacro.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 6156ac8c4cfb..76317a70200d 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h @@ -211,9 +211,13 @@ .endm #ifdef TOOLCHAIN_SUPPORTS_MSA +/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ +#undef fp + .macro _cfcmsa rd, cs .set push .set mips32r2 + .set fp=64 .set msa cfcmsa \rd, $\cs .set pop @@ -222,6 +226,7 @@ .macro _ctcmsa cd, rs .set push .set mips32r2 + .set fp=64 .set msa ctcmsa $\cd, \rs .set pop @@ -230,6 +235,7 @@ .macro ld_d wd, off, base .set push .set mips32r2 + .set fp=64 .set msa ld.d $w\wd, \off(\base) .set pop @@ -238,6 +244,7 @@ .macro st_d wd, off, base .set push .set mips32r2 + .set fp=64 .set msa st.d $w\wd, \off(\base) .set pop @@ -246,6 +253,7 @@ .macro copy_u_w ws, n .set push .set mips32r2 + .set fp=64 .set msa copy_u.w $1, $w\ws[\n] .set pop @@ -254,6 +262,7 @@ .macro copy_u_d ws, n .set push .set mips64r2 + .set fp=64 .set msa copy_u.d $1, $w\ws[\n] .set pop @@ -262,6 +271,7 @@ .macro insert_w wd, n .set push .set mips32r2 + .set fp=64 .set msa insert.w $w\wd[\n], $1 .set pop @@ -270,6 +280,7 @@ .macro insert_d wd, n .set push .set mips64r2 + .set fp=64 .set msa insert.d $w\wd[\n], $1 .set pop -- cgit v1.2.3 From 9ff897c4e8d5bd05ad7009f84a395596d4953858 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Mon, 20 Apr 2015 10:54:34 +0100 Subject: MIPS: spinlock: Adjust arch_spin_lock back-off time Make it similar to the trylock and R10000_LLSC_WAR cases. Signed-off-by: Markos Chandras Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/9789/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/spinlock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 7c7f3b2bd3de..9de4ba43dcd1 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -109,7 +109,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) " subu %[ticket], %[my_ticket], %[ticket] \n" "2: \n" " .subsection 2 \n" - "4: andi %[ticket], %[ticket], 0x1fff \n" + "4: andi %[ticket], %[ticket], 0xffff \n" " sll %[ticket], 5 \n" " \n" "6: bnez %[ticket], 6b \n" -- cgit v1.2.3