Merge branch 'master' of git://git.denx.de/u-boot-mips
authorTom Rini <trini@konsulko.com>
Wed, 21 Sep 2016 18:50:18 +0000 (14:50 -0400)
committerTom Rini <trini@konsulko.com>
Wed, 21 Sep 2016 18:50:18 +0000 (14:50 -0400)
57 files changed:
arch/mips/Kconfig
arch/mips/cpu/Makefile
arch/mips/cpu/cm_init.S [new file with mode: 0644]
arch/mips/cpu/cpu.c
arch/mips/cpu/start.S
arch/mips/cpu/u-boot.lds
arch/mips/dts/Makefile
arch/mips/dts/img,boston.dts [new file with mode: 0644]
arch/mips/dts/microAptiv.dtsi [new file with mode: 0644]
arch/mips/dts/nexys4ddr.dts [new file with mode: 0644]
arch/mips/include/asm/cache.h
arch/mips/include/asm/cm.h [new file with mode: 0644]
arch/mips/include/asm/global_data.h
arch/mips/include/asm/mipsregs.h
arch/mips/lib/cache.c
arch/mips/lib/cache_init.S
arch/mips/mach-ath79/cpu.c
board/imgtec/boston/Kconfig [new file with mode: 0644]
board/imgtec/boston/MAINTAINERS [new file with mode: 0644]
board/imgtec/boston/Makefile [new file with mode: 0644]
board/imgtec/boston/boston-lcd.h [new file with mode: 0644]
board/imgtec/boston/boston-regs.h [new file with mode: 0644]
board/imgtec/boston/checkboard.c [new file with mode: 0644]
board/imgtec/boston/ddr.c [new file with mode: 0644]
board/imgtec/boston/lowlevel_init.S [new file with mode: 0644]
board/imgtec/malta/lowlevel_init.S
board/imgtec/xilfpga/Kconfig [new file with mode: 0644]
board/imgtec/xilfpga/MAINTAINERS [new file with mode: 0644]
board/imgtec/xilfpga/Makefile [new file with mode: 0644]
board/imgtec/xilfpga/README [new file with mode: 0644]
board/imgtec/xilfpga/xilfpga.c [new file with mode: 0644]
common/board_f.c
configs/boston32r2_defconfig [new file with mode: 0644]
configs/boston32r2el_defconfig [new file with mode: 0644]
configs/boston64r2_defconfig [new file with mode: 0644]
configs/boston64r2el_defconfig [new file with mode: 0644]
configs/imgtec_xilfpga_defconfig [new file with mode: 0644]
doc/README.boston [new file with mode: 0644]
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/clk_boston.c [new file with mode: 0644]
drivers/core/lists.c
drivers/core/regmap.c
drivers/core/syscon-uclass.c
drivers/net/Kconfig
drivers/net/pch_gbe.c
drivers/net/xilinx_emaclite.c
drivers/pci/Kconfig
drivers/pci/Makefile
drivers/pci/pci-uclass.c
drivers/pci/pcie_xilinx.c [new file with mode: 0644]
drivers/serial/ns16550.c
include/clk.h
include/configs/boston.h [new file with mode: 0644]
include/configs/imgtec_xilfpga.h [new file with mode: 0644]
include/dt-bindings/clock/boston-clock.h [new file with mode: 0644]
include/dt-bindings/interrupt-controller/mips-gic.h [new file with mode: 0644]

index 21066f0fda69c1649cf981b52e2ae53c13a982d1..097ad587c1cf643c769b7c071d27615b48578da9 100644 (file)
@@ -26,6 +26,8 @@ config TARGET_MALTA
        select DM
        select DM_SERIAL
        select DYNAMIC_IO_PORT_BASE
+       select MIPS_CM
+       select MIPS_L2_CACHE
        select OF_CONTROL
        select OF_ISA_BUS
        select SUPPORTS_BIG_ENDIAN
@@ -73,10 +75,43 @@ config MACH_PIC32
        select OF_CONTROL
        select DM
 
+config TARGET_BOSTON
+       bool "Support Boston"
+       select DM
+       select DM_SERIAL
+       select OF_CONTROL
+       select MIPS_CM
+       select MIPS_L1_CACHE_SHIFT_6
+       select MIPS_L2_CACHE
+       select SUPPORTS_BIG_ENDIAN
+       select SUPPORTS_LITTLE_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       select SUPPORTS_CPU_MIPS32_R6
+       select SUPPORTS_CPU_MIPS64_R1
+       select SUPPORTS_CPU_MIPS64_R2
+       select SUPPORTS_CPU_MIPS64_R6
+
+config TARGET_XILFPGA
+       bool "Support Imagination Xilfpga"
+       select OF_CONTROL
+       select DM
+       select DM_SERIAL
+       select DM_GPIO
+       select DM_ETH
+       select SUPPORTS_LITTLE_ENDIAN
+       select SUPPORTS_CPU_MIPS32_R1
+       select SUPPORTS_CPU_MIPS32_R2
+       select MIPS_L1_CACHE_SHIFT_4
+       help
+         This supports IMGTEC MIPSfpga platform
+
 endchoice
 
 source "board/dbau1x00/Kconfig"
+source "board/imgtec/boston/Kconfig"
 source "board/imgtec/malta/Kconfig"
+source "board/imgtec/xilfpga/Kconfig"
 source "board/micronas/vct/Kconfig"
 source "board/pb1x00/Kconfig"
 source "board/qemu-mips/Kconfig"
@@ -300,9 +335,31 @@ config MIPS_L1_CACHE_SHIFT
        default "4" if MIPS_L1_CACHE_SHIFT_4
        default "5"
 
+config MIPS_L2_CACHE
+       bool
+       help
+         Select this if your system includes an L2 cache and you want U-Boot
+         to initialise & maintain it.
+
 config DYNAMIC_IO_PORT_BASE
        bool
 
+config MIPS_CM
+       bool
+       help
+         Select this if your system contains a MIPS Coherence Manager and you
+         wish U-Boot to configure it or make use of it to retrieve system
+         information such as cache configuration.
+
+config MIPS_CM_BASE
+       hex
+       default 0x1fbf8000
+       help
+         The physical base address at which to map the MIPS Coherence Manager
+         Global Configuration Registers (GCRs). This should be set such that
+         the GCRs occupy a region of the physical address space which is
+         otherwise unused, or at minimum that software doesn't need to access.
+
 endif
 
 endmenu
index fc6b455c68bb5245f29c2979f8488f8d61c15d3f..429fd3a50c97949a7f51e4e8126dbb4442ce32b6 100644 (file)
@@ -7,3 +7,5 @@ extra-y = start.o
 obj-y += time.o
 obj-y += interrupts.o
 obj-y += cpu.o
+
+obj-$(CONFIG_MIPS_CM)  += cm_init.o
diff --git a/arch/mips/cpu/cm_init.S b/arch/mips/cpu/cm_init.S
new file mode 100644 (file)
index 0000000..ddcaa49
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * MIPS Coherence Manager (CM) Initialisation
+ *
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/cm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+
+LEAF(mips_cm_map)
+       /* Config3 must exist for a CM to be present */
+       mfc0            t0, CP0_CONFIG, 1
+       bgez            t0, 2f
+       mfc0            t0, CP0_CONFIG, 2
+       bgez            t0, 2f
+
+       /* Check Config3.CMGCR to determine CM presence */
+       mfc0            t0, CP0_CONFIG, 3
+       and             t0, t0, MIPS_CONF3_CMGCR
+       beqz            t0, 2f
+
+       /* Find the current physical GCR base address */
+1:     MFC0            t0, CP0_CMGCRBASE
+       PTR_SLL         t0, t0, 4
+
+       /* If the GCRs are where we want, we're done */
+       PTR_LI          t1, CONFIG_MIPS_CM_BASE
+       beq             t0, t1, 2f
+
+       /* Move the GCRs to our configured base address */
+       PTR_LI          t2, CKSEG1
+       PTR_ADDU        t0, t0, t2
+       sw              zero, GCR_BASE_UPPER(t0)
+       sw              t1, GCR_BASE(t0)
+
+       /* Re-check the GCR base */
+       b               1b
+
+2:     jr              ra
+       END(mips_cm_map)
index 391feb3250e42f665627c11cc7d07f182ffc2b4f..1b919ed82289d1d4d30e4daccf057c8c4e89e9ed 100644 (file)
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <command.h>
 #include <linux/compiler.h>
+#include <asm/cache.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 
@@ -35,3 +36,9 @@ void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
        write_c0_index(index);
        tlb_write_indexed();
 }
+
+int arch_cpu_init(void)
+{
+       mips_cache_probe();
+       return 0;
+}
index fc6dd66aa655b9e1c7a8b25c5311e96e0ff6f4cb..3f0fc125475271835456db3490bd47a61a3dbb1b 100644 (file)
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 
-#ifndef CONFIG_SYS_MIPS_CACHE_MODE
-#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
-#endif
-
 #ifndef CONFIG_SYS_INIT_SP_ADDR
 #define CONFIG_SYS_INIT_SP_ADDR        (CONFIG_SYS_SDRAM_BASE + \
                                CONFIG_SYS_INIT_SP_OFFSET)
@@ -112,9 +108,28 @@ ENTRY(_start)
 
        .align 4
 reset:
+#if __mips_isa_rev >= 6
+       mfc0    t0, CP0_CONFIG, 5
+       and     t0, t0, MIPS_CONF5_VP
+       beqz    t0, 1f
+        nop
+
+       b       2f
+        mfc0   t0, CP0_GLOBALNUMBER
+#endif
+
+1:     mfc0    t0, CP0_EBASE
+       and     t0, t0, EBASE_CPUNUM
+
+       /* Hang if this isn't the first CPU in the system */
+2:     beqz    t0, 4f
+        nop
+3:     wait
+       b       3b
+        nop
 
        /* Clear watch registers */
-       MTC0    zero, CP0_WATCHLO
+4:     MTC0    zero, CP0_WATCHLO
        mtc0    zero, CP0_WATCHHI
 
        /* WP(Watch Pending), SW0/1 should be cleared */
@@ -127,9 +142,11 @@ reset:
        mtc0    zero, CP0_COMPARE
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
-       /* CONFIG0 register */
-       li      t0, CONF_CM_UNCACHED
+       mfc0    t0, CP0_CONFIG
+       and     t0, t0, MIPS_CONF_IMPL
+       or      t0, t0, CONF_CM_UNCACHED
        mtc0    t0, CP0_CONFIG
+       ehb
 #endif
 
        /*
@@ -144,20 +161,31 @@ reset:
 1:
        PTR_L   gp, 0(ra)
 
+#ifdef CONFIG_MIPS_CM
+       PTR_LA  t9, mips_cm_map
+       jalr    t9
+        nop
+#endif
+
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
+# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
        /* Initialize any external memory */
        PTR_LA  t9, lowlevel_init
        jalr    t9
         nop
+# endif
 
        /* Initialize caches... */
        PTR_LA  t9, mips_cache_reset
        jalr    t9
         nop
 
-       /* ... and enable them */
-       li      t0, CONFIG_SYS_MIPS_CACHE_MODE
-       mtc0    t0, CP0_CONFIG
+# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
+       /* Initialize any external memory */
+       PTR_LA  t9, lowlevel_init
+       jalr    t9
+        nop
+# endif
 #endif
 
        /* Set up temporary stack */
@@ -214,12 +242,9 @@ ENTRY(relocate_code)
        PTR_LI  t0, CONFIG_SYS_MONITOR_BASE
        PTR_SUB s1, s2, t0              # s1 <-- relocation offset
 
-       PTR_LA  t3, in_ram
-       PTR_L   t2, -(3 * PTRSIZE)(t3)  # t2 <-- __image_copy_end
+       PTR_LA  t2, __image_copy_end
        move    t1, a2
 
-       PTR_ADD gp, s1                  # adjust gp
-
        /*
         * t0 = source address
         * t1 = target address
@@ -232,32 +257,14 @@ ENTRY(relocate_code)
        blt     t0, t2, 1b
         PTR_ADDU t1, PTRSIZE
 
-       /* If caches were enabled, we would have to flush them here. */
-       PTR_SUB a1, t1, s2              # a1 <-- size
-       PTR_LA  t9, flush_cache
-       jalr    t9
-        move   a0, s2                  # a0 <-- destination address
-
-       /* Jump to where we've relocated ourselves */
-       PTR_ADDIU t0, s2, in_ram - _start
-       jr      t0
-        nop
-
-       PTR     __rel_dyn_end
-       PTR     __rel_dyn_start
-       PTR     __image_copy_end
-       PTR     _GLOBAL_OFFSET_TABLE_
-       PTR     num_got_entries
-
-in_ram:
        /*
         * Now we want to update GOT.
         *
         * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
         * generated by GNU ld. Skip these reserved entries from relocation.
         */
-       PTR_L   t3, -(1 * PTRSIZE)(t0)  # t3 <-- num_got_entries
-       PTR_L   t8, -(2 * PTRSIZE)(t0)  # t8 <-- _GLOBAL_OFFSET_TABLE_
+       PTR_LA  t3, num_got_entries
+       PTR_LA  t8, _GLOBAL_OFFSET_TABLE_
        PTR_ADD t8, s1                  # t8 now holds relocated _G_O_T_
        PTR_ADDIU t8, t8, 2 * PTRSIZE   # skipping first two entries
        PTR_LI  t2, 2
@@ -272,8 +279,8 @@ in_ram:
         PTR_ADDIU t8, PTRSIZE
 
        /* Update dynamic relocations */
