]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge tag 'soc-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 May 2013 18:02:18 +0000 (11:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 7 May 2013 18:02:18 +0000 (11:02 -0700)
Pull ARM SoC platform updates (part 3) from Arnd Bergmann:
 "This is the third and smallest of the SoC specific updates.  Changes
  include:

   - SMP support for the Xilinx zynq platform
   - Smaller imx changes
   - LPAE support for mvebu
   - Moving the orion5x, kirkwood, dove and mvebu platforms to a common
     "mbus" driver for their internal devices.

  It would be good to get feedback on the location of the "mbus" driver.
  Since this is used on multiple platforms may potentially get shared
  with other architectures (powerpc and arm64), it was moved to
  drivers/bus/.  We expect other similar drivers to get moved to the
  same place in order to avoid creating more top-level directories under
  drivers/ or cluttering up the messy drivers/misc/ even more."

* tag 'soc-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (50 commits)
  ARM: imx: reset_controller may be disabled
  ARM: mvebu: Align the internal registers virtual base to support LPAE
  ARM: mvebu: Limit the DMA zone when LPAE is selected
  arm: plat-orion: remove addr-map code
  arm: mach-mv78xx0: convert to use the mvebu-mbus driver
  arm: mach-orion5x: convert to use mvebu-mbus driver
  arm: mach-dove: convert to use mvebu-mbus driver
  arm: mach-kirkwood: convert to use mvebu-mbus driver
  arm: mach-mvebu: convert to use mvebu-mbus driver
  ARM i.MX53: set CLK_SET_RATE_PARENT flag on the tve_ext_sel clock
  ARM i.MX53: tve_di clock is not part of the CCM, but of TVE
  ARM i.MX53: make tve_ext_sel propagate rate change to PLL
  ARM i.MX53: Remove unused tve_gate clkdev entry
  ARM i.MX5: Remove tve_sel clock from i.MX53 clock tree
  ARM: i.MX5: Add PATA and SRTC clocks
  ARM: imx: do not bring up unavailable cores
  ARM: imx: add initial imx6dl support
  ARM: imx1: mm: add call to mxc_device_init
  ARM: imx_v4_v5_defconfig: Add CONFIG_GPIO_SYSFS
  ARM: imx_v6_v7_defconfig: Select CONFIG_PERF_EVENTS
  ...

95 files changed:
Documentation/devicetree/bindings/clock/imx5-clock.txt
Documentation/devicetree/bindings/clock/imx6q-clock.txt
Documentation/devicetree/bindings/reset/fsl,imx-src.txt [new file with mode: 0644]
Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/zynq-7000.dtsi
arch/arm/configs/imx_v4_v5_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/include/debug/mvebu.S
arch/arm/mach-dove/Makefile
arch/arm/mach-dove/addr-map.c [deleted file]
arch/arm/mach-dove/board-dt.c
arch/arm/mach-dove/common.c
arch/arm/mach-dove/common.h
arch/arm/mach-dove/include/mach/dove.h
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/anatop.c [new file with mode: 0644]
arch/arm/mach-imx/clk-imx51-imx53.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/clk.h
arch/arm/mach-imx/common.h
arch/arm/mach-imx/gpc.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mm-imx1.c
arch/arm/mach-imx/mxc.h
arch/arm/mach-imx/platsmp.c
arch/arm/mach-imx/pm-imx6q.c
arch/arm/mach-imx/src.c
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/addr-map.c [deleted file]
arch/arm/mach-kirkwood/board-dt.c
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/mach-kirkwood/include/mach/kirkwood.h
arch/arm/mach-kirkwood/pcie.c
arch/arm/mach-mv78xx0/Makefile
arch/arm/mach-mv78xx0/addr-map.c [deleted file]
arch/arm/mach-mv78xx0/common.c
arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
arch/arm/mach-mv78xx0/pcie.c
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-mvebu/Makefile
arch/arm/mach-mvebu/addr-map.c [deleted file]
arch/arm/mach-mvebu/armada-370-xp.c
arch/arm/mach-mvebu/armada-370-xp.h
arch/arm/mach-mvebu/platsmp.c
arch/arm/mach-orion5x/Makefile
arch/arm/mach-orion5x/addr-map.c [deleted file]
arch/arm/mach-orion5x/board-dt.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-orion5x/common.h
arch/arm/mach-orion5x/d2net-setup.c
arch/arm/mach-orion5x/db88f5281-setup.c
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/edmini_v2-setup.c
arch/arm/mach-orion5x/include/mach/orion5x.h
arch/arm/mach-orion5x/kurobox_pro-setup.c
arch/arm/mach-orion5x/ls-chl-setup.c
arch/arm/mach-orion5x/ls_hgl-setup.c
arch/arm/mach-orion5x/lsmini-setup.c
arch/arm/mach-orion5x/mss2-setup.c
arch/arm/mach-orion5x/mv2120-setup.c
arch/arm/mach-orion5x/net2big-setup.c
arch/arm/mach-orion5x/pci.c
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f5182-setup.c
arch/arm/mach-orion5x/terastation_pro2-setup.c
arch/arm/mach-orion5x/ts209-setup.c
arch/arm/mach-orion5x/ts409-setup.c
arch/arm/mach-orion5x/wnr854t-setup.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-shmobile/clock-r8a7779.c
arch/arm/mach-shmobile/include/mach/r8a7779.h
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-zynq/Kconfig
arch/arm/mach-zynq/Makefile
arch/arm/mach-zynq/common.c
arch/arm/mach-zynq/common.h
arch/arm/mach-zynq/headsmp.S [new file with mode: 0644]
arch/arm/mach-zynq/hotplug.c [new file with mode: 0644]
arch/arm/mach-zynq/platsmp.c [new file with mode: 0644]
arch/arm/mach-zynq/slcr.c [new file with mode: 0644]
arch/arm/plat-orion/Makefile
arch/arm/plat-orion/addr-map.c [deleted file]
arch/arm/plat-orion/gpio.c
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/mvebu-mbus.c [new file with mode: 0644]
drivers/pinctrl/sh-pfc/pfc-r8a7779.c
drivers/staging/imx-drm/ipu-v3/ipu-common.c
include/linux/mbus.h

index 2a0c904c46aee13ac4ff6667c943f09cde483fcb..d71b4b2c077daa410a53951893229ecbac59a892 100644 (file)
@@ -38,7 +38,6 @@ clocks and IDs.
        usb_phy_podf            23
        cpu_podf                24
        di_pred                 25
-       tve_di                  26
        tve_s                   27
        uart1_ipg_gate          28
        uart1_per_gate          29
@@ -172,6 +171,19 @@ clocks and IDs.
        can1_serial_gate        157
        can1_ipg_gate           158
        owire_gate              159
+       gpu3d_s                 160
+       gpu2d_s                 161
+       gpu3d_gate              162
+       gpu2d_gate              163
+       garb_gate               164
+       cko1_sel                165
+       cko1_podf               166
+       cko1                    167
+       cko2_sel                168
+       cko2_podf               169
+       cko2                    170
+       srtc_gate               171
+       pata_gate               172
 
 Examples (for mx53):
 
index 969b38e06ad3157c0621e2deabfecf0157a7913e..6deb6fd1c7cd07d718c94c81c13a6ec01f641151 100644 (file)
@@ -205,6 +205,9 @@ clocks and IDs.
        enet_ref                190
        usbphy1_gate            191
        usbphy2_gate            192
+       pll4_post_div           193
+       pll5_post_div           194
+       pll5_video_div          195
 
 Examples:
 
diff --git a/Documentation/devicetree/bindings/reset/fsl,imx-src.txt b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
new file mode 100644 (file)
index 0000000..1330177
--- /dev/null
@@ -0,0 +1,49 @@
+Freescale i.MX System Reset Controller
+======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "fsl,<chip>-src"
+- reg: should be register base and length as documented in the
+  datasheet
+- interrupts: Should contain SRC interrupt and CPU WDOG interrupt,
+  in this order.
+- #reset-cells: 1, see below
+
+example:
+
+src: src@020d8000 {
+        compatible = "fsl,imx6q-src";
+        reg = <0x020d8000 0x4000>;
+        interrupts = <0 91 0x04 0 96 0x04>;
+        #reset-cells = <1>;
+};
+
+Specifying reset lines connected to IP modules
+==============================================
+
+The system reset controller can be used to reset the GPU, VPU,
+IPU, and OpenVG IP modules on i.MX5 and i.MX6 ICs. Those device
+nodes should specify the reset line on the SRC in their resets
+property, containing a phandle to the SRC device node and a
+RESET_INDEX specifying which module to reset, as described in
+reset.txt
+
+example:
+
+        ipu1: ipu@02400000 {
+                resets = <&src 2>;
+        };
+        ipu2: ipu@02800000 {
+                resets = <&src 4>;
+        };
+
+The following RESET_INDEX values are valid for i.MX5:
+GPU_RESET     0
+VPU_RESET     1
+IPU1_RESET    2
+OPEN_VG_RESET 3
+The following additional RESET_INDEX value is valid for i.MX6:
+IPU2_RESET    4
index 8071ac20d4b3ab2e924ce9367040dc13bb2310a9..b876d4925a57da507bfb0b8e302655d79a03bf6d 100644 (file)
@@ -8,6 +8,8 @@ Required properties:
 - interrupts: Should contain sync interrupt and error interrupt,
   in this order.
 - #crtc-cells: 1, See below
+- resets: phandle pointing to the system reset controller and
+          reset line index, see reset/fsl,imx-src.txt for details
 
 example:
 
@@ -16,6 +18,7 @@ ipu: ipu@18000000 {
        compatible = "fsl,imx53-ipu";
        reg = <0x18000000 0x080000000>;
        interrupts = <11 10>;
+       resets = <&src 2>;
 };
 
 Parallel display support
index 5c56fa8824e9e41c28c4b35ada36577f6a000fbe..18bef301d6e690ce08f0c33c89ebb49be54a09dc 100644 (file)
@@ -498,6 +498,7 @@ config ARCH_DOVE
        select PINCTRL_DOVE
        select PLAT_ORION_LEGACY
        select USB_ARCH_HAS_EHCI
+       select MVEBU_MBUS
        help
          Support for the Marvell Dove SoC 88AP510
 
@@ -511,6 +512,7 @@ config ARCH_KIRKWOOD
        select PINCTRL
        select PINCTRL_KIRKWOOD
        select PLAT_ORION_LEGACY
+       select MVEBU_MBUS
        help
          Support for the following Marvell Kirkwood series SoCs:
          88F6180, 88F6192 and 88F6281.
@@ -522,6 +524,7 @@ config ARCH_MV78XX0
        select GENERIC_CLOCKEVENTS
        select PCI
        select PLAT_ORION_LEGACY
+       select MVEBU_MBUS
        help
          Support for the following Marvell MV78xx0 series SoCs:
          MV781x0, MV782x0.
@@ -534,6 +537,7 @@ config ARCH_ORION5X
        select GENERIC_CLOCKEVENTS
        select PCI
        select PLAT_ORION_LEGACY
+       select MVEBU_MBUS
        help
          Support for the following Marvell Orion 5x series SoCs:
          Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
index f57a6ba26e046b448f979720ee068689cfcb7901..1d41908d5cda0644a31a9048c882369f21db235b 100644 (file)
@@ -245,11 +245,11 @@ choice
                  on i.MX53.
 
        config DEBUG_IMX6Q_UART
-               bool "i.MX6Q Debug UART"
+               bool "i.MX6Q/DL Debug UART"
                depends on SOC_IMX6Q
                help
                  Say Y here if you want kernel low-level debugging support
-                 on i.MX6Q.
+                 on i.MX6Q/DL.
 
        config DEBUG_MMP_UART2
                bool "Kernel low-level debugging message via MMP UART2"
index 758c4ea903446175c76a8ec7a01c91929d2ed0c6..9693f796bcfe1d13617933db8b78412174384e77 100644 (file)
                               clocks = <&coreclk 2>;
                };
 
-               addr-decoding@d0020000 {
-                       compatible = "marvell,armada-addr-decoding-controller";
-                       reg = <0xd0020000 0x258>;
-               };
-
                sata@d00a0000 {
                        compatible = "marvell,orion-sata";
                        reg = <0xd00a0000 0x2400>;
index 748fc347ed186088c17dfa230d7239ee656a4e61..14fb2e609babcc881deeff1c59ea8d39090ff90f 100644 (file)
                        clock-names = "cpu_1x";
                        clock-ranges;
                };
+               scutimer: scutimer@f8f00600 {
+                       interrupt-parent = <&intc>;
+                       interrupts = < 1 13 0x301 >;
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = < 0xf8f00600 0x20 >;
+                       clocks = <&cpu_clk 1>;
+               } ;
        };
 };
index 02c657af4005603bcbc940000c1b97ea14f96eff..f07a847b00c91d27504b059beb2090c13b618875 100644 (file)
@@ -109,6 +109,7 @@ CONFIG_I2C_IMX=y
 CONFIG_SPI=y
 CONFIG_SPI_IMX=y
 CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
 CONFIG_W1=y
 CONFIG_W1_MASTER_MXC=y
 CONFIG_W1_SLAVE_THERM=y
index 088d6c11a0fa1cb896cf9e2c04351d9382b98b17..6ec010f248b5b54a73cea23d06691c207e3ea468 100644 (file)
@@ -9,6 +9,7 @@ CONFIG_CGROUPS=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_MODULES=y
index 865c6d02b332f891ff612cc25bf1208547c1df80..df191afa3be14b1338481e05ae00cf35ddbb0cd5 100644 (file)
@@ -12,7 +12,7 @@
 */
 
 #define ARMADA_370_XP_REGS_PHYS_BASE   0xd0000000
-#define ARMADA_370_XP_REGS_VIRT_BASE   0xfeb00000
+#define ARMADA_370_XP_REGS_VIRT_BASE   0xfec00000
 
        .macro  addruart, rp, rv, tmp
        ldr     \rp, =ARMADA_370_XP_REGS_PHYS_BASE
index 3f0a858fb59759702b018b47b1c9a78269b28adf..4d9d2ffc45358a5ca411f7b9dba7d9f06936a191 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                          += common.o addr-map.o irq.o
+obj-y                          += common.o irq.o
 obj-$(CONFIG_DOVE_LEGACY)      += mpp.o
 obj-$(CONFIG_PCI)              += pcie.o
 obj-$(CONFIG_MACH_DOVE_DB)     += dove-db-setup.o
diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c
deleted file mode 100644 (file)
index 2a06c01..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * arch/arm/mach-dove/addr-map.c
- *
- * Address map functions for Marvell Dove 88AP510 SoC
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <asm/mach/arch.h>
-#include <asm/setup.h>
-#include <mach/dove.h>
-#include <plat/addr-map.h>
-#include "common.h"
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DDR             0x0
-#define TARGET_BOOTROM         0x1
-#define TARGET_CESA            0x3
-#define TARGET_PCIE0           0x4
-#define TARGET_PCIE1           0x8
-#define TARGET_SCRATCHPAD      0xd
-
-#define ATTR_CESA              0x01
-#define ATTR_BOOTROM           0xfd
-#define ATTR_DEV_SPI0_ROM      0xfe
-#define ATTR_DEV_SPI1_ROM      0xfb
-#define ATTR_PCIE_IO           0xe0
-#define ATTR_PCIE_MEM          0xe8
-#define ATTR_SCRATCHPAD                0x0
-
-static inline void __iomem *ddr_map_sc(int i)
-{
-       return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
-}
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct __initdata orion_addr_map_cfg addr_map_cfg = {
-       .num_wins = 8,
-       .remappable_wins = 4,
-       .bridge_virt_base = BRIDGE_VIRT_BASE,
-};
-
-static const struct __initdata orion_addr_map_info addr_map_info[] = {
-       /*
-        * Windows for PCIe IO+MEM space.
-        */
-       { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
-         TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE
-       },
-       { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
-         TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE
-       },
-       { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
-         TARGET_PCIE0, ATTR_PCIE_MEM, -1
-       },
-       { 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
-         TARGET_PCIE1, ATTR_PCIE_MEM, -1
-       },
-       /*
-        * Window for CESA engine.
-        */
-       { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
-         TARGET_CESA, ATTR_CESA, -1
-       },
-       /*
-        * Window to the BootROM for Standby and Sleep Resume
-        */
-       { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
-         TARGET_BOOTROM, ATTR_BOOTROM, -1
-       },
-       /*
-        * Window to the PMU Scratch Pad space
-        */
-       { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
-         TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1
-       },
-       /* End marker */
-       { -1, 0, 0, 0, 0, 0 }
-};
-
-void __init dove_setup_cpu_mbus(void)
-{
-       int i;
-       int cs;
-
-       /*
-        * Disable, clear and configure windows.
-        */
-       orion_config_wins(&addr_map_cfg, addr_map_info);
-
-       /*
-        * Setup MBUS dram target info.
-        */
-       orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
-
-       for (i = 0, cs = 0; i < 2; i++) {
-               u32 map = readl(ddr_map_sc(i));
-
-               /*
-                * Chip select enabled?
-                */
-               if (map & 1) {
-                       struct mbus_dram_window *w;
-
-                       w = &orion_mbus_dram_info.cs[cs++];
-                       w->cs_index = i;
-                       w->mbus_attr = 0; /* CS address decoding done inside */
-                                         /* the DDR controller, no need to  */
-                                         /* provide attributes */
-                       w->base = map & 0xff800000;
-                       w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
-               }
-       }
-       orion_mbus_dram_info.num_cs = cs;
-}
index fbde1dd671136c63e6c0807f797173d8ac51012d..0b142803b2e17301d837659ca1f4eae085f36015 100644 (file)
@@ -64,7 +64,7 @@ static void __init dove_dt_init(void)
 #ifdef CONFIG_CACHE_TAUROS2
        tauros2_init(0);
 #endif
-       dove_setup_cpu_mbus();
+       dove_setup_cpu_wins();
 
        /* Setup root of clk tree */
        dove_of_clk_init();
index c6b3b2bb50e76984e6f1ea5195e8c4b8f707332e..e2b5da031f964c013478eb735a988bcb9ff12d0d 100644 (file)
@@ -224,6 +224,9 @@ void __init dove_i2c_init(void)
 void __init dove_init_early(void)
 {
        orion_time_set_base(TIMER_VIRT_BASE);
+       mvebu_mbus_init("marvell,dove-mbus",
+                       BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
+                       DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ);
 }
 
 static int __init dove_find_tclk(void)
@@ -326,6 +329,40 @@ void __init dove_sdio1_init(void)
        platform_device_register(&dove_sdio1);
 }
 
