From 9ab403d0dd3c88370612c97f8c4cb88199302833 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:16 +0100 Subject: bmips: bcm6338: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6338.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi index bbd58cf803..990355481c 100644 --- a/arch/mips/dts/brcm,bcm6338.dtsi +++ b/arch/mips/dts/brcm,bcm6338.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include "skeleton.dtsi" @@ -130,5 +131,18 @@ reg = <0xfffe3100 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@fffe2400 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe2400 0x1c>, + <0xfffe2500 0x60>, + <0xfffe2600 0x60>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <6>; + resets = <&periph_rst BCM6338_RST_DMAMEM>; + }; }; }; -- cgit From c225d6619e440c5e701f0b1317c89c54eaf79bce Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:17 +0100 Subject: bmips: bcm6348: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6348.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi index cc80bbc808..875de232ca 100644 --- a/arch/mips/dts/brcm,bcm6348.dtsi +++ b/arch/mips/dts/brcm,bcm6348.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include "skeleton.dtsi" @@ -159,5 +160,20 @@ reg = <0xfffe2300 0x38>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@fffe7000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe7000 0x1c>, + <0xfffe7100 0x40>, + <0xfffe7200 0x40>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&periph_clk BCM6348_CLK_ENET>; + resets = <&periph_rst BCM6348_RST_ENET>, + <&periph_rst BCM6348_RST_DMAMEM>; + }; }; }; -- cgit From 487250e6dfa3be57ef3d49ab04ab82d841d838a1 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:18 +0100 Subject: bmips: bcm6358: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6358.dtsi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi index 0617b46e92..5605723e83 100644 --- a/arch/mips/dts/brcm,bcm6358.dtsi +++ b/arch/mips/dts/brcm,bcm6358.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include "skeleton.dtsi" @@ -190,5 +191,22 @@ status = "disabled"; }; + + iudma: dma-controller@fffe5000 { + compatible = "brcm,bcm6348-iudma"; + reg = <0xfffe5000 0x24>, + <0xfffe5100 0x80>, + <0xfffe5200 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + clocks = <&periph_clk BCM6358_CLK_EMUSB>, + <&periph_clk BCM6358_CLK_USBSU>, + <&periph_clk BCM6358_CLK_EPHY>; + resets = <&periph_rst BCM6358_RST_ENET>, + <&periph_rst BCM6358_RST_EPHY>; + }; }; }; -- cgit From 0417eb55907344192fbc5d59b72e033838b29c06 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:19 +0100 Subject: bmips: bcm6368: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6368.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi index 65d769ab4f..30047f6360 100644 --- a/arch/mips/dts/brcm,bcm6368.dtsi +++ b/arch/mips/dts/brcm,bcm6368.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include "skeleton.dtsi" @@ -192,5 +193,17 @@ status = "disabled"; }; + + iudma: dma-controller@10006800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x10006800 0x80>, + <0x10006a00 0x80>, + <0x10006c00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; }; }; -- cgit From 85132221e2722089e04dd3842d23510c7c3b7fce Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:20 +0100 Subject: bmips: bcm6328: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6328.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi index e00a2950e2..6fa49e22bb 100644 --- a/arch/mips/dts/brcm,bcm6328.dtsi +++ b/arch/mips/dts/brcm,bcm6328.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -187,5 +188,17 @@ reg = <0x10003000 0x864>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@1000d800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x1000d800 0x80>, + <0x1000da00 0x80>, + <0x1000dc00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; }; }; -- cgit From b2bf5a22435926b406f0f76fcf199854965af994 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:21 +0100 Subject: bmips: bcm6362: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6362.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi index 3047b82b21..94e7de096d 100644 --- a/arch/mips/dts/brcm,bcm6362.dtsi +++ b/arch/mips/dts/brcm,bcm6362.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -211,5 +212,17 @@ reg = <0x10003000 0x864>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@1000d800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x1000d800 0x80>, + <0x1000da00 0x80>, + <0x1000dc00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; }; }; -- cgit From 83eae024623ef6a7d3c483c2fa7eea301bc72fb5 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:22 +0100 Subject: bmips: bcm63268: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm63268.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi index 62c440e675..c7ad83c306 100644 --- a/arch/mips/dts/brcm,bcm63268.dtsi +++ b/arch/mips/dts/brcm,bcm63268.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -217,5 +218,17 @@ reg = <0x10003000 0x894>; u-boot,dm-pre-reloc; }; + + iudma: dma-controller@1000d800 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x1000d800 0x80>, + <0x1000da00 0x80>, + <0x1000dc00 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; }; }; -- cgit From 6e0faa22dd394d42221d4dc0ad2975466d08eb21 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:23 +0100 Subject: bmips: bcm6318: add bcm6348-iudma support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi index f75988be12..d04b7cbb01 100644 --- a/arch/mips/dts/brcm,bcm6318.dtsi +++ b/arch/mips/dts/brcm,bcm6318.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -54,6 +55,12 @@ reg = <0x10000004 0x4>; #clock-cells = <1>; }; + + ubus_clk: ubus-clk { + compatible = "brcm,bcm6345-clk"; + reg = <0x10000008 0x4>; + #clock-cells = <1>; + }; }; ubus { @@ -182,5 +189,17 @@ status = "disabled"; }; + + iudma: dma-controller@10088000 { + compatible = "brcm,bcm6368-iudma"; + reg = <0x10088000 0x80>, + <0x10088200 0x80>, + <0x10088400 0x80>; + reg-names = "dma", + "dma-channels", + "dma-sram"; + #dma-cells = <1>; + dma-channels = <8>; + }; }; }; -- cgit From d7f5bc1aea26823b81d0ea1a6eb1481b5a25b9ed Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:25 +0100 Subject: bmips: bcm6338: add support for bcm6348-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6338.dtsi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6338.dtsi b/arch/mips/dts/brcm,bcm6338.dtsi index 990355481c..c547e949dd 100644 --- a/arch/mips/dts/brcm,bcm6338.dtsi +++ b/arch/mips/dts/brcm,bcm6338.dtsi @@ -144,5 +144,20 @@ dma-channels = <6>; resets = <&periph_rst BCM6338_RST_DMAMEM>; }; + + enet: ethernet@fffe2800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe2800 0x2dc>; + clocks = <&periph_clk BCM6338_CLK_ENET>; + resets = <&periph_rst BCM6338_RST_ENET>; + dmas = <&iudma BCM6338_DMA_ENET_RX>, + <&iudma BCM6338_DMA_ENET_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; }; }; -- cgit From ec96de3b66f059ae2d7abe572985f7e275a6284c Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:26 +0100 Subject: bmips: enable f@st1704 enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/sagem,f@st1704.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/sagem,f@st1704.dts b/arch/mips/dts/sagem,f@st1704.dts index 5300f8b6df..ec6846dd9f 100644 --- a/arch/mips/dts/sagem,f@st1704.dts +++ b/arch/mips/dts/sagem,f@st1704.dts @@ -39,6 +39,18 @@ }; }; +&enet { + status = "okay"; + phy = <&enetphy>; + phy-mode = "mii"; + + enetphy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio { status = "okay"; }; -- cgit From 9dc07b9493f1c340b3509dada8a4d26e8a96866c Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:27 +0100 Subject: bmips: bcm6348: add support for bcm6348-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6348.dtsi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6348.dtsi b/arch/mips/dts/brcm,bcm6348.dtsi index 875de232ca..79e7bd892b 100644 --- a/arch/mips/dts/brcm,bcm6348.dtsi +++ b/arch/mips/dts/brcm,bcm6348.dtsi @@ -161,6 +161,32 @@ u-boot,dm-pre-reloc; }; + enet0: ethernet@fffe6000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6000 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET0_RX>, + <&iudma BCM6348_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet@fffe6800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe6800 0x2dc>; + dmas = <&iudma BCM6348_DMA_ENET1_RX>, + <&iudma BCM6348_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller@fffe7000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe7000 0x1c>, -- cgit From eb4bdc7cc238f48313cc5554ad6515b314b7d101 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:28 +0100 Subject: bmips: enable ct-5361 enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/comtrend,ct-5361.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/comtrend,ct-5361.dts b/arch/mips/dts/comtrend,ct-5361.dts index 25747ca95d..f6b8a94e25 100644 --- a/arch/mips/dts/comtrend,ct-5361.dts +++ b/arch/mips/dts/comtrend,ct-5361.dts @@ -34,6 +34,18 @@ }; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; }; -- cgit From 4f88720e6aa27e74e8e3becd4216f332f12da57f Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:29 +0100 Subject: bmips: bcm6358: add support for bcm6348-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6358.dtsi | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6358.dtsi b/arch/mips/dts/brcm,bcm6358.dtsi index 5605723e83..5e9c9ad769 100644 --- a/arch/mips/dts/brcm,bcm6358.dtsi +++ b/arch/mips/dts/brcm,bcm6358.dtsi @@ -192,6 +192,34 @@ status = "disabled"; }; + enet0: ethernet@fffe4000 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4000 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET0>; + dmas = <&iudma BCM6358_DMA_ENET0_RX>, + <&iudma BCM6358_DMA_ENET0_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + + enet1: ethernet@fffe4800 { + compatible = "brcm,bcm6348-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xfffe4800 0x2dc>; + clocks = <&periph_clk BCM6358_CLK_ENET1>; + dmas = <&iudma BCM6358_DMA_ENET1_RX>, + <&iudma BCM6358_DMA_ENET1_TX>; + dma-names = "rx", + "tx"; + + status = "disabled"; + }; + iudma: dma-controller@fffe5000 { compatible = "brcm,bcm6348-iudma"; reg = <0xfffe5000 0x24>, -- cgit From 15591a9ae1215e6259059c09351bf9e7ad5a3ab7 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:30 +0100 Subject: bmips: enable hg556a enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/huawei,hg556a.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/huawei,hg556a.dts b/arch/mips/dts/huawei,hg556a.dts index 60455c2ff8..6a7fc1df4b 100644 --- a/arch/mips/dts/huawei,hg556a.dts +++ b/arch/mips/dts/huawei,hg556a.dts @@ -93,6 +93,18 @@ status = "okay"; }; +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; }; -- cgit From 9c0c7e8487b7b37d8b30aa790cbc5314011b2796 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:31 +0100 Subject: bmips: enable nb4-ser enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/sfr,nb4-ser.dts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/sfr,nb4-ser.dts b/arch/mips/dts/sfr,nb4-ser.dts index bdc6f8ae45..dfbc4148dc 100644 --- a/arch/mips/dts/sfr,nb4-ser.dts +++ b/arch/mips/dts/sfr,nb4-ser.dts @@ -53,6 +53,30 @@ status = "okay"; }; +&enet0 { + status = "okay"; + phy = <&enet0phy>; + phy-mode = "internal"; + + enet0phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + +&enet1 { + status = "okay"; + phy = <&enet1phy>; + phy-mode = "mii"; + + enet1phy: fixed-link { + reg = <1>; + speed = <100>; + full-duplex; + }; +}; + &gpio0 { status = "okay"; }; -- cgit From d9c1f0c23f16341916fe8797472cb37e9bdbabe9 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:33 +0100 Subject: bmips: bcm6368: add support for bcm6368-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6368.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6368.dtsi b/arch/mips/dts/brcm,bcm6368.dtsi index 30047f6360..89590d6ff9 100644 --- a/arch/mips/dts/brcm,bcm6368.dtsi +++ b/arch/mips/dts/brcm,bcm6368.dtsi @@ -205,5 +205,24 @@ #dma-cells = <1>; dma-channels = <8>; }; + + enet: ethernet@10f00000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10f00000 0x10000>; + clocks = <&periph_clk BCM6368_CLK_SWPKT_USB>, + <&periph_clk BCM6368_CLK_SWPKT_SAR>, + <&periph_clk BCM6368_CLK_ROBOSW>; + resets = <&periph_rst BCM6368_RST_SWITCH>, + <&periph_rst BCM6368_RST_EPHY>; + dmas = <&iudma BCM6368_DMA_ENETSW_RX>, + <&iudma BCM6368_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <6>; + + status = "disabled"; + }; }; }; -- cgit From 2e498f23ac298133173876afefea8cbf85721f4e Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:34 +0100 Subject: bmips: enable wap-5813n enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/comtrend,wap-5813n.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/comtrend,wap-5813n.dts b/arch/mips/dts/comtrend,wap-5813n.dts index bd41dab9f8..7e835b28d2 100644 --- a/arch/mips/dts/comtrend,wap-5813n.dts +++ b/arch/mips/dts/comtrend,wap-5813n.dts @@ -54,6 +54,20 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@4 { + compatible = "brcm,enetsw-port"; + reg = <4>; + label = "rgmii"; + brcm,phy-id = <0xff>; + speed = <1000>; + full-duplex; + bypass-link; + }; +}; + &gpio0 { status = "okay"; }; -- cgit From 45934ed8460e99e2a83c7d8f329fcfa6d8f39904 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:35 +0100 Subject: bmips: bcm6328: add support for bcm6368-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6328.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6328.dtsi b/arch/mips/dts/brcm,bcm6328.dtsi index 6fa49e22bb..50beed4171 100644 --- a/arch/mips/dts/brcm,bcm6328.dtsi +++ b/arch/mips/dts/brcm,bcm6328.dtsi @@ -200,5 +200,22 @@ #dma-cells = <1>; dma-channels = <8>; }; + + enet: ethernet@10e00000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10e00000 0x10000>; + clocks = <&periph_clk BCM6328_CLK_ROBOSW>; + resets = <&periph_rst BCM6328_RST_ENETSW>, + <&periph_rst BCM6328_RST_EPHY>; + dmas = <&iudma BCM6328_DMA_ENETSW_RX>, + <&iudma BCM6328_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <5>; + + status = "disabled"; + }; }; }; -- cgit From 54468f5853bb61a5e836a063f9aecc0469ba9033 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:36 +0100 Subject: bmips: enable ar-5387un enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/comtrend,ar-5387un.dts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts index e993b5cd89..03e3851ab1 100644 --- a/arch/mips/dts/comtrend,ar-5387un.dts +++ b/arch/mips/dts/comtrend,ar-5387un.dts @@ -24,6 +24,38 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@0 { + compatible = "brcm,enetsw-port"; + reg = <0>; + label = "fe1"; + brcm,phy-id = <1>; + }; + + port@1 { + compatible = "brcm,enetsw-port"; + reg = <1>; + label = "fe2"; + brcm,phy-id = <2>; + }; + + port@2 { + compatible = "brcm,enetsw-port"; + reg = <2>; + label = "fe3"; + brcm,phy-id = <3>; + }; + + port@3 { + compatible = "brcm,enetsw-port"; + reg = <3>; + label = "fe4"; + brcm,phy-id = <4>; + }; +}; + &leds { status = "okay"; -- cgit From 4518a24c290ae93b2d18282ae65423cf2acc2ff6 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:37 +0100 Subject: bmips: bcm6362: add support for bcm6368-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6362.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6362.dtsi b/arch/mips/dts/brcm,bcm6362.dtsi index 94e7de096d..c77b80a4cc 100644 --- a/arch/mips/dts/brcm,bcm6362.dtsi +++ b/arch/mips/dts/brcm,bcm6362.dtsi @@ -224,5 +224,24 @@ #dma-cells = <1>; dma-channels = <8>; }; + + enet: ethernet@10e00000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10e00000 0x10000>; + clocks = <&periph_clk BCM6362_CLK_SWPKT_USB>, + <&periph_clk BCM6362_CLK_SWPKT_SAR>, + <&periph_clk BCM6362_CLK_ROBOSW>; + resets = <&periph_rst BCM6362_RST_ENETSW>, + <&periph_rst BCM6362_RST_EPHY>; + dmas = <&iudma BCM6362_DMA_ENETSW_RX>, + <&iudma BCM6362_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <6>; + + status = "disabled"; + }; }; }; -- cgit From ba329fd1f2c7d411cdf1e83bdbaf2c878a02ba79 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:38 +0100 Subject: bmips: enable dgnd3700v2 enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/netgear,dgnd3700v2.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/netgear,dgnd3700v2.dts b/arch/mips/dts/netgear,dgnd3700v2.dts index 322d1567ff..2b72491f0b 100644 --- a/arch/mips/dts/netgear,dgnd3700v2.dts +++ b/arch/mips/dts/netgear,dgnd3700v2.dts @@ -43,6 +43,20 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@4 { + compatible = "brcm,enetsw-port"; + reg = <4>; + label = "rgmii"; + brcm,phy-id = <0xff>; + speed = <1000>; + full-duplex; + bypass-link; + }; +}; + &gpio0 { status = "okay"; }; -- cgit From b07f2dc6a055ef4f1486c97c0cffd992fb2ba8a5 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:39 +0100 Subject: bmips: bcm63268: add support for bcm6368-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm63268.dtsi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm63268.dtsi b/arch/mips/dts/brcm,bcm63268.dtsi index c7ad83c306..f8a72ef535 100644 --- a/arch/mips/dts/brcm,bcm63268.dtsi +++ b/arch/mips/dts/brcm,bcm63268.dtsi @@ -230,5 +230,30 @@ #dma-cells = <1>; dma-channels = <8>; }; + + enet: ethernet@10700000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10700000 0x10000>; + clocks = <&periph_clk BCM63268_CLK_GMAC>, + <&periph_clk BCM63268_CLK_ROBOSW>, + <&periph_clk BCM63268_CLK_ROBOSW250>, + <&timer_clk BCM63268_TCLK_EPHY1>, + <&timer_clk BCM63268_TCLK_EPHY2>, + <&timer_clk BCM63268_TCLK_EPHY3>, + <&timer_clk BCM63268_TCLK_GPHY>; + resets = <&periph_rst BCM63268_RST_ENETSW>, + <&periph_rst BCM63268_RST_EPHY>, + <&periph_rst BCM63268_RST_GPHY>; + dmas = <&iudma BCM63268_DMA_ENETSW_RX>, + <&iudma BCM63268_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,rgmii-override; + brcm,rgmii-timing; + + status = "disabled"; + }; }; }; -- cgit From 173e3aec81641dc7913f98fff9673b003918257f Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:40 +0100 Subject: bmips: enable vr-3032u enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/comtrend,vr-3032u.dts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/comtrend,vr-3032u.dts b/arch/mips/dts/comtrend,vr-3032u.dts index 8c6a4a1eac..512cb52de3 100644 --- a/arch/mips/dts/comtrend,vr-3032u.dts +++ b/arch/mips/dts/comtrend,vr-3032u.dts @@ -24,6 +24,38 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@0 { + compatible = "brcm,enetsw-port"; + reg = <0>; + label = "fe2"; + brcm,phy-id = <1>; + }; + + port@1 { + compatible = "brcm,enetsw-port"; + reg = <1>; + label = "fe3"; + brcm,phy-id = <2>; + }; + + port@2 { + compatible = "brcm,enetsw-port"; + reg = <2>; + label = "fe4"; + brcm,phy-id = <3>; + }; + + port@3 { + compatible = "brcm,enetsw-port"; + reg = <3>; + label = "fe1"; + brcm,phy-id = <4>; + }; +}; + &leds { status = "okay"; brcm,serial-leds; -- cgit From 93bd64bf0551e51d96cd25e107ca6589372d4377 Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:41 +0100 Subject: bmips: bcm6318: add support for bcm6368-enet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/brcm,bcm6318.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/brcm,bcm6318.dtsi b/arch/mips/dts/brcm,bcm6318.dtsi index d04b7cbb01..d678dab242 100644 --- a/arch/mips/dts/brcm,bcm6318.dtsi +++ b/arch/mips/dts/brcm,bcm6318.dtsi @@ -190,6 +190,25 @@ status = "disabled"; }; + enet: ethernet@10080000 { + compatible = "brcm,bcm6368-enet"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10080000 0x8000>; + clocks = <&periph_clk BCM6318_CLK_ROBOSW250>, + <&periph_clk BCM6318_CLK_ROBOSW025>, + <&ubus_clk BCM6318_UCLK_ROBOSW>; + resets = <&periph_rst BCM6318_RST_ENETSW>, + <&periph_rst BCM6318_RST_EPHY>; + dmas = <&iudma BCM6318_DMA_ENETSW_RX>, + <&iudma BCM6318_DMA_ENETSW_TX>; + dma-names = "rx", + "tx"; + brcm,num-ports = <5>; + + status = "disabled"; + }; + iudma: dma-controller@10088000 { compatible = "brcm,bcm6368-iudma"; reg = <0x10088000 0x80>, -- cgit From a4bfa0e969b82a2efd76784887dc9f790f055d6c Mon Sep 17 00:00:00 2001 From: Álvaro Fernández Rojas Date: Sat, 1 Dec 2018 19:00:42 +0100 Subject: bmips: enable ar-5315u enet support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Fernández Rojas --- arch/mips/dts/comtrend,ar-5315u.dts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'arch') diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts index 45570189d0..eb60aaa8d5 100644 --- a/arch/mips/dts/comtrend,ar-5315u.dts +++ b/arch/mips/dts/comtrend,ar-5315u.dts @@ -24,6 +24,38 @@ status = "okay"; }; +&enet { + status = "okay"; + + port@0 { + compatible = "brcm,enetsw-port"; + reg = <0>; + label = "fe4"; + brcm,phy-id = <1>; + }; + + port@1 { + compatible = "brcm,enetsw-port"; + reg = <1>; + label = "fe3"; + brcm,phy-id = <2>; + }; + + port@2 { + compatible = "brcm,enetsw-port"; + reg = <2>; + label = "fe2"; + brcm,phy-id = <3>; + }; + + port@3 { + compatible = "brcm,enetsw-port"; + reg = <3>; + label = "fe1"; + brcm,phy-id = <4>; + }; +}; + &leds { status = "okay"; -- cgit From d2f02586fdd43b7a8aed9ce305599a478cfde3b0 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 15 Dec 2018 19:05:08 +0100 Subject: mips: ath79: fix DTC warnings Remove all interrupt nodes that cause warnings regarding a missing interrupt parent. There are no interrupt controller nodes defined and the device trees don't match the ones in Linux anymore. Signed-off-by: Daniel Schwierzeck --- arch/mips/dts/ar933x.dtsi | 3 --- arch/mips/dts/qca953x.dtsi | 3 --- 2 files changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/dts/ar933x.dtsi b/arch/mips/dts/ar933x.dtsi index 85fb14b13b..37354324fe 100644 --- a/arch/mips/dts/ar933x.dtsi +++ b/arch/mips/dts/ar933x.dtsi @@ -3,7 +3,6 @@ * Copyright (C) 2015-2016 Wills Wang */ -#include #include "skeleton.dtsi" / { @@ -68,7 +67,6 @@ uart0: uart@18020000 { compatible = "qca,ar9330-uart"; reg = <0x18020000 0x20>; - interrupts = <128 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -103,7 +101,6 @@ spi0: spi@1f000000 { compatible = "qca,ar7100-spi"; reg = <0x1f000000 0x10>; - interrupts = <129 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; diff --git a/arch/mips/dts/qca953x.dtsi b/arch/mips/dts/qca953x.dtsi index 599e809c47..ba29ea287e 100644 --- a/arch/mips/dts/qca953x.dtsi +++ b/arch/mips/dts/qca953x.dtsi @@ -3,7 +3,6 @@ * Copyright (C) 2015-2016 Wills Wang */ -#include #include "skeleton.dtsi" / { @@ -63,7 +62,6 @@ reg = <0x18020000 0x20>; reg-shift = <2>; clock-frequency = <25000000>; - interrupts = <128 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -72,7 +70,6 @@ spi0: spi@1f000000 { compatible = "qca,ar7100-spi"; reg = <0x1f000000 0x10>; - interrupts = <129 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; -- cgit From 8da7495299230fb77d354ad507c5216f46d1dd37 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sat, 15 Dec 2018 19:19:33 +0100 Subject: mips: xilfpga: fix DTC warnings This fixes following DTC warning: arch/mips/dts/nexys4ddr.dtb: Warning (compatible_is_string_list): /ethernet@10e00000/mdio/phy@1:compatible: property is not a string list As upstream DTS in Linux doesn't have the offending property, simply remove it to fix the warning. Signed-off-by: Daniel Schwierzeck --- arch/mips/dts/nexys4ddr.dts | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/dts/nexys4ddr.dts b/arch/mips/dts/nexys4ddr.dts index e254ab1eaa..6de8584ea7 100644 --- a/arch/mips/dts/nexys4ddr.dts +++ b/arch/mips/dts/nexys4ddr.dts @@ -40,7 +40,6 @@ #address-cells = <1>; #size-cells = <0>; phy0: phy@1 { - compatible = <0x0007c0f0 0xfffffff0>; device_type = "ethernet-phy"; reg = <1>; } ; -- cgit From a5f50e0114f9fd39c16e416aad2aa292aaaaacd6 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 18 Dec 2018 10:27:14 +0100 Subject: mips: mt76xx: Flush d-cache in arch_misc_init() to solve d-cache issues It has been noticed, that sometimes the d-cache is not in a "clean-state" when U-Boot is running on MT7688. This was detected when using the ethernet driver (which uses d-cache) and a TFTP command does not complete. Flushing the complete d-cache (again?) here seems to fix this issue. Signed-off-by: Stefan Roese Cc: Daniel Schwierzeck --- arch/mips/Kconfig | 2 +- arch/mips/mach-mt7620/cpu.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1b1b1d7d00..355d3b4d91 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -79,7 +79,7 @@ config ARCH_MT7620 select DM_SERIAL imply DM_SPI imply DM_SPI_FLASH - select ARCH_MISC_INIT if WATCHDOG + select ARCH_MISC_INIT select MIPS_TUNE_24KC select OF_CONTROL select ROM_EXCEPTION_VECTORS diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c index 87cc973b75..9e0ca716f7 100644 --- a/arch/mips/mach-mt7620/cpu.c +++ b/arch/mips/mach-mt7620/cpu.c @@ -89,9 +89,21 @@ void watchdog_reset(void) wdt_reset(watchdog_dev); } } +#endif int arch_misc_init(void) { + /* + * It has been noticed, that sometimes the d-cache is not in a + * "clean-state" when U-Boot is running on MT7688. This was + * detected when using the ethernet driver (which uses d-cache) + * and a TFTP command does not complete. Flushing the complete + * d-cache (again?) here seems to fix this issue. + */ + flush_dcache_range(gd->bd->bi_memstart, + gd->bd->bi_memstart + gd->ram_size - 1); + +#ifdef CONFIG_WATCHDOG /* Init watchdog */ if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { debug("Watchdog: Not found by seq!\n"); @@ -103,7 +115,7 @@ int arch_misc_init(void) wdt_start(watchdog_dev, 60000, 0); /* 60 seconds */ printf("Watchdog: Started\n"); +#endif return 0; } -#endif -- cgit From a0abb52c5a5b1de522380984bb9429ee973b1f8e Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Wed, 19 Dec 2018 15:18:52 +0100 Subject: MIPS: remove local_irq_[save|restore] from CP0 macros With moving write_on_tlb() to arch/mips/include/asm/mipsregs.h there are now compiler warnings when some generic code includes asm/io.h. This happens for example when enabling OF live tree. Signed-off-by: Daniel Schwierzeck --- arch/mips/include/asm/mipsregs.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch') diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 48fa1f1f7f..cdd546a3b2 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1013,9 +1013,7 @@ do { \ #define __read_64bit_c0_split(source, sel) \ ({ \ unsigned long long __val; \ - unsigned long __flags; \ \ - local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -1034,16 +1032,12 @@ do { \ "dsra\t%L0, %L0, 32\n\t" \ ".set\tmips0" \ : "=r" (__val)); \ - local_irq_restore(__flags); \ \ __val; \ }) #define __write_64bit_c0_split(source, sel, val) \ do { \ - unsigned long __flags; \ - \ - local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -1064,7 +1058,6 @@ do { \ "dmtc0\t%L0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ : : "r" (val)); \ - local_irq_restore(__flags); \ } while (0) #define __readx_32bit_c0_register(source) \ -- cgit From 48ee7b68533b7f007c337d9a606eb52c975445ad Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 14 Dec 2018 16:16:45 +0100 Subject: MIPS: move create_tlb() in an proper header: mipsregs.h Export create_tlb() as an inline function in mipsregs.h. It allows to remove the declaration of the function from the board files. Then it will allow also to use this function very early in the boot when the stack is not usable. Signed-off-by: Gregory CLEMENT --- arch/mips/cpu/cpu.c | 10 ---------- arch/mips/include/asm/mipsregs.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c index 5c56ab0289..a403ff729b 100644 --- a/arch/mips/cpu/cpu.c +++ b/arch/mips/cpu/cpu.c @@ -28,16 +28,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif -void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) -{ - write_c0_entrylo0(low0); - write_c0_pagemask(pagemask); - write_c0_entrylo1(low1); - write_c0_entryhi(hi); - write_c0_index(index); - tlb_write_indexed(); -} - int arch_cpu_init(void) { mips_cache_probe(); diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index cdd546a3b2..f80311e64e 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1998,6 +1998,17 @@ static inline unsigned int get_ebase_cpunum(void) return read_c0_ebase() & 0x3ff; } +static inline void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, + u32 low1) +{ + write_c0_entrylo0(low0); + write_c0_pagemask(pagemask); + write_c0_entrylo1(low1); + write_c0_entryhi(hi); + write_c0_index(index); + tlb_write_indexed(); +} + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_MIPSREGS_H */ -- cgit From 464b96bb8094a359f7b27027319eda64a961c5af Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 14 Dec 2018 16:16:46 +0100 Subject: MIPS: Allow to prefetch and lock instructions into cache This path add a new helper allowing to prefetch and lock instructions into cache. This is useful very early in the boot when no RAM is available yet. Signed-off-by: Gregory CLEMENT --- arch/mips/include/asm/cacheops.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index 3161875441..98b67ccc8e 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -19,6 +19,25 @@ static inline void mips_cache(int op, const volatile void *addr) #endif } +#define MIPS32_WHICH_ICACHE 0x0 +#define MIPS32_FETCH_AND_LOCK 0x7 + +#define ICACHE_LOAD_LOCK (MIPS32_WHICH_ICACHE | (MIPS32_FETCH_AND_LOCK << 2)) + +/* Prefetch and lock instructions into cache */ +static inline void icache_lock(void *func, size_t len) +{ + int i, lines = ((len - 1) / ARCH_DMA_MINALIGN) + 1; + + for (i = 0; i < lines; i++) { + asm volatile (" cache %0, %1(%2)" + : /* No Output */ + : "I" ICACHE_LOAD_LOCK, + "n" (i * ARCH_DMA_MINALIGN), + "r" (func) + : /* No Clobbers */); + } +} #endif /* !__ASSEMBLY__ */ /* -- cgit From dd1033e4e0254bd2d19debe433921d9a71bdf674 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 14 Dec 2018 16:16:47 +0100 Subject: MSCC: add support for Ocelot SoCs This family of SoCs are found in the Microsemi Switches solution and have already a support in the linux kernel. Signed-off-by: Gregory CLEMENT --- arch/mips/Kconfig | 6 + arch/mips/Makefile | 1 + arch/mips/mach-mscc/Kconfig | 69 ++ arch/mips/mach-mscc/Makefile | 5 + arch/mips/mach-mscc/cpu.c | 90 +++ arch/mips/mach-mscc/dram.c | 71 +++ arch/mips/mach-mscc/include/ioremap.h | 49 ++ arch/mips/mach-mscc/include/mach/common.h | 24 + arch/mips/mach-mscc/include/mach/ddr.h | 708 +++++++++++++++++++++ arch/mips/mach-mscc/include/mach/ocelot/ocelot.h | 24 + .../include/mach/ocelot/ocelot_devcpu_gcb.h | 21 + .../include/mach/ocelot/ocelot_icpu_cfg.h | 274 ++++++++ arch/mips/mach-mscc/include/mach/tlb.h | 55 ++ arch/mips/mach-mscc/lowlevel_init.S | 23 + arch/mips/mach-mscc/reset.c | 30 + 15 files changed, 1450 insertions(+) create mode 100644 arch/mips/mach-mscc/Kconfig create mode 100644 arch/mips/mach-mscc/Makefile create mode 100644 arch/mips/mach-mscc/cpu.c create mode 100644 arch/mips/mach-mscc/dram.c create mode 100644 arch/mips/mach-mscc/include/ioremap.h create mode 100644 arch/mips/mach-mscc/include/mach/common.h create mode 100644 arch/mips/mach-mscc/include/mach/ddr.h create mode 100644 arch/mips/mach-mscc/include/mach/ocelot/ocelot.h create mode 100644 arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h create mode 100644 arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h create mode 100644 arch/mips/mach-mscc/include/mach/tlb.h create mode 100644 arch/mips/mach-mscc/lowlevel_init.S create mode 100644 arch/mips/mach-mscc/reset.c (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 355d3b4d91..fe041f0b78 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -59,6 +59,11 @@ config ARCH_ATH79 select OF_CONTROL imply CMD_DM +config ARCH_MSCC + bool "Support MSCC VCore-III" + select OF_CONTROL + select DM + config ARCH_BMIPS bool "Support BMIPS SoCs" select CLK @@ -138,6 +143,7 @@ source "board/imgtec/xilfpga/Kconfig" source "board/micronas/vct/Kconfig" source "board/qemu-mips/Kconfig" source "arch/mips/mach-ath79/Kconfig" +source "arch/mips/mach-mscc/Kconfig" source "arch/mips/mach-bmips/Kconfig" source "arch/mips/mach-pic32/Kconfig" source "arch/mips/mach-mt7620/Kconfig" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 802244a06e..124e93fa26 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -15,6 +15,7 @@ machine-$(CONFIG_ARCH_ATH79) += ath79 machine-$(CONFIG_ARCH_BMIPS) += bmips machine-$(CONFIG_MACH_PIC32) += pic32 machine-$(CONFIG_ARCH_MT7620) += mt7620 +machine-$(CONFIG_ARCH_MSCC) += mscc machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y)) libs-y += $(machdirs) diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig new file mode 100644 index 0000000000..7f1b270207 --- /dev/null +++ b/arch/mips/mach-mscc/Kconfig @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +menu "MSCC VCore-III platforms" + depends on ARCH_MSCC + +config SOC_VCOREIII + select MIPS_TUNE_24KC + select ROM_EXCEPTION_VECTORS + select SUPPORTS_BIG_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 + select SUPPORTS_LITTLE_ENDIAN + bool + +config SYS_SOC + default "mscc" + +config SOC_OCELOT + bool + select SOC_VCOREIII + help + This supports MSCC Ocelot family of SOCs. + +config SYS_CONFIG_NAME + default "vcoreiii" + +choice + prompt "Board select" + +config TARGET_OCELOT_PCB120 + bool "MSCC PCB120 Reference Board (aka VSC5635EV)" + select SOC_OCELOT + help + When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to + ocelot_pcb120 + +config TARGET_OCELOT_PCB123 + bool "MSCC PCB123 Reference Board (aka VSC7514EV))" + select SOC_OCELOT + help + When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to + ocelot_pcb123 + +endchoice + +choice + prompt "DDR type" + +config DDRTYPE_H5TQ4G63MFR + bool "Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16)" + +config DDRTYPE_MT41K256M16 + bool "Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16)" + +config DDRTYPE_H5TQ1G63BFA + bool "Hynix H5TQ1G63BFA (1Gbit DDR3, x16)" + +config DDRTYPE_MT41J128M16HA + bool "Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16)" + +config DDRTYPE_MT41K128M16JT + bool "Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16)" + +config DDRTYPE_MT47H128M8HQ + bool "Micron MT47H128M8-3 (1Gbit, DDR-533@CL4 @ 4.80ns 16Mbisx8x8)" + +endchoice + +endmenu diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile new file mode 100644 index 0000000000..d14ec33838 --- /dev/null +++ b/arch/mips/mach-mscc/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +CFLAGS_cpu.o += -finline-limit=64000 + +obj-y += cpu.o dram.o reset.o lowlevel_init.o diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c new file mode 100644 index 0000000000..b503e1407b --- /dev/null +++ b/arch/mips/mach-mscc/cpu.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include + +#include +#include + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_SYS_SDRAM_SIZE <= SZ_64M +#define MSCC_RAM_TLB_SIZE SZ_64M +#define MSCC_ATTRIB2 MMU_REGIO_INVAL +#elif CONFIG_SYS_SDRAM_SIZE <= SZ_128M +#define MSCC_RAM_TLB_SIZE SZ_64M +#define MSCC_ATTRIB2 MMU_REGIO_RW +#elif CONFIG_SYS_SDRAM_SIZE <= SZ_256M +#define MSCC_RAM_TLB_SIZE SZ_256M +#define MSCC_ATTRIB2 MMU_REGIO_INVAL +#elif CONFIG_SYS_SDRAM_SIZE <= SZ_512M +#define MSCC_RAM_TLB_SIZE SZ_256M +#define MSCC_ATTRIB2 MMU_REGIO_RW +#else +#define MSCC_RAM_TLB_SIZE SZ_512M +#define MSCC_ATTRIB2 MMU_REGIO_RW +#endif + +/* NOTE: lowlevel_init() function does not have access to the + * stack. Thus, all called functions must be inlined, and (any) local + * variables must be kept in registers. + */ +void vcoreiii_tlb_init(void) +{ + register int tlbix = 0; + + /* + * Unlike most of the MIPS based SoCs, the IO register address + * are not in KSEG0. The mainline linux kernel built in legacy + * mode needs to access some of the registers very early in + * the boot and make the assumption that the bootloader has + * already configured them, so we have to match this + * expectation. + */ + create_tlb(tlbix++, MSCC_IO_ORIGIN1_OFFSET, SZ_16M, MMU_REGIO_RW, + MMU_REGIO_RW); + +#if CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO + /* + * If U-Boot is located in NOR then we want to be able to use + * the data cache in order to boot in a decent duration + */ + create_tlb(tlbix++, MSCC_FLASH_TO, SZ_16M, MMU_REGIO_RO_C, + MMU_REGIO_RO_C); + create_tlb(tlbix++, MSCC_FLASH_TO + SZ_32M, SZ_16M, MMU_REGIO_RO_C, + MMU_REGIO_RO_C); + + /* + * Using cache for RAM also helps to improve boot time. Thanks + * to this the time to relocate U-Boot in RAM went from 2.092 + * secs to 0.104 secs. + */ + create_tlb(tlbix++, MSCC_DDR_TO, MSCC_RAM_TLB_SIZE, MMU_REGIO_RW, + MSCC_ATTRIB2); + + /* Enable caches by clearing the bit ERL, which is set on reset */ + write_c0_status(read_c0_status() & ~BIT(2)); +#endif /* CONFIG_SYS_TEXT_BASE */ +} + +int mach_cpu_init(void) +{ + /* Speed up NOR flash access */ + writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); + /* + * Legacy and mainline linux kernel expect that the + * interruption map was set as it was done by redboot. + */ + writel(~0, BASE_CFG + ICPU_DST_INTR_MAP(0)); + writel(0, BASE_CFG + ICPU_DST_INTR_MAP(1)); + writel(0, BASE_CFG + ICPU_DST_INTR_MAP(2)); + writel(0, BASE_CFG + ICPU_DST_INTR_MAP(3)); + + return 0; +} diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c new file mode 100644 index 0000000000..5acee6f918 --- /dev/null +++ b/arch/mips/mach-mscc/dram.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include + +#include +#include + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static inline int vcoreiii_train_bytelane(void) +{ + int ret; + + ret = hal_vcoreiii_train_bytelane(0); + + if (ret) + return ret; + ret = hal_vcoreiii_train_bytelane(1); + + return ret; +} + +int vcoreiii_ddr_init(void) +{ + int res; + + if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) + & ICPU_MEMCTRL_STAT_INIT_DONE)) { + hal_vcoreiii_init_memctl(); + hal_vcoreiii_wait_memctl(); + if (hal_vcoreiii_init_dqs() || vcoreiii_train_bytelane()) + hal_vcoreiii_ddr_failed(); + } +#if (CONFIG_SYS_TEXT_BASE != 0x20000000) + res = dram_check(); + if (res == 0) + hal_vcoreiii_ddr_verified(); + else + hal_vcoreiii_ddr_failed(); + + /* Clear boot-mode and read-back to activate/verify */ + clrbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_BOOT_MODE_ENA); + readl(BASE_CFG + ICPU_GENERAL_CTRL); +#else + res = 0; +#endif + return res; +} + +int print_cpuinfo(void) +{ + printf("MSCC VCore-III MIPS 24Kec\n"); + + return 0; +} + +int dram_init(void) +{ + while (vcoreiii_ddr_init()) + ; + + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + return 0; +} diff --git a/arch/mips/mach-mscc/include/ioremap.h b/arch/mips/mach-mscc/include/ioremap.h new file mode 100644 index 0000000000..9024364a57 --- /dev/null +++ b/arch/mips/mach-mscc/include/ioremap.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_MSCC_IOREMAP_H +#define __ASM_MACH_MSCC_IOREMAP_H + +#include +#include + +/* + * Allow physical addresses to be fixed up to help peripherals located + * outside the low 32-bit range -- generic pass-through version. + */ +static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, + phys_addr_t size) +{ + return phys_addr; +} + +static inline int is_vcoreiii_internal_registers(phys_addr_t offset) +{ + if ((offset >= MSCC_IO_ORIGIN1_OFFSET && + offset < (MSCC_IO_ORIGIN1_OFFSET + MSCC_IO_ORIGIN1_SIZE)) || + (offset >= MSCC_IO_ORIGIN2_OFFSET && + offset < (MSCC_IO_ORIGIN2_OFFSET + MSCC_IO_ORIGIN2_SIZE))) + return 1; + + return 0; +} + +static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, + unsigned long flags) +{ + if (is_vcoreiii_internal_registers(offset)) + return (void __iomem *)offset; + + return NULL; +} + +static inline int plat_iounmap(const volatile void __iomem *addr) +{ + return is_vcoreiii_internal_registers((unsigned long)addr); +} + +#define _page_cachable_default _CACHE_CACHABLE_NONCOHERENT + +#endif /* __ASM_MACH_MSCC_IOREMAP_H */ diff --git a/arch/mips/mach-mscc/include/mach/common.h b/arch/mips/mach-mscc/include/mach/common.h new file mode 100644 index 0000000000..842462aeed --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/common.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_COMMON_H +#define __ASM_MACH_COMMON_H + +#if defined(CONFIG_SOC_OCELOT) +#include +#include +#include +#else +#error Unsupported platform +#endif + +#define MSCC_DDR_TO 0x20000000 /* DDR RAM base offset */ +#define MSCC_MEMCTL1_TO 0x40000000 /* SPI/PI base offset */ +#define MSCC_MEMCTL2_TO 0x50000000 /* SPI/PI base offset */ +#define MSCC_FLASH_TO MSCC_MEMCTL1_TO /* Flash base offset */ + +#define VCOREIII_TIMER_DIVIDER 25 /* Clock tick ~ 0.1 us */ + +#endif /* __ASM_MACH_COMMON_H */ diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h new file mode 100644 index 0000000000..262985c8c9 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -0,0 +1,708 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_DDR_H +#define __ASM_MACH_DDR_H + +#include +#include +#include +#include + +#define MIPS_VCOREIII_MEMORY_DDR3 +#define MIPS_VCOREIII_DDR_SIZE CONFIG_SYS_SDRAM_SIZE + +#if defined(CONFIG_DDRTYPE_H5TQ1G63BFA) /* Serval1 Refboard */ + +/* Hynix H5TQ1G63BFA (1Gbit DDR3, x16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 13 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 6 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 35 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 38 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT41J128M16HA) /* Validation board */ + +/* Micron MT41J128M16HA-15E:D (2Gbit DDR3, x16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 14 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 5 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 50 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 54 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT41K256M16) /* JR2 Validation board */ + +/* Micron MT41K256M16 (4Gbit, DDR3L-800, 256Mbitx16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 15 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 5 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 82 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 85 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_H5TQ4G63MFR) /* JR2 Reference board */ + +/* Hynix H5TQ4G63MFR-PBC (4Gbit, DDR3-800, 256Mbitx16) - 2kb pages @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 15 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 6 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 17 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 82 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 85 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT41K128M16JT) + +/* Micron Micron MT41K128M16JT-125 (2Gbit DDR3L, 128Mbitx16) @ 3.20ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 14 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 2437 +#define VC3_MPAR_tRAS_min 12 +#define VC3_MPAR_CL 6 +#define VC3_MPAR_tWTR 4 +#define VC3_MPAR_tRC 16 +#define VC3_MPAR_tFAW 16 +#define VC3_MPAR_tRP 5 +#define VC3_MPAR_tRRD 4 +#define VC3_MPAR_tRCD 5 +#define VC3_MPAR_tMRD 4 +#define VC3_MPAR_tRFC 82 +#define VC3_MPAR_CWL 5 +#define VC3_MPAR_tXPR 85 +#define VC3_MPAR_tMOD 12 +#define VC3_MPAR_tDLLK 512 +#define VC3_MPAR_tWR 5 + +#elif defined(CONFIG_DDRTYPE_MT47H128M8HQ) /* Luton10/26 Refboards */ + +/* Micron 1Gb MT47H128M8-3 16Meg x 8 x 8 banks, DDR-533@CL4 @ 4.80ns */ +#define VC3_MPAR_bank_addr_cnt 3 +#define VC3_MPAR_row_addr_cnt 14 +#define VC3_MPAR_col_addr_cnt 10 +#define VC3_MPAR_tREFI 1625 +#define VC3_MPAR_tRAS_min 9 +#define VC3_MPAR_CL 4 +#define VC3_MPAR_tWTR 2 +#define VC3_MPAR_tRC 12 +#define VC3_MPAR_tFAW 8 +#define VC3_MPAR_tRP 4 +#define VC3_MPAR_tRRD 2 +#define VC3_MPAR_tRCD 4 + +#define VC3_MPAR_tRPA 4 +#define VC3_MPAR_tRP 4 + +#define VC3_MPAR_tMRD 2 +#define VC3_MPAR_tRFC 27 + +#define VC3_MPAR__400_ns_dly 84 + +#define VC3_MPAR_tWR 4 +#undef MIPS_VCOREIII_MEMORY_DDR3 +#else + +#error Unknown DDR system configuration - please add! + +#endif + +#ifdef CONFIG_SOC_OCELOT +#define MIPS_VCOREIII_MEMORY_16BIT 1 +#endif + +#define MIPS_VCOREIII_MEMORY_SSTL_ODT 7 +#define MIPS_VCOREIII_MEMORY_SSTL_DRIVE 7 +#define VCOREIII_DDR_DQS_MODE_CALIBRATE + +#ifdef MIPS_VCOREIII_MEMORY_16BIT +#define VC3_MPAR_16BIT 1 +#else +#define VC3_MPAR_16BIT 0 +#endif + +#ifdef MIPS_VCOREIII_MEMORY_DDR3 +#define VC3_MPAR_DDR3_MODE 1 /* DDR3 */ +#define VC3_MPAR_BURST_LENGTH 8 /* Always 8 (1) for DDR3 */ +#ifdef MIPS_VCOREIII_MEMORY_16BIT +#define VC3_MPAR_BURST_SIZE 1 /* Always 1 for DDR3/16bit */ +#else +#define VC3_MPAR_BURST_SIZE 0 +#endif +#else +#define VC3_MPAR_DDR3_MODE 0 /* DDR2 */ +#ifdef MIPS_VCOREIII_MEMORY_16BIT +#define VC3_MPAR_BURST_LENGTH 4 /* in DDR2 16-bit mode, use burstlen 4 */ +#else +#define VC3_MPAR_BURST_LENGTH 8 /* For 8-bit IF we must run burst-8 */ +#endif +#define VC3_MPAR_BURST_SIZE 0 /* Always 0 for DDR2 */ +#endif + +#define VC3_MPAR_RL VC3_MPAR_CL +#if !defined(MIPS_VCOREIII_MEMORY_DDR3) +#define VC3_MPAR_WL (VC3_MPAR_RL - 1) +#define VC3_MPAR_MD VC3_MPAR_tMRD +#define VC3_MPAR_ID VC3_MPAR__400_ns_dly +#define VC3_MPAR_SD VC3_MPAR_tXSRD +#define VC3_MPAR_OW (VC3_MPAR_WL - 2) +#define VC3_MPAR_OR (VC3_MPAR_WL - 3) +#define VC3_MPAR_RP (VC3_MPAR_bank_addr_cnt < 3 ? VC3_MPAR_tRP : VC3_MPAR_tRPA) +#define VC3_MPAR_FAW (VC3_MPAR_bank_addr_cnt < 3 ? 1 : VC3_MPAR_tFAW) +#define VC3_MPAR_BL (VC3_MPAR_BURST_LENGTH == 4 ? 2 : 4) +#define MSCC_MEMPARM_MR0 \ + (VC3_MPAR_BURST_LENGTH == 8 ? 3 : 2) | (VC3_MPAR_CL << 4) | \ + ((VC3_MPAR_tWR - 1) << 9) +/* DLL-on, Full-OD, AL=0, RTT=off, nDQS-on, RDQS-off, out-en */ +#define MSCC_MEMPARM_MR1 0x382 +#define MSCC_MEMPARM_MR2 0 +#define MSCC_MEMPARM_MR3 0 +#else +#define VC3_MPAR_WL VC3_MPAR_CWL +#define VC3_MPAR_MD VC3_MPAR_tMOD +#define VC3_MPAR_ID VC3_MPAR_tXPR +#define VC3_MPAR_SD VC3_MPAR_tDLLK +#define VC3_MPAR_OW 2 +#define VC3_MPAR_OR 2 +#define VC3_MPAR_RP VC3_MPAR_tRP +#define VC3_MPAR_FAW VC3_MPAR_tFAW +#define VC3_MPAR_BL 4 +#define MSCC_MEMPARM_MR0 ((VC3_MPAR_RL - 4) << 4) | ((VC3_MPAR_tWR - 4) << 9) +/* ODT_RTT: “0x0040” for 120ohm, and “0x0004” for 60ohm. */ +#define MSCC_MEMPARM_MR1 0x0040 +#define MSCC_MEMPARM_MR2 ((VC3_MPAR_WL - 5) << 3) +#define MSCC_MEMPARM_MR3 0 +#endif /* MIPS_VCOREIII_MEMORY_DDR3 */ + +#define MSCC_MEMPARM_MEMCFG \ + ((MIPS_VCOREIII_DDR_SIZE > SZ_512M) ? \ + ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS : 0) | \ + (VC3_MPAR_16BIT ? ICPU_MEMCTRL_CFG_DDR_WIDTH : 0) | \ + (VC3_MPAR_DDR3_MODE ? ICPU_MEMCTRL_CFG_DDR_MODE : 0) | \ + (VC3_MPAR_BURST_SIZE ? ICPU_MEMCTRL_CFG_BURST_SIZE : 0) | \ + (VC3_MPAR_BURST_LENGTH == 8 ? ICPU_MEMCTRL_CFG_BURST_LEN : 0) | \ + (VC3_MPAR_bank_addr_cnt == 3 ? ICPU_MEMCTRL_CFG_BANK_CNT : 0) | \ + ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(VC3_MPAR_row_addr_cnt - 1) | \ + ICPU_MEMCTRL_CFG_MSB_COL_ADDR(VC3_MPAR_col_addr_cnt - 1) + +#ifdef CONFIG_SOC_OCELOT +#define MSCC_MEMPARM_PERIOD \ + ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(8) | \ + ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI) + +#define MSCC_MEMPARM_TIMING0 \ + ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(VC3_MPAR_RL + VC3_MPAR_BL + 1 - \ + VC3_MPAR_WL) | \ + ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(VC3_MPAR_BL - 1) | \ + ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(VC3_MPAR_BL) | \ + ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) | \ + ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_WL + \ + VC3_MPAR_BL + \ + VC3_MPAR_tWR - 1) | \ + ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BL - 1) | \ + ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_WL - 1) | \ + ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_RL - 3) + +#define MSCC_MEMPARM_TIMING1 \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \ + ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_FAW - 1) | \ + ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_RP - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) | \ + ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_WL + \ + VC3_MPAR_BL + \ + VC3_MPAR_tWTR - 1) + +#define MSCC_MEMPARM_TIMING2 \ + ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_RP - 1) | \ + ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_MD - 1) | \ + ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) | \ + ICPU_MEMCTRL_TIMING2_INIT_DLY(VC3_MPAR_ID - 1) + +#define MSCC_MEMPARM_TIMING3 \ + ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_WL + \ + VC3_MPAR_tWTR - 1) |\ + ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(VC3_MPAR_OR - 1) | \ + ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_OW - 1) | \ + ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_RL - 3) + +#else +#define MSCC_MEMPARM_PERIOD \ + ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(1) | \ + ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI) + +#define MSCC_MEMPARM_TIMING0 \ + ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(VC3_MPAR_tRAS_min - 1) | \ + ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(VC3_MPAR_CL + \ + (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \ + VC3_MPAR_tWR) | \ + ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(VC3_MPAR_BURST_LENGTH == 8 ? 3 : 1) | \ + ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(VC3_MPAR_CL - 3) | \ + ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(VC3_MPAR_CL - 3) + +#define MSCC_MEMPARM_TIMING1 \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(VC3_MPAR_tRC - 1) | \ + ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(VC3_MPAR_tFAW - 1) | \ + ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(VC3_MPAR_tRP - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(VC3_MPAR_tRRD - 1) | \ + ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(VC3_MPAR_tRCD - 1) | \ + ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(VC3_MPAR_CL + \ + (VC3_MPAR_BURST_LENGTH == 8 ? 2 : 0) + \ + VC3_MPAR_tWTR) +#define MSCC_MEMPARM_TIMING2 \ + ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(VC3_MPAR_tRPA - 1) | \ + ICPU_MEMCTRL_TIMING2_MDSET_DLY(VC3_MPAR_tMRD - 1) | \ + ICPU_MEMCTRL_TIMING2_REF_DLY(VC3_MPAR_tRFC - 1) | \ + ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(VC3_MPAR__400_ns_dly) + +#define MSCC_MEMPARM_TIMING3 \ + ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(VC3_MPAR_CL - 1) | \ + ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(VC3_MPAR_CL - 1) | \ + ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(VC3_MPAR_CL - 1) + +#endif + +enum { + DDR_TRAIN_OK, + DDR_TRAIN_CONTINUE, + DDR_TRAIN_ERROR, +}; + +/* + * We actually have very few 'pause' possibilities apart from + * these assembly nops (at this very early stage). + */ +#define PAUSE() asm volatile("nop; nop; nop; nop; nop; nop; nop; nop") + +/* NB: Assumes inlining as no stack is available! */ +static inline void set_dly(u32 bytelane, u32 dly) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + + r &= ~ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M; + r |= ICPU_MEMCTRL_DQS_DLY_DQS_DLY(dly); + writel(r, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); +} + +static inline bool incr_dly(u32 bytelane) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + + if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) { + writel(r + 1, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + return true; + } + + return false; +} + +static inline bool adjust_dly(int adjust) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0)); + + if (ICPU_MEMCTRL_DQS_DLY_DQS_DLY(r) < 31) { + writel(r + adjust, BASE_CFG + ICPU_MEMCTRL_DQS_DLY(0)); + return true; + } + + return false; +} + +/* NB: Assumes inlining as no stack is available! */ +static inline void center_dly(u32 bytelane, u32 start) +{ + register u32 r = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)) - start; + + writel(start + (r >> 1), BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); +} + +static inline void memphy_soft_reset(void) +{ + setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST); + PAUSE(); + clrbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_FIFO_RST); + PAUSE(); +} + +#ifdef CONFIG_SOC_OCELOT +static u8 training_data[] = { 0xfe, 0x11, 0x33, 0x55, 0x77, 0x99, 0xbb, 0xdd }; + +static inline void sleep_100ns(u32 val) +{ + /* Set the timer tick generator to 100 ns */ + writel(VCOREIII_TIMER_DIVIDER - 1, BASE_CFG + ICPU_TIMER_TICK_DIV); + + /* Set the timer value */ + writel(val, BASE_CFG + ICPU_TIMER_VALUE(0)); + + /* Enable timer 0 for one-shot */ + writel(ICPU_TIMER_CTRL_ONE_SHOT_ENA | ICPU_TIMER_CTRL_TIMER_ENA, + BASE_CFG + ICPU_TIMER_CTRL(0)); + + /* Wait for timer 0 to reach 0 */ + while (readl(BASE_CFG + ICPU_TIMER_VALUE(0)) != 0) + ; +} + +static inline void hal_vcoreiii_ddr_reset_assert(void) +{ + /* DDR has reset pin on GPIO 19 toggle Low-High to release */ + setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19)); + writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_CLR); + sleep_100ns(10000); +} + +static inline void hal_vcoreiii_ddr_reset_release(void) +{ + /* DDR has reset pin on GPIO 19 toggle Low-High to release */ + setbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19)); + writel(BIT(19), BASE_DEVCPU_GCB + PERF_GPIO_OUT_SET); + sleep_100ns(10000); +} + +/* + * DDR memory sanity checking failed, tally and do hard reset + * + * NB: Assumes inlining as no stack is available! + */ +static inline void hal_vcoreiii_ddr_failed(void) +{ + register u32 reset; + + writel(readl(BASE_CFG + ICPU_GPR(6)) + 1, BASE_CFG + ICPU_GPR(6)); + + clrbits_le32(BASE_DEVCPU_GCB + PERF_GPIO_OE, BIT(19)); + + /* We have to execute the reset function from cache. Indeed, + * the reboot workaround in _machine_restart() will change the + * SPI NOR into SW bitbang. + * + * This will render the CPU unable to execute directly from + * the NOR, which is why the reset instructions are prefetched + * into the I-cache. + * + * When failing the DDR initialization we are executing from + * NOR. + * + * The last instruction in _machine_restart() will reset the + * MIPS CPU (and the cache), and the CPU will start executing + * from the reset vector. + */ + reset = KSEG0ADDR(_machine_restart); + icache_lock((void *)reset, 128); + asm volatile ("jr %0"::"r" (reset)); + + panic("DDR init failed\n"); +} + +/* + * DDR memory sanity checking done, possibly enable ECC. + * + * NB: Assumes inlining as no stack is available! + */ +static inline void hal_vcoreiii_ddr_verified(void) +{ +#ifdef MIPS_VCOREIII_MEMORY_ECC + /* Finally, enable ECC */ + register u32 val = readl(BASE_CFG + ICPU_MEMCTRL_CFG); + + val |= ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA; + val &= ~ICPU_MEMCTRL_CFG_BURST_SIZE; + + writel(val, BASE_CFG + ICPU_MEMCTRL_CFG); +#endif + + /* Reset Status register - sticky bits */ + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), BASE_CFG + ICPU_MEMCTRL_STAT); +} + +/* NB: Assumes inlining as no stack is available! */ +static inline int look_for(u32 bytelane) +{ + register u32 i; + + /* Reset FIFO in case any previous access failed */ + for (i = 0; i < sizeof(training_data); i++) { + register u32 byte; + + memphy_soft_reset(); + /* Reset sticky bits */ + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), + BASE_CFG + ICPU_MEMCTRL_STAT); + /* Read data */ + byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane + + (i * 4)); + + /* + * Prevent the compiler reordering the instruction so + * the read of RAM happens after the check of the + * errors. + */ + rmb(); + if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) & + (ICPU_MEMCTRL_STAT_RDATA_MASKED | + ICPU_MEMCTRL_STAT_RDATA_DUMMY)) { + /* Noise on the line */ + goto read_error; + } + /* If mismatch, increment DQS - if possible */ + if (byte != training_data[i]) { + read_error: + if (!incr_dly(bytelane)) + return DDR_TRAIN_ERROR; + return DDR_TRAIN_CONTINUE; + } + } + return DDR_TRAIN_OK; +} + +/* NB: Assumes inlining as no stack is available! */ +static inline int look_past(u32 bytelane) +{ + register u32 i; + + /* Reset FIFO in case any previous access failed */ + for (i = 0; i < sizeof(training_data); i++) { + register u32 byte; + + memphy_soft_reset(); + /* Ack sticky bits */ + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), + BASE_CFG + ICPU_MEMCTRL_STAT); + byte = __raw_readb((void __iomem *)MSCC_DDR_TO + bytelane + + (i * 4)); + /* + * Prevent the compiler reordering the instruction so + * the read of RAM happens after the check of the + * errors. + */ + rmb(); + if (readl(BASE_CFG + ICPU_MEMCTRL_STAT) & + (ICPU_MEMCTRL_STAT_RDATA_MASKED | + ICPU_MEMCTRL_STAT_RDATA_DUMMY)) { + /* Noise on the line */ + goto read_error; + } + /* Bail out when we see first mismatch */ + if (byte != training_data[i]) { + read_error: + return DDR_TRAIN_OK; + } + } + /* All data compares OK, increase DQS and retry */ + if (!incr_dly(bytelane)) + return DDR_TRAIN_ERROR; + + return DDR_TRAIN_CONTINUE; +} + +static inline int hal_vcoreiii_train_bytelane(u32 bytelane) +{ + register int res; + register u32 dqs_s; + + set_dly(bytelane, 0); /* Start training at DQS=0 */ + while ((res = look_for(bytelane)) == DDR_TRAIN_CONTINUE) + ; + if (res != DDR_TRAIN_OK) + return res; + + dqs_s = readl(BASE_CFG + ICPU_MEMCTRL_DQS_DLY(bytelane)); + while ((res = look_past(bytelane)) == DDR_TRAIN_CONTINUE) + ; + if (res != DDR_TRAIN_OK) + return res; + /* Reset FIFO - for good measure */ + memphy_soft_reset(); + /* Adjust to center [dqs_s;cur] */ + center_dly(bytelane, dqs_s); + return DDR_TRAIN_OK; +} + +/* This algorithm is converted from the TCL training algorithm used + * during silicon simulation. + * NB: Assumes inlining as no stack is available! + */ +static inline int hal_vcoreiii_init_dqs(void) +{ +#define MAX_DQS 32 + register u32 i, j; + + for (i = 0; i < MAX_DQS; i++) { + set_dly(0, i); /* Byte-lane 0 */ + for (j = 0; j < MAX_DQS; j++) { + __maybe_unused register u32 byte; + + set_dly(1, j); /* Byte-lane 1 */ + /* Reset FIFO in case any previous access failed */ + memphy_soft_reset(); + writel(readl(BASE_CFG + ICPU_MEMCTRL_STAT), + BASE_CFG + ICPU_MEMCTRL_STAT); + byte = __raw_readb((void __iomem *)MSCC_DDR_TO); + byte = __raw_readb((void __iomem *)(MSCC_DDR_TO + 1)); + if (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) & + (ICPU_MEMCTRL_STAT_RDATA_MASKED | + ICPU_MEMCTRL_STAT_RDATA_DUMMY))) + return 0; + } + } + return -1; +} + +static inline int dram_check(void) +{ + register u32 i; + + for (i = 0; i < 8; i++) { + __raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4))); + if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i) + return 1; + } + return 0; +} + +/* + * NB: Called *early* to init memory controller - assumes inlining as + * no stack is available! + */ +static inline void hal_vcoreiii_init_memctl(void) +{ + /* Ensure DDR is in reset */ + hal_vcoreiii_ddr_reset_assert(); + + /* Wait maybe not needed, but ... */ + PAUSE(); + + /* Drop sys ctl memory controller forced reset */ + clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE); + + PAUSE(); + + /* Drop Reset, enable SSTL */ + writel(ICPU_MEMPHY_CFG_PHY_SSTL_ENA, BASE_CFG + ICPU_MEMPHY_CFG); + PAUSE(); + + /* Start the automatic SSTL output and ODT drive-strength calibration */ + writel(ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(MIPS_VCOREIII_MEMORY_SSTL_ODT) | + /* drive strength */ + ICPU_MEMPHY_ZCAL_ZCAL_PROG(MIPS_VCOREIII_MEMORY_SSTL_DRIVE) | + /* Start calibration process */ + ICPU_MEMPHY_ZCAL_ZCAL_ENA, BASE_CFG + ICPU_MEMPHY_ZCAL); + + /* Wait for ZCAL to clear */ + while (readl(BASE_CFG + ICPU_MEMPHY_ZCAL) & ICPU_MEMPHY_ZCAL_ZCAL_ENA) + ; + + /* Check no ZCAL_ERR */ + if (readl(BASE_CFG + ICPU_MEMPHY_ZCAL_STAT) + & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR) + hal_vcoreiii_ddr_failed(); + + /* Drive CL, CK, ODT */ + setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_ODT_OE | + ICPU_MEMPHY_CFG_PHY_CK_OE | ICPU_MEMPHY_CFG_PHY_CL_OE); + + /* Initialize memory controller */ + writel(MSCC_MEMPARM_MEMCFG, BASE_CFG + ICPU_MEMCTRL_CFG); + writel(MSCC_MEMPARM_PERIOD, BASE_CFG + ICPU_MEMCTRL_REF_PERIOD); + + writel(MSCC_MEMPARM_TIMING0, BASE_CFG + ICPU_MEMCTRL_TIMING0); + + writel(MSCC_MEMPARM_TIMING1, BASE_CFG + ICPU_MEMCTRL_TIMING1); + writel(MSCC_MEMPARM_TIMING2, BASE_CFG + ICPU_MEMCTRL_TIMING2); + writel(MSCC_MEMPARM_TIMING3, BASE_CFG + ICPU_MEMCTRL_TIMING3); + writel(MSCC_MEMPARM_MR0, BASE_CFG + ICPU_MEMCTRL_MR0_VAL); + writel(MSCC_MEMPARM_MR1, BASE_CFG + ICPU_MEMCTRL_MR1_VAL); + writel(MSCC_MEMPARM_MR2, BASE_CFG + ICPU_MEMCTRL_MR2_VAL); + writel(MSCC_MEMPARM_MR3, BASE_CFG + ICPU_MEMCTRL_MR3_VAL); + + /* Termination setup - enable ODT */ + writel(ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA | + /* Assert ODT0 for any write */ + ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(3), + BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); + + /* Release Reset from DDR */ + hal_vcoreiii_ddr_reset_release(); + + writel(readl(BASE_CFG + ICPU_GPR(7)) + 1, BASE_CFG + ICPU_GPR(7)); +} + +static inline void hal_vcoreiii_wait_memctl(void) +{ + /* Now, rip it! */ + writel(ICPU_MEMCTRL_CTRL_INITIALIZE, BASE_CFG + ICPU_MEMCTRL_CTRL); + + while (!(readl(BASE_CFG + ICPU_MEMCTRL_STAT) + & ICPU_MEMCTRL_STAT_INIT_DONE)) + ; + + /* Settle...? */ + sleep_100ns(10000); + + /* Establish data contents in DDR RAM for training */ + + __raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO)); + __raw_writel(0x22221111, ((void __iomem *)MSCC_DDR_TO + 0x4)); + __raw_writel(0x44443333, ((void __iomem *)MSCC_DDR_TO + 0x8)); + __raw_writel(0x66665555, ((void __iomem *)MSCC_DDR_TO + 0xC)); + __raw_writel(0x88887777, ((void __iomem *)MSCC_DDR_TO + 0x10)); + __raw_writel(0xaaaa9999, ((void __iomem *)MSCC_DDR_TO + 0x14)); + __raw_writel(0xccccbbbb, ((void __iomem *)MSCC_DDR_TO + 0x18)); + __raw_writel(0xeeeedddd, ((void __iomem *)MSCC_DDR_TO + 0x1C)); +} +#endif /* __ASM_MACH_DDR_H */ diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h new file mode 100644 index 0000000000..2cb2135d37 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Microsemi Ocelot Switch driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_H_ +#define _MSCC_OCELOT_H_ + +#include +#include + +/* + * Target offset base(s) + */ +#define MSCC_IO_ORIGIN1_OFFSET 0x70000000 +#define MSCC_IO_ORIGIN1_SIZE 0x00200000 +#define MSCC_IO_ORIGIN2_OFFSET 0x71000000 +#define MSCC_IO_ORIGIN2_SIZE 0x01000000 +#define BASE_CFG ((void __iomem *)0x70000000) +#define BASE_DEVCPU_GCB ((void __iomem *)0x71070000) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h new file mode 100644 index 0000000000..f8aa97ba26 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_ +#define _MSCC_OCELOT_DEVCPU_GCB_H_ + +#define PERF_SOFT_RST 0x8 + +#define PERF_SOFT_RST_SOFT_NON_CFG_RST BIT(2) +#define PERF_SOFT_RST_SOFT_SWC_RST BIT(1) +#define PERF_SOFT_RST_SOFT_CHIP_RST BIT(0) + +#define PERF_GPIO_OUT_SET 0x34 + +#define PERF_GPIO_OUT_CLR 0x38 + +#define PERF_GPIO_OE 0x44 + +#endif diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h new file mode 100644 index 0000000000..04cf70bec3 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_icpu_cfg.h @@ -0,0 +1,274 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_ICPU_CFG_H_ +#define _MSCC_OCELOT_ICPU_CFG_H_ + +#define ICPU_GPR(x) (0x4 * (x)) +#define ICPU_GPR_RSZ 0x4 + +#define ICPU_RESET 0x20 + +#define ICPU_RESET_CORE_RST_CPU_ONLY BIT(3) +#define ICPU_RESET_CORE_RST_PROTECT BIT(2) +#define ICPU_RESET_CORE_RST_FORCE BIT(1) +#define ICPU_RESET_MEM_RST_FORCE BIT(0) + +#define ICPU_GENERAL_CTRL 0x24 + +#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS BIT(14) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA BIT(13) +#define ICPU_GENERAL_CTRL_CPU_8051_IROM_ENA BIT(12) +#define ICPU_GENERAL_CTRL_CPU_MIPS_DIS BIT(11) +#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ADDR_SEL BIT(10) +#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ENA BIT(9) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_DONEPOL BIT(8) +#define ICPU_GENERAL_CTRL_IF_PI_MST_ENA BIT(7) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_ENA BIT(6) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER(x) (((x) << 4) & GENMASK(5, 4)) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_M GENMASK(5, 4) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_X(x) (((x) & GENMASK(5, 4)) >> 4) +#define ICPU_GENERAL_CTRL_SSI_MST_CONTENTION BIT(3) +#define ICPU_GENERAL_CTRL_CPU_BE_ENA BIT(2) +#define ICPU_GENERAL_CTRL_CPU_DIS BIT(1) +#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA BIT(0) +#define ICPU_SPI_MST_CFG 0x3c + +#define ICPU_SPI_MST_CFG_A32B_ENA BIT(11) +#define ICPU_SPI_MST_CFG_FAST_READ_ENA BIT(10) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x) (((x) << 5) & GENMASK(9, 5)) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M GENMASK(9, 5) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x) (((x) & GENMASK(9, 5)) >> 5) +#define ICPU_SPI_MST_CFG_CLK_DIV(x) ((x) & GENMASK(4, 0)) +#define ICPU_SPI_MST_CFG_CLK_DIV_M GENMASK(4, 0) + +#define ICPU_SW_MODE 0x50 + +#define ICPU_SW_MODE_SW_PIN_CTRL_MODE BIT(13) +#define ICPU_SW_MODE_SW_SPI_SCK BIT(12) +#define ICPU_SW_MODE_SW_SPI_SCK_OE BIT(11) +#define ICPU_SW_MODE_SW_SPI_SDO BIT(10) +#define ICPU_SW_MODE_SW_SPI_SDO_OE BIT(9) +#define ICPU_SW_MODE_SW_SPI_CS(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_SW_MODE_SW_SPI_CS_M GENMASK(8, 5) +#define ICPU_SW_MODE_SW_SPI_CS_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_SW_MODE_SW_SPI_CS_OE(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_SW_MODE_SW_SPI_CS_OE_M GENMASK(4, 1) +#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_SW_MODE_SW_SPI_SDI BIT(0) + +#define ICPU_INTR_ENA 0x88 + +#define ICPU_DST_INTR_MAP(x) (0x98 + 0x4 * (x)) +#define ICPU_DST_INTR_MAP_RSZ 0x4 + +#define ICPU_DST_INTR_IDENT 0xa8 +#define ICPU_DST_INTR_IDENT_RSZ 0x4 + +#define ICPU_TIMER_TICK_DIV 0xe8 +#define ICPU_TIMER_VALUE(x) (0xec + 0x4 * (x)) + +#define ICPU_TIMER_CTRL(x) (0x104 + 0x4 * (x)) +#define ICPU_TIMER_CTRL_MAX_FREQ_ENA BIT(3) +#define ICPU_TIMER_CTRL_ONE_SHOT_ENA BIT(2) +#define ICPU_TIMER_CTRL_TIMER_ENA BIT(1) +#define ICPU_TIMER_CTRL_FORCE_RELOAD BIT(0) + +#define ICPU_MEMCTRL_CTRL 0x110 +#define ICPU_MEMCTRL_CTRL_PWR_DOWN BIT(3) +#define ICPU_MEMCTRL_CTRL_MDSET BIT(2) +#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA BIT(1) +#define ICPU_MEMCTRL_CTRL_INITIALIZE BIT(0) + +#define ICPU_MEMCTRL_CFG 0x114 + +#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS BIT(16) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA BIT(15) +#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA BIT(14) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA BIT(13) +#define ICPU_MEMCTRL_CFG_DDR_WIDTH BIT(12) +#define ICPU_MEMCTRL_CFG_DDR_MODE BIT(11) +#define ICPU_MEMCTRL_CFG_BURST_SIZE BIT(10) +#define ICPU_MEMCTRL_CFG_BURST_LEN BIT(9) +#define ICPU_MEMCTRL_CFG_BANK_CNT BIT(8) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M GENMASK(7, 4) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_STAT 0x118 + +#define ICPU_MEMCTRL_STAT_RDATA_MASKED BIT(5) +#define ICPU_MEMCTRL_STAT_RDATA_DUMMY BIT(4) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR BIT(3) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR BIT(2) +#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK BIT(1) +#define ICPU_MEMCTRL_STAT_INIT_DONE BIT(0) + +#define ICPU_MEMCTRL_REF_PERIOD 0x11c + +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M GENMASK(19, 16) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING0 0x124 + +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x) (((x) << 20) & GENMASK(23, 20)) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M GENMASK(23, 20) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x) (((x) & GENMASK(23, 20)) >> 20) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING1 0x128 + +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x) (((x) << 24) & GENMASK(31, 24)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M GENMASK(31, 24) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING2 0x12c + +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING2_REF_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING2_INIT_DLY(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_TIMING2_INIT_DLY_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING3 0x130 + +#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_MR0_VAL 0x138 + +#define ICPU_MEMCTRL_MR1_VAL 0x13c + +#define ICPU_MEMCTRL_MR2_VAL 0x140 + +#define ICPU_MEMCTRL_MR3_VAL 0x144 + +#define ICPU_MEMCTRL_TERMRES_CTRL 0x148 + +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT BIT(11) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x) (((x) << 7) & GENMASK(10, 7)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M GENMASK(10, 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x) (((x) & GENMASK(10, 7)) >> 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT BIT(6) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x) (((x) << 2) & GENMASK(5, 2)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M GENMASK(5, 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x) (((x) & GENMASK(5, 2)) >> 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT BIT(1) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA BIT(0) + +#define ICPU_MEMCTRL_DQS_DLY(x) (0x150 + 0x4 * (x)) +#define ICPU_MEMCTRL_DQS_DLY_RSZ 0x4 + +#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA BIT(11) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x) (((x) << 8) & GENMASK(10, 8)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M GENMASK(10, 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x) (((x) & GENMASK(10, 8)) >> 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x) (((x) << 5) & GENMASK(7, 5)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M GENMASK(7, 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x) (((x) & GENMASK(7, 5)) >> 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x) ((x) & GENMASK(4, 0)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M GENMASK(4, 0) + +#define ICPU_MEMPHY_CFG 0x160 + +#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS BIT(10) +#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS BIT(9) +#define ICPU_MEMPHY_CFG_PHY_DQS_EXT BIT(8) +#define ICPU_MEMPHY_CFG_PHY_FIFO_RST BIT(7) +#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST BIT(6) +#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST BIT(5) +#define ICPU_MEMPHY_CFG_PHY_ODT_OE BIT(4) +#define ICPU_MEMPHY_CFG_PHY_CK_OE BIT(3) +#define ICPU_MEMPHY_CFG_PHY_CL_OE BIT(2) +#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA BIT(1) +#define ICPU_MEMPHY_CFG_PHY_RST BIT(0) + +#define ICPU_MEMPHY_ZCAL 0x188 + +#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL BIT(9) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M GENMASK(8, 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M GENMASK(4, 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_ENA BIT(0) + +#define ICPU_MEMPHY_ZCAL_STAT 0x18c + +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL(x) (((x) << 12) & GENMASK(31, 12)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_M GENMASK(31, 12) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ZCTRL_X(x) (((x) & GENMASK(31, 12)) >> 12) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU(x) (((x) << 8) & GENMASK(9, 8)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_M GENMASK(9, 8) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPU_X(x) (((x) & GENMASK(9, 8)) >> 8) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD(x) (((x) << 6) & GENMASK(7, 6)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_M GENMASK(7, 6) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_ODTPD_X(x) (((x) & GENMASK(7, 6)) >> 6) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU(x) (((x) << 4) & GENMASK(5, 4)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_M GENMASK(5, 4) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PU_X(x) (((x) & GENMASK(5, 4)) >> 4) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD(x) (((x) << 2) & GENMASK(3, 2)) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_M GENMASK(3, 2) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_STAT_PD_X(x) (((x) & GENMASK(3, 2)) >> 2) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR BIT(1) +#define ICPU_MEMPHY_ZCAL_STAT_ZCAL_DONE BIT(0) +#endif diff --git a/arch/mips/mach-mscc/include/mach/tlb.h b/arch/mips/mach-mscc/include/mach/tlb.h new file mode 100644 index 0000000000..fdb554f551 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/tlb.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef __ASM_MACH_TLB_H +#define __ASM_MACH_TLB_H + +#include +#include +#include + +#define TLB_HI_MASK 0xffffe000 +#define TLB_LO_MASK 0x3fffffff /* Masks off Fill bits */ +#define TLB_LO_SHIFT 6 /* PFN Start bit */ + +#define PAGEMASK_SHIFT 13 + +#define MMU_PAGE_CACHED (3 << 3) /* C(5:3) Cache Coherency Attributes */ +#define MMU_PAGE_UNCACHED (2 << 3) /* C(5:3) Cache Coherency Attributes */ +#define MMU_PAGE_DIRTY BIT(2) /* = Writeable */ +#define MMU_PAGE_VALID BIT(1) +#define MMU_PAGE_GLOBAL BIT(0) +#define MMU_REGIO_RO_C (MMU_PAGE_CACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL) +#define MMU_REGIO_RO (MMU_PAGE_UNCACHED | MMU_PAGE_VALID | MMU_PAGE_GLOBAL) +#define MMU_REGIO_RW (MMU_PAGE_DIRTY | MMU_REGIO_RO) +#define MMU_REGIO_INVAL (MMU_PAGE_GLOBAL) + +#define TLB_COUNT_MASK GENMASK(5, 0) +#define TLB_COUNT_OFF 25 + +static inline u32 get_tlb_count(void) +{ + register u32 config1; + + config1 = read_c0_config1(); + config1 >>= TLB_COUNT_OFF; + config1 &= TLB_COUNT_MASK; + + return 1 + config1; +} + +static inline void create_tlb(int index, u32 offset, u32 size, u32 tlb_attrib1, + u32 tlb_attrib2) +{ + register u32 tlb_mask, tlb_lo0, tlb_lo1; + + tlb_mask = ((size >> 12) - 1) << PAGEMASK_SHIFT; + tlb_lo0 = tlb_attrib1 | (offset >> TLB_LO_SHIFT); + tlb_lo1 = tlb_attrib2 | ((offset + size) >> TLB_LO_SHIFT); + + write_one_tlb(index, tlb_mask, offset & TLB_HI_MASK, + tlb_lo0 & TLB_LO_MASK, tlb_lo1 & TLB_LO_MASK); +} +#endif /* __ASM_MACH_TLB_H */ diff --git a/arch/mips/mach-mscc/lowlevel_init.S b/arch/mips/mach-mscc/lowlevel_init.S new file mode 100644 index 0000000000..f8f14adf61 --- /dev/null +++ b/arch/mips/mach-mscc/lowlevel_init.S @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include +#include + + .set noreorder + .extern vcoreiii_tlb_init + +LEAF(lowlevel_init) + /* + * As we have no stack yet, we can assume the restricted + * luxury of the sX-registers without saving them + */ + move s0,ra + + jal vcoreiii_tlb_init + nop + jr s0 + nop + END(lowlevel_init) diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c new file mode 100644 index 0000000000..390bbd086a --- /dev/null +++ b/arch/mips/mach-mscc/reset.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include + +#include +#include + +#include + +void _machine_restart(void) +{ + register u32 resetbits = PERF_SOFT_RST_SOFT_CHIP_RST; + (void)readl(BASE_DEVCPU_GCB + PERF_SOFT_RST); + + /* Make sure VCore is NOT protected from reset */ + clrbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_CORE_RST_PROTECT); + + /* Change to SPI bitbang for SPI reset workaround... */ + writel(ICPU_SW_MODE_SW_SPI_CS_OE(1) | ICPU_SW_MODE_SW_SPI_CS(1) | + ICPU_SW_MODE_SW_PIN_CTRL_MODE, BASE_CFG + ICPU_SW_MODE); + + /* Do the global reset */ + writel(resetbits, BASE_DEVCPU_GCB + PERF_SOFT_RST); + + while (1) + ; /* NOP */ +} -- cgit From 6bd8231a6dd58c2003e67a84e55705014d963989 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 14 Dec 2018 16:16:48 +0100 Subject: MSCC: add support for Luton SoCs As the Ocelots SoCs, this family of SoCs are found in the Microsemi Switches solution. Signed-off-by: Gregory CLEMENT --- arch/mips/mach-mscc/Kconfig | 13 ++ arch/mips/mach-mscc/Makefile | 1 + arch/mips/mach-mscc/cpu.c | 14 +- arch/mips/mach-mscc/dram.c | 2 + arch/mips/mach-mscc/include/mach/common.h | 4 + arch/mips/mach-mscc/include/mach/ddr.h | 112 +++++++++- arch/mips/mach-mscc/include/mach/luton/luton.h | 24 ++ .../include/mach/luton/luton_devcpu_gcb.h | 14 ++ .../mach-mscc/include/mach/luton/luton_icpu_cfg.h | 245 +++++++++++++++++++++ arch/mips/mach-mscc/lowlevel_init.S | 7 + arch/mips/mach-mscc/lowlevel_init_luton.S | 62 ++++++ 11 files changed, 494 insertions(+), 4 deletions(-) create mode 100644 arch/mips/mach-mscc/include/mach/luton/luton.h create mode 100644 arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h create mode 100644 arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h create mode 100644 arch/mips/mach-mscc/lowlevel_init_luton.S (limited to 'arch') diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig index 7f1b270207..a8cace0e79 100644 --- a/arch/mips/mach-mscc/Kconfig +++ b/arch/mips/mach-mscc/Kconfig @@ -21,6 +21,12 @@ config SOC_OCELOT help This supports MSCC Ocelot family of SOCs. +config SOC_LUTON + bool + select SOC_VCOREIII + help + This supports MSCC Luton family of SOCs. + config SYS_CONFIG_NAME default "vcoreiii" @@ -41,6 +47,13 @@ config TARGET_OCELOT_PCB123 When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to ocelot_pcb123 +config TARGET_LUTON_PCB091 + bool "MSCC PCB091 Reference Board" + select SOC_LUTON + select MSCC_BITBANG_SPI_GPIO + help + When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to + luton_pcb091 endchoice choice diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile index d14ec33838..6c60f26ca4 100644 --- a/arch/mips/mach-mscc/Makefile +++ b/arch/mips/mach-mscc/Makefile @@ -3,3 +3,4 @@ CFLAGS_cpu.o += -finline-limit=64000 obj-y += cpu.o dram.o reset.o lowlevel_init.o +obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c index b503e1407b..5be8ff69d5 100644 --- a/arch/mips/mach-mscc/cpu.c +++ b/arch/mips/mach-mscc/cpu.c @@ -48,6 +48,10 @@ void vcoreiii_tlb_init(void) */ create_tlb(tlbix++, MSCC_IO_ORIGIN1_OFFSET, SZ_16M, MMU_REGIO_RW, MMU_REGIO_RW); +#ifdef CONFIG_SOC_LUTON + create_tlb(tlbix++, MSCC_IO_ORIGIN2_OFFSET, SZ_16M, MMU_REGIO_RW, + MMU_REGIO_RW); +#endif #if CONFIG_SYS_TEXT_BASE == MSCC_FLASH_TO /* @@ -75,6 +79,14 @@ void vcoreiii_tlb_init(void) int mach_cpu_init(void) { /* Speed up NOR flash access */ +#ifdef CONFIG_SOC_LUTON + writel(ICPU_PI_MST_CFG_TRISTATE_CTRL + + ICPU_PI_MST_CFG_CLK_DIV(4), BASE_CFG + ICPU_PI_MST_CFG); + + writel(ICPU_SPI_MST_CFG_FAST_READ_ENA + + ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); +#else writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); /* @@ -85,6 +97,6 @@ int mach_cpu_init(void) writel(0, BASE_CFG + ICPU_DST_INTR_MAP(1)); writel(0, BASE_CFG + ICPU_DST_INTR_MAP(2)); writel(0, BASE_CFG + ICPU_DST_INTR_MAP(3)); - +#endif return 0; } diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c index 5acee6f918..309007c14e 100644 --- a/arch/mips/mach-mscc/dram.c +++ b/arch/mips/mach-mscc/dram.c @@ -19,9 +19,11 @@ static inline int vcoreiii_train_bytelane(void) ret = hal_vcoreiii_train_bytelane(0); +#ifdef CONFIG_SOC_OCELOT if (ret) return ret; ret = hal_vcoreiii_train_bytelane(1); +#endif return ret; } diff --git a/arch/mips/mach-mscc/include/mach/common.h b/arch/mips/mach-mscc/include/mach/common.h index 842462aeed..931ecd7985 100644 --- a/arch/mips/mach-mscc/include/mach/common.h +++ b/arch/mips/mach-mscc/include/mach/common.h @@ -10,6 +10,10 @@ #include #include #include +#elif defined(CONFIG_SOC_LUTON) +#include +#include +#include #else #error Unsupported platform #endif diff --git a/arch/mips/mach-mscc/include/mach/ddr.h b/arch/mips/mach-mscc/include/mach/ddr.h index 262985c8c9..f445e63a35 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -614,6 +614,98 @@ static inline int dram_check(void) } return 0; } +#else /* Luton */ + +static inline void sleep_100ns(u32 val) +{ +} + +static inline void hal_vcoreiii_ddr_reset_assert(void) +{ + setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_RST); + setbits_le32(BASE_CFG + ICPU_RESET, ICPU_RESET_MEM_RST_FORCE); +} + +static inline void hal_vcoreiii_ddr_reset_release(void) +{ +} + +static inline void hal_vcoreiii_ddr_failed(void) +{ + register u32 memphy_cfg = readl(BASE_CFG + ICPU_MEMPHY_CFG); + + /* Do a fifo reset and start over */ + writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST, + BASE_CFG + ICPU_MEMPHY_CFG); + writel(memphy_cfg & ~ICPU_MEMPHY_CFG_PHY_FIFO_RST, + BASE_CFG + ICPU_MEMPHY_CFG); + writel(memphy_cfg | ICPU_MEMPHY_CFG_PHY_FIFO_RST, + BASE_CFG + ICPU_MEMPHY_CFG); +} + +static inline void hal_vcoreiii_ddr_verified(void) +{ +} + +static inline int look_for(u32 data) +{ + register u32 byte = __raw_readb((void __iomem *)MSCC_DDR_TO); + + if (data != byte) { + if (!incr_dly(0)) + return DDR_TRAIN_ERROR; + return DDR_TRAIN_CONTINUE; + } + + return DDR_TRAIN_OK; +} + +/* This algorithm is converted from the TCL training algorithm used + * during silicon simulation. + * NB: Assumes inlining as no stack is available! + */ +static inline int hal_vcoreiii_train_bytelane(u32 bytelane) +{ + register int res; + + set_dly(bytelane, 0); /* Start training at DQS=0 */ + while ((res = look_for(0xff)) == DDR_TRAIN_CONTINUE) + ; + if (res != DDR_TRAIN_OK) + return res; + + set_dly(bytelane, 0); /* Start training at DQS=0 */ + while ((res = look_for(0x00)) == DDR_TRAIN_CONTINUE) + + ; + + if (res != DDR_TRAIN_OK) + return res; + + adjust_dly(-3); + + return DDR_TRAIN_OK; +} + +static inline int hal_vcoreiii_init_dqs(void) +{ + return 0; +} + +static inline int dram_check(void) +{ + register u32 i; + + for (i = 0; i < 8; i++) { + __raw_writel(~i, (void __iomem *)(MSCC_DDR_TO + (i * 4))); + + if (__raw_readl((void __iomem *)(MSCC_DDR_TO + (i * 4))) != ~i) + return 1; + } + + return 0; +} +#endif /* * NB: Called *early* to init memory controller - assumes inlining as @@ -646,12 +738,12 @@ static inline void hal_vcoreiii_init_memctl(void) /* Wait for ZCAL to clear */ while (readl(BASE_CFG + ICPU_MEMPHY_ZCAL) & ICPU_MEMPHY_ZCAL_ZCAL_ENA) ; - +#ifdef CONFIG_SOC_OCELOT /* Check no ZCAL_ERR */ if (readl(BASE_CFG + ICPU_MEMPHY_ZCAL_STAT) & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR) hal_vcoreiii_ddr_failed(); - +#endif /* Drive CL, CK, ODT */ setbits_le32(BASE_CFG + ICPU_MEMPHY_CFG, ICPU_MEMPHY_CFG_PHY_ODT_OE | ICPU_MEMPHY_CFG_PHY_CK_OE | ICPU_MEMPHY_CFG_PHY_CL_OE); @@ -660,7 +752,12 @@ static inline void hal_vcoreiii_init_memctl(void) writel(MSCC_MEMPARM_MEMCFG, BASE_CFG + ICPU_MEMCTRL_CFG); writel(MSCC_MEMPARM_PERIOD, BASE_CFG + ICPU_MEMCTRL_REF_PERIOD); +#ifdef CONFIG_SOC_OCELOT writel(MSCC_MEMPARM_TIMING0, BASE_CFG + ICPU_MEMCTRL_TIMING0); +#else /* Luton */ + clrbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, ((1 << 20) - 1)); + setbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, MSCC_MEMPARM_TIMING0); +#endif writel(MSCC_MEMPARM_TIMING1, BASE_CFG + ICPU_MEMCTRL_TIMING1); writel(MSCC_MEMPARM_TIMING2, BASE_CFG + ICPU_MEMCTRL_TIMING2); @@ -670,6 +767,7 @@ static inline void hal_vcoreiii_init_memctl(void) writel(MSCC_MEMPARM_MR2, BASE_CFG + ICPU_MEMCTRL_MR2_VAL); writel(MSCC_MEMPARM_MR3, BASE_CFG + ICPU_MEMCTRL_MR3_VAL); +#ifdef CONFIG_SOC_OCELOT /* Termination setup - enable ODT */ writel(ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA | /* Assert ODT0 for any write */ @@ -680,6 +778,11 @@ static inline void hal_vcoreiii_init_memctl(void) hal_vcoreiii_ddr_reset_release(); writel(readl(BASE_CFG + ICPU_GPR(7)) + 1, BASE_CFG + ICPU_GPR(7)); +#else /* Luton */ + /* Termination setup - disable ODT */ + writel(0, BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); + +#endif } static inline void hal_vcoreiii_wait_memctl(void) @@ -693,7 +796,7 @@ static inline void hal_vcoreiii_wait_memctl(void) /* Settle...? */ sleep_100ns(10000); - +#ifdef CONFIG_SOC_OCELOT /* Establish data contents in DDR RAM for training */ __raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO)); @@ -704,5 +807,8 @@ static inline void hal_vcoreiii_wait_memctl(void) __raw_writel(0xaaaa9999, ((void __iomem *)MSCC_DDR_TO + 0x14)); __raw_writel(0xccccbbbb, ((void __iomem *)MSCC_DDR_TO + 0x18)); __raw_writel(0xeeeedddd, ((void __iomem *)MSCC_DDR_TO + 0x1C)); +#else + __raw_writel(0xff, ((void __iomem *)MSCC_DDR_TO)); +#endif } #endif /* __ASM_MACH_DDR_H */ diff --git a/arch/mips/mach-mscc/include/mach/luton/luton.h b/arch/mips/mach-mscc/include/mach/luton/luton.h new file mode 100644 index 0000000000..19f02ede66 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/luton/luton.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Microsemi Ocelot Switch driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_H_ +#define _MSCC_OCELOT_H_ + +#include +#include + +/* + * Target offset base(s) + */ +#define MSCC_IO_ORIGIN1_OFFSET 0x60000000 +#define MSCC_IO_ORIGIN1_SIZE 0x01000000 +#define MSCC_IO_ORIGIN2_OFFSET 0x70000000 +#define MSCC_IO_ORIGIN2_SIZE 0x00200000 +#define BASE_CFG ((void __iomem *)0x70000000) +#define BASE_DEVCPU_GCB ((void __iomem *)0x60070000) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h new file mode 100644 index 0000000000..8c0b612325 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_DEVCPU_GCB_H_ +#define _MSCC_OCELOT_DEVCPU_GCB_H_ + +#define PERF_SOFT_RST 0x90 + +#define PERF_SOFT_RST_SOFT_SWC_RST BIT(1) +#define PERF_SOFT_RST_SOFT_CHIP_RST BIT(0) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h new file mode 100644 index 0000000000..9233f037bb --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/luton/luton_icpu_cfg.h @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_ICPU_CFG_H_ +#define _MSCC_OCELOT_ICPU_CFG_H_ + +#define ICPU_GPR(x) (0x4 * (x)) +#define ICPU_GPR_RSZ 0x4 + +#define ICPU_RESET 0x20 + +#define ICPU_RESET_CORE_RST_CPU_ONLY BIT(3) +#define ICPU_RESET_CORE_RST_PROTECT BIT(2) +#define ICPU_RESET_CORE_RST_FORCE BIT(1) +#define ICPU_RESET_MEM_RST_FORCE BIT(0) + +#define ICPU_GENERAL_CTRL 0x24 + +#define ICPU_GENERAL_CTRL_SWC_CLEAR_IF BIT(6) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_SLEEP_DIS BIT(5) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA BIT(4) +#define ICPU_GENERAL_CTRL_IF_MASTER_DIS BIT(3) +#define ICPU_GENERAL_CTRL_IF_MASTER_SPI_ENA BIT(2) +#define ICPU_GENERAL_CTRL_IF_MASTER_PI_ENA BIT(1) + +#define ICPU_GENERAL_CTRL_BOOT_MODE_ENA BIT(0) + +#define ICPU_PI_MST_CFG 0x2c + +#define ICPU_PI_MST_CFG_ATE_MODE_DIS BIT(7) +#define ICPU_PI_MST_CFG_CLK_POL BIT(6) +#define ICPU_PI_MST_CFG_TRISTATE_CTRL BIT(5) +#define ICPU_PI_MST_CFG_CLK_DIV(x) ((x) & GENMASK(4, 0)) +#define ICPU_PI_MST_CFG_CLK_DIV_M GENMASK(4, 0) + +#define ICPU_SPI_MST_CFG 0x50 + +#define ICPU_SPI_MST_CFG_FAST_READ_ENA BIT(10) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME(x) (((x) << 5) & GENMASK(9, 5)) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_M GENMASK(9, 5) +#define ICPU_SPI_MST_CFG_CS_DESELECT_TIME_X(x) (((x) & GENMASK(9, 5)) >> 5) +#define ICPU_SPI_MST_CFG_CLK_DIV(x) ((x) & GENMASK(4, 0)) +#define ICPU_SPI_MST_CFG_CLK_DIV_M GENMASK(4, 0) + +#define ICPU_SW_MODE 0x64 + +#define ICPU_SW_MODE_SW_PIN_CTRL_MODE BIT(13) +#define ICPU_SW_MODE_SW_SPI_SCK BIT(12) +#define ICPU_SW_MODE_SW_SPI_SCK_OE BIT(11) +#define ICPU_SW_MODE_SW_SPI_SDO BIT(10) +#define ICPU_SW_MODE_SW_SPI_SDO_OE BIT(9) +#define ICPU_SW_MODE_SW_SPI_CS(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_SW_MODE_SW_SPI_CS_M GENMASK(8, 5) +#define ICPU_SW_MODE_SW_SPI_CS_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_SW_MODE_SW_SPI_CS_OE(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_SW_MODE_SW_SPI_CS_OE_M GENMASK(4, 1) +#define ICPU_SW_MODE_SW_SPI_CS_OE_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_SW_MODE_SW_SPI_SDI BIT(0) + +#define ICPU_INTR_ENA 0x88 + +#define ICPU_INTR_IRQ0_ENA 0x98 +#define ICPU_INTR_IRQ0_ENA_IRQ0_ENA BIT(0) + +#define ICPU_MEMCTRL_CTRL 0x234 + +#define ICPU_MEMCTRL_CTRL_PWR_DOWN BIT(3) +#define ICPU_MEMCTRL_CTRL_MDSET BIT(2) +#define ICPU_MEMCTRL_CTRL_STALL_REF_ENA BIT(1) +#define ICPU_MEMCTRL_CTRL_INITIALIZE BIT(0) + +#define ICPU_MEMCTRL_CFG 0x238 + +#define ICPU_MEMCTRL_CFG_DDR_512MBYTE_PLUS BIT(16) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ERR_ENA BIT(15) +#define ICPU_MEMCTRL_CFG_DDR_ECC_COR_ENA BIT(14) +#define ICPU_MEMCTRL_CFG_DDR_ECC_ENA BIT(13) +#define ICPU_MEMCTRL_CFG_DDR_WIDTH BIT(12) +#define ICPU_MEMCTRL_CFG_DDR_MODE BIT(11) +#define ICPU_MEMCTRL_CFG_BURST_SIZE BIT(10) +#define ICPU_MEMCTRL_CFG_BURST_LEN BIT(9) +#define ICPU_MEMCTRL_CFG_BANK_CNT BIT(8) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_M GENMASK(7, 4) +#define ICPU_MEMCTRL_CFG_MSB_ROW_ADDR_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_CFG_MSB_COL_ADDR_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_STAT 0x23C + +#define ICPU_MEMCTRL_STAT_RDATA_MASKED BIT(5) +#define ICPU_MEMCTRL_STAT_RDATA_DUMMY BIT(4) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_ERR BIT(3) +#define ICPU_MEMCTRL_STAT_RDATA_ECC_COR BIT(2) +#define ICPU_MEMCTRL_STAT_PWR_DOWN_ACK BIT(1) +#define ICPU_MEMCTRL_STAT_INIT_DONE BIT(0) + +#define ICPU_MEMCTRL_REF_PERIOD 0x240 + +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_M GENMASK(19, 16) +#define ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING0 0x248 + +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING0_RD_TO_WR_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING0_WR_CS_CHANGE_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY(x) (((x) << 20) & GENMASK(23, 20)) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_M GENMASK(23, 20) +#define ICPU_MEMCTRL_TIMING0_RD_CS_CHANGE_DLY_X(x) (((x) & GENMASK(23, 20)) >> 20) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING0_RAS_TO_PRECH_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING0_WR_TO_PRECH_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING0_RD_TO_PRECH_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING0_WR_DATA_XFR_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING0_RD_DATA_XFR_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING1 0x24c + +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY(x) (((x) << 24) & GENMASK(31, 24)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_M GENMASK(31, 24) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_SAME_BANK_DLY_X(x) (((x) & GENMASK(31, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING1_BANK8_FAW_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING1_PRECH_TO_RAS_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_RAS_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING1_RAS_TO_CAS_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING1_WR_TO_RD_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_TIMING2 0x250 + +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY(x) (((x) << 28) & GENMASK(31, 28)) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_M GENMASK(31, 28) +#define ICPU_MEMCTRL_TIMING2_PRECH_ALL_DLY_X(x) (((x) & GENMASK(31, 28)) >> 28) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY(x) (((x) << 24) & GENMASK(27, 24)) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_M GENMASK(27, 24) +#define ICPU_MEMCTRL_TIMING2_MDSET_DLY_X(x) (((x) & GENMASK(27, 24)) >> 24) +#define ICPU_MEMCTRL_TIMING2_REF_DLY(x) (((x) << 16) & GENMASK(23, 16)) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_M GENMASK(23, 16) +#define ICPU_MEMCTRL_TIMING2_REF_DLY_X(x) (((x) & GENMASK(23, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY(x) ((x) & GENMASK(15, 0)) +#define ICPU_MEMCTRL_TIMING2_FOUR_HUNDRED_NS_DLY_M GENMASK(15, 0) + +#define ICPU_MEMCTRL_TIMING3 0x254 + +#define ICPU_MEMCTRL_TIMING3_RMW_DLY(x) (((x) << 16) & GENMASK(19, 16)) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_M GENMASK(19, 16) +#define ICPU_MEMCTRL_TIMING3_RMW_DLY_X(x) (((x) & GENMASK(19, 16)) >> 16) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY(x) (((x) << 12) & GENMASK(15, 12)) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_M GENMASK(15, 12) +#define ICPU_MEMCTRL_TIMING3_ODT_RD_DLY_X(x) (((x) & GENMASK(15, 12)) >> 12) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY(x) (((x) << 8) & GENMASK(11, 8)) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_M GENMASK(11, 8) +#define ICPU_MEMCTRL_TIMING3_ODT_WR_DLY_X(x) (((x) & GENMASK(11, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY(x) (((x) << 4) & GENMASK(7, 4)) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_M GENMASK(7, 4) +#define ICPU_MEMCTRL_TIMING3_LOCAL_ODT_RD_DLY_X(x) (((x) & GENMASK(7, 4)) >> 4) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY(x) ((x) & GENMASK(3, 0)) +#define ICPU_MEMCTRL_TIMING3_WR_TO_RD_CS_CHANGE_DLY_M GENMASK(3, 0) + +#define ICPU_MEMCTRL_MR0_VAL 0x258 + +#define ICPU_MEMCTRL_MR1_VAL 0x25c + +#define ICPU_MEMCTRL_MR2_VAL 0x260 + +#define ICPU_MEMCTRL_MR3_VAL 0x264 + +#define ICPU_MEMCTRL_TERMRES_CTRL 0x268 + +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_EXT BIT(11) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA(x) (((x) << 7) & GENMASK(10, 7)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_M GENMASK(10, 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_RD_ENA_X(x) (((x) & GENMASK(10, 7)) >> 7) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_EXT BIT(6) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(x) (((x) << 2) & GENMASK(5, 2)) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_M GENMASK(5, 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA_X(x) (((x) & GENMASK(5, 2)) >> 2) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_EXT BIT(1) +#define ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA BIT(0) + +#define ICPU_MEMCTRL_DQS_DLY(x) (0x270) + +#define ICPU_MEMCTRL_DQS_DLY_TRAIN_DQ_ENA BIT(11) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1(x) (((x) << 8) & GENMASK(10, 8)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_M GENMASK(10, 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM1_X(x) (((x) & GENMASK(10, 8)) >> 8) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0(x) (((x) << 5) & GENMASK(7, 5)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_M GENMASK(7, 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_TRM0_X(x) (((x) & GENMASK(7, 5)) >> 5) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY(x) ((x) & GENMASK(4, 0)) +#define ICPU_MEMCTRL_DQS_DLY_DQS_DLY_M GENMASK(4, 0) + +#define ICPU_MEMPHY_CFG 0x278 + +#define ICPU_MEMPHY_CFG_PHY_FLUSH_DIS BIT(10) +#define ICPU_MEMPHY_CFG_PHY_RD_ADJ_DIS BIT(9) +#define ICPU_MEMPHY_CFG_PHY_DQS_EXT BIT(8) +#define ICPU_MEMPHY_CFG_PHY_FIFO_RST BIT(7) +#define ICPU_MEMPHY_CFG_PHY_DLL_BL_RST BIT(6) +#define ICPU_MEMPHY_CFG_PHY_DLL_CL_RST BIT(5) +#define ICPU_MEMPHY_CFG_PHY_ODT_OE BIT(4) +#define ICPU_MEMPHY_CFG_PHY_CK_OE BIT(3) +#define ICPU_MEMPHY_CFG_PHY_CL_OE BIT(2) +#define ICPU_MEMPHY_CFG_PHY_SSTL_ENA BIT(1) +#define ICPU_MEMPHY_CFG_PHY_RST BIT(0) +#define ICPU_MEMPHY_DQ_DLY_TRM 0x180 +#define ICPU_MEMPHY_DQ_DLY_TRM_RSZ 0x4 + +#define ICPU_MEMPHY_ZCAL 0x294 + +#define ICPU_MEMPHY_ZCAL_ZCAL_CLK_SEL BIT(9) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT(x) (((x) << 5) & GENMASK(8, 5)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_M GENMASK(8, 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_ODT_X(x) (((x) & GENMASK(8, 5)) >> 5) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG(x) (((x) << 1) & GENMASK(4, 1)) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_M GENMASK(4, 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_PROG_X(x) (((x) & GENMASK(4, 1)) >> 1) +#define ICPU_MEMPHY_ZCAL_ZCAL_ENA BIT(0) + +#endif diff --git a/arch/mips/mach-mscc/lowlevel_init.S b/arch/mips/mach-mscc/lowlevel_init.S index f8f14adf61..dfbe06766c 100644 --- a/arch/mips/mach-mscc/lowlevel_init.S +++ b/arch/mips/mach-mscc/lowlevel_init.S @@ -8,6 +8,9 @@ .set noreorder .extern vcoreiii_tlb_init +#ifdef CONFIG_SOC_LUTON + .extern pll_init +#endif LEAF(lowlevel_init) /* @@ -18,6 +21,10 @@ LEAF(lowlevel_init) jal vcoreiii_tlb_init nop +#ifdef CONFIG_SOC_LUTON + jal pll_init + nop +#endif jr s0 nop END(lowlevel_init) diff --git a/arch/mips/mach-mscc/lowlevel_init_luton.S b/arch/mips/mach-mscc/lowlevel_init_luton.S new file mode 100644 index 0000000000..8a528fa83a --- /dev/null +++ b/arch/mips/mach-mscc/lowlevel_init_luton.S @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include +#include + +#define BASE_MACRO 0x600a0000 +#define REG_OFFSET(t, o) (t + (o*4)) +#define REG_MACRO(x) REG_OFFSET(BASE_MACRO, x) +#define BIT(nr) (1 << (nr)) + +#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 REG_MACRO(6) +#define MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS BIT(0) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 REG_MACRO(2) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 REG_MACRO(0) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV (0x3F << 6) +#define MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(x) (x << 6) + + .set noreorder +LEAF(pll_init) + /* Make sure PLL is locked */ + lw v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 + andi v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS + bne v1, zero, 1f + nop + + /* Black magic from frontend */ + li v1, 0x00610400 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + li v1, 0x00610c00 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + li v1, 0x00610800 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + li v1, 0x00610000 + sw v1, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG2 + + /* Wait for lock */ +2: lw v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0 + andi v1, v0, MACRO_CTRL_PLL5G_STATUS_PLL5G_STATUS0_LOCK_STATUS + /* Keep looping if zero (no lock bit yet) */ + beq v1, zero, 2b + nop + + /* Setup PLL CPU clock divider for 416MHz */ +1: lw v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 + + /* Keep reserved bits */ + li v1, ~MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV + and v0, v0, v1 + + /* Set code 6 ~ 416.66 MHz */ + ori v0, v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0_CPU_CLK_DIV_ENC(6) + + sw v0, MACRO_CTRL_PLL5G_CFG_PLL5G_CFG0 + jr ra + nop + END(pll_init) -- cgit From 6787c1ece07f771629ea5b463a362f9b4c40d2c0 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 14 Dec 2018 16:16:49 +0100 Subject: MSCC: add board support for the Ocelots based evaluation boards Adding the support for 2 boards sharing common code for Ocelot chip: PCB120 and PCB123 Signed-off-by: Gregory CLEMENT --- arch/mips/dts/mscc,ocelot.dtsi | 152 +++++++++++++++++++++++++++++++++++++ arch/mips/dts/mscc,ocelot_pcb.dtsi | 42 ++++++++++ arch/mips/dts/ocelot_pcb120.dts | 12 +++ arch/mips/dts/ocelot_pcb123.dts | 12 +++ arch/mips/mach-mscc/Kconfig | 2 + 5 files changed, 220 insertions(+) create mode 100644 arch/mips/dts/mscc,ocelot.dtsi create mode 100644 arch/mips/dts/mscc,ocelot_pcb.dtsi create mode 100644 arch/mips/dts/ocelot_pcb120.dts create mode 100644 arch/mips/dts/ocelot_pcb123.dts (limited to 'arch') diff --git a/arch/mips/dts/mscc,ocelot.dtsi b/arch/mips/dts/mscc,ocelot.dtsi new file mode 100644 index 0000000000..87b4736285 --- /dev/null +++ b/arch/mips/dts/mscc,ocelot.dtsi @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mscc,ocelot"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mips,mips24KEc"; + device_type = "cpu"; + clocks = <&cpu_clk>; + reg = <0>; + }; + }; + + aliases { + serial0 = &uart0; + }; + + cpuintc: interrupt-controller@0 { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + cpu_clk: cpu-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <500000000>; + }; + + ahb_clk: ahb-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x70000000 0x2000000>; + + interrupt-parent = <&intc>; + + cpu_ctrl: syscon@0 { + compatible = "mscc,ocelot-cpu-syscon", "syscon"; + reg = <0x0 0x2c>; + }; + + intc: interrupt-controller@70 { + compatible = "mscc,ocelot-icpu-intr"; + reg = <0x70 0x70>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + uart0: serial@100000 { + pinctrl-0 = <&uart_pins>; + pinctrl-names = "default"; + compatible = "ns16550a"; + reg = <0x100000 0x20>; + interrupts = <6>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + uart2: serial@100800 { + pinctrl-0 = <&uart2_pins>; + pinctrl-names = "default"; + compatible = "ns16550a"; + reg = <0x100800 0x20>; + interrupts = <7>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + spi0: spi-master@101000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dw-apb-ssi"; + reg = <0x101000 0x40>; + num-chipselect = <4>; + bus-num = <0>; + reg-io-width = <4>; + reg-shift = <2>; + spi-max-frequency = <18000000>; /* input clock */ + clocks = <&ahb_clk>; + + status = "disabled"; + }; + + reset@1070008 { + compatible = "mscc,ocelot-chip-reset"; + reg = <0x1070008 0x4>; + }; + + gpio: pinctrl@1070034 { + compatible = "mscc,ocelot-pinctrl"; + reg = <0x1070034 0x68>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio 0 0 22>; + + uart_pins: uart-pins { + pins = "GPIO_6", "GPIO_7"; + function = "uart"; + }; + + uart2_pins: uart2-pins { + pins = "GPIO_12", "GPIO_13"; + function = "uart2"; + }; + + spi_cs1_pin: spi-cs1-pin { + pins = "GPIO_8"; + function = "si"; + }; + + spi_cs2_pin: spi-cs2-pin { + pins = "GPIO_9"; + function = "si"; + }; + + spi_cs3_pin: spi-cs3-pin { + pins = "GPIO_16"; + function = "si"; + }; + + spi_cs4_pin: spi-cs4-pin { + pins = "GPIO_17"; + function = "si"; + }; + }; + }; +}; diff --git a/arch/mips/dts/mscc,ocelot_pcb.dtsi b/arch/mips/dts/mscc,ocelot_pcb.dtsi new file mode 100644 index 0000000000..90725d3b94 --- /dev/null +++ b/arch/mips/dts/mscc,ocelot_pcb.dtsi @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,ocelot.dtsi" + +/ { + compatible = "mscc,ocelot"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi_cs1_pin>; + pinctrl-names = "default"; + + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; + + spi-nand@1 { + compatible = "spi-nand"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <1>; /* CS1 */ + }; +}; diff --git a/arch/mips/dts/ocelot_pcb120.dts b/arch/mips/dts/ocelot_pcb120.dts new file mode 100644 index 0000000000..47d305a614 --- /dev/null +++ b/arch/mips/dts/ocelot_pcb120.dts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,ocelot_pcb.dtsi" + +/ { + model = "Ocelot PCB120 Reference Board"; + compatible = "mscc,ocelot-pcb120", "mscc,ocelot"; +}; diff --git a/arch/mips/dts/ocelot_pcb123.dts b/arch/mips/dts/ocelot_pcb123.dts new file mode 100644 index 0000000000..17d8d326ce --- /dev/null +++ b/arch/mips/dts/ocelot_pcb123.dts @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,ocelot_pcb.dtsi" + +/ { + model = "Ocelot PCB123 Reference Board"; + compatible = "mscc,ocelot-pcb123", "mscc,ocelot"; +}; diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig index a8cace0e79..fc806fc1f3 100644 --- a/arch/mips/mach-mscc/Kconfig +++ b/arch/mips/mach-mscc/Kconfig @@ -79,4 +79,6 @@ config DDRTYPE_MT47H128M8HQ endchoice +source "board/mscc/ocelot/Kconfig" + endmenu -- cgit From f8c8cedd7ad377cb2a00d35d94dec0dd260117cc Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 14 Dec 2018 16:16:50 +0100 Subject: MSCC: add board support for the Luton based evaluation board Adding the support for the Luton boards PCB91 which share common code with the Ocelots boards, including board code, device tree and configuration. Signed-off-by: Gregory CLEMENT --- arch/mips/dts/luton_pcb091.dts | 36 +++++++++++++++++ arch/mips/dts/mscc,luton.dtsi | 87 ++++++++++++++++++++++++++++++++++++++++++ arch/mips/mach-mscc/Kconfig | 2 + 3 files changed, 125 insertions(+) create mode 100644 arch/mips/dts/luton_pcb091.dts create mode 100644 arch/mips/dts/mscc,luton.dtsi (limited to 'arch') diff --git a/arch/mips/dts/luton_pcb091.dts b/arch/mips/dts/luton_pcb091.dts new file mode 100644 index 0000000000..74f9274c21 --- /dev/null +++ b/arch/mips/dts/luton_pcb091.dts @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,luton.dtsi" + +/ { + model = "Luton10 PCB091 Reference Board"; + compatible = "mscc,luton-pcb091", "mscc,luton"; + + aliases { + serial0 = &uart0; + spi0 = &spi0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + spi-cs-high; + }; +}; + diff --git a/arch/mips/dts/mscc,luton.dtsi b/arch/mips/dts/mscc,luton.dtsi new file mode 100644 index 0000000000..6a4ad2a5be --- /dev/null +++ b/arch/mips/dts/mscc,luton.dtsi @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mscc,luton"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mips,mips24KEc"; + device_type = "cpu"; + reg = <0>; + }; + }; + + aliases { + serial0 = &uart0; + }; + + ahb_clk: ahb-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <208333333>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x60000000 0x10200000>; + + uart0: serial@10100000 { + pinctrl-0 = <&uart_pins>; + pinctrl-names = "default"; + + compatible = "ns16550a"; + reg = <0x10100000 0x20>; + clocks = <&ahb_clk>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + + gpio: pinctrl@70068 { + compatible = "mscc,luton-pinctrl"; + reg = <0x70068 0x68>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio 0 0 32>; + + uart_pins: uart-pins { + pins = "GPIO_30", "GPIO_31"; + function = "uart"; + }; + + }; + + gpio_spi_bitbang: gpio@10000064 { + compatible = "mscc,spi-bitbang-gpio"; + reg = <0x10000064 0x4>; + gpio-controller; + #gpio-cells = <2>; + + }; + + spi0: spi-bitbang { + compatible = "spi-gpio"; + status = "okay"; + gpio-sck = <&gpio_spi_bitbang 6 0>; + gpio-miso = <&gpio_spi_bitbang 0 0>; + gpio-mosi = <&gpio_spi_bitbang 5 0>; + cs-gpios = <&gpio_spi_bitbang 1 0>; + num-chipselects = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig index fc806fc1f3..0e35b77c9d 100644 --- a/arch/mips/mach-mscc/Kconfig +++ b/arch/mips/mach-mscc/Kconfig @@ -81,4 +81,6 @@ endchoice source "board/mscc/ocelot/Kconfig" +source "board/mscc/luton/Kconfig" + endmenu -- cgit From b325c4dcd72246a107580280ff66f4c86b23254a Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 16 Dec 2018 19:25:21 -0300 Subject: mips: Add SPL header Add header with SPL boot mode and type definitions. Cc: Daniel Schwierzeck Signed-off-by: Paul Burton Signed-off-by: Marek Vasut --- arch/mips/include/asm/spl.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 arch/mips/include/asm/spl.h (limited to 'arch') diff --git a/arch/mips/include/asm/spl.h b/arch/mips/include/asm/spl.h new file mode 100644 index 0000000000..0a847edec8 --- /dev/null +++ b/arch/mips/include/asm/spl.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2012 + * Texas Instruments, + */ +#ifndef _ASM_SPL_H_ +#define _ASM_SPL_H_ + +enum { + BOOT_DEVICE_RAM, + BOOT_DEVICE_MMC1, + BOOT_DEVICE_MMC2, + BOOT_DEVICE_MMC2_2, + BOOT_DEVICE_NAND, + BOOT_DEVICE_ONENAND, + BOOT_DEVICE_NOR, + BOOT_DEVICE_UART, + BOOT_DEVICE_SPI, + BOOT_DEVICE_USB, + BOOT_DEVICE_SATA, + BOOT_DEVICE_I2C, + BOOT_DEVICE_BOARD, + BOOT_DEVICE_DFU, + BOOT_DEVICE_XIP, + BOOT_DEVICE_BOOTROM, + BOOT_DEVICE_NONE +}; + +#ifndef CONFIG_DM +extern gd_t gdata; +#endif + +#endif -- cgit From cd71b1d5d26dfff15222f5df8a5a6df68fc41df7 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 16 Dec 2018 19:25:22 -0300 Subject: mips: jz47xx: Add JZ4780 SoC support Add initial support for the Ingenic JZ47xx MIPS SoC. Cc: Daniel Schwierzeck Signed-off-by: Paul Burton Signed-off-by: Marek Vasut Signed-off-by: Ezequiel Garcia Reviewed-by: Marek Vasut --- arch/mips/Kconfig | 7 + arch/mips/Makefile | 1 + arch/mips/dts/jz4780.dtsi | 164 +++++++ arch/mips/mach-jz47xx/Kconfig | 15 + arch/mips/mach-jz47xx/Makefile | 5 + arch/mips/mach-jz47xx/include/mach/jz4780.h | 103 +++++ arch/mips/mach-jz47xx/include/mach/jz4780_dram.h | 456 +++++++++++++++++++ arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h | 12 + arch/mips/mach-jz47xx/jz4780/Makefile | 3 + arch/mips/mach-jz47xx/jz4780/TODO | 4 + arch/mips/mach-jz47xx/jz4780/gpio.c | 39 ++ arch/mips/mach-jz47xx/jz4780/jz4780.c | 83 ++++ arch/mips/mach-jz47xx/jz4780/pll.c | 530 +++++++++++++++++++++++ arch/mips/mach-jz47xx/jz4780/reset.c | 53 +++ arch/mips/mach-jz47xx/jz4780/sdram.c | 270 ++++++++++++ arch/mips/mach-jz47xx/jz4780/timer.c | 239 ++++++++++ arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds | 50 +++ arch/mips/mach-jz47xx/start.S | 98 +++++ 18 files changed, 2132 insertions(+) create mode 100644 arch/mips/dts/jz4780.dtsi create mode 100644 arch/mips/mach-jz47xx/Kconfig create mode 100644 arch/mips/mach-jz47xx/Makefile create mode 100644 arch/mips/mach-jz47xx/include/mach/jz4780.h create mode 100644 arch/mips/mach-jz47xx/include/mach/jz4780_dram.h create mode 100644 arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h create mode 100644 arch/mips/mach-jz47xx/jz4780/Makefile create mode 100644 arch/mips/mach-jz47xx/jz4780/TODO create mode 100644 arch/mips/mach-jz47xx/jz4780/gpio.c create mode 100644 arch/mips/mach-jz47xx/jz4780/jz4780.c create mode 100644 arch/mips/mach-jz47xx/jz4780/pll.c create mode 100644 arch/mips/mach-jz47xx/jz4780/reset.c create mode 100644 arch/mips/mach-jz47xx/jz4780/sdram.c create mode 100644 arch/mips/mach-jz47xx/jz4780/timer.c create mode 100644 arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds create mode 100644 arch/mips/mach-jz47xx/start.S (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index fe041f0b78..194f4f349e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -93,6 +93,12 @@ config ARCH_MT7620 select SUPPORTS_LITTLE_ENDIAN select SYSRESET +config ARCH_JZ47XX + bool "Support Ingenic JZ47xx" + select SUPPORT_SPL + select OF_CONTROL + select DM + config MACH_PIC32 bool "Support Microchip PIC32" select DM @@ -145,6 +151,7 @@ source "board/qemu-mips/Kconfig" source "arch/mips/mach-ath79/Kconfig" source "arch/mips/mach-mscc/Kconfig" source "arch/mips/mach-bmips/Kconfig" +source "arch/mips/mach-jz47xx/Kconfig" source "arch/mips/mach-pic32/Kconfig" source "arch/mips/mach-mt7620/Kconfig" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 124e93fa26..029d290f1e 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -13,6 +13,7 @@ libs-y += arch/mips/lib/ machine-$(CONFIG_ARCH_ATH79) += ath79 machine-$(CONFIG_ARCH_BMIPS) += bmips +machine-$(CONFIG_ARCH_JZ47XX) += jz47xx machine-$(CONFIG_MACH_PIC32) += pic32 machine-$(CONFIG_ARCH_MT7620) += mt7620 machine-$(CONFIG_ARCH_MSCC) += mscc diff --git a/arch/mips/dts/jz4780.dtsi b/arch/mips/dts/jz4780.dtsi new file mode 100644 index 0000000000..f62a7a95f8 --- /dev/null +++ b/arch/mips/dts/jz4780.dtsi @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ingenic,jz4780"; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + intc: interrupt-controller@10001000 { + compatible = "ingenic,jz4780-intc"; + reg = <0x10001000 0x50>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + ext: ext { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + rtc: rtc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + cgu: jz4780-cgu@10000000 { + compatible = "ingenic,jz4780-cgu"; + reg = <0x10000000 0x100>; + + clocks = <&ext>, <&rtc>; + clock-names = "ext", "rtc"; + + #clock-cells = <1>; + }; + + mmc0: mmc@13450000 { + compatible = "ingenic,jz4780-mmc"; + reg = <0x13450000 0x1000>; + + status = "disabled"; + + clocks = <&cgu JZ4780_CLK_MSC0>; + clock-names = "mmc"; + }; + + mmc1: mmc@13460000 { + compatible = "ingenic,jz4780-mmc"; + reg = <0x13460000 0x1000>; + + clocks = <&cgu JZ4780_CLK_MSC1>; + clock-names = "mmc"; + + status = "disabled"; + }; + + uart0: serial@10030000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10030000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <51>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART0>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart1: serial@10031000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10031000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <50>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART1>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart2: serial@10032000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10032000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <49>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART2>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart3: serial@10033000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10033000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <48>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART3>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + uart4: serial@10034000 { + compatible = "ingenic,jz4780-uart"; + reg = <0x10034000 0x100>; + reg-shift = <2>; + + interrupt-parent = <&intc>; + interrupts = <34>; + + clocks = <&ext>, <&cgu JZ4780_CLK_UART4>; + clock-names = "baud", "module"; + + status = "disabled"; + }; + + nemc: nemc@13410000 { + compatible = "ingenic,jz4780-nemc"; + reg = <0x13410000 0x10000>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <1 0 0x1b000000 0x1000000 + 2 0 0x1a000000 0x1000000 + 3 0 0x19000000 0x1000000 + 4 0 0x18000000 0x1000000 + 5 0 0x17000000 0x1000000 + 6 0 0x16000000 0x1000000>; + + clocks = <&cgu JZ4780_CLK_NEMC>; + + status = "disabled"; + }; + + bch: bch@134d0000 { + compatible = "ingenic,jz4780-bch"; + reg = <0x134d0000 0x10000>; + + clocks = <&cgu JZ4780_CLK_BCH>; + + status = "disabled"; + }; +}; diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig new file mode 100644 index 0000000000..cd6944cfc2 --- /dev/null +++ b/arch/mips/mach-jz47xx/Kconfig @@ -0,0 +1,15 @@ +menu "Ingenic JZ47xx platforms" + depends on ARCH_JZ47XX + +config SYS_SOC + default "jz47xx" + +config SOC_JZ4780 + bool + select SUPPORTS_LITTLE_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 + help + Support for Ingenic JZ4780 family SoCs. + +endmenu diff --git a/arch/mips/mach-jz47xx/Makefile b/arch/mips/mach-jz47xx/Makefile new file mode 100644 index 0000000000..dbb8229f78 --- /dev/null +++ b/arch/mips/mach-jz47xx/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ + +extra-$(CONFIG_SPL_BUILD) := start.o + +obj-$(CONFIG_SOC_JZ4780) += jz4780/ diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780.h b/arch/mips/mach-jz47xx/include/mach/jz4780.h new file mode 100644 index 0000000000..4422e503ed --- /dev/null +++ b/arch/mips/mach-jz47xx/include/mach/jz4780.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * JZ4780 definitions + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton + */ + +#ifndef __JZ4780_H__ +#define __JZ4780_H__ + +/* AHB0 BUS Devices */ +#define DDRC_BASE 0xb3010000 + +/* AHB2 BUS Devices */ +#define NEMC_BASE 0xb3410000 +#define BCH_BASE 0xb34d0000 + +/* APB BUS Devices */ +#define CPM_BASE 0xb0000000 +#define TCU_BASE 0xb0002000 +#define WDT_BASE 0xb0002000 +#define GPIO_BASE 0xb0010000 +#define UART0_BASE 0xb0030000 +#define UART1_BASE 0xb0031000 +#define UART2_BASE 0xb0032000 +#define UART3_BASE 0xb0033000 +#define MSC0_BASE 0xb3450000 +#define MSC1_BASE 0xb3460000 +#define MSC2_BASE 0xb3470000 + +/* + * GPIO + */ +/* n = 0,1,2,3,4,5 */ +#define GPIO_PXPIN(n) (0x00 + (n) * 0x100) +#define GPIO_PXINT(n) (0x10 + (n) * 0x100) +#define GPIO_PXINTS(n) (0x14 + (n) * 0x100) +#define GPIO_PXINTC(n) (0x18 + (n) * 0x100) +#define GPIO_PXMASK(n) (0x20 + (n) * 0x100) +#define GPIO_PXMASKS(n) (0x24 + (n) * 0x100) +#define GPIO_PXMASKC(n) (0x28 + (n) * 0x100) +#define GPIO_PXPAT1(n) (0x30 + (n) * 0x100) +#define GPIO_PXPAT1S(n) (0x34 + (n) * 0x100) +#define GPIO_PXPAT1C(n) (0x38 + (n) * 0x100) +#define GPIO_PXPAT0(n) (0x40 + (n) * 0x100) +#define GPIO_PXPAT0S(n) (0x44 + (n) * 0x100) +#define GPIO_PXPAT0C(n) (0x48 + (n) * 0x100) +#define GPIO_PXFLG(n) (0x50 + (n) * 0x100) +#define GPIO_PXFLGC(n) (0x54 + (n) * 0x100) +#define GPIO_PXOEN(n) (0x60 + (n) * 0x100) +#define GPIO_PXOENS(n) (0x64 + (n) * 0x100) +#define GPIO_PXOENC(n) (0x68 + (n) * 0x100) +#define GPIO_PXPEN(n) (0x70 + (n) * 0x100) +#define GPIO_PXPENS(n) (0x74 + (n) * 0x100) +#define GPIO_PXPENC(n) (0x78 + (n) * 0x100) +#define GPIO_PXDS(n) (0x80 + (n) * 0x100) +#define GPIO_PXDSS(n) (0x84 + (n) * 0x100) +#define GPIO_PXDSC(n) (0x88 + (n) * 0x100) + +/* PLL setup */ +#define JZ4780_SYS_EXTAL 48000000 +#define JZ4780_SYS_MEM_SPEED (CONFIG_SYS_MHZ * 1000000) +#define JZ4780_SYS_MEM_DIV 3 +#define JZ4780_SYS_AUDIO_SPEED (768 * 1000000) + +#define JZ4780_APLL_M 1 +#define JZ4780_APLL_N 1 +#define JZ4780_APLL_OD 1 + +#define JZ4780_MPLL_M (JZ4780_SYS_MEM_SPEED / JZ4780_SYS_EXTAL * 2) +#define JZ4780_MPLL_N 2 +#define JZ4780_MPLL_OD 1 + +#define JZ4780_EPLL_M (JZ4780_SYS_AUDIO_SPEED * 2 / JZ4780_SYS_EXTAL) +#define JZ4780_EPLL_N 1 +#define JZ4780_EPLL_OD 2 + +#define JZ4780_VPLL_M ((888 * 1000000) * 2 / JZ4780_SYS_EXTAL) +#define JZ4780_VPLL_N 1 +#define JZ4780_VPLL_OD 2 + +#ifndef __ASSEMBLY__ + +u32 sdram_size(int bank); + +const u32 jz4780_clk_get_efuse_clk(void); +void jz4780_clk_ungate_ethernet(void); +void jz4780_clk_ungate_mmc(void); +void jz4780_clk_ungate_uart(const unsigned int uart); + +void jz4780_efuse_read(size_t addr, size_t count, u8 *buf); +void jz4780_efuse_init(u32 ahb2_rate); + +void jz4780_tcu_wdt_start(void); + +#ifdef CONFIG_SPL_BUILD +int jz_mmc_init(void __iomem *base); +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __JZ4780_H__ */ diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h new file mode 100644 index 0000000000..92d431bd04 --- /dev/null +++ b/arch/mips/mach-jz47xx/include/mach/jz4780_dram.h @@ -0,0 +1,456 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * JZ4780 DDR initialization - parameters definitions + * + * Copyright (c) 2015 Imagination Technologies + * Author: Matt Redfearn + */ + +#ifndef __JZ4780_DRAM_H__ +#define __JZ4780_DRAM_H__ + +/* + * DDR + */ +#define DDRC_ST 0x0 +#define DDRC_CFG 0x4 +#define DDRC_CTRL 0x8 +#define DDRC_LMR 0xc +#define DDRC_REFCNT 0x18 +#define DDRC_DQS 0x1c +#define DDRC_DQS_ADJ 0x20 +#define DDRC_MMAP0 0x24 +#define DDRC_MMAP1 0x28 +#define DDRC_MDELAY 0x2c +#define DDRC_CKEL 0x30 +#define DDRC_PMEMCTRL0 0x54 +#define DDRC_PMEMCTRL1 0x50 +#define DDRC_PMEMCTRL2 0x58 +#define DDRC_PMEMCTRL3 0x5c + +#define DDRC_TIMING(n) (0x60 + 4 * (n)) +#define DDRC_REMMAP(n) (0x9c + 4 * (n)) + +/* + * DDR PHY + */ +#define DDR_MEM_PHY_BASE 0x20000000 +#define DDR_PHY_OFFSET 0x1000 + +#define DDRP_PIR 0x4 +#define DDRP_PGCR 0x8 +#define DDRP_PGSR 0xc + +#define DDRP_PTR0 0x18 +#define DDRP_PTR1 0x1c +#define DDRP_PTR2 0x20 + +#define DDRP_ACIOCR 0x24 +#define DDRP_DXCCR 0x28 +#define DDRP_DSGCR 0x2c +#define DDRP_DCR 0x30 + +#define DDRP_DTPR0 0x34 +#define DDRP_DTPR1 0x38 +#define DDRP_DTPR2 0x3c +#define DDRP_MR0 0x40 +#define DDRP_MR1 0x44 +#define DDRP_MR2 0x48 +#define DDRP_MR3 0x4c + +#define DDRP_ODTCR 0x50 +#define DDRP_DTAR 0x54 +#define DDRP_DTDR0 0x58 +#define DDRP_DTDR1 0x5c + +#define DDRP_DCUAR 0xc0 +#define DDRP_DCUDR 0xc4 +#define DDRP_DCURR 0xc8 +#define DDRP_DCULR 0xcc +#define DDRP_DCUGCR 0xd0 +#define DDRP_DCUTPR 0xd4 +#define DDRP_DCUSR0 0xd8 +#define DDRP_DCUSR1 0xdc + +#define DDRP_ZQXCR0(n) (0x180 + ((n) * 0x10)) +#define DDRP_ZQXCR1(n) (0x184 + ((n) * 0x10)) +#define DDRP_ZQXSR0(n) (0x188 + ((n) * 0x10)) +#define DDRP_ZQXSR1(n) (0x18c + ((n) * 0x10)) + +#define DDRP_DXGCR(n) (0x1c0 + ((n) * 0x40)) +#define DDRP_DXGSR0(n) (0x1c4 + ((n) * 0x40)) +#define DDRP_DXGSR1(n) (0x1c8 + ((n) * 0x40)) +#define DDRP_DXDQSTR(n) (0x1d4 + ((n) * 0x40)) + +/* DDRC Status Register */ +#define DDRC_ST_ENDIAN BIT(7) +#define DDRC_ST_DPDN BIT(5) +#define DDRC_ST_PDN BIT(4) +#define DDRC_ST_AREF BIT(3) +#define DDRC_ST_SREF BIT(2) +#define DDRC_ST_CKE1 BIT(1) +#define DDRC_ST_CKE0 BIT(0) + +/* DDRC Configure Register */ +#define DDRC_CFG_ROW1_BIT 27 +#define DDRC_CFG_ROW1_MASK (0x7 << DDRC_CFG_ROW1_BIT) +#define DDRC_CFG_COL1_BIT 24 +#define DDRC_CFG_COL1_MASK (0x7 << DDRC_CFG_COL1_BIT) +#define DDRC_CFG_BA1 BIT(23) +#define DDRC_CFG_IMBA BIT(22) +#define DDRC_CFG_BL_8 BIT(21) + +#define DDRC_CFG_TYPE_BIT 17 +#define DDRC_CFG_TYPE_MASK (0x7 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_DDR1 (2 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_MDDR (3 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_DDR2 (4 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_LPDDR2 (5 << DDRC_CFG_TYPE_BIT) +#define DDRC_CFG_TYPE_DDR3 (6 << DDRC_CFG_TYPE_BIT) + +#define DDRC_CFG_ODT_EN BIT(16) + +#define DDRC_CFG_MPRT BIT(15) + +#define DDRC_CFG_ROW_BIT 11 +#define DDRC_CFG_ROW_MASK (0x7 << DDRC_CFG_ROW_BIT) +#define DDRC_CFG_ROW_12 (0 << DDRC_CFG_ROW_BIT) +#define DDRC_CFG_ROW_13 (1 << DDRC_CFG_ROW_BIT) +#define DDRC_CFG_ROW_14 (2 << DDRC_CFG_ROW_BIT) + +#define DDRC_CFG_COL_BIT 8 +#define DDRC_CFG_COL_MASK (0x7 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_8 (0 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_9 (1 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_10 (2 << DDRC_CFG_COL_BIT) +#define DDRC_CFG_COL_11 (3 << DDRC_CFG_COL_BIT) + +#define DDRC_CFG_CS1EN BIT(7) +#define DDRC_CFG_CS0EN BIT(6) +#define DDRC_CFG_CL_BIT 2 +#define DDRC_CFG_CL_MASK (0xf << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_3 (0 << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_4 (1 << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_5 (2 << DDRC_CFG_CL_BIT) +#define DDRC_CFG_CL_6 (3 << DDRC_CFG_CL_BIT) + +#define DDRC_CFG_BA BIT(1) +#define DDRC_CFG_DW BIT(0) + +/* DDRC Control Register */ +#define DDRC_CTRL_DFI_RST BIT(23) +#define DDRC_CTRL_DLL_RST BIT(22) +#define DDRC_CTRL_CTL_RST BIT(21) +#define DDRC_CTRL_CFG_RST BIT(20) +#define DDRC_CTRL_ACTPD BIT(15) +#define DDRC_CTRL_PDT_BIT 12 +#define DDRC_CTRL_PDT_MASK (0x7 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_DIS (0 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_8 (1 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_16 (2 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_32 (3 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_64 (4 << DDRC_CTRL_PDT_BIT) +#define DDRC_CTRL_PDT_128 (5 << DDRC_CTRL_PDT_BIT) + +#define DDRC_CTRL_PRET_BIT 8 +#define DDRC_CTRL_PRET_MASK (0x7 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_DIS (0 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_8 (1 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_16 (2 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_32 (3 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_64 (4 << DDRC_CTRL_PRET_BIT) +#define DDRC_CTRL_PRET_128 (5 << DDRC_CTRL_PRET_BIT) + +#define DDRC_CTRL_DPD BIT(6) +#define DDRC_CTRL_SR BIT(5) +#define DDRC_CTRL_UNALIGN BIT(4) +#define DDRC_CTRL_ALH BIT(3) +#define DDRC_CTRL_RDC BIT(2) +#define DDRC_CTRL_CKE BIT(1) +#define DDRC_CTRL_RESET BIT(0) + +/* DDRC Load-Mode-Register */ +#define DDRC_LMR_DDR_ADDR_BIT 16 +#define DDRC_LMR_DDR_ADDR_MASK (0x3fff << DDRC_LMR_DDR_ADDR_BIT) + +#define DDRC_LMR_BA_BIT 8 +#define DDRC_LMR_BA_MASK (0x7 << DDRC_LMR_BA_BIT) +/* For DDR2 */ +#define DDRC_LMR_BA_MRS (0 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_EMRS1 (1 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_EMRS2 (2 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_EMRS3 (3 << DDRC_LMR_BA_BIT) +/* For mobile DDR */ +#define DDRC_LMR_BA_M_MRS (0 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_M_EMRS (2 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_M_SR (1 << DDRC_LMR_BA_BIT) +/* For Normal DDR1 */ +#define DDRC_LMR_BA_N_MRS (0 << DDRC_LMR_BA_BIT) +#define DDRC_LMR_BA_N_EMRS (1 << DDRC_LMR_BA_BIT) + +#define DDRC_LMR_CMD_BIT 4 +#define DDRC_LMR_CMD_MASK (0x3 << DDRC_LMR_CMD_BIT) +#define DDRC_LMR_CMD_PREC (0 << DDRC_LMR_CMD_BIT) +#define DDRC_LMR_CMD_AUREF (1 << DDRC_LMR_CMD_BIT) +#define DDRC_LMR_CMD_LMR (2 << DDRC_LMR_CMD_BIT) + +#define DDRC_LMR_START BIT(0) + +/* DDRC Timing Config Register 1 */ +#define DDRC_TIMING1_TRTP_BIT 24 +#define DDRC_TIMING1_TRTP_MASK (0x3f << DDRC_TIMING1_TRTP_BIT) +#define DDRC_TIMING1_TWTR_BIT 16 +#define DDRC_TIMING1_TWTR_MASK (0x3f << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_1 (0 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_2 (1 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_3 (2 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWTR_4 (3 << DDRC_TIMING1_TWTR_BIT) +#define DDRC_TIMING1_TWR_BIT 8 +#define DDRC_TIMING1_TWR_MASK (0x3f << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_1 (0 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_2 (1 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_3 (2 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_4 (3 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_5 (4 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWR_6 (5 << DDRC_TIMING1_TWR_BIT) +#define DDRC_TIMING1_TWL_BIT 0 +#define DDRC_TIMING1_TWL_MASK (0x3f << DDRC_TIMING1_TWL_BIT) + +/* DDRC Timing Config Register 2 */ +#define DDRC_TIMING2_TCCD_BIT 24 +#define DDRC_TIMING2_TCCD_MASK (0x3f << DDRC_TIMING2_TCCD_BIT) +#define DDRC_TIMING2_TRAS_BIT 16 +#define DDRC_TIMING2_TRAS_MASK (0x3f << DDRC_TIMING2_TRAS_BIT) +#define DDRC_TIMING2_TRCD_BIT 8 +#define DDRC_TIMING2_TRCD_MASK (0x3f << DDRC_TIMING2_TRCD_BIT) +#define DDRC_TIMING2_TRL_BIT 0 +#define DDRC_TIMING2_TRL_MASK (0x3f << DDRC_TIMING2_TRL_BIT) + +/* DDRC Timing Config Register 3 */ +#define DDRC_TIMING3_ONUM 27 +#define DDRC_TIMING3_TCKSRE_BIT 24 +#define DDRC_TIMING3_TCKSRE_MASK (0x3f << DDRC_TIMING3_TCKSRE_BIT) +#define DDRC_TIMING3_TRP_BIT 16 +#define DDRC_TIMING3_TRP_MASK (0x3f << DDRC_TIMING3_TRP_BIT) +#define DDRC_TIMING3_TRRD_BIT 8 +#define DDRC_TIMING3_TRRD_MASK (0x3f << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_DISABLE (0 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_2 (1 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_3 (2 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRRD_4 (3 << DDRC_TIMING3_TRRD_BIT) +#define DDRC_TIMING3_TRC_BIT 0 +#define DDRC_TIMING3_TRC_MASK (0x3f << DDRC_TIMING3_TRC_BIT) + +/* DDRC Timing Config Register 4 */ +#define DDRC_TIMING4_TRFC_BIT 24 +#define DDRC_TIMING4_TRFC_MASK (0x3f << DDRC_TIMING4_TRFC_BIT) +#define DDRC_TIMING4_TEXTRW_BIT 21 +#define DDRC_TIMING4_TEXTRW_MASK (0x7 << DDRC_TIMING4_TEXTRW_BIT) +#define DDRC_TIMING4_TRWCOV_BIT 19 +#define DDRC_TIMING4_TRWCOV_MASK (0x3 << DDRC_TIMING4_TRWCOV_BIT) +#define DDRC_TIMING4_TCKE_BIT 16 +#define DDRC_TIMING4_TCKE_MASK (0x7 << DDRC_TIMING4_TCKE_BIT) +#define DDRC_TIMING4_TMINSR_BIT 8 +#define DDRC_TIMING4_TMINSR_MASK (0xf << DDRC_TIMING4_TMINSR_BIT) +#define DDRC_TIMING4_TXP_BIT 4 +#define DDRC_TIMING4_TXP_MASK (0x7 << DDRC_TIMING4_TXP_BIT) +#define DDRC_TIMING4_TMRD_BIT 0 +#define DDRC_TIMING4_TMRD_MASK (0x3 << DDRC_TIMING4_TMRD_BIT) + +/* DDRC Timing Config Register 5 */ +#define DDRC_TIMING5_TCTLUPD_BIT 24 +#define DDRC_TIMING4_TCTLUPD_MASK (0x3f << DDRC_TIMING5_TCTLUDP_BIT) +#define DDRC_TIMING5_TRTW_BIT 16 +#define DDRC_TIMING5_TRTW_MASK (0x3f << DDRC_TIMING5_TRTW_BIT) +#define DDRC_TIMING5_TRDLAT_BIT 8 +#define DDRC_TIMING5_TRDLAT_MASK (0x3f << DDRC_TIMING5_TRDLAT_BIT) +#define DDRC_TIMING5_TWDLAT_BIT 0 +#define DDRC_TIMING5_TWDLAT_MASK (0x3f << DDRC_TIMING5_TWDLAT_BIT) + +/* DDRC Timing Config Register 6 */ +#define DDRC_TIMING6_TXSRD_BIT 24 +#define DDRC_TIMING6_TXSRD_MASK (0x3f << DDRC_TIMING6_TXSRD_BIT) +#define DDRC_TIMING6_TFAW_BIT 16 +#define DDRC_TIMING6_TFAW_MASK (0x3f << DDRC_TIMING6_TFAW_BIT) +#define DDRC_TIMING6_TCFGW_BIT 8 +#define DDRC_TIMING6_TCFGW_MASK (0x3f << DDRC_TIMING6_TCFGW_BIT) +#define DDRC_TIMING6_TCFGR_BIT 0 +#define DDRC_TIMING6_TCFGR_MASK (0x3f << DDRC_TIMING6_TCFGR_BIT) + +/* DDRC Auto-Refresh Counter */ +#define DDRC_REFCNT_CON_BIT 16 +#define DDRC_REFCNT_CON_MASK (0xff << DDRC_REFCNT_CON_BIT) +#define DDRC_REFCNT_CNT_BIT 8 +#define DDRC_REFCNT_CNT_MASK (0xff << DDRC_REFCNT_CNT_BIT) +#define DDRC_REFCNT_CLKDIV_BIT 1 +#define DDRC_REFCNT_CLKDIV_MASK (0x7 << DDRC_REFCNT_CLKDIV_BIT) +#define DDRC_REFCNT_REF_EN BIT(0) + +/* DDRC DQS Delay Control Register */ +#define DDRC_DQS_ERROR BIT(29) +#define DDRC_DQS_READY BIT(28) +#define DDRC_DQS_AUTO BIT(23) +#define DDRC_DQS_DET BIT(24) +#define DDRC_DQS_SRDET BIT(25) +#define DDRC_DQS_CLKD_BIT 16 +#define DDRC_DQS_CLKD_MASK (0x3f << DDRC_DQS_CLKD_BIT) +#define DDRC_DQS_WDQS_BIT 8 +#define DDRC_DQS_WDQS_MASK (0x3f << DDRC_DQS_WDQS_BIT) +#define DDRC_DQS_RDQS_BIT 0 +#define DDRC_DQS_RDQS_MASK (0x3f << DDRC_DQS_RDQS_BIT) + +/* DDRC DQS Delay Adjust Register */ +#define DDRC_DQS_ADJWDQS_BIT 8 +#define DDRC_DQS_ADJWDQS_MASK (0x1f << DDRC_DQS_ADJWDQS_BIT) +#define DDRC_DQS_ADJRDQS_BIT 0 +#define DDRC_DQS_ADJRDQS_MASK (0x1f << DDRC_DQS_ADJRDQS_BIT) + +/* DDRC Memory Map Config Register */ +#define DDRC_MMAP_BASE_BIT 8 +#define DDRC_MMAP_BASE_MASK (0xff << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP_MASK_BIT 0 +#define DDRC_MMAP_MASK_MASK (0xff << DDRC_MMAP_MASK_BIT) + +#define DDRC_MMAP0_BASE (0x20 << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP1_BASE_64M (0x24 << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP1_BASE_128M (0x28 << DDRC_MMAP_BASE_BIT) +#define DDRC_MMAP1_BASE_256M (0x30 << DDRC_MMAP_BASE_BIT) + +#define DDRC_MMAP_MASK_64_64 (0xfc << DDRC_MMAP_MASK_BIT) +#define DDRC_MMAP_MASK_128_128 (0xf8 << DDRC_MMAP_MASK_BIT) +#define DDRC_MMAP_MASK_256_256 (0xf0 << DDRC_MMAP_MASK_BIT) + +/* DDRP PHY Initialization Register */ +#define DDRP_PIR_INIT BIT(0) +#define DDRP_PIR_DLLSRST BIT(1) +#define DDRP_PIR_DLLLOCK BIT(2) +#define DDRP_PIR_ZCAL BIT(3) +#define DDRP_PIR_ITMSRST BIT(4) +#define DDRP_PIR_DRAMRST BIT(5) +#define DDRP_PIR_DRAMINT BIT(6) +#define DDRP_PIR_QSTRN BIT(7) +#define DDRP_PIR_EYETRN BIT(8) +#define DDRP_PIR_DLLBYP BIT(17) +/* DDRP PHY General Configurate Register */ +#define DDRP_PGCR_ITMDMD BIT(0) +#define DDRP_PGCR_DQSCFG BIT(1) +#define DDRP_PGCR_DFTCMP BIT(2) +#define DDRP_PGCR_DFTLMT_BIT 3 +#define DDRP_PGCR_DTOSEL_BIT 5 +#define DDRP_PGCR_CKEN_BIT 9 +#define DDRP_PGCR_CKDV_BIT 12 +#define DDRP_PGCR_CKINV BIT(14) +#define DDRP_PGCR_RANKEN_BIT 18 +#define DDRP_PGCR_ZCKSEL_32 (2 << 22) +#define DDRP_PGCR_PDDISDX BIT(24) +/* DDRP PHY General Status Register */ +#define DDRP_PGSR_IDONE BIT(0) +#define DDRP_PGSR_DLDONE BIT(1) +#define DDRP_PGSR_ZCDONE BIT(2) +#define DDRP_PGSR_DIDONE BIT(3) +#define DDRP_PGSR_DTDONE BIT(4) +#define DDRP_PGSR_DTERR BIT(5) +#define DDRP_PGSR_DTIERR BIT(6) +#define DDRP_PGSR_DFTEERR BIT(7) +/* DDRP DRAM Configuration Register */ +#define DDRP_DCR_TYPE_BIT 0 +#define DDRP_DCR_TYPE_MASK (0x7 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_MDDR (0 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_DDR (1 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_DDR2 (2 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_DDR3 (3 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_TYPE_LPDDR2 (4 << DDRP_DCR_TYPE_BIT) +#define DDRP_DCR_DDR8BNK_BIT 3 +#define DDRP_DCR_DDR8BNK_MASK (1 << DDRP_DCR_DDR8BNK_BIT) +#define DDRP_DCR_DDR8BNK (1 << DDRP_DCR_DDR8BNK_BIT) +#define DDRP_DCR_DDR8BNK_DIS (0 << DDRP_DCR_DDR8BNK_BIT) + +#define DRP_DTRP1_RTODT BIT(11) + +#define DDRP_DXGCR_DXEN BIT(0) + +#define DDRP_ZQXCR_ZDEN_BIT 28 +#define DDRP_ZQXCR_ZDEN (1 << DDRP_ZQXCR_ZDEN_BIT) +#define DDRP_ZQXCR_PULLUP_IMPE_BIT 5 +#define DDRP_ZQXCR_PULLDOWN_IMPE_BIT 0 + +/* DDR3 Mode Register Set */ +#define DDR3_MR0_BL_BIT 0 +#define DDR3_MR0_BL_MASK (3 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BL_8 (0 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BL_fly (1 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BL_4 (2 << DDR3_MR0_BL_BIT) +#define DDR3_MR0_BT_BIT 3 +#define DDR3_MR0_BT_MASK (1 << DDR3_MR0_BT_BIT) +#define DDR3_MR0_BT_SEQ (0 << DDR3_MR0_BT_BIT) +#define DDR3_MR0_BT_INTER (1 << DDR3_MR0_BT_BIT) +#define DDR3_MR0_WR_BIT 9 + +#define DDR3_MR1_DLL_DISABLE 1 +#define DDR3_MR1_DIC_6 (0 << 5 | 0 << 1) +#define DDR3_MR1_DIC_7 (0 << 5 | BIT(1)) +#define DDR3_MR1_RTT_DIS (0 << 9 | 0 << 6 | 0 << 2) +#define DDR3_MR1_RTT_4 (0 << 9 | 0 << 6 | BIT(2)) +#define DDR3_MR1_RTT_2 (0 << 9 | BIT(6) | 0 << 2) +#define DDR3_MR1_RTT_6 (0 << 9 | BIT(6) | BIT(2)) +#define DDR3_MR1_RTT_12 (BIT(9) | 0 << 6 | 0 << 2) +#define DDR3_MR1_RTT_8 (BIT(9) | 0 << 6 | BIT(2)) + +#define DDR3_MR2_CWL_BIT 3 + +/* Parameters common to all RAM devices used */ + +/* Chip Select */ +/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */ +#define DDR_CS0EN 1 +/* CSEN : whether a ddr chip exists 0 - un-used, 1 - used */ +#define DDR_CS1EN 0 + +/* ROW : 12 to 18 row address, 1G only 512MB */ +#define DDR_ROW 15 +/* COL : 8 to 14 column address */ +#define DDR_COL 10 +/* Banks each chip: 0-4bank, 1-8bank */ +#define DDR_BANK8 1 +/* 0 - 16-bit data width, 1 - 32-bit data width */ +#define DDR_DW32 1 + +/* Refresh period: 64ms / 32768 = 1.95 us , 2 ^ 15 = 32768 */ +#define DDR_tREFI 7800 +/* Clock Divider */ +#define DDR_CLK_DIV 1 + +/* DDR3 Burst length: 0 - 8 burst, 2 - 4 burst , 1 - 4 or 8 (on the fly) */ +#define DDR_BL 8 + +/* CAS latency: 5 to 14, tCK */ +#define DDR_CL 6 +/* DDR3 only: CAS Write Latency, 5 to 8 */ +#define DDR_tCWL (DDR_CL - 1) + +/* Structure representing per-RAM type configuration */ + +struct jz4780_ddr_config { + u32 timing[6]; /* Timing1..6 register value */ + + /* DDR PHY control */ + u16 mr0; /* Mode Register 0 */ + u16 mr1; /* Mode Register 1 */ + + u32 ptr0; /* PHY Timing Register 0 */ + u32 ptr1; /* PHY Timing Register 1 */ + u32 ptr2; /* PHY Timing Register 1 */ + + u32 dtpr0; /* DRAM Timing Parameters Register 0 */ + u32 dtpr1; /* DRAM Timing Parameters Register 1 */ + u32 dtpr2; /* DRAM Timing Parameters Register 2 */ + + u8 pullup; /* PHY pullup impedance */ + u8 pulldn; /* PHY pulldown impedance */ +}; + +void pll_init(void); +void sdram_init(void); + +#endif /* __JZ4780_DRAM_H__ */ + diff --git a/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h b/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h new file mode 100644 index 0000000000..37f0892f7b --- /dev/null +++ b/arch/mips/mach-jz47xx/include/mach/jz4780_gpio.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __JZ4780_GPIO_H__ +#define __JZ4780_GPIO_H__ + +#define JZ_GPIO(bank, pin) ((32 * (bank)) + (pin)) + +int jz47xx_gpio_get_value(unsigned int gpio); +void jz47xx_gpio_direction_input(unsigned int gpio); +void jz47xx_gpio_direction_output(unsigned int gpio, int value); + +#endif diff --git a/arch/mips/mach-jz47xx/jz4780/Makefile b/arch/mips/mach-jz47xx/jz4780/Makefile new file mode 100644 index 0000000000..5b3c354327 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := gpio.o jz4780.o pll.o reset.o sdram.o timer.o diff --git a/arch/mips/mach-jz47xx/jz4780/TODO b/arch/mips/mach-jz47xx/jz4780/TODO new file mode 100644 index 0000000000..99ad6225b0 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/TODO @@ -0,0 +1,4 @@ +- dm gpio driver +- ethernet driver for the dm9000 +- reduce the hundreds of definitions of register addresses to the ones really needed in assembly or SPL. +- define the remaining register base addresses as physical addresses and establish a mapping with ioremap_nocache() diff --git a/arch/mips/mach-jz47xx/jz4780/gpio.c b/arch/mips/mach-jz47xx/jz4780/gpio.c new file mode 100644 index 0000000000..cee2328ab1 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/gpio.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include + +int jz47xx_gpio_get_value(unsigned int gpio) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + int port = gpio / 32; + int pin = gpio % 32; + + return readl(gpio_regs + GPIO_PXPIN(port)) & BIT(pin); +} + +void jz47xx_gpio_direction_input(unsigned int gpio) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + int port = gpio / 32; + int pin = gpio % 32; + + writel(BIT(pin), gpio_regs + GPIO_PXINTC(port)); + writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port)); + writel(BIT(pin), gpio_regs + GPIO_PXPAT1S(port)); +} + +void jz47xx_gpio_direction_output(unsigned int gpio, int value) +{ + void __iomem *gpio_regs = (void __iomem *)GPIO_BASE; + int port = gpio / 32; + int pin = gpio % 32; + + writel(BIT(pin), gpio_regs + GPIO_PXINTC(port)); + writel(BIT(pin), gpio_regs + GPIO_PXMASKS(port)); + writel(BIT(pin), gpio_regs + GPIO_PXPAT1C(port)); + writel(BIT(pin), gpio_regs + + (value ? GPIO_PXPAT0S(port) : GPIO_PXPAT0C(port))); +} diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c new file mode 100644 index 0000000000..dbd328cb49 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 common routines + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SPL_BUILD +/* Pointer to the global data structure for SPL */ +DECLARE_GLOBAL_DATA_PTR; +gd_t gdata __attribute__ ((section(".bss"))); + +void board_init_f(ulong dummy) +{ + typedef void __noreturn (*image_entry_noargs_t)(void); + struct mmc *mmc; + unsigned long count; + struct image_header *header; + int ret; + + /* Set global data pointer */ + gd = &gdata; + + timer_init(); + pll_init(); + sdram_init(); + enable_caches(); + + /* Clear the BSS */ + memset(__bss_start, 0, (char *)&__bss_end - __bss_start); + + gd->flags |= GD_FLG_SPL_INIT; + + ret = mmc_initialize(NULL); + if (ret) + hang(); + + mmc = find_mmc_device(BOOT_DEVICE_MMC1); + if (ret) + hang(); + + ret = mmc_init(mmc); + if (ret) + hang(); + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + count = blk_dread(mmc_get_blk_desc(mmc), + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, + 0x800, header); + if (count == 0) + hang(); + + image_entry_noargs_t image_entry = + (image_entry_noargs_t)CONFIG_SYS_TEXT_BASE; + + image_entry(); + + hang(); +} +#endif /* CONFIG_SPL_BUILD */ + +ulong board_get_usable_ram_top(ulong total_size) +{ + return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024); +} + +int print_cpuinfo(void) +{ + printf("CPU: Ingenic JZ4780\n"); + return 0; +} diff --git a/arch/mips/mach-jz47xx/jz4780/pll.c b/arch/mips/mach-jz47xx/jz4780/pll.c new file mode 100644 index 0000000000..9a46198f36 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/pll.c @@ -0,0 +1,530 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 PLL setup + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton + */ + +#include +#include +#include +#include + +#define CPM_CPCCR 0x00 +#define CPM_LCR 0x04 +#define CPM_RSR 0x08 +#define CPM_CPPCR 0x0c +#define CPM_CPAPCR 0x10 +#define CPM_CPMPCR 0x14 +#define CPM_CPEPCR 0x18 +#define CPM_CPVPCR 0x1c +#define CPM_CLKGR0 0x20 +#define CPM_OPCR 0x24 +#define CPM_CLKGR1 0x28 +#define CPM_DDCDR 0x2c +#define CPM_VPUCDR 0x30 +#define CPM_CPSPR 0x34 +#define CPM_CPSPPR 0x38 +#define CPM_USBPCR 0x3c +#define CPM_USBRDT 0x40 +#define CPM_USBVBFIL 0x44 +#define CPM_USBPCR1 0x48 +#define CPM_USBCDR 0x50 +#define CPM_LPCDR 0x54 +#define CPM_I2SCDR 0x60 +#define CPM_LPCDR1 0x64 +#define CPM_MSCCDR 0x68 +#define CPM_UHCCDR 0x6c +#define CPM_SSICDR 0x74 +#define CPM_CIMCDR 0x7c +#define CPM_PCMCDR 0x84 +#define CPM_GPUCDR 0x88 +#define CPM_HDMICDR 0x8c +#define CPM_I2S1CDR 0xa0 +#define CPM_MSCCDR1 0xa4 +#define CPM_MSCCDR2 0xa8 +#define CPM_BCHCDR 0xac +#define CPM_SPCR0 0xb8 +#define CPM_SPCR1 0xbc +#define CPM_CPCSR 0xd4 +#define CPM_PSWCST(n) ((0x4 * (n)) + 0x90) + +/* Clock control register */ +#define CPM_CPCCR_SEL_SRC_BIT 30 +#define CPM_CPCCR_SEL_SRC_MASK (0x3 << CPM_CPCCR_SEL_SRC_BIT) +#define CPM_SRC_SEL_STOP 0 +#define CPM_SRC_SEL_APLL 1 +#define CPM_SRC_SEL_EXCLK 2 +#define CPM_SRC_SEL_RTCLK 3 +#define CPM_CPCCR_SEL_CPLL_BIT 28 +#define CPM_CPCCR_SEL_CPLL_MASK (0x3 << CPM_CPCCR_SEL_CPLL_BIT) +#define CPM_CPCCR_SEL_H0PLL_BIT 26 +#define CPM_CPCCR_SEL_H0PLL_MASK (0x3 << CPM_CPCCR_SEL_H0PLL_BIT) +#define CPM_CPCCR_SEL_H2PLL_BIT 24 +#define CPM_CPCCR_SEL_H2PLL_MASK (0x3 << CPM_CPCCR_SEL_H2PLL_BIT) +#define CPM_PLL_SEL_STOP 0 +#define CPM_PLL_SEL_SRC 1 +#define CPM_PLL_SEL_MPLL 2 +#define CPM_PLL_SEL_EPLL 3 +#define CPM_CPCCR_CE_CPU (0x1 << 22) +#define CPM_CPCCR_CE_AHB0 (0x1 << 21) +#define CPM_CPCCR_CE_AHB2 (0x1 << 20) +#define CPM_CPCCR_PDIV_BIT 16 +#define CPM_CPCCR_PDIV_MASK (0xf << CPM_CPCCR_PDIV_BIT) +#define CPM_CPCCR_H2DIV_BIT 12 +#define CPM_CPCCR_H2DIV_MASK (0xf << CPM_CPCCR_H2DIV_BIT) +#define CPM_CPCCR_H0DIV_BIT 8 +#define CPM_CPCCR_H0DIV_MASK (0x0f << CPM_CPCCR_H0DIV_BIT) +#define CPM_CPCCR_L2DIV_BIT 4 +#define CPM_CPCCR_L2DIV_MASK (0x0f << CPM_CPCCR_L2DIV_BIT) +#define CPM_CPCCR_CDIV_BIT 0 +#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT) + +/* Clock Status register */ +#define CPM_CPCSR_H2DIV_BUSY BIT(2) +#define CPM_CPCSR_H0DIV_BUSY BIT(1) +#define CPM_CPCSR_CDIV_BUSY BIT(0) + +/* PLL control register */ +#define CPM_CPPCR_PLLST_BIT 0 +#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT) + +/* XPLL control register */ +#define CPM_CPXPCR_XPLLM_BIT 19 +#define CPM_CPXPCR_XPLLM_MASK (0x1fff << CPM_CPXPCR_XPLLM_BIT) +#define CPM_CPXPCR_XPLLN_BIT 13 +#define CPM_CPXPCR_XPLLN_MASK (0x3f << CPM_CPXPCR_XPLLN_BIT) +#define CPM_CPXPCR_XPLLOD_BIT 9 +#define CPM_CPXPCR_XPLLOD_MASK (0xf << CPM_CPXPCR_XPLLOD_BIT) +#define CPM_CPXPCR_XLOCK BIT(6) +#define CPM_CPXPCR_XPLL_ON BIT(4) +#define CPM_CPXPCR_XF_MODE BIT(3) +#define CPM_CPXPCR_XPLLBP BIT(1) +#define CPM_CPXPCR_XPLLEN BIT(0) + +/* CPM scratch protected register */ +#define CPM_CPSPPR_BIT 0 +#define CPM_CPSPPR_MASK (0xffff << CPM_CPSPPR_BIT) + +/* USB parameter control register */ +#define CPM_USBPCR_USB_MODE BIT(31) /* 1: OTG, 0: UDC*/ +#define CPM_USBPCR_AVLD_REG BIT(30) +#define CPM_USBPCR_IDPULLUP_MASK_BIT 28 +#define CPM_USBPCR_IDPULLUP_MASK_MASK (0x02 << IDPULLUP_MASK_BIT) +#define CPM_USBPCR_INCR_MASK BIT(27) +#define CPM_USBPCR_CLK12_EN BIT(26) +#define CPM_USBPCR_COMMONONN BIT(25) +#define CPM_USBPCR_VBUSVLDEXT BIT(24) +#define CPM_USBPCR_VBUSVLDEXTSEL BIT(23) +#define CPM_USBPCR_POR BIT(22) +#define CPM_USBPCR_SIDDQ BIT(21) +#define CPM_USBPCR_OTG_DISABLE BIT(20) +#define CPM_USBPCR_COMPDISTUNE_BIT 17 +#define CPM_USBPCR_COMPDISTUNE_MASK (0x07 << COMPDISTUNE_BIT) +#define CPM_USBPCR_OTGTUNE_BIT 14 +#define CPM_USBPCR_OTGTUNE_MASK (0x07 << OTGTUNE_BIT) +#define CPM_USBPCR_SQRXTUNE_BIT 11 +#define CPM_USBPCR_SQRXTUNE_MASK (0x7x << SQRXTUNE_BIT) +#define CPM_USBPCR_TXFSLSTUNE_BIT 7 +#define CPM_USBPCR_TXFSLSTUNE_MASK (0x0f << TXFSLSTUNE_BIT) +#define CPM_USBPCR_TXPREEMPHTUNE BIT(6) +#define CPM_USBPCR_TXRISETUNE_BIT 4 +#define CPM_USBPCR_TXRISETUNE_MASK (0x03 << TXRISETUNE_BIT) +#define CPM_USBPCR_TXVREFTUNE_BIT 0 +#define CPM_USBPCR_TXVREFTUNE_MASK (0x0f << TXVREFTUNE_BIT) + +/* DDR memory clock divider register */ +#define CPM_DDRCDR_DCS_BIT 30 +#define CPM_DDRCDR_DCS_MASK (0x3 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_DCS_STOP (0x0 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_DCS_SRC (0x1 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_DCS_MPLL (0x2 << CPM_DDRCDR_DCS_BIT) +#define CPM_DDRCDR_CE_DDR BIT(29) +#define CPM_DDRCDR_DDR_BUSY BIT(28) +#define CPM_DDRCDR_DDR_STOP BIT(27) +#define CPM_DDRCDR_DDRDIV_BIT 0 +#define CPM_DDRCDR_DDRDIV_MASK (0xf << CPM_DDRCDR_DDRDIV_BIT) + +/* USB reset detect timer register */ +#define CPM_USBRDT_VBFIL_LD_EN BIT(25) +#define CPM_USBRDT_IDDIG_EN BIT(24) +#define CPM_USBRDT_IDDIG_REG BIT(23) +#define CPM_USBRDT_USBRDT_BIT 0 +#define CPM_USBRDT_USBRDT_MASK (0x7fffff << CPM_USBRDT_USBRDT_BIT) + +/* USB OTG PHY clock divider register */ +#define CPM_USBCDR_UCS BIT(31) +#define CPM_USBCDR_UPCS BIT(30) +#define CPM_USBCDR_CEUSB BIT(29) +#define CPM_USBCDR_USB_BUSY BIT(28) +#define CPM_USBCDR_OTGDIV_BIT 0 +#define CPM_USBCDR_OTGDIV_MASK (0xff << CPM_USBCDR_OTGDIV_BIT) + +/* I2S device clock divider register */ +#define CPM_I2SCDR_I2CS BIT(31) +#define CPM_I2SCDR_I2PCS BIT(30) +#define CPM_I2SCDR_I2SDIV_BIT 0 +#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT) + +/* LCD0 pix clock divider register */ +#define CPM_LPCDR_LPCS_BIT 30 +#define CPM_LPCDR_LPCS_MASK (0x3 << CPM_LPCDR_LPCS_BIT) +#define CPM_LPCDR_CELCD BIT(28) +#define CPM_LPCDR_LCD_BUSY BIT(27) +#define CPM_LPCDR_LCD_STOP BIT(26) +#define CPM_LPCDR_PIXDIV_BIT 0 +#define CPM_LPCDR_PIXDIV_MASK (0xff << CPM_LPCDR_PIXDIV_BIT) + +/* MSC clock divider register */ +#define CPM_MSCCDR_MPCS_BIT 30 +#define CPM_MSCCDR_MPCS_MASK (3 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_MPCS_STOP (0x0 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_MPCS_SRC (0x1 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_MPCS_MPLL (0x2 << CPM_MSCCDR_MPCS_BIT) +#define CPM_MSCCDR_CE BIT(29) +#define CPM_MSCCDR_MSC_BUSY BIT(28) +#define CPM_MSCCDR_MSC_STOP BIT(27) +#define CPM_MSCCDR_MSC_CLK0_SEL BIT(15) +#define CPM_MSCCDR_MSCDIV_BIT 0 +#define CPM_MSCCDR_MSCDIV_MASK (0xff << CPM_MSCCDR_MSCDIV_BIT) + +/* UHC 48M clock divider register */ +#define CPM_UHCCDR_UHCS_BIT 30 +#define CPM_UHCCDR_UHCS_MASK (0x3 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_SRC (0x0 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_MPLL (0x1 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_EPLL (0x2 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_UHCS_OTG (0x3 << CPM_UHCCDR_UHCS_BIT) +#define CPM_UHCCDR_CE_UHC BIT(29) +#define CPM_UHCCDR_UHC_BUSY BIT(28) +#define CPM_UHCCDR_UHC_STOP BIT(27) +#define CPM_UHCCDR_UHCDIV_BIT 0 +#define CPM_UHCCDR_UHCDIV_MASK (0xff << CPM_UHCCDR_UHCDIV_BIT) + +/* SSI clock divider register */ +#define CPM_SSICDR_SCS BIT(31) +#define CPM_SSICDR_SSIDIV_BIT 0 +#define CPM_SSICDR_SSIDIV_MASK (0x3f << CPM_SSICDR_SSIDIV_BIT) + +/* CIM MCLK clock divider register */ +#define CPM_CIMCDR_CIMDIV_BIT 0 +#define CPM_CIMCDR_CIMDIV_MASK (0xff << CPM_CIMCDR_CIMDIV_BIT) + +/* GPS clock divider register */ +#define CPM_GPSCDR_GPCS BIT(31) +#define CPM_GPSCDR_GPSDIV_BIT 0 +#define CPM_GSPCDR_GPSDIV_MASK (0xf << CPM_GPSCDR_GPSDIV_BIT) + +/* PCM device clock divider register */ +#define CPM_PCMCDR_PCMS BIT(31) +#define CPM_PCMCDR_PCMPCS BIT(30) +#define CPM_PCMCDR_PCMDIV_BIT 0 +#define CPM_PCMCDR_PCMDIV_MASK (0x1ff << CPM_PCMCDR_PCMDIV_BIT) + +/* GPU clock divider register */ +#define CPM_GPUCDR_GPCS BIT(31) +#define CPM_GPUCDR_GPUDIV_BIT 0 +#define CPM_GPUCDR_GPUDIV_MASK (0x7 << CPM_GPUCDR_GPUDIV_BIT) + +/* HDMI clock divider register */ +#define CPM_HDMICDR_HPCS_BIT 30 +#define CPM_HDMICDR_HPCS_MASK (0x3 << CPM_HDMICDR_HPCS_BIT) +#define CPM_HDMICDR_CEHDMI BIT(29) +#define CPM_HDMICDR_HDMI_BUSY BIT(28) +#define CPM_HDMICDR_HDMI_STOP BIT(26) +#define CPM_HDMICDR_HDMIDIV_BIT 0 +#define CPM_HDMICDR_HDMIDIV_MASK (0xff << CPM_HDMICDR_HDMIDIV_BIT) + +/* Low Power Control Register */ +#define CPM_LCR_PD_SCPU BIT(31) +#define CPM_LCR_PD_VPU BIT(30) +#define CPM_LCR_PD_GPU BIT(29) +#define CPM_LCR_PD_GPS BIT(28) +#define CPM_LCR_SCPUS BIT(27) +#define CPM_LCR_VPUS BIT(26) +#define CPM_LCR_GPUS BIT(25) +#define CPM_LCR_GPSS BIT(24) +#define CPM_LCR_GPU_IDLE BIT(20) +#define CPM_LCR_PST_BIT 8 +#define CPM_LCR_PST_MASK (0xfff << CPM_LCR_PST_BIT) +#define CPM_LCR_DOZE_DUTY_BIT 3 +#define CPM_LCR_DOZE_DUTY_MASK (0x1f << CPM_LCR_DOZE_DUTY_BIT) +#define CPM_LCR_DOZE_ON BIT(2) +#define CPM_LCR_LPM_BIT 0 +#define CPM_LCR_LPM_MASK (0x3 << CPM_LCR_LPM_BIT) +#define CPM_LCR_LPM_IDLE (0x0 << CPM_LCR_LPM_BIT) +#define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT) + +/* Clock Gate Register0 */ +#define CPM_CLKGR0_DDR1 BIT(31) +#define CPM_CLKGR0_DDR0 BIT(30) +#define CPM_CLKGR0_IPU BIT(29) +#define CPM_CLKGR0_LCD1 BIT(28) +#define CPM_CLKGR0_LCD BIT(27) +#define CPM_CLKGR0_CIM BIT(26) +#define CPM_CLKGR0_I2C2 BIT(25) +#define CPM_CLKGR0_UHC BIT(24) +#define CPM_CLKGR0_MAC BIT(23) +#define CPM_CLKGR0_GPS BIT(22) +#define CPM_CLKGR0_PDMAC BIT(21) +#define CPM_CLKGR0_SSI2 BIT(20) +#define CPM_CLKGR0_SSI1 BIT(19) +#define CPM_CLKGR0_UART3 BIT(18) +#define CPM_CLKGR0_UART2 BIT(17) +#define CPM_CLKGR0_UART1 BIT(16) +#define CPM_CLKGR0_UART0 BIT(15) +#define CPM_CLKGR0_SADC BIT(14) +#define CPM_CLKGR0_KBC BIT(13) +#define CPM_CLKGR0_MSC2 BIT(12) +#define CPM_CLKGR0_MSC1 BIT(11) +#define CPM_CLKGR0_OWI BIT(10) +#define CPM_CLKGR0_TSSI BIT(9) +#define CPM_CLKGR0_AIC BIT(8) +#define CPM_CLKGR0_SCC BIT(7) +#define CPM_CLKGR0_I2C1 BIT(6) +#define CPM_CLKGR0_I2C0 BIT(5) +#define CPM_CLKGR0_SSI0 BIT(4) +#define CPM_CLKGR0_MSC0 BIT(3) +#define CPM_CLKGR0_OTG BIT(2) +#define CPM_CLKGR0_BCH BIT(1) +#define CPM_CLKGR0_NEMC BIT(0) + +/* Clock Gate Register1 */ +#define CPM_CLKGR1_P1 BIT(15) +#define CPM_CLKGR1_X2D BIT(14) +#define CPM_CLKGR1_DES BIT(13) +#define CPM_CLKGR1_I2C4 BIT(12) +#define CPM_CLKGR1_AHB BIT(11) +#define CPM_CLKGR1_UART4 BIT(10) +#define CPM_CLKGR1_HDMI BIT(9) +#define CPM_CLKGR1_OTG1 BIT(8) +#define CPM_CLKGR1_GPVLC BIT(7) +#define CPM_CLKGR1_AIC1 BIT(6) +#define CPM_CLKGR1_COMPRES BIT(5) +#define CPM_CLKGR1_GPU BIT(4) +#define CPM_CLKGR1_PCM BIT(3) +#define CPM_CLKGR1_VPU BIT(2) +#define CPM_CLKGR1_TSSI1 BIT(1) +#define CPM_CLKGR1_I2C3 BIT(0) + +/* Oscillator and Power Control Register */ +#define CPM_OPCR_O1ST_BIT 8 +#define CPM_OPCR_O1ST_MASK (0xff << CPM_OPCR_O1ST_BIT) +#define CPM_OPCR_SPENDN BIT(7) +#define CPM_OPCR_GPSEN BIT(6) +#define CPM_OPCR_SPENDH BIT(5) +#define CPM_OPCR_O1SE BIT(4) +#define CPM_OPCR_ERCS BIT(2) /* 0: select EXCLK/512 clock, 1: RTCLK clock */ +#define CPM_OPCR_USBM BIT(0) /* 0: select EXCLK/512 clock, 1: RTCLK clock */ + +/* Reset Status Register */ +#define CPM_RSR_P0R BIT(2) +#define CPM_RSR_WR BIT(1) +#define CPM_RSR_PR BIT(0) + +/* BCH clock divider register */ +#define CPM_BCHCDR_BPCS_BIT 30 +#define CPM_BCHCDR_BPCS_MASK (0x3 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_STOP (0X0 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_SRC_CLK (0x1 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_MPLL (0x2 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_BPCS_EPLL (0x3 << CPM_BCHCDR_BPCS_BIT) +#define CPM_BCHCDR_CE_BCH BIT(29) +#define CPM_BCHCDR_BCH_BUSY BIT(28) +#define CPM_BCHCDR_BCH_STOP BIT(27) +#define CPM_BCHCDR_BCHCDR_BIT 0 +#define CPM_BCHCDR_BCHCDR_MASK (0x7 << CPM_BCHCDR_BCHCDR_BIT) + +/* CPM scratch pad protected register(CPSPPR) */ +#define CPSPPR_CPSPR_WRITABLE 0x00005a5a +#define RECOVERY_SIGNATURE 0x1a1a /* means "RECY" */ +#define RECOVERY_SIGNATURE_SEC 0x800 /* means "RECY" */ + +#define REBOOT_SIGNATURE 0x3535 /* means reboot */ + +/* XPLL control register */ +#define XLOCK (1 << 6) +#define XPLL_ON (1 << 4) +#define XF_MODE (1 << 3) +#define XPLLBP (1 << 1) +#define XPLLEN (1 << 0) + +enum PLLS { + EXTCLK = 0, + APLL, + MPLL, + EPLL, + VPLL, +}; + +#define M_N_OD(m, n, od) \ + ((((m) - 1) << 19) | (((n) - 1) << 13) | (((od) - 1) << 9)) + +struct cgu_pll_select { + u8 reg; + u8 pll; + u8 pll_shift; +}; + +static void pll_init_one(int pll, int m, int n, int od) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + void __iomem *pll_reg = cpm_regs + CPM_CPAPCR + ((pll - 1) * 4); + + setbits_le32(pll_reg, M_N_OD(m, n, od) | XPLLEN); + + /* FIXME */ + while (!(readl(pll_reg) & XPLL_ON)) + ; +} + +static void cpu_mux_select(int pll) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 clk_ctrl; + unsigned int selectplls[] = { + CPM_PLL_SEL_STOP, + CPM_PLL_SEL_SRC, + CPM_PLL_SEL_MPLL, + CPM_PLL_SEL_EPLL + }; + + /* Init CPU, L2CACHE, AHB0, AHB2, APB clock */ + clk_ctrl = CPM_CPCCR_CE_CPU | CPM_CPCCR_CE_AHB0 | CPM_CPCCR_CE_AHB2 | + ((6 - 1) << CPM_CPCCR_H2DIV_BIT) | + ((3 - 1) << CPM_CPCCR_H0DIV_BIT) | + ((2 - 1) << CPM_CPCCR_L2DIV_BIT) | + ((1 - 1) << CPM_CPCCR_CDIV_BIT); + + if (CONFIG_SYS_MHZ >= 1000) + clk_ctrl |= (12 - 1) << CPM_CPCCR_PDIV_BIT; + else + clk_ctrl |= (6 - 1) << CPM_CPCCR_PDIV_BIT; + + clrsetbits_le32(cpm_regs + CPM_CPCCR, 0x00ffffff, clk_ctrl); + + while (readl(cpm_regs + CPM_CPCSR) & (CPM_CPCSR_CDIV_BUSY | + CPM_CPCSR_H0DIV_BUSY | CPM_CPCSR_H2DIV_BUSY)) + ; + + clk_ctrl = (selectplls[pll] << CPM_CPCCR_SEL_CPLL_BIT) | + (selectplls[MPLL] << CPM_CPCCR_SEL_H0PLL_BIT) | + (selectplls[MPLL] << CPM_CPCCR_SEL_H2PLL_BIT); + if (pll == APLL) + clk_ctrl |= CPM_PLL_SEL_SRC << CPM_CPCCR_SEL_SRC_BIT; + else + clk_ctrl |= CPM_SRC_SEL_EXCLK << CPM_CPCCR_SEL_SRC_BIT; + + clrsetbits_le32(cpm_regs + CPM_CPCCR, 0xff << 24, clk_ctrl); +} + +static void ddr_mux_select(int pll) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + int selectplls[] = { CPM_DDRCDR_DCS_STOP, + CPM_DDRCDR_DCS_SRC, + CPM_DDRCDR_DCS_MPLL}; + + writel(selectplls[pll] | CPM_DDRCDR_CE_DDR | (JZ4780_SYS_MEM_DIV - 1), + cpm_regs + CPM_DDCDR); + + while (readl(cpm_regs + CPM_DDCDR) & CPM_DDRCDR_DDR_BUSY) + ; + + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_DDR0); + + mdelay(200); +} + +static void cgu_mux_init(struct cgu_pll_select *cgu, unsigned int num) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + unsigned int selectplls[] = {0, 1, 2, 3, 2, 6}; + int i; + + for (i = 0; i < num; i++) + writel(selectplls[cgu[i].pll] << cgu[i].pll_shift, + cpm_regs + cgu[i].reg); +} + +void pll_init(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + struct cgu_pll_select cgu_mux[] = { + { CPM_MSCCDR, MPLL, 30 }, + { CPM_LPCDR, VPLL, 30 }, + { CPM_LPCDR1, VPLL, 30 }, + { CPM_GPUCDR, MPLL, 30 }, + { CPM_HDMICDR, VPLL, 30 }, + { CPM_I2SCDR, EPLL, 30 }, + { CPM_BCHCDR, MPLL, 30 }, + { CPM_VPUCDR, 0x1, 30 }, + { CPM_UHCCDR, 0x3, 30 }, + { CPM_CIMCDR, 0x1, 31 }, + { CPM_PCMCDR, 0x5, 29 }, + { CPM_SSICDR, 0x3, 30 }, + }; + + /* PLL stable time set to default -- 1ms */ + clrsetbits_le32(cpm_regs + CPM_CPPCR, 0xfffff, (16 << 8) | 0x20); + + pll_init_one(APLL, JZ4780_APLL_M, JZ4780_APLL_N, JZ4780_APLL_OD); + pll_init_one(MPLL, JZ4780_MPLL_M, JZ4780_MPLL_N, JZ4780_MPLL_OD); + pll_init_one(VPLL, JZ4780_VPLL_M, JZ4780_VPLL_N, JZ4780_VPLL_OD); + pll_init_one(EPLL, JZ4780_EPLL_M, JZ4780_EPLL_N, JZ4780_EPLL_OD); + + cpu_mux_select(MPLL); + ddr_mux_select(MPLL); + cgu_mux_init(cgu_mux, ARRAY_SIZE(cgu_mux)); +} + +const u32 jz4780_clk_get_efuse_clk(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 cpccr = readl(cpm_regs + CPM_CPCCR); + u32 ahb2_div = ((cpccr & CPM_CPCCR_H2DIV_MASK) >> + CPM_CPCCR_H2DIV_BIT) + 1; + return JZ4780_SYS_MEM_SPEED / ahb2_div; +} + +void jz4780_clk_ungate_ethernet(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_MAC); + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_NEMC); +} + +void jz4780_clk_ungate_mmc(void) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 msc_cdr = JZ4780_SYS_MEM_SPEED / 24000000 / 2 - 1; + + msc_cdr |= CPM_MSCCDR_MPCS_MPLL | CPM_MSCCDR_CE; + writel(msc_cdr, cpm_regs + CPM_MSCCDR); + writel(msc_cdr, cpm_regs + CPM_MSCCDR1); + writel(msc_cdr, cpm_regs + CPM_MSCCDR2); + + /* The wait_for_bit() won't fit, thus unbounded loop here. */ + while (readl(cpm_regs + CPM_MSCCDR1) & CPM_MSCCDR_MSC_BUSY) + ; +} + +void jz4780_clk_ungate_uart(const unsigned int uart) +{ + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + + if (uart == 0) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART0); + else if (uart == 1) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART1); + else if (uart == 2) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART2); + else if (uart == 3) + clrbits_le32(cpm_regs + CPM_CLKGR0, CPM_CLKGR0_UART3); + else if (uart == 4) + clrbits_le32(cpm_regs + CPM_CLKGR1, CPM_CLKGR1_UART4); + else + printf("%s[%i]: Invalid UART %d\n", __func__, __LINE__, uart); +} diff --git a/arch/mips/mach-jz47xx/jz4780/reset.c b/arch/mips/mach-jz47xx/jz4780/reset.c new file mode 100644 index 0000000000..73af34721f --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/reset.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 common routines + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton + */ + +#include +#include +#include +#include + +/* WDT */ +#define WDT_TDR 0x00 +#define WDT_TCER 0x04 +#define WDT_TCNT 0x08 +#define WDT_TCSR 0x0C + +/* Register definition */ +#define WDT_TCSR_PRESCALE_BIT 3 +#define WDT_TCSR_PRESCALE_MASK (0x7 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE1 (0x0 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE4 (0x1 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE16 (0x2 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE64 (0x3 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE256 (0x4 << WDT_TCSR_PRESCALE_BIT) + #define WDT_TCSR_PRESCALE1024 (0x5 << WDT_TCSR_PRESCALE_BIT) +#define WDT_TCSR_EXT_EN BIT(2) +#define WDT_TCSR_RTC_EN BIT(1) +#define WDT_TCSR_PCK_EN BIT(0) + +#define WDT_TCER_TCEN BIT(0) + +void _machine_restart(void) +{ + void __iomem *wdt_regs = (void __iomem *)WDT_BASE; + + /* EXTAL as the timer clock input. */ + writew(WDT_TCSR_PRESCALE1 | WDT_TCSR_EXT_EN, wdt_regs + WDT_TCSR); + + /* Reset the WDT counter and timeout. */ + writew(0, wdt_regs + WDT_TCNT); + writew(0, wdt_regs + WDT_TDR); + + jz4780_tcu_wdt_start(); + + /* WDT start */ + writeb(WDT_TCER_TCEN, wdt_regs + WDT_TCER); + + for (;;) + ; +} diff --git a/arch/mips/mach-jz47xx/jz4780/sdram.c b/arch/mips/mach-jz47xx/jz4780/sdram.c new file mode 100644 index 0000000000..5b25c8d002 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/sdram.c @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 DDR initialization + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton + * + * Based on spl/common/{jz4780_ddr,jz_ddr3_init}.c from X-Boot + * Copyright (c) 2006-2013 Ingenic Semiconductor + */ + +#include +#include +#include +#include + +static const u32 get_mem_clk(void) +{ + const u32 mpll_out = ((u64)JZ4780_SYS_EXTAL * JZ4780_MPLL_M) / + (JZ4780_MPLL_N * JZ4780_MPLL_OD); + return mpll_out / JZ4780_SYS_MEM_DIV; +} + +u32 sdram_size(int cs) +{ + u32 dw = DDR_DW32 ? 4 : 2; + u32 banks = DDR_BANK8 ? 8 : 4; + u32 size = 0; + + if ((cs == 0) && DDR_CS0EN) { + size = (1 << (DDR_ROW + DDR_COL)) * dw * banks; + if (DDR_CS1EN && (size > 0x20000000)) + size = 0x20000000; + } else if ((cs == 1) && DDR_CS1EN) { + size = (1 << (DDR_ROW + DDR_COL)) * dw * banks; + } + + return size; +} + +static void ddr_cfg_init(void) +{ + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + u32 ddrc_cfg, tmp; + + tmp = DDR_CL; + if (tmp) + tmp--; + if (tmp > 4) + tmp = 4; + + ddrc_cfg = DDRC_CFG_TYPE_DDR3 | DDRC_CFG_IMBA | + DDR_DW32 | DDRC_CFG_MPRT | ((tmp | 0x8) << 2) | + ((DDR_ROW - 12) << 11) | ((DDR_COL - 8) << 8) | + (DDR_CS0EN << 6) | (DDR_BANK8 << 1) | + ((DDR_ROW - 12) << 27) | ((DDR_COL - 8) << 24) | + (DDR_CS1EN << 7) | (DDR_BANK8 << 23); + + if (DDR_BL > 4) + ddrc_cfg |= BIT(21); + + writel(ddrc_cfg, ddr_ctl_regs + DDRC_CFG); +} + +static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config) +{ + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET; + unsigned int count = 0, i; + u32 reg, mask; + + writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), ddr_phy_regs + DDRP_DCR); + + writel(ddr_config->mr0, ddr_phy_regs + DDRP_MR0); + writel(ddr_config->mr1, ddr_phy_regs + DDRP_MR1); + writel(0, ddr_phy_regs + DDRP_ODTCR); + writel(0, ddr_phy_regs + DDRP_MR2); + + writel(ddr_config->ptr0, ddr_phy_regs + DDRP_PTR0); + writel(ddr_config->ptr1, ddr_phy_regs + DDRP_PTR1); + writel(ddr_config->ptr2, ddr_phy_regs + DDRP_PTR2); + + writel(ddr_config->dtpr0, ddr_phy_regs + DDRP_DTPR0); + writel(ddr_config->dtpr1, ddr_phy_regs + DDRP_DTPR1); + writel(ddr_config->dtpr2, ddr_phy_regs + DDRP_DTPR2); + + writel(DDRP_PGCR_DQSCFG | (7 << DDRP_PGCR_CKEN_BIT) | + (2 << DDRP_PGCR_CKDV_BIT) | + (DDR_CS0EN | (DDR_CS1EN << 1)) << DDRP_PGCR_RANKEN_BIT | + DDRP_PGCR_ZCKSEL_32 | DDRP_PGCR_PDDISDX, + ddr_phy_regs + DDRP_PGCR); + + for (i = 0; i < 8; i++) + clrbits_le32(ddr_phy_regs + DDRP_DXGCR(i), 0x3 << 9); + + count = 0; + mask = DDRP_PGSR_IDONE | DDRP_PGSR_DLDONE | DDRP_PGSR_ZCDONE; + for (;;) { + reg = readl(ddr_phy_regs + DDRP_PGSR); + if ((reg == mask) || (reg == 0x1f)) + break; + if (count++ == 10000) + hang(); + } + + /* DQS extension and early set to 1 */ + clrsetbits_le32(ddr_phy_regs + DDRP_DSGCR, 0x7E << 4, 0x12 << 4); + + /* 500 pull up and 500 pull down */ + clrsetbits_le32(ddr_phy_regs + DDRP_DXCCR, 0xFF << 4, 0xC4 << 4); + + /* Initialise phy */ + writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST, + ddr_phy_regs + DDRP_PIR); + + count = 0; + mask |= DDRP_PGSR_DIDONE; + for (;;) { + reg = readl(ddr_phy_regs + DDRP_PGSR); + if ((reg == mask) || (reg == 0x1f)) + break; + if (count++ == 20000) + hang(); + } + + writel(DDRP_PIR_INIT | DDRP_PIR_QSTRN, ddr_phy_regs + DDRP_PIR); + + count = 0; + mask |= DDRP_PGSR_DTDONE; + for (;;) { + reg = readl(ddr_phy_regs + DDRP_PGSR); + if (reg == mask) + break; + if (count++ != 50000) + continue; + reg &= DDRP_PGSR_DTDONE | DDRP_PGSR_DTERR | DDRP_PGSR_DTIERR; + if (reg) + hang(); + count = 0; + } + + /* Override impedance */ + clrsetbits_le32(ddr_phy_regs + DDRP_ZQXCR0(0), 0x3ff, + ((ddr_config->pullup & 0x1f) << DDRP_ZQXCR_PULLUP_IMPE_BIT) | + ((ddr_config->pulldn & 0x1f) << DDRP_ZQXCR_PULLDOWN_IMPE_BIT) | + DDRP_ZQXCR_ZDEN); +} + +#define JZBIT(bit) ((bit % 4) * 8) +#define JZMASK(bit) (0x1f << JZBIT(bit)) + +static void remap_swap(int a, int b) +{ + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + u32 remmap[2], tmp[2]; + + remmap[0] = readl(ddr_ctl_regs + DDRC_REMMAP(a / 4)); + remmap[1] = readl(ddr_ctl_regs + DDRC_REMMAP(b / 4)); + + tmp[0] = (remmap[0] & JZMASK(a)) >> JZBIT(a); + tmp[1] = (remmap[1] & JZMASK(b)) >> JZBIT(b); + + remmap[0] &= ~JZMASK(a); + remmap[1] &= ~JZMASK(b); + + writel(remmap[0] | (tmp[1] << JZBIT(a)), + ddr_ctl_regs + DDRC_REMMAP(a / 4)); + writel(remmap[1] | (tmp[0] << JZBIT(b)), + ddr_ctl_regs + DDRC_REMMAP(b / 4)); +} + +static void mem_remap(void) +{ + u32 start = (DDR_ROW + DDR_COL + (DDR_DW32 ? 4 : 2) / 2) - 12; + u32 num = DDR_BANK8 ? 3 : 2; + + if (DDR_CS0EN && DDR_CS1EN) + num++; + + for (; num > 0; num--) + remap_swap(0 + num - 1, start + num - 1); +} + +/* Fetch DRAM config from board file */ +__weak const struct jz4780_ddr_config *jz4780_get_ddr_config(void) +{ + return NULL; +} + +void sdram_init(void) +{ + const struct jz4780_ddr_config *ddr_config = jz4780_get_ddr_config(); + void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE; + void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET; + void __iomem *cpm_regs = (void __iomem *)CPM_BASE; + u32 mem_clk, tmp, i; + u32 mem_base0, mem_base1; + u32 mem_mask0, mem_mask1; + u32 mem_size0, mem_size1; + + if (!ddr_config) + hang(); + + /* Reset DLL in DDR PHY */ + writel(0x3, cpm_regs + 0xd0); + mdelay(400); + writel(0x1, cpm_regs + 0xd0); + mdelay(400); + + /* Enter reset */ + writel(0xf << 20, ddr_ctl_regs + DDRC_CTRL); + + mem_clk = get_mem_clk(); + + tmp = 1000000000 / mem_clk; + if (1000000000 % mem_clk) + tmp++; + tmp = DDR_tREFI / tmp; + tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1; + if (tmp > 0xff) + tmp = 0xff; + if (tmp < 1) + tmp = 1; + + writel(0x0, ddr_ctl_regs + DDRC_CTRL); + + writel(0x150000, ddr_phy_regs + DDRP_DTAR); + ddr_phy_init(ddr_config); + + writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL); + writel(0x0, ddr_ctl_regs + DDRC_CTRL); + + ddr_cfg_init(); + + for (i = 0; i < 6; i++) + writel(ddr_config->timing[i], ddr_ctl_regs + DDRC_TIMING(i)); + + mem_size0 = sdram_size(0); + mem_size1 = sdram_size(1); + + if (!mem_size1 && mem_size0 > 0x20000000) { + mem_base0 = 0x0; + mem_mask0 = ~(((mem_size0 * 2) >> 24) - 1) & DDRC_MMAP_MASK_MASK; + } else { + mem_base0 = (DDR_MEM_PHY_BASE >> 24) & 0xff; + mem_mask0 = ~((mem_size0 >> 24) - 1) & DDRC_MMAP_MASK_MASK; + } + + if (mem_size1) { + mem_mask1 = ~((mem_size1 >> 24) - 1) & DDRC_MMAP_MASK_MASK; + mem_base1 = ((DDR_MEM_PHY_BASE + mem_size0) >> 24) & 0xff; + } else { + mem_mask1 = 0; + mem_base1 = 0xff; + } + + writel(mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0, + ddr_ctl_regs + DDRC_MMAP0); + writel(mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1, + ddr_ctl_regs + DDRC_MMAP1); + writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL); + writel((DDR_CLK_DIV << 1) | DDRC_REFCNT_REF_EN | + (tmp << DDRC_REFCNT_CON_BIT), + ddr_ctl_regs + DDRC_REFCNT); + writel((1 << 15) | (4 << 12) | (1 << 11) | (1 << 8) | (0 << 6) | + (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1), + ddr_ctl_regs + DDRC_CTRL); + mem_remap(); + clrbits_le32(ddr_ctl_regs + DDRC_ST, 0x40); +} diff --git a/arch/mips/mach-jz47xx/jz4780/timer.c b/arch/mips/mach-jz47xx/jz4780/timer.c new file mode 100644 index 0000000000..a689b9d71a --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/timer.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * JZ4780 timer + * + * Copyright (c) 2013 Imagination Technologies + * Author: Paul Burton + */ + +#include +#include +#include +#include +#include +#include + +#define TCU_TSR 0x1C /* Timer Stop Register */ +#define TCU_TSSR 0x2C /* Timer Stop Set Register */ +#define TCU_TSCR 0x3C /* Timer Stop Clear Register */ +#define TCU_TER 0x10 /* Timer Counter Enable Register */ +#define TCU_TESR 0x14 /* Timer Counter Enable Set Register */ +#define TCU_TECR 0x18 /* Timer Counter Enable Clear Register */ +#define TCU_TFR 0x20 /* Timer Flag Register */ +#define TCU_TFSR 0x24 /* Timer Flag Set Register */ +#define TCU_TFCR 0x28 /* Timer Flag Clear Register */ +#define TCU_TMR 0x30 /* Timer Mask Register */ +#define TCU_TMSR 0x34 /* Timer Mask Set Register */ +#define TCU_TMCR 0x38 /* Timer Mask Clear Register */ +/* n = 0,1,2,3,4,5 */ +#define TCU_TDFR(n) (0x40 + (n) * 0x10) /* Timer Data Full Reg */ +#define TCU_TDHR(n) (0x44 + (n) * 0x10) /* Timer Data Half Reg */ +#define TCU_TCNT(n) (0x48 + (n) * 0x10) /* Timer Counter Reg */ +#define TCU_TCSR(n) (0x4C + (n) * 0x10) /* Timer Control Reg */ + +#define TCU_OSTCNTL 0xe4 +#define TCU_OSTCNTH 0xe8 +#define TCU_OSTCSR 0xec +#define TCU_OSTCNTHBUF 0xfc + +/* Register definitions */ +#define TCU_TCSR_PWM_SD BIT(9) +#define TCU_TCSR_PWM_INITL_HIGH BIT(8) +#define TCU_TCSR_PWM_EN BIT(7) +#define TCU_TCSR_PRESCALE_BIT 3 +#define TCU_TCSR_PRESCALE_MASK (0x7 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE1 (0x0 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE4 (0x1 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE16 (0x2 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE64 (0x3 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE256 (0x4 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_PRESCALE1024 (0x5 << TCU_TCSR_PRESCALE_BIT) +#define TCU_TCSR_EXT_EN BIT(2) +#define TCU_TCSR_RTC_EN BIT(1) +#define TCU_TCSR_PCK_EN BIT(0) + +#define TCU_TER_TCEN5 BIT(5) +#define TCU_TER_TCEN4 BIT(4) +#define TCU_TER_TCEN3 BIT(3) +#define TCU_TER_TCEN2 BIT(2) +#define TCU_TER_TCEN1 BIT(1) +#define TCU_TER_TCEN0 BIT(0) + +#define TCU_TESR_TCST5 BIT(5) +#define TCU_TESR_TCST4 BIT(4) +#define TCU_TESR_TCST3 BIT(3) +#define TCU_TESR_TCST2 BIT(2) +#define TCU_TESR_TCST1 BIT(1) +#define TCU_TESR_TCST0 BIT(0) + +#define TCU_TECR_TCCL5 BIT(5) +#define TCU_TECR_TCCL4 BIT(4) +#define TCU_TECR_TCCL3 BIT(3) +#define TCU_TECR_TCCL2 BIT(2) +#define TCU_TECR_TCCL1 BIT(1) +#define TCU_TECR_TCCL0 BIT(0) + +#define TCU_TFR_HFLAG5 BIT(21) +#define TCU_TFR_HFLAG4 BIT(20) +#define TCU_TFR_HFLAG3 BIT(19) +#define TCU_TFR_HFLAG2 BIT(18) +#define TCU_TFR_HFLAG1 BIT(17) +#define TCU_TFR_HFLAG0 BIT(16) +#define TCU_TFR_FFLAG5 BIT(5) +#define TCU_TFR_FFLAG4 BIT(4) +#define TCU_TFR_FFLAG3 BIT(3) +#define TCU_TFR_FFLAG2 BIT(2) +#define TCU_TFR_FFLAG1 BIT(1) +#define TCU_TFR_FFLAG0 BIT(0) + +#define TCU_TFSR_HFLAG5 BIT(21) +#define TCU_TFSR_HFLAG4 BIT(20) +#define TCU_TFSR_HFLAG3 BIT(19) +#define TCU_TFSR_HFLAG2 BIT(18) +#define TCU_TFSR_HFLAG1 BIT(17) +#define TCU_TFSR_HFLAG0 BIT(16) +#define TCU_TFSR_FFLAG5 BIT(5) +#define TCU_TFSR_FFLAG4 BIT(4) +#define TCU_TFSR_FFLAG3 BIT(3) +#define TCU_TFSR_FFLAG2 BIT(2) +#define TCU_TFSR_FFLAG1 BIT(1) +#define TCU_TFSR_FFLAG0 BIT(0) + +#define TCU_TFCR_HFLAG5 BIT(21) +#define TCU_TFCR_HFLAG4 BIT(20) +#define TCU_TFCR_HFLAG3 BIT(19) +#define TCU_TFCR_HFLAG2 BIT(18) +#define TCU_TFCR_HFLAG1 BIT(17) +#define TCU_TFCR_HFLAG0 BIT(16) +#define TCU_TFCR_FFLAG5 BIT(5) +#define TCU_TFCR_FFLAG4 BIT(4) +#define TCU_TFCR_FFLAG3 BIT(3) +#define TCU_TFCR_FFLAG2 BIT(2) +#define TCU_TFCR_FFLAG1 BIT(1) +#define TCU_TFCR_FFLAG0 BIT(0) + +#define TCU_TMR_HMASK5 BIT(21) +#define TCU_TMR_HMASK4 BIT(20) +#define TCU_TMR_HMASK3 BIT(19) +#define TCU_TMR_HMASK2 BIT(18) +#define TCU_TMR_HMASK1 BIT(17) +#define TCU_TMR_HMASK0 BIT(16) +#define TCU_TMR_FMASK5 BIT(5) +#define TCU_TMR_FMASK4 BIT(4) +#define TCU_TMR_FMASK3 BIT(3) +#define TCU_TMR_FMASK2 BIT(2) +#define TCU_TMR_FMASK1 BIT(1) +#define TCU_TMR_FMASK0 BIT(0) + +#define TCU_TMSR_HMST5 BIT(21) +#define TCU_TMSR_HMST4 BIT(20) +#define TCU_TMSR_HMST3 BIT(19) +#define TCU_TMSR_HMST2 BIT(18) +#define TCU_TMSR_HMST1 BIT(17) +#define TCU_TMSR_HMST0 BIT(16) +#define TCU_TMSR_FMST5 BIT(5) +#define TCU_TMSR_FMST4 BIT(4) +#define TCU_TMSR_FMST3 BIT(3) +#define TCU_TMSR_FMST2 BIT(2) +#define TCU_TMSR_FMST1 BIT(1) +#define TCU_TMSR_FMST0 BIT(0) + +#define TCU_TMCR_HMCL5 BIT(21) +#define TCU_TMCR_HMCL4 BIT(20) +#define TCU_TMCR_HMCL3 BIT(19) +#define TCU_TMCR_HMCL2 BIT(18) +#define TCU_TMCR_HMCL1 BIT(17) +#define TCU_TMCR_HMCL0 BIT(16) +#define TCU_TMCR_FMCL5 BIT(5) +#define TCU_TMCR_FMCL4 BIT(4) +#define TCU_TMCR_FMCL3 BIT(3) +#define TCU_TMCR_FMCL2 BIT(2) +#define TCU_TMCR_FMCL1 BIT(1) +#define TCU_TMCR_FMCL0 BIT(0) + +#define TCU_TSR_WDTS BIT(16) +#define TCU_TSR_STOP5 BIT(5) +#define TCU_TSR_STOP4 BIT(4) +#define TCU_TSR_STOP3 BIT(3) +#define TCU_TSR_STOP2 BIT(2) +#define TCU_TSR_STOP1 BIT(1) +#define TCU_TSR_STOP0 BIT(0) + +#define TCU_TSSR_WDTSS BIT(16) +#define TCU_TSSR_STPS5 BIT(5) +#define TCU_TSSR_STPS4 BIT(4) +#define TCU_TSSR_STPS3 BIT(3) +#define TCU_TSSR_STPS2 BIT(2) +#define TCU_TSSR_STPS1 BIT(1) +#define TCU_TSSR_STPS0 BIT(0) + +#define TCU_TSSR_WDTSC BIT(16) +#define TCU_TSSR_STPC5 BIT(5) +#define TCU_TSSR_STPC4 BIT(4) +#define TCU_TSSR_STPC3 BIT(3) +#define TCU_TSSR_STPC2 BIT(2) +#define TCU_TSSR_STPC1 BIT(1) +#define TCU_TSSR_STPC0 BIT(0) + +#define TER_OSTEN BIT(15) + +#define OSTCSR_CNT_MD BIT(15) +#define OSTCSR_SD BIT(9) +#define OSTCSR_PRESCALE_16 (0x2 << 3) +#define OSTCSR_EXT_EN BIT(2) + +int timer_init(void) +{ + void __iomem *regs = (void __iomem *)TCU_BASE; + + writel(OSTCSR_SD, regs + TCU_OSTCSR); + reset_timer(); + writel(OSTCSR_CNT_MD | OSTCSR_EXT_EN | OSTCSR_PRESCALE_16, + regs + TCU_OSTCSR); + writew(TER_OSTEN, regs + TCU_TESR); + return 0; +} + +void reset_timer(void) +{ + void __iomem *regs = (void __iomem *)TCU_BASE; + + writel(0, regs + TCU_OSTCNTH); + writel(0, regs + TCU_OSTCNTL); +} + +static u64 get_timer64(void) +{ + void __iomem *regs = (void __iomem *)TCU_BASE; + u32 low = readl(regs + TCU_OSTCNTL); + u32 high = readl(regs + TCU_OSTCNTHBUF); + + return ((u64)high << 32) | low; +} + +ulong get_timer(ulong base) +{ + return lldiv(get_timer64(), 3000) - base; +} + +void __udelay(unsigned long usec) +{ + /* OST count increments at 3MHz */ + u64 end = get_timer64() + ((u64)usec * 3); + + while (get_timer64() < end) + ; +} + +unsigned long long get_ticks(void) +{ + return get_timer64(); +} + +void jz4780_tcu_wdt_start(void) +{ + void __iomem *tcu_regs = (void __iomem *)TCU_BASE; + + /* Enable WDT clock */ + writel(TCU_TSSR_WDTSC, tcu_regs + TCU_TSCR); +} diff --git a/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds new file mode 100644 index 0000000000..347cabc450 --- /dev/null +++ b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_ARCH(mips) +ENTRY(_start) +SECTIONS +{ + .text : + { + __image_copy_start = .; + arch/mips/mach-jz47xx/start.o (.text*) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + . = ALIGN(4); + __image_copy_end = .; + + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.sbss.*) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } >.sdram + + /DISCARD/ : { + *(.dynbss) + *(.dynstr) + *(.dynamic) + *(.interp) + *(.hash) + *(.gnu.*) + *(.plt) + *(.got.plt) + *(.rel.plt) + *(.rel.dyn) + } +} diff --git a/arch/mips/mach-jz47xx/start.S b/arch/mips/mach-jz47xx/start.S new file mode 100644 index 0000000000..760d021549 --- /dev/null +++ b/arch/mips/mach-jz47xx/start.S @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Startup Code for MIPS32 XBURST CPU-core + * + * Copyright (c) 2010 Xiangfu Liu + */ + +#include +#include +#include +#include +#include +#include +#include + + .set noreorder + + .globl _start + .text +_start: +#ifdef CONFIG_SPL_BUILD + + /* magic value ("MSPL") */ + .word 0x4d53504c + + /* Invalidate BTB */ + mfc0 t0, CP0_CONFIG, 7 + nop + ori t0, 2 + mtc0 t0, CP0_CONFIG, 7 + nop + + /* + * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1 + */ + li t0, 0x0040FC04 + mtc0 t0, CP0_STATUS + + /* CAUSE register */ + /* IV=1, use the specical interrupt vector (0x200) */ + li t1, 0x00800000 + mtc0 t1, CP0_CAUSE + +#ifdef CONFIG_SOC_JZ4780 + /* enable bridge radical mode */ + la t0, CPM_BASE + lw t1, 0x24(t0) + ori t1, t1, 0x22 + sw t1, 0x24(t0) +#endif + + /* Set up stack */ + li sp, CONFIG_SPL_STACK + + b board_init_f + nop + +#ifdef CONFIG_SOC_JZ4780 + + .globl enable_caches + .ent enable_caches +enable_caches: + mtc0 zero, CP0_TAGLO + mtc0 zero, CP0_TAGHI + + li t0, KSEG0 + addu t1, t0, CONFIG_SYS_DCACHE_SIZE +1: + cache INDEX_STORE_TAG_D, 0(t0) + bne t0, t1, 1b + addiu t0, t0, CONFIG_SYS_CACHELINE_SIZE + + li t0, KSEG0 + addu t1, t0, CONFIG_SYS_ICACHE_SIZE +2: + cache INDEX_STORE_TAG_I, 0(t0) + bne t0, t1, 2b + addiu t0, t0, CONFIG_SYS_CACHELINE_SIZE + + /* Invalidate BTB */ + mfc0 t0, CP0_CONFIG, 7 + nop + ori t0, 2 + mtc0 t0, CP0_CONFIG, 7 + nop + + /* Enable caches */ + li t0, CONF_CM_CACHABLE_NONCOHERENT + mtc0 t0, CP0_CONFIG + nop + + jr ra + nop + + .end enable_caches + +#endif /* CONFIG_SOC_JZ4780 */ +#endif /* !CONFIG_SPL_BUILD */ -- cgit From 25c7de2255128743fcbe436b6f3b17a70d0cdd82 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Sun, 16 Dec 2018 19:25:23 -0300 Subject: mips: jz47xx: Add Creator CI20 platform Add support for the Creator CI20 platform based on the JZ4780 SoC. Cc: Daniel Schwierzeck Signed-off-by: Paul Burton Signed-off-by: Marek Vasut Signed-off-by: Ezequiel Garcia Reviewed-by: Marek Vasut --- arch/mips/dts/Makefile | 1 + arch/mips/dts/ci20.dts | 122 ++++++++++++++++++++++++++++++++++++++++++ arch/mips/mach-jz47xx/Kconfig | 11 ++++ 3 files changed, 134 insertions(+) create mode 100644 arch/mips/dts/ci20.dts (limited to 'arch') diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index b447141f87..647d2bf0d5 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -16,6 +16,7 @@ dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb +dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb targets += $(dtb-y) diff --git a/arch/mips/dts/ci20.dts b/arch/mips/dts/ci20.dts new file mode 100644 index 0000000000..8d6417af73 --- /dev/null +++ b/arch/mips/dts/ci20.dts @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +#include "jz4780.dtsi" + +/ { + compatible = "img,ci20", "ingenic,jz4780"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial3 = &uart3; + serial4 = &uart4; + }; + + chosen { + stdout-path = "serial4:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x10000000 + 0x30000000 0x30000000>; + }; +}; + +&ext { + clock-frequency = <48000000>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&nemc { + status = "okay"; + + nandc: nand-controller@1 { + compatible = "ingenic,jz4780-nand"; + reg = <1 0 0x1000000>; + + #address-cells = <1>; + #size-cells = <0>; + + ingenic,bch-controller = <&bch>; + + ingenic,nemc-tAS = <10>; + ingenic,nemc-tAH = <5>; + ingenic,nemc-tBP = <10>; + ingenic,nemc-tAW = <15>; + ingenic,nemc-tSTRV = <100>; + + nand@1 { + reg = <1>; + + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-ecc-mode = "hw"; + nand-on-flash-bbt; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <2>; + #size-cells = <2>; + + partition@0 { + label = "u-boot-spl"; + reg = <0x0 0x0 0x0 0x800000>; + }; + + partition@0x800000 { + label = "u-boot"; + reg = <0x0 0x800000 0x0 0x200000>; + }; + + partition@0xa00000 { + label = "u-boot-env"; + reg = <0x0 0xa00000 0x0 0x200000>; + }; + + partition@0xc00000 { + label = "boot"; + reg = <0x0 0xc00000 0x0 0x4000000>; + }; + + partition@0x8c00000 { + label = "system"; + reg = <0x0 0x4c00000 0x1 0xfb400000>; + }; + }; + }; + }; +}; + +&bch { + status = "okay"; +}; + +&mmc0 { + bus-width = <4>; + max-frequency = <50000000>; + status = "okay"; +}; + +&mmc1 { + bus-width = <4>; + max-frequency = <50000000>; + status = "okay"; +}; diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig index cd6944cfc2..dcaac01628 100644 --- a/arch/mips/mach-jz47xx/Kconfig +++ b/arch/mips/mach-jz47xx/Kconfig @@ -12,4 +12,15 @@ config SOC_JZ4780 help Support for Ingenic JZ4780 family SoCs. +choice + prompt "Board select" + +config TARGET_JZ4780_CI20 + bool "Creator CI20 Reference Board" + select SOC_JZ4780 + +endchoice + +source "board/imgtec/ci20/Kconfig" + endmenu -- cgit