-       PTR_L   t1, -(4 * PTRSIZE)(t0)  # t1 <-- __rel_dyn_start
-       PTR_L   t2, -(5 * PTRSIZE)(t0)  # t2 <-- __rel_dyn_end
+       PTR_LA  t1, __rel_dyn_start
+       PTR_LA  t2, __rel_dyn_end
 
        b       2f                      # skip first reserved entry
         PTR_ADDIU t1, 2 * PTRSIZE
@@ -297,6 +304,20 @@ in_ram:
        blt     t1, t2, 1b
         PTR_ADDIU t1, 2 * PTRSIZE      # each rel.dyn entry is 2*PTRSIZE bytes
 
+       /*
+        * Flush caches to ensure our newly modified instructions are visible
+        * to the instruction cache. We're still running with the old GOT, so
+        * apply the reloc offset to the start address.
+        */
+       PTR_LA  a0, __text_start
+       PTR_LA  a1, __text_end
+       PTR_SUB a1, a1, a0
+       PTR_LA  t9, flush_cache
+       jalr    t9
+        PTR_ADD        a0, s1
+
+       PTR_ADD gp, s1                  # adjust gp
+
        /*
         * Clear BSS
         *
index 7d71c11ae4c6cfa5ff1aa22df51a20d4ceb16bc0..0129c996118d621e913b097d433637e6503d25d0 100644 (file)
@@ -19,7 +19,9 @@ SECTIONS
 
        . = ALIGN(4);
        .text : {
+               __text_start = .;
                *(.text*)
+               __text_end = .;
        }
 
        . = ALIGN(4);
index 2f04d73b83ffc824cdadb4c903085bf6997698c3..30fcc2b91e6a9113fbbc76e62782a68ca3b909fd 100644 (file)
@@ -4,8 +4,10 @@
 
 dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
 dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
+dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb
 dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
 dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
+dtb-$(CONFIG_TARGET_XILFPGA) += nexys4ddr.dtb
 dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
 
 targets += $(dtb-y)
diff --git a/arch/mips/dts/img,boston.dts b/arch/mips/dts/img,boston.dts
new file mode 100644 (file)
index 0000000..1d4eeda
--- /dev/null
@@ -0,0 +1,222 @@
+/dts-v1/;
+
+#include <dt-bindings/clock/boston-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/mips-gic.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "img,boston";
+
+       chosen {
+               stdout-path = &uart0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "img,mips";
+                       reg = <0>;
+                       clocks = <&clk_boston BOSTON_CLK_CPU>;
+               };
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>;
+       };
+
+       gic: interrupt-controller {
+               compatible = "mti,gic";
+
+               interrupt-controller;
+               #interrupt-cells = <3>;
+
+               timer {
+                       compatible = "mti,gic-timer";
+                       interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
+                       clocks = <&clk_boston BOSTON_CLK_CPU>;
+               };
+       };
+
+       pci0: pci@10000000 {
+               status = "disabled";
+               compatible = "xlnx,axi-pcie-host-1.00.a";
+               device_type = "pci";
+               reg = <0x10000000 0x2000000>;
+
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_SHARED 2 IRQ_TYPE_LEVEL_HIGH>;
+
+               ranges = <0x02000000 0 0x40000000
+                         0x40000000 0 0x40000000>;
+
+               interrupt-map-mask = <0 0 0 7>;
+               interrupt-map = <0 0 0 1 &pci0_intc 0>,
+                               <0 0 0 2 &pci0_intc 1>,
+                               <0 0 0 3 &pci0_intc 2>,
+                               <0 0 0 4 &pci0_intc 3>;
+
+               pci0_intc: interrupt-controller {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+               };
+       };
+
+       pci1: pci@12000000 {
+               status = "disabled";
+               compatible = "xlnx,axi-pcie-host-1.00.a";
+               device_type = "pci";
+               reg = <0x12000000 0x2000000>;
+
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_SHARED 1 IRQ_TYPE_LEVEL_HIGH>;
+
+               ranges = <0x02000000 0 0x20000000
+                         0x20000000 0 0x20000000>;
+
+               interrupt-map-mask = <0 0 0 7>;
+               interrupt-map = <0 0 0 1 &pci1_intc 0>,
+                               <0 0 0 2 &pci1_intc 1>,
+                               <0 0 0 3 &pci1_intc 2>,
+                               <0 0 0 4 &pci1_intc 3>;
+
+               pci1_intc: interrupt-controller {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+               };
+       };
+
+       pci2: pci@14000000 {
+               compatible = "xlnx,axi-pcie-host-1.00.a";
+               device_type = "pci";
+               reg = <0x14000000 0x2000000>;
+
+               #address-cells = <3>;
+               #size-cells = <2>;
+               #interrupt-cells = <1>;
+
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_SHARED 0 IRQ_TYPE_LEVEL_HIGH>;
+
+               ranges = <0x02000000 0 0x16000000
+                         0x16000000 0 0x100000>;
+
+               interrupt-map-mask = <0 0 0 7>;
+               interrupt-map = <0 0 0 1 &pci2_intc 0>,
+                               <0 0 0 2 &pci2_intc 1>,
+                               <0 0 0 3 &pci2_intc 2>,
+                               <0 0 0 4 &pci2_intc 3>;
+
+               pci2_intc: interrupt-controller {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+               };
+
+               pci2_root@0,0,0 {
+                       compatible = "pci10ee,7021";
+                       reg = <0x00000000 0 0 0 0>;
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       #interrupt-cells = <1>;
+
+                       eg20t_bridge@1,0,0 {
+                               compatible = "pci8086,8800";
+                               reg = <0x00010000 0 0 0 0>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+
+                               eg20t_mac@2,0,1 {
+                                       compatible = "pci8086,8802";
+                                       reg = <0x00020100 0 0 0 0>;
+                                       phy-reset-gpios = <&eg20t_gpio 6 GPIO_ACTIVE_LOW>;
+                               };
+
+                               eg20t_gpio: eg20t_gpio@2,0,2 {
+                                       compatible = "pci8086,8803";
+                                       reg = <0x00020200 0 0 0 0>;
+
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                               };
+
+                               eg20t_i2c@2,12,2 {
+                                       compatible = "pci8086,8817";
+                                       reg = <0x00026200 0 0 0 0>;
+
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       rtc@0x68 {
+                                               compatible = "st,m41t81s";
+                                               reg = <0x68>;
+                                       };
+                               };
+                       };
+               };
+       };
+
+       plat_regs: system-controller@17ffd000 {
+               compatible = "img,boston-platform-regs", "syscon";
+               reg = <0x17ffd000 0x1000>;
+               u-boot,dm-pre-reloc;
+       };
+
+       clk_boston: clock {
+               compatible = "img,boston-clock";
+               #clock-cells = <1>;
+               regmap = <&plat_regs>;
+               u-boot,dm-pre-reloc;
+       };
+
+       reboot: syscon-reboot {
+               compatible = "syscon-reboot";
+               regmap = <&plat_regs>;
+               offset = <0x10>;
+               mask = <0x10>;
+       };
+
+       uart0: uart@17ffe000 {
+               compatible = "ns16550a";
+               reg = <0x17ffe000 0x1000>;
+               reg-shift = <2>;
+               reg-io-width = <4>;
+
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;
+
+               clocks = <&clk_boston BOSTON_CLK_SYS>;
+
+               u-boot,dm-pre-reloc;
+       };
+
+       lcd: lcd@17fff000 {
+               compatible = "img,boston-lcd";
+               reg = <0x17fff000 0x8>;
+       };
+
+       flash@18000000 {
+               compatible = "cfi-flash";
+               reg = <0x18000000 0x8000000>;
+               bank-width = <2>;
+       };
+};
diff --git a/arch/mips/dts/microAptiv.dtsi b/arch/mips/dts/microAptiv.dtsi
new file mode 100644 (file)
index 0000000..81d518e
--- /dev/null
@@ -0,0 +1,21 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "img,xilfpga";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mips,m14Kc";
+                       clocks  = <&ext>;
+                       reg = <0>;
+               };
+       };
+
+       ext: ext {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+       };
+};
diff --git a/arch/mips/dts/nexys4ddr.dts b/arch/mips/dts/nexys4ddr.dts
new file mode 100644 (file)
index 0000000..e254ab1
--- /dev/null
@@ -0,0 +1,62 @@
+/dts-v1/;
+
+#include "microAptiv.dtsi"
+
+/ {
+       compatible = "digilent,nexys4ddr";
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x08000000>;
+       };
+
+       cpuintc: interrupt-controller@0 {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       aliases {
+               console = &axi_uart16550;
+       };
+
+       axi_ethernetlite: ethernet@10e00000 {
+               compatible = "xlnx,xps-ethernetlite-1.00.a";
+               device_type = "network";
+               local-mac-address = [08 86 4C 0D F7 09];
+               phy-handle = <&phy0>;
+               reg = <0x10e00000 0x10000>;
+               xlnx,duplex = <0x1>;
+               xlnx,include-global-buffers = <0x1>;
+               xlnx,include-internal-loopback = <0x0>;
+               xlnx,include-mdio = <0x1>;
+               xlnx,instance = "axi_ethernetlite_inst";
+               xlnx,rx-ping-pong = <0x1>;
+               xlnx,s-axi-id-width = <0x1>;
+               xlnx,tx-ping-pong = <0x1>;
+               xlnx,use-internal = <0x0>;
+               mdio {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       phy0: phy@1 {
+                               compatible = <0x0007c0f0 0xfffffff0>;
+                               device_type = "ethernet-phy";
+                               reg = <1>;
+                       } ;
+               } ;
+        } ;
+
+
+       axi_uart16550: serial@10400000 {
+               compatible = "ns16550a";
+               reg = <0x10400000 0x10000>;
+
+               reg-shift = <2>;
+               reg-offset = <0x1000>;
+
+               clock-frequency = <50000000>;
+
+       };
+};
+
index 0cea581e5d8cd1575653c0730fdc32790b01321a..669c362a52a563ab6f7dfcf43188b8559644b69d 100644 (file)
  */
 #define CONFIG_SYS_CACHELINE_SIZE ARCH_DMA_MINALIGN
 
+/**
+ * mips_cache_probe() - Probe the properties of the caches
+ *
+ * Call this to probe the properties such as line sizes of the caches
+ * present in the system, if any. This must be done before cache maintenance
+ * functions such as flush_cache may be called.
+ */
+void mips_cache_probe(void);
+
 #endif /* __MIPS_CACHE_H__ */