+void __init dove_setup_cpu_wins(void)
+{
+       /*
+        * The PCIe windows will no longer be statically allocated
+        * here once Dove is migrated to the pci-mvebu driver.
+        */
+       mvebu_mbus_add_window_remap_flags("pcie0.0",
+                                         DOVE_PCIE0_IO_PHYS_BASE,
+                                         DOVE_PCIE0_IO_SIZE,
+                                         DOVE_PCIE0_IO_BUS_BASE,
+                                         MVEBU_MBUS_PCI_IO);
+       mvebu_mbus_add_window_remap_flags("pcie1.0",
+                                         DOVE_PCIE1_IO_PHYS_BASE,
+                                         DOVE_PCIE1_IO_SIZE,
+                                         DOVE_PCIE1_IO_BUS_BASE,
+                                         MVEBU_MBUS_PCI_IO);
+       mvebu_mbus_add_window_remap_flags("pcie0.0",
+                                         DOVE_PCIE0_MEM_PHYS_BASE,
+                                         DOVE_PCIE0_MEM_SIZE,
+                                         MVEBU_MBUS_NO_REMAP,
+                                         MVEBU_MBUS_PCI_MEM);
+       mvebu_mbus_add_window_remap_flags("pcie1.0",
+                                         DOVE_PCIE1_MEM_PHYS_BASE,
+                                         DOVE_PCIE1_MEM_SIZE,
+                                         MVEBU_MBUS_NO_REMAP,
+                                         MVEBU_MBUS_PCI_MEM);
+       mvebu_mbus_add_window("cesa", DOVE_CESA_PHYS_BASE,
+                             DOVE_CESA_SIZE);
+       mvebu_mbus_add_window("bootrom", DOVE_BOOTROM_PHYS_BASE,
+                             DOVE_BOOTROM_SIZE);
+       mvebu_mbus_add_window("scratchpad", DOVE_SCRATCHPAD_PHYS_BASE,
+                             DOVE_SCRATCHPAD_SIZE);
+}
+
 void __init dove_init(void)
 {
        pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
@@ -334,7 +371,7 @@ void __init dove_init(void)
 #ifdef CONFIG_CACHE_TAUROS2
        tauros2_init(0);
 #endif
-       dove_setup_cpu_mbus();
+       dove_setup_cpu_wins();
 
        /* Setup root of clk tree */
        dove_clk_init();
index ee59fba4c6d1b2950cfec98879528b034710b726..e86347928b677d364a908bfba4f1e6927cc4cfa2 100644 (file)
@@ -23,7 +23,7 @@ void dove_map_io(void);
 void dove_init(void);
 void dove_init_early(void);
 void dove_init_irq(void);
-void dove_setup_cpu_mbus(void);
+void dove_setup_cpu_wins(void);
 void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
 void dove_sata_init(struct mv_sata_platform_data *sata_data);
 #ifdef CONFIG_PCI
index 661725e3115a5d37433aabb93cbf0be37a5049a8..0c4b35f4ee5baeedc349daa4ec6ce2009dd45762 100644 (file)
@@ -77,6 +77,8 @@
 /* North-South Bridge */
 #define BRIDGE_VIRT_BASE       (DOVE_SB_REGS_VIRT_BASE + 0x20000)
 #define BRIDGE_PHYS_BASE       (DOVE_SB_REGS_PHYS_BASE + 0x20000)
+#define  BRIDGE_WINS_BASE       (BRIDGE_PHYS_BASE)
+#define  BRIDGE_WINS_SZ         (0x80)
 
 /* Cryptographic Engine */
 #define DOVE_CRYPT_PHYS_BASE   (DOVE_SB_REGS_PHYS_BASE + 0x30000)
 #define  DOVE_SSP_CLOCK_ENABLE         (1 << 1)
 #define  DOVE_SSP_BPB_CLOCK_SRC_SSP    (1 << 11)
 /* Memory Controller */
+#define DOVE_MC_PHYS_BASE       (DOVE_NB_REGS_PHYS_BASE + 0x00000)
+#define  DOVE_MC_WINS_BASE      (DOVE_MC_PHYS_BASE + 0x100)
+#define  DOVE_MC_WINS_SZ        (0x8)
 #define DOVE_MC_VIRT_BASE      (DOVE_NB_REGS_VIRT_BASE + 0x00000)
 
 /* LCD Controller */
index 2ebc97e16b911da6c33df4e78b80d02b6a7cc036..78f795d73cb64eeae161bda1ea5917aa3bf8fe3d 100644 (file)
@@ -65,6 +65,9 @@ config IRAM_ALLOC
        bool
        select GENERIC_ALLOCATOR
 
+config HAVE_IMX_ANATOP
+       bool
+
 config HAVE_IMX_GPC
        bool
 
@@ -73,6 +76,7 @@ config HAVE_IMX_MMDC
 
 config HAVE_IMX_SRC
        def_bool y if SMP
+       select ARCH_HAS_RESET_CONTROLLER
 
 config IMX_HAVE_IOMUX_V1
        bool
@@ -115,6 +119,8 @@ config SOC_IMX25
 
 config SOC_IMX27
        bool
+       select ARCH_HAS_CPUFREQ
+       select ARCH_HAS_OPP
        select COMMON_CLK
        select CPU_ARM926T
        select IMX_HAVE_IOMUX_V1
@@ -142,6 +148,7 @@ config SOC_IMX35
 config SOC_IMX5
        bool
        select ARCH_HAS_CPUFREQ
+       select ARCH_HAS_OPP
        select ARCH_MXC_IOMUX_V3
        select COMMON_CLK
        select CPU_V7
@@ -783,7 +790,7 @@ config      SOC_IMX53
          This enables support for Freescale i.MX53 processor.
 
 config SOC_IMX6Q
-       bool "i.MX6 Quad support"
+       bool "i.MX6 Quad/DualLite support"
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
        select ARM_CPU_SUSPEND if PM
@@ -796,6 +803,7 @@ config SOC_IMX6Q
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if LOCAL_TIMERS
        select HAVE_CAN_FLEXCAN if CAN
+       select HAVE_IMX_ANATOP
        select HAVE_IMX_GPC
        select HAVE_IMX_MMDC
        select HAVE_IMX_SRC
index fbe60a14534492310f26ee5f3af2871f2f64a1d5..930958973f81f14fce5ca270bcb3667b5f660ffa 100644 (file)
@@ -91,6 +91,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o
 obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
 obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
 
+obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
 obj-$(CONFIG_HAVE_IMX_SRC) += src.o
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
new file mode 100644 (file)
index 0000000..0cfa07d
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include "common.h"
+
+#define REG_SET                0x4
+#define REG_CLR                0x8
+
+#define ANADIG_REG_2P5         0x130
+#define ANADIG_REG_CORE                0x140
+#define ANADIG_ANA_MISC0       0x150
+#define ANADIG_USB1_CHRG_DETECT        0x1b0
+#define ANADIG_USB2_CHRG_DETECT        0x210
+#define ANADIG_DIGPROG         0x260
+
+#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG   0x40000
+#define BM_ANADIG_REG_CORE_FET_ODRIVE          0x20000000
+#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG   0x1000
+#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B   0x80000
+#define BM_ANADIG_USB_CHRG_DETECT_EN_B         0x100000
+
+static struct regmap *anatop;
+
+static void imx_anatop_enable_weak2p5(bool enable)
+{
+       u32 reg, val;
+
+       regmap_read(anatop, ANADIG_ANA_MISC0, &val);
+
+       /* can only be enabled when stop_mode_config is clear. */
+       reg = ANADIG_REG_2P5;
+       reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
+               REG_SET : REG_CLR;
+       regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
+}
+
+static void imx_anatop_enable_fet_odrive(bool enable)
+{
+       regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR),
+               BM_ANADIG_REG_CORE_FET_ODRIVE);
+}
+
+void imx_anatop_pre_suspend(void)
+{
+       imx_anatop_enable_weak2p5(true);
+       imx_anatop_enable_fet_odrive(true);
+}
+
+void imx_anatop_post_resume(void)
+{
+       imx_anatop_enable_fet_odrive(false);
+       imx_anatop_enable_weak2p5(false);
+}
+
+void imx_anatop_usb_chrg_detect_disable(void)
+{
+       regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
+               BM_ANADIG_USB_CHRG_DETECT_EN_B
+               | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+       regmap_write(anatop, ANADIG_USB2_CHRG_DETECT,
+               BM_ANADIG_USB_CHRG_DETECT_EN_B |
+               BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+}
+
+u32 imx_anatop_get_digprog(void)
+{
+       struct device_node *np;
+       void __iomem *anatop_base;
+       static u32 digprog;
+
+       if (digprog)
+               return digprog;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
+       anatop_base = of_iomap(np, 0);
+       WARN_ON(!anatop_base);
+       digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG);
+
+       return digprog;
+}
+
+void __init imx_anatop_init(void)
+{
+       anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
+       if (IS_ERR(anatop)) {
+               pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
+               return;
+       }
+}
index 2bc623b414c1c322957d07114b2e2819d25dda4b..6fc486b6a3c68f7a5bd6a5457680cd895f41dc76 100644 (file)
@@ -45,16 +45,40 @@ static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "
 static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
 static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
 static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
-static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", };
+static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", };
 static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
+static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
+static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" };
 static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
 static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", };
+static const char *mx53_cko1_sel[] = {
+       "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw",
+       "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy",
+       "di_pred", "dummy", "dummy", "ahb",
+       "ipg", "per_root", "ckil", "dummy",};
+static const char *mx53_cko2_sel[] = {
+       "dummy"/* dptc_core */, "dummy"/* dptc_perich */,
+       "dummy", "esdhc_a_podf",
+       "usboh3_podf", "dummy"/* wrck_clk_root */,
+       "ecspi_podf", "dummy"/* pll1_ref_clk */,
+       "esdhc_b_podf", "dummy"/* ddr_clk_root */,
+       "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */,
+       "vpu_sel", "ipu_sel",
+       "osc", "ckih1",
+       "dummy", "esdhc_c_sel",
+       "ssi1_root_podf", "ssi2_root_podf",
+       "dummy", "dummy",
+       "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */,
+       "dummy"/* tve_out */, "usb_phy_sel",
+       "tve_sel", "lp_apm",
+       "uart_root", "dummy"/* spdif0_clk_root */,
+       "dummy", "dummy", };
 
 enum imx5_clks {
        dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
        uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s,
        emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred,
-       usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di,
+       usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused,
        tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate,
        uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate,
        gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate,
@@ -83,7 +107,10 @@ enum imx5_clks {
        ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
        epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate,
        can_sel, can1_serial_gate, can1_ipg_gate,
-       owire_gate,
+       owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate,
+       cko1_sel, cko1_podf, cko1,
+       cko2_sel, cko2_podf, cko2,
+       srtc_gate, pata_gate,
        clk_max
 };
 
@@ -160,8 +187,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
                                usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
        clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
        clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
-       clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */
-       clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel));
        clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
        clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
        clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
@@ -200,6 +225,11 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
        clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
        clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
        clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
+       clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel));
+       clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel));
+       clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2);
+       clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4);
+       clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14);
        clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
        clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
        clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
@@ -235,6 +265,8 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
        clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6);
        clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8);
        clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
+       clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
+       clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
 
        for (i = 0; i < ARRAY_SIZE(clk); i++)
                if (IS_ERR(clk[i]))
@@ -286,7 +318,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
        clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
        clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
        clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
-       clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0");
        clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
        clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
        clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0");
@@ -331,8 +362,10 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
                                mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
        clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
                                mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
-       clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
-                               mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
+       clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+                               mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT);
+       clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
+                               mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel));
        clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
        clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
        clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
@@ -420,23 +453,23 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
        clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
 
-       clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
-                               mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
        clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
-       clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1);
+       clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0);
+       clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
+                               mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT);
        clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
-       clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
-                               mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
        clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
-       clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1);
+       clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0);
+       clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
+                               mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT);
        clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
        clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
        clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
                                mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
        clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
                                mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
-       clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
-                               mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
+       clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+                               mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT);
        clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
        clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
        clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
@@ -453,6 +486,16 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
        clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
 
+       clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
+                               mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
+       clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3);
+       clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7);
+
+       clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5,
+                               mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
+       clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
+       clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
+
        for (i = 0; i < ARRAY_SIZE(clk); i++)
                if (IS_ERR(clk[i]))
                        pr_err("i.MX53 clk %d: register failed with %ld\n",
index d38e54f5b6d7f1dbbbd245a91db8be9a2408b28f..151259003086e8d1f0db34015742ab307b3f986a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2013 Freescale Semiconductor, Inc.
  * Copyright 2011 Linaro Ltd.
  *
  * The code contained herein is licensed under the GNU General Public
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
 
 #include "clk.h"
 #include "common.h"
+#include "hardware.h"
+
+#define CCR                            0x0
+#define BM_CCR_WB_COUNT                        (0x7 << 16)
+#define BM_CCR_RBC_BYPASS_COUNT                (0x3f << 21)
+#define BM_CCR_RBC_EN                  (0x1 << 27)
 
 #define CCGR0                          0x68
 #define CCGR1                          0x6c
@@ -67,6 +74,67 @@ void imx6q_set_chicken_bit(void)
        writel_relaxed(val, ccm_base + CGPR);
 }
 
+static void imx6q_enable_rbc(bool enable)
+{
+       u32 val;
+       static bool last_rbc_mode;
+
+       if (last_rbc_mode == enable)
+               return;
+       /*
+        * need to mask all interrupts in GPC before
+        * operating RBC configurations
+        */
+       imx_gpc_mask_all();
+
+       /* configure RBC enable bit */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_RBC_EN;
+       val |= enable ? BM_CCR_RBC_EN : 0;
+       writel_relaxed(val, ccm_base + CCR);
+
+       /* configure RBC count */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_RBC_BYPASS_COUNT;
+       val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
+       writel(val, ccm_base + CCR);
+
+       /*
+        * need to delay at least 2 cycles of CKIL(32K)
+        * due to hardware design requirement, which is
+        * ~61us, here we use 65us for safe
+        */
+       udelay(65);
+
+       /* restore GPC interrupt mask settings */
+       imx_gpc_restore_all();
+
+       last_rbc_mode = enable;
+}
+
+static void imx6q_enable_wb(bool enable)
+{
+       u32 val;
+       static bool last_wb_mode;
+
+       if (last_wb_mode == enable)
+               return;
+
+       /* configure well bias enable bit */
+       val = readl_relaxed(ccm_base + CLPCR);
+       val &= ~BM_CLPCR_WB_PER_AT_LPM;
+       val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
+       writel_relaxed(val, ccm_base + CLPCR);
+
+       /* configure well bias count */
+       val = readl_relaxed(ccm_base + CCR);
+       val &= ~BM_CCR_WB_COUNT;
+       val |= enable ? BM_CCR_WB_COUNT : 0;
+       writel_relaxed(val, ccm_base + CCR);
+
+       last_wb_mode = enable;
+}
+
 int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
 {
        u32 val = readl_relaxed(ccm_base + CLPCR);
@@ -74,6 +142,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
        val &= ~BM_CLPCR_LPM;
        switch (mode) {
        case WAIT_CLOCKED:
+               imx6q_enable_wb(false);
+               imx6q_enable_rbc(false);
                break;
        case WAIT_UNCLOCKED:
                val |= 0x1 << BP_CLPCR_LPM;
@@ -92,6 +162,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
                val |= 0x3 << BP_CLPCR_STBY_COUNT;
                val |= BM_CLPCR_VSTBY;
                val |= BM_CLPCR_SBYOS;
+               imx6q_enable_wb(true);
+               imx6q_enable_rbc(true);
                break;
        default:
                return -EINVAL;
@@ -109,29 +181,29 @@ static const char *periph_clk2_sels[]     = { "pll3_usb_otg", "osc", };
 static const char *periph_sels[]       = { "periph_pre", "periph_clk2", };
 static const char *periph2_sels[]      = { "periph2_pre", "periph2_clk2", };
 static const char *axi_sels[]          = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
-static const char *audio_sels[]        = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
+static const char *audio_sels[]        = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
 static const char *gpu_axi_sels[]      = { "axi", "ahb", };
 static const char *gpu2d_core_sels[]   = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
 static const char *gpu3d_core_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
 static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
 static const char *ipu_sels[]          = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
 static const char *ldb_di_sels[]       = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
-static const char *ipu_di_pre_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *ipu_di_pre_sels[]   = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
 static const char *ipu1_di0_sels[]     = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *ipu1_di1_sels[]     = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *ipu2_di0_sels[]     = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *ipu2_di1_sels[]     = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
 static const char *hsi_tx_sels[]       = { "pll3_120m", "pll2_pfd2_396m", };
 static const char *pcie_axi_sels[]     = { "axi", "ahb", };
-static const char *ssi_sels[]          = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", };
+static const char *ssi_sels[]          = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", };
 static const char *usdhc_sels[]        = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
 static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
 static const char *emi_sels[]          = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
 static const char *vdo_axi_sels[]      = { "axi", "ahb", };
 static const char *vpu_axi_sels[]      = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
-static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video",
+static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
                                    "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
-                                   "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", };
+                                   "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", };
 
 enum mx6q_clks {
        dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
@@ -165,7 +237,7 @@ enum mx6q_clks {
        pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
        ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
        sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
-       usbphy2_gate, clk_max
+       usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -182,6 +254,21 @@ static struct clk_div_table clk_enet_ref_table[] = {
        { .val = 3, .div = 4, },
 };
 
+static struct clk_div_table post_div_table[] = {
+       { .val = 2, .div = 1, },
+       { .val = 1, .div = 2, },
+       { .val = 0, .div = 4, },
+       { }
+};
+
+static struct clk_div_table video_div_table[] = {
+       { .val = 0, .div = 1, },
+       { .val = 1, .div = 2, },
+       { .val = 2, .div = 1, },
+       { .val = 3, .div = 4, },
+       { }
+};
+
 int __init mx6q_clocks_init(void)
 {
        struct device_node *np;
@@ -208,6 +295,14 @@ int __init mx6q_clocks_init(void)
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
+       /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
+       if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) {
+               post_div_table[1].div = 1;
+               post_div_table[2].div = 1;
+               video_div_table[1].div = 1;
+               video_div_table[2].div = 1;
+       };
+
        /*                   type                               name         parent_name  base     div_mask */
        clk[pll1_sys]      = imx_clk_pllv3(IMX_PLLV3_SYS,       "pll1_sys",     "osc", base,        0x7f);
        clk[pll2_bus]      = imx_clk_pllv3(IMX_PLLV3_GENERIC,   "pll2_bus",     "osc", base + 0x30, 0x1);
@@ -260,6 +355,10 @@ int __init mx6q_clocks_init(void)
        clk[pll3_60m]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8);
        clk[twd]       = imx_clk_fixed_factor("twd",       "arm",            1, 2);
 
+       clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
+       clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
+       clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
+
        np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
        base = of_iomap(np, 0);
        WARN_ON(!base);
@@ -283,8 +382,8 @@ int __init mx6q_clocks_init(void)
        clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8,  2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
        clk[ipu1_sel]         = imx_clk_mux("ipu1_sel",         base + 0x3c, 9,  2, ipu_sels,          ARRAY_SIZE(ipu_sels));
        clk[ipu2_sel]         = imx_clk_mux("ipu2_sel",         base + 0x3c, 14, 2, ipu_sels,          ARRAY_SIZE(ipu_sels));
-       clk[ldb_di0_sel]      = imx_clk_mux("ldb_di0_sel",      base + 0x2c, 9,  3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
-       clk[ldb_di1_sel]      = imx_clk_mux("ldb_di1_sel",      base + 0x2c, 12, 3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
+       clk[ldb_di0_sel]      = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9,  3, ldb_di_sels,      ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
+       clk[ldb_di1_sel]      = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels,      ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
        clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
        clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
        clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
@@ -332,9 +431,9 @@ int __init mx6q_clocks_init(void)
        clk[ipu1_podf]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          base + 0x3c, 11, 3);
        clk[ipu2_podf]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          base + 0x3c, 16, 3);
        clk[ldb_di0_div_3_5]  = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
-       clk[ldb_di0_podf]     = imx_clk_divider("ldb_di0_podf",     "ldb_di0_div_3_5",       base + 0x20, 10, 1);
+       clk[ldb_di0_podf]     = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
        clk[ldb_di1_div_3_5]  = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
-       clk[ldb_di1_podf]     = imx_clk_divider("ldb_di1_podf",     "ldb_di1_div_3_5",   base + 0x20, 11, 1);
+       clk[ldb_di1_podf]     = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
        clk[ipu1_di0_pre]     = imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  base + 0x34, 3,  3);
        clk[ipu1_di1_pre]     = imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  base + 0x34, 12, 3);
        clk[ipu2_di0_pre]     = imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  base + 0x38, 3,  3);
@@ -448,6 +547,11 @@ int __init mx6q_clocks_init(void)
        clk_register_clkdev(clk[cko1], "cko1", NULL);
        clk_register_clkdev(clk[arm], NULL, "cpu0");
 
