diff options
90 files changed, 2907 insertions, 496 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index e192db0..399a839 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -523,9 +523,14 @@ F: arch/mips/mach-mscc/ F: arch/mips/dts/luton* F: arch/mips/dts/mscc* F: arch/mips/dts/ocelot* +F: arch/mips/dts/jr2* +F: arch/mips/dts/serval* F: board/mscc/ F: configs/mscc* +F: drivers/gpio/mscc_sgpio.c +F: drivers/spi/mscc_bb_spi.c F: include/configs/vcoreiii.h +F: drivers/pinctrl/mscc/ MIPS JZ4780 M: Ezequiel Garcia <ezequiel@collabora.com> diff --git a/arch/mips/cpu/u-boot-spl.lds b/arch/mips/cpu/u-boot-spl.lds index 1273b74..be194d3 100644 --- a/arch/mips/cpu/u-boot-spl.lds +++ b/arch/mips/cpu/u-boot-spl.lds @@ -46,43 +46,75 @@ SECTIONS __bss_end = .; } > .bss_mem - .rel.dyn (NOLOAD) : { - *(.rel.dyn) + /* These mark the ABI of U-Boot for debuggers. */ + .mdebug.abi32 : { + KEEP(*(.mdebug.abi32)) } - - .dynsym : { - *(.dynsym) - } - - .dynbss : { - *(.dynbss) - } - - .dynstr : { - *(.dynstr) - } - - .dynamic : { - *(.dynamic) + .mdebug.abi64 : { + KEEP(*(.mdebug.abi64)) } - .plt : { - *(.plt) + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* + * DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to + * the beginning of the section so we begin them at 0. + */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { + *(.debug_info + .gnu.linkonce.wi.*) } - - .interp : { - *(.interp) - } - - .gnu : { - *(.gnu*) - } - - .MIPS.stubs : { - *(.MIPS.stubs) - } - - .hash : { - *(.hash) + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + + /DISCARD/ : { + /* ABI crap starts here */ + *(.MIPS.abiflags) + *(.MIPS.options) + *(.options) + *(.pdr) + *(.reginfo) + *(.eh_frame) } } diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds index fd0f1b5..8649673 100644 --- a/arch/mips/cpu/u-boot.lds +++ b/arch/mips/cpu/u-boot.lds @@ -68,39 +68,75 @@ SECTIONS __bss_end = .; } - .dynsym _end : { - *(.dynsym) - } - - .dynbss : { - *(.dynbss) - } - - .dynstr : { - *(.dynstr) - } - - .dynamic : { - *(.dynamic) - } - - .plt : { - *(.plt) - } - - .interp : { - *(.interp) - } - - .gnu : { - *(.gnu*) - } - - .MIPS.stubs : { - *(.MIPS.stubs) - } - - .hash : { - *(.hash) + /* These mark the ABI of U-Boot for debuggers. */ + .mdebug.abi32 : { + KEEP(*(.mdebug.abi32)) + } + .mdebug.abi64 : { + KEEP(*(.mdebug.abi64)) + } + + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* + * DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to + * the beginning of the section so we begin them at 0. + */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { + *(.debug_info + .gnu.linkonce.wi.*) + } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + /* DWARF 5 */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + + /DISCARD/ : { + /* ABI crap starts here */ + *(.MIPS.abiflags) + *(.MIPS.options) + *(.options) + *(.pdr) + *(.reginfo) + *(.eh_frame) } } diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index 647d2bf..1484db9 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -17,6 +17,9 @@ 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 +dtb-$(CONFIG_SOC_LUTON) += luton_pcb090.dtb luton_pcb091.dtb +dtb-$(CONFIG_SOC_OCELOT) += ocelot_pcb120.dtb ocelot_pcb123.dtb +dtb-$(CONFIG_SOC_JR2) += jr2_pcb110.dtb jr2_pcb111.dtb serval2_pcb112.dtb targets += $(dtb-y) diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index d8d8868..75f6037 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -34,7 +34,7 @@ power_green { label = "smartgw:power:green"; gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>; - default-state = "off"; + default-state = "on"; }; power_red { diff --git a/arch/mips/dts/jr2_pcb110.dts b/arch/mips/dts/jr2_pcb110.dts new file mode 100644 index 0000000..ddc30ff --- /dev/null +++ b/arch/mips/dts/jr2_pcb110.dts @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,jr2.dtsi" + +/ { + model = "Jaguar2 Cu8-Sfp16 PCB110 Reference Board"; + compatible = "mscc,jr2-pcb110", "mscc,jr2"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb110:green:status"; + gpios = <&gpio 12 0>; + default-state = "on"; + }; + + status_red { + label = "pcb110:red:status"; + gpios = <&gpio 13 0>; + default-state = "off"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; +}; + +&gpio { + /* SPIO only use DO, CLK, no inputs */ + sgpio1_pins: sgpio1-pins { + pins = "GPIO_4", "GPIO_5"; + function = "sg1"; + }; +}; + +&sgpio { + status = "okay"; + sgpio-ports = <0x00ffffff>; +}; + +&sgpio1 { + status = "okay"; + sgpio-ports = <0x00ff0000>; +}; + +&sgpio2 { + status = "okay"; + sgpio-ports = <0x3f00ffff>; + gpio-ranges = <&sgpio2 0 0 96>; +}; diff --git a/arch/mips/dts/jr2_pcb111.dts b/arch/mips/dts/jr2_pcb111.dts new file mode 100644 index 0000000..4d411b6 --- /dev/null +++ b/arch/mips/dts/jr2_pcb111.dts @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,jr2.dtsi" + +/ { + model = "Jaguar2 Cu48 PCB111 Reference Board"; + compatible = "mscc,jr2-pcb111", "mscc,jr2"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb111:green:status"; + gpios = <&gpio 12 0>; + default-state = "on"; + }; + + status_red { + label = "pcb111:red:status"; + gpios = <&gpio 13 0>; + default-state = "off"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; +}; + +&gpio { + /* SPIO only use DO, CLK, no inputs */ + sgpio1_pins: sgpio1-pins { + pins = "GPIO_4", "GPIO_5"; + function = "sg1"; + }; +}; + +&sgpio { + status = "okay"; + sgpio-ports = <0xffffffff>; +}; + +&sgpio1 { + status = "okay"; + sgpio-ports = <0x001effff>; +}; + +&sgpio2 { + status = "okay"; + sgpio-ports = <0xff000000>; + gpio-ranges = <&sgpio2 0 0 96>; +}; diff --git a/arch/mips/dts/luton_pcb090.dts b/arch/mips/dts/luton_pcb090.dts new file mode 100644 index 0000000..951d8da --- /dev/null +++ b/arch/mips/dts/luton_pcb090.dts @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,luton.dtsi" + +/ { + model = "Luton26 PCB090 Reference Board"; + compatible = "mscc,luton-pcb090", "mscc,luton"; + + aliases { + serial0 = &uart0; + spi0 = &spi0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb090:green:status"; + gpios = <&sgpio 64 GPIO_ACTIVE_HIGH>; /* p0.2 */ + default-state = "on"; + }; + + status_red { + label = "pcb090:red:status"; + gpios = <&sgpio 65 GPIO_ACTIVE_HIGH>; /* p1.2 */ + default-state = "off"; + }; + }; +}; + +&sgpio { + status = "okay"; + gpio-ranges = <&sgpio 0 0 96>; +}; + +&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/luton_pcb091.dts b/arch/mips/dts/luton_pcb091.dts index 74f9274..bf638b2 100644 --- a/arch/mips/dts/luton_pcb091.dts +++ b/arch/mips/dts/luton_pcb091.dts @@ -18,6 +18,33 @@ chosen { stdout-path = "serial0:115200n8"; }; + + gpio-leds { + compatible = "gpio-leds"; + + top_dimmer { + label = "pcb091:top:dimmer"; + gpios = <&gpio 29 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + status_green { + label = "pcb091:green:status"; + gpios = <&sgpio 26 GPIO_ACTIVE_HIGH>; /* p26.0 */ + default-state = "on"; + }; + + status_red { + label = "pcb091:red:status"; + gpios = <&sgpio 58 GPIO_ACTIVE_HIGH>; /* p26.1 */ + default-state = "off"; + }; + }; +}; + +&sgpio { + status = "okay"; + mscc,sgpio-ports = <0xFFF000FF>; }; &uart0 { diff --git a/arch/mips/dts/mscc,jr2.dtsi b/arch/mips/dts/mscc,jr2.dtsi new file mode 100644 index 0000000..0900926 --- /dev/null +++ b/arch/mips/dts/mscc,jr2.dtsi @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mscc,jr2"; + + 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,jr2-cpu-syscon", "syscon"; + reg = <0x0 0x2c>; + }; + + intc: interrupt-controller@70 { + compatible = "mscc,jr2-icpu-intr"; + reg = <0x70 0x94>; + #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@1010008 { + compatible = "mscc,jr2-chip-reset"; + reg = <0x1010008 0x4>; + }; + + gpio: pinctrl@1070034 { + compatible = "mscc,jaguar2-pinctrl"; + reg = <0x1010038 0x90>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&gpio 0 0 64>; + + sgpio_pins: sgpio-pins { + pins = "GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3"; + function = "sg0"; + }; + + sgpio1_pins: sgpio1-pins { + pins = "GPIO_4", "GPIO_5", "GPIO_12", "GPIO_13"; + function = "sg1"; + }; + + sgpio2_pins: sgpio2-pins { + pins = "GPIO_30", "GPIO_31", + "GPIO_32", "GPIO_33"; + function = "sg2"; + }; + + uart_pins: uart-pins { + pins = "GPIO_10", "GPIO_11"; + function = "uart"; + }; + + uart2_pins: uart2-pins { + pins = "GPIO_24", "GPIO_25"; + function = "uart2"; + }; + }; + + sgpio: gpio@1010150 { + compatible = "mscc,ocelot-sgpio"; + status = "disabled"; + pinctrl-0 = <&sgpio_pins>; + pinctrl-names = "default"; + reg = <0x1010150 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio 0 0 64>; + gpio-bank-name = "sgpio0_"; + sgpio-clock = <0x14>; + }; + + sgpio1: gpio@101025c { + compatible = "mscc,ocelot-sgpio"; + status = "disabled"; + pinctrl-0 = <&sgpio1_pins>; + pinctrl-names = "default"; + reg = <0x101025c 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio1 0 0 64>; + gpio-bank-name = "sgpio1_"; + sgpio-clock = <0x14>; + }; + + sgpio2: gpio@1010368 { + compatible = "mscc,ocelot-sgpio"; + status = "disabled"; + pinctrl-0 = <&sgpio2_pins>; + pinctrl-names = "default"; + reg = <0x1010368 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio2 0 0 64>; + gpio-bank-name = "sgpio2_"; + sgpio-clock = <0x14>; + }; + }; +}; diff --git a/arch/mips/dts/mscc,luton.dtsi b/arch/mips/dts/mscc,luton.dtsi index 6a4ad2a..d11ec48 100644 --- a/arch/mips/dts/mscc,luton.dtsi +++ b/arch/mips/dts/mscc,luton.dtsi @@ -25,6 +25,11 @@ serial0 = &uart0; }; + sys_clk: sys-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + }; ahb_clk: ahb-clk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -57,28 +62,32 @@ #gpio-cells = <2>; gpio-ranges = <&gpio 0 0 32>; + sgpio_pins: sgpio-pins { + pins = "GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3"; + function = "sio"; + }; uart_pins: uart-pins { pins = "GPIO_30", "GPIO_31"; function = "uart"; }; - }; - gpio_spi_bitbang: gpio@10000064 { - compatible = "mscc,spi-bitbang-gpio"; - reg = <0x10000064 0x4>; + sgpio: gpio@70130 { + compatible = "mscc,luton-sgpio"; + status = "disabled"; + clocks = <&sys_clk>; + pinctrl-0 = <&sgpio_pins>; + pinctrl-names = "default"; + reg = <0x0070130 0x100>; gpio-controller; #gpio-cells = <2>; - + gpio-ranges = <&sgpio 0 0 64>; }; spi0: spi-bitbang { - compatible = "spi-gpio"; + compatible = "mscc,luton-bb-spi"; 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>; + reg = <0x10000064 0x4>; num-chipselects = <1>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/mips/dts/mscc,ocelot.dtsi b/arch/mips/dts/mscc,ocelot.dtsi index 87b4736..2592003 100644 --- a/arch/mips/dts/mscc,ocelot.dtsi +++ b/arch/mips/dts/mscc,ocelot.dtsi @@ -37,6 +37,12 @@ clock-frequency = <500000000>; }; + sys_clk: sys-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + }; + ahb_clk: ahb-clk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -118,6 +124,11 @@ #gpio-cells = <2>; gpio-ranges = <&gpio 0 0 22>; + sgpio_pins: sgpio-pins { + pins = "GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3"; + function = "sg0"; + }; + uart_pins: uart-pins { pins = "GPIO_6", "GPIO_7"; function = "uart"; @@ -148,5 +159,17 @@ function = "si"; }; }; + + sgpio: gpio@10700f8 { + compatible = "mscc,ocelot-sgpio"; + status = "disabled"; + clocks = <&sys_clk>; + pinctrl-0 = <&sgpio_pins>; + pinctrl-names = "default"; + reg = <0x10700f8 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio 0 0 64>; + }; }; }; diff --git a/arch/mips/dts/ocelot_pcb120.dts b/arch/mips/dts/ocelot_pcb120.dts index 47d305a..658719e 100644 --- a/arch/mips/dts/ocelot_pcb120.dts +++ b/arch/mips/dts/ocelot_pcb120.dts @@ -9,4 +9,80 @@ / { model = "Ocelot PCB120 Reference Board"; compatible = "mscc,ocelot-pcb120", "mscc,ocelot"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + poe_green { + label = "pcb120:green:poe"; + gpios = <&sgpio 44 1>; /* p12.1 */ + default-state = "off"; + }; + + poe_red { + label = "pcb120:red:poe"; + gpios = <&sgpio 12 1>; /* p12.0 */ + default-state = "off"; + }; + + alarm_green { + label = "pcb120:green:alarm"; + gpios = <&sgpio 45 1>; /* p13.1 */ + default-state = "off"; + }; + + alarm_red { + label = "pcb120:red:alarm"; + gpios = <&sgpio 13 1>; /* p13.0 */ + default-state = "off"; + }; + + dc_a_green { + label = "pcb120:green:dc_a"; + gpios = <&sgpio 46 1>; /* p14.1 */ + default-state = "off"; + }; + + dc_a_red { + label = "pcb120:red:dc_a"; + gpios = <&sgpio 14 1>; /* p14.0 */ + default-state = "off"; + }; + + dc_b_green { + label = "pcb120:green:dc_b"; + gpios = <&sgpio 47 1>; /* p15.1 */ + default-state = "off"; + }; + + dc_b_red { + label = "pcb120:red:dc_b"; + gpios = <&sgpio 15 1>; /* p15.0 */ + default-state = "off"; + }; + + status_green { + label = "pcb120:green:status"; + gpios = <&sgpio 48 1>; /* p16.1 */ + default-state = "on"; + }; + + status_red { + label = "pcb120:red:alarm"; + gpios = <&sgpio 16 1>; /* p16.0 */ + default-state = "off"; + }; + + }; + +}; + +&sgpio { + status = "okay"; + mscc,sgpio-ports = <0x000FFFFF>; }; + diff --git a/arch/mips/dts/ocelot_pcb123.dts b/arch/mips/dts/ocelot_pcb123.dts index 17d8d32..c4cb7a1 100644 --- a/arch/mips/dts/ocelot_pcb123.dts +++ b/arch/mips/dts/ocelot_pcb123.dts @@ -9,4 +9,29 @@ / { model = "Ocelot PCB123 Reference Board"; compatible = "mscc,ocelot-pcb123", "mscc,ocelot"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb123:green:status"; + gpios = <&sgpio 43 1>; /* p11.1 */ + default-state = "on"; + }; + + status_red { + label = "pcb123:red:status"; + gpios = <&sgpio 11 1>; /* p11.0 */ + default-state = "off"; + }; + }; +}; + +&sgpio { + status = "okay"; + mscc,sgpio-ports = <0x00FFFFFF>; }; diff --git a/arch/mips/dts/serval2_pcb112.dts b/arch/mips/dts/serval2_pcb112.dts new file mode 100644 index 0000000..fe025f4 --- /dev/null +++ b/arch/mips/dts/serval2_pcb112.dts @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +/dts-v1/; +#include "mscc,jr2.dtsi" + +/ { + model = "Serval2 NID PCB112 Reference Board"; + compatible = "mscc,serval2-pcb110", "mscc,jr2"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_green { + label = "pcb110:green:status"; + gpios = <&gpio 12 0>; + default-state = "on"; + }; + + status_red { + label = "pcb110:red:status"; + gpios = <&gpio 13 0>; + default-state = "off"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + spi-flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <18000000>; /* input clock */ + reg = <0>; /* CS0 */ + }; +}; + +&sgpio { + status = "okay"; + sgpio-ports = <0x0000ffff>; +}; + +&sgpio2 { + status = "okay"; + sgpio-ports = <0x3fe0ffff>; +}; diff --git a/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds b/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds deleted file mode 100644 index 347cabc..0000000 --- a/arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds +++ /dev/null @@ -1,50 +0,0 @@ -/* 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-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig index 0e35b77..fc6aa03 100644 --- a/arch/mips/mach-mscc/Kconfig +++ b/arch/mips/mach-mscc/Kconfig @@ -15,47 +15,36 @@ config SOC_VCOREIII config SYS_SOC default "mscc" +choice + + prompt "SOC Family Variant" + config SOC_OCELOT - bool + bool "Ocelot SOC Family" select SOC_VCOREIII + select DESIGNWARE_SPI help This supports MSCC Ocelot family of SOCs. config SOC_LUTON - bool + bool "Luton SOC Family" select SOC_VCOREIII + select MSCC_BITBANG_SPI_GPIO help This supports MSCC Luton 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 +config SOC_JR2 + bool "Jaguar2 SOC Family" + select SOC_VCOREIII + select DESIGNWARE_SPI help - When selected, CONFIG_DEFAULT_DEVICE_TREE should be set to - ocelot_pcb123 + This supports MSCC Jaguar2 family of SOCs. -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 +config SYS_CONFIG_NAME + default "vcoreiii" + choice prompt "DDR type" @@ -83,4 +72,6 @@ source "board/mscc/ocelot/Kconfig" source "board/mscc/luton/Kconfig" +source "board/mscc/jr2/Kconfig" + endmenu diff --git a/arch/mips/mach-mscc/Makefile b/arch/mips/mach-mscc/Makefile index 6c60f26..f5b6968 100644 --- a/arch/mips/mach-mscc/Makefile +++ b/arch/mips/mach-mscc/Makefile @@ -2,5 +2,6 @@ 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 +obj-y += cpu.o dram.o reset.o phy.o lowlevel_init.o +obj-$(CONFIG_SOC_LUTON) += lowlevel_init_luton.o gpio.o +obj-$(CONFIG_SOC_OCELOT) += gpio.o diff --git a/arch/mips/mach-mscc/cpu.c b/arch/mips/mach-mscc/cpu.c index 5be8ff6..4729b7a 100644 --- a/arch/mips/mach-mscc/cpu.c +++ b/arch/mips/mach-mscc/cpu.c @@ -87,8 +87,15 @@ int mach_cpu_init(void) ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); #else +#ifdef CONFIG_SOC_OCELOT writel(ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + ICPU_SPI_MST_CFG_CLK_DIV(9), BASE_CFG + ICPU_SPI_MST_CFG); +#endif +#ifdef CONFIG_SOC_JR2 + writel(ICPU_SPI_MST_CFG_FAST_READ_ENA + + ICPU_SPI_MST_CFG_CS_DESELECT_TIME(0x19) + + ICPU_SPI_MST_CFG_CLK_DIV(14), BASE_CFG + ICPU_SPI_MST_CFG); +#endif /* * Legacy and mainline linux kernel expect that the * interruption map was set as it was done by redboot. diff --git a/arch/mips/mach-mscc/dram.c b/arch/mips/mach-mscc/dram.c index 309007c..8002e07 100644 --- a/arch/mips/mach-mscc/dram.c +++ b/arch/mips/mach-mscc/dram.c @@ -19,7 +19,7 @@ static inline int vcoreiii_train_bytelane(void) ret = hal_vcoreiii_train_bytelane(0); -#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) if (ret) return ret; ret = hal_vcoreiii_train_bytelane(1); diff --git a/arch/mips/mach-mscc/gpio.c b/arch/mips/mach-mscc/gpio.c new file mode 100644 index 0000000..5e3a533 --- /dev/null +++ b/arch/mips/mach-mscc/gpio.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <asm/io.h> + +void mscc_gpio_set_alternate(int gpio, int mode) +{ + u32 mask = BIT(gpio); + u32 val0, val1; + + val0 = readl(BASE_DEVCPU_GCB + GPIO_ALT(0)); + val1 = readl(BASE_DEVCPU_GCB + GPIO_ALT(1)); + + if (mode == 1) { + val0 |= mask; + val1 &= ~mask; + } else if (mode == 2) { + val0 &= ~mask; + val1 |= mask; + } else if (mode == 3) { + val0 |= mask; + val1 |= mask; + } else { + val0 &= ~mask; + val1 &= ~mask; + } + + writel(val0, BASE_DEVCPU_GCB + GPIO_ALT(0)); + writel(val1, BASE_DEVCPU_GCB + GPIO_ALT(1)); +} diff --git a/arch/mips/mach-mscc/include/mach/common.h b/arch/mips/mach-mscc/include/mach/common.h index 931ecd7..b9e0939 100644 --- a/arch/mips/mach-mscc/include/mach/common.h +++ b/arch/mips/mach-mscc/include/mach/common.h @@ -9,11 +9,18 @@ #if defined(CONFIG_SOC_OCELOT) #include <mach/ocelot/ocelot.h> #include <mach/ocelot/ocelot_devcpu_gcb.h> +#include <mach/ocelot/ocelot_devcpu_gcb_miim_regs.h> #include <mach/ocelot/ocelot_icpu_cfg.h> #elif defined(CONFIG_SOC_LUTON) #include <mach/luton/luton.h> #include <mach/luton/luton_devcpu_gcb.h> +#include <mach/luton/luton_devcpu_gcb_miim_regs.h> #include <mach/luton/luton_icpu_cfg.h> +#elif defined(CONFIG_SOC_JR2) +#include <mach/jr2/jr2.h> +#include <mach/jr2/jr2_devcpu_gcb.h> +#include <mach/jr2/jr2_devcpu_gcb_miim_regs.h> +#include <mach/jr2/jr2_icpu_cfg.h> #else #error Unsupported platform #endif @@ -25,4 +32,62 @@ #define VCOREIII_TIMER_DIVIDER 25 /* Clock tick ~ 0.1 us */ +/* Common utility functions */ + +/* + * Perform a number of NOP instructions, blocks of 8 instructions. + * The (inlined) function will not affect cache or processor state. + */ +static inline void mscc_vcoreiii_nop_delay(int delay) +{ + while (delay > 0) { +#define DELAY_8_NOPS() asm volatile("nop; nop; nop; nop; nop; nop; nop; nop;") + switch (delay) { + case 8: + DELAY_8_NOPS(); + /* fallthrough */ + case 7: + DELAY_8_NOPS(); + /* fallthrough */ + case 6: + DELAY_8_NOPS(); + /* fallthrough */ + case 5: + DELAY_8_NOPS(); + /* fallthrough */ + case 4: + DELAY_8_NOPS(); + /* fallthrough */ + case 3: + DELAY_8_NOPS(); + /* fallthrough */ + case 2: + DELAY_8_NOPS(); + /* fallthrough */ + case 1: + DELAY_8_NOPS(); + } + delay -= 8; +#undef DELAY_8_NOPS + } +} + +int mscc_phy_rd_wr(u8 read, + u32 miim_controller, + u8 miim_addr, + u8 addr, + u16 *value); + +int mscc_phy_rd(u32 miim_controller, + u8 miim_addr, + u8 addr, + u16 *value); + +int mscc_phy_wr(u32 miim_controller, + u8 miim_addr, + u8 addr, + u16 value); + +void mscc_gpio_set_alternate(int gpio, int mode); + #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 index f445e63..7552acb 100644 --- a/arch/mips/mach-mscc/include/mach/ddr.h +++ b/arch/mips/mach-mscc/include/mach/ddr.h @@ -161,7 +161,7 @@ #endif -#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) #define MIPS_VCOREIII_MEMORY_16BIT 1 #endif @@ -239,7 +239,7 @@ 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 +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) #define MSCC_MEMPARM_PERIOD \ ICPU_MEMCTRL_REF_PERIOD_MAX_PEND_REF(8) | \ ICPU_MEMCTRL_REF_PERIOD_REF_PERIOD(VC3_MPAR_tREFI) @@ -378,7 +378,7 @@ static inline void memphy_soft_reset(void) PAUSE(); } -#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) static u8 training_data[] = { 0xfe, 0x11, 0x33, 0x55, 0x77, 0x99, 0xbb, 0xdd }; static inline void sleep_100ns(u32 val) @@ -398,6 +398,7 @@ static inline void sleep_100ns(u32 val) ; } +#if defined(CONFIG_SOC_OCELOT) static inline void hal_vcoreiii_ddr_reset_assert(void) { /* DDR has reset pin on GPIO 19 toggle Low-High to release */ @@ -448,6 +449,26 @@ static inline void hal_vcoreiii_ddr_failed(void) panic("DDR init failed\n"); } +#else /* JR2 */ +static inline void hal_vcoreiii_ddr_reset_assert(void) +{ + /* Ensure the memory controller physical iface is forced reset */ + writel(readl(BASE_CFG + ICPU_MEMPHY_CFG) | + ICPU_MEMPHY_CFG_PHY_RST, BASE_CFG + ICPU_MEMPHY_CFG); + + /* Ensure the memory controller is forced reset */ + writel(readl(BASE_CFG + ICPU_RESET) | + ICPU_RESET_MEM_RST_FORCE, BASE_CFG + ICPU_RESET); +} + +static inline void hal_vcoreiii_ddr_failed(void) +{ + writel(0, BASE_CFG + ICPU_RESET); + writel(PERF_SOFT_RST_SOFT_CHIP_RST, BASE_CFG + PERF_SOFT_RST); + + panic("DDR init failed\n"); +} +#endif /* * DDR memory sanity checking done, possibly enable ECC. @@ -738,7 +759,7 @@ 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 +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) /* Check no ZCAL_ERR */ if (readl(BASE_CFG + ICPU_MEMPHY_ZCAL_STAT) & ICPU_MEMPHY_ZCAL_STAT_ZCAL_ERR) @@ -752,7 +773,7 @@ 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 +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) writel(MSCC_MEMPARM_TIMING0, BASE_CFG + ICPU_MEMCTRL_TIMING0); #else /* Luton */ clrbits_le32(BASE_CFG + ICPU_MEMCTRL_TIMING0, ((1 << 20) - 1)); @@ -767,7 +788,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 +#if defined(CONFIG_SOC_OCELOT) /* Termination setup - enable ODT */ writel(ICPU_MEMCTRL_TERMRES_CTRL_LOCAL_ODT_RD_ENA | /* Assert ODT0 for any write */ @@ -778,6 +799,9 @@ 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)); +#elif defined(CONFIG_SOC_JR2) + writel(ICPU_MEMCTRL_TERMRES_CTRL_ODT_WR_ENA(3), + BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); #else /* Luton */ /* Termination setup - disable ODT */ writel(0, BASE_CFG + ICPU_MEMCTRL_TERMRES_CTRL); @@ -796,7 +820,7 @@ static inline void hal_vcoreiii_wait_memctl(void) /* Settle...? */ sleep_100ns(10000); -#ifdef CONFIG_SOC_OCELOT +#if defined(CONFIG_SOC_OCELOT) || defined(CONFIG_SOC_JR2) /* Establish data contents in DDR RAM for training */ __raw_writel(0xcacafefe, ((void __iomem *)MSCC_DDR_TO)); diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2.h b/arch/mips/mach-mscc/include/mach/jr2/jr2.h new file mode 100644 index 0000000..67244f6 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Microsemi Jaguar2 Switch driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_H_ +#define _MSCC_JR2_H_ + +#include <linux/bitops.h> +#include <dm.h> + +/* + * 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 *)0x71010000) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h new file mode 100644 index 0000000..4a1228d --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb.h @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_DEVCPU_GCB_H_ +#define _MSCC_JR2_DEVCPU_GCB_H_ + +#define PERF_GPR 0x4 + +#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 GPIO_GPIO_ALT(x) (0x78 + 4 * (x)) +#define GPIO_GPIO_ALT1(x) (0x80 + 4 * (x)) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h new file mode 100644 index 0000000..3c84edc --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2_devcpu_gcb_miim_regs.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_DEVCPU_GCB_MIIM_REGS_H_ +#define _MSCC_JR2_DEVCPU_GCB_MIIM_REGS_H_ + +#define MIIM_MII_STATUS(gi) (0xc8 + (gi * 36)) +#define MIIM_MII_CMD(gi) (0xd0 + (gi * 36)) +#define MIIM_MII_DATA(gi) (0xd4 + (gi * 36)) + +#define MSCC_F_MII_STATUS_MIIM_STAT_BUSY(x) ((x) ? BIT(3) : 0) + +#define MSCC_F_MII_CMD_MIIM_CMD_VLD(x) ((x) ? BIT(31) : 0) +#define MSCC_F_MII_CMD_MIIM_CMD_PHYAD(x) (GENMASK(29, 25) & ((x) << 25)) +#define MSCC_F_MII_CMD_MIIM_CMD_REGAD(x) (GENMASK(24, 20) & ((x) << 20)) +#define MSCC_F_MII_CMD_MIIM_CMD_WRDATA(x) (GENMASK(19, 4) & ((x) << 4)) +#define MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(x) (GENMASK(2, 1) & ((x) << 1)) +#define MSCC_F_MII_CMD_MIIM_CMD_SCAN(x) ((x) ? BIT(0) : 0) + +#define MSCC_M_MII_DATA_MIIM_DATA_SUCCESS GENMASK(17, 16) +#define MSCC_X_MII_DATA_MIIM_DATA_RDDATA(x) (((x) >> 0) & GENMASK(15, 0)) + +#endif diff --git a/arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h b/arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h new file mode 100644 index 0000000..6e0bbe2 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/jr2/jr2_icpu_cfg.h @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_JR2_ICPU_CFG_H_ +#define _MSCC_JR2_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(15) +#define ICPU_GENERAL_CTRL_CPU_BUSIF_WERR_ENA BIT(14) +#define ICPU_GENERAL_CTRL_CPU_8051_IROM_ENA BIT(13) +#define ICPU_GENERAL_CTRL_CPU_MIPS_DIS BIT(12) +#define ICPU_GENERAL_CTRL_IF_MIIM_SLV_ENA BIT(11) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_DONEPOL BIT(10) +#define ICPU_GENERAL_CTRL_IF_PI_MST_ENA BIT(9) +#define ICPU_GENERAL_CTRL_IF_PI_SLV_ENA BIT(8) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER(x) (((x) << 6) & GENMASK(7, 6)) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_M GENMASK(7, 6) +#define ICPU_GENERAL_CTRL_IF_SI_OWNER_X(x) (((x) & GENMASK(7, 6)) >> 4) +#define ICPU_GENERAL_CTRL_IF_SI1_OWNER(x) (((x) << 4) & GENMASK(5, 4)) +#define ICPU_GENERAL_CTRL_IF_SI1_OWNER_M GENMASK(5, 4) +#define ICPU_GENERAL_CTRL_IF_SI1_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_TIMER_TICK_DIV 0x108 + +#define ICPU_TIMER_VALUE(x) (0x10c + 0x4 * (x)) +#define ICPU_TIMER_VALUE_RSZ 0x4 + +#define ICPU_TIMER_CTRL(x) (0x124 + 0x4 * (x)) +#define ICPU_TIMER_CTRL_RSZ 0x4 + +#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 0x130 + +#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 0x134 + +#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 0x138 + +#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 0x13c + +#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_ZQCAL 0x140 + +#define ICPU_MEMCTRL_ZQCAL_ZQCAL_LONG BIT(1) +#define ICPU_MEMCTRL_ZQCAL_ZQCAL_SHORT BIT(0) + +#define ICPU_MEMCTRL_TIMING0 0x144 + +#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 0x148 + +#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 0x14c + +#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 0x150 + +#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_TIMING4 0x154 + +#define ICPU_MEMCTRL_TIMING4_ZQCAL_INIT_DLY(x) (((x) << 20) & GENMASK(31, 20)) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_INIT_DLY_M GENMASK(31, 20) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_INIT_DLY_X(x) (((x) & GENMASK(31, 20)) >> 20) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_LONG_DLY(x) (((x) << 8) & GENMASK(19, 8)) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_LONG_DLY_M GENMASK(19, 8) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_LONG_DLY_X(x) (((x) & GENMASK(19, 8)) >> 8) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_SHORT_DLY(x) ((x) & GENMASK(7, 0)) +#define ICPU_MEMCTRL_TIMING4_ZQCAL_SHORT_DLY_M GENMASK(7, 0) + +#define ICPU_MEMCTRL_MR0_VAL 0x158 + +#define ICPU_MEMCTRL_MR1_VAL 0x15c + +#define ICPU_MEMCTRL_MR2_VAL 0x160 + +#define ICPU_MEMCTRL_MR3_VAL 0x164 + +#define ICPU_MEMCTRL_TERMRES_CTRL 0x168 + +#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_DFT 0x16c + +#define ICPU_MEMCTRL_DFT_DDRDFT_LBW BIT(7) +#define ICPU_MEMCTRL_DFT_DDRDFT_GATE_ENA BIT(6) +#define ICPU_MEMCTRL_DFT_DDRDFT_TERM_ENA BIT(5) +#define ICPU_MEMCTRL_DFT_DDRDFT_A10 BIT(4) +#define ICPU_MEMCTRL_DFT_DDRDFT_STAT BIT(3) +#define ICPU_MEMCTRL_DFT_DDRDFT_MODE(x) (((x) << 1) & GENMASK(2, 1)) +#define ICPU_MEMCTRL_DFT_DDRDFT_MODE_M GENMASK(2, 1) +#define ICPU_MEMCTRL_DFT_DDRDFT_MODE_X(x) (((x) & GENMASK(2, 1)) >> 1) +#define ICPU_MEMCTRL_DFT_DDRDFT_ENA BIT(0) + +#define ICPU_MEMCTRL_DQS_DLY(x) (0x170 + 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_MEMCTRL_DQS_AUTO (0x178 + 0x4 * (x)) +#define ICPU_MEMCTRL_DQS_AUTO_RSZ 0x4 + +#define ICPU_MEMCTRL_DQS_AUTO_DQS_DRIFT(x) (((x) << 6) & GENMASK(7, 6)) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_DRIFT_M GENMASK(7, 6) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_DRIFT_X(x) (((x) & GENMASK(7, 6)) >> 6) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_OVERFLOW BIT(5) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_UNDERFLOW BIT(4) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_SRC BIT(3) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_UP BIT(2) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_DOWN BIT(1) +#define ICPU_MEMCTRL_DQS_AUTO_DQS_AUTO_ENA BIT(0) + +#define ICPU_MEMPHY_CFG 0x180 + +#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 0x1a8 + +#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 0x1ac + +#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/luton/luton_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h index 8c0b612..a74a685 100644 --- a/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h +++ b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb.h @@ -11,4 +11,8 @@ #define PERF_SOFT_RST_SOFT_SWC_RST BIT(1) #define PERF_SOFT_RST_SOFT_CHIP_RST BIT(0) +#define GPIO_ALT(x) (0x88 + 4 * (x)) + +#define CHIP_ID (0x08) + #endif diff --git a/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb_miim_regs.h b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb_miim_regs.h new file mode 100644 index 0000000..2303734 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/luton/luton_devcpu_gcb_miim_regs.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Microsemi Ocelot Switch driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_LUTON_MIIM_REGS_H_ +#define _MSCC_LUTON_MIIM_REGS_H_ + +#define MIIM_MII_STATUS(gi) (0xa0 + (gi * 36)) +#define MIIM_MII_CMD(gi) (0xa8 + (gi * 36)) +#define MIIM_MII_DATA(gi) (0xac + (gi * 36)) + +#define MSCC_F_MII_STATUS_MIIM_STAT_BUSY(x) (x ? BIT(3) : 0) + +#define MSCC_F_MII_CMD_MIIM_CMD_VLD(x) (x ? BIT(31) : 0) +#define MSCC_F_MII_CMD_MIIM_CMD_PHYAD(x) (GENMASK(29, 25) & (x << 25)) +#define MSCC_F_MII_CMD_MIIM_CMD_REGAD(x) (GENMASK(24, 20) & (x << 20)) +#define MSCC_F_MII_CMD_MIIM_CMD_WRDATA(x) (GENMASK(19, 4) & (x << 4)) +#define MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(x) (GENMASK(2, 1) & (x << 1)) + +#define MSCC_M_MII_DATA_MIIM_DATA_SUCCESS GENMASK(17, 16) +#define MSCC_X_MII_DATA_MIIM_DATA_RDDATA(x) ((x >> 0) & GENMASK(15, 0)) + +#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 index f8aa97b..d3a7641 100644 --- a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb.h @@ -18,4 +18,6 @@ #define PERF_GPIO_OE 0x44 +#define GPIO_ALT(x) (0x54 + 4 * (x)) + #endif diff --git a/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb_miim_regs.h b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb_miim_regs.h new file mode 100644 index 0000000..4ad9221 --- /dev/null +++ b/arch/mips/mach-mscc/include/mach/ocelot/ocelot_devcpu_gcb_miim_regs.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _MSCC_OCELOT_DEVCPU_GCB_MIIM_REGS_H_ +#define _MSCC_OCELOT_DEVCPU_GCB_MIIM_REGS_H_ + +#define MIIM_MII_STATUS(gi) (0x9c + (gi * 36)) +#define MIIM_MII_CMD(gi) (0xa4 + (gi * 36)) +#define MIIM_MII_DATA(gi) (0xa8 + (gi * 36)) + +#define MSCC_F_MII_STATUS_MIIM_STAT_BUSY(x) ((x) ? BIT(3) : 0) + +#define MSCC_F_MII_CMD_MIIM_CMD_VLD(x) ((x) ? BIT(31) : 0) +#define MSCC_F_MII_CMD_MIIM_CMD_PHYAD(x) (GENMASK(29, 25) & ((x) << 25)) +#define MSCC_F_MII_CMD_MIIM_CMD_REGAD(x) (GENMASK(24, 20) & ((x) << 20)) +#define MSCC_F_MII_CMD_MIIM_CMD_WRDATA(x) (GENMASK(19, 4) & ((x) << 4)) +#define MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(x) (GENMASK(2, 1) & ((x) << 1)) +#define MSCC_F_MII_CMD_MIIM_CMD_SCAN(x) ((x) ? BIT(0) : 0) + +#define MSCC_M_MII_DATA_MIIM_DATA_SUCCESS GENMASK(17, 16) +#define MSCC_X_MII_DATA_MIIM_DATA_RDDATA(x) (((x) >> 0) & GENMASK(15, 0)) + +#endif diff --git a/arch/mips/mach-mscc/phy.c b/arch/mips/mach-mscc/phy.c new file mode 100644 index 0000000..add6280 --- /dev/null +++ b/arch/mips/mach-mscc/phy.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <asm/io.h> + +int mscc_phy_rd_wr(u8 read, + u32 miimdev, + u8 miim_addr, + u8 addr, + u16 *value) +{ + u32 data; + int i; + + /* Command part */ + data = (read ? MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(2) : /* Read */ + MSCC_F_MII_CMD_MIIM_CMD_OPR_FIELD(1) | /* Write */ + MSCC_F_MII_CMD_MIIM_CMD_WRDATA(*value)); /* value */ + + /* Addressing part */ + data |= + MSCC_F_MII_CMD_MIIM_CMD_VLD(1) | /* Valid command */ + MSCC_F_MII_CMD_MIIM_CMD_REGAD(addr) | /* Reg addr */ + MSCC_F_MII_CMD_MIIM_CMD_PHYAD(miim_addr); /* Miim addr */ + + /* Enqueue MIIM operation to be executed */ + writel(data, BASE_DEVCPU_GCB + MIIM_MII_CMD(miimdev)); + + /* Wait for MIIM operation to finish */ + i = 0; + do { + if (i++ > 100) { + debug("Miim timeout"); + return -1; + } + data = readl(BASE_DEVCPU_GCB + MIIM_MII_STATUS(miimdev)); + debug("Read status miim(%d): 0x%08x\n", miimdev, data); + } while (data & MSCC_F_MII_STATUS_MIIM_STAT_BUSY(1)); + + if (read) { + data = readl(BASE_DEVCPU_GCB + MIIM_MII_DATA(miimdev)); + if (data & MSCC_M_MII_DATA_MIIM_DATA_SUCCESS) { + debug("Read(%d, %d) returned 0x%08x\n", + miim_addr, addr, data); + return -1; + } + *value = MSCC_X_MII_DATA_MIIM_DATA_RDDATA(data); + } + + return 0; +} + +int mscc_phy_rd(u32 miimdev, + u8 miim_addr, + u8 addr, + u16 *value) +{ + if (mscc_phy_rd_wr(1, miimdev, miim_addr, addr, value) == 0) + return 0; + debug("Read(%d, %d) returned error\n", miim_addr, addr); + return -1; +} + +int mscc_phy_wr(u32 miimdev, + u8 miim_addr, + u8 addr, + u16 value) +{ + return mscc_phy_rd_wr(0, miimdev, miim_addr, addr, &value); +} diff --git a/arch/mips/mach-mscc/reset.c b/arch/mips/mach-mscc/reset.c index 390bbd0..e0e610a 100644 --- a/arch/mips/mach-mscc/reset.c +++ b/arch/mips/mach-mscc/reset.c @@ -12,6 +12,22 @@ void _machine_restart(void) { +#if defined(CONFIG_SOC_JR2) + register u32 reg = readl(BASE_CFG + ICPU_GENERAL_CTRL); + /* Set owner */ + reg &= ~ICPU_GENERAL_CTRL_IF_SI_OWNER_M; + reg |= ICPU_GENERAL_CTRL_IF_SI_OWNER(1); + /* Set boot mode */ + reg |= ICPU_GENERAL_CTRL_BOOT_MODE_ENA; + writel(reg, BASE_CFG + ICPU_GENERAL_CTRL); + /* Read back in order to make BOOT mode setting active */ + reg = readl(BASE_CFG + ICPU_GENERAL_CTRL); + /* Reset CPU only - still executing _here_. but from cache */ + writel(readl(BASE_CFG + ICPU_RESET) | + ICPU_RESET_CORE_RST_CPU_ONLY | + ICPU_RESET_CORE_RST_FORCE, + BASE_CFG + ICPU_RESET); +#else register u32 resetbits = PERF_SOFT_RST_SOFT_CHIP_RST; (void)readl(BASE_DEVCPU_GCB + PERF_SOFT_RST); @@ -24,6 +40,7 @@ void _machine_restart(void) /* Do the global reset */ writel(resetbits, BASE_DEVCPU_GCB + PERF_SOFT_RST); +#endif while (1) ; /* NOP */ diff --git a/board/mscc/common/Makefile b/board/mscc/common/Makefile new file mode 100644 index 0000000..4f0eded --- /dev/null +++ b/board/mscc/common/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +obj-$(CONFIG_SOC_JR2) := spi.o +obj-$(CONFIG_SOC_OCELOT) := spi.o diff --git a/board/mscc/common/spi.c b/board/mscc/common/spi.c new file mode 100644 index 0000000..0566fcb --- /dev/null +++ b/board/mscc/common/spi.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Coprporation + */ + +#include <common.h> +#include <asm/io.h> +#include <spi.h> + +void external_cs_manage(struct udevice *dev, bool enable) +{ + u32 cs = spi_chip_select(dev); + /* IF_SI0_OWNER, select the owner of the SI interface + * Encoding: 0: SI Slave + * 1: SI Boot Master + * 2: SI Master Controller + */ + if (!enable) { + writel(ICPU_SW_MODE_SW_PIN_CTRL_MODE | + ICPU_SW_MODE_SW_SPI_CS(BIT(cs)), + BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); + } else { + writel(0, BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(1)); + } +} diff --git a/board/mscc/jr2/Kconfig b/board/mscc/jr2/Kconfig new file mode 100644 index 0000000..68a2de8 --- /dev/null +++ b/board/mscc/jr2/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +config SYS_VENDOR + default "mscc" + +if SOC_JR2 + +config SYS_BOARD + default "jr2" + +config SYS_CONFIG_NAME + default "jr2" + +endif + diff --git a/board/mscc/jr2/Makefile b/board/mscc/jr2/Makefile new file mode 100644 index 0000000..c1db2a9 --- /dev/null +++ b/board/mscc/jr2/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +obj-$(CONFIG_SOC_JR2) := jr2.o + diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c new file mode 100644 index 0000000..eac4dca --- /dev/null +++ b/board/mscc/jr2/jr2.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <asm/io.h> +#include <led.h> + +enum { + BOARD_TYPE_PCB110 = 0xAABBCE00, + BOARD_TYPE_PCB111, + BOARD_TYPE_PCB112, +}; + +int board_early_init_r(void) +{ + /* Prepare SPI controller to be used in master mode */ + writel(0, BASE_CFG + ICPU_SW_MODE); + clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, + ICPU_GENERAL_CTRL_IF_SI_OWNER_M, + ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); + + /* Address of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE; + + /* LED setup */ + if (IS_ENABLED(CONFIG_LED)) + led_default_state(); + + return 0; +} + +static void vcoreiii_gpio_set_alternate(int gpio, int mode) +{ + u32 mask; + u32 val0, val1; + void __iomem *reg0, *reg1; + + if (gpio < 32) { + mask = BIT(gpio); + reg0 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT(0); + reg1 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT(1); + } else { + gpio -= 32; + mask = BIT(gpio); + reg0 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT1(0); + reg1 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT1(1); + } + val0 = readl(reg0); + val1 = readl(reg1); + if (mode == 1) { + writel(val0 | mask, reg0); + writel(val1 & ~mask, reg1); + } else if (mode == 2) { + writel(val0 & ~mask, reg0); + writel(val1 | mask, reg1); + } else if (mode == 3) { + writel(val0 | mask, reg0); + writel(val1 | mask, reg1); + } else { + writel(val0 & ~mask, reg0); + writel(val1 & ~mask, reg1); + } +} + +static void do_board_detect(void) +{ + int i; + u16 pval; + + /* MIIM 1 + 2 MDC/MDIO */ + for (i = 56; i < 60; i++) + vcoreiii_gpio_set_alternate(i, 1); + + if (mscc_phy_rd(0, 0x10, 0x3, &pval) == 0 && + ((pval >> 4) & 0x3F) == 0x3c) { + gd->board_type = BOARD_TYPE_PCB112; /* Serval2-NID */ + } else if (mscc_phy_rd(1, 0x0, 0x3, &pval) == 0 && + ((pval >> 4) & 0x3F) == 0x3c) { + gd->board_type = BOARD_TYPE_PCB110; /* Jr2-24 */ + } else { + /* Fall-back */ + gd->board_type = BOARD_TYPE_PCB111; /* Jr2-48 */ + } +} + +#if defined(CONFIG_MULTI_DTB_FIT) +int board_fit_config_name_match(const char *name) +{ + if (gd->board_type == BOARD_TYPE_PCB110 && + strcmp(name, "jr2_pcb110") == 0) + return 0; + + if (gd->board_type == BOARD_TYPE_PCB111 && + strcmp(name, "jr2_pcb111") == 0) + return 0; + + if (gd->board_type == BOARD_TYPE_PCB112 && + strcmp(name, "serval2_pcb112") == 0) + return 0; + + return -1; +} +#endif + +#if defined(CONFIG_DTB_RESELECT) +int embedded_dtb_select(void) +{ + do_board_detect(); + fdtdec_setup(); + + return 0; +} +#endif diff --git a/board/mscc/luton/luton.c b/board/mscc/luton/luton.c index 41fc6d5..807c717 100644 --- a/board/mscc/luton/luton.c +++ b/board/mscc/luton/luton.c @@ -5,16 +5,20 @@ #include <common.h> #include <asm/io.h> - -#define MSCC_GPIO_ALT0 0x88 -#define MSCC_GPIO_ALT1 0x8C +#include <led.h> DECLARE_GLOBAL_DATA_PTR; +enum { + BOARD_TYPE_PCB090 = 0xAABBCD00, + BOARD_TYPE_PCB091, +}; + void board_debug_uart_init(void) { /* too early for the pinctrl driver, so configure the UART pins here */ - setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(30) | BIT(31)); + mscc_gpio_set_alternate(30, 1); + mscc_gpio_set_alternate(31, 1); } int board_early_init_r(void) @@ -24,5 +28,45 @@ int board_early_init_r(void) /* Address of boot parameters */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE; + + /* LED setup */ + if (IS_ENABLED(CONFIG_LED)) + led_default_state(); + + return 0; +} + +static void do_board_detect(void) +{ + u32 chipid = (readl(BASE_DEVCPU_GCB + CHIP_ID) >> 12) & 0xFFFF; + + if (chipid == 0x7428 || chipid == 0x7424) + gd->board_type = BOARD_TYPE_PCB091; // Lu10 + else + gd->board_type = BOARD_TYPE_PCB090; // Lu26 +} + +#if defined(CONFIG_MULTI_DTB_FIT) +int board_fit_config_name_match(const char *name) +{ + if (gd->board_type == BOARD_TYPE_PCB090 && + strcmp(name, "luton_pcb090") == 0) + return 0; + + if (gd->board_type == BOARD_TYPE_PCB091 && + strcmp(name, "luton_pcb091") == 0) + return 0; + + return -1; +} +#endif + +#if defined(CONFIG_DTB_RESELECT) +int embedded_dtb_select(void) +{ + do_board_detect(); + fdtdec_setup(); + return 0; } +#endif diff --git a/board/mscc/ocelot/ocelot.c b/board/mscc/ocelot/ocelot.c index d521a61..0f7a532 100644 --- a/board/mscc/ocelot/ocelot.c +++ b/board/mscc/ocelot/ocelot.c @@ -9,39 +9,20 @@ #include <asm/types.h> #include <environment.h> #include <spi.h> +#include <led.h> DECLARE_GLOBAL_DATA_PTR; -#define MSCC_GPIO_ALT0 0x54 -#define MSCC_GPIO_ALT1 0x58 - -void external_cs_manage(struct udevice *dev, bool enable) -{ - u32 cs = spi_chip_select(dev); - /* IF_SI0_OWNER, select the owner of the SI interface - * Encoding: 0: SI Slave - * 1: SI Boot Master - * 2: SI Master Controller - */ - if (!enable) { - writel(ICPU_SW_MODE_SW_PIN_CTRL_MODE | - ICPU_SW_MODE_SW_SPI_CS(BIT(cs)), BASE_CFG + ICPU_SW_MODE); - clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, - ICPU_GENERAL_CTRL_IF_SI_OWNER_M, - ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); - } else { - writel(0, BASE_CFG + ICPU_SW_MODE); - clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, - ICPU_GENERAL_CTRL_IF_SI_OWNER_M, - ICPU_GENERAL_CTRL_IF_SI_OWNER(1)); - } -} +enum { + BOARD_TYPE_PCB120 = 0xAABBCC00, + BOARD_TYPE_PCB123, +}; void board_debug_uart_init(void) { /* too early for the pinctrl driver, so configure the UART pins here */ - setbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT0, BIT(6) | BIT(7)); - clrbits_le32(BASE_DEVCPU_GCB + MSCC_GPIO_ALT1, BIT(6) | BIT(7)); + mscc_gpio_set_alternate(6, 1); + mscc_gpio_set_alternate(7, 1); } int board_early_init_r(void) @@ -54,5 +35,48 @@ int board_early_init_r(void) /* Address of boot parameters */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE; + + /* LED setup */ + if (IS_ENABLED(CONFIG_LED)) + led_default_state(); + + return 0; +} + +static void do_board_detect(void) +{ + u16 dummy = 0; + + /* Enable MIIM */ + mscc_gpio_set_alternate(14, 1); + mscc_gpio_set_alternate(15, 1); + if (mscc_phy_rd(1, 0, 0, &dummy) == 0) + gd->board_type = BOARD_TYPE_PCB120; + else + gd->board_type = BOARD_TYPE_PCB123; +} + +#if defined(CONFIG_MULTI_DTB_FIT) +int board_fit_config_name_match(const char *name) +{ + if (gd->board_type == BOARD_TYPE_PCB120 && + strcmp(name, "ocelot_pcb120") == 0) + return 0; + + if (gd->board_type == BOARD_TYPE_PCB123 && + strcmp(name, "ocelot_pcb123") == 0) + return 0; + + return -1; +} +#endif + +#if defined(CONFIG_DTB_RESELECT) +int embedded_dtb_select(void) +{ + do_board_detect(); + fdtdec_setup(); + return 0; } +#endif diff --git a/configs/bcm968380gerg_ram_defconfig b/configs/bcm968380gerg_ram_defconfig index 8b2b318..fdecc0f 100644 --- a/configs/bcm968380gerg_ram_defconfig +++ b/configs/bcm968380gerg_ram_defconfig @@ -26,7 +26,6 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_LOADS is not set # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="brcm,bcm968380gerg" # CONFIG_NET is not set # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/boston32r2_defconfig b/configs/boston32r2_defconfig index 2d52f52..3d8d972 100644 --- a/configs/boston32r2_defconfig +++ b/configs/boston32r2_defconfig @@ -23,7 +23,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/boston32r2el_defconfig b/configs/boston32r2el_defconfig index 2e2beed..6650211 100644 --- a/configs/boston32r2el_defconfig +++ b/configs/boston32r2el_defconfig @@ -24,7 +24,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/boston32r6_defconfig b/configs/boston32r6_defconfig index 07613bf..b916460 100644 --- a/configs/boston32r6_defconfig +++ b/configs/boston32r6_defconfig @@ -24,7 +24,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/boston32r6el_defconfig b/configs/boston32r6el_defconfig index 14d9aa1..6bf0027 100644 --- a/configs/boston32r6el_defconfig +++ b/configs/boston32r6el_defconfig @@ -25,7 +25,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/boston64r2_defconfig b/configs/boston64r2_defconfig index 310c4a9..250a70d 100644 --- a/configs/boston64r2_defconfig +++ b/configs/boston64r2_defconfig @@ -24,7 +24,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/boston64r2el_defconfig b/configs/boston64r2el_defconfig index 3b39df1..84c4e53 100644 --- a/configs/boston64r2el_defconfig +++ b/configs/boston64r2el_defconfig @@ -25,7 +25,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/boston64r6_defconfig b/configs/boston64r6_defconfig index a0779b8..133a0a9 100644 --- a/configs/boston64r6_defconfig +++ b/configs/boston64r6_defconfig @@ -24,7 +24,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/boston64r6el_defconfig b/configs/boston64r6el_defconfig index 3cdd1de..8c97dca 100644 --- a/configs/boston64r6el_defconfig +++ b/configs/boston64r6el_defconfig @@ -25,7 +25,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="img,boston" CONFIG_ENV_IS_IN_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/ci20_mmc_defconfig b/configs/ci20_mmc_defconfig index c1b1c3f..9602c8c 100644 --- a/configs/ci20_mmc_defconfig +++ b/configs/ci20_mmc_defconfig @@ -1,5 +1,4 @@ CONFIG_MIPS=y -CONFIG_SPL_LDSCRIPT="arch/mips/mach-jz47xx/jz4780/u-boot-spl.lds" CONFIG_SYS_TEXT_BASE=0x80010000 CONFIG_SPL_GPIO_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y diff --git a/configs/comtrend_ar5315u_ram_defconfig b/configs/comtrend_ar5315u_ram_defconfig index 1b8e4e4..f6f0977 100644 --- a/configs/comtrend_ar5315u_ram_defconfig +++ b/configs/comtrend_ar5315u_ram_defconfig @@ -31,7 +31,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5315u" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/comtrend_ar5387un_ram_defconfig b/configs/comtrend_ar5387un_ram_defconfig index 5ba401a..8304552 100644 --- a/configs/comtrend_ar5387un_ram_defconfig +++ b/configs/comtrend_ar5387un_ram_defconfig @@ -31,7 +31,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,ar-5387un" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/comtrend_ct5361_ram_defconfig b/configs/comtrend_ct5361_ram_defconfig index 6297e78..b87a161 100644 --- a/configs/comtrend_ct5361_ram_defconfig +++ b/configs/comtrend_ct5361_ram_defconfig @@ -28,7 +28,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,ct-5361" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/comtrend_vr3032u_ram_defconfig b/configs/comtrend_vr3032u_ram_defconfig index 47f5399..0c27bfc 100644 --- a/configs/comtrend_vr3032u_ram_defconfig +++ b/configs/comtrend_vr3032u_ram_defconfig @@ -29,7 +29,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,vr-3032u" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/comtrend_wap5813n_ram_defconfig b/configs/comtrend_wap5813n_ram_defconfig index fd5107b..9e5f9ed 100644 --- a/configs/comtrend_wap5813n_ram_defconfig +++ b/configs/comtrend_wap5813n_ram_defconfig @@ -28,7 +28,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="comtrend,wap-5813n" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig index ae8bf29..bfd9bad 100644 --- a/configs/gardena-smart-gateway-mt7688-ram_defconfig +++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig @@ -33,8 +33,8 @@ CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_TIME=y CONFIG_CMD_UUID=y CONFIG_CMD_MTDPARTS=y -CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0" -CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)" +CONFIG_MTDIDS_DEFAULT="spi-nand0=spi0.1,nor0=spi0.0" +CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);spi0.1:-(nand)" CONFIG_CMD_UBI=y CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688" CONFIG_ENV_IS_IN_SPI_FLASH=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index b7024e3..d844932 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -36,8 +36,8 @@ CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_TIME=y CONFIG_CMD_UUID=y CONFIG_CMD_MTDPARTS=y -CONFIG_MTDIDS_DEFAULT="spi-nand0=gd5f,nor0=spi0.0" -CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);gd5f:-(nand)" +CONFIG_MTDIDS_DEFAULT="spi-nand0=spi0.1,nor0=spi0.0" +CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);spi0.1:-(nand)" CONFIG_CMD_UBI=y CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688" CONFIG_ENV_IS_IN_SPI_FLASH=y diff --git a/configs/huawei_hg556a_ram_defconfig b/configs/huawei_hg556a_ram_defconfig index d4e6144..1d4b833 100644 --- a/configs/huawei_hg556a_ram_defconfig +++ b/configs/huawei_hg556a_ram_defconfig @@ -28,7 +28,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="huawei,hg556a" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/imgtec_xilfpga_defconfig b/configs/imgtec_xilfpga_defconfig index 4fe7531..cea6424 100644 --- a/configs/imgtec_xilfpga_defconfig +++ b/configs/imgtec_xilfpga_defconfig @@ -17,7 +17,6 @@ CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="nexys4ddr" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_NETCONSOLE=y diff --git a/configs/malta64_defconfig b/configs/malta64_defconfig index 15c4e62..10d2e55 100644 --- a/configs/malta64_defconfig +++ b/configs/malta64_defconfig @@ -18,7 +18,6 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y CONFIG_CMD_DATE=y # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="mti,malta" CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig index 592fef5..6759d18 100644 --- a/configs/malta64el_defconfig +++ b/configs/malta64el_defconfig @@ -19,7 +19,6 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y CONFIG_CMD_DATE=y # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="mti,malta" CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y diff --git a/configs/malta_defconfig b/configs/malta_defconfig index 9d6064e..6b6869d 100644 --- a/configs/malta_defconfig +++ b/configs/malta_defconfig @@ -17,7 +17,6 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y CONFIG_CMD_DATE=y # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="mti,malta" CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig index f30f451..8dca7ff 100644 --- a/configs/maltael_defconfig +++ b/configs/maltael_defconfig @@ -18,7 +18,6 @@ CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y CONFIG_CMD_DATE=y # CONFIG_ISO_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="mti,malta" CONFIG_ENV_IS_IN_FLASH=y CONFIG_MTD_NOR_FLASH=y diff --git a/configs/mscc_ocelot_pcb120_defconfig b/configs/mscc_jr2_defconfig index c5a9f96..b215754 100644 --- a/configs/mscc_ocelot_pcb120_defconfig +++ b/configs/mscc_jr2_defconfig @@ -2,6 +2,7 @@ CONFIG_MIPS=y CONFIG_SYS_TEXT_BASE=0x40000000 CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_ARCH_MSCC=y +CONFIG_SOC_JR2=y CONFIG_SYS_LITTLE_ENDIAN=y CONFIG_FIT=y CONFIG_BOOTDELAY=3 @@ -9,7 +10,7 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200" CONFIG_LOGLEVEL=7 CONFIG_DISPLAY_CPUINFO=y -CONFIG_SYS_PROMPT="pcb120 # " +CONFIG_SYS_PROMPT="jr2 # " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set # CONFIG_CMD_ELF is not set @@ -21,26 +22,24 @@ CONFIG_CMD_MEMINFO=y CONFIG_CMD_MEMTEST=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y -CONFIG_CMD_MTD=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -CONFIG_CMD_DHCP=y -# CONFIG_NET_TFTP_VARS is not set -# CONFIG_CMD_NFS is not set -CONFIG_CMD_PING=y +# CONFIG_CMD_NET is not set CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" -CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),15m(linux),15m(linux.bk)" -CONFIG_CMD_UBI=y -# CONFIG_CMD_UBIFS is not set +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:1m(UBoot),256k(Env),256k(Env.bk)" # CONFIG_ISO_PARTITION is not set -CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb120" +CONFIG_DEFAULT_DEVICE_TREE="jr2_pcb110" +CONFIG_OF_LIST="jr2_pcb110 jr2_pcb111 serval2_pcb112" +CONFIG_DTB_RESELECT=y +CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y -CONFIG_MTD=y -CONFIG_MTD_SPI_NAND=y +CONFIG_MSCC_SGPIO=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y @@ -56,5 +55,5 @@ CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y -CONFIG_DESIGNWARE_SPI=y CONFIG_LZMA=y +CONFIG_XZ=y diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig index d7476c4..7154e97 100644 --- a/configs/mscc_luton_defconfig +++ b/configs/mscc_luton_defconfig @@ -5,7 +5,7 @@ CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART_BASE=0x70100000 CONFIG_DEBUG_UART_CLOCK=208333333 CONFIG_ARCH_MSCC=y -CONFIG_TARGET_LUTON_PCB091=y +CONFIG_SOC_LUTON=y CONFIG_DDRTYPE_MT47H128M8HQ=y CONFIG_SYS_LITTLE_ENDIAN=y CONFIG_MIPS_BOOT_FDT=y @@ -16,7 +16,7 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200" CONFIG_LOGLEVEL=7 CONFIG_DISPLAY_CPUINFO=y -CONFIG_SYS_PROMPT="pcb091 # " +CONFIG_SYS_PROMPT="luton # " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set # CONFIG_CMD_ELF is not set @@ -34,15 +34,22 @@ CONFIG_CMD_DHCP=y # CONFIG_NET_TFTP_VARS is not set # CONFIG_CMD_NFS is not set CONFIG_CMD_PING=y +CONFIG_CMD_TIME=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:512k(UBoot),256k(Env),256k(conf),6m@1m(linux)" # CONFIG_ISO_PARTITION is not set CONFIG_DEFAULT_DEVICE_TREE="luton_pcb091" +CONFIG_OF_LIST="luton_pcb090 luton_pcb091" +CONFIG_DTB_RESELECT=y +CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y +CONFIG_MSCC_SGPIO=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y @@ -60,5 +67,5 @@ CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y -CONFIG_SOFT_SPI=y +CONFIG_MSCC_BB_SPI=y CONFIG_LZMA=y diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig index 5fa74db..fb6a5bd 100644 --- a/configs/mscc_ocelot_defconfig +++ b/configs/mscc_ocelot_defconfig @@ -5,7 +5,6 @@ CONFIG_DEBUG_UART_BOARD_INIT=y CONFIG_DEBUG_UART_BASE=0x70100000 CONFIG_DEBUG_UART_CLOCK=250000000 CONFIG_ARCH_MSCC=y -CONFIG_TARGET_OCELOT_PCB123=y CONFIG_SYS_LITTLE_ENDIAN=y CONFIG_DEBUG_UART=y CONFIG_FIT=y @@ -14,7 +13,7 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200" CONFIG_LOGLEVEL=7 CONFIG_DISPLAY_CPUINFO=y -CONFIG_SYS_PROMPT="pcb123 # " +CONFIG_SYS_PROMPT="ocelot # " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set # CONFIG_CMD_ELF is not set @@ -40,12 +39,18 @@ CONFIG_CMD_UBI=y # CONFIG_CMD_UBIFS is not set # CONFIG_ISO_PARTITION is not set CONFIG_DEFAULT_DEVICE_TREE="ocelot_pcb123" +CONFIG_OF_LIST="ocelot_pcb120 ocelot_pcb123" +CONFIG_DTB_RESELECT=y +CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y CONFIG_MTD=y CONFIG_MTD_SPI_NAND=y +CONFIG_MSCC_SGPIO=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y @@ -63,5 +68,4 @@ CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y -CONFIG_DESIGNWARE_SPI=y CONFIG_LZMA=y diff --git a/configs/netgear_cg3100d_ram_defconfig b/configs/netgear_cg3100d_ram_defconfig index 83e8224..5fada57 100644 --- a/configs/netgear_cg3100d_ram_defconfig +++ b/configs/netgear_cg3100d_ram_defconfig @@ -27,7 +27,6 @@ CONFIG_CMD_MEMINFO=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="netgear,cg3100d" # CONFIG_NET is not set # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/netgear_dgnd3700v2_ram_defconfig b/configs/netgear_dgnd3700v2_ram_defconfig index 0f3914f..8968517 100644 --- a/configs/netgear_dgnd3700v2_ram_defconfig +++ b/configs/netgear_dgnd3700v2_ram_defconfig @@ -30,7 +30,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="netgear,dgnd3700v2" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/pic32mzdask_defconfig b/configs/pic32mzdask_defconfig index de699fc..d411031 100644 --- a/configs/pic32mzdask_defconfig +++ b/configs/pic32mzdask_defconfig @@ -21,7 +21,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_ISO_PARTITION is not set # CONFIG_EFI_PARTITION is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="pic32mzda_sk" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_BLK is not set diff --git a/configs/sagem_f@st1704_ram_defconfig b/configs/sagem_f@st1704_ram_defconfig index 8c36f5d..da19b61 100644 --- a/configs/sagem_f@st1704_ram_defconfig +++ b/configs/sagem_f@st1704_ram_defconfig @@ -30,7 +30,6 @@ CONFIG_CMD_SPI=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="sagem,f@st1704" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/configs/sfr_nb4-ser_ram_defconfig b/configs/sfr_nb4-ser_ram_defconfig index 3962287..600e656 100644 --- a/configs/sfr_nb4-ser_ram_defconfig +++ b/configs/sfr_nb4-ser_ram_defconfig @@ -29,7 +29,6 @@ CONFIG_CMD_USB=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y # CONFIG_CMD_MISC is not set -CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="sfr,nb4-ser" CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set diff --git a/doc/device-tree-bindings/gpio/mscc_sgpio.txt b/doc/device-tree-bindings/gpio/mscc_sgpio.txt new file mode 100644 index 0000000..3d344d6 --- /dev/null +++ b/doc/device-tree-bindings/gpio/mscc_sgpio.txt @@ -0,0 +1,45 @@ +Microsemi Corporation (MSCC) Serial GPIO driver + +The MSCC serial GPIO extends the number or GPIO's on the system by +means of 4 dedicated pins: one input, one output, one clock and one +strobe pin. By attaching a number of (external) shift registers, the +effective GPIO count can be extended by up to 128 GPIO's per +controller. + +Required properties: +- compatible : "mscc,luton-sgpio" or "mscc,ocelot-sgpio" +- clock: Reference clock used to generate clock divider setting. See + mscc,sgpio-frequency property. +- reg : Physical base address and length of the controller's registers. +- #gpio-cells : Should be two. The first cell is the pin number and the + second cell is used to specify optional parameters: + - bit 0 specifies polarity (0 for normal, 1 for inverted) +- gpio-controller : Marks the device node as a GPIO controller. +- gpio-ranges: Standard gpio range(s): phandle, gpio base, pinctrl base + and count. + +Optional properties: +- ngpios: See gpio.txt +- mscc,sgpio-frequency: The frequency at which the serial bitstream is + generated and sampled. Default: 12500000 (Hz). +- mscc,sgpio-ports: A bitmask (32 bits) of which ports are enabled in + the serialized gpio stream. One 'port' will transport from 1 to 4 + gpio bits. Default: 0xFFFFFFFF. + +Typically the pinctrl-0 and pinctrl-names properties will also be +present to enable the use of the SIO CLK, LD, DI and DO for some +regular GPIO pins. + +Example: + +sgpio: gpio@10700f8 { + compatible = "mscc,ocelot-sgpio"; + pinctrl-0 = <&sgpio_pins>; + pinctrl-names = "default"; + reg = <0x10700f8 0x100>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&sgpio 0 0 64>; + mscc,sgpio-frequency = <12500>; + mscc,sgpio-ports = <0x000FFFFF>; +}; diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c8c6c60..14a14be 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -99,12 +99,16 @@ config LPC32XX_GPIO help Support for the LPC32XX GPIO driver. -config MSCC_BITBANG_SPI_GPIO - bool "Microsemi bitbang spi GPIO driver" +config MSCC_SGPIO + bool "Microsemi Serial GPIO driver" depends on DM_GPIO && SOC_VCOREIII help - Support controlling the GPIO used for SPI bitbang by software. Can - be used by the VCoreIII SoCs, but it was mainly useful for Luton. + Support for the VCoreIII SoC serial GPIO device. By using a + serial interface, the SIO controller significantly extends + the number of available GPIOs with a minimum number of + additional pins on the device. The primary purpose of the + SIO controller is to connect control signals from SFP + modules and to act as an LED controller. config MSM_GPIO bool "Qualcomm GPIO driver" diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 61feda1..7c479ef 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -59,4 +59,4 @@ obj-$(CONFIG_MSM_GPIO) += msm_gpio.o obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o obj-$(CONFIG_PM8916_GPIO) += pm8916_gpio.o obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o -obj-$(CONFIG_MSCC_BITBANG_SPI_GPIO) += gpio-mscc-bitbang-spi.o +obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o diff --git a/drivers/gpio/gpio-mscc-bitbang-spi.c b/drivers/gpio/gpio-mscc-bitbang-spi.c deleted file mode 100644 index b675f90..0000000 --- a/drivers/gpio/gpio-mscc-bitbang-spi.c +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Microsemi SoCs pinctrl driver - * - * Author: <gregory.clement@bootlin.com> - * License: Dual MIT/GPL - * Copyright (c) 2018 Microsemi Corporation - */ - -#include <common.h> -#include <asm-generic/gpio.h> -#include <asm/io.h> -#include <dm.h> -#include <errno.h> - -enum { - SDI, - CS0, - CS1, - CS2, - CS3, - SDO, - SCK -}; - -static const int pinmap[] = { 0, 5, 6, 7, 8, 10, 12 }; - -#define SW_SPI_CSn_OE 0x1E /* bits 1 to 4 */ -#define SW_SPI_CS0_OE BIT(1) -#define SW_SPI_SDO_OE BIT(9) -#define SW_SPI_SCK_OE BIT(11) -#define SW_PIN_CTRL_MODE BIT(13) - -struct mscc_bb_spi_gpio { - void __iomem *regs; - u32 cache_val; -}; - -static int mscc_bb_spi_gpio_set(struct udevice *dev, unsigned oft, int val) -{ - struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); - - if (val) - gpio->cache_val |= BIT(pinmap[oft]); - else - gpio->cache_val &= ~BIT(pinmap[oft]); - - writel(gpio->cache_val, gpio->regs); - - return 0; -} - -static int mscc_bb_spi_gpio_direction_output(struct udevice *dev, unsigned oft, - int val) -{ - if (oft == 0) { - pr_err("SW_SPI_DSI can't be used as output\n"); - return -ENOTSUPP; - } - - mscc_bb_spi_gpio_set(dev, oft, val); - - return 0; -} - -static int mscc_bb_spi_gpio_direction_input(struct udevice *dev, unsigned oft) -{ - return 0; -} - -static int mscc_bb_spi_gpio_get(struct udevice *dev, unsigned int oft) -{ - struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); - u32 val = readl(gpio->regs); - - return !!(val & BIT(pinmap[oft])); -} - -static const struct dm_gpio_ops mscc_bb_spi_gpio_ops = { - .direction_output = mscc_bb_spi_gpio_direction_output, - .direction_input = mscc_bb_spi_gpio_direction_input, - .set_value = mscc_bb_spi_gpio_set, - .get_value = mscc_bb_spi_gpio_get, -}; - -static int mscc_bb_spi_gpio_probe(struct udevice *dev) -{ - struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); - struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); - - gpio->regs = dev_remap_addr(dev); - if (!gpio->regs) - return -EINVAL; - - uc_priv->bank_name = dev->name; - uc_priv->gpio_count = ARRAY_SIZE(pinmap); - /* - * Enable software mode to control the SPI pin, enables the - * output mode for most of the pin and initialize the cache - * value in the same time - */ - - gpio->cache_val = SW_PIN_CTRL_MODE | SW_SPI_SCK_OE | SW_SPI_SDO_OE | - SW_SPI_CS0_OE; - writel(gpio->cache_val, gpio->regs); - - return 0; -} - -static const struct udevice_id mscc_bb_spi_gpio_ids[] = { - {.compatible = "mscc,spi-bitbang-gpio"}, - {} -}; - -U_BOOT_DRIVER(gpio_mscc_bb_spi) = { - .name = "gpio-mscc-spi-bitbang", - .id = UCLASS_GPIO, - .ops = &mscc_bb_spi_gpio_ops, - .probe = mscc_bb_spi_gpio_probe, - .of_match = of_match_ptr(mscc_bb_spi_gpio_ids), - .priv_auto_alloc_size = sizeof(struct mscc_bb_spi_gpio), -}; diff --git a/drivers/gpio/mscc_sgpio.c b/drivers/gpio/mscc_sgpio.c new file mode 100644 index 0000000..c899454 --- /dev/null +++ b/drivers/gpio/mscc_sgpio.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs serial gpio driver + * + * Author: <lars.povlsen@microchip.com> + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <dm.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <errno.h> +#include <clk.h> + +#define MSCC_SGPIOS_PER_BANK 32 +#define MSCC_SGPIO_BANK_DEPTH 4 + +enum { + REG_INPUT_DATA, + REG_PORT_CONFIG, + REG_PORT_ENABLE, + REG_SIO_CONFIG, + REG_SIO_CLOCK, + MAXREG +}; + +struct mscc_sgpio_bf { + u8 beg; + u8 end; +}; + +struct mscc_sgpio_props { + u8 regoff[MAXREG]; + struct mscc_sgpio_bf auto_repeat; + struct mscc_sgpio_bf port_width; + struct mscc_sgpio_bf clk_freq; + struct mscc_sgpio_bf bit_source; +}; + +#define __M(bf) GENMASK((bf).end, (bf).beg) +#define __F(bf, x) (__M(bf) & ((x) << (bf).beg)) +#define __X(bf, x) (((x) >> (bf).beg) & GENMASK(((bf).end - (bf).beg), 0)) + +#define MSCC_M_CFG_SIO_AUTO_REPEAT(p) BIT(p->props->auto_repeat.beg) +#define MSCC_F_CFG_SIO_PORT_WIDTH(p, x) __F(p->props->port_width, x) +#define MSCC_M_CFG_SIO_PORT_WIDTH(p) __M(p->props->port_width) +#define MSCC_F_CLOCK_SIO_CLK_FREQ(p, x) __F(p->props->clk_freq, x) +#define MSCC_M_CLOCK_SIO_CLK_FREQ(p) __M(p->props->clk_freq) +#define MSCC_F_PORT_CFG_BIT_SOURCE(p, x) __F(p->props->bit_source, x) +#define MSCC_X_PORT_CFG_BIT_SOURCE(p, x) __X(p->props->bit_source, x) + +const struct mscc_sgpio_props props_luton = { + .regoff = { 0x00, 0x09, 0x29, 0x2a, 0x2b }, + .auto_repeat = { 5, 5 }, + .port_width = { 2, 3 }, + .clk_freq = { 0, 11 }, + .bit_source = { 0, 11 }, +}; + +const struct mscc_sgpio_props props_ocelot = { + .regoff = { 0x00, 0x06, 0x26, 0x04, 0x05 }, + .auto_repeat = { 10, 10 }, + .port_width = { 7, 8 }, + .clk_freq = { 8, 19 }, + .bit_source = { 12, 23 }, +}; + +struct mscc_sgpio_priv { + u32 bitcount; + u32 ports; + u32 clock; + u32 mode[MSCC_SGPIOS_PER_BANK]; + u32 __iomem *regs; + const struct mscc_sgpio_props *props; +}; + +static inline u32 sgpio_readl(struct mscc_sgpio_priv *priv, u32 rno, u32 off) +{ + u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off]; + + return readl(reg); +} + +static inline void sgpio_writel(struct mscc_sgpio_priv *priv, + u32 val, u32 rno, u32 off) +{ + u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off]; + + writel(val, reg); +} + +static void sgpio_clrsetbits(struct mscc_sgpio_priv *priv, + u32 rno, u32 off, u32 clear, u32 set) +{ + u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off]; + + clrsetbits_le32(reg, clear, set); +} + +static int mscc_sgpio_direction_input(struct udevice *dev, unsigned int gpio) +{ + struct mscc_sgpio_priv *priv = dev_get_priv(dev); + + u32 port = gpio % MSCC_SGPIOS_PER_BANK; + u32 bit = gpio / MSCC_SGPIOS_PER_BANK; + + priv->mode[port] |= BIT(bit); + + return 0; +} + +static int mscc_sgpio_direction_output(struct udevice *dev, + unsigned int gpio, int value) +{ + struct mscc_sgpio_priv *priv = dev_get_priv(dev); + u32 port = gpio % MSCC_SGPIOS_PER_BANK; + u32 bit = gpio / MSCC_SGPIOS_PER_BANK; + u32 mask = 3 << (3 * bit); + + debug("set: port %d, bit %d, mask 0x%08x, value %d\n", + port, bit, mask, value); + + value = (value & 3) << (3 * bit); + sgpio_clrsetbits(priv, REG_PORT_CONFIG, port, + MSCC_F_PORT_CFG_BIT_SOURCE(priv, mask), + MSCC_F_PORT_CFG_BIT_SOURCE(priv, value)); + clrbits_le32(&priv->mode[port], BIT(bit)); + + return 0; +} + +static int mscc_sgpio_get_function(struct udevice *dev, unsigned int gpio) +{ + struct mscc_sgpio_priv *priv = dev_get_priv(dev); + u32 port = gpio % MSCC_SGPIOS_PER_BANK; + u32 bit = gpio / MSCC_SGPIOS_PER_BANK; + u32 val = priv->mode[port] & BIT(bit); + + if (val) + return GPIOF_INPUT; + else + return GPIOF_OUTPUT; +} + +static int mscc_sgpio_set_value(struct udevice *dev, + unsigned int gpio, int value) +{ + return mscc_sgpio_direction_output(dev, gpio, value); +} + +static int mscc_sgpio_get_value(struct udevice *dev, unsigned int gpio) +{ + struct mscc_sgpio_priv *priv = dev_get_priv(dev); + u32 port = gpio % MSCC_SGPIOS_PER_BANK; + u32 bit = gpio / MSCC_SGPIOS_PER_BANK; + int ret; + + if (mscc_sgpio_get_function(dev, gpio) == GPIOF_INPUT) { + ret = !!(sgpio_readl(priv, REG_INPUT_DATA, bit) & BIT(port)); + } else { + u32 portval = sgpio_readl(priv, REG_PORT_CONFIG, port); + + ret = MSCC_X_PORT_CFG_BIT_SOURCE(priv, portval); + ret = !!(ret & (3 << (3 * bit))); + } + + debug("get: gpio %d, port %d, bit %d, value %d\n", + gpio, port, bit, ret); + return ret; +} + +static int mscc_sgpio_get_count(struct udevice *dev) +{ + struct ofnode_phandle_args args; + int count = 0, i = 0, ret; + + ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, i, &args); + while (ret != -ENOENT) { + count += args.args[2]; + ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, + ++i, &args); + } + return count; +} + +static int mscc_sgpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct mscc_sgpio_priv *priv = dev_get_priv(dev); + int err, div_clock = 0, port; + u32 val; + struct clk clk; + + err = clk_get_by_index(dev, 0, &clk); + if (!err) { + err = clk_get_rate(&clk); + if (IS_ERR_VALUE(err)) { + dev_err(dev, "Invalid clk rate\n"); + return -EINVAL; + } + div_clock = err; + } else { + dev_err(dev, "Failed to get clock\n"); + return err; + } + + priv->props = (const struct mscc_sgpio_props *)dev_get_driver_data(dev); + priv->ports = dev_read_u32_default(dev, "mscc,sgpio-ports", 0xFFFFFFFF); + priv->clock = dev_read_u32_default(dev, "mscc,sgpio-frequency", + 12500000); + if (priv->clock <= 0 || priv->clock > div_clock) { + dev_err(dev, "Invalid frequency %d\n", priv->clock); + return -EINVAL; + } + + uc_priv->gpio_count = mscc_sgpio_get_count(dev); + uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", + uc_priv->gpio_count); + if (uc_priv->gpio_count < 1 || uc_priv->gpio_count > + (4 * MSCC_SGPIOS_PER_BANK)) { + dev_err(dev, "Invalid gpio count %d\n", uc_priv->gpio_count); + return -EINVAL; + } + priv->bitcount = DIV_ROUND_UP(uc_priv->gpio_count, + MSCC_SGPIOS_PER_BANK); + debug("probe: gpios = %d, bit-count = %d\n", + uc_priv->gpio_count, priv->bitcount); + + priv->regs = (u32 __iomem *)dev_read_addr(dev); + uc_priv->bank_name = "sgpio"; + + sgpio_clrsetbits(priv, REG_SIO_CONFIG, 0, + MSCC_M_CFG_SIO_PORT_WIDTH(priv), + MSCC_F_CFG_SIO_PORT_WIDTH(priv, priv->bitcount - 1) | + MSCC_M_CFG_SIO_AUTO_REPEAT(priv)); + val = div_clock / priv->clock; + debug("probe: div-clock = %d KHz, freq = %d KHz, div = %d\n", + div_clock / 1000, priv->clock / 1000, val); + sgpio_clrsetbits(priv, REG_SIO_CLOCK, 0, + MSCC_M_CLOCK_SIO_CLK_FREQ(priv), + MSCC_F_CLOCK_SIO_CLK_FREQ(priv, val)); + + for (port = 0; port < 32; port++) + sgpio_writel(priv, 0, REG_PORT_CONFIG, port); + sgpio_writel(priv, priv->ports, REG_PORT_ENABLE, 0); + + debug("probe: sgpio regs = %p\n", priv->regs); + + return 0; +} + +static const struct dm_gpio_ops mscc_sgpio_ops = { + .direction_input = mscc_sgpio_direction_input, + .direction_output = mscc_sgpio_direction_output, + .get_function = mscc_sgpio_get_function, + .get_value = mscc_sgpio_get_value, + .set_value = mscc_sgpio_set_value, +}; + +static const struct udevice_id mscc_sgpio_ids[] = { + { .compatible = "mscc,luton-sgpio", .data = (ulong)&props_luton }, + { .compatible = "mscc,ocelot-sgpio", .data = (ulong)&props_ocelot }, + { } +}; + +U_BOOT_DRIVER(gpio_mscc_sgpio) = { + .name = "mscc-sgpio", + .id = UCLASS_GPIO, + .of_match = mscc_sgpio_ids, + .ops = &mscc_sgpio_ops, + .probe = mscc_sgpio_probe, + .priv_auto_alloc_size = sizeof(struct mscc_sgpio_priv), +}; diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c index 3132c3e..cb2a7c3 100644 --- a/drivers/mmc/jz_mmc.c +++ b/drivers/mmc/jz_mmc.c @@ -134,6 +134,60 @@ static int jz_mmc_clock_rate(void) return 24000000; } +#if CONFIG_IS_ENABLED(MMC_WRITE) +static inline void jz_mmc_write_data(struct jz_mmc_priv *priv, struct mmc_data *data) +{ + int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4); + const void *buf = data->src; + + while (sz--) { + u32 val = get_unaligned_le32(buf); + + wait_for_bit_le32(priv->regs + MSC_IREG, + MSC_IREG_TXFIFO_WR_REQ, + true, 10000, false); + writel(val, priv->regs + MSC_TXFIFO); + buf += 4; + } +} +#else +static void jz_mmc_write_data(struct jz_mmc_priv *priv, struct mmc_data *data) +{} +#endif + +static inline int jz_mmc_read_data(struct jz_mmc_priv *priv, struct mmc_data *data) +{ + int sz = data->blocks * data->blocksize; + void *buf = data->dest; + u32 stat, val; + + do { + stat = readl(priv->regs + MSC_STAT); + + if (stat & MSC_STAT_TIME_OUT_READ) + return -ETIMEDOUT; + if (stat & MSC_STAT_CRC_READ_ERROR) + return -EINVAL; + if (stat & MSC_STAT_DATA_FIFO_EMPTY) { + udelay(10); + continue; + } + do { + val = readl(priv->regs + MSC_RXFIFO); + if (sz == 1) + *(u8 *)buf = (u8)val; + else if (sz == 2) + put_unaligned_le16(val, buf); + else if (sz >= 4) + put_unaligned_le32(val, buf); + buf += 4; + sz -= 4; + stat = readl(priv->regs + MSC_STAT); + } while (!(stat & MSC_STAT_DATA_FIFO_EMPTY)); + } while (!(stat & MSC_STAT_DATA_TRAN_DONE)); + return 0; +} + static int jz_mmc_send_cmd(struct mmc *mmc, struct jz_mmc_priv *priv, struct mmc_cmd *cmd, struct mmc_data *data) { @@ -249,51 +303,14 @@ static int jz_mmc_send_cmd(struct mmc *mmc, struct jz_mmc_priv *priv, cmd->response[0] |= readw(priv->regs + MSC_RES) & 0xff; } } - - if (data && (data->flags & MMC_DATA_WRITE)) { - /* write the data */ - int sz = DIV_ROUND_UP(data->blocks * data->blocksize, 4); - const void *buf = data->src; - - while (sz--) { - u32 val = get_unaligned_le32(buf); - - wait_for_bit_le32(priv->regs + MSC_IREG, - MSC_IREG_TXFIFO_WR_REQ, - true, 10000, false); - writel(val, priv->regs + MSC_TXFIFO); - buf += 4; + if (data) { + if (data->flags & MMC_DATA_WRITE) + jz_mmc_write_data(priv, data); + else if (data->flags & MMC_DATA_READ) { + ret = jz_mmc_read_data(priv, data); + if (ret) + return ret; } - } else if (data && (data->flags & MMC_DATA_READ)) { - /* read the data */ - int sz = data->blocks * data->blocksize; - void *buf = data->dest; - - do { - stat = readl(priv->regs + MSC_STAT); - - if (stat & MSC_STAT_TIME_OUT_READ) - return -ETIMEDOUT; - if (stat & MSC_STAT_CRC_READ_ERROR) - return -EINVAL; - if (stat & MSC_STAT_DATA_FIFO_EMPTY) { - udelay(10); - continue; - } - do { - u32 val = readl(priv->regs + MSC_RXFIFO); - - if (sz == 1) - *(u8 *)buf = (u8)val; - else if (sz == 2) - put_unaligned_le16(val, buf); - else if (sz >= 4) - put_unaligned_le32(val, buf); - buf += 4; - sz -= 4; - stat = readl(priv->regs + MSC_STAT); - } while (!(stat & MSC_STAT_DATA_FIFO_EMPTY)); - } while (!(stat & MSC_STAT_DATA_TRAN_DONE)); } return 0; diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index b8acc33..c8c83c9 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -65,13 +65,13 @@ err_out: return err; } -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_berase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt) #else ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) #endif { -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct blk_desc *block_dev = dev_get_uclass_platdata(dev); #endif int dev_num = block_dev->devnum; @@ -183,7 +183,7 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, return blkcnt; } -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, const void *src) #else @@ -191,7 +191,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, const void *src) #endif { -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) struct blk_desc *block_dev = dev_get_uclass_platdata(dev); #endif int dev_num = block_dev->devnum; diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c index a31efba..110985e 100644 --- a/drivers/net/bcm6368-eth.c +++ b/drivers/net/bcm6368-eth.c @@ -309,6 +309,43 @@ static int bcm6368_eth_start(struct udevice *dev) struct bcm6368_eth_priv *priv = dev_get_priv(dev); uint8_t i; + /* disable all ports */ + for (i = 0; i < priv->num_ports; i++) { + setbits_8(priv->base + ETH_PORTOV_REG(i), + ETH_PORTOV_ENABLE_MASK); + setbits_8(priv->base + ETH_PTCTRL_REG(i), + ETH_PTCTRL_RXDIS_MASK | ETH_PTCTRL_TXDIS_MASK); + priv->sw_port_link[i] = 0; + } + + /* enable external ports */ + for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) { + u8 rgmii_ctrl = ETH_RGMII_CTRL_GMII_CLK_EN; + + if (!priv->used_ports[i].used) + continue; + + if (priv->rgmii_override) + rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN; + if (priv->rgmii_timing) + rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN; + + setbits_8(priv->base + ETH_RGMII_CTRL_REG(i), rgmii_ctrl); + } + + /* reset mib */ + setbits_8(priv->base + ETH_GMCR_REG, ETH_GMCR_RST_MIB_MASK); + mdelay(1); + clrbits_8(priv->base + ETH_GMCR_REG, ETH_GMCR_RST_MIB_MASK); + mdelay(1); + + /* force CPU port state */ + setbits_8(priv->base + ETH_IMPOV_REG, + ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK); + + /* enable switch forward engine */ + setbits_8(priv->base + ETH_SWMODE_REG, ETH_SWMODE_FWD_EN_MASK); + /* prepare rx dma buffers */ for (i = 0; i < ETH_RX_DESC; i++) { int ret = dma_prepare_rcv_buf(&priv->rx_dma, net_rx_packets[i], @@ -368,6 +405,31 @@ static int bcm6368_eth_start(struct udevice *dev) static void bcm6368_eth_stop(struct udevice *dev) { struct bcm6368_eth_priv *priv = dev_get_priv(dev); + uint8_t i; + + /* disable all ports */ + for (i = 0; i < priv->num_ports; i++) { + setbits_8(priv->base + ETH_PORTOV_REG(i), + ETH_PORTOV_ENABLE_MASK); + setbits_8(priv->base + ETH_PTCTRL_REG(i), + ETH_PTCTRL_RXDIS_MASK | ETH_PTCTRL_TXDIS_MASK); + } + + /* disable external ports */ + for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) { + if (!priv->used_ports[i].used) + continue; + + clrbits_8(priv->base + ETH_RGMII_CTRL_REG(i), + ETH_RGMII_CTRL_GMII_CLK_EN); + } + + /* disable CPU port */ + clrbits_8(priv->base + ETH_IMPOV_REG, + ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK); + + /* disable switch forward engine */ + clrbits_8(priv->base + ETH_SWMODE_REG, ETH_SWMODE_FWD_EN_MASK); /* disable dma rx channel */ dma_disable(&priv->rx_dma); @@ -444,7 +506,6 @@ static int bcm6368_eth_probe(struct udevice *dev) struct eth_pdata *pdata = dev_get_platdata(dev); struct bcm6368_eth_priv *priv = dev_get_priv(dev); int num_ports, ret, i; - uint32_t val; ofnode node; /* get base address */ @@ -561,52 +622,6 @@ static int bcm6368_eth_probe(struct udevice *dev) if (ret) return ret; - /* disable all ports */ - for (i = 0; i < priv->num_ports; i++) { - writeb_be(ETH_PORTOV_ENABLE_MASK, - priv->base + ETH_PORTOV_REG(i)); - writeb_be(ETH_PTCTRL_RXDIS_MASK | - ETH_PTCTRL_TXDIS_MASK, - priv->base + ETH_PTCTRL_REG(i)); - - priv->sw_port_link[i] = 0; - } - - /* enable external ports */ - for (i = ETH_RGMII_PORT0; i < priv->num_ports; i++) { - u8 rgmii_ctrl; - - if (!priv->used_ports[i].used) - continue; - - rgmii_ctrl = readb_be(priv->base + ETH_RGMII_CTRL_REG(i)); - rgmii_ctrl |= ETH_RGMII_CTRL_GMII_CLK_EN; - if (priv->rgmii_override) - rgmii_ctrl |= ETH_RGMII_CTRL_MII_OVERRIDE_EN; - if (priv->rgmii_timing) - rgmii_ctrl |= ETH_RGMII_CTRL_TIMING_SEL_EN; - writeb_be(rgmii_ctrl, priv->base + ETH_RGMII_CTRL_REG(i)); - } - - /* reset mib */ - val = readb_be(priv->base + ETH_GMCR_REG); - val |= ETH_GMCR_RST_MIB_MASK; - writeb_be(val, priv->base + ETH_GMCR_REG); - mdelay(1); - val &= ~ETH_GMCR_RST_MIB_MASK; - writeb_be(val, priv->base + ETH_GMCR_REG); - mdelay(1); - - /* force CPU port state */ - val = readb_be(priv->base + ETH_IMPOV_REG); - val |= ETH_IMPOV_FORCE_MASK | ETH_IMPOV_LINKUP_MASK; - writeb_be(val, priv->base + ETH_IMPOV_REG); - - /* enable switch forward engine */ - val = readb_be(priv->base + ETH_SWMODE_REG); - val |= ETH_SWMODE_FWD_EN_MASK; - writeb_be(val, priv->base + ETH_SWMODE_REG); - /* enable jumbo on all ports */ writel_be(0x1ff, priv->base + ETH_JMBCTL_PORT_REG); writew_be(9728, priv->base + ETH_JMBCTL_MAXSIZE_REG); diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig index cfc6c06..d07ea1b 100644 --- a/drivers/pinctrl/mscc/Kconfig +++ b/drivers/pinctrl/mscc/Kconfig @@ -20,3 +20,12 @@ config PINCTRL_MSCC_LUTON help Support pin multiplexing and pin configuration control on Microsemi luton SoCs. + +config PINCTRL_MSCC_JR2 + depends on SOC_JR2 && PINCTRL_FULL && OF_CONTROL + select PINCTRL_MSCC + default y + bool "Microsemi jr2 family pin control driver" + help + Support pin multiplexing and pin configuration control on + Microsemi jr2 SoCs. diff --git a/drivers/pinctrl/mscc/Makefile b/drivers/pinctrl/mscc/Makefile index 6910671..8038d54 100644 --- a/drivers/pinctrl/mscc/Makefile +++ b/drivers/pinctrl/mscc/Makefile @@ -3,3 +3,4 @@ obj-y += mscc-common.o obj-$(CONFIG_PINCTRL_MSCC_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_MSCC_LUTON) += pinctrl-luton.o +obj-$(CONFIG_PINCTRL_MSCC_JR2) += pinctrl-jr2.o diff --git a/drivers/pinctrl/mscc/mscc-common.c b/drivers/pinctrl/mscc/mscc-common.c index d74b8a6..bd3e6ea 100644 --- a/drivers/pinctrl/mscc/mscc-common.c +++ b/drivers/pinctrl/mscc/mscc-common.c @@ -22,16 +22,37 @@ #include <linux/io.h> #include "mscc-common.h" -#define MSCC_GPIO_OUT_SET 0x0 -#define MSCC_GPIO_OUT_CLR 0x4 -#define MSCC_GPIO_OUT 0x8 -#define MSCC_GPIO_IN 0xc -#define MSCC_GPIO_OE 0x10 -#define MSCC_GPIO_INTR 0x14 -#define MSCC_GPIO_INTR_ENA 0x18 -#define MSCC_GPIO_INTR_IDENT 0x1c -#define MSCC_GPIO_ALT0 0x20 -#define MSCC_GPIO_ALT1 0x24 +static void mscc_writel(unsigned int offset, void *addr) +{ + if (offset < 32) + writel(BIT(offset), addr); + else + writel(BIT(offset % 32), addr + 4); +} + +static unsigned int mscc_readl(unsigned int offset, void *addr) +{ + if (offset < 32) + return readl(addr); + else + return readl(addr + 4); +} + +static void mscc_setbits(unsigned int offset, void *addr) +{ + if (offset < 32) + writel(readl(addr) | BIT(offset), addr); + else + writel(readl(addr + 4) | BIT(offset % 32), addr + 4); +} + +static void mscc_clrbits(unsigned int offset, void *addr) +{ + if (offset < 32) + writel(readl(addr) & ~BIT(offset), addr); + else + writel(readl(addr + 4) & ~BIT(offset % 32), addr + 4); +} static int mscc_get_functions_count(struct udevice *dev) { @@ -67,7 +88,7 @@ static int mscc_pinmux_set_mux(struct udevice *dev, { struct mscc_pinctrl *info = dev_get_priv(dev); struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data; - int f; + int f, offset, regoff; f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins); if (f < 0) @@ -79,15 +100,22 @@ static int mscc_pinmux_set_mux(struct udevice *dev, * This is racy because both registers can't be updated at the same time * but it doesn't matter much for now. */ + offset = pin->pin; + regoff = info->mscc_gpios[MSCC_GPIO_ALT0]; + if (offset >= 32) { + offset = offset % 32; + regoff = info->mscc_gpios[MSCC_GPIO_ALT1]; + } + if (f & BIT(0)) - setbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); + mscc_setbits(offset, info->regs + regoff); else - clrbits_le32(info->regs + MSCC_GPIO_ALT0, BIT(pin->pin)); + mscc_clrbits(offset, info->regs + regoff); if (f & BIT(1)) - setbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); + mscc_setbits(offset, info->regs + regoff + 4); else - clrbits_le32(info->regs + MSCC_GPIO_ALT1, BIT(pin->pin - 1)); + mscc_clrbits(offset, info->regs + regoff + 4); return 0; } @@ -120,8 +148,8 @@ static int mscc_create_group_func_map(struct udevice *dev, } info->func[f].ngroups = npins; - info->func[f].groups = devm_kzalloc(dev, npins * - sizeof(char *), GFP_KERNEL); + info->func[f].groups = devm_kzalloc(dev, npins * sizeof(char *), + GFP_KERNEL); if (!info->func[f].groups) return -ENOMEM; @@ -150,9 +178,15 @@ static int mscc_gpio_get(struct udevice *dev, unsigned int offset) struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val; - val = readl(info->regs + MSCC_GPIO_IN); + if (mscc_readl(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]) & + BIT(offset % 32)) + val = mscc_readl(offset, + info->regs + info->mscc_gpios[MSCC_GPIO_OUT]); + else + val = mscc_readl(offset, + info->regs + info->mscc_gpios[MSCC_GPIO_IN]); - return !!(val & BIT(offset)); + return !!(val & BIT(offset % 32)); } static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) @@ -160,9 +194,11 @@ static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value) struct mscc_pinctrl *info = dev_get_priv(dev->parent); if (value) - writel(BIT(offset), info->regs + MSCC_GPIO_OUT_SET); + mscc_writel(offset, + info->regs + info->mscc_gpios[MSCC_GPIO_OUT_SET]); else - writel(BIT(offset), info->regs + MSCC_GPIO_OUT_CLR); + mscc_writel(offset, + info->regs + info->mscc_gpios[MSCC_GPIO_OUT_CLR]); return 0; } @@ -172,16 +208,16 @@ static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset) struct mscc_pinctrl *info = dev_get_priv(dev->parent); unsigned int val; - val = readl(info->regs + MSCC_GPIO_OE); + val = mscc_readl(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]); - return (val & BIT(offset)) ? GPIOF_OUTPUT : GPIOF_INPUT; + return (val & BIT(offset % 32)) ? GPIOF_OUTPUT : GPIOF_INPUT; } static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset) { struct mscc_pinctrl *info = dev_get_priv(dev->parent); - clrbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); + mscc_clrbits(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]); return 0; } @@ -191,7 +227,7 @@ static int mscc_gpio_direction_output(struct udevice *dev, { struct mscc_pinctrl *info = dev_get_priv(dev->parent); - setbits_le32(info->regs + MSCC_GPIO_OE, BIT(offset)); + mscc_setbits(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]); return mscc_gpio_set(dev, offset, value); } @@ -215,7 +251,8 @@ const struct pinctrl_ops mscc_pinctrl_ops = { int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, - char *const *function_names) + char * const *function_names, + const unsigned long *mscc_gpios) { struct mscc_pinctrl *priv = dev_get_priv(dev); int ret; @@ -230,6 +267,7 @@ int mscc_pinctrl_probe(struct udevice *dev, int num_func, priv->mscc_pins = mscc_pins; priv->num_pins = num_pins; priv->function_names = function_names; + priv->mscc_gpios = mscc_gpios; ret = mscc_pinctrl_register(dev, priv); return ret; diff --git a/drivers/pinctrl/mscc/mscc-common.h b/drivers/pinctrl/mscc/mscc-common.h index b0001db..3c5c1fa 100644 --- a/drivers/pinctrl/mscc/mscc-common.h +++ b/drivers/pinctrl/mscc/mscc-common.h @@ -9,6 +9,19 @@ #define MSCC_FUNC_PER_PIN 4 +enum mscc_regs_gpio { + MSCC_GPIO_OUT_SET, + MSCC_GPIO_OUT_CLR, + MSCC_GPIO_OUT, + MSCC_GPIO_IN, + MSCC_GPIO_OE, + MSCC_GPIO_INTR, + MSCC_GPIO_INTR_ENA, + MSCC_GPIO_INTR_IDENT, + MSCC_GPIO_ALT0, + MSCC_GPIO_ALT1, +}; + struct mscc_pin_caps { unsigned int pin; unsigned char functions[MSCC_FUNC_PER_PIN]; @@ -41,11 +54,13 @@ struct mscc_pinctrl { const struct mscc_pin_data *mscc_pins; int num_pins; char * const *function_names; + const unsigned long *mscc_gpios; }; int mscc_pinctrl_probe(struct udevice *dev, int num_func, const struct mscc_pin_data *mscc_pins, int num_pins, - char * const *function_names); + char * const *function_names, + const unsigned long *mscc_gpios); const struct pinctrl_ops mscc_pinctrl_ops; const struct dm_gpio_ops mscc_gpio_ops; diff --git a/drivers/pinctrl/mscc/pinctrl-jr2.c b/drivers/pinctrl/mscc/pinctrl-jr2.c new file mode 100644 index 0000000..72a9470 --- /dev/null +++ b/drivers/pinctrl/mscc/pinctrl-jr2.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs pinctrl driver + * + * Author: <horatiu.vultur@microchip.com> + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <dm/root.h> +#include <errno.h> +#include <fdtdec.h> +#include <linux/io.h> +#include <asm/gpio.h> +#include <asm/system.h> +#include "mscc-common.h" + +enum { + FUNC_NONE, + FUNC_GPIO, + FUNC_IRQ0_IN, + FUNC_IRQ0_OUT, + FUNC_IRQ1_IN, + FUNC_IRQ1_OUT, + FUNC_MIIM1, + FUNC_MIIM2, + FUNC_PCI_WAKE, + FUNC_PTP0, + FUNC_PTP1, + FUNC_PTP2, + FUNC_PTP3, + FUNC_PWM, + FUNC_RECO_CLK0, + FUNC_RECO_CLK1, + FUNC_SFP0, + FUNC_SFP1, + FUNC_SFP2, + FUNC_SFP3, + FUNC_SFP4, + FUNC_SFP5, + FUNC_SFP6, + FUNC_SFP7, + FUNC_SFP8, + FUNC_SFP9, + FUNC_SFP10, + FUNC_SFP11, + FUNC_SFP12, + FUNC_SFP13, + FUNC_SFP14, + FUNC_SFP15, + FUNC_SG0, + FUNC_SG1, + FUNC_SG2, + FUNC_SI, + FUNC_TACHO, + FUNC_TWI, + FUNC_TWI2, + FUNC_TWI_SCL_M, + FUNC_UART, + FUNC_UART2, + FUNC_MAX +}; + +static char * const jr2_function_names[] = { + [FUNC_NONE] = "none", + [FUNC_GPIO] = "gpio", + [FUNC_IRQ0_IN] = "irq0_in", + [FUNC_IRQ0_OUT] = "irq0_out", + [FUNC_IRQ1_IN] = "irq1_in", + [FUNC_IRQ1_OUT] = "irq1_out", + [FUNC_MIIM1] = "miim1", + [FUNC_MIIM2] = "miim2", + [FUNC_PCI_WAKE] = "pci_wake", + [FUNC_PTP0] = "ptp0", + [FUNC_PTP1] = "ptp1", + [FUNC_PTP2] = "ptp2", + [FUNC_PTP3] = "ptp3", + [FUNC_PWM] = "pwm", + [FUNC_RECO_CLK0] = "reco_clk0", + [FUNC_RECO_CLK1] = "reco_clk1", + [FUNC_SFP0] = "sfp0", + [FUNC_SFP1] = "sfp1", + [FUNC_SFP2] = "sfp2", + [FUNC_SFP3] = "sfp3", + [FUNC_SFP4] = "sfp4", + [FUNC_SFP5] = "sfp5", + [FUNC_SFP6] = "sfp6", + [FUNC_SFP7] = "sfp7", + [FUNC_SFP8] = "sfp8", + [FUNC_SFP9] = "sfp9", + [FUNC_SFP10] = "sfp10", + [FUNC_SFP11] = "sfp11", + [FUNC_SFP12] = "sfp12", + [FUNC_SFP13] = "sfp13", + [FUNC_SFP14] = "sfp14", + [FUNC_SFP15] = "sfp15", + [FUNC_SG0] = "sg0", + [FUNC_SG1] = "sg1", + [FUNC_SG2] = "sg2", + [FUNC_SI] = "si", + [FUNC_TACHO] = "tacho", + [FUNC_TWI] = "twi", + [FUNC_TWI2] = "twi2", + [FUNC_TWI_SCL_M] = "twi_scl_m", + [FUNC_UART] = "uart", + [FUNC_UART2] = "uart2", +}; + +#define JR2_P(p, f0, f1) \ +static struct mscc_pin_caps jr2_pin_##p = { \ + .pin = p, \ + .functions = { \ + FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_NONE \ + }, \ +} + +JR2_P(0, SG0, NONE); +JR2_P(1, SG0, NONE); +JR2_P(2, SG0, NONE); +JR2_P(3, SG0, NONE); +JR2_P(4, SG1, NONE); +JR2_P(5, SG1, NONE); +JR2_P(6, IRQ0_IN, IRQ0_OUT); +JR2_P(7, IRQ1_IN, IRQ1_OUT); +JR2_P(8, PTP0, NONE); +JR2_P(9, PTP1, NONE); +JR2_P(10, UART, NONE); +JR2_P(11, UART, NONE); +JR2_P(12, SG1, NONE); +JR2_P(13, SG1, NONE); +JR2_P(14, TWI, TWI_SCL_M); +JR2_P(15, TWI, NONE); +JR2_P(16, SI, TWI_SCL_M); +JR2_P(17, SI, TWI_SCL_M); +JR2_P(18, SI, TWI_SCL_M); +JR2_P(19, PCI_WAKE, NONE); +JR2_P(20, IRQ0_OUT, TWI_SCL_M); +JR2_P(21, IRQ1_OUT, TWI_SCL_M); +JR2_P(22, TACHO, NONE); +JR2_P(23, PWM, NONE); +JR2_P(24, UART2, NONE); +JR2_P(25, UART2, SI); +JR2_P(26, PTP2, SI); +JR2_P(27, PTP3, SI); +JR2_P(28, TWI2, SI); +JR2_P(29, TWI, SI); +JR2_P(30, SG2, SI); +JR2_P(31, SG2, SI); +JR2_P(32, SG2, SI); +JR2_P(33, SG2, SI); +JR2_P(34, NONE, TWI_SCL_M); +JR2_P(35, NONE, TWI_SCL_M); +JR2_P(36, NONE, TWI_SCL_M); +JR2_P(37, NONE, TWI_SCL_M); +JR2_P(38, NONE, TWI_SCL_M); +JR2_P(39, NONE, TWI_SCL_M); +JR2_P(40, NONE, TWI_SCL_M); +JR2_P(41, NONE, TWI_SCL_M); +JR2_P(42, NONE, TWI_SCL_M); +JR2_P(43, NONE, TWI_SCL_M); +JR2_P(44, NONE, SFP8); +JR2_P(45, NONE, SFP9); +JR2_P(46, NONE, SFP10); +JR2_P(47, NONE, SFP11); +JR2_P(48, SFP0, NONE); +JR2_P(49, SFP1, SI); +JR2_P(50, SFP2, SI); +JR2_P(51, SFP3, SI); +JR2_P(52, SFP4, NONE); +JR2_P(53, SFP5, NONE); +JR2_P(54, SFP6, NONE); +JR2_P(55, SFP7, NONE); +JR2_P(56, MIIM1, SFP12); +JR2_P(57, MIIM1, SFP13); +JR2_P(58, MIIM2, SFP14); +JR2_P(59, MIIM2, SFP15); +JR2_P(60, NONE, NONE); +JR2_P(61, NONE, NONE); +JR2_P(62, NONE, NONE); +JR2_P(63, NONE, NONE); + +#define JR2_PIN(n) { \ + .name = "GPIO_"#n, \ + .drv_data = &jr2_pin_##n \ +} + +static const struct mscc_pin_data jr2_pins[] = { + JR2_PIN(0), + JR2_PIN(1), + JR2_PIN(2), + JR2_PIN(3), + JR2_PIN(4), + JR2_PIN(5), + JR2_PIN(6), + JR2_PIN(7), + JR2_PIN(8), + JR2_PIN(9), + JR2_PIN(10), + JR2_PIN(11), + JR2_PIN(12), + JR2_PIN(13), + JR2_PIN(14), + JR2_PIN(15), + JR2_PIN(16), + JR2_PIN(17), + JR2_PIN(18), + JR2_PIN(19), + JR2_PIN(20), + JR2_PIN(21), + JR2_PIN(22), + JR2_PIN(23), + JR2_PIN(24), + JR2_PIN(25), + JR2_PIN(26), + JR2_PIN(27), + JR2_PIN(28), + JR2_PIN(29), + JR2_PIN(30), + JR2_PIN(31), + JR2_PIN(32), + JR2_PIN(33), + JR2_PIN(34), + JR2_PIN(35), + JR2_PIN(36), + JR2_PIN(37), + JR2_PIN(38), + JR2_PIN(39), + JR2_PIN(40), + JR2_PIN(41), + JR2_PIN(42), + JR2_PIN(43), + JR2_PIN(44), + JR2_PIN(45), + JR2_PIN(46), + JR2_PIN(47), + JR2_PIN(48), + JR2_PIN(49), + JR2_PIN(50), + JR2_PIN(51), + JR2_PIN(52), + JR2_PIN(53), + JR2_PIN(54), + JR2_PIN(55), + JR2_PIN(56), + JR2_PIN(57), + JR2_PIN(58), + JR2_PIN(59), + JR2_PIN(60), + JR2_PIN(61), + JR2_PIN(62), + JR2_PIN(63), +}; + +static const unsigned long jr2_gpios[] = { + [MSCC_GPIO_OUT_SET] = 0x00, + [MSCC_GPIO_OUT_CLR] = 0x08, + [MSCC_GPIO_OUT] = 0x10, + [MSCC_GPIO_IN] = 0x18, + [MSCC_GPIO_OE] = 0x20, + [MSCC_GPIO_INTR] = 0x28, + [MSCC_GPIO_INTR_ENA] = 0x30, + [MSCC_GPIO_INTR_IDENT] = 0x38, + [MSCC_GPIO_ALT0] = 0x40, + [MSCC_GPIO_ALT1] = 0x48, +}; + +static int jr2_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + uc_priv->bank_name = "jr2-gpio"; + uc_priv->gpio_count = ARRAY_SIZE(jr2_pins); + + return 0; +} + +static struct driver jr2_gpio_driver = { + .name = "jr2-gpio", + .id = UCLASS_GPIO, + .probe = jr2_gpio_probe, + .ops = &mscc_gpio_ops, +}; + +static int jr2_pinctrl_probe(struct udevice *dev) +{ + int ret; + + ret = mscc_pinctrl_probe(dev, FUNC_MAX, jr2_pins, + ARRAY_SIZE(jr2_pins), + jr2_function_names, + jr2_gpios); + + if (ret) + return ret; + + ret = device_bind(dev, &jr2_gpio_driver, "jr2-gpio", NULL, + dev_of_offset(dev), NULL); + + if (ret) + return ret; + + return 0; +} + +static const struct udevice_id jr2_pinctrl_of_match[] = { + { .compatible = "mscc,jaguar2-pinctrl" }, + {}, +}; + +U_BOOT_DRIVER(jr2_pinctrl) = { + .name = "jr2-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(jr2_pinctrl_of_match), + .probe = jr2_pinctrl_probe, + .priv_auto_alloc_size = sizeof(struct mscc_pinctrl), + .ops = &mscc_pinctrl_ops, +}; diff --git a/drivers/pinctrl/mscc/pinctrl-luton.c b/drivers/pinctrl/mscc/pinctrl-luton.c index 7166588..17fbc53 100644 --- a/drivers/pinctrl/mscc/pinctrl-luton.c +++ b/drivers/pinctrl/mscc/pinctrl-luton.c @@ -123,6 +123,19 @@ static const struct mscc_pin_data luton_pins[] = { LUTON_PIN(31), }; +static const unsigned long luton_gpios[] = { + [MSCC_GPIO_OUT_SET] = 0x00, + [MSCC_GPIO_OUT_CLR] = 0x04, + [MSCC_GPIO_OUT] = 0x08, + [MSCC_GPIO_IN] = 0x0c, + [MSCC_GPIO_OE] = 0x10, + [MSCC_GPIO_INTR] = 0x14, + [MSCC_GPIO_INTR_ENA] = 0x18, + [MSCC_GPIO_INTR_IDENT] = 0x1c, + [MSCC_GPIO_ALT0] = 0x20, + [MSCC_GPIO_ALT1] = 0x24, +}; + static int luton_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv; @@ -146,7 +159,8 @@ int luton_pinctrl_probe(struct udevice *dev) int ret; ret = mscc_pinctrl_probe(dev, FUNC_MAX, luton_pins, - ARRAY_SIZE(luton_pins), luton_function_names); + ARRAY_SIZE(luton_pins), luton_function_names, + luton_gpios); if (ret) return ret; diff --git a/drivers/pinctrl/mscc/pinctrl-ocelot.c b/drivers/pinctrl/mscc/pinctrl-ocelot.c index 10f9b90..49e026b 100644 --- a/drivers/pinctrl/mscc/pinctrl-ocelot.c +++ b/drivers/pinctrl/mscc/pinctrl-ocelot.c @@ -138,6 +138,19 @@ static const struct mscc_pin_data ocelot_pins[] = { OCELOT_PIN(21), }; +static const unsigned long ocelot_gpios[] = { + [MSCC_GPIO_OUT_SET] = 0x00, + [MSCC_GPIO_OUT_CLR] = 0x04, + [MSCC_GPIO_OUT] = 0x08, + [MSCC_GPIO_IN] = 0x0c, + [MSCC_GPIO_OE] = 0x10, + [MSCC_GPIO_INTR] = 0x14, + [MSCC_GPIO_INTR_ENA] = 0x18, + [MSCC_GPIO_INTR_IDENT] = 0x1c, + [MSCC_GPIO_ALT0] = 0x20, + [MSCC_GPIO_ALT1] = 0x24, +}; + static int ocelot_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv; @@ -162,7 +175,8 @@ int ocelot_pinctrl_probe(struct udevice *dev) ret = mscc_pinctrl_probe(dev, FUNC_MAX, ocelot_pins, ARRAY_SIZE(ocelot_pins), - ocelot_function_names); + ocelot_function_names, + ocelot_gpios); if (ret) return ret; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a7bb5b3..de4d62d 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -294,6 +294,13 @@ config SOFT_SPI Enable Soft SPI driver. This driver is to use GPIO simulate the SPI protocol. +config MSCC_BB_SPI + bool "MSCC bitbang SPI driver" + depends on SOC_VCOREIII + help + Enable MSCC bitbang SPI driver. This driver can be used on + MSCC SOCs. + config CF_SPI bool "ColdFire SPI driver" help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 392a925..4acec3e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o obj-$(CONFIG_MTK_QSPI) += mtk_qspi.o obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o +obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o obj-$(CONFIG_MXC_SPI) += mxc_spi.o obj-$(CONFIG_MXS_SPI) += mxs_spi.o diff --git a/drivers/spi/mscc_bb_spi.c b/drivers/spi/mscc_bb_spi.c new file mode 100644 index 0000000..c3c7b80 --- /dev/null +++ b/drivers/spi/mscc_bb_spi.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Microsemi SoCs spi driver + * + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <malloc.h> +#include <spi.h> +#include <dm.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <linux/delay.h> + +struct mscc_bb_priv { + void __iomem *regs; + u32 deactivate_delay_us; + bool cs_active; /* State flag as to whether CS is asserted */ + int cs_num; + u32 svalue; /* Value to start transfer with */ + u32 clk1; /* Clock value start */ + u32 clk2; /* Clock value 2nd phase */ +}; + +/* Delay 24 instructions for this particular application */ +#define hold_time_delay() mscc_vcoreiii_nop_delay(3) + +static int mscc_bb_spi_cs_activate(struct mscc_bb_priv *priv, int mode, int cs) +{ + if (!priv->cs_active) { + int cpha = mode & SPI_CPHA; + u32 cs_value; + + priv->cs_num = cs; + + if (cpha) { + /* Initial clock starts SCK=1 */ + priv->clk1 = ICPU_SW_MODE_SW_SPI_SCK; + priv->clk2 = 0; + } else { + /* Initial clock starts SCK=0 */ + priv->clk1 = 0; + priv->clk2 = ICPU_SW_MODE_SW_SPI_SCK; + } + + /* Enable bitbang, SCK_OE, SDO_OE */ + priv->svalue = (ICPU_SW_MODE_SW_PIN_CTRL_MODE | /* Bitbang */ + ICPU_SW_MODE_SW_SPI_SCK_OE | /* SCK_OE */ + ICPU_SW_MODE_SW_SPI_SDO_OE); /* SDO OE */ + + /* Add CS */ + if (cs >= 0) { + cs_value = + ICPU_SW_MODE_SW_SPI_CS_OE(BIT(cs)) | + ICPU_SW_MODE_SW_SPI_CS(BIT(cs)); + } else { + cs_value = 0; + } + + priv->svalue |= cs_value; + + /* Enable the CS in HW, Initial clock value */ + writel(priv->svalue | priv->clk2, priv->regs); + + priv->cs_active = true; + debug("Activated CS%d\n", priv->cs_num); + } + + return 0; +} + +static int mscc_bb_spi_cs_deactivate(struct mscc_bb_priv *priv, int deact_delay) +{ + if (priv->cs_active) { + /* Keep driving the CLK to its current value while + * actively deselecting CS. + */ + u32 value = readl(priv->regs); + + value &= ~ICPU_SW_MODE_SW_SPI_CS_M; + writel(value, priv->regs); + hold_time_delay(); + + /* Stop driving the clock, but keep CS with nCS == 1 */ + value &= ~ICPU_SW_MODE_SW_SPI_SCK_OE; + writel(value, priv->regs); + + /* Deselect hold time delay */ + if (deact_delay) + udelay(deact_delay); + + /* Drop everything */ + writel(0, priv->regs); + + priv->cs_active = false; + debug("Deactivated CS%d\n", priv->cs_num); + } + + return 0; +} + +int mscc_bb_spi_claim_bus(struct udevice *dev) +{ + return 0; +} + +int mscc_bb_spi_release_bus(struct udevice *dev) +{ + return 0; +} + +int mscc_bb_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct udevice *bus = dev_get_parent(dev); + struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev); + struct mscc_bb_priv *priv = dev_get_priv(bus); + u32 i, count; + const u8 *txd = dout; + u8 *rxd = din; + + debug("spi_xfer: slave %s:%s cs%d mode %d, dout %p din %p bitlen %u\n", + dev->parent->name, dev->name, plat->cs, plat->mode, dout, + din, bitlen); + + if (flags & SPI_XFER_BEGIN) + mscc_bb_spi_cs_activate(priv, plat->mode, plat->cs); + + count = bitlen / 8; + for (i = 0; i < count; i++) { + u32 rx = 0, mask = 0x80, value; + + while (mask) { + /* Initial condition: CLK is low. */ + value = priv->svalue; + if (txd && txd[i] & mask) + value |= ICPU_SW_MODE_SW_SPI_SDO; + + /* Drive data while taking CLK low. The device + * we're accessing will sample on the + * following rising edge and will output data + * on this edge for us to be sampled at the + * end of this loop. + */ + writel(value | priv->clk1, priv->regs); + + /* Wait for t_setup. All devices do have a + * setup-time, so we always insert some delay + * here. Some devices have a very long + * setup-time, which can be adjusted by the + * user through vcoreiii_device->delay. + */ + hold_time_delay(); + + /* Drive the clock high. */ + writel(value | priv->clk2, priv->regs); + + /* Wait for t_hold. See comment about t_setup + * above. + */ + hold_time_delay(); + + /* We sample as close to the next falling edge + * as possible. + */ + value = readl(priv->regs); + if (value & ICPU_SW_MODE_SW_SPI_SDI) + rx |= mask; + mask >>= 1; + } + if (rxd) { + debug("Read 0x%02x\n", rx); + rxd[i] = (u8)rx; + } + debug("spi_xfer: byte %d/%d\n", i + 1, count); + } + + debug("spi_xfer: done\n"); + + if (flags & SPI_XFER_END) + mscc_bb_spi_cs_deactivate(priv, priv->deactivate_delay_us); + + return 0; +} + +int mscc_bb_spi_set_speed(struct udevice *dev, unsigned int speed) +{ + /* Accept any speed */ + return 0; +} + +int mscc_bb_spi_set_mode(struct udevice *dev, unsigned int mode) +{ + return 0; +} + +static const struct dm_spi_ops mscc_bb_ops = { + .claim_bus = mscc_bb_spi_claim_bus, + .release_bus = mscc_bb_spi_release_bus, + .xfer = mscc_bb_spi_xfer, + .set_speed = mscc_bb_spi_set_speed, + .set_mode = mscc_bb_spi_set_mode, +}; + +static const struct udevice_id mscc_bb_ids[] = { + { .compatible = "mscc,luton-bb-spi" }, + { } +}; + +static int mscc_bb_spi_probe(struct udevice *bus) +{ + struct mscc_bb_priv *priv = dev_get_priv(bus); + + debug("%s: loaded, priv %p\n", __func__, priv); + + priv->regs = (void __iomem *)dev_read_addr(bus); + + priv->deactivate_delay_us = + dev_read_u32_default(bus, "spi-deactivate-delay", 0); + + priv->cs_active = false; + + return 0; +} + +U_BOOT_DRIVER(mscc_bb) = { + .name = "mscc_bb", + .id = UCLASS_SPI, + .of_match = mscc_bb_ids, + .ops = &mscc_bb_ops, + .priv_auto_alloc_size = sizeof(struct mscc_bb_priv), + .probe = mscc_bb_spi_probe, +}; diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h index df89cda..4ea5f40 100644 --- a/include/configs/vcoreiii.h +++ b/include/configs/vcoreiii.h @@ -22,6 +22,8 @@ #endif #define CONFIG_SYS_NS16550_CLK CONFIG_SYS_MIPS_TIMER_FREQ +#define CONFIG_BOARD_TYPES + #if defined(CONFIG_ENV_IS_IN_SPI_FLASH) && !defined(CONFIG_ENV_OFFSET) #define CONFIG_ENV_OFFSET (1024 * 1024) #define CONFIG_ENV_SIZE (256 * 1024) |