diff --git a/arch/mips/include/asm/cm.h b/arch/mips/include/asm/cm.h
new file mode 100644 (file)
index 0000000..b9ab0c6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * MIPS Coherence Manager (CM) Register Definitions
+ *
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef __MIPS_ASM_CM_H__
+#define __MIPS_ASM_CM_H__
+
+/* Global Control Register (GCR) offsets */
+#define GCR_BASE                       0x0008
+#define GCR_BASE_UPPER                 0x000c
+#define GCR_REV                                0x0030
+#define GCR_L2_CONFIG                  0x0130
+#define GCR_L2_TAG_ADDR                        0x0600
+#define GCR_L2_TAG_ADDR_UPPER          0x0604
+#define GCR_L2_TAG_STATE               0x0608
+#define GCR_L2_TAG_STATE_UPPER         0x060c
+#define GCR_L2_DATA                    0x0610
+#define GCR_L2_DATA_UPPER              0x0614
+#define GCR_Cx_COHERENCE               0x2008
+
+/* GCR_REV CM versions */
+#define GCR_REV_CM3                    0x0800
+
+/* GCR_L2_CONFIG fields */
+#define GCR_L2_CONFIG_ASSOC_SHIFT      0
+#define GCR_L2_CONFIG_ASSOC_BITS       8
+#define GCR_L2_CONFIG_LINESZ_SHIFT     8
+#define GCR_L2_CONFIG_LINESZ_BITS      4
+#define GCR_L2_CONFIG_SETSZ_SHIFT      12
+#define GCR_L2_CONFIG_SETSZ_BITS       4
+#define GCR_L2_CONFIG_BYPASS           (1 << 20)
+
+/* GCR_Cx_COHERENCE */
+#define GCR_Cx_COHERENCE_DOM_EN                (0xff << 0)
+#define GCR_Cx_COHERENCE_EN            (0x1 << 0)
+
+#ifndef __ASSEMBLY__
+
+#include <asm/io.h>
+
+static inline void *mips_cm_base(void)
+{
+       return (void *)CKSEG1ADDR(CONFIG_MIPS_CM_BASE);
+}
+
+static inline unsigned long mips_cm_l2_line_size(void)
+{
+       unsigned long l2conf, line_sz;
+
+       l2conf = __raw_readl(mips_cm_base() + GCR_L2_CONFIG);
+
+       line_sz = l2conf >> GCR_L2_CONFIG_LINESZ_SHIFT;
+       line_sz &= GENMASK(GCR_L2_CONFIG_LINESZ_BITS - 1, 0);
+       return line_sz ? (2 << line_sz) : 0;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __MIPS_ASM_CM_H__ */
index 37f8ed52e6a4ff07612a93948b4d6e255aa62bac..0078bbe1b851683795da30eb9ec5830305282e70 100644 (file)
@@ -21,6 +21,13 @@ struct arch_global_data {
        unsigned long rev;
        unsigned long ver;
 #endif
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+       unsigned short l1i_line_size;
+       unsigned short l1d_line_size;
+#endif
+#ifdef CONFIG_MIPS_L2_CACHE
+       unsigned short l2_line_size;
+#endif
 };
 
 #include <asm-generic/global_data.h>
index 3185dc7abf2048d3ea4d917c678333d04b63509c..9ab506361e7897fb76ad0c8cdd37ebf3e58afc7a 100644 (file)
@@ -39,6 +39,7 @@
 #define CP0_ENTRYLO0 $2
 #define CP0_ENTRYLO1 $3
 #define CP0_CONF $3
+#define CP0_GLOBALNUMBER $3, 1
 #define CP0_CONTEXT $4
 #define CP0_PAGEMASK $5
 #define CP0_WIRED $6
 #define CAUSEB_BD              31
 #define CAUSEF_BD              (_ULCAST_(1)   << 31)
 
+/*
+ * Bits in the coprocessor 0 EBase register.
+ */
+#define EBASE_CPUNUM           0x3ff
+
 /*
  * Bits in the coprocessor 0 config register.
  */
 #define MIPS_CONF_MT_FTLB      (_ULCAST_(4) <<  7)
 #define MIPS_CONF_AR           (_ULCAST_(7) << 10)
 #define MIPS_CONF_AT           (_ULCAST_(3) << 13)
+#define MIPS_CONF_IMPL         (_ULCAST_(0x1ff) << 16)
 #define MIPS_CONF_M            (_ULCAST_(1) << 31)
 
 /*
 #define MIPS_CONF1_TLBS_SIZE    (6)
 #define MIPS_CONF1_TLBS         (_ULCAST_(63) << MIPS_CONF1_TLBS_SHIFT)
 
+#define MIPS_CONF2_SA_SHF      0
 #define MIPS_CONF2_SA          (_ULCAST_(15) << 0)
+#define MIPS_CONF2_SL_SHF      4
 #define MIPS_CONF2_SL          (_ULCAST_(15) << 4)
+#define MIPS_CONF2_SS_SHF      8
 #define MIPS_CONF2_SS          (_ULCAST_(15) << 8)
+#define MIPS_CONF2_L2B         (_ULCAST_(1) << 12)
 #define MIPS_CONF2_SU          (_ULCAST_(15) << 12)
 #define MIPS_CONF2_TA          (_ULCAST_(15) << 16)
 #define MIPS_CONF2_TL          (_ULCAST_(15) << 20)
 #define MIPS_CONF5_MRP         (_ULCAST_(1) << 3)
 #define MIPS_CONF5_LLB         (_ULCAST_(1) << 4)
 #define MIPS_CONF5_MVH         (_ULCAST_(1) << 5)
+#define MIPS_CONF5_VP          (_ULCAST_(1) << 7)
 #define MIPS_CONF5_FRE         (_ULCAST_(1) << 8)
 #define MIPS_CONF5_UFE         (_ULCAST_(1) << 9)
+#define MIPS_CONF5_L2C         (_ULCAST_(1) << 10)
 #define MIPS_CONF5_MSAEN       (_ULCAST_(1) << 27)
 #define MIPS_CONF5_EVA         (_ULCAST_(1) << 28)
 #define MIPS_CONF5_CV          (_ULCAST_(1) << 29)
index db81953f86c5486bd1730fed99ac72a5b52f7401..bd14ba6ea7c5fdc82f31ede48d6ea3c569565fc4 100644 (file)
@@ -7,34 +7,85 @@
 
 #include <common.h>
 #include <asm/cacheops.h>
+#include <asm/cm.h>
 #include <asm/mipsregs.h>
 
-static inline unsigned long icache_line_size(void)
+DECLARE_GLOBAL_DATA_PTR;
+
+static void probe_l2(void)
 {
-       unsigned long conf1, il;
+#ifdef CONFIG_MIPS_L2_CACHE
+       unsigned long conf2, sl;
+       bool l2c = false;
+
+       if (!(read_c0_config1() & MIPS_CONF_M))
+               return;
 
-       if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
-               return CONFIG_SYS_ICACHE_LINE_SIZE;
+       conf2 = read_c0_config2();
+
+       if (__mips_isa_rev >= 6) {
+               l2c = conf2 & MIPS_CONF_M;
+               if (l2c)
+                       l2c = read_c0_config3() & MIPS_CONF_M;
+               if (l2c)
+                       l2c = read_c0_config4() & MIPS_CONF_M;
+               if (l2c)
+                       l2c = read_c0_config5() & MIPS_CONF5_L2C;
+       }
+
+       if (l2c && config_enabled(CONFIG_MIPS_CM)) {
+               gd->arch.l2_line_size = mips_cm_l2_line_size();
+       } else if (l2c) {
+               /* We don't know how to retrieve L2 config on this system */
+               BUG();
+       } else {
+               sl = (conf2 & MIPS_CONF2_SL) >> MIPS_CONF2_SL_SHF;
+               gd->arch.l2_line_size = sl ? (2 << sl) : 0;
+       }
+#endif
+}
+
+void mips_cache_probe(void)
+{
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+       unsigned long conf1, il, dl;
 
        conf1 = read_c0_config1();
+
        il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHF;
-       if (!il)
-               return 0;
-       return 2 << il;
+       dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
+
+       gd->arch.l1i_line_size = il ? (2 << il) : 0;
+       gd->arch.l1d_line_size = dl ? (2 << dl) : 0;
+#endif
+       probe_l2();
 }
 
-static inline unsigned long dcache_line_size(void)
+static inline unsigned long icache_line_size(void)
 {
-       unsigned long conf1, dl;
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+       return gd->arch.l1i_line_size;
+#else
+       return CONFIG_SYS_ICACHE_LINE_SIZE;
+#endif
+}
 
-       if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
-               return CONFIG_SYS_DCACHE_LINE_SIZE;
+static inline unsigned long dcache_line_size(void)
+{
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+       return gd->arch.l1d_line_size;
+#else
+       return CONFIG_SYS_DCACHE_LINE_SIZE;
+#endif
+}
 
-       conf1 = read_c0_config1();
-       dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
-       if (!dl)
-               return 0;
-       return 2 << dl;
+static inline unsigned long scache_line_size(void)
+{
+#ifdef CONFIG_MIPS_L2_CACHE
+       return gd->arch.l2_line_size;
+#else
+       return 0;
+#endif
 }
 
 #define cache_loop(start, end, lsize, ops...) do {                     \