+       if (imx6q_revision() != IMX_CHIP_REVISION_1_0) {
+               clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
+               clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
+       }
+
        /*
         * The gpmi needs 100MHz frequency in the EDO/Sync mode,
         * We can not get the 100MHz from the pll2_pfd0_352m.
index 9d1f3b99d1d3630a6f4b339a5cf2d52817dd1be3..d9d9d9c66dffd2538d0b58cf34021212969836f1 100644 (file)
@@ -59,6 +59,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent,
                        reg, shift, width, 0, &imx_ccm_lock);
 }
 
+static inline struct clk *imx_clk_divider_flags(const char *name,
+               const char *parent, void __iomem *reg, u8 shift, u8 width,
+               unsigned long flags)
+{
+       return clk_register_divider(NULL, name, parent, flags,
+                       reg, shift, width, 0, &imx_ccm_lock);
+}
+
 static inline struct clk *imx_clk_gate(const char *name, const char *parent,
                void __iomem *reg, u8 shift)
 {
@@ -73,6 +81,15 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
                        width, 0, &imx_ccm_lock);
 }
 
+static inline struct clk *imx_clk_mux_flags(const char *name,
+               void __iomem *reg, u8 shift, u8 width, const char **parents,
+               int num_parents, unsigned long flags)
+{
+       return clk_register_mux(NULL, name, parents, num_parents,
+                       flags, reg, shift, width, 0,
+                       &imx_ccm_lock);
+}
+
 static inline struct clk *imx_clk_fixed_factor(const char *name,
                const char *parent, unsigned int mult, unsigned int div)
 {
index 9fea2522d7a3921f60f43fa0aae71ee2c3225c3d..4cba7dbb079fce445fca9afbd8d9f18ce11b56ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -74,6 +74,7 @@ extern void mxc_set_cpu_type(unsigned int type);
 extern void mxc_restart(char, const char *);
 extern void mxc_arch_reset_init(void __iomem *);
 extern int mx53_revision(void);
+extern int imx6q_revision(void);
 extern int mx53_display_revision(void);
 extern void imx_set_aips(void __iomem *);
 extern int mxc_device_init(void);
@@ -128,6 +129,13 @@ extern void imx_src_prepare_restart(void);
 extern void imx_gpc_init(void);
 extern void imx_gpc_pre_suspend(void);
 extern void imx_gpc_post_resume(void);
+extern void imx_gpc_mask_all(void);
+extern void imx_gpc_restore_all(void);
+extern void imx_anatop_init(void);
+extern void imx_anatop_pre_suspend(void);
+extern void imx_anatop_post_resume(void);
+extern void imx_anatop_usb_chrg_detect_disable(void);
+extern u32 imx_anatop_get_digprog(void);
 extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
 extern void imx6q_set_chicken_bit(void);
 
index 02b61cdf39b97bbf5c7aee5f92b74a8c3fb86684..44a65e9ff1fc9366bb62c35242c4f6dcc188a0d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2013 Freescale Semiconductor, Inc.
  * Copyright 2011 Linaro Ltd.
  *
  * The code contained herein is licensed under the GNU General Public
@@ -69,6 +69,27 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
        return 0;
 }
 
+void imx_gpc_mask_all(void)
+{
+       void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+       int i;
+
+       for (i = 0; i < IMR_NUM; i++) {
+               gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
+               writel_relaxed(~0, reg_imr1 + i * 4);
+       }
+
+}
+
+void imx_gpc_restore_all(void)
+{
+       void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
+       int i;
+
+       for (i = 0; i < IMR_NUM; i++)
+               writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
+}
+
 static void imx_gpc_irq_unmask(struct irq_data *d)
 {
        void __iomem *reg;
index 99502eeefdf7ed46c13b1ccc8c7d140ce33b145c..5536fd81379a87dc2d7856a9b46338578aa52cbd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2013 Freescale Semiconductor, Inc.
  * Copyright 2011 Linaro Ltd.
  *
  * The code contained herein is licensed under the GNU General Public
 #include "cpuidle.h"
 #include "hardware.h"
 
-#define IMX6Q_ANALOG_DIGPROG   0x260
+static u32 chip_revision;
 
-static int imx6q_revision(void)
+int imx6q_revision(void)
 {
-       struct device_node *np;
-       void __iomem *base;
-       static u32 rev;
-
-       if (!rev) {
-               np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
-               if (!np)
-                       return IMX_CHIP_REVISION_UNKNOWN;
-               base = of_iomap(np, 0);
-               if (!base) {
-                       of_node_put(np);
-                       return IMX_CHIP_REVISION_UNKNOWN;
-               }
-               rev =  readl_relaxed(base + IMX6Q_ANALOG_DIGPROG);
-               iounmap(base);
-               of_node_put(np);
-       }
+       return chip_revision;
+}
+
+static void __init imx6q_init_revision(void)
+{
+       u32 rev = imx_anatop_get_digprog();
 
        switch (rev & 0xff) {
        case 0:
-               return IMX_CHIP_REVISION_1_0;
+               chip_revision = IMX_CHIP_REVISION_1_0;
+               break;
        case 1:
-               return IMX_CHIP_REVISION_1_1;
+               chip_revision = IMX_CHIP_REVISION_1_1;
+               break;
        case 2:
-               return IMX_CHIP_REVISION_1_2;
+               chip_revision = IMX_CHIP_REVISION_1_2;
+               break;
        default:
-               return IMX_CHIP_REVISION_UNKNOWN;
+               chip_revision = IMX_CHIP_REVISION_UNKNOWN;
        }
+
+       mxc_set_cpu_type(rev >> 16 & 0xff);
 }
 
 static void imx6q_restart(char mode, const char *cmd)
@@ -164,29 +158,7 @@ static void __init imx6q_1588_init(void)
 }
 static void __init imx6q_usb_init(void)
 {
-       struct regmap *anatop;
-
-#define HW_ANADIG_USB1_CHRG_DETECT             0x000001b0
-#define HW_ANADIG_USB2_CHRG_DETECT             0x00000210
-
-#define BM_ANADIG_USB_CHRG_DETECT_EN_B         0x00100000
-#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B   0x00080000
-
-       anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
-       if (!IS_ERR(anatop)) {
-               /*
-                * The external charger detector needs to be disabled,
-                * or the signal at DP will be poor
-                */
-               regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT,
-                               BM_ANADIG_USB_CHRG_DETECT_EN_B
-                               | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
-               regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT,
-                               BM_ANADIG_USB_CHRG_DETECT_EN_B |
-                               BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
-       } else {
-               pr_warn("failed to find fsl,imx6q-anatop regmap\n");
-       }
+       imx_anatop_usb_chrg_detect_disable();
 }
 
 static void __init imx6q_init_machine(void)
@@ -196,6 +168,7 @@ static void __init imx6q_init_machine(void)
 
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
+       imx_anatop_init();
        imx6q_pm_init();
        imx6q_usb_init();
        imx6q_1588_init();
@@ -282,6 +255,7 @@ static void __init imx6q_map_io(void)
 
 static void __init imx6q_init_irq(void)
 {
+       imx6q_init_revision();
        l2x0_of_init(0, ~0UL);
        imx_src_init();
        imx_gpc_init();
@@ -292,15 +266,17 @@ static void __init imx6q_timer_init(void)
 {
        mx6q_clocks_init();
        clocksource_of_init();
-       imx_print_silicon_rev("i.MX6Q", imx6q_revision());
+       imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
+                             imx6q_revision());
 }
 
 static const char *imx6q_dt_compat[] __initdata = {
+       "fsl,imx6dl",
        "fsl,imx6q",
        NULL,
 };
 
-DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
+DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
        .smp            = smp_ops(imx_smp_ops),
        .map_io         = imx6q_map_io,
        .init_irq       = imx6q_init_irq,
index 7a146671e65a8768572840b138da9a3987f8cb49..3c609c52d3eb984f2d71cf43fc933c8b5e777056 100644 (file)
@@ -51,6 +51,8 @@ void __init mx1_init_irq(void)
 
 void __init imx1_soc_init(void)
 {
+       mxc_device_init();
+
        mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
                                                MX1_GPIO_INT_PORTA, 0);
        mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
index 7dce17a9fe6c154e58fd6e119694523b116df6f6..8629e5be7ecd19f665a13a10a554d4b3bedab00f 100644 (file)
@@ -34,6 +34,8 @@
 #define MXC_CPU_MX35           35
 #define MXC_CPU_MX51           51
 #define MXC_CPU_MX53           53
+#define MXC_CPU_IMX6DL         0x61
+#define MXC_CPU_IMX6Q          0x63
 
 #define IMX_CHIP_REVISION_1_0          0x10
 #define IMX_CHIP_REVISION_1_1          0x11
@@ -150,6 +152,15 @@ extern unsigned int __mxc_cpu_type;
 #endif
 
 #ifndef __ASSEMBLY__
+static inline bool cpu_is_imx6dl(void)
+{
+       return __mxc_cpu_type == MXC_CPU_IMX6DL;
+}
+
+static inline bool cpu_is_imx6q(void)
+{
+       return __mxc_cpu_type == MXC_CPU_IMX6Q;
+}
 
 struct cpu_op {
        u32 cpu_rate;
index 77e9a25ed0f69a0e528f7484c9e3f17dab2fb825..4a69305db65e395366187a84cde322e37fc99e94 100644 (file)
@@ -68,8 +68,8 @@ static void __init imx_smp_init_cpus(void)
 
        ncores = scu_get_core_count(scu_base);
 
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
+       for (i = ncores; i < NR_CPUS; i++)
+               set_cpu_possible(i, false);
 }
 
 void imx_smp_prepare(void)
index 5faba7a3c95f6e74393699045aa0635331459d46..204942749e2199bbe4ff1632e974e17d4612d37b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011-2013 Freescale Semiconductor, Inc.
  * Copyright 2011 Linaro Ltd.
  *
  * The code contained herein is licensed under the GNU General Public
@@ -34,10 +34,12 @@ static int imx6q_pm_enter(suspend_state_t state)
        case PM_SUSPEND_MEM:
                imx6q_set_lpm(STOP_POWER_OFF);
                imx_gpc_pre_suspend();
+               imx_anatop_pre_suspend();
                imx_set_cpu_jump(0, v7_cpu_resume);
                /* Zzz ... */
                cpu_suspend(0, imx6q_suspend_finish);
                imx_smp_prepare();
+               imx_anatop_post_resume();
                imx_gpc_post_resume();
                imx6q_set_lpm(WAIT_CLOCKED);
                break;
index 97d086889481a0091fba58effed7f7fe478c90ea..10a6b1a8c5acee611c2ae0c74766866b70cffd67 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/reset-controller.h>
 #include <linux/smp.h>
 #include <asm/smp_plat.h>
 #include "common.h"
 #define SRC_SCR                                0x000
 #define SRC_GPR1                       0x020
 #define BP_SRC_SCR_WARM_RESET_ENABLE   0
+#define BP_SRC_SCR_SW_GPU_RST          1
+#define BP_SRC_SCR_SW_VPU_RST          2
+#define BP_SRC_SCR_SW_IPU1_RST         3
+#define BP_SRC_SCR_SW_OPEN_VG_RST      4
+#define BP_SRC_SCR_SW_IPU2_RST         12
 #define BP_SRC_SCR_CORE1_RST           14
 #define BP_SRC_SCR_CORE1_ENABLE                22
 
 static void __iomem *src_base;
+static DEFINE_SPINLOCK(scr_lock);
+
+static const int sw_reset_bits[5] = {
+       BP_SRC_SCR_SW_GPU_RST,
+       BP_SRC_SCR_SW_VPU_RST,
+       BP_SRC_SCR_SW_IPU1_RST,
+       BP_SRC_SCR_SW_OPEN_VG_RST,
+       BP_SRC_SCR_SW_IPU2_RST
+};
+
+static int imx_src_reset_module(struct reset_controller_dev *rcdev,
+               unsigned long sw_reset_idx)
+{
+       unsigned long timeout;
+       unsigned long flags;
+       int bit;
+       u32 val;
+
+       if (!src_base)
+               return -ENODEV;
+
+       if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
+               return -EINVAL;
+
+       bit = 1 << sw_reset_bits[sw_reset_idx];
+
+       spin_lock_irqsave(&scr_lock, flags);
+       val = readl_relaxed(src_base + SRC_SCR);
+       val |= bit;
+       writel_relaxed(val, src_base + SRC_SCR);
+       spin_unlock_irqrestore(&scr_lock, flags);
+
+       timeout = jiffies + msecs_to_jiffies(1000);
+       while (readl(src_base + SRC_SCR) & bit) {
+               if (time_after(jiffies, timeout))
+                       return -ETIME;
+               cpu_relax();
+       }
+
+       return 0;
+}
+
+static struct reset_control_ops imx_src_ops = {
+       .reset = imx_src_reset_module,
+};
+
+static struct reset_controller_dev imx_reset_controller = {
+       .ops = &imx_src_ops,
+       .nr_resets = ARRAY_SIZE(sw_reset_bits),
+};
 
 void imx_enable_cpu(int cpu, bool enable)
 {
@@ -32,9 +88,11 @@ void imx_enable_cpu(int cpu, bool enable)
 
        cpu = cpu_logical_map(cpu);
        mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
+       spin_lock(&scr_lock);
        val = readl_relaxed(src_base + SRC_SCR);
        val = enable ? val | mask : val & ~mask;
        writel_relaxed(val, src_base + SRC_SCR);
+       spin_unlock(&scr_lock);
 }
 
 void imx_set_cpu_jump(int cpu, void *jump_addr)
@@ -61,9 +119,11 @@ void imx_src_prepare_restart(void)
        u32 val;
 
        /* clear enable bits of secondary cores */
+       spin_lock(&scr_lock);
        val = readl_relaxed(src_base + SRC_SCR);
        val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
        writel_relaxed(val, src_base + SRC_SCR);
+       spin_unlock(&scr_lock);
 
        /* clear persistent entry register of primary core */
        writel_relaxed(0, src_base + SRC_GPR1);
@@ -80,11 +140,17 @@ void __init imx_src_init(void)
        src_base = of_iomap(np, 0);
        WARN_ON(!src_base);
 
+       imx_reset_controller.of_node = np;
+       if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
+               reset_controller_register(&imx_reset_controller);
+
        /*
         * force warm reset sources to generate cold reset
         * for a more reliable restart
         */
+       spin_lock(&scr_lock);
        val = readl_relaxed(src_base + SRC_SCR);
        val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
        writel_relaxed(val, src_base + SRC_SCR);
+       spin_unlock(&scr_lock);
 }
index cdbca328a412b2490a1eafd47f901d8bcf0ca9f2..e1f3735d34154aaa90da215fdab1359070f8ab64 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                          += common.o addr-map.o irq.o pcie.o mpp.o
+obj-y                          += common.o irq.o pcie.o mpp.o
 
 obj-$(CONFIG_MACH_D2NET_V2)            += d2net_v2-setup.o lacie_v2-common.o
 obj-$(CONFIG_MACH_DB88F6281_BP)                += db88f6281-bp-setup.o
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
deleted file mode 100644 (file)
index 8f0d162..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/addr-map.c
- *
- * Address map functions for Marvell Kirkwood SoCs
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <plat/addr-map.h>
-#include "common.h"
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DEV_BUS         1
-#define TARGET_SRAM            3
-#define TARGET_PCIE            4
-#define ATTR_DEV_SPI_ROM       0x1e
-#define ATTR_DEV_BOOT          0x1d
-#define ATTR_DEV_NAND          0x2f
-#define ATTR_DEV_CS3           0x37
-#define ATTR_DEV_CS2           0x3b
-#define ATTR_DEV_CS1           0x3d
-#define ATTR_DEV_CS0           0x3e
-#define ATTR_PCIE_IO           0xe0
-#define ATTR_PCIE_MEM          0xe8
-#define ATTR_PCIE1_IO          0xd0
-#define ATTR_PCIE1_MEM         0xd8
-#define ATTR_SRAM              0x01
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct __initdata orion_addr_map_cfg addr_map_cfg = {
-       .num_wins = 8,
-       .remappable_wins = 4,
-       .bridge_virt_base = BRIDGE_VIRT_BASE,
-};
-
-static const struct __initdata orion_addr_map_info addr_map_info[] = {
-       /*
-        * Windows for PCIe IO+MEM space.
-        */
-       { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
-         TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE
-       },
-       { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
-         TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE
-       },
-       { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
-         TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE
-       },
-       { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
-         TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE
-       },
-       /*
-        * Window for NAND controller.
-        */
-       { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
-         TARGET_DEV_BUS, ATTR_DEV_NAND, -1
-       },
-       /*
-        * Window for SRAM.
-        */
-       { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
-         TARGET_SRAM, ATTR_SRAM, -1
-       },
-       /* End marker */
-       { -1, 0, 0, 0, 0, 0 }
-};
-
-void __init kirkwood_setup_cpu_mbus(void)
-{
-       /*
-        * Disable, clear and configure windows.
-        */
-       orion_config_wins(&addr_map_cfg, addr_map_info);
-
-       /*
-        * Setup MBUS dram target info.
-        */
-       orion_setup_cpu_mbus_target(&addr_map_cfg,
-                                   (void __iomem *) DDR_WINDOW_CPU_BASE);
-}
index 7904758e771fb1f30df89036191956831a88e9c7..e9647b80cb590d9d0131b9542a5e476da9cad459 100644 (file)
@@ -93,7 +93,7 @@ static void __init kirkwood_dt_init(void)
         */
        writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
 
-       kirkwood_setup_cpu_mbus();
+       kirkwood_setup_wins();
 
        kirkwood_l2_init();
 
index 49792a0cd2d3d17f399ea96ee8f5369f49c3bb99..c2cae69e6d2bb9343798a7a3398ce174850d59cf 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <plat/common.h>
 #include <plat/time.h>
-#include <plat/addr-map.h>
 #include <linux/platform_data/dma-mv_xor.h>
 #include "common.h"
 
@@ -535,6 +534,9 @@ void __init kirkwood_init_early(void)
         * the allocations won't fail.
         */
        init_dma_coherent_pool_size(SZ_1M);
+       mvebu_mbus_init("marvell,kirkwood-mbus",
+                       BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
+                       DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ);
 }
 
 int kirkwood_tclk;
@@ -650,6 +652,38 @@ char * __init kirkwood_id(void)
        }
 }
 