@@ -53,12 +104,13 @@ void flush_cache(ulong start_addr, ulong size)
 {
        unsigned long ilsize = icache_line_size();
        unsigned long dlsize = dcache_line_size();
+       unsigned long slsize = scache_line_size();
 
        /* aend will be miscalculated when size is zero, so we return here */
        if (size == 0)
                return;
 
-       if (ilsize == dlsize) {
+       if ((ilsize == dlsize) && !slsize) {
                /* flush I-cache & D-cache simultaneously */
                cache_loop(start_addr, start_addr + size, ilsize,
                           HIT_WRITEBACK_INV_D, HIT_INVALIDATE_I);
@@ -68,6 +120,11 @@ void flush_cache(ulong start_addr, ulong size)
        /* flush D-cache */
        cache_loop(start_addr, start_addr + size, dlsize, HIT_WRITEBACK_INV_D);
 
+       /* flush L2 cache */
+       if (slsize)
+               cache_loop(start_addr, start_addr + size, slsize,
+                          HIT_WRITEBACK_INV_SD);
+
        /* flush I-cache */
        cache_loop(start_addr, start_addr + size, ilsize, HIT_INVALIDATE_I);
 }
@@ -75,21 +132,31 @@ void flush_cache(ulong start_addr, ulong size)
 void flush_dcache_range(ulong start_addr, ulong stop)
 {
        unsigned long lsize = dcache_line_size();
+       unsigned long slsize = scache_line_size();
 
        /* aend will be miscalculated when size is zero, so we return here */
        if (start_addr == stop)
                return;
 
        cache_loop(start_addr, stop, lsize, HIT_WRITEBACK_INV_D);
+
+       /* flush L2 cache */
+       if (slsize)
+               cache_loop(start_addr, stop, slsize, HIT_WRITEBACK_INV_SD);
 }
 
 void invalidate_dcache_range(ulong start_addr, ulong stop)
 {
        unsigned long lsize = dcache_line_size();
+       unsigned long slsize = scache_line_size();
 
        /* aend will be miscalculated when size is zero, so we return here */
        if (start_addr == stop)
                return;
 
+       /* invalidate L2 cache */
+       if (slsize)
+               cache_loop(start_addr, stop, slsize, HIT_INVALIDATE_SD);
+
        cache_loop(start_addr, stop, lsize, HIT_INVALIDATE_D);
 }
index bc8ab27b58d92289088b8659d0ac224babdb6d46..698a5afdee96a1a03e46d19e8e4584b5b3ac074a 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
 #include <asm/cacheops.h>
+#include <asm/cm.h>
 
 #ifndef CONFIG_SYS_MIPS_CACHE_MODE
 #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
  * with good parity is available. This routine will initialise an area of
  * memory starting at location zero to be used as a source of parity.
  *
+ * Note that this function does not follow the standard calling convention &
+ * may clobber typically callee-saved registers.
+ *
  * RETURNS: N/A
  *
  */
+#define R_RETURN       s0
+#define R_IC_SIZE      s1
+#define R_IC_LINE      s2
+#define R_DC_SIZE      s3
+#define R_DC_LINE      s4
+#define R_L2_SIZE      s5
+#define R_L2_LINE      s6
+#define R_L2_BYPASSED  s7
+#define R_L2_L2C       t8
 LEAF(mips_cache_reset)
+       move    R_RETURN, ra
+
+#ifdef CONFIG_MIPS_L2_CACHE
+       /*
+        * For there to be an L2 present, Config2 must be present. If it isn't
+        * then we proceed knowing there's no L2 cache.
+        */
+       move    R_L2_SIZE, zero
+       move    R_L2_LINE, zero
+       move    R_L2_BYPASSED, zero
+       move    R_L2_L2C, zero
+       mfc0    t0, CP0_CONFIG, 1
+       bgez    t0, l2_probe_done
+
+       /*
+        * From MIPSr6 onwards the L2 cache configuration might not be reported
+        * by Config2. The Config5.L2C bit indicates whether this is the case,
+        * and if it is then we need knowledge of where else to look. For cores
+        * from Imagination Technologies this is a CM GCR.
+        */
+# if __mips_isa_rev >= 6
+       /* Check that Config5 exists */
+       mfc0    t0, CP0_CONFIG, 2
+       bgez    t0, l2_probe_cop0
+       mfc0    t0, CP0_CONFIG, 3
+       bgez    t0, l2_probe_cop0
+       mfc0    t0, CP0_CONFIG, 4
+       bgez    t0, l2_probe_cop0
+
+       /* Check Config5.L2C is set */
+       mfc0    t0, CP0_CONFIG, 5
+       and     R_L2_L2C, t0, MIPS_CONF5_L2C
+       beqz    R_L2_L2C, l2_probe_cop0
+
+       /* Config5.L2C is set */
+#  ifdef CONFIG_MIPS_CM
+       /* The CM will provide L2 configuration */
+       PTR_LI  t0, CKSEG1ADDR(CONFIG_MIPS_CM_BASE)
+       lw      t1, GCR_L2_CONFIG(t0)
+       bgez    t1, l2_probe_done
+
+       ext     R_L2_LINE, t1, \
+               GCR_L2_CONFIG_LINESZ_SHIFT, GCR_L2_CONFIG_LINESZ_BITS
+       beqz    R_L2_LINE, l2_probe_done
+       li      t2, 2
+       sllv    R_L2_LINE, t2, R_L2_LINE
+
+       ext     t2, t1, GCR_L2_CONFIG_ASSOC_SHIFT, GCR_L2_CONFIG_ASSOC_BITS
+       addiu   t2, t2, 1
+       mul     R_L2_SIZE, R_L2_LINE, t2
+
+       ext     t2, t1, GCR_L2_CONFIG_SETSZ_SHIFT, GCR_L2_CONFIG_SETSZ_BITS
+       sllv    R_L2_SIZE, R_L2_SIZE, t2
+       li      t2, 64
+       mul     R_L2_SIZE, R_L2_SIZE, t2
+
+       /* Bypass the L2 cache so that we can init the L1s early */
+       or      t1, t1, GCR_L2_CONFIG_BYPASS
+       sw      t1, GCR_L2_CONFIG(t0)
+       sync
+       li      R_L2_BYPASSED, 1
+
+       /* Zero the L2 tag registers */
+       sw      zero, GCR_L2_TAG_ADDR(t0)
+       sw      zero, GCR_L2_TAG_ADDR_UPPER(t0)
+       sw      zero, GCR_L2_TAG_STATE(t0)
+       sw      zero, GCR_L2_TAG_STATE_UPPER(t0)
+       sw      zero, GCR_L2_DATA(t0)
+       sw      zero, GCR_L2_DATA_UPPER(t0)
+       sync
+#  else
+       /* We don't know how to retrieve L2 configuration on this system */
+#  endif
+       b       l2_probe_done
+# endif
+
+       /*
+        * For pre-r6 systems, or r6 systems with Config5.L2C==0, probe the L2
+        * cache configuration from the cop0 Config2 register.
+        */
+l2_probe_cop0:
+       mfc0    t0, CP0_CONFIG, 2
+
+       srl     R_L2_LINE, t0, MIPS_CONF2_SL_SHF
+       andi    R_L2_LINE, R_L2_LINE, MIPS_CONF2_SL >> MIPS_CONF2_SL_SHF
+       beqz    R_L2_LINE, l2_probe_done
+       li      t1, 2
+       sllv    R_L2_LINE, t1, R_L2_LINE
+
+       srl     t1, t0, MIPS_CONF2_SA_SHF
+       andi    t1, t1, MIPS_CONF2_SA >> MIPS_CONF2_SA_SHF
+       addiu   t1, t1, 1
+       mul     R_L2_SIZE, R_L2_LINE, t1
+
+       srl     t1, t0, MIPS_CONF2_SS_SHF
+       andi    t1, t1, MIPS_CONF2_SS >> MIPS_CONF2_SS_SHF
+       sllv    R_L2_SIZE, R_L2_SIZE, t1
+       li      t1, 64
+       mul     R_L2_SIZE, R_L2_SIZE, t1
+
+       /* Attempt to bypass the L2 so that we can init the L1s early */
+       or      t0, t0, MIPS_CONF2_L2B
+       mtc0    t0, CP0_CONFIG, 2
+       ehb
+       mfc0    t0, CP0_CONFIG, 2
+       and     R_L2_BYPASSED, t0, MIPS_CONF2_L2B
+
+       /* Zero the L2 tag registers */
+       mtc0    zero, CP0_TAGLO, 4
+       ehb
+l2_probe_done:
+#endif
+
 #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
-       li      t2, CONFIG_SYS_ICACHE_SIZE
-       li      t8, CONFIG_SYS_ICACHE_LINE_SIZE
+       li      R_IC_SIZE, CONFIG_SYS_ICACHE_SIZE
+       li      R_IC_LINE, CONFIG_SYS_ICACHE_LINE_SIZE
 #else
-       l1_info t2, t8, MIPS_CONF1_IA_SHF
+       l1_info R_IC_SIZE, R_IC_LINE, MIPS_CONF1_IA_SHF
 #endif
 
 #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
-       li      t3, CONFIG_SYS_DCACHE_SIZE
-       li      t9, CONFIG_SYS_DCACHE_LINE_SIZE
+       li      R_DC_SIZE, CONFIG_SYS_DCACHE_SIZE
+       li      R_DC_LINE, CONFIG_SYS_DCACHE_LINE_SIZE
 #else
-       l1_info t3, t9, MIPS_CONF1_DA_SHF
+       l1_info R_DC_SIZE, R_DC_LINE, MIPS_CONF1_DA_SHF
 #endif
 
 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
@@ -123,9 +249,9 @@ LEAF(mips_cache_reset)
        li      v0, CONFIG_SYS_DCACHE_SIZE
 #endif
 #else
-       move    v0, t2
-       sltu    t1, t2, t3
-       movn    v0, t3, t1
+       move    v0, R_IC_SIZE
+       sltu    t1, R_IC_SIZE, R_DC_SIZE
+       movn    v0, R_DC_SIZE, t1
 #endif
        /*
         * Now clear that much memory starting from zero.
@@ -138,13 +264,36 @@ LEAF(mips_cache_reset)
 
 #endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */
 
+#ifdef CONFIG_MIPS_L2_CACHE
+       /*
+        * If the L2 is bypassed, init the L1 first so that we can execute the
+        * rest of the cache initialisation using the L1 instruction cache.
+        */
+       bnez            R_L2_BYPASSED, l1_init
+
+l2_init:
+       PTR_LI          t0, INDEX_BASE
+       PTR_ADDU        t1, t0, R_L2_SIZE
+1:     cache           INDEX_STORE_TAG_SD, 0(t0)
+       PTR_ADDU        t0, t0, R_L2_LINE
+       bne             t0, t1, 1b
+
+       /*
+        * If the L2 was bypassed then we already initialised the L1s before
+        * the L2, so we are now done.
+        */
+       bnez            R_L2_BYPASSED, l2_unbypass
+#endif
+
        /*
         * The TagLo registers used depend upon the CPU implementation, but the
         * architecture requires that it is safe for software to write to both
         * TagLo selects 0 & 2 covering supported cases.
         */
+l1_init:
        mtc0            zero, CP0_TAGLO
        mtc0            zero, CP0_TAGLO, 2
+       ehb
 
        /*
         * The caches are probably in an indeterminate state, so we force good
@@ -158,40 +307,122 @@ LEAF(mips_cache_reset)
        /*
         * Initialize the I-cache first,
         */
-       blez            t2, 1f
+       blez            R_IC_SIZE, 1f
        PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, t2
+       PTR_ADDU        t1, t0, R_IC_SIZE
        /* clear tag to invalidate */
-       cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
+       cache_loop      t0, t1, R_IC_LINE, INDEX_STORE_TAG_I
 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
        /* fill once, so data field parity is correct */
        PTR_LI          t0, INDEX_BASE
-       cache_loop      t0, t1, t8, FILL
+       cache_loop      t0, t1, R_IC_LINE, FILL
        /* invalidate again - prudent but not strictly neccessary */
        PTR_LI          t0, INDEX_BASE
-       cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
+       cache_loop      t0, t1, R_IC_LINE, INDEX_STORE_TAG_I
+#endif
+
+       /* Enable use of the I-cache by setting Config.K0 */
+       sync
+       mfc0            t0, CP0_CONFIG
+       li              t1, CONFIG_SYS_MIPS_CACHE_MODE
+#if __mips_isa_rev >= 2
+       ins             t0, t1, 0, 3
+#else
+       ori             t0, t0, CONF_CM_CMASK
+       xori            t0, t0, CONF_CM_CMASK
+       or              t0, t0, t1
 #endif
+       mtc0            t0, CP0_CONFIG
 
        /*
         * then initialize D-cache.
         */
-1:     blez            t3, 3f
+1:     blez            R_DC_SIZE, 3f
        PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, t3
+       PTR_ADDU        t1, t0, R_DC_SIZE
        /* clear all tags */
-       cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
+       cache_loop      t0, t1, R_DC_LINE, INDEX_STORE_TAG_D
 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
        /* load from each line (in cached space) */
        PTR_LI          t0, INDEX_BASE
 2:     LONG_L          zero, 0(t0)
-       PTR_ADDU        t0, t9
+       PTR_ADDU        t0, R_DC_LINE
        bne             t0, t1, 2b
        /* clear all tags */
        PTR_LI          t0, INDEX_BASE
-       cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
+       cache_loop      t0, t1, R_DC_LINE, INDEX_STORE_TAG_D
 #endif
+3:
+
+#ifdef CONFIG_MIPS_L2_CACHE
+       /* If the L2 isn't bypassed then we're done */
+       beqz            R_L2_BYPASSED, return
+
+       /* The L2 is bypassed - go initialise it */
+       b               l2_init
 
-3:     jr      ra
+l2_unbypass:
+# if __mips_isa_rev >= 6
+       beqz            R_L2_L2C, 1f
+
+       li              t0, CKSEG1ADDR(CONFIG_MIPS_CM_BASE)
+       lw              t1, GCR_L2_CONFIG(t0)
+       xor             t1, t1, GCR_L2_CONFIG_BYPASS
+       sw              t1, GCR_L2_CONFIG(t0)
+       sync
+       ehb
+       b               2f
+# endif
+1:     mfc0            t0, CP0_CONFIG, 2
+       xor             t0, t0, MIPS_CONF2_L2B
+       mtc0            t0, CP0_CONFIG, 2
+       ehb
+
+2:
+# ifdef CONFIG_MIPS_CM
+       /* Config3 must exist for a CM to be present */
+       mfc0            t0, CP0_CONFIG, 1
+       bgez            t0, 2f
+       mfc0            t0, CP0_CONFIG, 2
+       bgez            t0, 2f
+
+       /* Check Config3.CMGCR to determine CM presence */
+       mfc0            t0, CP0_CONFIG, 3
+       and             t0, t0, MIPS_CONF3_CMGCR
+       beqz            t0, 2f
+
+       /* Change Config.K0 to a coherent CCA */
+       mfc0            t0, CP0_CONFIG
+       li              t1, CONF_CM_CACHABLE_COW
+#if __mips_isa_rev >= 2
+       ins             t0, t1, 0, 3
+#else
+       ori             t0, t0, CONF_CM_CMASK
+       xori            t0, t0, CONF_CM_CMASK
+       or              t0, t0, t1
+#endif
+       mtc0            t0, CP0_CONFIG
+
+       /*
+        * Join the coherent domain such that the caches of this core are kept
+        * coherent with those of other cores.
+        */
+       PTR_LI          t0, CKSEG1ADDR(CONFIG_MIPS_CM_BASE)
+       lw              t1, GCR_REV(t0)
+       li              t2, GCR_REV_CM3
+       li              t3, GCR_Cx_COHERENCE_EN
+       bge             t1, t2, 1f
+       li              t3, GCR_Cx_COHERENCE_DOM_EN
+1:     sw              t3, GCR_Cx_COHERENCE(t0)
+       ehb
+2:
+# endif
+#endif
+
+return:
+       /* Ensure all cache operations complete before returning */
+       sync
+       jr      ra
        END(mips_cache_reset)
 
 /*
index 5756a06d5082de35c4faa6f47c1fa15539b1f5f3..4ef50924789eb120270dea8b425389446429a735 100644 (file)
@@ -46,7 +46,7 @@ static const struct ath79_soc_desc desc[] = {
        {ATH79_SOC_QCA9561,     "9561", REV_ID_MAJOR_QCA9561,   0},
 };
 
-int arch_cpu_init(void)
+int mach_cpu_init(void)
 {
        void __iomem *base;
        enum ath79_soc_type soc = ATH79_SOC_UNKNOWN;
diff --git a/board/imgtec/boston/Kconfig b/board/imgtec/boston/Kconfig
new file mode 100644 (file)
index 0000000..ab76a3c
--- /dev/null
@@ -0,0 +1,16 @@
+if TARGET_BOSTON
+
+config SYS_BOARD
+       default "boston"
+
+config SYS_VENDOR
+       default "imgtec"
+
+config SYS_CONFIG_NAME
+       default "boston"
+
+config SYS_TEXT_BASE
+       default 0x9fc00000 if 32BIT
+       default 0xffffffff9fc00000 if 64BIT
+
+endif
diff --git a/board/imgtec/boston/MAINTAINERS b/board/imgtec/boston/MAINTAINERS
new file mode 100644 (file)
index 0000000..30dd481
--- /dev/null
@@ -0,0 +1,6 @@
+BOSTON BOARD
+M:     Paul Burton <paul.burton@imgtec.com>
+S:     Maintained
+F:     board/imgtec/boston/
+F:     include/configs/boston.h
+F:     configs/boston_defconfig
diff --git a/board/imgtec/boston/Makefile b/board/imgtec/boston/Makefile
new file mode 100644 (file)
index 0000000..deda457
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2016 Imagination Technologies
+#
+# SPDX-License-Identifier:     GPL-2.0
+#
+
+obj-y += checkboard.o
+obj-y += ddr.o
+obj-y += lowlevel_init.o
diff --git a/board/imgtec/boston/boston-lcd.h b/board/imgtec/boston/boston-lcd.h
new file mode 100644 (file)
index 0000000..9f5c1b9
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef __BOARD_BOSTON_LCD_H__
+#define __BOARD_BOSTON_LCD_H__
+
+/**
+ * lowlevel_display() - Display a message on Boston's LCD
+ * @msg: The string to display
+ *
+ * Display the string @msg on the 7 character LCD display of the Boston board.
+ * This is typically used for debug or to present some form of status
+ * indication to the user, allowing faults to be identified when things go
+ * wrong early enough that the UART isn't up.
+ */
+void lowlevel_display(const char msg[static 8]);
+
+#endif /* __BOARD_BOSTON_LCD_H__ */
diff --git a/board/imgtec/boston/boston-regs.h b/board/imgtec/boston/boston-regs.h
new file mode 100644 (file)
index 0000000..b9dfbb4
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef __BOARD_BOSTON_REGS_H__
+#define __BOARD_BOSTON_REGS_H__
+
+#include <asm/addrspace.h>
+
+#define BOSTON_PLAT_BASE               CKSEG1ADDR(0x17ffd000)
+#define BOSTON_LCD_BASE                        CKSEG1ADDR(0x17fff000)
+
+/*
+ * Platform Register Definitions
+ */
+#define BOSTON_PLAT_CORE_CL            (BOSTON_PLAT_BASE + 0x04)
+
+#define BOSTON_PLAT_DDR3STAT           (BOSTON_PLAT_BASE + 0x14)
+# define BOSTON_PLAT_DDR3STAT_CALIB    (1 << 2)
+
+#define BOSTON_PLAT_DDRCONF0           (BOSTON_PLAT_BASE + 0x38)
+# define BOSTON_PLAT_DDRCONF0_SIZE     (0xf << 0)
+
+#endif /* __BOARD_BOSTON_REGS_H__ */
diff --git a/board/imgtec/boston/checkboard.c b/board/imgtec/boston/checkboard.c
new file mode 100644 (file)
index 0000000..93eae7f
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+
+#include "boston-lcd.h"
+#include "boston-regs.h"
+
+int checkboard(void)
+{
+       u32 changelist;
+
+       lowlevel_display("U-boot  ");
+
+       printf("Board: MIPS Boston\n");
+
+       printf("CPU:   0x%08x", read_c0_prid());
+       changelist = __raw_readl((uint32_t *)BOSTON_PLAT_CORE_CL);
+       if (changelist > 1)
+               printf(" cl%x", changelist);
+       putc('\n');
+
+       return 0;
+}
diff --git a/board/imgtec/boston/ddr.c b/board/imgtec/boston/ddr.c
new file mode 100644 (file)
index 0000000..ceffef6
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+
+#include <asm/io.h>
+
+#include "boston-regs.h"
+
+phys_size_t initdram(int board_type)
+{
+       u32 ddrconf0 = __raw_readl((uint32_t *)BOSTON_PLAT_DDRCONF0);
+
+       return (phys_size_t)(ddrconf0 & BOSTON_PLAT_DDRCONF0_SIZE) << 30;
+}
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+
+       if (gd->ram_top < CONFIG_SYS_SDRAM_BASE) {
+               /* 2GB wrapped around to 0 */
+               return CKSEG0ADDR(256 << 20);
+       }
+
+       return min_t(unsigned long, gd->ram_top, CKSEG0ADDR(256 << 20));
+}
diff --git a/board/imgtec/boston/lowlevel_init.S b/board/imgtec/boston/lowlevel_init.S
new file mode 100644 (file)
index 0000000..0c01aa9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <config.h>
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+
+#include "boston-regs.h"
+
+.data
+
+msg_ddr_cal:   .ascii "DDR Cal "
+msg_ddr_ok:    .ascii "DDR OK  "
+
+.text
+
+LEAF(lowlevel_init)
+       move    s0, ra
+
+       PTR_LA  a0, msg_ddr_cal
+       bal     lowlevel_display
+
+       PTR_LI  t0, BOSTON_PLAT_DDR3STAT
+1:     lw      t1, 0(t0)
+       andi    t1, t1, BOSTON_PLAT_DDR3STAT_CALIB
+       beqz    t1, 1b
+
+       PTR_LA  a0, msg_ddr_ok
+       bal     lowlevel_display
+
+       move    v0, zero
+       jr      s0
+       END(lowlevel_init)
+
+LEAF(lowlevel_display)
+       .set    push
+       .set    noat
+       PTR_LI  AT, BOSTON_LCD_BASE
+#ifdef CONFIG_64BIT
+       ld      k1, 0(a0)
+       sd      k1, 0(AT)
+#else
+       lw      k1, 0(a0)
+       sw      k1, 0(AT)
+       lw      k1, 4(a0)
+       sw      k1, 4(AT)
+#endif
+       .set    pop
+1:     jr      ra
+       END(lowlevel_display)
index 3d48cdc1f4714ec05805c49a857197b51bc3a214..6df4d9f719bbfb6b6ef2dd7c34f0be43602af97b 100644 (file)
 
        .globl  lowlevel_init
 lowlevel_init:
-       /* disable any L2 cache for now */
-       sync
-       mfc0    t0, CP0_CONFIG, 2
-       ori     t0, t0, 0x1 << 12
-       mtc0    t0, CP0_CONFIG, 2
-
        /* detect the core card */
        PTR_LI  t0, CKSEG1ADDR(MALTA_REVISION)
        lw      t0, 0(t0)
diff --git a/board/imgtec/xilfpga/Kconfig b/board/imgtec/xilfpga/Kconfig
new file mode 100644 (file)
index 0000000..b078278
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_XILFPGA
+
+config SYS_BOARD
+       default "xilfpga"
+
+config SYS_VENDOR
+       default "imgtec"
+
+config SYS_CONFIG_NAME
+       default "imgtec_xilfpga"
+
+config SYS_TEXT_BASE
+       default 0x80C00000
+
+endif
diff --git a/board/imgtec/xilfpga/MAINTAINERS b/board/imgtec/xilfpga/MAINTAINERS
new file mode 100644 (file)
index 0000000..aa04532
--- /dev/null
@@ -0,0 +1,6 @@
+XILFPGA BOARD
+M:     Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+S:     Maintained
+F:     board/imgtec/xilfpga
+F:     include/configs/xilfpga.h
+F:     configs/imgtec_xilfpga_defconfig
diff --git a/board/imgtec/xilfpga/Makefile b/board/imgtec/xilfpga/Makefile
new file mode 100644 (file)
index 0000000..9aaf9ce
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2016, Imagination Technologies Ltd.
+# Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+obj-y := xilfpga.o
diff --git a/board/imgtec/xilfpga/README b/board/imgtec/xilfpga/README
new file mode 100644 (file)
index 0000000..ac19d48
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016, Imagination Technologies Ltd.
+ *
+ * Zubair Lutfullah Kakakhel, Zubair.Kakakhel@imgtec.com
+ */
+
+MIPSfpga
+=======================================
+
+MIPSfpga is an FPGA based development platform by Imagination Technologies
+As we are dealing with a MIPS core instantiated on an FPGA, specifications
+are fluid and can be varied in RTL.
+
+The example project provided by IMGTEC runs on the Nexys4DDR board by
+Digilent powered by the ARTIX-7 FPGA by Xilinx. Relevant details about
+the example project and the Nexys4DDR board:
+
+- microAptiv UP core m14Kc
+- 50MHz clock speed
+- 128Mbyte DDR RAM     at 0x0000_0000
+- 8Kbyte RAM           at 0x1000_0000
+- axi_intc             at 0x1020_0000
+- axi_uart16550                at 0x1040_0000
+- axi_gpio             at 0x1060_0000
+- axi_i2c              at 0x10A0_0000
+- custom_gpio          at 0x10C0_0000
+- axi_ethernetlite     at 0x10E0_0000
+- 8Kbyte BootRAM       at 0x1FC0_0000
+- 16Mbyte QPI          at 0x1D00_0000
+
+Boot protocol:
+--------------
+
+The BootRAM is a writeable "RAM" in FPGA at 0x1FC0_0000.
+This is for easy reprogrammibility via JTAG.
+
+DDR initialization is already handled by a HW IP block.
+
+When the example project bitstream is loaded, the cpu_reset button
+needs to be pressed.
+
+The bootram initializes the cache and axi_uart
+Then checks if there is anything non 0xffff_ffff at location 0x1D40_0000
+
+If there is, then that is considered as u-boot. u-boot is copied from
+0x1D40_0000 to memory and the bootram jumps into u-boot code.
+
+At this point, the board is ready to load the Linux kernel + buildroot initramfs
+
+This can be done in multiple ways:
+
+1- JTAG load the binary and jump into it.
+2- Load kernel stored in the QSPI flash at 0x1D80_0000
+3- Load uImage via tftp. Ethernet works in u-boot.
+   e.g. env set server ip 192.168.154.45; dhcp uImage; bootm
diff --git a/board/imgtec/xilfpga/xilfpga.c b/board/imgtec/xilfpga/xilfpga.c
new file mode 100644 (file)
index 0000000..77a1952
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Imagination Technologies MIPSfpga platform code
+ *
+ * Copyright (C) 2016, Imagination Technologies Ltd.
+ *
+ * Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+
+/* initialize the DDR Controller and PHY */
+phys_size_t initdram(int board_type)
+{
+       /* MIG IP block is smart and doesn't need SW
+        * to do any init */
+       return CONFIG_SYS_SDRAM_SIZE;   /* in bytes */
+}
index da381dbd93b4d7de42a547874c8e652decfe5a7d..9ef998f9ed239337f542f9f875e826e4050a270e 100644 (file)
@@ -290,6 +290,11 @@ __weak int arch_cpu_init(void)
        return 0;
 }
 