+void __init kirkwood_setup_wins(void)
+{
+       /*
+        * The PCIe windows will no longer be statically allocated
+        * here once Kirkwood is migrated to the pci-mvebu driver.
+        */
+       mvebu_mbus_add_window_remap_flags("pcie0.0",
+                                         KIRKWOOD_PCIE_IO_PHYS_BASE,
+                                         KIRKWOOD_PCIE_IO_SIZE,
+                                         KIRKWOOD_PCIE_IO_BUS_BASE,
+                                         MVEBU_MBUS_PCI_IO);
+       mvebu_mbus_add_window_remap_flags("pcie0.0",
+                                         KIRKWOOD_PCIE_MEM_PHYS_BASE,
+                                         KIRKWOOD_PCIE_MEM_SIZE,
+                                         MVEBU_MBUS_NO_REMAP,
+                                         MVEBU_MBUS_PCI_MEM);
+       mvebu_mbus_add_window_remap_flags("pcie1.0",
+                                         KIRKWOOD_PCIE1_IO_PHYS_BASE,
+                                         KIRKWOOD_PCIE1_IO_SIZE,
+                                         KIRKWOOD_PCIE1_IO_BUS_BASE,
+                                         MVEBU_MBUS_PCI_IO);
+       mvebu_mbus_add_window_remap_flags("pcie1.0",
+                                         KIRKWOOD_PCIE1_MEM_PHYS_BASE,
+                                         KIRKWOOD_PCIE1_MEM_SIZE,
+                                         MVEBU_MBUS_NO_REMAP,
+                                         MVEBU_MBUS_PCI_MEM);
+       mvebu_mbus_add_window("nand", KIRKWOOD_NAND_MEM_PHYS_BASE,
+                             KIRKWOOD_NAND_MEM_SIZE);
+       mvebu_mbus_add_window("sram", KIRKWOOD_SRAM_PHYS_BASE,
+                             KIRKWOOD_SRAM_SIZE);
+}
+
 void __init kirkwood_l2_init(void)
 {
 #ifdef CONFIG_CACHE_FEROCEON_L2
@@ -675,7 +709,7 @@ void __init kirkwood_init(void)
         */
        writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
 
-       kirkwood_setup_cpu_mbus();
+       kirkwood_setup_wins();
 
        kirkwood_l2_init();
 
index 3147be2f34da7558818c6a7a667058f50b22b94e..21da3b1ebd7bf843c2b9b1e11a8fd025b5e30287 100644 (file)
@@ -30,7 +30,7 @@ void kirkwood_init(void);
 void kirkwood_init_early(void);
 void kirkwood_init_irq(void);
 
-void kirkwood_setup_cpu_mbus(void);
+void kirkwood_setup_wins(void);
 
 void kirkwood_enable_pcie(void);
 void kirkwood_pcie_id(u32 *dev, u32 *rev);
index a05563a31c95c41d8690243ab0bb34e302da793e..92976cef3910bb4b50094df748744f8c74ccce53 100644 (file)
@@ -60,8 +60,9 @@
  * Register Map
  */
 #define DDR_VIRT_BASE          (KIRKWOOD_REGS_VIRT_BASE + 0x00000)
-#define DDR_PHYS_BASE          (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
-#define  DDR_WINDOW_CPU_BASE   (DDR_VIRT_BASE + 0x1500)
+#define DDR_PHYS_BASE           (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
+#define  DDR_WINDOW_CPU_BASE    (DDR_PHYS_BASE + 0x1500)
+#define  DDR_WINDOW_CPU_SZ      (0x20)
 #define DDR_OPERATION_BASE     (DDR_PHYS_BASE + 0x1418)
 
 #define DEV_BUS_PHYS_BASE      (KIRKWOOD_REGS_PHYS_BASE + 0x10000)
@@ -80,6 +81,8 @@
 
 #define BRIDGE_VIRT_BASE       (KIRKWOOD_REGS_VIRT_BASE + 0x20000)
 #define BRIDGE_PHYS_BASE       (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
+#define  BRIDGE_WINS_BASE       (BRIDGE_PHYS_BASE)
+#define  BRIDGE_WINS_SZ         (0x80)
 
 #define CRYPTO_PHYS_BASE       (KIRKWOOD_REGS_PHYS_BASE + 0x30000)
 
index d96ad4c099726f8dc4706031d0da4f79556aaf44..7f43e6c2f8c0a15f820ce7fc0cbd6ddb0f6936de 100644 (file)
@@ -17,7 +17,6 @@
 #include <asm/mach/pci.h>
 #include <plat/pcie.h>
 #include <mach/bridge-regs.h>
-#include <plat/addr-map.h>
 #include "common.h"
 
 static void kirkwood_enable_pcie_clk(const char *port)
index 67a13f9bfe643f54fb789443dff8c1cd5eabe3f8..7cd04634d302ef5d4b28d119f93ef27005ecae74 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                          += common.o addr-map.o mpp.o irq.o pcie.o
+obj-y                          += common.o mpp.o irq.o pcie.o
 obj-$(CONFIG_MACH_DB78X00_BP)  += db78x00-bp-setup.o
 obj-$(CONFIG_MACH_RD78X00_MASA)        += rd78x00-masa-setup.o
 obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c
deleted file mode 100644 (file)
index 26e9876..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/addr-map.c
- *
- * Address map functions for Marvell MV78xx0 SoCs
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <plat/addr-map.h>
-#include <mach/mv78xx0.h>
-#include "common.h"
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DEV_BUS         1
-#define TARGET_PCIE0           4
-#define TARGET_PCIE1           8
-#define TARGET_PCIE(i)         ((i) ? TARGET_PCIE1 : TARGET_PCIE0)
-#define ATTR_DEV_SPI_ROM       0x1f
-#define ATTR_DEV_BOOT          0x2f
-#define ATTR_DEV_CS3           0x37
-#define ATTR_DEV_CS2           0x3b
-#define ATTR_DEV_CS1           0x3d
-#define ATTR_DEV_CS0           0x3e
-#define ATTR_PCIE_IO(l)                (0xf0 & ~(0x10 << (l)))
-#define ATTR_PCIE_MEM(l)       (0xf8 & ~(0x10 << (l)))
-
-/*
- * CPU Address Decode Windows registers
- */
-#define WIN0_OFF(n)            (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
-#define WIN8_OFF(n)            (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
-
-static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
-{
-       /*
-        * Find the control register base address for this window.
-        *
-        * BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's)
-        * MBUS bridge depending on which CPU core we're running on,
-        * so we don't need to take that into account here.
-        */
-
-       return (win < 8) ? WIN0_OFF(win) : WIN8_OFF(win);
-}
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct orion_addr_map_cfg addr_map_cfg __initdata = {
-       .num_wins = 14,
-       .remappable_wins = 8,
-       .win_cfg_base = win_cfg_base,
-};
-
-void __init mv78xx0_setup_cpu_mbus(void)
-{
-       /*
-        * Disable, clear and configure windows.
-        */
-       orion_config_wins(&addr_map_cfg, NULL);
-
-       /*
-        * Setup MBUS dram target info.
-        */
-       if (mv78xx0_core_index() == 0)
-               orion_setup_cpu_mbus_target(&addr_map_cfg,
-                                           (void __iomem *) DDR_WINDOW_CPU0_BASE);
-       else
-               orion_setup_cpu_mbus_target(&addr_map_cfg,
-                                           (void __iomem *) DDR_WINDOW_CPU1_BASE);
-}
-
-void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
-                                     int maj, int min)
-{
-       orion_setup_cpu_win(&addr_map_cfg, window, base, size,
-                           TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0);
-}
-
-void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
-                                      int maj, int min)
-{
-       orion_setup_cpu_win(&addr_map_cfg, window, base, size,
-                           TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1);
-}
index 0efa14498ebccf99f6733674db3de7d83f37b334..749a7f8c4992e9746cccad78c0f4ee8d41553f20 100644 (file)
@@ -334,6 +334,14 @@ void __init mv78xx0_uart3_init(void)
 void __init mv78xx0_init_early(void)
 {
        orion_time_set_base(TIMER_VIRT_BASE);
+       if (mv78xx0_core_index() == 0)
+               mvebu_mbus_init("marvell,mv78xx0-mbus",
+                               BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ,
+                               DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ);
+       else
+               mvebu_mbus_init("marvell,mv78xx0-mbus",
+                               BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ,
+                               DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ);
 }
 
 void __init_refok mv78xx0_timer_init(void)
@@ -397,8 +405,6 @@ void __init mv78xx0_init(void)
        printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
        printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
 
-       mv78xx0_setup_cpu_mbus();
-
 #ifdef CONFIG_CACHE_FEROCEON_L2
        feroceon_l2_init(is_l2_writethrough());
 #endif
index 46200a183cf2cbf5f96bd6e62f8eb3a0cc4240f3..723748d8ba7d4294bc0d8da6640653f3e3bfb796 100644 (file)
  */
 #define BRIDGE_VIRT_BASE       (MV78XX0_CORE_REGS_VIRT_BASE)
 #define BRIDGE_PHYS_BASE       (MV78XX0_CORE_REGS_PHYS_BASE)
+#define  BRIDGE_WINS_CPU0_BASE  (MV78XX0_CORE0_REGS_PHYS_BASE)
+#define  BRIDGE_WINS_CPU1_BASE  (MV78XX0_CORE1_REGS_PHYS_BASE)
+#define  BRIDGE_WINS_SZ         (0xA000)
 
 /*
  * Register Map
  */
 #define DDR_VIRT_BASE          (MV78XX0_REGS_VIRT_BASE + 0x00000)
-#define  DDR_WINDOW_CPU0_BASE  (DDR_VIRT_BASE + 0x1500)
-#define  DDR_WINDOW_CPU1_BASE  (DDR_VIRT_BASE + 0x1570)
+#define DDR_PHYS_BASE           (MV78XX0_REGS_PHYS_BASE + 0x00000)
+#define  DDR_WINDOW_CPU0_BASE  (DDR_PHYS_BASE + 0x1500)
+#define  DDR_WINDOW_CPU1_BASE  (DDR_PHYS_BASE + 0x1570)
+#define  DDR_WINDOW_CPU_SZ      (0x20)
 
 #define DEV_BUS_PHYS_BASE      (MV78XX0_REGS_PHYS_BASE + 0x10000)
 #define DEV_BUS_VIRT_BASE      (MV78XX0_REGS_VIRT_BASE + 0x10000)
index ee8c0b51df2c7013126f52ef8f441d4b9ccb6a8a..dc26a654c496d1d06797af927531f6030a24e146 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/mbus.h>
 #include <video/vga.h>
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
 #include <plat/pcie.h>
-#include <plat/addr-map.h>
 #include <mach/mv78xx0.h>
 #include "common.h"
 
@@ -54,7 +54,6 @@ static void __init mv78xx0_pcie_preinit(void)
        int i;
        u32 size_each;
        u32 start;
-       int win = 0;
 
        pcie_io_space.name = "PCIe I/O Space";
        pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
@@ -72,6 +71,7 @@ static void __init mv78xx0_pcie_preinit(void)
        start = MV78XX0_PCIE_MEM_PHYS_BASE;
        for (i = 0; i < num_pcie_ports; i++) {
                struct pcie_port *pp = pcie_port + i;
+               char winname[MVEBU_MBUS_MAX_WINNAME_SZ];
 
                snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
                        "PCIe %d.%d MEM", pp->maj, pp->min);
@@ -85,12 +85,17 @@ static void __init mv78xx0_pcie_preinit(void)
                if (request_resource(&iomem_resource, &pp->res))
                        panic("can't allocate PCIe MEM sub-space");
 
-               mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start,
-                                          resource_size(&pp->res),
-                                          pp->maj, pp->min);
-
-               mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K,
-                                         pp->maj, pp->min);
+               snprintf(winname, sizeof(winname), "pcie%d.%d",
+                        pp->maj, pp->min);
+
+               mvebu_mbus_add_window_remap_flags(winname,
+                                                 pp->res.start,
+                                                 resource_size(&pp->res),
+                                                 MVEBU_MBUS_NO_REMAP,
+                                                 MVEBU_MBUS_PCI_MEM);
+               mvebu_mbus_add_window_remap_flags(winname,
+                                                 i * SZ_64K, SZ_64K,
+                                                 0, MVEBU_MBUS_PCI_IO);
        }
 }
 
index 440b13ef1fedeecffd308f448dad7ae27cb8d4d7..e11acbb0a46d4316c82f23cb333744cbab41d89f 100644 (file)
@@ -13,6 +13,8 @@ config ARCH_MVEBU
        select MVEBU_CLK_CORE
        select MVEBU_CLK_CPU
        select MVEBU_CLK_GATING
+       select MVEBU_MBUS
+       select ZONE_DMA if ARM_LPAE
 
 if ARCH_MVEBU
 
index da93bcbc74c196256f3a504c6c9dd485701bd4f4..ba769e082ad474c61c69860c24f22f7267670454 100644 (file)
@@ -5,6 +5,6 @@ AFLAGS_coherency_ll.o           := -Wa,-march=armv7-a
 
 obj-y                           += system-controller.o
 obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o
-obj-$(CONFIG_ARCH_MVEBU)        += addr-map.o coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o 
+obj-$(CONFIG_ARCH_MVEBU)        += coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o
 obj-$(CONFIG_SMP)                += platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)        += hotplug.o
diff --git a/arch/arm/mach-mvebu/addr-map.c b/arch/arm/mach-mvebu/addr-map.c
deleted file mode 100644 (file)
index ab9b3bd..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Address map functions for Marvell 370 / XP SoCs
- *
- * Copyright (C) 2012 Marvell
- *
- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <plat/addr-map.h>
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define ARMADA_XP_TARGET_DEV_BUS       1
-#define   ARMADA_XP_ATTR_DEV_BOOTROM    0x1D
-#define ARMADA_XP_TARGET_ETH1          3
-#define ARMADA_XP_TARGET_PCIE_0_2      4
-#define ARMADA_XP_TARGET_ETH0          7
-#define ARMADA_XP_TARGET_PCIE_1_3      8
-
-#define ARMADA_370_TARGET_DEV_BUS       1
-#define   ARMADA_370_ATTR_DEV_BOOTROM   0x1D
-#define ARMADA_370_TARGET_PCIE_0        4
-#define ARMADA_370_TARGET_PCIE_1        8
-
-#define ARMADA_WINDOW_8_PLUS_OFFSET       0x90
-#define ARMADA_SDRAM_ADDR_DECODING_OFFSET 0x180
-
-static const struct __initdata orion_addr_map_info
-armada_xp_addr_map_info[] = {
-       /*
-        * Window for the BootROM, needed for SMP on Armada XP
-        */
-       { 0, 0xfff00000, SZ_1M, ARMADA_XP_TARGET_DEV_BUS,
-         ARMADA_XP_ATTR_DEV_BOOTROM, -1 },
-       /* End marker */
-       { -1, 0, 0, 0, 0, 0 },
-};
-
-static const struct __initdata orion_addr_map_info
-armada_370_addr_map_info[] = {
-       /* End marker */
-       { -1, 0, 0, 0, 0, 0 },
-};
-
-static struct of_device_id of_addr_decoding_controller_table[] = {
-       { .compatible = "marvell,armada-addr-decoding-controller" },
-       { /* end of list */ },
-};
-
-static void __iomem *
-armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
-{
-       unsigned int offset;
-
-       /* The register layout is a bit annoying and the below code
-        * tries to cope with it.
-        * - At offset 0x0, there are the registers for the first 8
-        *   windows, with 4 registers of 32 bits per window (ctrl,
-        *   base, remap low, remap high)
-        * - Then at offset 0x80, there is a hole of 0x10 bytes for
-        *   the internal registers base address and internal units
-        *   sync barrier register.
-        * - Then at offset 0x90, there the registers for 12
-        *   windows, with only 2 registers of 32 bits per window
-        *   (ctrl, base).
-        */
-       if (win < 8)
-               offset = (win << 4);
-       else
-               offset = ARMADA_WINDOW_8_PLUS_OFFSET + ((win - 8) << 3);
-
-       return cfg->bridge_virt_base + offset;
-}
-
-static struct __initdata orion_addr_map_cfg addr_map_cfg = {
-       .num_wins = 20,
-       .remappable_wins = 8,
-       .win_cfg_base = armada_cfg_base,
-};
-
-static int __init armada_setup_cpu_mbus(void)
-{
-       struct device_node *np;
-       void __iomem *mbus_unit_addr_decoding_base;
-       void __iomem *sdram_addr_decoding_base;
-
-       np = of_find_matching_node(NULL, of_addr_decoding_controller_table);
-       if (!np)
-               return -ENODEV;
-
-       mbus_unit_addr_decoding_base = of_iomap(np, 0);
-       BUG_ON(!mbus_unit_addr_decoding_base);
-
-       sdram_addr_decoding_base =
-               mbus_unit_addr_decoding_base +
-               ARMADA_SDRAM_ADDR_DECODING_OFFSET;
-
-       addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base;
-
-       if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
-               addr_map_cfg.hw_io_coherency = 1;
-
-       /*
-        * Disable, clear and configure windows.
-        */
-       if (of_machine_is_compatible("marvell,armadaxp"))
-               orion_config_wins(&addr_map_cfg, armada_xp_addr_map_info);
-       else if (of_machine_is_compatible("marvell,armada370"))
-               orion_config_wins(&addr_map_cfg, armada_370_addr_map_info);
-       else {
-               pr_err("Unsupported SoC\n");
-               return -EINVAL;
-       }
-
-       /*
-        * Setup MBUS dram target info.
-        */
-       orion_setup_cpu_mbus_target(&addr_map_cfg,
-                                   sdram_addr_decoding_base);
-       return 0;
-}
-
-/* Using a early_initcall is needed so that this initialization gets
- * done before the SMP initialization, which requires the BootROM to
- * be remapped. */
-early_initcall(armada_setup_cpu_mbus);
index a5ea616d6d12b896fc49b2f13730ba5a65fd6e02..12d3655830d1482eba5c34667b01a0bb6bc6e9d7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/time-armada-370-xp.h>
 #include <linux/clk/mvebu.h>
 #include <linux/dma-mapping.h>
+#include <linux/mbus.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -48,12 +49,29 @@ void __init armada_370_xp_timer_and_clk_init(void)
 
 void __init armada_370_xp_init_early(void)
 {
+       char *mbus_soc_name;
+
        /*
         * Some Armada 370/XP devices allocate their coherent buffers
         * from atomic context. Increase size of atomic coherent pool
         * to make sure such the allocations won't fail.
         */
        init_dma_coherent_pool_size(SZ_1M);
+
+       /*
+        * This initialization will be replaced by a DT-based
+        * initialization once the mvebu-mbus driver gains DT support.
+        */
+       if (of_machine_is_compatible("marvell,armada370"))
+               mbus_soc_name = "marvell,armada370-mbus";
+       else
+               mbus_soc_name = "marvell,armadaxp-mbus";
+
+       mvebu_mbus_init(mbus_soc_name,
+                       ARMADA_370_XP_MBUS_WINS_BASE,
+                       ARMADA_370_XP_MBUS_WINS_SIZE,
+                       ARMADA_370_XP_SDRAM_WINS_BASE,
+                       ARMADA_370_XP_SDRAM_WINS_SIZE);
 }
 
 static void __init armada_370_xp_dt_init(void)
index c6a7d74fddfec24f719ade3fdd1a1ce649742cec..2070e1b4f34241685f451b024b87a8ab43c63fcb 100644 (file)
 #define __MACH_ARMADA_370_XP_H
 
 #define ARMADA_370_XP_REGS_PHYS_BASE   0xd0000000
-#define ARMADA_370_XP_REGS_VIRT_BASE   IOMEM(0xfeb00000)
+#define ARMADA_370_XP_REGS_VIRT_BASE   IOMEM(0xfec00000)
 #define ARMADA_370_XP_REGS_SIZE                SZ_1M
 
+/* These defines can go away once mvebu-mbus has a DT binding */
+#define ARMADA_370_XP_MBUS_WINS_BASE    (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000)
+#define ARMADA_370_XP_MBUS_WINS_SIZE    0x100
+#define ARMADA_370_XP_SDRAM_WINS_BASE   (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180)
+#define ARMADA_370_XP_SDRAM_WINS_SIZE   0x20
+
 #ifdef CONFIG_SMP
 #include <linux/cpumask.h>
 
index fe16aaf7c19c7e506fb2d0d1e759268fe0a2cf41..875ea748391ca87adfbc0756837da2bad6584be8 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/mbus.h>
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 #include "common.h"
@@ -109,6 +110,7 @@ void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
        set_secondary_cpus_clock();
        flush_cache_all();
        set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
+       mvebu_mbus_add_window("bootrom", 0xfff00000, SZ_1M);
 }
 
 struct smp_operations armada_xp_smp_ops __initdata = {
index 9e809a7c05c0c607b00433fc6a95047ac1365e7c..45da805fb23692d07703310e8076a0cd8e4070f5 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                          += common.o addr-map.o pci.o irq.o mpp.o
+obj-y                          += common.o pci.o irq.o mpp.o
 obj-$(CONFIG_MACH_DB88F5281)   += db88f5281-setup.o
 obj-$(CONFIG_MACH_RD88F5182)   += rd88f5182-setup.o
 obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
deleted file mode 100644 (file)
index b5efc0f..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * arch/arm/mach-orion5x/addr-map.c
- *
- * Address map functions for Marvell Orion 5x SoCs
- *
- * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <plat/addr-map.h>
-#include "common.h"
-
-/*
- * The Orion has fully programmable address map. There's a separate address
- * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIe, USB,
- * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
- * address decode windows that allow it to access any of the Orion resources.
- *
- * CPU address decoding --
- * Linux assumes that it is the boot loader that already setup the access to
- * DDR and internal registers.
- * Setup access to PCI and PCIe IO/MEM space is issued by this file.
- * Setup access to various devices located on the device bus interface (e.g.
- * flashes, RTC, etc) should be issued by machine-setup.c according to
- * specific board population (by using orion5x_setup_*_win()).
- *
- * Non-CPU Masters address decoding --
- * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
- * banks only (the typical use case).
- * Setup access for each master to DDR is issued by platform device setup.
- */
-
-/*
- * Generic Address Decode Windows bit settings
- */
-#define TARGET_DEV_BUS         1
-#define TARGET_PCI             3
-#define TARGET_PCIE            4
-#define TARGET_SRAM            9
-#define ATTR_PCIE_MEM          0x59
-#define ATTR_PCIE_IO           0x51
-#define ATTR_PCIE_WA           0x79
-#define ATTR_PCI_MEM           0x59
-#define ATTR_PCI_IO            0x51
-#define ATTR_DEV_CS0           0x1e
-#define ATTR_DEV_CS1           0x1d
-#define ATTR_DEV_CS2           0x1b
-#define ATTR_DEV_BOOT          0xf
-#define ATTR_SRAM              0x0
-
-static int __initdata win_alloc_count;
-
-static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
-                 const int win)
-{
-       u32 dev, rev;
-
-       orion5x_pcie_id(&dev, &rev);
-       if ((dev == MV88F5281_DEV_ID && win < 4)
-           || (dev == MV88F5182_DEV_ID && win < 2)
-           || (dev == MV88F5181_DEV_ID && win < 2)
-           || (dev == MV88F6183_DEV_ID && win < 4))
-               return 1;
-
-       return 0;
-}
-
-/*
- * Description of the windows needed by the platform code
- */
-static struct orion_addr_map_cfg addr_map_cfg __initdata = {
-       .num_wins = 8,
-       .cpu_win_can_remap = cpu_win_can_remap,
-       .bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE,
-};
-
-static const struct __initdata orion_addr_map_info addr_map_info[] = {
-       /*
-        * Setup windows for PCI+PCIe IO+MEM space.
-        */
-       { 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
-         TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE
-       },
-       { 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
-         TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE
-       },
-       { 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
-         TARGET_PCIE, ATTR_PCIE_MEM, -1
-       },
-       { 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
-         TARGET_PCI, ATTR_PCI_MEM, -1
-       },
-       /* End marker */
-       { -1, 0, 0, 0, 0, 0 }
-};
-
-void __init orion5x_setup_cpu_mbus_bridge(void)
-{
-       /*
-        * Disable, clear and configure windows.
-        */
-       orion_config_wins(&addr_map_cfg, addr_map_info);
-       win_alloc_count = 4;
-
-       /*
-        * Setup MBUS dram target info.
-        */
-       orion_setup_cpu_mbus_target(&addr_map_cfg,
-                                   (void __iomem *) ORION5X_DDR_WINDOW_CPU_BASE);
-}
-
-void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
-{
-       orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
-                           TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
-}
-
-void __init orion5x_setup_dev0_win(u32 base, u32 size)
-{
-       orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
-                           TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
-}
-
-void __init orion5x_setup_dev1_win(u32 base, u32 size)
-{
-       orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
-                           TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
-}
-
-void __init orion5x_setup_dev2_win(u32 base, u32 size)
-{
-       orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
-                           TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
-}
-
-void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
-{
-       orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
-                           TARGET_PCIE, ATTR_PCIE_WA, -1);
-}
-
-void __init orion5x_setup_sram_win(void)
-{
-       orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++,
-                           ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE,
-                           TARGET_SRAM, ATTR_SRAM, -1);
-}
index 94fbb815680c40d117069714d2d1d8b342949ce2..b91002ca92f3b42b6a04f54683daa4f2504e5c2a 100644 (file)
@@ -42,7 +42,7 @@ static void __init orion5x_dt_init(void)
        /*
         * Setup Orion address map
         */
-       orion5x_setup_cpu_mbus_bridge();
+       orion5x_setup_wins();
 
        /* Setup root of clk tree */
        clk_init();
index 2075bf8e3d90959784d27ff0b36bb423836c2711..b97fd672e89d74f40e3ebfc0b1e18c365be785f3 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <plat/time.h>
 #include <plat/common.h>
-#include <plat/addr-map.h>
 #include "common.h"
 
 /*****************************************************************************
@@ -175,7 +174,8 @@ void __init orion5x_xor_init(void)
  ****************************************************************************/
 static void __init orion5x_crypto_init(void)
 {
-       orion5x_setup_sram_win();
+       mvebu_mbus_add_window("sram", ORION5X_SRAM_PHYS_BASE,
+                             ORION5X_SRAM_SIZE);
        orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
                          SZ_8K, IRQ_ORION5X_CESA);
 }
@@ -194,6 +194,9 @@ void __init orion5x_wdt_init(void)
  ****************************************************************************/
 void __init orion5x_init_early(void)
 {
+       u32 rev, dev;
+       const char *mbus_soc_name;
+
        orion_time_set_base(TIMER_VIRT_BASE);
 
        /*
@@ -202,6 +205,46 @@ void __init orion5x_init_early(void)
         * the allocations won't fail.
         */
        init_dma_coherent_pool_size(SZ_1M);
+
+       /* Initialize the MBUS driver */
+       orion5x_pcie_id(&dev, &rev);
+       if (dev == MV88F5281_DEV_ID)
+               mbus_soc_name = "marvell,orion5x-88f5281-mbus";
+       else if (dev == MV88F5182_DEV_ID)
+               mbus_soc_name = "marvell,orion5x-88f5182-mbus";
+       else if (dev == MV88F5181_DEV_ID)
+               mbus_soc_name = "marvell,orion5x-88f5181-mbus";
+       else if (dev == MV88F6183_DEV_ID)
+               mbus_soc_name = "marvell,orion5x-88f6183-mbus";
+       else
+               mbus_soc_name = NULL;
+       mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE,
+                       ORION5X_BRIDGE_WINS_SZ,
+                       ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ);
+}
+
+void orion5x_setup_wins(void)
+{
+       /*
+        * The PCIe windows will no longer be statically allocated
+        * here once Orion5x is migrated to the pci-mvebu driver.
+        */
+       mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_IO_PHYS_BASE,
+                                         ORION5X_PCIE_IO_SIZE,
+                                         ORION5X_PCIE_IO_BUS_BASE,
+                                         MVEBU_MBUS_PCI_IO);
+       mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_MEM_PHYS_BASE,
+                                         ORION5X_PCIE_MEM_SIZE,
+                                         MVEBU_MBUS_NO_REMAP,
+                                         MVEBU_MBUS_PCI_MEM);
+       mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_IO_PHYS_BASE,
+                                         ORION5X_PCI_IO_SIZE,
+                                         ORION5X_PCI_IO_BUS_BASE,
+                                         MVEBU_MBUS_PCI_IO);
+       mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_MEM_PHYS_BASE,
+                                         ORION5X_PCI_MEM_SIZE,
+                                         MVEBU_MBUS_NO_REMAP,
+                                         MVEBU_MBUS_PCI_MEM);
 }
 
 int orion5x_tclk;
@@ -283,7 +326,7 @@ void __init orion5x_init(void)
        /*
         * Setup Orion address map
         */
-       orion5x_setup_cpu_mbus_bridge();
+       orion5x_setup_wins();
 
        /* Setup root of clk tree */
        clk_init();
index e60345760283a9263a10be96c3fa4fd54a7c9c91..cdaa01f3d186f59a9b41fd7bff58853c957817ec 100644 (file)
@@ -17,18 +17,7 @@ void clk_init(void);
 extern int orion5x_tclk;
 extern void orion5x_timer_init(void);
 
-/*
- * Enumerations and functions for Orion windows mapping. Used by Orion core
- * functions to map its interfaces and by the machine-setup to map its on-
- * board devices. Details in /mach-orion/addr-map.c
- */
-void orion5x_setup_cpu_mbus_bridge(void);
-void orion5x_setup_dev_boot_win(u32 base, u32 size);
-void orion5x_setup_dev0_win(u32 base, u32 size);
-void orion5x_setup_dev1_win(u32 base, u32 size);
-void orion5x_setup_dev2_win(u32 base, u32 size);
-void orion5x_setup_pcie_wa_win(u32 base, u32 size);
-void orion5x_setup_sram_win(void);
+void orion5x_setup_wins(void);
 
 void orion5x_ehci0_init(void);
 void orion5x_ehci1_init(void);
index 57d0af74874d0877a77dc0d4a44c4bebe56b7605..16c88bbabc9814d2b9967efa3aab2becaa054604 100644 (file)
@@ -317,8 +317,8 @@ static void __init d2net_init(void)
        d2net_sata_power_init();
        orion5x_sata_init(&d2net_sata_data);
 
-       orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE,
-                               D2NET_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", D2NET_NOR_BOOT_BASE,
+                             D2NET_NOR_BOOT_SIZE);
        platform_device_register(&d2net_nor_flash);
 
        platform_device_register(&d2net_gpio_buttons);
index 76665640087b879f54ef5bbc150a95e3b7de923f..4e1263da38bb2b2e21119ebfbff1b890fd3e8051 100644 (file)
@@ -340,16 +340,19 @@ static void __init db88f5281_init(void)
        orion5x_uart0_init();
        orion5x_uart1_init();
 
-       orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE,
-                               DB88F5281_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", DB88F5281_NOR_BOOT_BASE,
+                             DB88F5281_NOR_BOOT_SIZE);
        platform_device_register(&db88f5281_boot_flash);
 
-       orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE);
+       mvebu_mbus_add_window("devbus-cs0", DB88F5281_7SEG_BASE,
+                             DB88F5281_7SEG_SIZE);
 
-       orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE);
+       mvebu_mbus_add_window("devbus-cs1", DB88F5281_NOR_BASE,
+                             DB88F5281_NOR_SIZE);
        platform_device_register(&db88f5281_nor_flash);
 
-       orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE);
+       mvebu_mbus_add_window("devbus-cs2", DB88F5281_NAND_BASE,
+                             DB88F5281_NAND_SIZE);
        platform_device_register(&db88f5281_nand_flash);
 
        i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
index 6eb1732757fd241132cbfea85e83f79272621c84..9e6baf581ed3ef71e338c494931a0b5069ca722d 100644 (file)
@@ -611,7 +611,8 @@ static void __init dns323_init(void)
        /* setup flash mapping
         * CS3 holds a 8 MB Spansion S29GL064M90TFIR4
         */
-       orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", DNS323_NOR_BOOT_BASE,
+                             DNS323_NOR_BOOT_SIZE);
        platform_device_register(&dns323_nor_flash);
 
        /* Sort out LEDs, Buttons and i2c devices */
index d675e727803d214f49320db72f5b059e54d076b2..147615510dd0ccd29f1dd8d62626661dbfdd0476 100644 (file)
@@ -154,8 +154,8 @@ void __init edmini_v2_init(void)
        orion5x_ehci0_init();
        orion5x_eth_init(&edmini_v2_eth_data);
 
-       orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE,
-                               EDMINI_V2_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", EDMINI_V2_NOR_BOOT_BASE,
+                             EDMINI_V2_NOR_BOOT_SIZE);
        platform_device_register(&edmini_v2_nor_flash);
 
        pr_notice("edmini_v2: USB device port, flash write and power-off "
index d265f5484a8e6934a7a1105c196539d27e6d3b15..b78ff324886888844ff8f6de83a4dfe5b63996da 100644 (file)
  * Orion Registers Map
  ******************************************************************************/
 
+#define ORION5X_DDR_PHYS_BASE           (ORION5X_REGS_PHYS_BASE + 0x00000)
+#define  ORION5X_DDR_WINS_BASE          (ORION5X_DDR_PHYS_BASE + 0x1500)
+#define  ORION5X_DDR_WINS_SZ            (0x10)
 #define ORION5X_DDR_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x00000)
-#define  ORION5X_DDR_WINDOW_CPU_BASE    (ORION5X_DDR_VIRT_BASE + 0x1500)
 #define ORION5X_DEV_BUS_PHYS_BASE      (ORION5X_REGS_PHYS_BASE + 0x10000)
 #define ORION5X_DEV_BUS_VIRT_BASE      (ORION5X_REGS_VIRT_BASE + 0x10000)
 #define ORION5X_DEV_BUS_REG(x)         (ORION5X_DEV_BUS_VIRT_BASE + (x))
@@ -81,6 +83,8 @@
 
 #define ORION5X_BRIDGE_VIRT_BASE       (ORION5X_REGS_VIRT_BASE + 0x20000)
 #define ORION5X_BRIDGE_PHYS_BASE       (ORION5X_REGS_PHYS_BASE + 0x20000)
+#define  ORION5X_BRIDGE_WINS_BASE       (ORION5X_BRIDGE_PHYS_BASE)
+#define  ORION5X_BRIDGE_WINS_SZ         (0x80)
 
 #define ORION5X_PCI_VIRT_BASE          (ORION5X_REGS_VIRT_BASE + 0x30000)
 
index b984035262180af2c072c7f8cca492c3baed97a0..aae10e4a917cbd9e41f3a0370e0dece8ba7feed9 100644 (file)
@@ -359,13 +359,13 @@ static void __init kurobox_pro_init(void)
        orion5x_uart1_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE,
-                                  KUROBOX_PRO_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", KUROBOX_PRO_NOR_BOOT_BASE,
+                             KUROBOX_PRO_NOR_BOOT_SIZE);
        platform_device_register(&kurobox_pro_nor_flash);
 
        if (machine_is_kurobox_pro()) {
-               orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE,
-                                      KUROBOX_PRO_NAND_SIZE);
+               mvebu_mbus_add_window("devbus-cs0", KUROBOX_PRO_NAND_BASE,
+                                     KUROBOX_PRO_NAND_SIZE);
                platform_device_register(&kurobox_pro_nand_flash);
        }
 
index 044da5b6a6ae6057efff262eed3e870716691b26..24f4e14e58939b7453c689b93580fa33facd36f4 100644 (file)
@@ -294,8 +294,8 @@ static void __init lschl_init(void)
        orion5x_uart0_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(LSCHL_NOR_BOOT_BASE,
-                                  LSCHL_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", LSCHL_NOR_BOOT_BASE,
+                             LSCHL_NOR_BOOT_SIZE);
        platform_device_register(&lschl_nor_flash);
 
        platform_device_register(&lschl_leds);
index d49f93423f52feaeb2061542982ce0db477d7fa3..fc653bb41e78f0889b5956b79db41e18d66f17bf 100644 (file)
@@ -243,8 +243,8 @@ static void __init ls_hgl_init(void)
        orion5x_uart0_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(LS_HGL_NOR_BOOT_BASE,
-                                  LS_HGL_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", LS_HGL_NOR_BOOT_BASE,
+                             LS_HGL_NOR_BOOT_SIZE);
        platform_device_register(&ls_hgl_nor_flash);
 
        platform_device_register(&ls_hgl_button_device);
index 8e3965c6c0fe15fa96b615d55cc4c6e16aded6c3..18e66e617dc297e02063710ff87366ec465dad3a 100644 (file)
@@ -244,8 +244,8 @@ static void __init lsmini_init(void)
        orion5x_uart0_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE,
-                                  LSMINI_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", LSMINI_NOR_BOOT_BASE,
+                             LSMINI_NOR_BOOT_SIZE);
        platform_device_register(&lsmini_nor_flash);
 
        platform_device_register(&lsmini_button_device);
index 0ec94a1f2b16e2fe9a9ac34bd7964867c42a8e20..827acbafc9dc2a3b841b869e5e35924d114ac632 100644 (file)
@@ -241,7 +241,8 @@ static void __init mss2_init(void)
        orion5x_uart0_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(MSS2_NOR_BOOT_BASE, MSS2_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", MSS2_NOR_BOOT_BASE,
+                             MSS2_NOR_BOOT_SIZE);
        platform_device_register(&mss2_nor_flash);
 
        platform_device_register(&mss2_button_device);
index 18143f2a909398eb709066c7bba1a2d32261b575..92600ae2b4b6e4992ff7f27311ecf9186a2b401b 100644 (file)
@@ -204,7 +204,8 @@ static void __init mv2120_init(void)
        orion5x_uart0_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", MV2120_NOR_BOOT_BASE,
+                             MV2120_NOR_BOOT_SIZE);
        platform_device_register(&mv2120_nor_flash);
 
        platform_device_register(&mv2120_button_device);
index 282e503b003eb12c6ffd62b62ae4dd35cc09982c..dd0641a0d074447a1c1934128a8a90564b4860da 100644 (file)
@@ -397,8 +397,8 @@ static void __init net2big_init(void)
        net2big_sata_power_init();
        orion5x_sata_init(&net2big_sata_data);
 
-       orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE,
-                                  NET2BIG_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", NET2BIG_NOR_BOOT_BASE,
+                             NET2BIG_NOR_BOOT_SIZE);
        platform_device_register(&net2big_nor_flash);
 
        platform_device_register(&net2big_gpio_buttons);
index 973db98a3c277f4c89fec32a2f0c5250815abbc8..503368023bb18ffdd1ba62f019a90adbe73c9522 100644 (file)
@@ -157,8 +157,11 @@ static int __init pcie_setup(struct pci_sys_data *sys)
        if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
                printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
                                   "read transaction workaround\n");
-               orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
-                                         ORION5X_PCIE_WA_SIZE);
+               mvebu_mbus_add_window_remap_flags("pcie0.0",
+                                                 ORION5X_PCIE_WA_PHYS_BASE,
+                                                 ORION5X_PCIE_WA_SIZE,
+                                                 MVEBU_MBUS_NO_REMAP,
+                                                 MVEBU_MBUS_PCI_WA);
                pcie_ops.read = pcie_rd_conf_wa;
        }
 
index d6e72f672afbf221a9066100a64b3d96107d9e5f..1c4498bf650a6cbc8d109a18de761f58beb9acd0 100644 (file)
@@ -123,8 +123,8 @@ static void __init rd88f5181l_fxo_init(void)
        orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
        orion5x_uart0_init();
 
-       orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
-                                  RD88F5181L_FXO_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", RD88F5181L_FXO_NOR_BOOT_BASE,
+                             RD88F5181L_FXO_NOR_BOOT_SIZE);
        platform_device_register(&rd88f5181l_fxo_nor_boot_flash);
 }
 
index c8b7913310e53b7f97ced2566fd0d4001512513f..adabe34c4fc62b1ac02e9333b90128add8809c3b 100644 (file)
@@ -130,8 +130,8 @@ static void __init rd88f5181l_ge_init(void)
        orion5x_i2c_init();
        orion5x_uart0_init();
 
-       orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE,
-                                  RD88F5181L_GE_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", RD88F5181L_GE_NOR_BOOT_BASE,
+                             RD88F5181L_GE_NOR_BOOT_SIZE);
        platform_device_register(&rd88f5181l_ge_nor_boot_flash);
 
        i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1);
index f9e156725d7cf52e742972d90ba58776c57c7708..66e77ec91532ba1e42189af393772c7a2248dc81 100644 (file)
@@ -264,10 +264,11 @@ static void __init rd88f5182_init(void)
        orion5x_uart0_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE,
-                                  RD88F5182_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", RD88F5182_NOR_BOOT_BASE,
+                             RD88F5182_NOR_BOOT_SIZE);
 
-       orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
+       mvebu_mbus_add_window("devbus-cs1", RD88F5182_NOR_BASE,
+                             RD88F5182_NOR_SIZE);
        platform_device_register(&rd88f5182_nor_flash);
        platform_device_register(&rd88f5182_gpio_leds);
 
index acc0877ec1c9848be42c2fceaf40a956532bb07c..a0bfa53e75569e292785af06eca421d6073c70af 100644 (file)
@@ -329,8 +329,8 @@ static void __init tsp2_init(void)
        /*
         * Configure peripherals.
         */
-       orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE,
-                                  TSP2_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", TSP2_NOR_BOOT_BASE,
+                             TSP2_NOR_BOOT_SIZE);
        platform_device_register(&tsp2_nor_flash);
 
        orion5x_ehci0_init();
index 9c17f0c2b488616404472282be1d955dba515711..80174f0f168e7ce6c9ca91d73175a064bcad8ed6 100644 (file)
@@ -286,8 +286,8 @@ static void __init qnap_ts209_init(void)
        /*
         * Configure peripherals.
         */
-       orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE,
-                                  QNAP_TS209_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", QNAP_TS209_NOR_BOOT_BASE,
+                             QNAP_TS209_NOR_BOOT_SIZE);
        platform_device_register(&qnap_ts209_nor_flash);
 
        orion5x_ehci0_init();
index 8cc5ab6c503e31f17f5f4b0bf9b9e8207d90657c..92592790d6da2eb9048fc06523c13b80dcf2c1d5 100644 (file)
@@ -277,8 +277,8 @@ static void __init qnap_ts409_init(void)
        /*
         * Configure peripherals.
         */
-       orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE,
-                                  QNAP_TS409_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", QNAP_TS409_NOR_BOOT_BASE,
+                             QNAP_TS409_NOR_BOOT_SIZE);
        platform_device_register(&qnap_ts409_nor_flash);
 
        orion5x_ehci0_init();
index 66552ca7e05da68de13934ddaae342cd75622404..6b84863c018d6c4f83440a26b5c7e4ca85977e4f 100644 (file)
@@ -127,8 +127,8 @@ static void __init wnr854t_init(void)
        orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ);
        orion5x_uart0_init();
 
-       orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE,
-                                  WNR854T_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", WNR854T_NOR_BOOT_BASE,
+                             WNR854T_NOR_BOOT_SIZE);
        platform_device_register(&wnr854t_nor_flash);
 }
 