+__weak int mach_cpu_init(void)
+{
+       return 0;
+}
+
 #ifdef CONFIG_SANDBOX
 static int setup_ram_buf(void)
 {
@@ -860,6 +865,7 @@ static init_fnc_t init_sequence_f[] = {
        x86_fsp_init,
 #endif
        arch_cpu_init,          /* basic arch cpu dependent setup */
+       mach_cpu_init,          /* SoC/machine dependent CPU setup */
        initf_dm,
        arch_cpu_init_dm,
        mark_bootstage,         /* need timer, go after init dm */
diff --git a/configs/boston32r2_defconfig b/configs/boston32r2_defconfig
new file mode 100644 (file)
index 0000000..ca66248
--- /dev/null
@@ -0,0 +1,41 @@
+CONFIG_MIPS=y
+CONFIG_TARGET_BOSTON=y
+CONFIG_SYS_TEXT_BASE=0x9fc00000
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="img,boston"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="boston # "
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_MTD=y
+CONFIG_CFI_FLASH=y
+CONFIG_DM_ETH=y
+CONFIG_PCH_GBE=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_XILINX=y
+CONFIG_SYS_NS16550=y
+CONFIG_LZ4=y
diff --git a/configs/boston32r2el_defconfig b/configs/boston32r2el_defconfig
new file mode 100644 (file)
index 0000000..67f54bf
--- /dev/null
@@ -0,0 +1,42 @@
+CONFIG_MIPS=y
+CONFIG_TARGET_BOSTON=y
+CONFIG_SYS_TEXT_BASE=0x9fc00000
+CONFIG_SYS_LITTLE_ENDIAN=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="img,boston"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="boston # "
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_MTD=y
+CONFIG_CFI_FLASH=y
+CONFIG_DM_ETH=y
+CONFIG_PCH_GBE=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_XILINX=y
+CONFIG_SYS_NS16550=y
+CONFIG_LZ4=y
diff --git a/configs/boston64r2_defconfig b/configs/boston64r2_defconfig
new file mode 100644 (file)
index 0000000..1245d1b
--- /dev/null
@@ -0,0 +1,41 @@
+CONFIG_MIPS=y
+CONFIG_TARGET_BOSTON=y
+CONFIG_CPU_MIPS64_R2=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="img,boston"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="boston # "
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_MTD=y
+CONFIG_CFI_FLASH=y
+CONFIG_DM_ETH=y
+CONFIG_PCH_GBE=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_XILINX=y
+CONFIG_SYS_NS16550=y
+CONFIG_LZ4=y
diff --git a/configs/boston64r2el_defconfig b/configs/boston64r2el_defconfig
new file mode 100644 (file)
index 0000000..9b5fa5a
--- /dev/null
@@ -0,0 +1,42 @@
+CONFIG_MIPS=y
+CONFIG_TARGET_BOSTON=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS64_R2=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="img,boston"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="boston # "
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_MTD=y
+CONFIG_CFI_FLASH=y
+CONFIG_DM_ETH=y
+CONFIG_PCH_GBE=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_XILINX=y
+CONFIG_SYS_NS16550=y
+CONFIG_LZ4=y
diff --git a/configs/imgtec_xilfpga_defconfig b/configs/imgtec_xilfpga_defconfig
new file mode 100644 (file)
index 0000000..63f03cd
--- /dev/null
@@ -0,0 +1,25 @@
+CONFIG_MIPS=y
+CONFIG_SYS_MALLOC_F_LEN=0x600
+CONFIG_TARGET_XILFPGA=y
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="nexys4ddr"
+CONFIG_BOOTDELAY=5
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="MIPSfpga # "
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_SAVEENV is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TIME=y
+CONFIG_OF_EMBED=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_NETCONSOLE=y
+CONFIG_CLK=y
+CONFIG_XILINX_EMACLITE=y
+CONFIG_SYS_NS16550=y
+CONFIG_CMD_DHRYSTONE=y
diff --git a/doc/README.boston b/doc/README.boston
new file mode 100644 (file)
index 0000000..38f6710
--- /dev/null
@@ -0,0 +1,58 @@
+MIPS Boston Development Board
+
+---------
+  About
+---------
+
+The MIPS Boston development board is built around an FPGA & 3 PCIe controllers,
+one of which is connected to an Intel EG20T Platform Controller Hub which
+provides most connectivity to the board. It is used during the development &
+testing of both new CPUs and the software support for them. It is essentially
+the successor of the older MIPS Malta board.
+
+--------
+  QEMU
+--------
+
+U-Boot can be run on a currently out-of-tree branch of QEMU with support for
+the Boston board added. This QEMU code can currently be found in the "boston"
+branch of git://git.linux-mips.org/pub/scm/paul/qemu.git and used like so:
+
+  $ git clone git://git.linux-mips.org/pub/scm/paul/qemu.git -b boston
+  $ cd qemu
+  $ ./configure --target-list=mips64el-softmmu
+  $ make
+  $ ./mips64el-softmmu/qemu-system-mips64el -M boston -m 2G \
+      -bios u-boot.bin -serial stdio
+
+Please note that QEMU will default to emulating the I6400 CPU which implements
+the MIPS64r6 ISA, and at the time of writing doesn't implement any earlier CPUs
+with support for the CPS features the Boston board relies upon. You will
+therefore need to configure U-Boot to build for MIPSr6 in order to obtain a
+binary that will work in QEMU.
+
+-------------
+  Toolchain
+-------------
+
+If building for MIPSr6 then you will need a toolchain including GCC 5.x or
+newer, or the Codescape toolchain available for download from Imagination
+Technologies:
+
+  http://codescape-mips-sdk.imgtec.com/components/toolchain/2015.06-05/
+
+The "IMG GNU Linux Toolchain" is capable of building for all current MIPS ISAs,
+architecture revisions & both endiannesses.
+
+--------
+  TODO
+--------
+
+  - AHCI support
+  - CPU driver
+  - Exception handling (+UHI?)
+  - Flash support
+  - IOCU support
+  - L2 cache support
+  - More general LCD display driver
+  - Multi-arch-variant multi-endian fat binary
index 8f3b96a97362268a346e6da11a74adeb82c3c479..c05ce2a9efa384034bc5773ffe5cc83b11a500f8 100644 (file)
@@ -20,6 +20,14 @@ config SPL_CLK
          setting up clocks within SPL, and allows the same drivers to be
          used as U-Boot proper.
 
+config CLK_BOSTON
+       def_bool y if TARGET_BOSTON
+       depends on CLK
+       select REGMAP
+       select SYSCON
+       help
+         Enable this to support the clocks
+
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/uniphier/Kconfig"
 source "drivers/clk/exynos/Kconfig"
index 778d7486f066c9934e47e62817499914b9ccb120..40a5e8cae868d8e579b9488e2ec88267bf668956 100644 (file)
@@ -15,3 +15,4 @@ obj-y += tegra/
 obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
+obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
diff --git a/drivers/clk/clk_boston.c b/drivers/clk/clk_boston.c
new file mode 100644 (file)
index 0000000..78f1b75
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-bindings/clock/boston-clock.h>
+#include <regmap.h>
+#include <syscon.h>
+
+struct clk_boston {
+       struct regmap *regmap;
+};
+
+#define BOSTON_PLAT_MMCMDIV            0x30
+# define BOSTON_PLAT_MMCMDIV_CLK0DIV   (0xff << 0)
+# define BOSTON_PLAT_MMCMDIV_INPUT     (0xff << 8)
+# define BOSTON_PLAT_MMCMDIV_MUL       (0xff << 16)
+# define BOSTON_PLAT_MMCMDIV_CLK1DIV   (0xff << 24)
+
+static uint32_t ext_field(uint32_t val, uint32_t mask)
+{
+       return (val & mask) >> (ffs(mask) - 1);
+}
+
+static ulong clk_boston_get_rate(struct clk *clk)
+{
+       struct clk_boston *state = dev_get_platdata(clk->dev);
+       uint32_t in_rate, mul, div;
+       uint mmcmdiv;
+       int err;
+
+       err = regmap_read(state->regmap, BOSTON_PLAT_MMCMDIV, &mmcmdiv);
+       if (err)
+               return 0;
+
+       in_rate = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_INPUT);
+       mul = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_MUL);
+
+       switch (clk->id) {
+       case BOSTON_CLK_SYS:
+               div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK0DIV);
+               break;
+       case BOSTON_CLK_CPU:
+               div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK1DIV);
+               break;
+       default:
+               return 0;
+       }
+
+       return (in_rate * mul * 1000000) / div;
+}
+
+const struct clk_ops clk_boston_ops = {
+       .get_rate = clk_boston_get_rate,
+};
+
+static int clk_boston_ofdata_to_platdata(struct udevice *dev)
+{
+       struct clk_boston *state = dev_get_platdata(dev);
+       struct udevice *syscon;
+       int err;
+
+       err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
+                                          "regmap", &syscon);
+       if (err) {
+               error("unable to find syscon device\n");
+               return err;
+       }
+
+       state->regmap = syscon_get_regmap(syscon);
+       if (!state->regmap) {
+               error("unable to find regmap\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static const struct udevice_id clk_boston_match[] = {
+       {
+               .compatible = "img,boston-clock",
+       },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(clk_boston) = {
+       .name = "boston_clock",
+       .id = UCLASS_CLK,
+       .of_match = clk_boston_match,
+       .ofdata_to_platdata = clk_boston_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct clk_boston),
+       .ops = &clk_boston_ops,
+};
index 6a634e695180cd35b35619ee6bdb10dbfa31ec08..23b6ba78d3b0b1876cf8b2ab58731bbe384d7e68 100644 (file)
@@ -101,36 +101,24 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 /**
- * driver_check_compatible() - Check if a driver is compatible with this node
+ * driver_check_compatible() - Check if a driver matches a compatible string
  *
- * @param blob:                Device tree pointer
- * @param offset:      Offset of node in device tree
  * @param of_match:    List of compatible strings to match
  * @param of_idp:      Returns the match that was found
- * @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node
- * does not have a compatible string, other error <0 if there is a device
- * tree error
+ * @param compat:      The compatible string to search for
+ * @return 0 if there is a match, -ENOENT if no match
  */
-static int driver_check_compatible(const void *blob, int offset,
-                                  const struct udevice_id *of_match,
-                                  const struct udevice_id **of_idp)
+static int driver_check_compatible(const struct udevice_id *of_match,
+                                  const struct udevice_id **of_idp,
+                                  const char *compat)
 {
-       int ret;
-
-       *of_idp = NULL;
        if (!of_match)
                return -ENOENT;
 
        while (of_match->compatible) {
-               ret = fdt_node_check_compatible(blob, offset,
-                                               of_match->compatible);
-               if (!ret) {
+               if (!strcmp(of_match->compatible, compat)) {
                        *of_idp = of_match;
                        return 0;
-               } else if (ret == -FDT_ERR_NOTFOUND) {
-                       return -ENODEV;
-               } else if (ret < 0) {
-                       return -EINVAL;
                }
                of_match++;
        }
@@ -147,28 +135,46 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
        struct driver *entry;
        struct udevice *dev;
        bool found = false;
-       const char *name;
+       const char *name, *compat_list, *compat;
+       int compat_length, i;
        int result = 0;
        int ret = 0;
 
-       dm_dbg("bind node %s\n", fdt_get_name(blob, offset, NULL));
+       name = fdt_get_name(blob, offset, NULL);
+       dm_dbg("bind node %s\n", name);
        if (devp)
                *devp = NULL;
-       for (entry = driver; entry != driver + n_ents; entry++) {
-               ret = driver_check_compatible(blob, offset, entry->of_match,
-                                             &id);
-               name = fdt_get_name(blob, offset, NULL);
-               if (ret == -ENOENT) {
-                       continue;
-               } else if (ret == -ENODEV) {
+
+       compat_list = fdt_getprop(blob, offset, "compatible", &compat_length);
+       if (!compat_list) {
+               if (compat_length == -FDT_ERR_NOTFOUND) {
                        dm_dbg("Device '%s' has no compatible string\n", name);
-                       break;
-               } else if (ret) {
-                       dm_warn("Device tree error at offset %d\n", offset);
-                       result = ret;
-                       break;
+                       return 0;
                }
 
+               dm_warn("Device tree error at offset %d\n", offset);
+               return compat_length;
+       }
+
+       /*
+        * Walk through the compatible string list, attempting to match each
+        * compatible string in order such that we match in order of priority
+        * from the first string to the last.
+        */
+       for (i = 0; i < compat_length; i += strlen(compat) + 1) {
+               compat = compat_list + i;
+               dm_dbg("   - attempt to match compatible string '%s'\n",
+                      compat);
+
+               for (entry = driver; entry != driver + n_ents; entry++) {
+                       ret = driver_check_compatible(entry->of_match, &id,
+                                                     compat);
+                       if (!ret)
+                               break;
+               }
+               if (entry == driver + n_ents)
+                       continue;
+
                dm_dbg("   - found match at '%s'\n", entry->name);
                ret = device_bind_with_driver_data(parent, entry, name,
                                                   id->data, offset, &dev);
@@ -188,10 +194,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
                break;
        }
 
-       if (!found && !result && ret != -ENODEV) {
-               dm_dbg("No match for node '%s'\n",
-                      fdt_get_name(blob, offset, NULL));
-       }
+       if (!found && !result && ret != -ENODEV)
+               dm_dbg("No match for node '%s'\n", name);
 
        return result;
 }
index 0299ff087937f406a939a15a585046b900584143..c68bcba54f1e5cfd750ec854f5c12b1a6096b214 100644 (file)
@@ -13,6 +13,8 @@
 #include <mapmem.h>
 #include <regmap.h>
 
+#include <asm/io.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
 static struct regmap *regmap_alloc_count(int count)
@@ -117,3 +119,21 @@ int regmap_uninit(struct regmap *map)
 
        return 0;
 }
+
+int regmap_read(struct regmap *map, uint offset, uint *valp)
+{
+       uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
+
+       *valp = le32_to_cpu(readl(ptr));
+
+       return 0;
+}
+
+int regmap_write(struct regmap *map, uint offset, uint val)
+{
+       uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE);
+
+       writel(cpu_to_le32(val), ptr);
+
+       return 0;
+}
index 01bd9683a7a757ccf20a9a769c83ee1555350cd6..2148469abc10e1e13468bc0ed58c695446d20c08 100644 (file)
@@ -95,3 +95,14 @@ UCLASS_DRIVER(syscon) = {
        .per_device_auto_alloc_size = sizeof(struct syscon_uc_info),
        .pre_probe = syscon_pre_probe,
 };
+
+static const struct udevice_id generic_syscon_ids[] = {
+       { .compatible = "syscon" },
+       { }
+};
+
+U_BOOT_DRIVER(generic_syscon) = {
+       .name   = "syscon",
+       .id     = UCLASS_SYSCON,
+       .of_match = generic_syscon_ids,
+};
index be3ed73e52219fbc9179c9d7553cf5887b86c407..302c005aa132986718589bcee06ee449923977d7 100644 (file)
@@ -175,7 +175,7 @@ config XILINX_AXIEMAC
          This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
 
 config XILINX_EMACLITE
-       depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
+       depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP || MIPS)
        select PHYLIB
        select MII
        bool "Xilinx Ethernetlite"
index 137818b39071406b707c6a6741ad51926fedfe5c..d40fff0e48863fb79f26099899257ae4b32566a5 100644 (file)
@@ -118,14 +118,14 @@ static void pch_gbe_rx_descs_init(struct udevice *dev)
        memset(rx_desc, 0, sizeof(struct pch_gbe_rx_desc) * PCH_GBE_DESC_NUM);
        for (i = 0; i < PCH_GBE_DESC_NUM; i++)
                rx_desc->buffer_addr = dm_pci_phys_to_mem(priv->dev,
-                       (u32)(priv->rx_buff[i]));
+                       (ulong)(priv->rx_buff[i]));
 