index 2c5408e2e689431fdd40de391db45890f9821caa..fae684bc54f2b51f81dcec16bc7ad31fe210fb0d 100644 (file)
@@ -213,8 +213,8 @@ static void __init wrt350n_v2_init(void)
        orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
        orion5x_uart0_init();
 
-       orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
-                                  WRT350N_V2_NOR_BOOT_SIZE);
+       mvebu_mbus_add_window("devbus-boot", WRT350N_V2_NOR_BOOT_BASE,
+                             WRT350N_V2_NOR_BOOT_SIZE);
        platform_device_register(&wrt350n_v2_nor_flash);
        platform_device_register(&wrt350n_v2_leds);
        platform_device_register(&wrt350n_v2_button_device);
index 7d86bfbb5b065323bd4496c4f4ae0101a40450d7..31d5cd4d97879f7d9243c9310eb0ea1dd8c7f047 100644 (file)
 #include <mach/clock.h>
 #include <mach/common.h>
 
+/*
+ *             MD1 = 1                 MD1 = 0
+ *             (PLLA = 1500)           (PLLA = 1600)
+ *             (MHz)                   (MHz)
+ *------------------------------------------------+--------------------
+ * clkz                1000   (2/3)            800   (1/2)
+ * clkzs        250   (1/6)            200   (1/8)
+ * clki                 750   (1/2)            800   (1/2)
+ * clks                 250   (1/6)            200   (1/8)
+ * clks1        125   (1/12)           100   (1/16)
+ * clks3        187.5 (1/8)            200   (1/8)
+ * clks4         93.7 (1/16)           100   (1/16)
+ * clkp                  62.5 (1/24)            50   (1/32)
+ * clkg                  62.5 (1/24)            66.6 (1/24)
+ * clkb, CLKOUT
+ * (MD2 = 0)     62.5 (1/24)            66.6 (1/24)
+ * (MD2 = 1)     41.6 (1/36)            50   (1/32)
+*/
+
 #define MD(nr) BIT(nr)
 
 #define FRQMR          IOMEM(0xffc80014)
@@ -93,7 +112,7 @@ static struct clk *main_clks[] = {
 };
 
 enum { MSTP323, MSTP322, MSTP321, MSTP320,
-       MSTP115,
+       MSTP115, MSTP114,
        MSTP103, MSTP101, MSTP100,
        MSTP030,
        MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
@@ -107,6 +126,7 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
        [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
        [MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
+       [MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
        [MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1,  3, 0), /* DU */
        [MSTP101] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1,  1, 0), /* USB2 */
        [MSTP100] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1,  0, 0), /* USB0/1 */
@@ -143,6 +163,7 @@ static struct clk_lookup lookups[] = {
        /* MSTP32 clocks */
        CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
        CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
+       CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */
        CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
        CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
        CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
index 945299ed1638c4d2441bda423c38dae7aeffe2ae..188b295938a5cab5a9599f3874444074323ad97f 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/sh_clk.h>
 #include <linux/pm_domain.h>
+#include <linux/sh_eth.h>
 
 struct platform_device;
 
@@ -31,6 +32,7 @@ extern void r8a7779_earlytimer_init(void);
 extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_add_standard_devices_dt(void);
+extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata);
 extern void r8a7779_clock_init(void);
 extern void r8a7779_pinmux_init(void);
 extern void r8a7779_pm_init(void);
index a460ba3dedcb1af67083b402f78a7592ec0818b1..b0b394842ea5011b31b678a8b53b012cea2580ba 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * r8a7779 processor support
  *
- * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011, 2013  Renesas Solutions Corp.
  * Copyright (C) 2011  Magnus Damm
+ * Copyright (C) 2013  Cogent Embedded, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -393,6 +394,18 @@ static struct platform_device sata_device = {
        },
 };
 
+/* Ether */
+static struct resource ether_resources[] = {
+       {
+               .start  = 0xfde00000,
+               .end    = 0xfde003ff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = gic_iid(0xb4),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
 static struct platform_device *r8a7779_devices_dt[] __initdata = {
        &scif0_device,
        &scif1_device,
@@ -428,6 +441,14 @@ void __init r8a7779_add_standard_devices(void)
                            ARRAY_SIZE(r8a7779_late_devices));
 }
 
+void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
+{
+       platform_device_register_resndata(&platform_bus, "sh_eth", -1,
+                                         ether_resources,
+                                         ARRAY_SIZE(ether_resources),
+                                         pdata, sizeof(*pdata));
+}
+
 /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
 void __init __weak r8a7779_register_twd(void) { }
 
index cf3226b041f51a7f8b53daa60e3aa1a0bce9c2bc..c1d61f281e68d424b82060caf6b0601e6ecbf967 100644 (file)
@@ -10,6 +10,7 @@ config ARCH_ZYNQ
        select ICST
        select MIGHT_HAVE_CACHE_L2X0
        select USE_OF
+       select HAVE_SMP
        select SPARSE_IRQ
        select CADENCE_TTC_TIMER
        help
index 320faedeb48482968fae80fe2fd36f1fa97312c3..1b25d92ebf22c9d9bb513344138816568aef8212 100644 (file)
@@ -3,4 +3,8 @@
 #
 
 # Common support
-obj-y                          := common.o
+obj-y                          := common.o slcr.o
+CFLAGS_REMOVE_hotplug.o                =-march=armv6k
+CFLAGS_hotplug.o               =-Wa,-march=armv7-a -mcpu=cortex-a9
+obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
+obj-$(CONFIG_SMP)              += headsmp.o platsmp.o
index 68e0907de5d002fc162c0247845f27c284d057e2..5bfe7035b73d96b6394046a67f5a50fcc287d782 100644 (file)
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/smp_scu.h>
 #include <asm/hardware/cache-l2x0.h>
 
 #include "common.h"
 
+void __iomem *zynq_scu_base;
+
 static struct of_device_id zynq_of_bus_ids[] __initdata = {
        { .compatible = "simple-bus", },
        {}
 };
 
 /**
- * xilinx_init_machine() - System specific initialization, intended to be
- *                        called from board specific initialization.
+ * zynq_init_machine - System specific initialization, intended to be
+ *                    called from board specific initialization.
  */
-static void __init xilinx_init_machine(void)
+static void __init zynq_init_machine(void)
 {
        /*
         * 64KB way size, 8-way associativity, parity disabled
@@ -56,50 +59,56 @@ static void __init xilinx_init_machine(void)
        of_platform_bus_probe(NULL, zynq_of_bus_ids, NULL);
 }
 
-#define SCU_PERIPH_PHYS                0xF8F00000
-#define SCU_PERIPH_SIZE                SZ_8K
-#define SCU_PERIPH_VIRT                (VMALLOC_END - SCU_PERIPH_SIZE)
+static void __init zynq_timer_init(void)
+{
+       zynq_slcr_init();
+       clocksource_of_init();
+}
 
-static struct map_desc scu_desc __initdata = {
-       .virtual        = SCU_PERIPH_VIRT,
-       .pfn            = __phys_to_pfn(SCU_PERIPH_PHYS),
-       .length         = SCU_PERIPH_SIZE,
-       .type           = MT_DEVICE,
+static struct map_desc zynq_cortex_a9_scu_map __initdata = {
+       .length = SZ_256,
+       .type   = MT_DEVICE,
 };
 
-static void __init xilinx_zynq_timer_init(void)
+static void __init zynq_scu_map_io(void)
 {
-       struct device_node *np;
-       void __iomem *slcr;
-
-       np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-slcr");
-       slcr = of_iomap(np, 0);
-       WARN_ON(!slcr);
+       unsigned long base;
 
-       xilinx_zynq_clocks_init(slcr);
-
-       clocksource_of_init();
+       base = scu_a9_get_base();
+       zynq_cortex_a9_scu_map.pfn = __phys_to_pfn(base);
+       /* Expected address is in vmalloc area that's why simple assign here */
+       zynq_cortex_a9_scu_map.virtual = base;
+       iotable_init(&zynq_cortex_a9_scu_map, 1);
+       zynq_scu_base = (void __iomem *)base;
+       BUG_ON(!zynq_scu_base);
 }
 
 /**
- * xilinx_map_io() - Create memory mappings needed for early I/O.
+ * zynq_map_io - Create memory mappings needed for early I/O.
  */
-static void __init xilinx_map_io(void)
+static void __init zynq_map_io(void)
 {
        debug_ll_io_init();
-       iotable_init(&scu_desc, 1);
+       zynq_scu_map_io();
+}
+
+static void zynq_system_reset(char mode, const char *cmd)
+{
+       zynq_slcr_system_reset();
 }
 
-static const char *xilinx_dt_match[] = {
+static const char * const zynq_dt_match[] = {
        "xlnx,zynq-zc702",
        "xlnx,zynq-7000",
        NULL
 };
 
 MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
-       .map_io         = xilinx_map_io,
+       .smp            = smp_ops(zynq_smp_ops),
+       .map_io         = zynq_map_io,
        .init_irq       = irqchip_init,
-       .init_machine   = xilinx_init_machine,
-       .init_time      = xilinx_zynq_timer_init,
-       .dt_compat      = xilinx_dt_match,
+       .init_machine   = zynq_init_machine,
+       .init_time      = zynq_timer_init,
+       .dt_compat      = zynq_dt_match,
+       .restart        = zynq_system_reset,
 MACHINE_END
index 5050bb10bb12a16646d71b0a74ca202ec9af9e7d..fbbd0e21c404d5f98bc4c6bf5387df045ceaa66f 100644 (file)
 #ifndef __MACH_ZYNQ_COMMON_H__
 #define __MACH_ZYNQ_COMMON_H__
 
+extern int zynq_slcr_init(void);
+extern void zynq_slcr_system_reset(void);
+extern void zynq_slcr_cpu_stop(int cpu);
+extern void zynq_slcr_cpu_start(int cpu);
+
+#ifdef CONFIG_SMP
+extern void secondary_startup(void);
+extern char zynq_secondary_trampoline;
+extern char zynq_secondary_trampoline_jump;
+extern char zynq_secondary_trampoline_end;
+extern int __cpuinit zynq_cpun_start(u32 address, int cpu);
+extern struct smp_operations zynq_smp_ops __initdata;
+#endif
+
+extern void __iomem *zynq_slcr_base;
+extern void __iomem *zynq_scu_base;
+
+/* Hotplug */
+extern void zynq_platform_cpu_die(unsigned int cpu);
+
 #endif
diff --git a/arch/arm/mach-zynq/headsmp.S b/arch/arm/mach-zynq/headsmp.S
new file mode 100644 (file)
index 0000000..d183cd2
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ * Copyright (c) 2012-2013 Xilinx
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+       __CPUINIT
+
+ENTRY(zynq_secondary_trampoline)
+       ldr     r0, [pc]
+       bx      r0
+.globl zynq_secondary_trampoline_jump
+zynq_secondary_trampoline_jump:
+       /* Space for jumping address */
+       .word   /* cpu 1 */
+.globl zynq_secondary_trampoline_end
+zynq_secondary_trampoline_end:
+
+ENDPROC(zynq_secondary_trampoline)
diff --git a/arch/arm/mach-zynq/hotplug.c b/arch/arm/mach-zynq/hotplug.c
new file mode 100644 (file)
index 0000000..c89672b
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012-2013 Xilinx
+ *
+ * based on linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include "common.h"
+
+static inline void zynq_cpu_enter_lowpower(void)
+{
+       unsigned int v;
+
+       flush_cache_all();
+       asm volatile(
+       "       mcr     p15, 0, %1, c7, c5, 0\n"
+       "       dsb\n"
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, #0x40\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+         : "=&r" (v)
+         : "r" (0), "Ir" (CR_C)
+         : "cc");
+}
+
+static inline void zynq_cpu_leave_lowpower(void)
+{
+       unsigned int v;
+
+       asm volatile(
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       orr     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       orr     %0, %0, #0x40\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+         : "=&r" (v)
+         : "Ir" (CR_C)
+         : "cc");
+}
+
+static inline void zynq_platform_do_lowpower(unsigned int cpu, int *spurious)
+{
+       /*
+        * there is no power-control hardware on this platform, so all
+        * we can do is put the core into WFI; this is safe as the calling
+        * code will have already disabled interrupts
+        */
+       for (;;) {
+               dsb();
+               wfi();
+
+               /*
+                * Getting here, means that we have come out of WFI without
+                * having been woken up - this shouldn't happen
+                *
+                * Just note it happening - when we're woken, we can report
+                * its occurrence.
+                */
+               (*spurious)++;
+       }
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void zynq_platform_cpu_die(unsigned int cpu)
+{
+       int spurious = 0;
+
+       /*
+        * we're ready for shutdown now, so do it
+        */
+       zynq_cpu_enter_lowpower();
+       zynq_platform_do_lowpower(cpu, &spurious);
+
+       /*
+        * bring this CPU back into the world of cache
+        * coherency, and then restore interrupts
+        */
+       zynq_cpu_leave_lowpower();
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
new file mode 100644 (file)
index 0000000..5fc167e
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * This file contains Xilinx specific SMP code, used to start up
+ * the second processor.
+ *
+ * Copyright (C) 2011-2013 Xilinx
+ *
+ * based on linux/arch/arm/mach-realview/platsmp.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/export.h>
+#include <linux/jiffies.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <linux/irqchip/arm-gic.h>
+#include "common.h"
+
+/*
+ * Store number of cores in the system
+ * Because of scu_get_core_count() must be in __init section and can't
+ * be called from zynq_cpun_start() because it is in __cpuinit section.
+ */
+static int ncores;
+
+int __cpuinit zynq_cpun_start(u32 address, int cpu)
+{
+       u32 trampoline_code_size = &zynq_secondary_trampoline_end -
+                                               &zynq_secondary_trampoline;
+
+       if (cpu > ncores) {
+               pr_warn("CPU No. is not available in the system\n");
+               return -1;
+       }
+
+       /* MS: Expectation that SLCR are directly map and accessible */
+       /* Not possible to jump to non aligned address */
+       if (!(address & 3) && (!address || (address >= trampoline_code_size))) {
+               /* Store pointer to ioremap area which points to address 0x0 */
+               static u8 __iomem *zero;
+               u32 trampoline_size = &zynq_secondary_trampoline_jump -
+                                               &zynq_secondary_trampoline;
+
+               zynq_slcr_cpu_stop(cpu);
+
+               if (__pa(PAGE_OFFSET)) {
+                       zero = ioremap(0, trampoline_code_size);
+                       if (!zero) {
+                               pr_warn("BOOTUP jump vectors not accessible\n");
+                               return -1;
+                       }
+               } else {
+                       zero = (__force u8 __iomem *)PAGE_OFFSET;
+               }
+
+               /*
+                * This is elegant way how to jump to any address
+                * 0x0: Load address at 0x8 to r0
+                * 0x4: Jump by mov instruction
+                * 0x8: Jumping address
+                */
+               memcpy((__force void *)zero, &zynq_secondary_trampoline,
+                                               trampoline_size);
+               writel(address, zero + trampoline_size);
+
+               flush_cache_all();
+               outer_flush_range(0, trampoline_code_size);
+               smp_wmb();
+
+               if (__pa(PAGE_OFFSET))
+                       iounmap(zero);
+
+               zynq_slcr_cpu_start(cpu);
+
+               return 0;
+       }
+
+       pr_warn("Can't start CPU%d: Wrong starting address %x\n", cpu, address);
+
+       return -1;
+}
+EXPORT_SYMBOL(zynq_cpun_start);
+
+static int __cpuinit zynq_boot_secondary(unsigned int cpu,
+                                               struct task_struct *idle)
+{
+       return zynq_cpun_start(virt_to_phys(secondary_startup), cpu);
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+static void __init zynq_smp_init_cpus(void)
+{
+       int i;
+
+       ncores = scu_get_core_count(zynq_scu_base);
+
+       for (i = 0; i < ncores && i < CONFIG_NR_CPUS; i++)
+               set_cpu_possible(i, true);
+}
+
+static void __init zynq_smp_prepare_cpus(unsigned int max_cpus)
+{
+       int i;
+
+       /*
+        * Initialise the present map, which describes the set of CPUs
+        * actually populated at the present time.
+        */
+       for (i = 0; i < max_cpus; i++)
+               set_cpu_present(i, true);
+
+       scu_enable(zynq_scu_base);
+}
+
+struct smp_operations zynq_smp_ops __initdata = {
+       .smp_init_cpus          = zynq_smp_init_cpus,
+       .smp_prepare_cpus       = zynq_smp_prepare_cpus,
+       .smp_boot_secondary     = zynq_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = zynq_platform_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
new file mode 100644 (file)
index 0000000..c70969b
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Xilinx SLCR driver
+ *
+ * Copyright (c) 2011-2013 Xilinx Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+ * 02139, USA.
+ */
+
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/clk/zynq.h>
+#include "common.h"
+
+#define SLCR_UNLOCK_MAGIC              0xDF0D
+#define SLCR_UNLOCK                    0x8   /* SCLR unlock register */
+
+#define SLCR_PS_RST_CTRL_OFFSET                0x200 /* PS Software Reset Control */
+
+#define SLCR_A9_CPU_CLKSTOP            0x10
+#define SLCR_A9_CPU_RST                        0x1
+
+#define SLCR_A9_CPU_RST_CTRL           0x244 /* CPU Software Reset Control */
+#define SLCR_REBOOT_STATUS             0x258 /* PS Reboot Status */
+
+void __iomem *zynq_slcr_base;
+
+/**
+ * zynq_slcr_system_reset - Reset the entire system.
+ */
+void zynq_slcr_system_reset(void)
+{
+       u32 reboot;
+
+       /*
+        * Unlock the SLCR then reset the system.
+        * Note that this seems to require raw i/o
+        * functions or there's a lockup?
+        */
+       writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK);
+
+       /*
+        * Clear 0x0F000000 bits of reboot status register to workaround
+        * the FSBL not loading the bitstream after soft-reboot
+        * This is a temporary solution until we know more.
+        */
+       reboot = readl(zynq_slcr_base + SLCR_REBOOT_STATUS);
+       writel(reboot & 0xF0FFFFFF, zynq_slcr_base + SLCR_REBOOT_STATUS);
+       writel(1, zynq_slcr_base + SLCR_PS_RST_CTRL_OFFSET);
+}
+
+/**
+ * zynq_slcr_cpu_start - Start cpu
+ * @cpu:       cpu number
+ */
+void zynq_slcr_cpu_start(int cpu)
+{
+       /* enable CPUn */
+       writel(SLCR_A9_CPU_CLKSTOP << cpu,
+              zynq_slcr_base + SLCR_A9_CPU_RST_CTRL);
+       /* enable CLK for CPUn */
+       writel(0x0 << cpu, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL);
+}
+
+/**
+ * zynq_slcr_cpu_stop - Stop cpu
+ * @cpu:       cpu number
+ */
+void zynq_slcr_cpu_stop(int cpu)
+{
+       /* stop CLK and reset CPUn */
+       writel((SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu,
+              zynq_slcr_base + SLCR_A9_CPU_RST_CTRL);
+}
+
+/**
+ * zynq_slcr_init
+ * Returns 0 on success, negative errno otherwise.
+ *
+ * Called early during boot from platform code to remap SLCR area.
+ */
+int __init zynq_slcr_init(void)
+{
+       struct device_node *np;
+
+       np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-slcr");
+       if (!np) {
+               pr_err("%s: no slcr node found\n", __func__);
+               BUG();
+       }
+
+       zynq_slcr_base = of_iomap(np, 0);
+       if (!zynq_slcr_base) {
+               pr_err("%s: Unable to map I/O memory\n", __func__);
+               BUG();
+       }
+
+       /* unlock the SLCR so that registers can be changed */
+       writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK);
+
+       pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
+
+       xilinx_zynq_clocks_init(zynq_slcr_base);
+
+       of_node_put(np);
+
+       return 0;
+}
index ad97400ba3ada182f934947dcaa4bd47cf45dc7c..2eca54b65906e1ffbf69ffd9a27b74d71b7415d6 100644 (file)
@@ -3,12 +3,6 @@
 #
 ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
 
-obj-$(CONFIG_ARCH_MVEBU)          += addr-map.o
-obj-$(CONFIG_ARCH_KIRKWOOD)       += addr-map.o
-obj-$(CONFIG_ARCH_DOVE)           += addr-map.o
-obj-$(CONFIG_ARCH_ORION5X)        += addr-map.o
-obj-$(CONFIG_ARCH_MV78XX0)        += addr-map.o
-
 orion-gpio-$(CONFIG_GENERIC_GPIO) += gpio.o
 obj-$(CONFIG_PLAT_ORION_LEGACY)   += irq.o pcie.o time.o common.o mpp.o
 obj-$(CONFIG_PLAT_ORION_LEGACY)   += $(orion-gpio-y)
diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
deleted file mode 100644 (file)
index 807ac8e..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * arch/arm/plat-orion/addr-map.c
- *
- * Address map functions for Marvell Orion based SoCs
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/mbus.h>
-#include <linux/io.h>
-#include <plat/addr-map.h>
-
-struct mbus_dram_target_info orion_mbus_dram_info;
-
-const struct mbus_dram_target_info *mv_mbus_dram_info(void)
-{
-       return &orion_mbus_dram_info;
-}
-EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
-
-/*
- * DDR target is the same on all Orion platforms.
- */
-#define TARGET_DDR             0
-
-/*
- * Helpers to get DDR bank info
- */
-#define DDR_BASE_CS_OFF(n)     (0x0000 + ((n) << 3))
-#define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
-
-/*
- * CPU Address Decode Windows registers
- */
-#define WIN_CTRL_OFF           0x0000
-#define WIN_BASE_OFF           0x0004
-#define WIN_REMAP_LO_OFF       0x0008
-#define WIN_REMAP_HI_OFF       0x000c
-
-#define ATTR_HW_COHERENCY      (0x1 << 4)
-
-/*
- * Default implementation
- */
-static void __init __iomem *
-orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
-{
-       return cfg->bridge_virt_base + (win << 4);
-}
-
-/*
- * Default implementation
- */
-static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
-                                         const int win)
-{
-       if (win < cfg->remappable_wins)
-               return 1;
-
-       return 0;
-}
-
-void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
-                               const int win, const u32 base,
-                               const u32 size, const u8 target,
-                               const u8 attr, const int remap)
-{
-       void __iomem *addr = cfg->win_cfg_base(cfg, win);
-       u32 ctrl, base_high, remap_addr;
-
-       if (win >= cfg->num_wins) {
-               printk(KERN_ERR "setup_cpu_win: trying to allocate window "
-                      "%d when only %d allowed\n", win, cfg->num_wins);
-       }
-
-       base_high = base & 0xffff0000;
-       ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
-
-       writel(base_high, addr + WIN_BASE_OFF);
-       writel(ctrl, addr + WIN_CTRL_OFF);
-       if (cfg->cpu_win_can_remap(cfg, win)) {
-               if (remap < 0)
-                       remap_addr = base;
-               else
-                       remap_addr = remap;
-               writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF);
-               writel(0, addr + WIN_REMAP_HI_OFF);
-       }
-}
-
-/*
- * Configure a number of windows.
- */
-static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg,
-                                       const struct orion_addr_map_info *info)
-{
-       while (info->win != -1) {
-               orion_setup_cpu_win(cfg, info->win, info->base, info->size,
-                                   info->target, info->attr, info->remap);
-               info++;
-       }
-}
-
-static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg)
-{
-       void __iomem *addr;
-       int i;
-
-       for (i = 0; i < cfg->num_wins; i++) {
-               addr = cfg->win_cfg_base(cfg, i);
-
-               writel(0, addr + WIN_BASE_OFF);
-               writel(0, addr + WIN_CTRL_OFF);
-               if (cfg->cpu_win_can_remap(cfg, i)) {
-                       writel(0, addr + WIN_REMAP_LO_OFF);
-                       writel(0, addr + WIN_REMAP_HI_OFF);
-               }
-       }
-}
-
-/*
- * Disable, clear and configure windows.
- */
-void __init orion_config_wins(struct orion_addr_map_cfg * cfg,
-                             const struct orion_addr_map_info *info)
-{
-       if (!cfg->cpu_win_can_remap)
-               cfg->cpu_win_can_remap = orion_cpu_win_can_remap;
-
-       if (!cfg->win_cfg_base)
-               cfg->win_cfg_base = orion_win_cfg_base;
-
-       orion_disable_wins(cfg);
-
-       if (info)
-               orion_setup_cpu_wins(cfg, info);
-}
-
-/*
- * Setup MBUS dram target info.
- */
-void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
-                                       const void __iomem *ddr_window_cpu_base)
-{
-       int i;
-       int cs;
-
-       orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
-
-       for (i = 0, cs = 0; i < 4; i++) {
-               u32 base = readl(ddr_window_cpu_base + DDR_BASE_CS_OFF(i));
-               u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
-
-               /*
-                * We only take care of entries for which the chip
-                * select is enabled, and that don't have high base
-                * address bits set (devices can only access the first
-                * 32 bits of the memory).
-                */
-               if ((size & 1) && !(base & 0xF)) {
-                       struct mbus_dram_window *w;
-
-                       w = &orion_mbus_dram_info.cs[cs++];
-                       w->cs_index = i;
-                       w->mbus_attr = 0xf & ~(1 << i);
-                       if (cfg->hw_io_coherency)
-                               w->mbus_attr |= ATTR_HW_COHERENCY;
-                       w->base = base & 0xffff0000;
-                       w->size = (size | 0x0000ffff) + 1;
-               }
-       }
-       orion_mbus_dram_info.num_cs = cs;
-}
index c29ee7ea200be1baeacb46981ddd5fad993dfe4b..e39c2ba6e2fba385aae9b9ce43db23e48d2caa05 100644 (file)
@@ -439,6 +439,64 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
        }
 }
 
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+       struct orion_gpio_chip *ochip =
+               container_of(chip, struct orion_gpio_chip, chip);
+       u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
+       int i;
+
+       out     = readl_relaxed(GPIO_OUT(ochip));
+       io_conf = readl_relaxed(GPIO_IO_CONF(ochip));
+       blink   = readl_relaxed(GPIO_BLINK_EN(ochip));
+       in_pol  = readl_relaxed(GPIO_IN_POL(ochip));
+       data_in = readl_relaxed(GPIO_DATA_IN(ochip));
+       cause   = readl_relaxed(GPIO_EDGE_CAUSE(ochip));
+       edg_msk = readl_relaxed(GPIO_EDGE_MASK(ochip));
+       lvl_msk = readl_relaxed(GPIO_LEVEL_MASK(ochip));
+
+       for (i = 0; i < chip->ngpio; i++) {
+               const char *label;
+               u32 msk;
+               bool is_out;
+
+               label = gpiochip_is_requested(chip, i);
+               if (!label)
+                       continue;
+
+               msk = 1 << i;
+               is_out = !(io_conf & msk);
+
+               seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);
+
+               if (is_out) {
+                       seq_printf(s, " out %s %s\n",
+                                  out & msk ? "hi" : "lo",
+                                  blink & msk ? "(blink )" : "");
+                       continue;
+               }
+
+               seq_printf(s, " in  %s (act %s) - IRQ",
+                          (data_in ^ in_pol) & msk  ? "hi" : "lo",
+                          in_pol & msk ? "lo" : "hi");
+               if (!((edg_msk | lvl_msk) & msk)) {
+                       seq_printf(s, " disabled\n");
+                       continue;
+               }
+               if (edg_msk & msk)
+                       seq_printf(s, " edge ");
+               if (lvl_msk & msk)
+                       seq_printf(s, " level");
+               seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear  ");
+       }
+}
+#else
+#define orion_gpio_dbg_show NULL
+#endif
+
 void __init orion_gpio_init(struct device_node *np,
                            int gpio_base, int ngpio,
                            void __iomem *base, int mask_offset,
@@ -471,6 +529,7 @@ void __init orion_gpio_init(struct device_node *np,
 #ifdef CONFIG_OF
        ochip->chip.of_node = np;
 #endif
+       ochip->chip.dbg_show = orion_gpio_dbg_show;
 
        spin_lock_init(&ochip->lock);
        ochip->base = (void __iomem *)base;
index 0f51ed687dc8442ed1a1c3107c9cb0f5b74bccda..b05ecab915c4ba30e1ea668f09f700b1d2519937 100644 (file)
@@ -4,6 +4,13 @@
 
 menu "Bus devices"
 
+config MVEBU_MBUS
+       bool
+       depends on PLAT_ORION
+       help
+         Driver needed for the MBus configuration on Marvell EBU SoCs
+         (Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
+
 config OMAP_OCP2SCP
        tristate "OMAP OCP2SCP DRIVER"
        depends on ARCH_OMAP2PLUS
index 45d997c85453288436ecc56eccfaec5ca35085ac..3c7b53c12091cb0cdafa5ab74fd43ddc616ae5c9 100644 (file)
@@ -2,6 +2,7 @@
 # Makefile for the bus drivers.
 #
 
+obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
 obj-$(CONFIG_OMAP_OCP2SCP)     += omap-ocp2scp.o
 
 # Interconnect bus driver for OMAP SoCs.
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
new file mode 100644 (file)
index 0000000..8740f46
--- /dev/null
@@ -0,0 +1,870 @@
+/*
+ * Address map functions for Marvell EBU SoCs (Kirkwood, Armada
+ * 370/XP, Dove, Orion5x and MV78xx0)
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The Marvell EBU SoCs have a configurable physical address space:
+ * the physical address at which certain devices (PCIe, NOR, NAND,
+ * etc.) sit can be configured. The configuration takes place through
+ * two sets of registers:
+ *
+ * - One to configure the access of the CPU to the devices. Depending
+ *   on the families, there are between 8 and 20 configurable windows,
+ *   each can be use to create a physical memory window that maps to a
+ *   specific device. Devices are identified by a tuple (target,
+ *   attribute).
+ *
+ * - One to configure the access to the CPU to the SDRAM. There are
+ *   either 2 (for Dove) or 4 (for other families) windows to map the
+ *   SDRAM into the physical address space.
+ *
+ * This driver:
+ *
+ * - Reads out the SDRAM address decoding windows at initialization
+ *   time, and fills the mvebu_mbus_dram_info structure with these
+ *   informations. The exported function mv_mbus_dram_info() allow
+ *   device drivers to get those informations related to the SDRAM
+ *   address decoding windows. This is because devices also have their
+ *   own windows (configured through registers that are part of each
+ *   device register space), and therefore the drivers for Marvell
+ *   devices have to configure those device -> SDRAM windows to ensure
+ *   that DMA works properly.
+ *
+ * - Provides an API for platform code or device drivers to
+ *   dynamically add or remove address decoding windows for the CPU ->
+ *   device accesses. This API is mvebu_mbus_add_window(),
+ *   mvebu_mbus_add_window_remap_flags() and
+ *   mvebu_mbus_del_window(). Since the (target, attribute) values
+ *   differ from one SoC family to another, the API uses a 'const char
+ *   *' string to identify devices, and this driver is responsible for
+ *   knowing the mapping between the name of a device and its
+ *   corresponding (target, attribute) in the current SoC family.
+ *
+ * - Provides a debugfs interface in /sys/kernel/debug/mvebu-mbus/ to
+ *   see the list of CPU -> SDRAM windows and their configuration
+ *   (file 'sdram') and the list of CPU -> devices windows and their
+ *   configuration (file 'devices').
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/debugfs.h>
+
+/*
+ * DDR target is the same on all platforms.
+ */
+#define TARGET_DDR             0
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN_CTRL_OFF           0x0000
+#define   WIN_CTRL_ENABLE       BIT(0)
+#define   WIN_CTRL_TGT_MASK     0xf0
+#define   WIN_CTRL_TGT_SHIFT    4
+#define   WIN_CTRL_ATTR_MASK    0xff00
+#define   WIN_CTRL_ATTR_SHIFT   8
+#define   WIN_CTRL_SIZE_MASK    0xffff0000
+#define   WIN_CTRL_SIZE_SHIFT   16
+#define WIN_BASE_OFF           0x0004
+#define   WIN_BASE_LOW          0xffff0000
+#define   WIN_BASE_HIGH         0xf
+#define WIN_REMAP_LO_OFF       0x0008
+#define   WIN_REMAP_LOW         0xffff0000
+#define WIN_REMAP_HI_OFF       0x000c
+
+#define ATTR_HW_COHERENCY      (0x1 << 4)
+
+#define DDR_BASE_CS_OFF(n)     (0x0000 + ((n) << 3))
+#define  DDR_BASE_CS_HIGH_MASK  0xf
+#define  DDR_BASE_CS_LOW_MASK   0xff000000
+#define DDR_SIZE_CS_OFF(n)     (0x0004 + ((n) << 3))
+#define  DDR_SIZE_ENABLED       BIT(0)
+#define  DDR_SIZE_CS_MASK       0x1c
+#define  DDR_SIZE_CS_SHIFT      2
+#define  DDR_SIZE_MASK          0xff000000
+
+#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4)
+
+struct mvebu_mbus_mapping {
+       const char *name;
+       u8 target;
+       u8 attr;
+       u8 attrmask;
+};
+
+/*
+ * Masks used for the 'attrmask' field of mvebu_mbus_mapping. They
+ * allow to get the real attribute value, discarding the special bits
+ * used to select a PCI MEM region or a PCI WA region. This allows the
+ * debugfs code to reverse-match the name of a device from its
+ * target/attr values.
+ *
+ * For all devices except PCI, all bits of 'attr' must be
+ * considered. For most SoCs, only bit 3 should be ignored (it allows
+ * to select between PCI MEM and PCI I/O). On Orion5x however, there
+ * is the special bit 5 to select a PCI WA region.
+ */
+#define MAPDEF_NOMASK       0xff
+#define MAPDEF_PCIMASK      0xf7
+#define MAPDEF_ORIONPCIMASK 0xd7
+
+/* Macro used to define one mvebu_mbus_mapping entry */
+#define MAPDEF(__n, __t, __a, __m) \
+       { .name = __n, .target = __t, .attr = __a, .attrmask = __m }
+
+struct mvebu_mbus_state;
+
+struct mvebu_mbus_soc_data {
+       unsigned int num_wins;
+       unsigned int num_remappable_wins;
+       unsigned int (*win_cfg_offset)(const int win);
+       void (*setup_cpu_target)(struct mvebu_mbus_state *s);
+       int (*show_cpu_target)(struct mvebu_mbus_state *s,
+                              struct seq_file *seq, void *v);
+       const struct mvebu_mbus_mapping *map;
+};
+
+struct mvebu_mbus_state {
+       void __iomem *mbuswins_base;
+       void __iomem *sdramwins_base;
+       struct dentry *debugfs_root;
+       struct dentry *debugfs_sdram;
+       struct dentry *debugfs_devs;
+       const struct mvebu_mbus_soc_data *soc;
+       int hw_io_coherency;
+};
+
+static struct mvebu_mbus_state mbus_state;
+
+static struct mbus_dram_target_info mvebu_mbus_dram_info;
+const struct mbus_dram_target_info *mv_mbus_dram_info(void)
+{
+       return &mvebu_mbus_dram_info;
+}
+EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
+
+/*
+ * Functions to manipulate the address decoding windows
+ */
+
+static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus,
+                                  int win, int *enabled, u64 *base,
+                                  u32 *size, u8 *target, u8 *attr,
+                                  u64 *remap)
+{
+       void __iomem *addr = mbus->mbuswins_base +
+               mbus->soc->win_cfg_offset(win);
+       u32 basereg = readl(addr + WIN_BASE_OFF);
+       u32 ctrlreg = readl(addr + WIN_CTRL_OFF);
+
+       if (!(ctrlreg & WIN_CTRL_ENABLE)) {
+               *enabled = 0;
+               return;
+       }
+
+       *enabled = 1;
+       *base = ((u64)basereg & WIN_BASE_HIGH) << 32;
+       *base |= (basereg & WIN_BASE_LOW);
+       *size = (ctrlreg | ~WIN_CTRL_SIZE_MASK) + 1;
+
+       if (target)
+               *target = (ctrlreg & WIN_CTRL_TGT_MASK) >> WIN_CTRL_TGT_SHIFT;
+
+       if (attr)
+               *attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT;
+
+       if (remap) {
+               if (win < mbus->soc->num_remappable_wins) {
+                       u32 remap_low = readl(addr + WIN_REMAP_LO_OFF);
+                       u32 remap_hi  = readl(addr + WIN_REMAP_HI_OFF);
+                       *remap = ((u64)remap_hi << 32) | remap_low;
+               } else
+                       *remap = 0;
+       }
+}
+
+static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus,
+                                     int win)
+{
+       void __iomem *addr;
+
+       addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win);
+
+       writel(0, addr + WIN_BASE_OFF);
+       writel(0, addr + WIN_CTRL_OFF);
+       if (win < mbus->soc->num_remappable_wins) {
+               writel(0, addr + WIN_REMAP_LO_OFF);
+               writel(0, addr + WIN_REMAP_HI_OFF);
+       }
+}
+
+/* Checks whether the given window number is available */
+static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus,
+                                    const int win)
+{
+       void __iomem *addr = mbus->mbuswins_base +
+               mbus->soc->win_cfg_offset(win);
+       u32 ctrl = readl(addr + WIN_CTRL_OFF);
+       return !(ctrl & WIN_CTRL_ENABLE);
+}
+
+/*
+ * Checks whether the given (base, base+size) area doesn't overlap an
+ * existing region
+ */
+static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus,
+                                      phys_addr_t base, size_t size,
+                                      u8 target, u8 attr)
+{
+       u64 end = (u64)base + size;
+       int win;
+
+       for (win = 0; win < mbus->soc->num_wins; win++) {
+               u64 wbase, wend;
+               u32 wsize;
+               u8 wtarget, wattr;
+               int enabled;
+
+               mvebu_mbus_read_window(mbus, win,
+                                      &enabled, &wbase, &wsize,
+                                      &wtarget, &wattr, NULL);
+
+               if (!enabled)
+                       continue;
+
+               wend = wbase + wsize;
+
+               /*
+                * Check if the current window overlaps with the
+                * proposed physical range
+                */
+               if ((u64)base < wend && end > wbase)
+                       return 0;
+
+               /*
+                * Check if target/attribute conflicts
+                */
+               if (target == wtarget && attr == wattr)
+                       return 0;
+       }
+
+       return 1;
+}
+
+static int mvebu_mbus_find_window(struct mvebu_mbus_state *mbus,
+                                 phys_addr_t base, size_t size)
+{
+       int win;
+
+       for (win = 0; win < mbus->soc->num_wins; win++) {
+               u64 wbase;
+               u32 wsize;
+               int enabled;
+
+               mvebu_mbus_read_window(mbus, win,
+                                      &enabled, &wbase, &wsize,
+                                      NULL, NULL, NULL);
+
+               if (!enabled)
+                       continue;
+
+               if (base == wbase && size == wsize)
+                       return win;
+       }
+
+       return -ENODEV;
+}
+
+static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
+                                  int win, phys_addr_t base, size_t size,
+                                  phys_addr_t remap, u8 target,
+                                  u8 attr)
+{
+       void __iomem *addr = mbus->mbuswins_base +
+               mbus->soc->win_cfg_offset(win);
+       u32 ctrl, remap_addr;
+
+       ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) |
+               (attr << WIN_CTRL_ATTR_SHIFT)    |
+               (target << WIN_CTRL_TGT_SHIFT)   |
+               WIN_CTRL_ENABLE;
+
+       writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF);
+       writel(ctrl, addr + WIN_CTRL_OFF);
+       if (win < mbus->soc->num_remappable_wins) {
+               if (remap == MVEBU_MBUS_NO_REMAP)
+                       remap_addr = base;
+               else
+                       remap_addr = remap;
+               writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF);
+               writel(0, addr + WIN_REMAP_HI_OFF);
+       }
+
+       return 0;
+}
+
+static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus,
+                                  phys_addr_t base, size_t size,
+                                  phys_addr_t remap, u8 target,
+                                  u8 attr)
+{
+       int win;
+
+       if (remap == MVEBU_MBUS_NO_REMAP) {
+               for (win = mbus->soc->num_remappable_wins;
+                    win < mbus->soc->num_wins; win++)
+                       if (mvebu_mbus_window_is_free(mbus, win))
+                               return mvebu_mbus_setup_window(mbus, win, base,
+                                                              size, remap,
+                                                              target, attr);
+       }
+
+
+       for (win = 0; win < mbus->soc->num_wins; win++)
+               if (mvebu_mbus_window_is_free(mbus, win))
+                       return mvebu_mbus_setup_window(mbus, win, base, size,
+                                                      remap, target, attr);
+
+       return -ENOMEM;
+}
+
+/*
+ * Debugfs debugging
+ */
+
+/* Common function used for Dove, Kirkwood, Armada 370/XP and Orion 5x */
+static int mvebu_sdram_debug_show_orion(struct mvebu_mbus_state *mbus,
+                                       struct seq_file *seq, void *v)
+{
+       int i;
+
+       for (i = 0; i < 4; i++) {
+               u32 basereg = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
+               u32 sizereg = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
+               u64 base;
+               u32 size;
+
+               if (!(sizereg & DDR_SIZE_ENABLED)) {
+                       seq_printf(seq, "[%d] disabled\n", i);
+                       continue;
+               }
+
+               base = ((u64)basereg & DDR_BASE_CS_HIGH_MASK) << 32;
+               base |= basereg & DDR_BASE_CS_LOW_MASK;
+               size = (sizereg | ~DDR_SIZE_MASK);
+
+               seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
+                          i, (unsigned long long)base,
+                          (unsigned long long)base + size + 1,
+                          (sizereg & DDR_SIZE_CS_MASK) >> DDR_SIZE_CS_SHIFT);
+       }
+
+       return 0;
+}
+
+/* Special function for Dove */
+static int mvebu_sdram_debug_show_dove(struct mvebu_mbus_state *mbus,
+                                      struct seq_file *seq, void *v)
+{
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
+               u64 base;
+               u32 size;
+
+               if (!(map & 1)) {
+                       seq_printf(seq, "[%d] disabled\n", i);
+                       continue;
+               }
+
+               base = map & 0xff800000;
+               size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
+
+               seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
+                          i, (unsigned long long)base,
+                          (unsigned long long)base + size, i);
+       }
+
+       return 0;
+}
+
+static int mvebu_sdram_debug_show(struct seq_file *seq, void *v)
+{
+       struct mvebu_mbus_state *mbus = &mbus_state;
+       return mbus->soc->show_cpu_target(mbus, seq, v);
+}
+
+static int mvebu_sdram_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mvebu_sdram_debug_show, inode->i_private);
+}
+
+static const struct file_operations mvebu_sdram_debug_fops = {
+       .open = mvebu_sdram_debug_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int mvebu_devs_debug_show(struct seq_file *seq, void *v)
+{
+       struct mvebu_mbus_state *mbus = &mbus_state;
+       int win;
+
+       for (win = 0; win < mbus->soc->num_wins; win++) {
+               u64 wbase, wremap;
+               u32 wsize;
+               u8 wtarget, wattr;
+               int enabled, i;
+               const char *name;
+
+               mvebu_mbus_read_window(mbus, win,
+                                      &enabled, &wbase, &wsize,
+                                      &wtarget, &wattr, &wremap);
+
+               if (!enabled) {
+                       seq_printf(seq, "[%02d] disabled\n", win);
+                       continue;
+               }
+
+
+               for (i = 0; mbus->soc->map[i].name; i++)
+                       if (mbus->soc->map[i].target == wtarget &&
+                           mbus->soc->map[i].attr ==
+                           (wattr & mbus->soc->map[i].attrmask))
+                               break;
+
+               name = mbus->soc->map[i].name ?: "unknown";
+
+               seq_printf(seq, "[%02d] %016llx - %016llx : %s",
+                          win, (unsigned long long)wbase,
+                          (unsigned long long)(wbase + wsize), name);
+
+               if (win < mbus->soc->num_remappable_wins) {
+                       seq_printf(seq, " (remap %016llx)\n",
+                                  (unsigned long long)wremap);
+               } else
+                       seq_printf(seq, "\n");
+       }
+
+       return 0;
+}
+
+static int mvebu_devs_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, mvebu_devs_debug_show, inode->i_private);
+}
+
+static const struct file_operations mvebu_devs_debug_fops = {
+       .open = mvebu_devs_debug_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+/*
+ * SoC-specific functions and definitions
+ */
+
+static unsigned int orion_mbus_win_offset(int win)
+{
+       return win << 4;
+}
+
+static unsigned int armada_370_xp_mbus_win_offset(int win)
+{
+       /* The register layout is a bit annoying and the below code
+        * tries to cope with it.
+        * - At offset 0x0, there are the registers for the first 8
+        *   windows, with 4 registers of 32 bits per window (ctrl,
+        *   base, remap low, remap high)
+        * - Then at offset 0x80, there is a hole of 0x10 bytes for
+        *   the internal registers base address and internal units
+        *   sync barrier register.
+        * - Then at offset 0x90, there the registers for 12
+        *   windows, with only 2 registers of 32 bits per window
+        *   (ctrl, base).
+        */
+       if (win < 8)
+               return win << 4;
+       else
+               return 0x90 + ((win - 8) << 3);
+}
+
+static unsigned int mv78xx0_mbus_win_offset(int win)
+{
+       if (win < 8)
+               return win << 4;
+       else
+               return 0x900 + ((win - 8) << 4);
+}
+
+static void __init
+mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
+{
+       int i;
+       int cs;
+
+       mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+       for (i = 0, cs = 0; i < 4; i++) {
+               u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
+               u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
+
+               /*
+                * We only take care of entries for which the chip
+                * select is enabled, and that don't have high base
+                * address bits set (devices can only access the first
+                * 32 bits of the memory).
+                */
+               if ((size & DDR_SIZE_ENABLED) &&
+                   !(base & DDR_BASE_CS_HIGH_MASK)) {
+                       struct mbus_dram_window *w;
+
+                       w = &mvebu_mbus_dram_info.cs[cs++];
+                       w->cs_index = i;
+                       w->mbus_attr = 0xf & ~(1 << i);
+                       if (mbus->hw_io_coherency)
+                               w->mbus_attr |= ATTR_HW_COHERENCY;
+                       w->base = base & DDR_BASE_CS_LOW_MASK;
+                       w->size = (size | ~DDR_SIZE_MASK) + 1;
+               }
+       }
+       mvebu_mbus_dram_info.num_cs = cs;
+}
+
+static void __init
+mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
+{
+       int i;
+       int cs;
+
+       mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+       for (i = 0, cs = 0; i < 2; i++) {
+               u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
+
+               /*
+                * Chip select enabled?
+                */
+               if (map & 1) {
+                       struct mbus_dram_window *w;
+
+                       w = &mvebu_mbus_dram_info.cs[cs++];
+                       w->cs_index = i;
+                       w->mbus_attr = 0; /* CS address decoding done inside */
+                                         /* the DDR controller, no need to  */
+                                         /* provide attributes */
+                       w->base = map & 0xff800000;
+                       w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
+               }
+       }
+
+       mvebu_mbus_dram_info.num_cs = cs;
+}
+
+static const struct mvebu_mbus_mapping armada_370_map[] = {
+       MAPDEF("bootrom",     1, 0xe0, MAPDEF_NOMASK),
+       MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs0",  1, 0x3e, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs1",  1, 0x3d, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs2",  1, 0x3b, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs3",  1, 0x37, MAPDEF_NOMASK),
+       MAPDEF("pcie0.0",     4, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.0",     8, 0xe0, MAPDEF_PCIMASK),
+       {},
+};
+
+static const struct mvebu_mbus_soc_data armada_370_mbus_data = {
+       .num_wins            = 20,
+       .num_remappable_wins = 8,
+       .win_cfg_offset      = armada_370_xp_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+       .show_cpu_target     = mvebu_sdram_debug_show_orion,
+       .map                 = armada_370_map,
+};
+
+static const struct mvebu_mbus_mapping armada_xp_map[] = {
+       MAPDEF("bootrom",     1, 0x1d, MAPDEF_NOMASK),
+       MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs0",  1, 0x3e, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs1",  1, 0x3d, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs2",  1, 0x3b, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs3",  1, 0x37, MAPDEF_NOMASK),
+       MAPDEF("pcie0.0",     4, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("pcie0.1",     4, 0xd0, MAPDEF_PCIMASK),
+       MAPDEF("pcie0.2",     4, 0xb0, MAPDEF_PCIMASK),
+       MAPDEF("pcie0.3",     4, 0x70, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.0",     8, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.1",     8, 0xd0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.2",     8, 0xb0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.3",     8, 0x70, MAPDEF_PCIMASK),
+       MAPDEF("pcie2.0",     4, 0xf0, MAPDEF_PCIMASK),
+       MAPDEF("pcie3.0",     8, 0xf0, MAPDEF_PCIMASK),
+       {},
+};
+
+static const struct mvebu_mbus_soc_data armada_xp_mbus_data = {
+       .num_wins            = 20,
+       .num_remappable_wins = 8,
+       .win_cfg_offset      = armada_370_xp_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+       .show_cpu_target     = mvebu_sdram_debug_show_orion,
+       .map                 = armada_xp_map,
+};
+
+static const struct mvebu_mbus_mapping kirkwood_map[] = {
+       MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.0", 4, 0xd0, MAPDEF_PCIMASK),
+       MAPDEF("sram",    3, 0x01, MAPDEF_NOMASK),
+       MAPDEF("nand",    1, 0x2f, MAPDEF_NOMASK),
+       {},
+};
+
+static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
+       .num_wins            = 8,
+       .num_remappable_wins = 4,
+       .win_cfg_offset      = orion_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+       .show_cpu_target     = mvebu_sdram_debug_show_orion,
+       .map                 = kirkwood_map,
+};
+
+static const struct mvebu_mbus_mapping dove_map[] = {
+       MAPDEF("pcie0.0",    0x4, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.0",    0x8, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("cesa",       0x3, 0x01, MAPDEF_NOMASK),
+       MAPDEF("bootrom",    0x1, 0xfd, MAPDEF_NOMASK),
+       MAPDEF("scratchpad", 0xd, 0x0, MAPDEF_NOMASK),
+       {},
+};
+
+static const struct mvebu_mbus_soc_data dove_mbus_data = {
+       .num_wins            = 8,
+       .num_remappable_wins = 4,
+       .win_cfg_offset      = orion_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_dove_setup_cpu_target,
+       .show_cpu_target     = mvebu_sdram_debug_show_dove,
+       .map                 = dove_map,
+};
+
+static const struct mvebu_mbus_mapping orion5x_map[] = {
+       MAPDEF("pcie0.0",     4, 0x51, MAPDEF_ORIONPCIMASK),
+       MAPDEF("pci0.0",      3, 0x51, MAPDEF_ORIONPCIMASK),
+       MAPDEF("devbus-boot", 1, 0x0f, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs0",  1, 0x1e, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs1",  1, 0x1d, MAPDEF_NOMASK),
+       MAPDEF("devbus-cs2",  1, 0x1b, MAPDEF_NOMASK),
+       MAPDEF("sram",        0, 0x00, MAPDEF_NOMASK),
+       {},
+};
+
+/*
+ * Some variants of Orion5x have 4 remappable windows, some other have
+ * only two of them.
+ */
+static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = {
+       .num_wins            = 8,
+       .num_remappable_wins = 4,
+       .win_cfg_offset      = orion_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+       .show_cpu_target     = mvebu_sdram_debug_show_orion,
+       .map                 = orion5x_map,
+};
+
+static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
+       .num_wins            = 8,
+       .num_remappable_wins = 2,
+       .win_cfg_offset      = orion_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+       .show_cpu_target     = mvebu_sdram_debug_show_orion,
+       .map                 = orion5x_map,
+};
+
+static const struct mvebu_mbus_mapping mv78xx0_map[] = {
+       MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
+       MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
+       MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
+       MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
+       MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
+       MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
+       {},
+};
+
+static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
+       .num_wins            = 14,
+       .num_remappable_wins = 8,
+       .win_cfg_offset      = mv78xx0_mbus_win_offset,
+       .setup_cpu_target    = mvebu_mbus_default_setup_cpu_target,
+       .show_cpu_target     = mvebu_sdram_debug_show_orion,
+       .map                 = mv78xx0_map,
+};
+
+/*
+ * The driver doesn't yet have a DT binding because the details of
+ * this DT binding still need to be sorted out. However, as a
+ * preparation, we already use of_device_id to match a SoC description
+ * string against the SoC specific details of this driver.
+ */
+static const struct of_device_id of_mvebu_mbus_ids[] = {
+       { .compatible = "marvell,armada370-mbus",
+         .data = &armada_370_mbus_data, },
+       { .compatible = "marvell,armadaxp-mbus",
+         .data = &armada_xp_mbus_data, },
+       { .compatible = "marvell,kirkwood-mbus",
+         .data = &kirkwood_mbus_data, },
+       { .compatible = "marvell,dove-mbus",
+         .data = &dove_mbus_data, },
+       { .compatible = "marvell,orion5x-88f5281-mbus",
+         .data = &orion5x_4win_mbus_data, },
+       { .compatible = "marvell,orion5x-88f5182-mbus",
+         .data = &orion5x_2win_mbus_data, },
+       { .compatible = "marvell,orion5x-88f5181-mbus",
+         .data = &orion5x_2win_mbus_data, },
+       { .compatible = "marvell,orion5x-88f6183-mbus",
+         .data = &orion5x_4win_mbus_data, },
+       { .compatible = "marvell,mv78xx0-mbus",
+         .data = &mv78xx0_mbus_data, },
+       { },
+};
+
+/*
+ * Public API of the driver
+ */
+int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
+                                     size_t size, phys_addr_t remap,
+                                     unsigned int flags)
+{
+       struct mvebu_mbus_state *s = &mbus_state;
+       u8 target, attr;
+       int i;
+
+       if (!s->soc->map)
+               return -ENODEV;
+
+       for (i = 0; s->soc->map[i].name; i++)
+               if (!strcmp(s->soc->map[i].name, devname))
+                       break;
+
+       if (!s->soc->map[i].name) {
+               pr_err("mvebu-mbus: unknown device '%s'\n", devname);
+               return -ENODEV;
+       }
+
+       target = s->soc->map[i].target;
+       attr   = s->soc->map[i].attr;
+
+       if (flags == MVEBU_MBUS_PCI_MEM)
+               attr |= 0x8;
+       else if (flags == MVEBU_MBUS_PCI_WA)
+               attr |= 0x28;
+
+       if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
+               pr_err("mvebu-mbus: cannot add window '%s', conflicts with another window\n",
+                      devname);
+               return -EINVAL;
+       }
+
+       return mvebu_mbus_alloc_window(s, base, size, remap, target, attr);
+
+}
+
+int mvebu_mbus_add_window(const char *devname, phys_addr_t base, size_t size)
+{
+       return mvebu_mbus_add_window_remap_flags(devname, base, size,
+                                                MVEBU_MBUS_NO_REMAP, 0);
+}
+
+int mvebu_mbus_del_window(phys_addr_t base, size_t size)
+{
+       int win;
+
+       win = mvebu_mbus_find_window(&mbus_state, base, size);
+       if (win < 0)
+               return win;
+
+       mvebu_mbus_disable_window(&mbus_state, win);
+       return 0;
+}
+
+static __init int mvebu_mbus_debugfs_init(void)
+{
+       struct mvebu_mbus_state *s = &mbus_state;
+
+       /*
+        * If no base has been initialized, doesn't make sense to
+        * register the debugfs entries. We may be on a multiplatform
+        * kernel that isn't running a Marvell EBU SoC.
+        */
+       if (!s->mbuswins_base)
+               return 0;
+
+       s->debugfs_root = debugfs_create_dir("mvebu-mbus", NULL);
+       if (s->debugfs_root) {
+               s->debugfs_sdram = debugfs_create_file("sdram", S_IRUGO,
+                                                      s->debugfs_root, NULL,
+                                                      &mvebu_sdram_debug_fops);
+               s->debugfs_devs = debugfs_create_file("devices", S_IRUGO,
+                                                     s->debugfs_root, NULL,
+                                                     &mvebu_devs_debug_fops);
+       }
+
+       return 0;
+}
+fs_initcall(mvebu_mbus_debugfs_init);
+
+int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
+                          size_t mbuswins_size,
+                          phys_addr_t sdramwins_phys_base,
+                          size_t sdramwins_size)
+{
+       struct mvebu_mbus_state *mbus = &mbus_state;
+       const struct of_device_id *of_id;
+       int win;
+
+       for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++)
+               if (!strcmp(of_id->compatible, soc))
+                       break;
+
+       if (!of_id->compatible) {
+               pr_err("mvebu-mbus: could not find a matching SoC family\n");
+               return -ENODEV;
+       }
+
+       mbus->soc = of_id->data;
+
+       mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size);
+       if (!mbus->mbuswins_base)
+               return -ENOMEM;
+
+       mbus->sdramwins_base = ioremap(sdramwins_phys_base, sdramwins_size);
+       if (!mbus->sdramwins_base) {
+               iounmap(mbus_state.mbuswins_base);
+               return -ENOMEM;
+       }
+
+       if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
+               mbus->hw_io_coherency = 1;
+
+       for (win = 0; win < mbus->soc->num_wins; win++)
+               mvebu_mbus_disable_window(mbus, win);
+
+       mbus->soc->setup_cpu_target(mbus);
+
+       return 0;
+}
index 62dcdcdec94058d2fcb5faeb408690af810d417f..791a6719d8a9d0b551b70e3532433efc3c60e97f 100644 (file)
@@ -2552,7 +2552,7 @@ static const char * const intc_groups[] = {
        "intc_irq2",
        "intc_irq2_b",
        "intc_irq3",
-       "intc_irq4_b",
+       "intc_irq3_b",
 };
 
 static const char * const lbsc_groups[] = {
index 0880ef1a01baa4ab4a355302d05fde8c65ca7aae..0127601c26c7ff6b7a50ebd72d034c444ef434e4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/reset.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/spinlock.h>
@@ -661,7 +662,7 @@ int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
 }
 EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel);
 