-       writel(dm_pci_phys_to_mem(priv->dev, (u32)rx_desc),
+       writel(dm_pci_phys_to_mem(priv->dev, (ulong)rx_desc),
               &mac_regs->rx_dsc_base);
        writel(sizeof(struct pch_gbe_rx_desc) * (PCH_GBE_DESC_NUM - 1),
               &mac_regs->rx_dsc_size);
 
-       writel(dm_pci_phys_to_mem(priv->dev, (u32)(rx_desc + 1)),
+       writel(dm_pci_phys_to_mem(priv->dev, (ulong)(rx_desc + 1)),
               &mac_regs->rx_dsc_sw_p);
 }
 
@@ -137,11 +137,11 @@ static void pch_gbe_tx_descs_init(struct udevice *dev)
 
        memset(tx_desc, 0, sizeof(struct pch_gbe_tx_desc) * PCH_GBE_DESC_NUM);
 
-       writel(dm_pci_phys_to_mem(priv->dev, (u32)tx_desc),
+       writel(dm_pci_phys_to_mem(priv->dev, (ulong)tx_desc),
               &mac_regs->tx_dsc_base);
        writel(sizeof(struct pch_gbe_tx_desc) * (PCH_GBE_DESC_NUM - 1),
               &mac_regs->tx_dsc_size);
-       writel(dm_pci_phys_to_mem(priv->dev, (u32)(tx_desc + 1)),
+       writel(dm_pci_phys_to_mem(priv->dev, (ulong)(tx_desc + 1)),
               &mac_regs->tx_dsc_sw_p);
 }
 
@@ -251,7 +251,7 @@ static int pch_gbe_send(struct udevice *dev, void *packet, int length)
        if (length < 64)
                frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
 
-       tx_desc->buffer_addr = dm_pci_phys_to_mem(priv->dev, (u32)packet);
+       tx_desc->buffer_addr = dm_pci_phys_to_mem(priv->dev, (ulong)packet);
        tx_desc->length = length;
        tx_desc->tx_words_eob = length + 3;
        tx_desc->tx_frame_ctrl = frame_ctrl;
@@ -262,7 +262,7 @@ static int pch_gbe_send(struct udevice *dev, void *packet, int length)
        if (++priv->tx_idx >= PCH_GBE_DESC_NUM)
                priv->tx_idx = 0;
 
-       writel(dm_pci_phys_to_mem(priv->dev, (u32)(tx_head + priv->tx_idx)),
+       writel(dm_pci_phys_to_mem(priv->dev, (ulong)(tx_head + priv->tx_idx)),
               &mac_regs->tx_dsc_sw_p);
 
        start = get_timer(0);
@@ -283,7 +283,7 @@ static int pch_gbe_recv(struct udevice *dev, int flags, uchar **packetp)
        struct pch_gbe_priv *priv = dev_get_priv(dev);
        struct pch_gbe_regs *mac_regs = priv->mac_regs;
        struct pch_gbe_rx_desc *rx_desc;
-       u32 hw_desc, buffer_addr, length;
+       ulong hw_desc, buffer_addr, length;
 
        rx_desc = &priv->rx_desc[priv->rx_idx];
 
@@ -291,7 +291,7 @@ static int pch_gbe_recv(struct udevice *dev, int flags, uchar **packetp)
        hw_desc = readl(&mac_regs->rx_dsc_hw_p_hld);
 
        /* Just return if not receiving any packet */
-       if ((u32)rx_desc == hw_desc)
+       if ((ulong)rx_desc == hw_desc)
                return -EAGAIN;
 
        buffer_addr = dm_pci_mem_to_phys(priv->dev, rx_desc->buffer_addr);
@@ -315,7 +315,7 @@ static int pch_gbe_free_pkt(struct udevice *dev, uchar *packet, int length)
        if (++rx_swp >= PCH_GBE_DESC_NUM)
                rx_swp = 0;
 
-       writel(dm_pci_phys_to_mem(priv->dev, (u32)(rx_head + rx_swp)),
+       writel(dm_pci_phys_to_mem(priv->dev, (ulong)(rx_head + rx_swp)),
               &mac_regs->rx_dsc_sw_p);
 
        return 0;
@@ -421,7 +421,7 @@ int pch_gbe_probe(struct udevice *dev)
 {
        struct pch_gbe_priv *priv;
        struct eth_pdata *plat = dev_get_platdata(dev);
-       u32 iobase;
+       void *iobase;
 
        /*
         * The priv structure contains the descriptors and frame buffers which
@@ -432,11 +432,9 @@ int pch_gbe_probe(struct udevice *dev)
 
        priv->dev = dev;
 
-       dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase);
-       iobase &= PCI_BASE_ADDRESS_MEM_MASK;
-       iobase = dm_pci_mem_to_phys(dev, iobase);
+       iobase = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_1, PCI_REGION_MEM);
 
-       plat->iobase = iobase;
+       plat->iobase = (ulong)iobase;
        priv->mac_regs = (struct pch_gbe_regs *)iobase;
 
        /* Read MAC address from SROM and initialize dev->enetaddr with it */
index 7b85aa0463851d22e0c8f6e45f56eb11e62b59ca..d86e7a3954645e59f8563eb999c110b5812c0cd6 100644 (file)
@@ -19,6 +19,7 @@
 #include <fdtdec.h>
 #include <asm-generic/errno.h>
 #include <linux/kernel.h>
+#include <asm/io.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -154,7 +155,7 @@ static int wait_for_bit(const char *func, u32 *reg, const u32 mask,
        unsigned long start = get_timer(0);
 
        while (1) {
-               val = readl(reg);
+               val = __raw_readl(reg);
 
                if (!set)
                        val = ~val;
@@ -193,16 +194,17 @@ static u32 phyread(struct xemaclite *emaclite, u32 phyaddress, u32 registernum,
        if (mdio_wait(regs))
                return 1;
 
-       u32 ctrl_reg = in_be32(&regs->mdioctrl);
-       out_be32(&regs->mdioaddr, XEL_MDIOADDR_OP_MASK |
-                ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
-       out_be32(&regs->mdioctrl, ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+       u32 ctrl_reg = __raw_readl(&regs->mdioctrl);
+       __raw_writel(XEL_MDIOADDR_OP_MASK
+               | ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT)
+               | registernum), &regs->mdioaddr);
+       __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, &regs->mdioctrl);
 
        if (mdio_wait(regs))
                return 1;
 
        /* Read data */
-       *data = in_be32(&regs->mdiord);
+       *data = __raw_readl(&regs->mdiord);
        return 0;
 }
 
@@ -220,11 +222,12 @@ static u32 phywrite(struct xemaclite *emaclite, u32 phyaddress, u32 registernum,
         * Data register. Finally, set the Status bit in the MDIO Control
         * register to start a MDIO write transaction.
         */
-       u32 ctrl_reg = in_be32(&regs->mdioctrl);
-       out_be32(&regs->mdioaddr, ~XEL_MDIOADDR_OP_MASK &
-                ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
-       out_be32(&regs->mdiowr, data);
-       out_be32(&regs->mdioctrl, ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+       u32 ctrl_reg = __raw_readl(&regs->mdioctrl);
+       __raw_writel(~XEL_MDIOADDR_OP_MASK
+               & ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT)
+               | registernum), &regs->mdioaddr);
+       __raw_writel(data, &regs->mdiowr);
+       __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, &regs->mdioctrl);
 
        if (mdio_wait(regs))
                return 1;
@@ -327,27 +330,27 @@ static int emaclite_start(struct udevice *dev)
  * TX - TX_PING & TX_PONG initialization
  */
        /* Restart PING TX */
-       out_be32(&regs->tx_ping_tsr, 0);
+       __raw_writel(0, &regs->tx_ping_tsr);
        /* Copy MAC address */
        xemaclite_alignedwrite(pdata->enetaddr, &regs->tx_ping,
                               ENET_ADDR_LENGTH);
        /* Set the length */
-       out_be32(&regs->tx_ping_tplr, ENET_ADDR_LENGTH);
+       __raw_writel(ENET_ADDR_LENGTH, &regs->tx_ping_tplr);
        /* Update the MAC address in the EMAC Lite */
-       out_be32(&regs->tx_ping_tsr, XEL_TSR_PROG_MAC_ADDR);
+       __raw_writel(XEL_TSR_PROG_MAC_ADDR, &regs->tx_ping_tsr);
        /* Wait for EMAC Lite to finish with the MAC address update */
-       while ((in_be32 (&regs->tx_ping_tsr) &
+       while ((__raw_readl(&regs->tx_ping_tsr) &
                XEL_TSR_PROG_MAC_ADDR) != 0)
                ;
 
        if (emaclite->txpp) {
                /* The same operation with PONG TX */
-               out_be32(&regs->tx_pong_tsr, 0);
+               __raw_writel(0, &regs->tx_pong_tsr);
                xemaclite_alignedwrite(pdata->enetaddr, &regs->tx_pong,
                                       ENET_ADDR_LENGTH);
-               out_be32(&regs->tx_pong_tplr, ENET_ADDR_LENGTH);
-               out_be32(&regs->tx_pong_tsr, XEL_TSR_PROG_MAC_ADDR);
-               while ((in_be32(&regs->tx_pong_tsr) &
+               __raw_writel(ENET_ADDR_LENGTH, &regs->tx_pong_tplr);
+               __raw_writel(XEL_TSR_PROG_MAC_ADDR, &regs->tx_pong_tsr);
+               while ((__raw_readl(&regs->tx_pong_tsr) &
                       XEL_TSR_PROG_MAC_ADDR) != 0)
                        ;
        }
@@ -356,13 +359,13 @@ static int emaclite_start(struct udevice *dev)
  * RX - RX_PING & RX_PONG initialization
  */
        /* Write out the value to flush the RX buffer */
-       out_be32(&regs->rx_ping_rsr, XEL_RSR_RECV_IE_MASK);
+       __raw_writel(XEL_RSR_RECV_IE_MASK, &regs->rx_ping_rsr);
 
        if (emaclite->rxpp)
-               out_be32(&regs->rx_pong_rsr, XEL_RSR_RECV_IE_MASK);
+               __raw_writel(XEL_RSR_RECV_IE_MASK, &regs->rx_pong_rsr);
 
-       out_be32(&regs->mdioctrl, XEL_MDIOCTRL_MDIOEN_MASK);
-       if (in_be32(&regs->mdioctrl) & XEL_MDIOCTRL_MDIOEN_MASK)
+       __raw_writel(XEL_MDIOCTRL_MDIOEN_MASK, &regs->mdioctrl);
+       if (__raw_readl(&regs->mdioctrl) & XEL_MDIOCTRL_MDIOEN_MASK)
                if (!setup_phy(dev))
                        return -1;
 
@@ -379,9 +382,9 @@ static int xemaclite_txbufferavailable(struct xemaclite *emaclite)
         * Read the other buffer register
         * and determine if the other buffer is available
         */
-       tmp = ~in_be32(&regs->tx_ping_tsr);
+       tmp = ~__raw_readl(&regs->tx_ping_tsr);
        if (emaclite->txpp)
-               tmp |= ~in_be32(&regs->tx_pong_tsr);
+               tmp |= ~__raw_readl(&regs->tx_pong_tsr);
 
        return !(tmp & XEL_TSR_XMIT_BUSY_MASK);
 }
@@ -405,40 +408,42 @@ static int emaclite_send(struct udevice *dev, void *ptr, int len)
        if (!maxtry) {
                printf("Error: Timeout waiting for ethernet TX buffer\n");
                /* Restart PING TX */
-               out_be32(&regs->tx_ping_tsr, 0);
+               __raw_writel(0, &regs->tx_ping_tsr);
                if (emaclite->txpp) {
-                       out_be32(&regs->tx_pong_tsr, 0);
+                       __raw_writel(0, &regs->tx_pong_tsr);
                }
                return -1;
        }
 
        /* Determine if the expected buffer address is empty */
-       reg = in_be32(&regs->tx_ping_tsr);
+       reg = __raw_readl(&regs->tx_ping_tsr);
        if ((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) {
                debug("Send packet from tx_ping buffer\n");
                /* Write the frame to the buffer */
                xemaclite_alignedwrite(ptr, &regs->tx_ping, len);
-               out_be32(&regs->tx_ping_tplr, len &
-                       (XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO));
-               reg = in_be32(&regs->tx_ping_tsr);
+               __raw_writel(len
+                       & (XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO),
+                      &regs->tx_ping_tplr);
+               reg = __raw_readl(&regs->tx_ping_tsr);
                reg |= XEL_TSR_XMIT_BUSY_MASK;
-               out_be32(&regs->tx_ping_tsr, reg);
+               __raw_writel(reg, &regs->tx_ping_tsr);
                return 0;
        }
 
        if (emaclite->txpp) {
                /* Determine if the expected buffer address is empty */
-               reg = in_be32(&regs->tx_pong_tsr);
+               reg = __raw_readl(&regs->tx_pong_tsr);
                if ((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) {
                        debug("Send packet from tx_pong buffer\n");
                        /* Write the frame to the buffer */
                        xemaclite_alignedwrite(ptr, &regs->tx_pong, len);
-                       out_be32(&regs->tx_pong_tplr, len &
+                       __raw_writel(len &
                                 (XEL_TPLR_LENGTH_MASK_HI |
-                                 XEL_TPLR_LENGTH_MASK_LO));
-                       reg = in_be32(&regs->tx_pong_tsr);
+                                 XEL_TPLR_LENGTH_MASK_LO),
+                                 &regs->tx_pong_tplr);
+                       reg = __raw_readl(&regs->tx_pong_tsr);
                        reg |= XEL_TSR_XMIT_BUSY_MASK;
-                       out_be32(&regs->tx_pong_tsr, reg);
+                       __raw_writel(reg, &regs->tx_pong_tsr);
                        return 0;
                }
        }
@@ -458,7 +463,7 @@ static int emaclite_recv(struct udevice *dev, int flags, uchar **packetp)
 
 try_again:
        if (!emaclite->use_rx_pong_buffer_next) {
-               reg = in_be32(&regs->rx_ping_rsr);
+               reg = __raw_readl(&regs->rx_ping_rsr);
                debug("Testing data at rx_ping\n");
                if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
                        debug("Data found in rx_ping buffer\n");
@@ -478,7 +483,7 @@ try_again:
                        goto try_again;
                }
        } else {
-               reg = in_be32(&regs->rx_pong_rsr);
+               reg = __raw_readl(&regs->rx_pong_rsr);
                debug("Testing data at rx_pong\n");
                if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
                        debug("Data found in rx_pong buffer\n");
@@ -525,9 +530,9 @@ try_again:
                                      length - first_read);
 
        /* Acknowledge the frame */
-       reg = in_be32(ack);
+       reg = __raw_readl(ack);
        reg &= ~XEL_RSR_RECV_DONE_MASK;
-       out_be32(ack, reg);
+       __raw_writel(reg, ack);
 
        debug("Packet receive from 0x%p, length %dB\n", addr, length);
        *packetp = etherrxbuff;
@@ -595,7 +600,8 @@ static int emaclite_ofdata_to_platdata(struct udevice *dev)
        int offset = 0;
 
        pdata->iobase = (phys_addr_t)dev_get_addr(dev);
-       emaclite->regs = (struct emaclite_regs *)pdata->iobase;
+       emaclite->regs = (struct emaclite_regs *)ioremap_nocache(pdata->iobase,
+                                                                0x10000);
 
        emaclite->phyaddr = -1;
 
index 669e37bb5dc5ce0b4cd4df255d5405c7a98d6a48..9a7c187446b85940c68c9015beccee348655e35c 100644 (file)
@@ -39,4 +39,11 @@ config PCI_TEGRA
          with a total of 5 lanes. Some boards require this for Ethernet
          support to work (e.g. beaver, jetson-tk1).
 
+config PCI_XILINX
+       bool "Xilinx AXI Bridge for PCI Express"
+       depends on DM_PCI
+       help
+         Enable support for the Xilinx AXI bridge for PCI express, an IP block
+         which can be used on some generations of Xilinx FPGAs.
+
 endmenu
index f8be9bf1ea5393b7421408a6d8c1dcb93f565b3b..9583e91ceb07e51370ed0f6f05d2676a869f5e05 100644 (file)
@@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o
 obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o
 obj-$(CONFIG_WINBOND_83C553) += w83c553f.o
 obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
+obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o
index 342b78c0c4ba566518284fe04d5e64468e921c72..3b00e6a41b36c040e3c1298bf4f5b1248c51872a 100644 (file)
@@ -837,7 +837,7 @@ static int pci_uclass_pre_probe(struct udevice *bus)
        hose = bus->uclass_priv;
 
        /* For bridges, use the top-level PCI controller */
-       if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) {
+       if (!device_is_on_pci_bus(bus)) {
                hose->ctlr = bus;
                ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset,
                                bus->of_offset);
diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c
new file mode 100644 (file)
index 0000000..5216001
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Xilinx AXI Bridge for PCI Express Driver
+ *
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+
+#include <asm/io.h>
+
+/**
+ * struct xilinx_pcie - Xilinx PCIe controller state
+ * @hose: The parent classes PCI controller state
+ * @cfg_base: The base address of memory mapped configuration space
+ */
+struct xilinx_pcie {
+       struct pci_controller hose;
+       void *cfg_base;
+};
+
+/* Register definitions */
+#define XILINX_PCIE_REG_PSCR           0x144
+#define XILINX_PCIE_REG_PSCR_LNKUP     BIT(11)
+
+/**
+ * pcie_xilinx_link_up() - Check whether the PCIe link is up
+ * @pcie: Pointer to the PCI controller state
+ *
+ * Checks whether the PCIe link for the given device is up or down.
+ *
+ * Return: true if the link is up, else false
+ */
+static bool pcie_xilinx_link_up(struct xilinx_pcie *pcie)
+{
+       uint32_t pscr = __raw_readl(pcie->cfg_base + XILINX_PCIE_REG_PSCR);
+
+       return pscr & XILINX_PCIE_REG_PSCR_LNKUP;
+}
+
+/**
+ * pcie_xilinx_config_address() - Calculate the address of a config access
+ * @pcie: Pointer to the PCI controller state
+ * @bdf: Identifies the PCIe device to access
+ * @offset: The offset into the device's configuration space
+ * @paddress: Pointer to the pointer to write the calculates address to
+ *
+ * Calculates the address that should be accessed to perform a PCIe
+ * configuration space access for a given device identified by the PCIe
+ * controller device @pcie and the bus, device & function numbers in @bdf. If
+ * access to the device is not valid then the function will return an error
+ * code. Otherwise the address to access will be written to the pointer pointed
+ * to by @paddress.
+ *
+ * Return: 0 on success, else -ENODEV
+ */
+static int pcie_xilinx_config_address(struct xilinx_pcie *pcie, pci_dev_t bdf,
+                                     uint offset, void **paddress)
+{
+       unsigned int bus = PCI_BUS(bdf);
+       unsigned int dev = PCI_DEV(bdf);
+       unsigned int func = PCI_FUNC(bdf);
+       void *addr;
+
+       if ((bus > 0) && !pcie_xilinx_link_up(pcie))
+               return -ENODEV;
+
+       /*
+        * Busses 0 (host-PCIe bridge) & 1 (its immediate child) are
+        * limited to a single device each.
+        */
+       if ((bus < 2) && (dev > 0))
+               return -ENODEV;
+
+       addr = pcie->cfg_base;
+       addr += bus << 20;
+       addr += dev << 15;
+       addr += func << 12;
+       addr += offset;
+       *paddress = addr;
+
+       return 0;
+}
+
+/**
+ * pcie_xilinx_read_config() - Read from configuration space
+ * @pcie: Pointer to the PCI controller state
+ * @bdf: Identifies the PCIe device to access
+ * @offset: The offset into the device's configuration space
+ * @valuep: A pointer at which to store the read value
+ * @size: Indicates the size of access to perform
+ *
+ * Read a value of size @size from offset @offset within the configuration
+ * space of the device identified by the bus, device & function numbers in @bdf
+ * on the PCI bus @bus.
+ *
+ * Return: 0 on success, else -ENODEV or -EINVAL
+ */
+static int pcie_xilinx_read_config(struct udevice *bus, pci_dev_t bdf,
+                                  uint offset, ulong *valuep,
+                                  enum pci_size_t size)
+{
+       struct xilinx_pcie *pcie = dev_get_priv(bus);
+       void *address;
+       int err;
+
+       err = pcie_xilinx_config_address(pcie, bdf, offset, &address);
+       if (err < 0) {
+               *valuep = pci_get_ff(size);
+               return 0;
+       }
+
+       switch (size) {
+       case PCI_SIZE_8:
+               *valuep = __raw_readb(address);
+               return 0;
+       case PCI_SIZE_16:
+               *valuep = __raw_readw(address);
+               return 0;
+       case PCI_SIZE_32:
+               *valuep = __raw_readl(address);
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+/**
+ * pcie_xilinx_write_config() - Write to configuration space
+ * @pcie: Pointer to the PCI controller state
+ * @bdf: Identifies the PCIe device to access
+ * @offset: The offset into the device's configuration space
+ * @value: The value to write
+ * @size: Indicates the size of access to perform
+ *
+ * Write the value @value of size @size from offset @offset within the
+ * configuration space of the device identified by the bus, device & function
+ * numbers in @bdf on the PCI bus @bus.
+ *
+ * Return: 0 on success, else -ENODEV or -EINVAL
+ */
+static int pcie_xilinx_write_config(struct udevice *bus, pci_dev_t bdf,
+                                   uint offset, ulong value,
+                                   enum pci_size_t size)
+{
+       struct xilinx_pcie *pcie = dev_get_priv(bus);
+       void *address;
+       int err;
+
+       err = pcie_xilinx_config_address(pcie, bdf, offset, &address);
+       if (err < 0)
+               return 0;
+
+       switch (size) {
+       case PCI_SIZE_8:
+               __raw_writeb(value, address);
+               return 0;
+       case PCI_SIZE_16:
+               __raw_writew(value, address);
+               return 0;
+       case PCI_SIZE_32:
+               __raw_writel(value, address);
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+/**
+ * pcie_xilinx_ofdata_to_platdata() - Translate from DT to device state
+ * @dev: A pointer to the device being operated on
+ *
+ * Translate relevant data from the device tree pertaining to device @dev into
+ * state that the driver will later make use of. This state is stored in the
+ * device's private data structure.
+ *
+ * Return: 0 on success, else -EINVAL
+ */
+static int pcie_xilinx_ofdata_to_platdata(struct udevice *dev)
+{
+       struct xilinx_pcie *pcie = dev_get_priv(dev);
+       struct fdt_resource reg_res;
+       DECLARE_GLOBAL_DATA_PTR;
+       int err;
+
+       err = fdt_get_resource(gd->fdt_blob, dev->of_offset, "reg",
+                              0, &reg_res);
+       if (err < 0) {
+               error("\"reg\" resource not found\n");
+               return err;
+       }
+
+       pcie->cfg_base = map_physmem(reg_res.start,
+                                    fdt_resource_size(&reg_res),
+                                    MAP_NOCACHE);
+
+       return 0;
+}
+
+static const struct dm_pci_ops pcie_xilinx_ops = {
+       .read_config    = pcie_xilinx_read_config,
+       .write_config   = pcie_xilinx_write_config,
+};
+
+static const struct udevice_id pcie_xilinx_ids[] = {
+       { .compatible = "xlnx,axi-pcie-host-1.00.a" },
+       { }
+};
+
+U_BOOT_DRIVER(pcie_xilinx) = {
+       .name                   = "pcie_xilinx",
+       .id                     = UCLASS_PCI,
+       .of_match               = pcie_xilinx_ids,
+       .ops                    = &pcie_xilinx_ops,
+       .ofdata_to_platdata     = pcie_xilinx_ofdata_to_platdata,
+       .priv_auto_alloc_size   = sizeof(struct xilinx_pcie),
+};
index 88fca15357e6414915427d79d561669d67a156d9..3f6ea4d27591233836977c84450c5d7aac96f824 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <errno.h>
 #include <fdtdec.h>
@@ -352,6 +353,8 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
 {
        struct ns16550_platdata *plat = dev->platdata;
        fdt_addr_t addr;
+       struct clk clk;
+       int err;
 
        /* try Processor Local Bus device first */
        addr = dev_get_addr(dev);
@@ -397,9 +400,21 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
                                     "reg-offset", 0);
        plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
                                         "reg-shift", 0);
-       plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
-                                    "clock-frequency",
-                                    CONFIG_SYS_NS16550_CLK);
+
+       err = clk_get_by_index(dev, 0, &clk);
+       if (!err) {
+               err = clk_get_rate(&clk);
+               if (!IS_ERR_VALUE(err))
+                       plat->clock = err;
+       } else if (err != -ENODEV && err != -ENOSYS) {
+               debug("ns16550 failed to get clock\n");
+               return err;
+       }
+
+       if (!plat->clock)
+               plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+                                            "clock-frequency",
+                                            CONFIG_SYS_NS16550_CLK);
        if (!plat->clock) {
                debug("ns16550 clock not defined\n");
                return -EINVAL;
index dc18b0310a4eea139095449901f3c8fe3faac05d..9b2452268d40ebde5062fb9c79e97888e7e65f81 100644 (file)
@@ -59,7 +59,7 @@ struct clk {
        unsigned long id;
 };
 
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK)
 struct phandle_2_cell;
 int clk_get_by_index_platdata(struct udevice *dev, int index,
                              struct phandle_2_cell *cells, struct clk *clk);
diff --git a/include/configs/boston.h b/include/configs/boston.h
new file mode 100644 (file)
index 0000000..e958054
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef __CONFIGS_BOSTON_H__
+#define __CONFIGS_BOSTON_H__
+
+/*
+ * General board configuration
+ */
+#define CONFIG_DISPLAY_BOARDINFO
+
+/*
+ * CPU
+ */
+#define CONFIG_SYS_MIPS_TIMER_FREQ     30000000
+
+/*
+ * PCI
+ */
+#define CONFIG_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_CMD_PCI
+
+/*
+ * Memory map
+ */
+#ifdef CONFIG_64BIT
+# define CONFIG_SYS_SDRAM_BASE         0xffffffff80000000
+#else
+# define CONFIG_SYS_SDRAM_BASE         0x80000000
+#endif
+
+#define CONFIG_SYS_INIT_SP_OFFSET      0x400000
+
+#define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_LOAD_ADDR           (CONFIG_SYS_SDRAM_BASE + 0x100000)
+
+#define CONFIG_SYS_MEMTEST_START       (CONFIG_SYS_SDRAM_BASE + 0)
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+#define CONFIG_SYS_MALLOC_LEN          (256 * 1024)
+
+/*
+ * Console
+ */
+#define CONFIG_SYS_MAXARGS             16
+#define CONFIG_SYS_CBSIZE              256
+#define CONFIG_SYS_PBSIZE              (CONFIG_SYS_CBSIZE + \
+                                        sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_BAUDRATE                        115200
+
+/*
+ * Flash
+ */
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT      1
+#define CONFIG_SYS_MAX_FLASH_SECT              1024
+
+/*
+ * Environment
+ */
+#define CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_SECT_SIZE           0x20000
+#define CONFIG_ENV_SIZE                        CONFIG_ENV_SECT_SIZE
+#ifdef CONFIG_64BIT
+# define CONFIG_ENV_ADDR \
+       (0xffffffffb8000000 + (128 << 20) - CONFIG_ENV_SIZE)
+#else
+# define CONFIG_ENV_ADDR \
+       (0xb8000000 + (128 << 20) - CONFIG_ENV_SIZE)
+#endif
+
+#endif /* __CONFIGS_BOSTON_H__ */
diff --git a/include/configs/imgtec_xilfpga.h b/include/configs/imgtec_xilfpga.h
new file mode 100644 (file)
index 0000000..0a7fe60
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016, Imagination Technologies Ltd.
+ *
+ * Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Imagination Technologies Ltd. MIPSfpga
+ */
+
+#ifndef __XILFPGA_CONFIG_H
+#define __XILFPGA_CONFIG_H
+
+/* BootROM + MIG is pretty smart. DDR and Cache initialized */
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+/*--------------------------------------------
+ * CPU configuration
+ */
+/* CPU Timer rate */
+#define CONFIG_SYS_MIPS_TIMER_FREQ     50000000
+
+/* Cache Configuration */
+#define CONFIG_SYS_MIPS_CACHE_MODE     CONF_CM_CACHABLE_NONCOHERENT
+
+/*----------------------------------------------------------------------
+ * Memory Layout
+ */
+
+/* SDRAM Configuration (for final code, data, stack, heap) */
+#define CONFIG_SYS_SDRAM_BASE          0x80000000
+#define CONFIG_SYS_SDRAM_SIZE          0x08000000      /* 128 Mbytes */
+#define CONFIG_SYS_INIT_SP_ADDR                \
+       (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - 0x1000)
+
+#define CONFIG_SYS_MALLOC_LEN          (256 << 10)
+#define CONFIG_SYS_MONITOR_BASE                CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_LOAD_ADDR           0x80500000 /* default load address */
+
+/*----------------------------------------------------------------------
+ * Commands
+ */
+#define CONFIG_SYS_LONGHELP            /* undef to save memory */
+
+/*-------------------------------------------------
+ * FLASH configuration
+ */
+#define CONFIG_SYS_NO_FLASH
+
+/*------------------------------------------------------------
+ * Console Configuration
+ */
+#define CONFIG_SYS_CBSIZE              1024 /* Console I/O Buffer Size   */
+#define CONFIG_SYS_MAXARGS             16   /* max number of command args*/
+#define CONFIG_BAUDRATE                        115200
+
+/* -------------------------------------------------
+ * Environment
+ */
+#define CONFIG_ENV_IS_NOWHERE  1
+#define CONFIG_ENV_SIZE                0x4000
+
+/* ---------------------------------------------------------------------
+ * Board boot configuration
+ */
+#define CONFIG_TIMESTAMP       /* Print image info with timestamp */
+
+#endif /* __XILFPGA_CONFIG_H */
diff --git a/include/dt-bindings/clock/boston-clock.h b/include/dt-bindings/clock/boston-clock.h
new file mode 100644 (file)
index 0000000..25f9cd2
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__
+#define __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__
+
+#define BOSTON_CLK_SYS 0
+#define BOSTON_CLK_CPU 1
+
+#endif /* __DT_BINDINGS_CLOCK_BOSTON_CLOCK_H__ */
diff --git a/include/dt-bindings/interrupt-controller/mips-gic.h b/include/dt-bindings/interrupt-controller/mips-gic.h
new file mode 100644 (file)
index 0000000..cf35a57
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_MIPS_GIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_MIPS_GIC_H
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#define GIC_SHARED 0
+#define GIC_LOCAL 1
+
+#endif