-static int ipu_reset(struct ipu_soc *ipu)
+static int ipu_memory_reset(struct ipu_soc *ipu)
 {
        unsigned long timeout;
 
@@ -1105,7 +1106,12 @@ static int ipu_probe(struct platform_device *pdev)
        if (ret)
                goto out_failed_irq;
 
-       ret = ipu_reset(ipu);
+       ret = device_reset(&pdev->dev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to reset: %d\n", ret);
+               goto out_failed_reset;
+       }
+       ret = ipu_memory_reset(ipu);
        if (ret)
                goto out_failed_reset;
 
@@ -1131,8 +1137,8 @@ static int ipu_probe(struct platform_device *pdev)
 failed_add_clients:
        ipu_submodules_exit(ipu);
 failed_submodules_init:
-       ipu_irq_exit(ipu);
 out_failed_reset:
+       ipu_irq_exit(ipu);
 out_failed_irq:
        clk_disable_unprepare(ipu->clk);
 failed_clk_get:
index efa1a6d7aca8dabca57ee2df75d69e10173f8d81..dba482e31a130e2e29690bf0c63e36b1e88e6aa8 100644 (file)
@@ -32,6 +32,20 @@ struct mbus_dram_target_info
        } cs[4];
 };
 
+/* Flags for PCI/PCIe address decoding regions */
+#define MVEBU_MBUS_PCI_IO  0x1
+#define MVEBU_MBUS_PCI_MEM 0x2
+#define MVEBU_MBUS_PCI_WA  0x3
+
+/*
+ * Magic value that explicits that we don't need a remapping-capable
+ * address decoding window.
+ */
+#define MVEBU_MBUS_NO_REMAP (0xffffffff)
+
+/* Maximum size of a mbus window name */
+#define MVEBU_MBUS_MAX_WINNAME_SZ 32
+
 /*
  * The Marvell mbus is to be found only on SOCs from the Orion family
  * at the moment.  Provide a dummy stub for other architectures.
@@ -44,4 +58,15 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void)
        return NULL;
 }
 #endif
-#endif
+
+int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
+                                     size_t size, phys_addr_t remap,
+                                     unsigned int flags);
+int mvebu_mbus_add_window(const char *devname, phys_addr_t base,
+                         size_t size);
+int mvebu_mbus_del_window(phys_addr_t base, size_t size);
+int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base,
+                   size_t mbus_size, phys_addr_t sdram_phys_base,
+                   size_t sdram_size);
+
+#endif /* __LINUX_MBUS_H */