From: Tom Rini Date: Sat, 29 Jul 2017 15:44:08 +0000 (-0400) Subject: Merge git://git.denx.de/u-boot-socfpga X-Git-Tag: v2017.09-rc1~31 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=19d1f1a2f3ccfbf85125150f7876ce22714b38bd;hp=9af91b7c4041a455de5f3e3da4e36644768bff68;p=platform%2Fkernel%2Fu-boot.git Merge git://git.denx.de/u-boot-socfpga --- diff --git a/Documentation/devicetree/bindings/phy/no-op.txt b/Documentation/devicetree/bindings/phy/no-op.txt new file mode 100644 index 0000000..a338112 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/no-op.txt @@ -0,0 +1,16 @@ +NOP PHY driver + +This driver is used to stub PHY operations in a driver (USB, SATA). +This is useful when the 'client' driver (USB, SATA, ...) uses the PHY framework +and there is no actual PHY harwdare to drive. + +Required properties: +- compatible : must contain "nop-phy" +- #phy-cells : must contain <0> + +Example: + +nop_phy { + compatible = "nop-phy"; + #phy-cells = <0>; +}; diff --git a/Kconfig b/Kconfig index bb80ada..c1451bc 100644 --- a/Kconfig +++ b/Kconfig @@ -95,6 +95,16 @@ config SYS_MALLOC_F_LEN particular needs this to operate, so that it can allocate the initial serial device and any others that are needed. +config SPL_SYS_MALLOC_F_LEN + hex "Size of malloc() pool in spl before relocation" + depends on SYS_MALLOC_F + default SYS_MALLOC_F_LEN + help + Before relocation, memory is very limited on many platforms. Still, + we can provide a small malloc() pool if needed. Driver model in + particular needs this to operate, so that it can allocate the + initial serial device and any others that are needed. + menuconfig EXPERT bool "Configure standard U-Boot features (expert users)" default y diff --git a/MAINTAINERS b/MAINTAINERS index 9fd9116..f7e6abd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -452,6 +452,7 @@ F: drivers/video/ X86 M: Simon Glass +M: Bin Meng S: Maintained T: git git://git.denx.de/u-boot-x86.git F: arch/x86/ diff --git a/Makefile b/Makefile index a1a3aea..3d2b66a 100644 --- a/Makefile +++ b/Makefile @@ -1232,13 +1232,16 @@ u-boot.elf: u-boot.bin $(Q)$(OBJCOPY) -I binary $(PLATFORM_ELFFLAGS) $< u-boot-elf.o $(call if_changed,u-boot-elf) +ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) + # Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk quiet_cmd_u-boot__ ?= LD $@ cmd_u-boot__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ -T u-boot.lds $(u-boot-init) \ --start-group $(u-boot-main) --end-group \ - $(PLATFORM_LIBS) -Map u-boot.map + $(PLATFORM_LIBS) -Map u-boot.map; \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) quiet_cmd_smap = GEN common/system_map.o cmd_smap = \ @@ -1248,7 +1251,7 @@ cmd_smap = \ -c $(srctree)/common/system_map.c -o common/system_map.o u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE - $(call if_changed,u-boot__) + +$(call if_changed,u-boot__) ifeq ($(CONFIG_KALLSYMS),y) $(call cmd,smap) $(call cmd,u-boot__) common/system_map.o diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi index c129100..436b875 100644 --- a/arch/arm/dts/meson-gx.dtsi +++ b/arch/arm/dts/meson-gx.dtsi @@ -71,6 +71,14 @@ reg = <0x0 0x10000000 0x0 0x200000>; no-map; }; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0xbc00000>; + alignment = <0x0 0x400000>; + linux,cma-default; + }; }; cpus { @@ -233,7 +241,7 @@ }; i2c_A: i2c@8500 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x08500 0x0 0x20>; interrupts = ; #address-cells = <1>; @@ -255,6 +263,14 @@ status = "disabled"; }; + saradc: adc@8680 { + compatible = "amlogic,meson-saradc"; + reg = <0x0 0x8680 0x0 0x34>; + #io-channel-cells = <1>; + interrupts = ; + status = "disabled"; + }; + pwm_ef: pwm@86c0 { compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm"; reg = <0x0 0x086c0 0x0 0x10>; @@ -271,7 +287,7 @@ }; i2c_B: i2c@87c0 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x087c0 0x0 0x20>; interrupts = ; #address-cells = <1>; @@ -280,7 +296,7 @@ }; i2c_C: i2c@87e0 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x087e0 0x0 0x20>; interrupts = ; #address-cells = <1>; @@ -288,6 +304,14 @@ status = "disabled"; }; + spifc: spi@8c80 { + compatible = "amlogic,meson-gx-spifc", "amlogic,meson-gxbb-spifc"; + reg = <0x0 0x08c80 0x0 0x80>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + watchdog@98d0 { compatible = "amlogic,meson-gx-wdt", "amlogic,meson-gxbb-wdt"; reg = <0x0 0x098d0 0x0 0x10>; @@ -309,7 +333,7 @@ }; sram: sram@c8000000 { - compatible = "amlogic,meson-gxbb-sram", "mmio-sram"; + compatible = "amlogic,meson-gx-sram", "amlogic,meson-gxbb-sram", "mmio-sram"; reg = <0x0 0xc8000000 0x0 0x14000>; #address-cells = <1>; @@ -317,12 +341,12 @@ ranges = <0 0x0 0xc8000000 0x14000>; cpu_scp_lpri: scp-shmem@0 { - compatible = "amlogic,meson-gxbb-scp-shmem"; + compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; reg = <0x13000 0x400>; }; cpu_scp_hpri: scp-shmem@200 { - compatible = "amlogic,meson-gxbb-scp-shmem"; + compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; reg = <0x13400 0x400>; }; }; @@ -334,6 +358,13 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>; + clkc_AO: clock-controller@040 { + compatible = "amlogic,gx-aoclkc", "amlogic,gxbb-aoclkc"; + reg = <0x0 0x00040 0x0 0x4>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + uart_AO: serial@4c0 { compatible = "amlogic,meson-uart"; reg = <0x0 0x004c0 0x0 0x14>; @@ -350,8 +381,24 @@ status = "disabled"; }; + i2c_AO: i2c@500 { + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; + reg = <0x0 0x500 0x0 0x20>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm_AO_ab: pwm@550 { + compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm"; + reg = <0x0 0x00550 0x0 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + ir: ir@580 { - compatible = "amlogic,meson-gxbb-ir"; + compatible = "amlogic,meson-gx-ir", "amlogic,meson-gxbb-ir"; reg = <0x0 0x00580 0x0 0x40>; interrupts = ; status = "disabled"; @@ -365,13 +412,12 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>; - rng { + hwrng: rng { compatible = "amlogic,meson-rng"; reg = <0x0 0x0 0x0 0x4>; }; }; - hiubus: hiubus@c883c000 { compatible = "simple-bus"; reg = <0x0 0xc883c000 0x0 0x2000>; @@ -395,7 +441,6 @@ 0x0 0xc8834540 0x0 0x4>; interrupts = <0 8 1>; interrupt-names = "macirq"; - phy-mode = "rgmii"; status = "disabled"; }; @@ -442,6 +487,38 @@ cvbs_vdac_port: port@0 { reg = <0>; }; + + /* HDMI-TX output port */ + hdmi_tx_port: port@1 { + reg = <1>; + + hdmi_tx_out: endpoint { + remote-endpoint = <&hdmi_tx_in>; + }; + }; + }; + + hdmi_tx: hdmi-tx@c883a000 { + compatible = "amlogic,meson-gx-dw-hdmi"; + reg = <0x0 0xc883a000 0x0 0x1c>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + /* VPU VENC Input */ + hdmi_tx_venc_port: port@0 { + reg = <0>; + + hdmi_tx_in: endpoint { + remote-endpoint = <&hdmi_tx_out>; + }; + }; + + /* TMDS Output */ + hdmi_tx_tmds_port: port@1 { + reg = <1>; + }; }; }; }; diff --git a/arch/arm/dts/meson-gxbb-odroidc2.dts b/arch/arm/dts/meson-gxbb-odroidc2.dts index c737183..54a9c6a 100644 --- a/arch/arm/dts/meson-gxbb-odroidc2.dts +++ b/arch/arm/dts/meson-gxbb-odroidc2.dts @@ -50,7 +50,7 @@ / { compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; model = "Hardkernel ODROID-C2"; - + aliases { serial0 = &uart_AO; }; @@ -96,7 +96,7 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - gpio = <&gpio_ao GPIOAO_12 GPIO_ACTIVE_HIGH>; + gpio = <&gpio GPIOY_12 GPIO_ACTIVE_HIGH>; enable-active-high; }; @@ -152,6 +152,13 @@ pinctrl-0 = <ð_rgmii_pins>; pinctrl-names = "default"; phy-handle = <ð_phy0>; + phy-mode = "rgmii"; + + snps,reset-gpio = <&gpio GPIOZ_14 0>; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-active-low; + + amlogic,tx-delay-ns = <2>; mdio { compatible = "snps,dwmac-mdio"; @@ -165,6 +172,57 @@ }; }; +&pinctrl_aobus { + gpio-line-names = "UART TX", "UART RX", "VCCK En", "TF 3V3/1V8 En", + "USB HUB nRESET", "USB OTG Power En", + "J7 Header Pin2", "IR In", "J7 Header Pin4", + "J7 Header Pin6", "J7 Header Pin5", "J7 Header Pin7", + "HDMI CEC", "SYS LED"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "Eth MDIO", "Eth MDC", "Eth RGMII RX Clk", + "Eth RX DV", "Eth RX D0", "Eth RX D1", "Eth RX D2", + "Eth RX D3", "Eth RGMII TX Clk", "Eth TX En", + "Eth TX D0", "Eth TX D1", "Eth TX D2", "Eth TX D3", + "Eth PHY nRESET", "Eth PHY Intc", + /* Bank GPIOH */ + "HDMI HPD", "HDMI DDC SDA", "HDMI DDC SCL", "", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", "eMMC D4", + "eMMC D5", "eMMC D6", "eMMC D7", "eMMC Clk", + "eMMC Reset", "eMMC CMD", + "", "", "", "", "", "", "", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", + "I2C A SDA", "I2C A SCK", "I2C B SDA", "I2C B SCK", + "PWM D", "PWM B", + /* Bank GPIOY */ + "Revision Bit0", "Revision Bit1", "", + "J2 Header Pin35", "", "", "", "J2 Header Pin36", + "J2 Header Pin31", "", "", "", "TF VDD En", + "J2 Header Pin32", "J2 Header Pin26", "", "", + /* Bank GPIOX */ + "J2 Header Pin29", "J2 Header Pin24", + "J2 Header Pin23", "J2 Header Pin22", + "J2 Header Pin21", "J2 Header Pin18", + "J2 Header Pin33", "J2 Header Pin19", + "J2 Header Pin16", "J2 Header Pin15", + "J2 Header Pin12", "J2 Header Pin13", + "J2 Header Pin8", "J2 Header Pin10", + "", "", "", "", "", + "J2 Header Pin11", "", "J2 Header Pin7", + /* Bank GPIOCLK */ + "", "", "", "", + /* GPIO_TEST_N */ + ""; +}; + &ir { status = "okay"; pinctrl-0 = <&remote_input_ao_pins>; @@ -177,6 +235,21 @@ pinctrl-names = "default"; }; +&gpio_ao { + /* + * WARNING: The USB Hub on the Odroid-C2 needs a reset signal + * to be turned high in order to be detected by the USB Controller + * This signal should be handled by a USB specific power sequence + * in order to reset the Hub when USB bus is powered down. + */ + usb-hub { + gpio-hog; + gpios = ; + output-high; + line-name = "usb-hub-reset"; + }; +}; + &usb0_phy { status = "okay"; phy-supply = <&usb_otg_pwr>; @@ -194,6 +267,11 @@ status = "okay"; }; +&saradc { + status = "okay"; + vref-supply = <&vcc1v8>; +}; + /* SD */ &sd_emmc_b { status = "okay"; diff --git a/arch/arm/dts/meson-gxbb.dtsi b/arch/arm/dts/meson-gxbb.dtsi index 39a774a..86105a6 100644 --- a/arch/arm/dts/meson-gxbb.dtsi +++ b/arch/arm/dts/meson-gxbb.dtsi @@ -97,17 +97,6 @@ }; }; -&cbus { - spifc: spi@8c80 { - compatible = "amlogic,meson-gxbb-spifc"; - reg = <0x0 0x08c80 0x0 0x80>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_SPI>; - status = "disabled"; - }; -}; - ðmac { clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, @@ -129,6 +118,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 0 14>; }; uart_ao_a_pins: uart_ao_a { @@ -203,30 +193,62 @@ function = "pwm_ao_b"; }; }; - }; - clkc_AO: clock-controller@040 { - compatible = "amlogic,gxbb-aoclkc"; - reg = <0x0 0x00040 0x0 0x4>; - #clock-cells = <1>; - #reset-cells = <1>; - }; + i2s_am_clk_pins: i2s_am_clk { + mux { + groups = "i2s_am_clk"; + function = "i2s_out_ao"; + }; + }; - pwm_ab_AO: pwm@550 { - compatible = "amlogic,meson-gxbb-pwm"; - reg = <0x0 0x0550 0x0 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; + i2s_out_ao_clk_pins: i2s_out_ao_clk { + mux { + groups = "i2s_out_ao_clk"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_lr_clk_pins: i2s_out_lr_clk { + mux { + groups = "i2s_out_lr_clk"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch01_ao_pins: i2s_out_ch01_ao { + mux { + groups = "i2s_out_ch01_ao"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch23_ao_pins: i2s_out_ch23_ao { + mux { + groups = "i2s_out_ch23_ao"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch45_ao_pins: i2s_out_ch45_ao { + mux { + groups = "i2s_out_ch45_ao"; + function = "i2s_out_ao"; + }; + }; + + spdif_out_ao_6_pins: spdif_out_ao_6 { + mux { + groups = "spdif_out_ao_6"; + function = "spdif_out_ao"; + }; + }; - i2c_AO: i2c@500 { - compatible = "amlogic,meson-gxbb-i2c"; - reg = <0x0 0x500 0x0 0x20>; - interrupts = ; - clocks = <&clkc CLKID_AO_I2C>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; + spdif_out_ao_13_pins: spdif_out_ao_13 { + mux { + groups = "spdif_out_ao_13"; + function = "spdif_out_ao"; + }; + }; }; }; @@ -245,6 +267,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_periphs 0 14 120>; }; emmc_pins: emmc { @@ -467,6 +490,34 @@ function = "hdmi_i2c"; }; }; + + i2sout_ch23_y_pins: i2sout_ch23_y { + mux { + groups = "i2sout_ch23_y"; + function = "i2s_out"; + }; + }; + + i2sout_ch45_y_pins: i2sout_ch45_y { + mux { + groups = "i2sout_ch45_y"; + function = "i2s_out"; + }; + }; + + i2sout_ch67_y_pins: i2sout_ch67_y { + mux { + groups = "i2sout_ch67_y"; + function = "i2s_out"; + }; + }; + + spdif_out_y_pins: spdif_out_y { + mux { + groups = "spdif_out_y"; + function = "spdif_out"; + }; + }; }; }; @@ -478,10 +529,51 @@ }; }; +&apb { + mali: gpu@c0000 { + compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; + reg = <0x0 0xc0000 0x0 0x40000>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "gp", "gpmmu", "pp", "pmu", + "pp0", "ppmmu0", "pp1", "ppmmu1", + "pp2", "ppmmu2"; + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; + clock-names = "bus", "core"; + + /* + * Mali clocking is provided by two identical clock paths + * MALI_0 and MALI_1 muxed to a single clock by a glitch + * free mux to safely change frequency while running. + */ + assigned-clocks = <&clkc CLKID_MALI_0_SEL>, + <&clkc CLKID_MALI_0>, + <&clkc CLKID_MALI>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, + <0>, /* Do Nothing */ + <&clkc CLKID_MALI_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <666666666>, + <0>; /* Do Nothing */ + }; +}; + &i2c_A { clocks = <&clkc CLKID_I2C>; }; +&i2c_AO { + clocks = <&clkc CLKID_AO_I2C>; +}; + &i2c_B { clocks = <&clkc CLKID_I2C>; }; @@ -490,6 +582,16 @@ clocks = <&clkc CLKID_I2C>; }; +&saradc { + compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, + <&clkc CLKID_SAR_ADC>, + <&clkc CLKID_SANA>, + <&clkc CLKID_SAR_ADC_CLK>, + <&clkc CLKID_SAR_ADC_SEL>; + clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; +}; + &sd_emmc_a { clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, @@ -511,6 +613,27 @@ clock-names = "core", "clkin0", "clkin1"; }; +&spifc { + clocks = <&clkc CLKID_SPI>; +}; + &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; }; + +&hwrng { + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + +&hdmi_tx { + compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, + <&reset RESET_HDMI_SYSTEM_RESET>, + <&reset RESET_HDMI_TX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; + clocks = <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; +}; diff --git a/arch/arm/dts/rk3036-sdk-u-boot.dtsi b/arch/arm/dts/rk3036-sdk-u-boot.dtsi new file mode 100644 index 0000000..6f15f4a --- /dev/null +++ b/arch/arm/dts/rk3036-sdk-u-boot.dtsi @@ -0,0 +1,11 @@ +&uart2 { + u-boot,dm-pre-reloc; +}; + +&grf { + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/rk3229-evb.dts b/arch/arm/dts/rk3229-evb.dts index ccdac1c..37137c2 100644 --- a/arch/arm/dts/rk3229-evb.dts +++ b/arch/arm/dts/rk3229-evb.dts @@ -75,3 +75,7 @@ &uart2 { status = "okay"; }; + +&usb20_otg { + status = "okay"; +}; diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi index 7237da4..4f2a1f6 100644 --- a/arch/arm/dts/rk322x.dtsi +++ b/arch/arm/dts/rk322x.dtsi @@ -403,6 +403,16 @@ status = "disabled"; }; + usb20_otg: usb@30040000 { + compatible = "rockchip,rk3229-usb", "rockchip,rk3288-usb", + "snps,dwc2"; + reg = <0x30040000 0x40000>; + interrupts = ; + hnp-srp-disable; + dr_mode = "otg"; + status = "disabled"; + }; + gmac: ethernet@30200000 { compatible = "rockchip,rk3228-gmac"; reg = <0x30200000 0x10000>; diff --git a/arch/arm/dts/rk3288-phycore-som.dtsi b/arch/arm/dts/rk3288-phycore-som.dtsi index fd463f4..02d1196 100644 --- a/arch/arm/dts/rk3288-phycore-som.dtsi +++ b/arch/arm/dts/rk3288-phycore-som.dtsi @@ -61,6 +61,7 @@ aliases { rtc0 = &i2c_rtc; rtc1 = &rk818; + eeprom0 = &i2c_eeprom_id; }; ext_gmac: external-gmac-clock { @@ -383,6 +384,13 @@ pagesize = <32>; }; + /* M24C32-D Identification page */ + i2c_eeprom_id: eeprom@58 { + compatible = "atmel,24c32"; + reg = <0x58>; + pagesize = <32>; + }; + vdd_cpu: regulator@60 { compatible = "fcs,fan53555"; reg = <0x60>; diff --git a/arch/arm/dts/rk3399-firefly.dts b/arch/arm/dts/rk3399-firefly.dts index 91d3193..3d3f507 100644 --- a/arch/arm/dts/rk3399-firefly.dts +++ b/arch/arm/dts/rk3399-firefly.dts @@ -8,7 +8,7 @@ #include #include #include "rk3399.dtsi" -#include "rk3399-sdram-ddr3-1333.dtsi" +#include "rk3399-sdram-ddr3-1600.dtsi" / { model = "Firefly-RK3399 Board"; @@ -157,8 +157,9 @@ regulator-name = "vdd_log"; regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <800000>; + regulator-min-microvolt = <430000>; regulator-max-microvolt = <1400000>; + regulator-init-microvolt = <950000>; }; vccadc_ref: vccadc-ref { diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi index 1aad6c5..dd1baea 100644 --- a/arch/arm/dts/rk3399-puma.dtsi +++ b/arch/arm/dts/rk3399-puma.dtsi @@ -12,7 +12,9 @@ compatible = "tsd,rk3399-q7", "tsd,puma", "rockchip,rk3399"; config { - u-boot,spl-payload-offset = <0x40000>; /* 256kbyte */ + u-boot,spl-payload-offset = <0x40000>; /* @ 256KB */ + u-boot,mmc-env-offset = <0x4000>; /* @ 16KB */ + u-boot,efi-partition-entries-offset = <0x200000>; /* 2MB */ u-boot,boot-led = "module_led"; }; diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts index 2c7fa79..c92c2e2 100644 --- a/arch/arm/dts/stm32f746-disco.dts +++ b/arch/arm/dts/stm32f746-disco.dts @@ -195,7 +195,6 @@ pinctrl-names = "default"; status = "okay"; - mr-nbanks = <1>; /* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */ bank1: bank@0 { st,sdram-control = /bits/ 8 +#include +#include / { clocks { @@ -74,7 +76,7 @@ fmc: fmc@A0000000 { compatible = "st,stm32-fmc"; reg = <0xA0000000 0x1000>; - clocks = <&rcc 0 64>; + clocks = <&rcc 0 STM32F7_AHB3_CLOCK(FMC)>; u-boot,dm-pre-reloc; }; @@ -86,14 +88,14 @@ reg-names = "QuadSPI", "QuadSPI-memory"; interrupts = <92>; spi-max-frequency = <108000000>; - clocks = <&rcc 0 65>; + clocks = <&rcc 0 STM32F7_AHB3_CLOCK(QSPI)>; status = "disabled"; }; usart1: serial@40011000 { compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40011000 0x400>; interrupts = <37>; - clocks = <&rcc 0 164>; + clocks = <&rcc 0 STM32F7_APB2_CLOCK(USART1)>; status = "disabled"; u-boot,dm-pre-reloc; }; @@ -119,7 +121,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x0 0x400>; - clocks = <&rcc 0 0>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>; st,bank-name = "GPIOA"; u-boot,dm-pre-reloc; }; @@ -129,7 +131,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x400 0x400>; - clocks = <&rcc 0 1>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>; st,bank-name = "GPIOB"; u-boot,dm-pre-reloc; }; @@ -140,7 +142,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x800 0x400>; - clocks = <&rcc 0 2>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>; st,bank-name = "GPIOC"; u-boot,dm-pre-reloc; }; @@ -150,7 +152,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0xc00 0x400>; - clocks = <&rcc 0 3>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>; st,bank-name = "GPIOD"; u-boot,dm-pre-reloc; }; @@ -160,7 +162,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1000 0x400>; - clocks = <&rcc 0 4>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>; st,bank-name = "GPIOE"; u-boot,dm-pre-reloc; }; @@ -170,7 +172,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1400 0x400>; - clocks = <&rcc 0 5>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>; st,bank-name = "GPIOF"; u-boot,dm-pre-reloc; }; @@ -180,7 +182,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1800 0x400>; - clocks = <&rcc 0 6>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>; st,bank-name = "GPIOG"; u-boot,dm-pre-reloc; }; @@ -190,7 +192,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1c00 0x400>; - clocks = <&rcc 0 7>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>; st,bank-name = "GPIOH"; u-boot,dm-pre-reloc; }; @@ -200,7 +202,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x2000 0x400>; - clocks = <&rcc 0 8>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>; st,bank-name = "GPIOI"; u-boot,dm-pre-reloc; }; @@ -210,7 +212,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x2400 0x400>; - clocks = <&rcc 0 9>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>; st,bank-name = "GPIOJ"; u-boot,dm-pre-reloc; }; @@ -220,7 +222,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x2800 0x400>; - clocks = <&rcc 0 10>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>; st,bank-name = "GPIOK"; u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f769-disco.dts b/arch/arm/dts/stm32f769-disco.dts index 6591cc8..f34ffcc 100644 --- a/arch/arm/dts/stm32f769-disco.dts +++ b/arch/arm/dts/stm32f769-disco.dts @@ -209,7 +209,6 @@ pinctrl-names = "default"; status = "okay"; - mr-nbanks = <1>; /* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */ bank1: bank@0 { st,sdram-control = /bits/ 8 ; #size-cells = <1>; ranges = <0 0 0 0xffffffff>; - u-boot,dm-pre-reloc; serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; @@ -343,11 +342,9 @@ compatible = "socionext,uniphier-ld11-soc-glue", "simple-mfd", "syscon"; reg = <0x5f800000 0x2000>; - u-boot,dm-pre-reloc; pinctrl: pinctrl { compatible = "socionext,uniphier-ld11-pinctrl"; - u-boot,dm-pre-reloc; }; }; diff --git a/arch/arm/dts/uniphier-ld20-global.dts b/arch/arm/dts/uniphier-ld20-global.dts index 535c0ee..9f620d4 100644 --- a/arch/arm/dts/uniphier-ld20-global.dts +++ b/arch/arm/dts/uniphier-ld20-global.dts @@ -50,12 +50,3 @@ &i2c0 { status = "okay"; }; - -/* for U-Boot only */ -&serial0 { - u-boot,dm-pre-reloc; -}; - -&pinctrl_uart0 { - u-boot,dm-pre-reloc; -}; diff --git a/arch/arm/dts/uniphier-ld20-ref.dts b/arch/arm/dts/uniphier-ld20-ref.dts index 2bcab96..494166a 100644 --- a/arch/arm/dts/uniphier-ld20-ref.dts +++ b/arch/arm/dts/uniphier-ld20-ref.dts @@ -50,12 +50,3 @@ &i2c0 { status = "okay"; }; - -/* for U-Boot only */ -&serial0 { - u-boot,dm-pre-reloc; -}; - -&pinctrl_uart0 { - u-boot,dm-pre-reloc; -}; diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi index ab031f2..927340f 100644 --- a/arch/arm/dts/uniphier-ld20.dtsi +++ b/arch/arm/dts/uniphier-ld20.dtsi @@ -178,7 +178,6 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0 0 0 0xffffffff>; - u-boot,dm-pre-reloc; serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; @@ -378,11 +377,9 @@ compatible = "socionext,uniphier-ld20-soc-glue", "simple-mfd", "syscon"; reg = <0x5f800000 0x2000>; - u-boot,dm-pre-reloc; pinctrl: pinctrl { compatible = "socionext,uniphier-ld20-pinctrl"; - u-boot,dm-pre-reloc; }; }; diff --git a/arch/arm/include/asm/arch-meson/gpio.h b/arch/arm/include/asm/arch-meson/gpio.h new file mode 100644 index 0000000..7079ab3 --- /dev/null +++ b/arch/arm/include/asm/arch-meson/gpio.h @@ -0,0 +1,11 @@ +/* + * (C) Copyright 2017 - Beniamino Galvani + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_MESON_GPIO_H +#define __ASM_ARCH_MESON_GPIO_H + + +#endif /* __ASM_ARCH_MESON_GPIO_H */ diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index 7346876..72d264b 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -1,3 +1,4 @@ + /* * Copyright 2017 Theobroma Systems Design und Consulting GmbH * @@ -13,7 +14,17 @@ */ #ifdef CONFIG_SPL_BUILD - .space 0x4 /* space for the 'RK33' */ + /* + * We need to add 4 bytes of space for the 'RK33' at the + * beginning of the executable. However, as we want to keep + * this generic and make it applicable to builds that are like + * the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no + * TPL, but extra space needed in the SPL), we simply repeat + * the 'b reset' with the expectation that the first one will + * be overwritten, if this is the first stage contained in the + * final image created with mkimage)... + */ + b reset /* may be overwritten --- should be 'nop' or a 'b reset' */ #endif b reset diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3368.h b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h index 4910ee7..24a9cc0 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3368.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3368.h @@ -51,8 +51,6 @@ check_member(rk3368_cru, emmc_con[1], 0x41c); struct rk3368_clk_priv { struct rk3368_cru *cru; - ulong rate; - bool has_bwadj; }; enum { diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h index cf830d0..033f067 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h @@ -12,12 +12,10 @@ /* Private data for the clock driver - used by rockchip_get_cru() */ struct rk3399_clk_priv { struct rk3399_cru *cru; - ulong rate; }; struct rk3399_pmuclk_priv { struct rk3399_pmucru *pmucru; - ulong rate; }; struct rk3399_pmucru { diff --git a/arch/arm/include/asm/arch-rockchip/pwm.h b/arch/arm/include/asm/arch-rockchip/pwm.h index 08ff945..b1d8047 100644 --- a/arch/arm/include/asm/arch-rockchip/pwm.h +++ b/arch/arm/include/asm/arch-rockchip/pwm.h @@ -25,9 +25,11 @@ check_member(rk3288_pwm, ctrl, 0xc); #define PWM_DUTY_POSTIVE (1 << 3) #define PWM_DUTY_NEGATIVE (0 << 3) +#define PWM_DUTY_MASK (1 << 3) #define PWM_INACTIVE_POSTIVE (1 << 4) #define PWM_INACTIVE_NEGATIVE (0 << 4) +#define PWM_INACTIVE_MASK (1 << 4) #define PWM_OUTPUT_LEFT (0 << 5) #define PWM_OUTPUT_CENTER (1 << 5) diff --git a/arch/arm/include/asm/arch-rockchip/timer.h b/arch/arm/include/asm/arch-rockchip/timer.h index 1d044bb..c23c509 100644 --- a/arch/arm/include/asm/arch-rockchip/timer.h +++ b/arch/arm/include/asm/arch-rockchip/timer.h @@ -8,12 +8,12 @@ #define __ASM_ARCH_TIMER_H struct rk_timer { - unsigned int timer_load_count0; - unsigned int timer_load_count1; - unsigned int timer_curr_value0; - unsigned int timer_curr_value1; - unsigned int timer_ctrl_reg; - unsigned int timer_int_status; + u32 timer_load_count0; + u32 timer_load_count1; + u32 timer_curr_value0; + u32 timer_curr_value1; + u32 timer_ctrl_reg; + u32 timer_int_status; }; void rockchip_timer_init(void); diff --git a/arch/arm/include/asm/arch-stm32f7/fmc.h b/arch/arm/include/asm/arch-stm32f7/fmc.h deleted file mode 100644 index 4741e5a..0000000 --- a/arch/arm/include/asm/arch-stm32f7/fmc.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * (C) Copyright 2013 - * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com - * - * (C) Copyright 2015 - * Kamil Lulko, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _MACH_FMC_H_ -#define _MACH_FMC_H_ - -struct stm32_fmc_regs { - u32 sdcr1; /* Control register 1 */ - u32 sdcr2; /* Control register 2 */ - u32 sdtr1; /* Timing register 1 */ - u32 sdtr2; /* Timing register 2 */ - u32 sdcmr; /* Mode register */ - u32 sdrtr; /* Refresh timing register */ - u32 sdsr; /* Status register */ -}; - -/* - * FMC registers base - */ -#define STM32_SDRAM_FMC ((struct stm32_fmc_regs *)SDRAM_FMC_BASE) - -/* Control register SDCR */ -#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */ -#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */ -#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */ -#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */ -#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */ -#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */ -#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */ -#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */ -#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */ - -/* Timings register SDTR */ -#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */ -#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */ -#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */ -#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */ -#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */ -#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */ -#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */ - - -#define FMC_SDCMR_NRFS_SHIFT 5 - -#define FMC_SDCMR_MODE_NORMAL 0 -#define FMC_SDCMR_MODE_START_CLOCK 1 -#define FMC_SDCMR_MODE_PRECHARGE 2 -#define FMC_SDCMR_MODE_AUTOREFRESH 3 -#define FMC_SDCMR_MODE_WRITE_MODE 4 -#define FMC_SDCMR_MODE_SELFREFRESH 5 -#define FMC_SDCMR_MODE_POWERDOWN 6 - -#define FMC_SDCMR_BANK_1 BIT(4) -#define FMC_SDCMR_BANK_2 BIT(3) - -#define FMC_SDCMR_MODE_REGISTER_SHIFT 9 - -#define FMC_SDSR_BUSY BIT(5) - -#define FMC_BUSY_WAIT() do { \ - __asm__ __volatile__ ("dsb" : : : "memory"); \ - while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \ - ; \ - } while (0) - - -#endif /* _MACH_FMC_H_ */ diff --git a/arch/arm/include/asm/arch-stm32f7/rcc.h b/arch/arm/include/asm/arch-stm32f7/rcc.h index 0f8d50b..a33f8cf 100644 --- a/arch/arm/include/asm/arch-stm32f7/rcc.h +++ b/arch/arm/include/asm/arch-stm32f7/rcc.h @@ -8,44 +8,24 @@ #ifndef _STM32_RCC_H #define _STM32_RCC_H +#include + /* * RCC AHB1ENR specific definitions */ -#define RCC_AHB1ENR_GPIO_A_EN BIT(0) -#define RCC_AHB1ENR_GPIO_B_EN BIT(1) -#define RCC_AHB1ENR_GPIO_C_EN BIT(2) -#define RCC_AHB1ENR_GPIO_D_EN BIT(3) -#define RCC_AHB1ENR_GPIO_E_EN BIT(4) -#define RCC_AHB1ENR_GPIO_F_EN BIT(5) -#define RCC_AHB1ENR_GPIO_G_EN BIT(6) -#define RCC_AHB1ENR_GPIO_H_EN BIT(7) -#define RCC_AHB1ENR_GPIO_I_EN BIT(8) -#define RCC_AHB1ENR_GPIO_J_EN BIT(9) -#define RCC_AHB1ENR_GPIO_K_EN BIT(10) #define RCC_AHB1ENR_ETHMAC_EN BIT(25) #define RCC_AHB1ENR_ETHMAC_TX_EN BIT(26) #define RCC_AHB1ENR_ETHMAC_RX_EN BIT(27) -#define RCC_AHB1ENR_ETHMAC_PTP_EN BIT(28) - -/* - * RCC AHB3ENR specific definitions - */ -#define RCC_AHB3ENR_FMC_EN BIT(0) -#define RCC_AHB3ENR_QSPI_EN BIT(1) /* * RCC APB1ENR specific definitions */ #define RCC_APB1ENR_TIM2EN BIT(0) -#define RCC_APB1ENR_USART2EN BIT(17) -#define RCC_APB1ENR_USART3EN BIT(18) #define RCC_APB1ENR_PWREN BIT(28) /* * RCC APB2ENR specific definitions */ -#define RCC_APB2ENR_USART1EN BIT(4) -#define RCC_APB2ENR_USART6EN BIT(5) #define RCC_APB2ENR_SYSCFGEN BIT(14) #endif diff --git a/arch/arm/include/asm/arch-stm32f7/stm32.h b/arch/arm/include/asm/arch-stm32f7/stm32.h index 14e3398..87aee60 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32.h @@ -57,12 +57,6 @@ static const u32 sect_sz_kb[CONFIG_SYS_MAX_FLASH_SECT] = { [5 ... 7] = 256 * 1024 }; -enum clock { - CLOCK_CORE, - CLOCK_AHB, - CLOCK_APB1, - CLOCK_APB2 -}; #define STM32_BUS_MASK GENMASK(31, 16) struct stm32_rcc_regs { @@ -101,11 +95,6 @@ struct stm32_rcc_regs { }; #define STM32_RCC ((struct stm32_rcc_regs *)RCC_BASE) -struct stm32_rcc_ext_f7_regs { - u32 dckcfgr2; /* dedicated clocks configuration register */ -}; -#define STM32_RCC_EXT_F7 ((struct stm32_rcc_ext_f7_regs *) (RCC_BASE + sizeof(struct stm32_rcc_regs))) - struct stm32_pwr_regs { u32 cr1; /* power control register 1 */ u32 csr1; /* power control/status register 2 */ @@ -114,8 +103,6 @@ struct stm32_pwr_regs { }; #define STM32_PWR ((struct stm32_pwr_regs *)PWR_BASE) -int configure_clocks(void); -unsigned long clock_get(enum clock clck); void stm32_flash_latency_cfg(int latency); #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h index 3c5604a..9c1ec02 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h @@ -21,24 +21,9 @@ enum periph_id { }; enum periph_clock { - USART1_CLOCK_CFG = 0, - USART2_CLOCK_CFG, - GPIO_A_CLOCK_CFG, - GPIO_B_CLOCK_CFG, - GPIO_C_CLOCK_CFG, - GPIO_D_CLOCK_CFG, - GPIO_E_CLOCK_CFG, - GPIO_F_CLOCK_CFG, - GPIO_G_CLOCK_CFG, - GPIO_H_CLOCK_CFG, - GPIO_I_CLOCK_CFG, - GPIO_J_CLOCK_CFG, - GPIO_K_CLOCK_CFG, SYSCFG_CLOCK_CFG, TIMER2_CLOCK_CFG, - FMC_CLOCK_CFG, STMMAC_CLOCK_CFG, - QSPI_CLOCK_CFG, }; #endif /* __ASM_ARM_ARCH_PERIPH_H */ diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h index f62b2a4..92180db 100644 --- a/arch/arm/include/asm/arch-tegra/clock.h +++ b/arch/arm/include/asm/arch-tegra/clock.h @@ -266,7 +266,7 @@ void clock_ll_start_uart(enum periph_id periph_id); * @param node Node to look at * @return peripheral ID, or PERIPH_ID_NONE if none */ -enum periph_id clock_decode_periph_id(const void *blob, int node); +int clock_decode_periph_id(struct udevice *dev); /** * Checks if the oscillator bypass is enabled (XOBP bit) diff --git a/arch/arm/include/asm/arch-tegra/tegra.h b/arch/arm/include/asm/arch-tegra/tegra.h index 3add1b3..3b9711d 100644 --- a/arch/arm/include/asm/arch-tegra/tegra.h +++ b/arch/arm/include/asm/arch-tegra/tegra.h @@ -97,6 +97,11 @@ enum { TEGRA_SOC_UNKNOWN = -1, }; +/* Tegra system controller (SYSCON) devices */ +enum { + TEGRA_SYSCON_PMC, +}; + #else /* __ASSEMBLY__ */ #define PRM_RSTCTRL NV_PA_PMC_BASE #endif diff --git a/arch/arm/include/asm/arch-tegra/xusb-padctl.h b/arch/arm/include/asm/arch-tegra/xusb-padctl.h index b4b4c8b..deccdf4 100644 --- a/arch/arm/include/asm/arch-tegra/xusb-padctl.h +++ b/arch/arm/include/asm/arch-tegra/xusb-padctl.h @@ -15,7 +15,7 @@ struct tegra_xusb_phy; */ struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type); -void tegra_xusb_padctl_init(const void *fdt); +void tegra_xusb_padctl_init(void); int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy); int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy); int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy); diff --git a/arch/arm/include/asm/ehci-omap.h b/arch/arm/include/asm/ehci-omap.h index 5a53e40..9dbb2c4 100644 --- a/arch/arm/include/asm/ehci-omap.h +++ b/arch/arm/include/asm/ehci-omap.h @@ -19,11 +19,7 @@ enum usbhs_omap_port_mode { OMAP_EHCI_PORT_MODE_HSIC, }; -#ifdef CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS -#define OMAP_HS_USB_PORTS CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS -#else #define OMAP_HS_USB_PORTS 3 -#endif #define is_ehci_phy_mode(x) ((x) == OMAP_EHCI_PORT_MODE_PHY) #define is_ehci_tll_mode(x) ((x) == OMAP_EHCI_PORT_MODE_TLL) diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c index 591e758..c2525bd 100644 --- a/arch/arm/mach-keystone/cmd_mon.c +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -19,6 +19,7 @@ static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, u32 addr, dpsc_base = 0x1E80000, freq, load_addr, size; int rcode = 0; struct image_header *header; + u32 ecrypt_bm_addr = 0; if (argc < 2) return CMD_RET_USAGE; @@ -39,14 +40,17 @@ static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, memcpy((void *)load_addr, (void *)(addr + sizeof(struct image_header)), size); - rcode = mon_install(load_addr, dpsc_base, freq); + if (argc >= 3) + ecrypt_bm_addr = simple_strtoul(argv[2], NULL, 16); + + rcode = mon_install(load_addr, dpsc_base, freq, ecrypt_bm_addr); printf("## installed monitor @ 0x%x, freq [%d], status %d\n", load_addr, freq, rcode); return 0; } -U_BOOT_CMD(mon_install, 2, 0, do_mon_install, +U_BOOT_CMD(mon_install, 3, 0, do_mon_install, "Install boot kernel at 'addr'", "" ); diff --git a/arch/arm/mach-keystone/include/mach/mon.h b/arch/arm/mach-keystone/include/mach/mon.h index eb7aa93..30c57e0 100644 --- a/arch/arm/mach-keystone/include/mach/mon.h +++ b/arch/arm/mach-keystone/include/mach/mon.h @@ -10,7 +10,7 @@ #ifndef _MACH_MON_H_ #define _MACH_MON_H_ -int mon_install(u32 addr, u32 dpsc, u32 freq); +int mon_install(u32 addr, u32 dpsc, u32 freq, u32 bm_addr); int mon_power_on(int core_id, void *ep); int mon_power_off(int core_id); diff --git a/arch/arm/mach-keystone/mon.c b/arch/arm/mach-keystone/mon.c index ebfb483..dd446ab 100644 --- a/arch/arm/mach-keystone/mon.c +++ b/arch/arm/mach-keystone/mon.c @@ -13,7 +13,7 @@ #include asm(".arch_extension sec\n\t"); -int mon_install(u32 addr, u32 dpsc, u32 freq) +int mon_install(u32 addr, u32 dpsc, u32 freq, u32 bm_addr) { int result; @@ -22,11 +22,13 @@ int mon_install(u32 addr, u32 dpsc, u32 freq) "mov r0, %1\n" "mov r1, %2\n" "mov r2, %3\n" + "mov r3, %4\n" "blx r0\n" + "mov %0, r0\n" "ldmfd r13!, {lr}\n" : "=&r" (result) - : "r" (addr), "r" (dpsc), "r" (freq) - : "cc", "r0", "r1", "r2", "memory"); + : "r" (addr), "r" (dpsc), "r" (freq), "r" (bm_addr) + : "cc", "r0", "r1", "r2", "r3", "memory"); return result; } @@ -40,6 +42,7 @@ int mon_power_on(int core_id, void *ep) "mov r2, %2\n" "mov r0, #0\n" "smc #0\n" + "mov %0, r0\n" "ldmfd r13!, {lr}\n" : "=&r" (result) : "r" (core_id), "r" (ep) @@ -56,6 +59,7 @@ int mon_power_off(int core_id) "mov r1, %1\n" "mov r0, #1\n" "smc #1\n" + "mov %0, r0\n" "ldmfd r13!, {lr}\n" : "=&r" (result) : "r" (core_id) @@ -89,6 +93,7 @@ static int k2_hs_bm_auth(int cmd, void *arg1) "mov r0, %1\n" "mov r1, %2\n" "smc #2\n" + "mov %0, r0\n" "ldmfd r13!, {r4-r12, lr}\n" : "=&r" (result) : "r" (cmd), "r" (arg1) diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index bb44c61..c924613 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -82,6 +82,8 @@ config ROCKCHIP_RK3399 select SUPPORT_SPL select SPL select SPL_SEPARATE_BSS + select SPL_SERIAL_SUPPORT + select SPL_DRIVERS_MISC_SUPPORT select ENABLE_ARM_SOC_BOOT0_HOOK select DEBUG_UART_BOARD_INIT help diff --git a/arch/arm/mach-rockchip/bootrom.c b/arch/arm/mach-rockchip/bootrom.c index da36f92..4ca9962 100644 --- a/arch/arm/mach-rockchip/bootrom.c +++ b/arch/arm/mach-rockchip/bootrom.c @@ -9,8 +9,8 @@ void back_to_bootrom(void) { -#if defined(CONFIG_SPL_LIBGENERIC_SUPPORT) && !defined(CONFIG_TPL_BUILD) - printf("Returning to boot ROM..."); +#if defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && !defined(CONFIG_TPL_BUILD) + puts("Returning to boot ROM..."); #endif _back_to_bootrom_s(); } diff --git a/arch/arm/mach-rockchip/rk3036-board-spl.c b/arch/arm/mach-rockchip/rk3036-board-spl.c index 7b8d0ee..9458201 100644 --- a/arch/arm/mach-rockchip/rk3036-board-spl.c +++ b/arch/arm/mach-rockchip/rk3036-board-spl.c @@ -53,9 +53,3 @@ void board_init_r(gd_t *id, ulong dest_addr) while (1) ; } - -void hang(void) -{ - while (1) - ; -} diff --git a/arch/arm/mach-rockchip/rk_timer.c b/arch/arm/mach-rockchip/rk_timer.c index ae5123d..853b986 100644 --- a/arch/arm/mach-rockchip/rk_timer.c +++ b/arch/arm/mach-rockchip/rk_timer.c @@ -4,9 +4,9 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include #include #include -#include #include struct rk_timer * const timer_ptr = (void *)CONFIG_SYS_TIMER_BASE; diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 4838758..58085dc 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -88,6 +88,8 @@ config TEGRA124 bool "Tegra124 family" select TEGRA_ARMV7_COMMON imply ENV_IS_IN_MMC + imply REGMAP + imply SYSCON config TEGRA210 bool "Tegra210 family" diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 6b5fa7d..bd13796 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -29,7 +29,6 @@ #ifdef CONFIG_TEGRA_CLOCK_SCALING #include #endif -#include #include "emc.h" DECLARE_GLOBAL_DATA_PTR; @@ -142,11 +141,6 @@ int board_init(void) debug("Memory controller init failed: %d\n", err); # endif # endif /* CONFIG_TEGRA_PMU */ -#ifdef CONFIG_PMIC_AS3722 - err = as3722_init(NULL); - if (err && err != -ENODEV) - return err; -#endif #endif /* CONFIG_SYS_I2C_TEGRA */ #ifdef CONFIG_USB_EHCI_TEGRA @@ -166,7 +160,7 @@ int board_init(void) pin_mux_nand(); #endif - tegra_xusb_padctl_init(gd->fdt_blob); + tegra_xusb_padctl_init(); #ifdef CONFIG_TEGRA_LP0 /* save Sdram params to PMC 2, 4, and 24 for WB0 */ diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index 668bbd2..dc58b30 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -655,14 +655,13 @@ void clock_ll_start_uart(enum periph_id periph_id) } #if CONFIG_IS_ENABLED(OF_CONTROL) -int clock_decode_periph_id(const void *blob, int node) +int clock_decode_periph_id(struct udevice *dev) { enum periph_id id; u32 cell[2]; int err; - err = fdtdec_get_int_array(blob, node, "clocks", cell, - ARRAY_SIZE(cell)); + err = dev_read_u32_array(dev, "clocks", cell, ARRAY_SIZE(cell)); if (err) return -1; id = clk_id_to_periph_id(cell[1]); diff --git a/arch/arm/mach-tegra/spl.c b/arch/arm/mach-tegra/spl.c index 41c88cb..189b3da 100644 --- a/arch/arm/mach-tegra/spl.c +++ b/arch/arm/mach-tegra/spl.c @@ -7,6 +7,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ #include +#include #include #include @@ -32,6 +33,9 @@ void spl_board_init(void) gpio_early_init_uart(); clock_early_init(); +#ifdef CONFIG_DEBUG_UART + debug_uart_init(); +#endif preloader_console_init(); } diff --git a/arch/arm/mach-tegra/tegra124/Makefile b/arch/arm/mach-tegra/tegra124/Makefile index c00de61..d275daf 100644 --- a/arch/arm/mach-tegra/tegra124/Makefile +++ b/arch/arm/mach-tegra/tegra124/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_SPL_BUILD) += cpu.o obj-y += clock.o obj-y += funcmux.o obj-y += pinmux.o +obj-y += pmc.o obj-y += xusb-padctl.o obj-y += ../xusb-padctl-common.o diff --git a/arch/arm/mach-tegra/tegra124/pmc.c b/arch/arm/mach-tegra/tegra124/pmc.c new file mode 100644 index 0000000..be82acf --- /dev/null +++ b/arch/arm/mach-tegra/tegra124/pmc.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +static const struct udevice_id tegra124_syscon_ids[] = { + { .compatible = "nvidia,tegra124-pmc", .data = TEGRA_SYSCON_PMC }, +}; + +U_BOOT_DRIVER(syscon_tegra124) = { + .name = "tegra124_syscon", + .id = UCLASS_SYSCON, + .of_match = tegra124_syscon_ids, +}; diff --git a/arch/arm/mach-tegra/tegra124/xusb-padctl.c b/arch/arm/mach-tegra/tegra124/xusb-padctl.c index 76af924..d326a6a 100644 --- a/arch/arm/mach-tegra/tegra124/xusb-padctl.c +++ b/arch/arm/mach-tegra/tegra124/xusb-padctl.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include "../xusb-padctl-common.h" @@ -317,13 +319,33 @@ static const struct tegra_xusb_padctl_soc tegra124_socdata = { .num_phys = ARRAY_SIZE(tegra124_phys), }; -void tegra_xusb_padctl_init(const void *fdt) +void tegra_xusb_padctl_init(void) { - int count, nodes[1]; + ofnode nodes[1]; + int count = 0; + int ret; + + debug("%s: start\n", __func__); + if (of_live_active()) { + struct device_node *np = of_find_compatible_node(NULL, NULL, + "nvidia,tegra124-xusb-padctl"); + + debug("np=%p\n", np); + if (np) { + nodes[0] = np_to_ofnode(np); + count = 1; + } + } else { + int node_offsets[1]; + int i; + + count = fdtdec_find_aliases_for_id(gd->fdt_blob, "padctl", + COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, + node_offsets, ARRAY_SIZE(node_offsets)); + for (i = 0; i < count; i++) + nodes[i] = offset_to_ofnode(node_offsets[i]); + } - count = fdtdec_find_aliases_for_id(fdt, "padctl", - COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, - nodes, ARRAY_SIZE(nodes)); - if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra124_socdata)) - return; + ret = tegra_xusb_process_nodes(nodes, count, &tegra124_socdata); + debug("%s: done, ret=%d\n", __func__, ret); } diff --git a/arch/arm/mach-tegra/tegra210/xusb-padctl.c b/arch/arm/mach-tegra/tegra210/xusb-padctl.c index 9ec93e7..bf85e07 100644 --- a/arch/arm/mach-tegra/tegra210/xusb-padctl.c +++ b/arch/arm/mach-tegra/tegra210/xusb-padctl.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include "../xusb-padctl-common.h" @@ -15,6 +17,8 @@ #include +DECLARE_GLOBAL_DATA_PTR; + enum tegra210_function { TEGRA210_FUNC_SNPS, TEGRA210_FUNC_XUSB, @@ -421,17 +425,33 @@ static const struct tegra_xusb_padctl_soc tegra210_socdata = { .num_phys = ARRAY_SIZE(tegra210_phys), }; -void tegra_xusb_padctl_init(const void *fdt) +void tegra_xusb_padctl_init(void) { - int count, nodes[1]; - - debug("> %s(fdt=%p)\n", __func__, fdt); - - count = fdtdec_find_aliases_for_id(fdt, "padctl", - COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL, - nodes, ARRAY_SIZE(nodes)); - if (tegra_xusb_process_nodes(fdt, nodes, count, &tegra210_socdata)) - return; + ofnode nodes[1]; + int count = 0; + int ret; + + debug("%s: start\n", __func__); + if (of_live_active()) { + struct device_node *np = of_find_compatible_node(NULL, NULL, + "nvidia,tegra210-xusb-padctl"); + + debug("np=%p\n", np); + if (np) { + nodes[0] = np_to_ofnode(np); + count = 1; + } + } else { + int node_offsets[1]; + int i; + + count = fdtdec_find_aliases_for_id(gd->fdt_blob, "padctl", + COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL, + node_offsets, ARRAY_SIZE(node_offsets)); + for (i = 0; i < count; i++) + nodes[i] = offset_to_ofnode(node_offsets[i]); + } - debug("< %s()\n", __func__); + ret = tegra_xusb_process_nodes(nodes, count, &tegra210_socdata); + debug("%s: done, ret=%d\n", __func__, ret); } diff --git a/arch/arm/mach-tegra/xusb-padctl-common.c b/arch/arm/mach-tegra/xusb-padctl-common.c index 43f5bb7..37b5b8f 100644 --- a/arch/arm/mach-tegra/xusb-padctl-common.c +++ b/arch/arm/mach-tegra/xusb-padctl-common.c @@ -75,14 +75,14 @@ tegra_xusb_padctl_find_lane(struct tegra_xusb_padctl *padctl, const char *name) static int tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, struct tegra_xusb_padctl_group *group, - const void *fdt, int node) + ofnode node) { unsigned int i; - int len; + int len, ret; - group->name = fdt_get_name(fdt, node, &len); + group->name = ofnode_get_name(node); - len = fdt_stringlist_count(fdt, node, "nvidia,lanes"); + len = ofnode_read_string_count(node, "nvidia,lanes"); if (len < 0) { error("failed to parse \"nvidia,lanes\" property"); return -EINVAL; @@ -91,9 +91,9 @@ tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, group->num_pins = len; for (i = 0; i < group->num_pins; i++) { - group->pins[i] = fdt_stringlist_get(fdt, node, "nvidia,lanes", - i, NULL); - if (!group->pins[i]) { + ret = ofnode_read_string_index(node, "nvidia,lanes", i, + &group->pins[i]); + if (ret) { error("failed to read string from \"nvidia,lanes\" property"); return -EINVAL; } @@ -101,13 +101,14 @@ tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, group->num_pins = len; - group->func = fdt_stringlist_get(fdt, node, "nvidia,function", 0, NULL); - if (!group->func) { + ret = ofnode_read_string_index(node, "nvidia,function", 0, + &group->func); + if (ret) { error("failed to parse \"nvidia,func\" property"); return -EINVAL; } - group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1); + group->iddq = ofnode_read_u32_default(node, "nvidia,iddq", -1); return 0; } @@ -217,20 +218,21 @@ tegra_xusb_padctl_config_apply(struct tegra_xusb_padctl *padctl, static int tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl, struct tegra_xusb_padctl_config *config, - const void *fdt, int node) + ofnode node) { - int subnode; + ofnode subnode; - config->name = fdt_get_name(fdt, node, NULL); + config->name = ofnode_get_name(node); - fdt_for_each_subnode(subnode, fdt, node) { + for (subnode = ofnode_first_subnode(node); + ofnode_valid(subnode); + subnode = ofnode_next_subnode(subnode)) { struct tegra_xusb_padctl_group *group; int err; group = &config->groups[config->num_groups]; - err = tegra_xusb_padctl_group_parse_dt(padctl, group, fdt, - subnode); + err = tegra_xusb_padctl_group_parse_dt(padctl, group, subnode); if (err < 0) { error("failed to parse group %s", group->name); return err; @@ -243,20 +245,24 @@ tegra_xusb_padctl_config_parse_dt(struct tegra_xusb_padctl *padctl, } static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl, - const void *fdt, int node) + ofnode node) { - int subnode, err; + ofnode subnode; + int err; - err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs); + err = ofnode_read_resource(node, 0, &padctl->regs); if (err < 0) { error("registers not found"); return err; } - fdt_for_each_subnode(subnode, fdt, node) { + for (subnode = ofnode_first_subnode(node); + ofnode_valid(subnode); + subnode = ofnode_next_subnode(subnode)) { struct tegra_xusb_padctl_config *config = &padctl->config; - err = tegra_xusb_padctl_config_parse_dt(padctl, config, fdt, + debug("%s: subnode=%s\n", __func__, ofnode_get_name(subnode)); + err = tegra_xusb_padctl_config_parse_dt(padctl, config, subnode); if (err < 0) { error("failed to parse entry %s: %d", @@ -264,25 +270,28 @@ static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl, continue; } } + debug("%s: done\n", __func__); return 0; } struct tegra_xusb_padctl padctl; -int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count, - const struct tegra_xusb_padctl_soc *socdata) +int tegra_xusb_process_nodes(ofnode nodes[], unsigned int count, + const struct tegra_xusb_padctl_soc *socdata) { unsigned int i; int err; + debug("%s: count=%d\n", __func__, count); for (i = 0; i < count; i++) { - if (!fdtdec_get_is_enabled(fdt, nodes[i])) + debug("%s: i=%d, node=%p\n", __func__, i, nodes[i].np); + if (!ofnode_is_available(nodes[i])) continue; padctl.socdata = socdata; - err = tegra_xusb_padctl_parse_dt(&padctl, fdt, nodes[i]); + err = tegra_xusb_padctl_parse_dt(&padctl, nodes[i]); if (err < 0) { error("failed to parse DT: %d", err); continue; @@ -300,6 +309,7 @@ int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count, /* only a single instance is supported */ break; } + debug("%s: done\n", __func__); return 0; } diff --git a/arch/arm/mach-tegra/xusb-padctl-common.h b/arch/arm/mach-tegra/xusb-padctl-common.h index f44790a..6836588 100644 --- a/arch/arm/mach-tegra/xusb-padctl-common.h +++ b/arch/arm/mach-tegra/xusb-padctl-common.h @@ -9,9 +9,11 @@ #include #include +#include #include #include +#include struct tegra_xusb_padctl_lane { const char *name; @@ -77,7 +79,7 @@ struct tegra_xusb_padctl_config { struct tegra_xusb_padctl { const struct tegra_xusb_padctl_soc *socdata; struct tegra_xusb_padctl_config config; - struct fdt_resource regs; + struct resource regs; unsigned int enable; }; @@ -95,7 +97,7 @@ static inline void padctl_writel(struct tegra_xusb_padctl *padctl, writel(value, padctl->regs.start + offset); } -int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count, - const struct tegra_xusb_padctl_soc *socdata); +int tegra_xusb_process_nodes(ofnode nodes[], unsigned int count, + const struct tegra_xusb_padctl_soc *socdata); #endif diff --git a/arch/arm/mach-tegra/xusb-padctl-dummy.c b/arch/arm/mach-tegra/xusb-padctl-dummy.c index 65f8d2e..856d712 100644 --- a/arch/arm/mach-tegra/xusb-padctl-dummy.c +++ b/arch/arm/mach-tegra/xusb-padctl-dummy.c @@ -34,6 +34,6 @@ int __weak tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy) return -ENOSYS; } -void __weak tegra_xusb_padctl_init(const void *fdt) +void __weak tegra_xusb_padctl_init(void) { } diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig index 5739325..1aed55a 100644 --- a/arch/arm/mach-uniphier/Kconfig +++ b/arch/arm/mach-uniphier/Kconfig @@ -10,14 +10,6 @@ config ARCH_UNIPHIER_32BIT select ARMV7_NONSEC select ARCH_SUPPORT_PSCI -config ARCH_UNIPHIER_64BIT - bool - select ARM64 - select CMD_UNZIP - select SPL_SEPARATE_BSS if SPL - select ARMV8_MULTIENTRY if SPL - select ARMV8_SPIN_TABLE if SPL - choice prompt "UniPhier SoC select" default ARCH_UNIPHIER_PRO4 @@ -38,18 +30,11 @@ config ARCH_UNIPHIER_PRO5_PXS2_LD6B bool "UniPhier Pro5/PXs2/LD6b SoCs" select ARCH_UNIPHIER_32BIT -config ARCH_UNIPHIER_LD11_SINGLE - bool "UniPhier LD11 SoC" - select ARCH_UNIPHIER_64BIT - -config ARCH_UNIPHIER_LD20_SINGLE - bool "UniPhier LD20 SoC" - select ARCH_UNIPHIER_64BIT - config ARCH_UNIPHIER_V8_MULTI bool "UniPhier V8 SoCs" depends on !SPL - select ARCH_UNIPHIER_64BIT + select ARM64 + select CMD_UNZIP endchoice @@ -79,13 +64,13 @@ config ARCH_UNIPHIER_LD6B default y config ARCH_UNIPHIER_LD11 - bool "Enable UniPhier LD11 SoC support" if ARCH_UNIPHIER_V8_MULTI - depends on ARCH_UNIPHIER_LD11_SINGLE || ARCH_UNIPHIER_V8_MULTI + bool "Enable UniPhier LD11 SoC support" + depends on ARCH_UNIPHIER_V8_MULTI default y config ARCH_UNIPHIER_LD20 - bool "Enable UniPhier LD20 SoC support" if ARCH_UNIPHIER_V8_MULTI - depends on ARCH_UNIPHIER_LD20_SINGLE || ARCH_UNIPHIER_V8_MULTI + bool "Enable UniPhier LD20 SoC support" + depends on ARCH_UNIPHIER_V8_MULTI select OF_BOARD_SETUP default y diff --git a/arch/arm/mach-uniphier/arm64/Makefile b/arch/arm/mach-uniphier/arm64/Makefile index 06072f2..12d91e0 100644 --- a/arch/arm/mach-uniphier/arm64/Makefile +++ b/arch/arm/mach-uniphier/arm64/Makefile @@ -2,14 +2,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifdef CONFIG_SPL_BUILD -obj-y += timer.o -else obj-y += mem_map.o -ifdef CONFIG_ARMV8_MULTIENTRY -obj-y += smp.o smp_kick_cpus.o -obj-$(CONFIG_ARCH_UNIPHIER_LD20) += arm-cci500.o -else obj-$(CONFIG_ARCH_UNIPHIER_LD20) += lowlevel_init.o -endif -endif diff --git a/arch/arm/mach-uniphier/arm64/arm-cci500.c b/arch/arm/mach-uniphier/arm64/arm-cci500.c deleted file mode 100644 index bf0fad4..0000000 --- a/arch/arm/mach-uniphier/arm64/arm-cci500.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Initialization of ARM Corelink CCI-500 Cache Coherency Interconnect - * - * Copyright (C) 2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#include "../init.h" - -#define CCI500_BASE 0x5FD00000 -#define CCI500_SLAVE_OFFSET 0x1000 - -#define CCI500_SNOOP_CTRL -#define CCI500_SNOOP_CTRL_EN_DVM BIT(1) -#define CCI500_SNOOP_CTRL_EN_SNOOP BIT(0) - -void cci500_init(unsigned int nr_slaves) -{ - unsigned long slave_base = CCI500_BASE + CCI500_SLAVE_OFFSET; - int i; - - for (i = 0; i < nr_slaves; i++) { - void __iomem *base; - u32 tmp; - - base = ioremap(slave_base, SZ_4K); - - tmp = readl(base); - tmp |= CCI500_SNOOP_CTRL_EN_DVM | CCI500_SNOOP_CTRL_EN_SNOOP; - writel(tmp, base); - - iounmap(base); - - slave_base += CCI500_SLAVE_OFFSET; - } -} diff --git a/arch/arm/mach-uniphier/arm64/smp.S b/arch/arm/mach-uniphier/arm64/smp.S deleted file mode 100644 index 9348ec9..0000000 --- a/arch/arm/mach-uniphier/arm64/smp.S +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2016 Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -ENTRY(uniphier_smp_setup) - mrs x0, s3_1_c15_c2_1 /* CPUECTLR_EL1 */ - orr x0, x0, #(1 << 6) /* SMPEN */ - msr s3_1_c15_c2_1, x0 - ret -ENDPROC(uniphier_smp_setup) - -ENTRY(uniphier_secondary_startup) - bl uniphier_smp_setup - b _start -ENDPROC(uniphier_secondary_startup) diff --git a/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c b/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c deleted file mode 100644 index 8e5b198..0000000 --- a/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include - -#include "../init.h" - -#define UNIPHIER_SMPCTRL_ROM_RSV0 0x59801200 - -void uniphier_smp_setup(void); -void uniphier_secondary_startup(void); - -void uniphier_smp_kick_all_cpus(void) -{ - void __iomem *rom_boot_rsv0; - - rom_boot_rsv0 = ioremap(UNIPHIER_SMPCTRL_ROM_RSV0, SZ_8); - - writeq((u64)uniphier_secondary_startup, rom_boot_rsv0); - - iounmap(rom_boot_rsv0); - - uniphier_smp_setup(); - - asm("dsb ishst\n" /* Ensure the write to ROM_RSV0 is visible */ - "sev"); /* Bring up all secondary CPUs from Boot ROM into U-Boot */ -} diff --git a/arch/arm/mach-uniphier/arm64/timer.c b/arch/arm/mach-uniphier/arm64/timer.c deleted file mode 100644 index c10903a..0000000 --- a/arch/arm/mach-uniphier/arm64/timer.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#define CNT_CONTROL_BASE 0x60E00000 - -#define CNTCR 0x000 -#define CNTCR_EN BIT(0) - -/* setup ARMv8 Generic Timer */ -int timer_init(void) -{ - void __iomem *base; - u32 tmp; - - base = ioremap(CNT_CONTROL_BASE, SZ_4K); - - /* - * Note: - * In a system that implements both Secure and Non-secure states, - * this register is only writable in Secure state. - */ - tmp = readl(base + CNTCR); - tmp |= CNTCR_EN; - writel(tmp, base + CNTCR); - - iounmap(base); - - return 0; -} diff --git a/arch/arm/mach-uniphier/board_init.c b/arch/arm/mach-uniphier/board_init.c index ca910f6..884bc67 100644 --- a/arch/arm/mach-uniphier/board_init.c +++ b/arch/arm/mach-uniphier/board_init.c @@ -73,9 +73,6 @@ static void uniphier_ld20_misc_init(void) writel(0x0000b500, 0x6184e024); writel(0x00000001, 0x6184e000); } -#ifdef CONFIG_ARMV8_MULTIENTRY - cci500_init(2); -#endif } #endif @@ -230,12 +227,6 @@ int board_init(void) support_card_late_init(); - led_puts("U6"); - -#ifdef CONFIG_ARMV8_MULTIENTRY - uniphier_smp_kick_all_cpus(); -#endif - led_puts("Uboo"); return 0; diff --git a/arch/arm/mach-uniphier/boards.c b/arch/arm/mach-uniphier/boards.c index e3b9335..78de256 100644 --- a/arch/arm/mach-uniphier/boards.c +++ b/arch/arm/mach-uniphier/boards.c @@ -140,69 +140,6 @@ static const struct uniphier_board_data uniphier_ld6b_data = { }; #endif -#if defined(CONFIG_ARCH_UNIPHIER_LD11) -static const struct uniphier_board_data uniphier_ld11_data = { - .dram_freq = 1600, - .dram_ch[0] = { - .size = 0x20000000, - .width = 16, - }, - .dram_ch[1] = { - .size = 0x20000000, - .width = 16, - }, -}; -#endif - -#if defined(CONFIG_ARCH_UNIPHIER_LD20) -static const struct uniphier_board_data uniphier_ld20_ref_data = { - .dram_freq = 1866, - .dram_ch[0] = { - .size = 0x40000000, - .width = 32, - }, - .dram_ch[1] = { - .size = 0x40000000, - .width = 32, - }, - .dram_ch[2] = { - .size = 0x40000000, - .width = 32, - }, - .flags = UNIPHIER_BD_BOARD_LD20_REF, -}; - -static const struct uniphier_board_data uniphier_ld20_data = { - .dram_freq = 1866, - .dram_ch[0] = { - .size = 0x40000000, - .width = 32, - }, - .dram_ch[1] = { - .size = 0x40000000, - .width = 32, - }, - .dram_ch[2] = { - .size = 0x40000000, - .width = 32, - }, - .flags = UNIPHIER_BD_BOARD_LD20_GLOBAL, -}; - -static const struct uniphier_board_data uniphier_ld21_data = { - .dram_freq = 1866, - .dram_ch[0] = { - .size = 0x20000000, - .width = 32, - }, - .dram_ch[1] = { - .size = 0x40000000, - .width = 32, - }, - .flags = UNIPHIER_BD_DRAM_SPARSE | UNIPHIER_BD_BOARD_LD21_GLOBAL, -}; -#endif - struct uniphier_board_id { const char *compatible; const struct uniphier_board_data *param; @@ -232,14 +169,6 @@ static const struct uniphier_board_id uniphier_boards[] = { #if defined(CONFIG_ARCH_UNIPHIER_LD6B) { "socionext,uniphier-ld6b", &uniphier_ld6b_data, }, #endif -#if defined(CONFIG_ARCH_UNIPHIER_LD11) - { "socionext,uniphier-ld11", &uniphier_ld11_data, }, -#endif -#if defined(CONFIG_ARCH_UNIPHIER_LD20) - { "socionext,uniphier-ld21", &uniphier_ld21_data, }, - { "socionext,uniphier-ld20-ref", &uniphier_ld20_ref_data, }, - { "socionext,uniphier-ld20", &uniphier_ld20_data, }, -#endif }; const struct uniphier_board_data *uniphier_get_board_param(void) diff --git a/arch/arm/mach-uniphier/boot-device/Makefile b/arch/arm/mach-uniphier/boot-device/Makefile index abb58a7..b357292 100644 --- a/arch/arm/mach-uniphier/boot-device/Makefile +++ b/arch/arm/mach-uniphier/boot-device/Makefile @@ -14,7 +14,3 @@ obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += boot-device-pxs2.o obj-$(CONFIG_ARCH_UNIPHIER_LD11) += boot-device-ld11.o obj-$(CONFIG_ARCH_UNIPHIER_LD20) += boot-device-ld11.o obj-$(CONFIG_ARCH_UNIPHIER_PXS3) += boot-device-pxs3.o - -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_SPL_BOARD_LOAD_IMAGE) += spl_board.o -endif diff --git a/arch/arm/mach-uniphier/boot-device/spl_board.c b/arch/arm/mach-uniphier/boot-device/spl_board.c deleted file mode 100644 index bd47ac8..0000000 --- a/arch/arm/mach-uniphier/boot-device/spl_board.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2017 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -#include "../soc-info.h" - -#define MMC_CMD_SWITCH 6 -#define MMC_CMD_SELECT_CARD 7 -#define MMC_CMD_SEND_CSD 9 -#define MMC_CMD_READ_MULTIPLE_BLOCK 18 - -#define EXT_CSD_PART_CONF 179 /* R/W */ - -#define MMC_RSP_PRESENT BIT(0) -#define MMC_RSP_136 BIT(1) /* 136 bit response */ -#define MMC_RSP_CRC BIT(2) /* expect valid crc */ -#define MMC_RSP_BUSY BIT(3) /* card may send busy */ -#define MMC_RSP_OPCODE BIT(4) /* response contains opcode */ - -#define MMC_RSP_NONE (0) -#define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R1b (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | \ - MMC_RSP_BUSY) -#define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC) -#define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R4 (MMC_RSP_PRESENT) -#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) - -#define SDHCI_DMA_ADDRESS 0x00 -#define SDHCI_BLOCK_SIZE 0x04 -#define SDHCI_MAKE_BLKSZ(dma, blksz) ((((dma) & 0x7) << 12) | ((blksz) & 0xFFF)) -#define SDHCI_BLOCK_COUNT 0x06 -#define SDHCI_ARGUMENT 0x08 -#define SDHCI_TRANSFER_MODE 0x0C -#define SDHCI_TRNS_DMA BIT(0) -#define SDHCI_TRNS_BLK_CNT_EN BIT(1) -#define SDHCI_TRNS_ACMD12 BIT(2) -#define SDHCI_TRNS_READ BIT(4) -#define SDHCI_TRNS_MULTI BIT(5) -#define SDHCI_COMMAND 0x0E -#define SDHCI_CMD_RESP_MASK 0x03 -#define SDHCI_CMD_CRC 0x08 -#define SDHCI_CMD_INDEX 0x10 -#define SDHCI_CMD_DATA 0x20 -#define SDHCI_CMD_ABORTCMD 0xC0 -#define SDHCI_CMD_RESP_NONE 0x00 -#define SDHCI_CMD_RESP_LONG 0x01 -#define SDHCI_CMD_RESP_SHORT 0x02 -#define SDHCI_CMD_RESP_SHORT_BUSY 0x03 -#define SDHCI_MAKE_CMD(c, f) ((((c) & 0xff) << 8) | ((f) & 0xff)) -#define SDHCI_RESPONSE 0x10 -#define SDHCI_HOST_CONTROL 0x28 -#define SDHCI_CTRL_DMA_MASK 0x18 -#define SDHCI_CTRL_SDMA 0x00 -#define SDHCI_BLOCK_GAP_CONTROL 0x2A -#define SDHCI_SOFTWARE_RESET 0x2F -#define SDHCI_RESET_CMD 0x02 -#define SDHCI_RESET_DATA 0x04 -#define SDHCI_INT_STATUS 0x30 -#define SDHCI_INT_RESPONSE BIT(0) -#define SDHCI_INT_DATA_END BIT(1) -#define SDHCI_INT_ERROR BIT(15) -#define SDHCI_SIGNAL_ENABLE 0x38 - -/* RCA assigned by Boot ROM */ -#define UNIPHIER_EMMC_RCA 0x1000 - -struct uniphier_mmc_cmd { - unsigned int cmdidx; - unsigned int resp_type; - unsigned int cmdarg; - unsigned int is_data; -}; - -static int uniphier_emmc_send_cmd(void __iomem *host_base, - struct uniphier_mmc_cmd *cmd) -{ - u32 mode = 0; - u32 mask = SDHCI_INT_RESPONSE; - u32 stat, flags; - - writel(U32_MAX, host_base + SDHCI_INT_STATUS); - writel(0, host_base + SDHCI_SIGNAL_ENABLE); - writel(cmd->cmdarg, host_base + SDHCI_ARGUMENT); - - if (cmd->is_data) - mode = SDHCI_TRNS_DMA | SDHCI_TRNS_BLK_CNT_EN | - SDHCI_TRNS_ACMD12 | SDHCI_TRNS_READ | - SDHCI_TRNS_MULTI; - - writew(mode, host_base + SDHCI_TRANSFER_MODE); - - if (!(cmd->resp_type & MMC_RSP_PRESENT)) - flags = SDHCI_CMD_RESP_NONE; - else if (cmd->resp_type & MMC_RSP_136) - flags = SDHCI_CMD_RESP_LONG; - else if (cmd->resp_type & MMC_RSP_BUSY) - flags = SDHCI_CMD_RESP_SHORT_BUSY; - else - flags = SDHCI_CMD_RESP_SHORT; - - if (cmd->resp_type & MMC_RSP_CRC) - flags |= SDHCI_CMD_CRC; - if (cmd->resp_type & MMC_RSP_OPCODE) - flags |= SDHCI_CMD_INDEX; - if (cmd->is_data) - flags |= SDHCI_CMD_DATA; - - if (cmd->resp_type & MMC_RSP_BUSY || cmd->is_data) - mask |= SDHCI_INT_DATA_END; - - writew(SDHCI_MAKE_CMD(cmd->cmdidx, flags), host_base + SDHCI_COMMAND); - - do { - stat = readl(host_base + SDHCI_INT_STATUS); - if (stat & SDHCI_INT_ERROR) - return -EIO; - - } while ((stat & mask) != mask); - - return 0; -} - -static int uniphier_emmc_switch_part(void __iomem *host_base, int part_num) -{ - struct uniphier_mmc_cmd cmd = {}; - - cmd.cmdidx = MMC_CMD_SWITCH; - cmd.resp_type = MMC_RSP_R1b; - cmd.cmdarg = (EXT_CSD_PART_CONF << 16) | (part_num << 8) | (3 << 24); - - return uniphier_emmc_send_cmd(host_base, &cmd); -} - -static int uniphier_emmc_is_over_2gb(void __iomem *host_base) -{ - struct uniphier_mmc_cmd cmd = {}; - u32 csd40, csd72; /* CSD[71:40], CSD[103:72] */ - int ret; - - cmd.cmdidx = MMC_CMD_SEND_CSD; - cmd.resp_type = MMC_RSP_R2; - cmd.cmdarg = UNIPHIER_EMMC_RCA << 16; - - ret = uniphier_emmc_send_cmd(host_base, &cmd); - if (ret) - return ret; - - csd40 = readl(host_base + SDHCI_RESPONSE + 4); - csd72 = readl(host_base + SDHCI_RESPONSE + 8); - - return !(~csd40 & 0xffc00380) && !(~csd72 & 0x3); -} - -static int uniphier_emmc_load_image(void __iomem *host_base, u32 dev_addr, - unsigned long load_addr, u32 block_cnt) -{ - struct uniphier_mmc_cmd cmd = {}; - u8 tmp; - - WARN_ON(load_addr >> 32); - - writel(load_addr, host_base + SDHCI_DMA_ADDRESS); - writew(SDHCI_MAKE_BLKSZ(7, 512), host_base + SDHCI_BLOCK_SIZE); - writew(block_cnt, host_base + SDHCI_BLOCK_COUNT); - - tmp = readb(host_base + SDHCI_HOST_CONTROL); - tmp &= ~SDHCI_CTRL_DMA_MASK; - tmp |= SDHCI_CTRL_SDMA; - writeb(tmp, host_base + SDHCI_HOST_CONTROL); - - tmp = readb(host_base + SDHCI_BLOCK_GAP_CONTROL); - tmp &= ~1; /* clear Stop At Block Gap Request */ - writeb(tmp, host_base + SDHCI_BLOCK_GAP_CONTROL); - - cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; - cmd.resp_type = MMC_RSP_R1; - cmd.cmdarg = dev_addr; - cmd.is_data = 1; - - return uniphier_emmc_send_cmd(host_base, &cmd); -} - -static int spl_board_load_image(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev) -{ - u32 dev_addr = CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR; - void __iomem *host_base = (void __iomem *)0x5a000200; - struct uniphier_mmc_cmd cmd = {}; - int ret; - - /* - * deselect card before SEND_CSD command. - * Do not check the return code. It fails, but it is OK. - */ - cmd.cmdidx = MMC_CMD_SELECT_CARD; - cmd.resp_type = MMC_RSP_R1; - - uniphier_emmc_send_cmd(host_base, &cmd); /* CMD7 (arg=0) */ - - /* reset CMD Line */ - writeb(SDHCI_RESET_CMD | SDHCI_RESET_DATA, - host_base + SDHCI_SOFTWARE_RESET); - while (readb(host_base + SDHCI_SOFTWARE_RESET)) - cpu_relax(); - - ret = uniphier_emmc_is_over_2gb(host_base); - if (ret < 0) - return ret; - if (ret) { - debug("card is block addressing\n"); - } else { - debug("card is byte addressing\n"); - dev_addr *= 512; - } - - cmd.cmdarg = UNIPHIER_EMMC_RCA << 16; - - /* select card again */ - ret = uniphier_emmc_send_cmd(host_base, &cmd); - if (ret) - printf("failed to select card\n"); - - /* Switch to Boot Partition 1 */ - ret = uniphier_emmc_switch_part(host_base, 1); - if (ret) - printf("failed to switch partition\n"); - - ret = uniphier_emmc_load_image(host_base, dev_addr, - CONFIG_SYS_TEXT_BASE, 1); - if (ret) { - printf("failed to load image\n"); - return ret; - } - - ret = spl_parse_image_header(spl_image, (void *)CONFIG_SYS_TEXT_BASE); - if (ret) - return ret; - - ret = uniphier_emmc_load_image(host_base, dev_addr, - spl_image->load_addr, - spl_image->size / 512); - if (ret) { - printf("failed to load image\n"); - return ret; - } - - return 0; -} -SPL_LOAD_IMAGE_METHOD("eMMC", 0, BOOT_DEVICE_BOARD, spl_board_load_image); diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile index dad035d..1680ddd 100644 --- a/arch/arm/mach-uniphier/clk/Makefile +++ b/arch/arm/mach-uniphier/clk/Makefile @@ -11,8 +11,6 @@ obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += clk-early-sld3.o clk-dram-sld3.o dpll-sld8.o obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += clk-early-sld3.o clk-dram-pro5.o dpll-pro5.o obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += clk-early-sld3.o clk-dram-pxs2.o dpll-pxs2.o obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += clk-early-sld3.o clk-dram-pxs2.o dpll-pxs2.o -obj-$(CONFIG_ARCH_UNIPHIER_LD11) += clk-early-ld11.o clk-dram-ld11.o dpll-ld11.o -obj-$(CONFIG_ARCH_UNIPHIER_LD20) += clk-early-ld11.o clk-dram-ld20.o dpll-ld20.o else diff --git a/arch/arm/mach-uniphier/clk/clk-dram-ld11.c b/arch/arm/mach-uniphier/clk/clk-dram-ld11.c deleted file mode 100644 index 593e11a..0000000 --- a/arch/arm/mach-uniphier/clk/clk-dram-ld11.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2016-2017 Socionext Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#include "../init.h" -#include "../sc64-regs.h" - -void uniphier_ld11_dram_clk_init(void) -{ - u32 tmp; - - /* deassert reset */ - tmp = readl(SC_RSTCTRL7); - tmp |= SC_RSTCTRL7_UMC31 | SC_RSTCTRL7_UMC30; - writel(tmp, SC_RSTCTRL7); - - /* provide clocks */ - tmp = readl(SC_CLKCTRL7); - tmp |= SC_CLKCTRL7_UMC31 | SC_CLKCTRL7_UMC30; - writel(tmp, SC_CLKCTRL7); -} diff --git a/arch/arm/mach-uniphier/clk/clk-dram-ld20.c b/arch/arm/mach-uniphier/clk/clk-dram-ld20.c deleted file mode 100644 index 62e5acd..0000000 --- a/arch/arm/mach-uniphier/clk/clk-dram-ld20.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2016-2017 Socionext Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#include "../init.h" -#include "../sc64-regs.h" - -void uniphier_ld20_dram_clk_init(void) -{ - u32 tmp; - - /* deassert reset */ - tmp = readl(SC_RSTCTRL7); - tmp |= SC_RSTCTRL7_UMCSB | SC_RSTCTRL7_UMCA2 | SC_RSTCTRL7_UMCA1 | - SC_RSTCTRL7_UMCA0 | SC_RSTCTRL7_UMC32 | SC_RSTCTRL7_UMC31 | - SC_RSTCTRL7_UMC30; - writel(tmp, SC_RSTCTRL7); - - /* provide clocks */ - tmp = readl(SC_CLKCTRL7); - tmp |= SC_CLKCTRL7_UMCSB | SC_CLKCTRL7_UMC32 | SC_CLKCTRL7_UMC31 | - SC_CLKCTRL7_UMC30; - writel(tmp, SC_CLKCTRL7); -} diff --git a/arch/arm/mach-uniphier/clk/clk-early-ld11.c b/arch/arm/mach-uniphier/clk/clk-early-ld11.c deleted file mode 100644 index bb6f7a4..0000000 --- a/arch/arm/mach-uniphier/clk/clk-early-ld11.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2016-2017 Socionext Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#include "../init.h" -#include "../sc64-regs.h" - -void uniphier_ld11_early_clk_init(void) -{ - u32 tmp; - - /* provide clocks */ - tmp = readl(SC_CLKCTRL4); - tmp |= SC_CLKCTRL4_PERI; - writel(tmp, SC_CLKCTRL4); -} diff --git a/arch/arm/mach-uniphier/clk/dpll-ld11.c b/arch/arm/mach-uniphier/clk/dpll-ld11.c deleted file mode 100644 index 7f0677c..0000000 --- a/arch/arm/mach-uniphier/clk/dpll-ld11.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include "../init.h" -#include "../sc64-regs.h" -#include "pll.h" - -int uniphier_ld11_dpll_init(const struct uniphier_board_data *bd) -{ - uniphier_ld20_sscpll_init(SC_DPLLCTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 2); - - return 0; -} diff --git a/arch/arm/mach-uniphier/clk/dpll-ld20.c b/arch/arm/mach-uniphier/clk/dpll-ld20.c deleted file mode 100644 index 86e99c4..0000000 --- a/arch/arm/mach-uniphier/clk/dpll-ld20.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include "../init.h" -#include "../sc64-regs.h" -#include "pll.h" - -int uniphier_ld20_dpll_init(const struct uniphier_board_data *bd) -{ - uniphier_ld20_sscpll_init(SC_DPLL0CTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 2); - uniphier_ld20_sscpll_init(SC_DPLL1CTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 2); - uniphier_ld20_sscpll_init(SC_DPLL2CTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 2); - - return 0; -} diff --git a/arch/arm/mach-uniphier/cpu-info.c b/arch/arm/mach-uniphier/cpu-info.c index 94dce7c..2ce73c5 100644 --- a/arch/arm/mach-uniphier/cpu-info.c +++ b/arch/arm/mach-uniphier/cpu-info.c @@ -20,37 +20,37 @@ int print_cpuinfo(void) model = uniphier_get_soc_model(); rev = uniphier_get_soc_revision(); - puts("CPU: "); + puts("SoC: "); switch (id) { case UNIPHIER_SLD3_ID: - puts("sLD3 (MN2WS0220)"); + puts("sLD3"); required_model = 2; break; case UNIPHIER_LD4_ID: - puts("LD4 (MN2WS0250)"); + puts("LD4"); required_rev = 2; break; case UNIPHIER_PRO4_ID: - puts("Pro4 (MN2WS0230)"); + puts("Pro4"); break; case UNIPHIER_SLD8_ID: - puts("sLD8 (MN2WS0270)"); + puts("sLD8"); break; case UNIPHIER_PRO5_ID: - puts("Pro5 (MN2WS0300)"); + puts("Pro5"); break; case UNIPHIER_PXS2_ID: - puts("PXs2 (MN2WS0310)"); + puts("PXs2"); break; case UNIPHIER_LD6B_ID: - puts("LD6b (MN2WS0320)"); + puts("LD6b"); break; case UNIPHIER_LD11_ID: - puts("LD11 (SC1405AP1)"); + puts("LD11"); break; case UNIPHIER_LD20_ID: - puts("LD20 (SC1401AJ1)"); + puts("LD20"); break; case UNIPHIER_PXS3_ID: puts("PXs3"); @@ -60,7 +60,7 @@ int print_cpuinfo(void) return -ENOTSUPP; } - printf(" model %d (revision %d)\n", model, rev); + printf(" (model %d, revision %d)\n", model, rev); if (model < required_model) { printf("Only model %d or newer is supported.\n", diff --git a/arch/arm/mach-uniphier/dram/Makefile b/arch/arm/mach-uniphier/dram/Makefile index 2ce6199..1da33f6 100644 --- a/arch/arm/mach-uniphier/dram/Makefile +++ b/arch/arm/mach-uniphier/dram/Makefile @@ -14,8 +14,6 @@ obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += umc-sld8.o \ obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += umc-pro5.o obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += umc-pxs2.o obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += umc-pxs2.o -obj-$(CONFIG_ARCH_UNIPHIER_LD11) += umc-ld11.o -obj-$(CONFIG_ARCH_UNIPHIER_LD20) += umc-ld20.o else diff --git a/arch/arm/mach-uniphier/dram/ddruqphy-regs.h b/arch/arm/mach-uniphier/dram/ddruqphy-regs.h deleted file mode 100644 index e496af5..0000000 --- a/arch/arm/mach-uniphier/dram/ddruqphy-regs.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _DDRUQPHY_REGS_H -#define _DDRUQPHY_REGS_H - -#include - -#define PHY_REG_SHIFT 2 -#define PHY_SLV_DLY_WIDTH 6 -#define PHY_BITLVL_DLY_WIDTH 6 -#define PHY_MAS_DLY_WIDTH 8 - -#define PHY_SCL_START (0x40 << (PHY_REG_SHIFT)) -#define PHY_SCL_START_GO_DONE BIT(28) -#define PHY_SCL_DATA_0 (0x41 << (PHY_REG_SHIFT)) -#define PHY_SCL_DATA_1 (0x42 << (PHY_REG_SHIFT)) -#define PHY_SCL_LATENCY (0x43 << (PHY_REG_SHIFT)) -#define PHY_SCL_CONFIG_1 (0x46 << (PHY_REG_SHIFT)) -#define PHY_SCL_CONFIG_2 (0x47 << (PHY_REG_SHIFT)) -#define PHY_PAD_CTRL (0x48 << (PHY_REG_SHIFT)) -#define PHY_DLL_RECALIB (0x49 << (PHY_REG_SHIFT)) -#define PHY_DLL_RECALIB_TRIM_MASK GENMASK(PHY_SLV_DLY_WIDTH - 1, 0) -#define PHY_DLL_RECALIB_INCR BIT(27) -#define PHY_DLL_ADRCTRL (0x4A << (PHY_REG_SHIFT)) -#define PHY_DLL_ADRCTRL_TRIM_MASK GENMASK(PHY_SLV_DLY_WIDTH - 1, 0) -#define PHY_DLL_ADRCTRL_INCR BIT(9) -#define PHY_DLL_ADRCTRL_MDL_SHIFT 24 -#define PHY_DLL_ADRCTRL_MDL_MASK (GENMASK(PHY_MAS_DLY_WIDTH - 1, 0) << \ - PHY_DLL_ADRCTRL_MDL_SHIFT) -#define PHY_LANE_SEL (0x4B << (PHY_REG_SHIFT)) -#define PHY_LANE_SEL_LANE_SHIFT 0 -#define PHY_LANE_SEL_LANE_WIDTH 8 -#define PHY_LANE_SEL_BIT_SHIFT 8 -#define PHY_LANE_SEL_BIT_WIDTH 4 -#define PHY_DLL_TRIM_1 (0x4C << (PHY_REG_SHIFT)) -#define PHY_DLL_TRIM_2 (0x4D << (PHY_REG_SHIFT)) -#define PHY_DLL_TRIM_3 (0x4E << (PHY_REG_SHIFT)) -#define PHY_SCL_MAIN_CLK_DELTA (0x50 << (PHY_REG_SHIFT)) -#define PHY_WRLVL_AUTOINC_TRIM (0x53 << (PHY_REG_SHIFT)) -#define PHY_WRLVL_DYN_ODT (0x54 << (PHY_REG_SHIFT)) -#define PHY_WRLVL_ON_OFF (0x55 << (PHY_REG_SHIFT)) -#define PHY_UNQ_ANALOG_DLL_1 (0x57 << (PHY_REG_SHIFT)) -#define PHY_UNQ_ANALOG_DLL_2 (0x58 << (PHY_REG_SHIFT)) -#define PHY_DLL_INCR_TRIM_1 (0x59 << (PHY_REG_SHIFT)) -#define PHY_DLL_INCR_TRIM_3 (0x5A << (PHY_REG_SHIFT)) -#define PHY_SCL_CONFIG_3 (0x5B << (PHY_REG_SHIFT)) -#define PHY_UNIQUIFY_TSMC_IO_1 (0x5C << (PHY_REG_SHIFT)) -#define PHY_SCL_START_ADDR (0x62 << (PHY_REG_SHIFT)) -#define PHY_IP_DQ_DQS_BITWISE_TRIM (0x65 << (PHY_REG_SHIFT)) -#define PHY_IP_DQ_DQS_BITWISE_TRIM_MASK \ - GENMASK(PHY_BITLVL_DLY_WIDTH - 1, 0) -#define PHY_IP_DQ_DQS_BITWISE_TRIM_INC \ - BIT(PHY_BITLVL_DLY_WIDTH) -#define PHY_IP_DQ_DQS_BITWISE_TRIM_OVERRIDE \ - BIT(PHY_BITLVL_DLY_WIDTH + 1) -#define PHY_DSCL_CNT (0x67 << (PHY_REG_SHIFT)) -#define PHY_OP_DQ_DM_DQS_BITWISE_TRIM (0x68 << (PHY_REG_SHIFT)) -#define PHY_OP_DQ_DM_DQS_BITWISE_TRIM_MASK \ - GENMASK(PHY_BITLVL_DLY_WIDTH - 1, 0) -#define PHY_OP_DQ_DM_DQS_BITWISE_TRIM_INC \ - BIT(PHY_BITLVL_DLY_WIDTH) -#define PHY_OP_DQ_DM_DQS_BITWISE_TRIM_OVERRIDE \ - BIT(PHY_BITLVL_DLY_WIDTH + 1) -#define PHY_DLL_TRIM_CLK (0x69 << (PHY_REG_SHIFT)) -#define PHY_DLL_TRIM_CLK_MASK GENMASK(PHY_SLV_DLY_WIDTH, 0) -#define PHY_DLL_TRIM_CLK_INCR BIT(PHY_SLV_DLY_WIDTH + 1) -#define PHY_DYNAMIC_BIT_LVL (0x6B << (PHY_REG_SHIFT)) -#define PHY_SCL_WINDOW_TRIM (0x6D << (PHY_REG_SHIFT)) -#define PHY_DISABLE_GATING_FOR_SCL (0x6E << (PHY_REG_SHIFT)) -#define PHY_SCL_CONFIG_4 (0x6F << (PHY_REG_SHIFT)) -#define PHY_DYNAMIC_WRITE_BIT_LVL (0x70 << (PHY_REG_SHIFT)) -#define PHY_VREF_TRAINING (0x72 << (PHY_REG_SHIFT)) -#define PHY_SCL_GATE_TIMING (0x78 << (PHY_REG_SHIFT)) - -#endif /* _DDRUQPHY_REGS_H */ diff --git a/arch/arm/mach-uniphier/dram/umc-ld11.c b/arch/arm/mach-uniphier/dram/umc-ld11.c deleted file mode 100644 index 9e2021a..0000000 --- a/arch/arm/mach-uniphier/dram/umc-ld11.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - */ - -#include -#include -#include -#include - -#include "../init.h" -#include "ddrphy-regs.h" -#include "umc64-regs.h" - -#define DDR_FREQ 1600 - -#define DRAM_CH_NR 2 -#define RANK_BLOCKS_TR 2 - -enum dram_freq { - DRAM_FREQ_1600M, - DRAM_FREQ_NR, -}; - -enum dram_size { - DRAM_SZ_256M, - DRAM_SZ_512M, - DRAM_SZ_NR, -}; - -/* PHY */ -static const int rof_pos_shift_pre[RANK_BLOCKS_TR][2] = { {0, 0}, {0, 0} }; -static const int rof_neg_shift_pre[RANK_BLOCKS_TR][2] = { {0, 0}, {0, 0} }; -static const int rof_pos_shift[RANK_BLOCKS_TR][2] = { {-35, -35}, {-35, -35} }; -static const int rof_neg_shift[RANK_BLOCKS_TR][2] = { {-17, -17}, {-17, -17} }; -static const int tof_shift[RANK_BLOCKS_TR][2] = { {-50, -50}, {-50, -50} }; - -/* Register address */ -#define PHY_ZQ0CR1 0x00000184 -#define PHY_ZQ1CR1 0x00000194 -#define PHY_ZQ2CR1 0x000001A4 -#define PHY_DX0GCR 0x000001C0 -#define PHY_DX0GTR 0x000001F0 -#define PHY_DX1GCR 0x00000200 -#define PHY_DX1GTR 0x00000230 -#define PHY_DX2GCR 0x00000240 -#define PHY_DX2GTR 0x00000270 -#define PHY_DX3GCR 0x00000280 -#define PHY_DX3GTR 0x000002B0 - -#define PHY_DXMDLR(dx) (0x000001EC + 0x40 * (dx)) -#define PHY_DXLCDLR0(dx) (0x000001E0 + 0x40 * (dx)) -#define PHY_DXLCDLR1(dx) (0x000001E4 + 0x40 * (dx)) -#define PHY_DXLCDLR2(dx) (0x000001E8 + 0x40 * (dx)) -#define PHY_DXBDLR1(dx) (0x000001D0 + 0x40 * (dx)) -#define PHY_DXBDLR2(dx) (0x000001D4 + 0x40 * (dx)) - -/* MASK */ -#define PHY_ACBD_MASK 0x00FC0000 -#define PHY_CK0BD_MASK 0x0000003F -#define PHY_CK1BD_MASK 0x00000FC0 -#define PHY_IPRD_MASK 0x000000FF -#define PHY_WLD_MASK(rank) (0xFF << (8 * (rank))) -#define PHY_DQSGD_MASK(rank) (0xFF << (8 * (rank))) -#define PHY_DQSGX_MASK BIT(6) -#define PHY_DSWBD_MASK 0x3F000000 /* bit[29:24] */ -#define PHY_DSDQOE_MASK 0x00000FFF - -static void ddrphy_maskwritel(u32 data, u32 mask, void __iomem *addr) -{ - u32 value; - - value = (readl(addr) & ~(mask)) | (data & mask); - writel(value, addr); -} - -static u32 ddrphy_maskreadl(u32 mask, void __iomem *addr) -{ - return readl(addr) & mask; -} - -/* step of 0.5T for PUB-byte */ -static u8 ddrphy_get_mdl(int dx, void __iomem *phy_base) -{ - return ddrphy_maskreadl(PHY_IPRD_MASK, phy_base + PHY_DXMDLR(dx)); -} - -/* Calculating step for PUB-byte */ -static int ddrphy_hpstep(int delay, int dx, void __iomem *phy_base) -{ - return delay * ddrphy_get_mdl(dx, phy_base) * DDR_FREQ / 1000000; -} - -static void ddrphy_vt_ctrl(void __iomem *phy_base, int enable) -{ - u32 tmp; - - tmp = readl(phy_base + PHY_PGCR1); - - if (enable) - tmp &= ~PHY_PGCR1_INHVT; - else - tmp |= PHY_PGCR1_INHVT; - - writel(tmp, phy_base + PHY_PGCR1); - - if (!enable) { - while (!(readl(phy_base + PHY_PGSR1) & PHY_PGSR1_VTSTOP)) - cpu_relax(); - } -} - -static void ddrphy_set_ckoffset_qoffset(int delay_ckoffset0, int delay_ckoffset1, - int delay_qoffset, int enable, - void __iomem *phy_base) -{ - u8 ck_step0, ck_step1; /* ckoffset_step for clock */ - u8 q_step; /* qoffset_step for clock */ - int dx; - - dx = 2; /* use dx2 in sLD11 */ - - ck_step0 = ddrphy_hpstep(delay_ckoffset0, dx, phy_base); /* CK-Offset */ - ck_step1 = ddrphy_hpstep(delay_ckoffset1, dx, phy_base); /* CK-Offset */ - q_step = ddrphy_hpstep(delay_qoffset, dx, phy_base); /* Q-Offset */ - - ddrphy_vt_ctrl(phy_base, 0); - - /* Q->[23:18], CK1->[11:6], CK0->bit[5:0] */ - if (enable == 1) - ddrphy_maskwritel((q_step << 18) + (ck_step1 << 6) + ck_step0, - PHY_ACBD_MASK | PHY_CK1BD_MASK | PHY_CK0BD_MASK, - phy_base + PHY_ACBDLR); - - ddrphy_vt_ctrl(phy_base, 1); -} - -static void ddrphy_set_wl_delay_dx(int dx, int r0_delay, int r1_delay, - int enable, void __iomem *phy_base) -{ - int rank; - int delay_wl[4]; - u32 wl_mask = 0; /* WriteLeveling's Mask */ - u32 wl_value = 0; /* WriteLeveling's Value */ - - delay_wl[0] = r0_delay & 0xfff; - delay_wl[1] = r1_delay & 0xfff; - delay_wl[2] = 0; - delay_wl[3] = 0; - - ddrphy_vt_ctrl(phy_base, 0); - - for (rank = 0; rank < 4; rank++) { - wl_mask |= PHY_WLD_MASK(rank); - /* WriteLeveling's delay */ - wl_value |= ddrphy_hpstep(delay_wl[rank], dx, phy_base) << (8 * rank); - } - - if (enable == 1) - ddrphy_maskwritel(wl_value, wl_mask, phy_base + PHY_DXLCDLR0(dx)); - - ddrphy_vt_ctrl(phy_base, 1); -} - -static void ddrphy_set_dqsg_delay_dx(int dx, int r0_delay, int r1_delay, - int enable, void __iomem *phy_base) -{ - int rank; - int delay_dqsg[4]; - u32 dqsg_mask = 0; /* DQSGating_LCDL_delay's Mask */ - u32 dqsg_value = 0; /* DQSGating_LCDL_delay's Value */ - - delay_dqsg[0] = r0_delay; - delay_dqsg[1] = r1_delay; - delay_dqsg[2] = 0; - delay_dqsg[3] = 0; - - ddrphy_vt_ctrl(phy_base, 0); - - for (rank = 0; rank < 4; rank++) { - dqsg_mask |= PHY_DQSGD_MASK(rank); - /* DQSGating's delay */ - dqsg_value |= ddrphy_hpstep(delay_dqsg[rank], dx, phy_base) << (8 * rank); - } - - if (enable == 1) - ddrphy_maskwritel(dqsg_value, dqsg_mask, phy_base + PHY_DXLCDLR2(dx)); - - ddrphy_vt_ctrl(phy_base, 1); -} - -static void ddrphy_set_dswb_delay_dx(int dx, int delay, int enable, void __iomem *phy_base) -{ - u8 dswb_step; - - ddrphy_vt_ctrl(phy_base, 0); - - dswb_step = ddrphy_hpstep(delay, dx, phy_base); /* DQS-BDL's delay */ - - if (enable == 1) - ddrphy_maskwritel(dswb_step << 24, PHY_DSWBD_MASK, phy_base + PHY_DXBDLR1(dx)); - - ddrphy_vt_ctrl(phy_base, 1); -} - -static void ddrphy_set_oe_delay_dx(int dx, int dqs_delay, int dq_delay, - int enable, void __iomem *phy_base) -{ - u8 dqs_oe_step, dq_oe_step; - u32 wdata; - - ddrphy_vt_ctrl(phy_base, 0); - - /* OE(DQS,DQ) */ - dqs_oe_step = ddrphy_hpstep(dqs_delay, dx, phy_base); /* DQS-oe's delay */ - dq_oe_step = ddrphy_hpstep(dq_delay, dx, phy_base); /* DQ-oe's delay */ - wdata = ((dq_oe_step<<6) + dqs_oe_step) & 0xFFF; - - if (enable == 1) - ddrphy_maskwritel(wdata, PHY_DSDQOE_MASK, phy_base + PHY_DXBDLR2(dx)); - - ddrphy_vt_ctrl(phy_base, 1); -} - -static void ddrphy_ext_dqsgt(void __iomem *phy_base) -{ - /* Extend DQSGating_window min:+1T max:+1T */ - ddrphy_maskwritel(PHY_DQSGX_MASK, PHY_DQSGX_MASK, phy_base + PHY_DSGCR); -} - -static void ddrphy_shift_tof_hws(void __iomem *phy_base, const int shift[][2]) -{ - int dx, block, byte; - u32 lcdlr1, wdqd; - - ddrphy_vt_ctrl(phy_base, 0); - - for (block = 0; block < RANK_BLOCKS_TR; block++) { - for (byte = 0; byte < 2; byte++) { - dx = block * 2 + byte; - lcdlr1 = readl(phy_base + PHY_DXLCDLR1(dx)); - wdqd = lcdlr1 & 0xff; - wdqd = clamp(wdqd + ddrphy_hpstep(shift[block][byte], dx, phy_base), - 0U, 0xffU); - lcdlr1 = (lcdlr1 & ~0xff) | wdqd; - writel(lcdlr1, phy_base + PHY_DXLCDLR1(dx)); - readl(phy_base + PHY_DXLCDLR1(dx)); /* relax */ - } - } - - ddrphy_vt_ctrl(phy_base, 1); -} - -static void ddrphy_shift_rof_hws(void __iomem *phy_base, const int pos_shift[][2], - const int neg_shift[][2]) -{ - int dx, block, byte; - u32 lcdlr1, rdqsd, rdqnsd; - - ddrphy_vt_ctrl(phy_base, 0); - - for (block = 0; block < RANK_BLOCKS_TR; block++) { - for (byte = 0; byte < 2; byte++) { - dx = block * 2 + byte; - lcdlr1 = readl(phy_base + PHY_DXLCDLR1(dx)); - - /* DQS LCDL RDQNSD->[23:16] RDQSD->[15:8] */ - rdqsd = (lcdlr1 >> 8) & 0xff; - rdqnsd = (lcdlr1 >> 16) & 0xff; - rdqsd = clamp(rdqsd + ddrphy_hpstep(pos_shift[block][byte], dx, phy_base), - 0U, 0xffU); - rdqnsd = clamp(rdqnsd + ddrphy_hpstep(neg_shift[block][byte], dx, phy_base), - 0U, 0xffU); - lcdlr1 = (lcdlr1 & ~(0xffff << 8)) | (rdqsd << 8) | (rdqnsd << 16); - writel(lcdlr1, phy_base + PHY_DXLCDLR1(dx)); - readl(phy_base + PHY_DXLCDLR1(dx)); /* relax */ - } - } - - ddrphy_vt_ctrl(phy_base, 1); -} - -static void ddrphy_boot_run_hws(void __iomem *phy_base) -{ - /* Hard Training for DIO */ - writel(0x0000f401, phy_base + PHY_PIR); - while (!(readl(phy_base + PHY_PGSR0) & PHY_PGSR0_IDONE)) - cpu_relax(); -} - -static void ddrphy_training(void __iomem *phy_base) -{ - /* DIO roffset shift before hard training */ - ddrphy_shift_rof_hws(phy_base, rof_pos_shift_pre, rof_neg_shift_pre); - - /* Hard Training for each CH */ - ddrphy_boot_run_hws(phy_base); - - /* DIO toffset shift after training */ - ddrphy_shift_tof_hws(phy_base, tof_shift); - - /* DIO roffset shift after training */ - ddrphy_shift_rof_hws(phy_base, rof_pos_shift, rof_neg_shift); - - /* Extend DQSGating window min:+1T max:+1T */ - ddrphy_ext_dqsgt(phy_base); -} - -static void ddrphy_init(void __iomem *phy_base, enum dram_freq freq) -{ - writel(0x40000000, phy_base + PHY_PIR); - writel(0x0300C4F1, phy_base + PHY_PGCR1); - writel(0x0C807D04, phy_base + PHY_PTR0); - writel(0x27100578, phy_base + PHY_PTR1); - writel(0x00083DEF, phy_base + PHY_PTR2); - writel(0x12061A80, phy_base + PHY_PTR3); - writel(0x08027100, phy_base + PHY_PTR4); - writel(0x9D9CBB66, phy_base + PHY_DTPR0); - writel(0x1a878400, phy_base + PHY_DTPR1); - writel(0x50025200, phy_base + PHY_DTPR2); - writel(0xF004641A, phy_base + PHY_DSGCR); - writel(0x0000040B, phy_base + PHY_DCR); - writel(0x00000d71, phy_base + PHY_MR0); - writel(0x00000006, phy_base + PHY_MR1); - writel(0x00000098, phy_base + PHY_MR2); - writel(0x00000000, phy_base + PHY_MR3); - - while (!(readl(phy_base + PHY_PGSR0) & PHY_PGSR0_IDONE)) - cpu_relax(); - - writel(0x00000059, phy_base + PHY_ZQ0CR1); - writel(0x00000019, phy_base + PHY_ZQ1CR1); - writel(0x00000019, phy_base + PHY_ZQ2CR1); - writel(0x30FC6C20, phy_base + PHY_PGCR2); - - ddrphy_set_ckoffset_qoffset(119, 0, 0, 1, phy_base); - ddrphy_set_wl_delay_dx(0, 220, 220, 1, phy_base); - ddrphy_set_wl_delay_dx(1, 160, 160, 1, phy_base); - ddrphy_set_wl_delay_dx(2, 190, 190, 1, phy_base); - ddrphy_set_wl_delay_dx(3, 150, 150, 1, phy_base); - ddrphy_set_dqsg_delay_dx(0, 750, 750, 1, phy_base); - ddrphy_set_dqsg_delay_dx(1, 750, 750, 1, phy_base); - ddrphy_set_dqsg_delay_dx(2, 750, 750, 1, phy_base); - ddrphy_set_dqsg_delay_dx(3, 750, 750, 1, phy_base); - ddrphy_set_dswb_delay_dx(0, 0, 1, phy_base); - ddrphy_set_dswb_delay_dx(1, 0, 1, phy_base); - ddrphy_set_dswb_delay_dx(2, 0, 1, phy_base); - ddrphy_set_dswb_delay_dx(3, 0, 1, phy_base); - ddrphy_set_oe_delay_dx(0, 0, 0, 1, phy_base); - ddrphy_set_oe_delay_dx(1, 0, 0, 1, phy_base); - ddrphy_set_oe_delay_dx(2, 0, 0, 1, phy_base); - ddrphy_set_oe_delay_dx(3, 0, 0, 1, phy_base); - - writel(0x44000E81, phy_base + PHY_DX0GCR); - writel(0x44000E81, phy_base + PHY_DX1GCR); - writel(0x44000E81, phy_base + PHY_DX2GCR); - writel(0x44000E81, phy_base + PHY_DX3GCR); - writel(0x00055002, phy_base + PHY_DX0GTR); - writel(0x00055002, phy_base + PHY_DX1GTR); - writel(0x00055010, phy_base + PHY_DX2GTR); - writel(0x00055010, phy_base + PHY_DX3GTR); - writel(0x930035C7, phy_base + PHY_DTCR); - writel(0x00000003, phy_base + PHY_PIR); - readl(phy_base + PHY_PIR); - while (!(readl(phy_base + PHY_PGSR0) & PHY_PGSR0_IDONE)) - cpu_relax(); - - writel(0x00000181, phy_base + PHY_PIR); - readl(phy_base + PHY_PIR); - while (!(readl(phy_base + PHY_PGSR0) & PHY_PGSR0_IDONE)) - cpu_relax(); - - writel(0x44181884, phy_base + PHY_DXCCR); - writel(0x00000001, phy_base + PHY_GPR1); -} - -/* UMC */ -static const u32 umc_cmdctla[DRAM_FREQ_NR] = {0x060B0B1C}; -static const u32 umc_cmdctlb[DRAM_FREQ_NR] = {0x27201806}; -static const u32 umc_cmdctlc[DRAM_FREQ_NR] = {0x00120B04}; -static const u32 umc_cmdctle[DRAM_FREQ_NR] = {0x00680607}; -static const u32 umc_cmdctlf[DRAM_FREQ_NR] = {0x02000200}; -static const u32 umc_cmdctlg[DRAM_FREQ_NR] = {0x08080808}; - -static const u32 umc_rdatactl[DRAM_FREQ_NR] = {0x00000810}; -static const u32 umc_wdatactl[DRAM_FREQ_NR] = {0x00000004}; -static const u32 umc_odtctl[DRAM_FREQ_NR] = {0x02000002}; -static const u32 umc_acssetb[DRAM_CH_NR] = {0x00000200, 0x00000203}; - -static const u32 umc_memconfch[DRAM_FREQ_NR] = {0x00023605}; - -static int umc_dc_init(void __iomem *dc_base, enum dram_freq freq, - unsigned long size, int ch) -{ - /* Wait for PHY Init Complete */ - writel(umc_cmdctla[freq], dc_base + UMC_CMDCTLA); - writel(umc_cmdctlb[freq], dc_base + UMC_CMDCTLB); - writel(umc_cmdctlc[freq], dc_base + UMC_CMDCTLC); - writel(umc_cmdctle[freq], dc_base + UMC_CMDCTLE); - writel(umc_cmdctlf[freq], dc_base + UMC_CMDCTLF); - writel(umc_cmdctlg[freq], dc_base + UMC_CMDCTLG); - - writel(umc_rdatactl[freq], dc_base + UMC_RDATACTL_D0); - writel(umc_rdatactl[freq], dc_base + UMC_RDATACTL_D1); - - writel(umc_wdatactl[freq], dc_base + UMC_WDATACTL_D0); - writel(umc_wdatactl[freq], dc_base + UMC_WDATACTL_D1); - - writel(umc_odtctl[freq], dc_base + UMC_ODTCTL_D0); - writel(umc_odtctl[freq], dc_base + UMC_ODTCTL_D1); - - writel(0x00000003, dc_base + UMC_ACSSETA); - writel(0x00000103, dc_base + UMC_FLOWCTLG); - writel(umc_acssetb[ch], dc_base + UMC_ACSSETB); - writel(0x02020200, dc_base + UMC_SPCSETB); - writel(umc_memconfch[freq], dc_base + UMC_MEMCONFCH); - writel(0x00000002, dc_base + UMC_ACFETCHCTRL); - - return 0; -} - -static int umc_ch_init(void __iomem *umc_ch_base, - enum dram_freq freq, unsigned long size, int ch) -{ - void __iomem *dc_base = umc_ch_base; - - return umc_dc_init(dc_base, freq, size, ch); -} - -static void um_init(void __iomem *um_base) -{ - writel(0x00000001, um_base + UMC_SIORST); - writel(0x00000001, um_base + UMC_VO0RST); - writel(0x00000001, um_base + UMC_VPERST); - writel(0x00000001, um_base + UMC_RGLRST); - writel(0x00000001, um_base + UMC_A2DRST); - writel(0x00000001, um_base + UMC_DMDRST); -} - -int uniphier_ld11_umc_init(const struct uniphier_board_data *bd) -{ - void __iomem *um_base = (void __iomem *)0x5B800000; - void __iomem *umc_ch_base = (void __iomem *)0x5BC00000; - void __iomem *phy_base = (void __iomem *)0x5BC01000; - enum dram_freq freq; - int ch, ret; - - switch (bd->dram_freq) { - case 1600: - freq = DRAM_FREQ_1600M; - break; - default: - pr_err("unsupported DRAM frequency %d MHz\n", bd->dram_freq); - return -EINVAL; - } - - writel(0x00000101, umc_ch_base + UMC_DIOCTLA); - while (!(readl(phy_base + PHY_PGSR0) & PHY_PGSR0_IDONE)) - cpu_relax(); - - writel(0x00000000, umc_ch_base + UMC_DIOCTLA); - writel(0x00000001, umc_ch_base + UMC_DEBUGC); - writel(0x00000101, umc_ch_base + UMC_DIOCTLA); - - writel(0x00000100, umc_ch_base + UMC_INITSET); - while (readl(umc_ch_base + UMC_INITSTAT) & BIT(8)) - cpu_relax(); - - writel(0x00000100, umc_ch_base + 0x00200000 + UMC_INITSET); - while (readl(umc_ch_base + 0x00200000 + UMC_INITSTAT) & BIT(8)) - cpu_relax(); - - ddrphy_init(phy_base, freq); - - for (ch = 0; ch < DRAM_CH_NR; ch++) { - unsigned long size = bd->dram_ch[ch].size; - unsigned int width = bd->dram_ch[ch].width; - - ret = umc_ch_init(umc_ch_base, freq, size / (width / 16), ch); - if (ret) { - pr_err("failed to initialize UMC ch%d\n", ch); - return ret; - } - - umc_ch_base += 0x00200000; - } - ddrphy_training(phy_base); - - um_init(um_base); - - return 0; -} diff --git a/arch/arm/mach-uniphier/dram/umc-ld20.c b/arch/arm/mach-uniphier/dram/umc-ld20.c deleted file mode 100644 index 500c1c1..0000000 --- a/arch/arm/mach-uniphier/dram/umc-ld20.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Copyright (C) 2016-2017 Socionext Inc. - * - * based on commit 5ffd75ecd4929f22361ef65a35f0331d2fbc0f35 of Diag - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "../init.h" -#include "ddruqphy-regs.h" -#include "umc64-regs.h" - -#define DRAM_CH_NR 3 - -enum dram_freq { - DRAM_FREQ_1866M, - DRAM_FREQ_NR, -}; - -enum dram_size { - DRAM_SZ_256M, - DRAM_SZ_512M, - DRAM_SZ_NR, -}; - -enum dram_board { /* board type */ - DRAM_BOARD_LD20_REF, /* LD20 reference */ - DRAM_BOARD_LD20_GLOBAL, /* LD20 TV */ - DRAM_BOARD_LD20_C1, /* LD20 TV C1 */ - DRAM_BOARD_LD21_REF, /* LD21 reference */ - DRAM_BOARD_LD21_GLOBAL, /* LD21 TV */ - DRAM_BOARD_NR, -}; - -/* PHY */ -static const int ddrphy_adrctrl[DRAM_BOARD_NR][DRAM_CH_NR] = { - {268 - 262, 268 - 263, 268 - 378}, /* LD20 reference */ - {268 - 262, 268 - 263, 268 - 378}, /* LD20 TV */ - {268 - 262, 268 - 263, 268 - 378}, /* LD20 TV C1 */ - {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 reference */ - {268 - 212, 268 - 268, /* No CH2 */}, /* LD21 TV */ -}; - -static const int ddrphy_dlltrimclk[DRAM_BOARD_NR][DRAM_CH_NR] = { - {268, 268, 268}, /* LD20 reference */ - {268, 268, 268}, /* LD20 TV */ - {189, 189, 189}, /* LD20 TV C1 */ - {268, 268 + 252, /* No CH2 */}, /* LD21 reference */ - {268, 268 + 202, /* No CH2 */}, /* LD21 TV */ -}; - -static const int ddrphy_dllrecalib[DRAM_BOARD_NR][DRAM_CH_NR] = { - {268 - 378, 268 - 263, 268 - 378}, /* LD20 reference */ - {268 - 378, 268 - 263, 268 - 378}, /* LD20 TV */ - {268 - 378, 268 - 263, 268 - 378}, /* LD20 TV C1 */ - {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 reference */ - {268 - 212, 268 - 536, /* No CH2 */}, /* LD21 TV */ -}; - -static const u32 ddrphy_phy_pad_ctrl[DRAM_BOARD_NR][DRAM_CH_NR] = { - {0x50B840B1, 0x50B840B1, 0x50B840B1}, /* LD20 reference */ - {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV */ - {0x50BB40B1, 0x50BB40B1, 0x50BB40B1}, /* LD20 TV C1 */ - {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 reference */ - {0x50BB40B4, 0x50B840B1, /* No CH2 */}, /* LD21 TV */ -}; - -static const u32 ddrphy_scl_gate_timing[DRAM_CH_NR] = { - 0x00000140, 0x00000180, 0x00000140 -}; - -static const short ddrphy_op_dq_shift_val_ld20[DRAM_CH_NR][32] = { - { - 2, 1, 0, 1, 2, 1, 1, 1, - 2, 1, 1, 2, 1, 1, 1, 1, - 1, 2, 1, 1, 1, 2, 1, 1, - 2, 2, 0, 1, 1, 2, 2, 1, - }, - { - 1, 1, 0, 1, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 1, 2, 1, 2, 1, - }, - { - 2, 2, 0, 2, 1, 1, 2, 1, - 1, 1, 0, 1, 1, -1, 1, 1, - 2, 2, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 0, 2, 2, 1, 2, - }, -}; - -static const short ddrphy_op_dq_shift_val_ld21[DRAM_CH_NR][32] = { - { - 1, 1, 0, 1, 1, 1, 1, 1, - 1, 0, 0, 0, 1, 1, 0, 2, - 1, 1, 0, 0, 1, 1, 1, 1, - 1, 0, 0, 0, 1, 0, 0, 1, - }, - { 1, 0, 2, 1, 1, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 0, 0, - 1, 0, 1, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 0, 1, 0, 0, - }, - /* No CH2 */ -}; - -static const short (* const ddrphy_op_dq_shift_val[DRAM_BOARD_NR])[32] = { - ddrphy_op_dq_shift_val_ld20, /* LD20 reference */ - ddrphy_op_dq_shift_val_ld20, /* LD20 TV */ - ddrphy_op_dq_shift_val_ld20, /* LD20 TV C */ - ddrphy_op_dq_shift_val_ld21, /* LD21 reference */ - ddrphy_op_dq_shift_val_ld21, /* LD21 TV */ -}; - -static const short ddrphy_ip_dq_shift_val_ld20[DRAM_CH_NR][32] = { - { - 3, 3, 3, 2, 3, 2, 0, 2, - 2, 3, 3, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 0, 1, 1, 1, - 2, 2, 2, 2, 3, 0, 2, 2, - }, - { - 2, 2, 1, 1, -1, 1, 1, 1, - 2, 0, 2, 2, 2, 1, 0, 2, - 2, 1, 2, 1, 0, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, - }, - { - 2, 2, 3, 2, 1, 2, 2, 2, - 2, 3, 4, 2, 3, 4, 3, 3, - 2, 2, 1, 2, 1, 1, 1, 1, - 2, 2, 2, 2, 1, 2, 2, 1, - }, -}; - -static const short ddrphy_ip_dq_shift_val_ld21[DRAM_CH_NR][32] = { - { - 2, 2, 2, 2, 1, 2, 2, 2, - 2, 3, 3, 2, 2, 2, 2, 2, - 2, 1, 2, 2, 1, 1, 1, 1, - 2, 2, 2, 3, 1, 2, 2, 2, - }, - { - 3, 4, 4, 1, 0, 1, 1, 1, - 1, 2, 1, 2, 2, 3, 3, 2, - 1, 0, 2, 1, 1, 0, 1, 0, - 0, 1, 0, 0, 1, 1, 0, 1, - }, - /* No CH2 */ -}; - -static const short (* const ddrphy_ip_dq_shift_val[DRAM_BOARD_NR])[32] = { - ddrphy_ip_dq_shift_val_ld20, /* LD20 reference */ - ddrphy_ip_dq_shift_val_ld20, /* LD20 TV */ - ddrphy_ip_dq_shift_val_ld20, /* LD20 TV C */ - ddrphy_ip_dq_shift_val_ld21, /* LD21 reference */ - ddrphy_ip_dq_shift_val_ld21, /* LD21 TV */ -}; - -static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane, - unsigned int bit) -{ - WARN_ON(lane >= 1 << PHY_LANE_SEL_LANE_WIDTH); - WARN_ON(bit >= 1 << PHY_LANE_SEL_BIT_WIDTH); - - writel((bit << PHY_LANE_SEL_BIT_SHIFT) | - (lane << PHY_LANE_SEL_LANE_SHIFT), - phy_base + PHY_LANE_SEL); -} - -#define DDRPHY_EFUSEMON (void *)0x5f900118 - -static void ddrphy_init(void __iomem *phy_base, enum dram_board board, int ch) -{ - writel(0x0C001001, phy_base + PHY_UNIQUIFY_TSMC_IO_1); - while (!(readl(phy_base + PHY_UNIQUIFY_TSMC_IO_1) & BIT(1))) - cpu_relax(); - - if (readl(DDRPHY_EFUSEMON) & BIT(ch)) - writel(0x00000000, phy_base + PHY_UNIQUIFY_TSMC_IO_1); - else - writel(0x0C001000, phy_base + PHY_UNIQUIFY_TSMC_IO_1); - - writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_3); - writel(0x00000000, phy_base + PHY_DLL_INCR_TRIM_1); - ddrphy_select_lane(phy_base, 0, 0); - writel(0x00000005, phy_base + PHY_DLL_TRIM_1); - writel(0x0000000a, phy_base + PHY_DLL_TRIM_3); - ddrphy_select_lane(phy_base, 6, 0); - writel(0x00000005, phy_base + PHY_DLL_TRIM_1); - writel(0x0000000a, phy_base + PHY_DLL_TRIM_3); - ddrphy_select_lane(phy_base, 12, 0); - writel(0x00000005, phy_base + PHY_DLL_TRIM_1); - writel(0x0000000a, phy_base + PHY_DLL_TRIM_3); - ddrphy_select_lane(phy_base, 18, 0); - writel(0x00000005, phy_base + PHY_DLL_TRIM_1); - writel(0x0000000a, phy_base + PHY_DLL_TRIM_3); - writel(0x00000001, phy_base + PHY_SCL_WINDOW_TRIM); - writel(0x00000000, phy_base + PHY_UNQ_ANALOG_DLL_1); - writel(ddrphy_phy_pad_ctrl[board][ch], phy_base + PHY_PAD_CTRL); - writel(0x00000070, phy_base + PHY_VREF_TRAINING); - writel(0x01000075, phy_base + PHY_SCL_CONFIG_1); - writel(0x00000501, phy_base + PHY_SCL_CONFIG_2); - writel(0x00000000, phy_base + PHY_SCL_CONFIG_3); - writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL); - writel(0x00000000, phy_base + PHY_SCL_CONFIG_4); - writel(ddrphy_scl_gate_timing[ch], phy_base + PHY_SCL_GATE_TIMING); - writel(0x02a000a0, phy_base + PHY_WRLVL_DYN_ODT); - writel(0x00840004, phy_base + PHY_WRLVL_ON_OFF); - writel(0x0000020d, phy_base + PHY_DLL_ADRCTRL); - ddrphy_select_lane(phy_base, 0, 0); - writel(0x0000008d, phy_base + PHY_DLL_TRIM_CLK); - writel(0xa800100d, phy_base + PHY_DLL_RECALIB); - writel(0x00005076, phy_base + PHY_SCL_LATENCY); -} - -static int ddrphy_to_dly_step(void __iomem *phy_base, unsigned int freq, - int delay) -{ - int mdl; - - mdl = (readl(phy_base + PHY_DLL_ADRCTRL) & PHY_DLL_ADRCTRL_MDL_MASK) >> - PHY_DLL_ADRCTRL_MDL_SHIFT; - - return DIV_ROUND_CLOSEST((long)freq * delay * mdl, 2 * 1000000L); -} - -static void ddrphy_set_delay(void __iomem *phy_base, unsigned int reg, - u32 mask, u32 incr, int dly_step) -{ - u32 tmp; - - tmp = readl(phy_base + reg); - tmp &= ~mask; - tmp |= min_t(u32, abs(dly_step), mask); - - if (dly_step >= 0) - tmp |= incr; - else - tmp &= ~incr; - - writel(tmp, phy_base + reg); -} - -static void ddrphy_set_dll_recalib(void __iomem *phy_base, int dly_step) -{ - ddrphy_set_delay(phy_base, PHY_DLL_RECALIB, - PHY_DLL_RECALIB_TRIM_MASK, PHY_DLL_RECALIB_INCR, - dly_step); -} - -static void ddrphy_set_dll_adrctrl(void __iomem *phy_base, int dly_step) -{ - ddrphy_set_delay(phy_base, PHY_DLL_ADRCTRL, - PHY_DLL_ADRCTRL_TRIM_MASK, PHY_DLL_ADRCTRL_INCR, - dly_step); -} - -static void ddrphy_set_dll_trim_clk(void __iomem *phy_base, int dly_step) -{ - ddrphy_select_lane(phy_base, 0, 0); - - ddrphy_set_delay(phy_base, PHY_DLL_TRIM_CLK, - PHY_DLL_TRIM_CLK_MASK, PHY_DLL_TRIM_CLK_INCR, - dly_step); -} - -static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board, - unsigned int freq, int ch) -{ - int step; - - step = ddrphy_to_dly_step(phy_base, freq, ddrphy_adrctrl[board][ch]); - ddrphy_set_dll_adrctrl(phy_base, step); - - step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dlltrimclk[board][ch]); - ddrphy_set_dll_trim_clk(phy_base, step); - - step = ddrphy_to_dly_step(phy_base, freq, ddrphy_dllrecalib[board][ch]); - ddrphy_set_dll_recalib(phy_base, step); -} - -static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg, - u32 mask, u32 incr, short shift_val) -{ - u32 tmp; - int val; - - tmp = readl(phy_base + reg); - - val = tmp & mask; - if (!(tmp & incr)) - val = -val; - - val += shift_val; - - tmp &= ~(incr | mask); - tmp |= min_t(u32, abs(val), mask); - if (val >= 0) - tmp |= incr; - - writel(tmp, phy_base + reg); -} - -static void ddrphy_shift_dq(void __iomem *phy_base, unsigned int reg, - u32 mask, u32 incr, u32 override, - const short *shift_val_array) -{ - u32 tmp; - int dx, bit; - - tmp = readl(phy_base + reg); - tmp |= override; - writel(tmp, phy_base + reg); - - for (dx = 0; dx < 4; dx++) { - for (bit = 0; bit < 8; bit++) { - ddrphy_select_lane(phy_base, - (PHY_BITLVL_DLY_WIDTH + 1) * dx, - bit); - - ddrphy_shift_one_dq(phy_base, reg, mask, incr, - shift_val_array[dx * 8 + bit]); - } - } - - ddrphy_select_lane(phy_base, 0, 0); -} - -static int ddrphy_training(void __iomem *phy_base, enum dram_board board, - int ch) -{ - writel(0x0000000f, phy_base + PHY_WRLVL_AUTOINC_TRIM); - writel(0x00010000, phy_base + PHY_DLL_TRIM_2); - writel(0x50000000, phy_base + PHY_SCL_START); - - while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE) - cpu_relax(); - - writel(0x00000000, phy_base + PHY_DISABLE_GATING_FOR_SCL); - writel(0xff00ff00, phy_base + PHY_SCL_DATA_0); - writel(0xff00ff00, phy_base + PHY_SCL_DATA_1); - writel(0xFBF8FFFF, phy_base + PHY_SCL_START_ADDR); - writel(0x11000000, phy_base + PHY_SCL_START); - - while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE) - cpu_relax(); - - writel(0xFBF0FFFF, phy_base + PHY_SCL_START_ADDR); - writel(0x30500000, phy_base + PHY_SCL_START); - - while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE) - cpu_relax(); - - writel(0x00000001, phy_base + PHY_DISABLE_GATING_FOR_SCL); - writel(0x00000010, phy_base + PHY_SCL_MAIN_CLK_DELTA); - writel(0x789b3de0, phy_base + PHY_SCL_DATA_0); - writel(0xf10e4a56, phy_base + PHY_SCL_DATA_1); - writel(0x11000000, phy_base + PHY_SCL_START); - - while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE) - cpu_relax(); - - writel(0x34000000, phy_base + PHY_SCL_START); - - while (readl(phy_base + PHY_SCL_START) & PHY_SCL_START_GO_DONE) - cpu_relax(); - - writel(0x00000003, phy_base + PHY_DISABLE_GATING_FOR_SCL); - - writel(0x000261c0, phy_base + PHY_DYNAMIC_WRITE_BIT_LVL); - writel(0x00003270, phy_base + PHY_DYNAMIC_BIT_LVL); - writel(0x011BD0C4, phy_base + PHY_DSCL_CNT); - - /* shift ip_dq trim */ - ddrphy_shift_dq(phy_base, - PHY_IP_DQ_DQS_BITWISE_TRIM, - PHY_IP_DQ_DQS_BITWISE_TRIM_MASK, - PHY_IP_DQ_DQS_BITWISE_TRIM_INC, - PHY_IP_DQ_DQS_BITWISE_TRIM_OVERRIDE, - ddrphy_ip_dq_shift_val[board][ch]); - - /* shift op_dq trim */ - ddrphy_shift_dq(phy_base, - PHY_OP_DQ_DM_DQS_BITWISE_TRIM, - PHY_OP_DQ_DM_DQS_BITWISE_TRIM_MASK, - PHY_OP_DQ_DM_DQS_BITWISE_TRIM_INC, - PHY_OP_DQ_DM_DQS_BITWISE_TRIM_OVERRIDE, - ddrphy_op_dq_shift_val[board][ch]); - - return 0; -} - -/* UMC */ -static const u32 umc_initctla[DRAM_FREQ_NR] = {0x71016D11}; -static const u32 umc_initctlb[DRAM_FREQ_NR] = {0x07E390AC}; -static const u32 umc_initctlc[DRAM_FREQ_NR] = {0x00FF00FF}; -static const u32 umc_drmmr0[DRAM_FREQ_NR] = {0x00000114}; -static const u32 umc_drmmr2[DRAM_FREQ_NR] = {0x000002a0}; - -static const u32 umc_memconf0a[DRAM_FREQ_NR][DRAM_SZ_NR] = { - /* 256MB 512MB */ - {0x00000601, 0x00000801}, /* 1866 MHz */ -}; - -static const u32 umc_memconf0b[DRAM_FREQ_NR][DRAM_SZ_NR] = { - /* 256MB 512MB */ - {0x00000120, 0x00000130}, /* 1866 MHz */ -}; - -static const u32 umc_memconfch[DRAM_FREQ_NR][DRAM_SZ_NR] = { - /* 256MB 512MB */ - {0x00033603, 0x00033803}, /* 1866 MHz */ -}; - -static const u32 umc_cmdctla[DRAM_FREQ_NR] = {0x060D0D20}; -static const u32 umc_cmdctlb[DRAM_FREQ_NR] = {0x2D211C08}; -static const u32 umc_cmdctlc[DRAM_FREQ_NR] = {0x00150C04}; -static const u32 umc_cmdctle[DRAM_FREQ_NR][DRAM_SZ_NR] = { - /* 256MB 512MB */ - {0x0049071D, 0x0078071D}, /* 1866 MHz */ -}; - -static const u32 umc_rdatactl[DRAM_FREQ_NR] = {0x00000610}; -static const u32 umc_wdatactl[DRAM_FREQ_NR] = {0x00000204}; -static const u32 umc_odtctl[DRAM_FREQ_NR] = {0x02000002}; -static const u32 umc_dataset[DRAM_FREQ_NR] = {0x04000000}; - -static const u32 umc_flowctla[DRAM_FREQ_NR] = {0x0081E01E}; -static const u32 umc_directbusctrla[DRAM_CH_NR] = { - 0x00000000, 0x00000001, 0x00000001 -}; - -static void umc_poll_phy_init_complete(void __iomem *dc_base) -{ - /* Wait for PHY Init Complete */ - while (!(readl(dc_base + UMC_DFISTCTLC) & BIT(0))) - cpu_relax(); -} - -static int umc_dc_init(void __iomem *dc_base, unsigned int freq, - unsigned long size, int ch) -{ - enum dram_freq freq_e; - enum dram_size size_e; - - switch (freq) { - case 1866: - freq_e = DRAM_FREQ_1866M; - break; - default: - pr_err("unsupported DRAM frequency %ud MHz\n", freq); - return -EINVAL; - } - - switch (size) { - case 0: - return 0; - case SZ_256M: - size_e = DRAM_SZ_256M; - break; - case SZ_512M: - size_e = DRAM_SZ_512M; - break; - default: - pr_err("unsupported DRAM size 0x%08lx (per 16bit) for ch%d\n", - size, ch); - return -EINVAL; - } - - writel(0x00000001, dc_base + UMC_DFICSOVRRD); - writel(0x00000000, dc_base + UMC_DFITURNOFF); - - writel(umc_initctla[freq_e], dc_base + UMC_INITCTLA); - writel(umc_initctlb[freq_e], dc_base + UMC_INITCTLB); - writel(umc_initctlc[freq_e], dc_base + UMC_INITCTLC); - - writel(umc_drmmr0[freq_e], dc_base + UMC_DRMMR0); - writel(0x00000004, dc_base + UMC_DRMMR1); - writel(umc_drmmr2[freq_e], dc_base + UMC_DRMMR2); - writel(0x00000000, dc_base + UMC_DRMMR3); - - writel(umc_memconf0a[freq_e][size_e], dc_base + UMC_MEMCONF0A); - writel(umc_memconf0b[freq_e][size_e], dc_base + UMC_MEMCONF0B); - writel(umc_memconfch[freq_e][size_e], dc_base + UMC_MEMCONFCH); - writel(0x00000000, dc_base + UMC_MEMMAPSET); - - writel(umc_cmdctla[freq_e], dc_base + UMC_CMDCTLA); - writel(umc_cmdctlb[freq_e], dc_base + UMC_CMDCTLB); - writel(umc_cmdctlc[freq_e], dc_base + UMC_CMDCTLC); - writel(umc_cmdctle[freq_e][size_e], dc_base + UMC_CMDCTLE); - - writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D0); - writel(umc_rdatactl[freq_e], dc_base + UMC_RDATACTL_D1); - - writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D0); - writel(umc_wdatactl[freq_e], dc_base + UMC_WDATACTL_D1); - writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D0); - writel(umc_odtctl[freq_e], dc_base + UMC_ODTCTL_D1); - writel(umc_dataset[freq_e], dc_base + UMC_DATASET); - - writel(0x00400020, dc_base + UMC_DCCGCTL); - writel(0x00000003, dc_base + UMC_ACSSETA); - writel(0x00000103, dc_base + UMC_FLOWCTLG); - writel(0x00010200, dc_base + UMC_ACSSETB); - - writel(umc_flowctla[freq_e], dc_base + UMC_FLOWCTLA); - writel(0x00004444, dc_base + UMC_FLOWCTLC); - writel(0x00000000, dc_base + UMC_DFICUPDCTLA); - - writel(0x00202000, dc_base + UMC_FLOWCTLB); - writel(0x00000000, dc_base + UMC_BSICMAPSET); - writel(0x00000000, dc_base + UMC_ERRMASKA); - writel(0x00000000, dc_base + UMC_ERRMASKB); - - writel(umc_directbusctrla[ch], dc_base + UMC_DIRECTBUSCTRLA); - - writel(0x00000001, dc_base + UMC_INITSET); - /* Wait for PHY Init Complete */ - while (readl(dc_base + UMC_INITSTAT) & BIT(0)) - cpu_relax(); - - writel(0x2A0A0A00, dc_base + UMC_SPCSETB); - writel(0x00000000, dc_base + UMC_DFICSOVRRD); - - return 0; -} - -static int umc_ch_init(void __iomem *umc_ch_base, void __iomem *phy_ch_base, - enum dram_board board, unsigned int freq, - unsigned long size, int ch) -{ - void __iomem *dc_base = umc_ch_base + 0x00011000; - void __iomem *phy_base = phy_ch_base; - int ret; - - /* PHY Update Mode (ON) */ - writel(0x8000003f, dc_base + UMC_DFIPUPDCTLA); - - /* deassert PHY reset signals */ - writel(UMC_DIOCTLA_CTL_NRST | UMC_DIOCTLA_CFG_NRST, - dc_base + UMC_DIOCTLA); - - ddrphy_init(phy_base, board, ch); - - umc_poll_phy_init_complete(dc_base); - - ddrphy_init_tail(phy_base, board, freq, ch); - - ret = umc_dc_init(dc_base, freq, size, ch); - if (ret) - return ret; - - ret = ddrphy_training(phy_base, board, ch); - if (ret) - return ret; - - return 0; -} - -static void um_init(void __iomem *um_base) -{ - writel(0x000000ff, um_base + UMC_MBUS0); - writel(0x000000ff, um_base + UMC_MBUS1); - writel(0x000000ff, um_base + UMC_MBUS2); - writel(0x00000001, um_base + UMC_MBUS3); - writel(0x00000001, um_base + UMC_MBUS4); - writel(0x00000001, um_base + UMC_MBUS5); - writel(0x00000001, um_base + UMC_MBUS6); - writel(0x00000001, um_base + UMC_MBUS7); - writel(0x00000001, um_base + UMC_MBUS8); - writel(0x00000001, um_base + UMC_MBUS9); - writel(0x00000001, um_base + UMC_MBUS10); -} - -int uniphier_ld20_umc_init(const struct uniphier_board_data *bd) -{ - void __iomem *um_base = (void __iomem *)0x5b600000; - void __iomem *umc_ch_base = (void __iomem *)0x5b800000; - void __iomem *phy_ch_base = (void __iomem *)0x6e200000; - enum dram_board board; - int ch, ret; - - switch (UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)) { - case UNIPHIER_BD_BOARD_LD20_REF: - board = DRAM_BOARD_LD20_REF; - break; - case UNIPHIER_BD_BOARD_LD20_GLOBAL: - board = DRAM_BOARD_LD20_GLOBAL; - break; - case UNIPHIER_BD_BOARD_LD20_C1: - board = DRAM_BOARD_LD20_C1; - break; - case UNIPHIER_BD_BOARD_LD21_REF: - board = DRAM_BOARD_LD21_REF; - break; - case UNIPHIER_BD_BOARD_LD21_GLOBAL: - board = DRAM_BOARD_LD21_GLOBAL; - break; - default: - pr_err("unsupported board type %d\n", - UNIPHIER_BD_BOARD_GET_TYPE(bd->flags)); - return -EINVAL; - } - - for (ch = 0; ch < DRAM_CH_NR; ch++) { - unsigned long size = bd->dram_ch[ch].size; - unsigned int width = bd->dram_ch[ch].width; - - if (size) { - ret = umc_ch_init(umc_ch_base, phy_ch_base, board, - bd->dram_freq, size / (width / 16), - ch); - if (ret) { - pr_err("failed to initialize UMC ch%d\n", ch); - return ret; - } - } - - umc_ch_base += 0x00200000; - phy_ch_base += 0x00004000; - } - - um_init(um_base); - - return 0; -} diff --git a/arch/arm/mach-uniphier/dram/umc64-regs.h b/arch/arm/mach-uniphier/dram/umc64-regs.h deleted file mode 100644 index 860d04e..0000000 --- a/arch/arm/mach-uniphier/dram/umc64-regs.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2016 Socionext Inc. - */ - -#ifndef UMC_LD20_REGS_H -#define UMC_LD20_REGS_H - -#define UMC_CMDCTLA 0x00000000 -#define UMC_CMDCTLB 0x00000004 -#define UMC_CMDCTLC 0x00000008 -#define UMC_INITCTLA 0x00000020 -#define UMC_INITCTLB 0x00000024 -#define UMC_INITCTLC 0x00000028 -#define UMC_DRMMR0 0x00000030 -#define UMC_DRMMR1 0x00000034 -#define UMC_DRMMR2 0x00000038 -#define UMC_DRMMR3 0x0000003C -#define UMC_INITSET 0x00000040 -#define UMC_INITSTAT 0x00000044 -#define UMC_CMDCTLE 0x00000050 -#define UMC_CMDCTLF 0x00000054 -#define UMC_CMDCTLG 0x00000058 -#define UMC_SPCSETB 0x00000084 -#define UMC_SPCSETB_AREFMD_MASK (0x3) /* Auto Refresh Mode */ -#define UMC_SPCSETB_AREFMD_ARB (0x0) /* control by arbitor */ -#define UMC_SPCSETB_AREFMD_CONT (0x1) /* control by DRAMCONT */ -#define UMC_SPCSETB_AREFMD_REG (0x2) /* control by register */ -#define UMC_ACSSETA 0x000000C0 -#define UMC_ACSSETB 0x000000C4 -#define UMC_MEMCONF0A 0x00000200 -#define UMC_MEMCONF0B 0x00000204 -#define UMC_MEMCONFCH 0x00000240 -#define UMC_MEMMAPSET 0x00000250 -#define UMC_FLOWCTLA 0x00000400 -#define UMC_FLOWCTLB 0x00000404 -#define UMC_FLOWCTLC 0x00000408 -#define UMC_ACFETCHCTRL 0x00000460 -#define UMC_FLOWCTLG 0x00000508 -#define UMC_RDATACTL_D0 0x00000600 -#define UMC_WDATACTL_D0 0x00000604 -#define UMC_RDATACTL_D1 0x00000608 -#define UMC_WDATACTL_D1 0x0000060C -#define UMC_DATASET 0x00000610 -#define UMC_ODTCTL_D0 0x00000618 -#define UMC_ODTCTL_D1 0x0000061C -#define UMC_RESPCTL 0x00000624 -#define UMC_DIRECTBUSCTRLA 0x00000680 -#define UMC_DEBUGC 0x00000718 -#define UMC_DCCGCTL 0x00000720 -#define UMC_DICGCTLA 0x00000724 -#define UMC_DICGCTLB 0x00000728 -#define UMC_ERRMASKA 0x00000958 -#define UMC_ERRMASKB 0x0000095C -#define UMC_BSICMAPSET 0x00000988 -#define UMC_DIOCTLA 0x00000C00 -#define UMC_DIOCTLA_CTL_NRST BIT(8) /* ctl_rst_n */ -#define UMC_DIOCTLA_CFG_NRST BIT(0) /* cfg_rst_n */ -#define UMC_DFISTCTLC 0x00000C18 -#define UMC_DFICUPDCTLA 0x00000C20 -#define UMC_DFIPUPDCTLA 0x00000C30 -#define UMC_DFICSOVRRD 0x00000C84 -#define UMC_DFITURNOFF 0x00000C88 - -/* UM registers */ -#define UMC_MBUS0 0x00080004 -#define UMC_MBUS1 0x00081004 -#define UMC_MBUS2 0x00082004 -#define UMC_MBUS3 0x00000C78 -#define UMC_MBUS4 0x00000CF8 -#define UMC_MBUS5 0x00000E78 -#define UMC_MBUS6 0x00000EF8 -#define UMC_MBUS7 0x00001278 -#define UMC_MBUS8 0x000012F8 -#define UMC_MBUS9 0x00002478 -#define UMC_MBUS10 0x000024F8 - -/* UMC1 register */ -#define UMC_SIORST 0x00000728 -#define UMC_VO0RST 0x0000073c -#define UMC_VPERST 0x00000744 -#define UMC_RGLRST 0x00000750 -#define UMC_A2DRST 0x00000764 -#define UMC_DMDRST 0x00000770 - -#endif /* UMC_LD20_REGS_H */ diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h index 56f514e..b322628 100644 --- a/arch/arm/mach-uniphier/init.h +++ b/arch/arm/mach-uniphier/init.h @@ -24,13 +24,6 @@ struct uniphier_board_data { #define UNIPHIER_BD_DRAM_SPARSE BIT(9) #define UNIPHIER_BD_DDR3PLUS BIT(8) - -#define UNIPHIER_BD_BOARD_GET_TYPE(f) ((f) & 0x7) -#define UNIPHIER_BD_BOARD_LD20_REF 0 /* LD20 reference */ -#define UNIPHIER_BD_BOARD_LD20_GLOBAL 1 /* LD20 TV Set */ -#define UNIPHIER_BD_BOARD_LD20_C1 2 /* LD20 TV Set C1 */ -#define UNIPHIER_BD_BOARD_LD21_REF 3 /* LD21 reference */ -#define UNIPHIER_BD_BOARD_LD21_GLOBAL 4 /* LD21 TV Set */ }; const struct uniphier_board_data *uniphier_get_board_param(void); @@ -41,8 +34,6 @@ int uniphier_pro4_init(const struct uniphier_board_data *bd); int uniphier_sld8_init(const struct uniphier_board_data *bd); int uniphier_pro5_init(const struct uniphier_board_data *bd); int uniphier_pxs2_init(const struct uniphier_board_data *bd); -int uniphier_ld11_init(const struct uniphier_board_data *bd); -int uniphier_ld20_init(const struct uniphier_board_data *bd); #if defined(CONFIG_MICRO_SUPPORT_CARD) void uniphier_sbc_init_admulti(void); @@ -85,17 +76,12 @@ int uniphier_pro4_dpll_init(const struct uniphier_board_data *bd); int uniphier_sld8_dpll_init(const struct uniphier_board_data *bd); int uniphier_pro5_dpll_init(const struct uniphier_board_data *bd); int uniphier_pxs2_dpll_init(const struct uniphier_board_data *bd); -int uniphier_ld11_dpll_init(const struct uniphier_board_data *bd); -int uniphier_ld20_dpll_init(const struct uniphier_board_data *bd); void uniphier_sld3_early_clk_init(void); -void uniphier_ld11_early_clk_init(void); void uniphier_sld3_dram_clk_init(void); void uniphier_pro5_dram_clk_init(void); void uniphier_pxs2_dram_clk_init(void); -void uniphier_ld11_dram_clk_init(void); -void uniphier_ld20_dram_clk_init(void); int uniphier_sld3_umc_init(const struct uniphier_board_data *bd); int uniphier_ld4_umc_init(const struct uniphier_board_data *bd); @@ -103,8 +89,6 @@ int uniphier_pro4_umc_init(const struct uniphier_board_data *bd); int uniphier_sld8_umc_init(const struct uniphier_board_data *bd); int uniphier_pro5_umc_init(const struct uniphier_board_data *bd); int uniphier_pxs2_umc_init(const struct uniphier_board_data *bd); -int uniphier_ld20_umc_init(const struct uniphier_board_data *bd); -int uniphier_ld11_umc_init(const struct uniphier_board_data *bd); void uniphier_sld3_pll_init(void); void uniphier_ld4_pll_init(void); @@ -125,8 +109,6 @@ unsigned int uniphier_boot_device_raw(void); int uniphier_have_internal_stm(void); int uniphier_boot_from_backend(void); int uniphier_pin_init(const char *pinconfig_name); -void uniphier_smp_kick_all_cpus(void); -void cci500_init(unsigned int nr_slaves); #undef pr_warn #define pr_warn(fmt, args...) printf(fmt, ##args) diff --git a/arch/arm/mach-uniphier/spl_board_init.c b/arch/arm/mach-uniphier/spl_board_init.c index 0079a08..6da5631 100644 --- a/arch/arm/mach-uniphier/spl_board_init.c +++ b/arch/arm/mach-uniphier/spl_board_init.c @@ -97,26 +97,6 @@ static const struct uniphier_spl_initdata uniphier_spl_initdata[] = { .umc_init = uniphier_pxs2_umc_init, }, #endif -#if defined(CONFIG_ARCH_UNIPHIER_LD11) - { - .soc_id = UNIPHIER_LD11_ID, - .early_clk_init = uniphier_ld11_early_clk_init, - .dpll_init = uniphier_ld11_dpll_init, - .memconf_init = uniphier_memconf_2ch_init, - .dram_clk_init = uniphier_ld11_dram_clk_init, - .umc_init = uniphier_ld11_umc_init, - }, -#endif -#if defined(CONFIG_ARCH_UNIPHIER_LD20) - { - .soc_id = UNIPHIER_LD20_ID, - .early_clk_init = uniphier_ld11_early_clk_init, - .dpll_init = uniphier_ld20_dpll_init, - .memconf_init = uniphier_memconf_3ch_init, - .dram_clk_init = uniphier_ld20_dram_clk_init, - .umc_init = uniphier_ld20_umc_init, - }, -#endif }; UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_spl_initdata, uniphier_spl_initdata) @@ -141,10 +121,8 @@ void spl_board_init(void) if (initdata->bcu_init) initdata->bcu_init(bd); - initdata->early_clk_init(); - #ifdef CONFIG_SPL_SERIAL_SUPPORT preloader_console_init(); #endif @@ -168,8 +146,4 @@ void spl_board_init(void) pr_err("failed to init DRAM\n"); hang(); } - -#ifdef CONFIG_ARM64 - dcache_disable(); -#endif } diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 79dc0cf..baf4f51 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -31,8 +31,8 @@ _start: mts rshr, r1 addi r1, r1, -4 /* Decrement SP to top of memory */ #else -#if defined(CONFIG_SYS_MALLOC_F_LEN) - addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET - CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) + addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET - CONFIG_VAL(SYS_MALLOC_F_LEN) #else addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET #endif @@ -162,14 +162,14 @@ clear_bss: #ifndef CONFIG_SPL_BUILD or r5, r0, r0 /* flags - empty */ addi r31, r0, _gd -#if defined(CONFIG_SYS_MALLOC_F_LEN) +#if CONFIG_VAL(SYS_MALLOC_F_LEN) addi r6, r0, CONFIG_SYS_INIT_SP_OFFSET swi r6, r31, GD_MALLOC_BASE #endif brai board_init_f #else addi r31, r0, _gd -#if defined(CONFIG_SYS_MALLOC_F_LEN) +#if CONFIG_VAL(SYS_MALLOC_F_LEN) addi r6, r0, CONFIG_SPL_STACK_ADDR swi r6, r31, GD_MALLOC_BASE #endif diff --git a/arch/mips/Makefile.postlink b/arch/mips/Makefile.postlink new file mode 100644 index 0000000..7da3acd --- /dev/null +++ b/arch/mips/Makefile.postlink @@ -0,0 +1,23 @@ +# +# Copyright (c) 2017 Imagination Technologies Ltd. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PHONY := __archpost +__archpost: + +-include include/config/auto.conf +include scripts/Kbuild.include + +CMD_RELOCS = tools/mips-relocs +quiet_cmd_relocs = RELOCS $@ + cmd_relocs = $(CMD_RELOCS) $@ + +u-boot: FORCE + @true + $(call if_changed,relocs) + +.PHONY: FORCE + +FORCE: diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 2c72c15..cefdbe6 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -56,25 +56,14 @@ PLATFORM_ELFFLAGS += -B mips $(OBJCOPYFLAGS) # LDFLAGS_vmlinux += -G 0 -static -n -nostdlib # MODFLAGS += -mlong-calls # -# On the other hand, we want PIC in the U-Boot code to relocate it from ROM -# to RAM. $28 is always used as gp. -# -ifdef CONFIG_SPL_BUILD -PF_ABICALLS := -mno-abicalls -PF_PIC := -fno-pic -PF_PIE := -else -PF_ABICALLS := -mabicalls -PF_PIC := -fpic -PF_PIE := -pie -PF_OBJCOPY := -j .got -j .rel.dyn -j .padding -PF_OBJCOPY += -j .dtb.init.rodata +ifndef CONFIG_SPL_BUILD +OBJCOPYFLAGS += -j .got -j .rel -j .padding -j .dtb.init.rodata +LDFLAGS_FINAL += --emit-relocs endif -PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) +PLATFORM_CPPFLAGS += -G 0 -mno-abicalls -fno-pic PLATFORM_CPPFLAGS += -msoft-float PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections -LDFLAGS_FINAL += --gc-sections $(PF_PIE) +LDFLAGS_FINAL += --gc-sections OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -OBJCOPYFLAGS += $(PF_OBJCOPY) diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index d01ee9f..42af9de 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -60,8 +60,8 @@ sp, sp, GD_SIZE # reserve space for gd and sp, sp, t0 # force 16 byte alignment move k0, sp # save gd pointer -#ifdef CONFIG_SYS_MALLOC_F_LEN - li t2, CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) + li t2, CONFIG_VAL(SYS_MALLOC_F_LEN) PTR_SUBU \ sp, sp, t2 # reserve space for early malloc and sp, sp, t0 # force 16 byte alignment @@ -75,7 +75,7 @@ blt t0, t1, 1b PTR_ADDIU t0, PTRSIZE -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset #endif .endm @@ -221,18 +221,6 @@ wr_done: ehb #endif - /* - * Initialize $gp, force pointer sized alignment of bal instruction to - * forbid the compiler to put nop's between bal and _gp. This is - * required to keep _gp and ra aligned to 8 byte. - */ - .align PTRLOG - bal 1f - nop - PTR _gp -1: - PTR_L gp, 0(ra) - #ifdef CONFIG_MIPS_CM PTR_LA t9, mips_cm_map jalr t9 @@ -291,121 +279,3 @@ wr_done: move ra, zero END(_start) - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM - * after relocating the monitor code. - * - * a0 = addr_sp - * a1 = gd - * a2 = destination address - */ -ENTRY(relocate_code) - move sp, a0 # set new stack pointer - move fp, sp - - move s0, a1 # save gd in s0 - move s2, a2 # save destination address in s2 - - PTR_LI t0, CONFIG_SYS_MONITOR_BASE - PTR_SUB s1, s2, t0 # s1 <-- relocation offset - - PTR_LA t2, __image_copy_end - move t1, a2 - - /* - * t0 = source address - * t1 = target address - * t2 = source end address - */ -1: - PTR_L t3, 0(t0) - PTR_S t3, 0(t1) - PTR_ADDU t0, PTRSIZE - blt t0, t2, 1b - PTR_ADDU t1, PTRSIZE - - /* - * Now we want to update GOT. - * - * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object - * generated by GNU ld. Skip these reserved entries from relocation. - */ - PTR_LA t3, num_got_entries - PTR_LA t8, _GLOBAL_OFFSET_TABLE_ - PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_ - PTR_ADDIU t8, t8, 2 * PTRSIZE # skipping first two entries - PTR_LI t2, 2 -1: - PTR_L t1, 0(t8) - beqz t1, 2f - PTR_ADD t1, s1 - PTR_S t1, 0(t8) -2: - PTR_ADDIU t2, 1 - blt t2, t3, 1b - PTR_ADDIU t8, PTRSIZE - - /* Update dynamic relocations */ - PTR_LA t1, __rel_dyn_start - PTR_LA t2, __rel_dyn_end - - b 2f # skip first reserved entry - PTR_ADDIU t1, 2 * PTRSIZE - -1: - lw t8, -4(t1) # t8 <-- relocation info - - PTR_LI t3, MIPS_RELOC - bne t8, t3, 2f # skip non-MIPS_RELOC entries - nop - - PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH - - PTR_L t8, 0(t3) # t8 <-- original pointer - PTR_ADD t8, s1 # t8 <-- adjusted pointer - - PTR_ADD t3, s1 # t3 <-- location to fix up in RAM - PTR_S t8, 0(t3) - -2: - blt t1, t2, 1b - PTR_ADDIU t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes - - /* - * Flush caches to ensure our newly modified instructions are visible - * to the instruction cache. We're still running with the old GOT, so - * apply the reloc offset to the start address. - */ - PTR_LA a0, __text_start - PTR_LA a1, __text_end - PTR_SUB a1, a1, a0 - PTR_LA t9, flush_cache - jalr t9 - PTR_ADD a0, s1 - - PTR_ADD gp, s1 # adjust gp - - /* - * Clear BSS - * - * GOT is now relocated. Thus __bss_start and __bss_end can be - * accessed directly via $gp. - */ - PTR_LA t1, __bss_start # t1 <-- __bss_start - PTR_LA t2, __bss_end # t2 <-- __bss_end - -1: - PTR_S zero, 0(t1) - blt t1, t2, 1b - PTR_ADDIU t1, PTRSIZE - - move a0, s0 # a0 <-- gd - move a1, s2 - PTR_LA t9, board_init_r - jr t9 - move ra, zero - - END(relocate_code) diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds index 0129c99..bd5536f 100644 --- a/arch/mips/cpu/u-boot.lds +++ b/arch/mips/cpu/u-boot.lds @@ -34,15 +34,6 @@ SECTIONS *(.data*) } - . = .; - _gp = ALIGN(16) + 0x7ff0; - - .got : { - *(.got) - } - - num_got_entries = SIZEOF(.got) >> PTR_COUNT_SHIFT; - . = ALIGN(4); .sdata : { *(.sdata*) @@ -57,33 +48,19 @@ SECTIONS __image_copy_end = .; __init_end = .; - .rel.dyn : { - __rel_dyn_start = .; - *(.rel.dyn) - __rel_dyn_end = .; - } - - .padding : { - /* - * Workaround for a binutils feature (or bug?). - * - * The GNU ld from binutils puts the dynamic relocation - * entries into the .rel.dyn section. Sometimes it - * allocates more dynamic relocation entries than it needs - * and the unused slots are set to R_MIPS_NONE entries. - * - * However the size of the .rel.dyn section in the ELF - * section header does not cover the unused entries, so - * objcopy removes those during stripping. - * - * Create a small section here to avoid that. - */ - LONG(0xFFFFFFFF) + /* + * .rel must come last so that the mips-relocs tool can shrink + * the section size & the PT_LOAD program header filesz. + */ + .rel : { + __rel_start = .; + BYTE(0x0) + . += (32 * 1024) - 1; } _end = .; - .bss __rel_dyn_start (OVERLAY) : { + .bss __rel_start (OVERLAY) : { __bss_start = .; *(.sbss.*) *(.bss.*) diff --git a/arch/mips/include/asm/relocs.h b/arch/mips/include/asm/relocs.h new file mode 100644 index 0000000..92e9d04 --- /dev/null +++ b/arch/mips/include/asm/relocs.h @@ -0,0 +1,24 @@ +/* + * MIPS Relocations + * + * Copyright (c) 2017 Imagination Technologies Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_MIPS_RELOCS_H__ +#define __ASM_MIPS_RELOCS_H__ + +#define R_MIPS_NONE 0 +#define R_MIPS_32 2 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_PC16 10 +#define R_MIPS_64 18 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_PC21_S2 60 +#define R_MIPS_PC26_S2 61 + +#endif /* __ASM_MIPS_RELOCS_H__ */ diff --git a/arch/mips/include/asm/sections.h b/arch/mips/include/asm/sections.h index fc4640a..b9d2179 100644 --- a/arch/mips/include/asm/sections.h +++ b/arch/mips/include/asm/sections.h @@ -8,4 +8,11 @@ #include +/** + * __rel_start: Relocation data generated by the mips-relocs tool + * + * See arch/mips/lib/reloc.c for details on the format & use of this data. + */ +extern uint8_t __rel_start[]; + #endif diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 659c6ad..ef557c6 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -8,6 +8,7 @@ obj-y += cache.o obj-y += cache_init.o obj-y += genex.o +obj-y += reloc.o obj-y += stack.o obj-y += traps.o diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index be87762..2b67905 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -279,17 +279,17 @@ static void boot_prep_linux(bootm_headers_t *images) boot_reloc_fdt(images); boot_setup_fdt(images); } else { - if (CONFIG_IS_ENABLED(CONFIG_MIPS_BOOT_ENV_LEGACY)) - linux_env_legacy(images); - if (CONFIG_IS_ENABLED(MIPS_BOOT_CMDLINE_LEGACY)) { linux_cmdline_legacy(images); - if (!CONFIG_IS_ENABLED(CONFIG_MIPS_BOOT_ENV_LEGACY)) + if (!CONFIG_IS_ENABLED(MIPS_BOOT_ENV_LEGACY)) linux_cmdline_append(images); linux_cmdline_dump(); } + + if (CONFIG_IS_ENABLED(MIPS_BOOT_ENV_LEGACY)) + linux_env_legacy(images); } } diff --git a/arch/mips/lib/reloc.c b/arch/mips/lib/reloc.c new file mode 100644 index 0000000..d0c52c9 --- /dev/null +++ b/arch/mips/lib/reloc.c @@ -0,0 +1,164 @@ +/* + * MIPS Relocation + * + * Copyright (c) 2017 Imagination Technologies Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Relocation data, found in the .rel section, is generated by the mips-relocs + * tool & contains a record of all locations in the U-Boot binary that need to + * be fixed up during relocation. + * + * The data is a sequence of unsigned integers, which are of somewhat arbitrary + * size. This is achieved by encoding integers as a sequence of bytes, each of + * which contains 7 bits of data with the most significant bit indicating + * whether any further bytes need to be read. The least significant bits of the + * integer are found in the first byte - ie. it somewhat resembles little + * endian. + * + * Each pair of two integers represents a relocation that must be applied. The + * first integer represents the type of relocation as a standard ELF relocation + * type (ie. R_MIPS_*). The second integer represents the offset at which to + * apply the relocation, relative to the previous relocation or for the first + * relocation the start of the relocated .text section. + * + * The end of the relocation data is indicated when type R_MIPS_NONE (0) is + * read, at which point no further integers should be read. That is, the + * terminating R_MIPS_NONE reloc includes no offset. + */ + +#include +#include +#include + +/** + * read_uint() - Read an unsigned integer from the buffer + * @buf: pointer to a pointer to the reloc buffer + * + * Read one whole unsigned integer from the relocation data pointed to by @buf, + * advancing @buf past the bytes encoding the integer. + * + * Returns: the integer read from @buf + */ +static unsigned long read_uint(uint8_t **buf) +{ + unsigned long val = 0; + unsigned int shift = 0; + uint8_t new; + + do { + new = *(*buf)++; + val |= (new & 0x7f) << shift; + shift += 7; + } while (new & 0x80); + + return val; +} + +/** + * apply_reloc() - Apply a single relocation + * @type: the type of reloc (R_MIPS_*) + * @addr: the address that the reloc should be applied to + * @off: the relocation offset, ie. number of bytes we're moving U-Boot by + * + * Apply a single relocation of type @type at @addr. This function is + * intentionally simple, and does the bare minimum needed to fixup the + * relocated U-Boot - in particular, it does not check for overflows. + */ +static void apply_reloc(unsigned int type, void *addr, long off) +{ + uint32_t u32; + + switch (type) { + case R_MIPS_26: + u32 = *(uint32_t *)addr; + u32 = (u32 & GENMASK(31, 26)) | + ((u32 + (off >> 2)) & GENMASK(25, 0)); + *(uint32_t *)addr = u32; + break; + + case R_MIPS_32: + *(uint32_t *)addr += off; + break; + + case R_MIPS_64: + *(uint64_t *)addr += off; + break; + + case R_MIPS_HI16: + *(uint32_t *)addr += off >> 16; + break; + + default: + panic("Unhandled reloc type %u\n", type); + } +} + +/** + * relocate_code() - Relocate U-Boot, generally from flash to DDR + * @start_addr_sp: new stack pointer + * @new_gd: pointer to relocated global data + * @relocaddr: the address to relocate to + * + * Relocate U-Boot from its current location (generally in flash) to a new one + * (generally in DDR). This function will copy the U-Boot binary & apply + * relocations as necessary, then jump to board_init_r in the new build of + * U-Boot. As such, this function does not return. + */ +void relocate_code(ulong start_addr_sp, gd_t *new_gd, ulong relocaddr) +{ + unsigned long addr, length, bss_len; + uint8_t *buf, *bss_start; + unsigned int type; + long off; + + /* + * Ensure that we're relocating by an offset which is a multiple of + * 64KiB, ie. doesn't change the least significant 16 bits of any + * addresses. This allows us to discard R_MIPS_LO16 relocs, saving + * space in the U-Boot binary & complexity in handling them. + */ + off = relocaddr - (unsigned long)__text_start; + if (off & 0xffff) + panic("Mis-aligned relocation\n"); + + /* Copy U-Boot to RAM */ + length = __image_copy_end - __text_start; + memcpy((void *)relocaddr, __text_start, length); + + /* Now apply relocations to the copy in RAM */ + buf = __rel_start; + addr = relocaddr; + while (true) { + type = read_uint(&buf); + if (type == R_MIPS_NONE) + break; + + addr += read_uint(&buf) << 2; + apply_reloc(type, (void *)addr, off); + } + + /* Ensure the icache is coherent */ + flush_cache(relocaddr, length); + + /* Clear the .bss section */ + bss_start = (uint8_t *)((unsigned long)__bss_start + off); + bss_len = (unsigned long)&__bss_end - (unsigned long)__bss_start; + memset(bss_start, 0, bss_len); + + /* Jump to the relocated U-Boot */ + asm volatile( + "move $29, %0\n" + " move $4, %1\n" + " move $5, %2\n" + " move $31, $0\n" + " jr %3" + : /* no outputs */ + : "r"(start_addr_sp), + "r"(new_gd), + "r"(relocaddr), + "r"((unsigned long)board_init_r + off)); + + /* Since we jumped to the new U-Boot above, we won't get here */ + unreachable(); +} diff --git a/arch/powerpc/cpu/mpc83xx/start.S b/arch/powerpc/cpu/mpc83xx/start.S index d99ae27..d2fced8a 100644 --- a/arch/powerpc/cpu/mpc83xx/start.S +++ b/arch/powerpc/cpu/mpc83xx/start.S @@ -264,14 +264,14 @@ in_flash: cmplw r3, r4 bne 1b -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) -#if CONFIG_SYS_MALLOC_F_LEN + GENERATED_GBL_DATA_SIZE > CONFIG_SYS_INIT_RAM_SIZE -#error "CONFIG_SYS_MALLOC_F_LEN too large to fit into initial RAM." +#if CONFIG_VAL(SYS_MALLOC_F_LEN) + GENERATED_GBL_DATA_SIZE > CONFIG_SYS_INIT_RAM_SIZE +#error "SYS_MALLOC_F_LEN too large to fit into initial RAM." #endif /* r3 = new stack pointer / pre-reloc malloc area */ - subi r3, r3, CONFIG_SYS_MALLOC_F_LEN + subi r3, r3, CONFIG_VAL(SYS_MALLOC_F_LEN) /* Set pointer to pre-reloc malloc area in GD */ stw r3, GD_MALLOC_BASE(r4) diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index f03e1a0..0f016f0 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -1183,14 +1183,13 @@ _start_cont: lis r3,(CONFIG_SYS_INIT_RAM_ADDR)@h ori r3,r3,((CONFIG_SYS_INIT_SP_OFFSET-16)&~0xf)@l /* Align to 16 */ -#ifdef CONFIG_SYS_MALLOC_F_LEN - -#if CONFIG_SYS_MALLOC_F_LEN + GENERATED_GBL_DATA_SIZE > CONFIG_SYS_INIT_RAM_SIZE -#error "CONFIG_SYS_MALLOC_F_LEN too large to fit into initial RAM." +#if CONFIG_VAL(SYS_MALLOC_F_LEN) +#if CONFIG_VAL(SYS_MALLOC_F_LEN) + GENERATED_GBL_DATA_SIZE > CONFIG_SYS_INIT_RAM_SIZE +#error "SYS_MALLOC_F_LEN too large to fit into initial RAM." #endif /* Leave 16+ byte for back chain termination and NULL return address */ - subi r3,r3,((CONFIG_SYS_MALLOC_F_LEN+16+15)&~0xf) + subi r3,r3,((CONFIG_VAL(SYS_MALLOC_F_LEN)+16+15)&~0xf) #endif /* End of RAM */ @@ -1204,7 +1203,7 @@ _start_cont: cmplw r4,r3 bne 1b -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) lis r4,(CONFIG_SYS_INIT_RAM_ADDR)@h ori r4,r4,(CONFIG_SYS_GBL_DATA_OFFSET)@l diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 7243bfc..22d6aab 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -413,17 +413,6 @@ int os_get_filesize(const char *fname, loff_t *size) return 0; } -void os_putc(int ch) -{ - putchar(ch); -} - -void os_puts(const char *str) -{ - while (*str) - os_putc(*str++); -} - int os_write_ram_buf(const char *fname) { struct sandbox_state *state = state_get_current(); diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index f605d4d..00742fd 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -310,7 +310,7 @@ int main(int argc, char *argv[]) memset(&data, '\0', sizeof(data)); gd = &data; -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif setup_ram_buf(state); diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index 4c0a8fe..a0ad03c 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -272,6 +272,9 @@ fsp,enable-spi; fsp,enable-sata; fsp,sata-mode = ; +#ifdef CONFIG_USB_XHCI_HCD + fsp,enable-xhci; +#endif fsp,lpe-mode = ; fsp,lpss-sio-mode = ; fsp,enable-dma0; diff --git a/board/cei/cei-tk1-som/cei-tk1-som.c b/board/cei/cei-tk1-som/cei-tk1-som.c index 9ba7490..7c87bd1 100644 --- a/board/cei/cei-tk1-som/cei-tk1-som.c +++ b/board/cei/cei-tk1-som/cei-tk1-som.c @@ -39,6 +39,7 @@ void pinmux_init(void) #ifdef CONFIG_PCI_TEGRA int tegra_pcie_board_init(void) { +/* TODO: Convert to driver model struct udevice *pmic; int err; @@ -59,6 +60,7 @@ int tegra_pcie_board_init(void) error("failed to set SD4 voltage: %d\n", err); return err; } +*/ return 0; } diff --git a/board/nvidia/jetson-tk1/jetson-tk1.c b/board/nvidia/jetson-tk1/jetson-tk1.c index a66b710..bd08a2e 100644 --- a/board/nvidia/jetson-tk1/jetson-tk1.c +++ b/board/nvidia/jetson-tk1/jetson-tk1.c @@ -6,7 +6,9 @@ */ #include +#include #include +#include #include #include @@ -37,27 +39,45 @@ void pinmux_init(void) } #ifdef CONFIG_PCI_TEGRA -int tegra_pcie_board_init(void) +/* TODO: Convert to driver model */ +static int as3722_sd_enable(struct udevice *pmic, unsigned int sd) { - struct udevice *pmic; int err; - err = as3722_init(&pmic); + if (sd > 6) + return -EINVAL; + + err = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd); if (err) { - error("failed to initialize AS3722 PMIC: %d\n", err); + error("failed to update SD control register: %d", err); return err; } - err = as3722_sd_enable(pmic, 4); - if (err < 0) { - error("failed to enable SD4: %d\n", err); - return err; + return 0; +} + +int tegra_pcie_board_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_as3722), &dev); + if (ret) { + debug("%s: Failed to find PMIC\n", __func__); + return ret; } - err = as3722_sd_set_voltage(pmic, 4, 0x24); - if (err < 0) { - error("failed to set SD4 voltage: %d\n", err); - return err; + ret = as3722_sd_enable(dev, 4); + if (ret < 0) { + error("failed to enable SD4: %d\n", ret); + return ret; + } + + ret = as3722_sd_set_voltage(dev, 4, 0x24); + if (ret < 0) { + error("failed to set SD4 voltage: %d\n", ret); + return ret; } return 0; diff --git a/board/nvidia/nyan-big/nyan-big.c b/board/nvidia/nyan-big/nyan-big.c index 8f68ae9..54acf54 100644 --- a/board/nvidia/nyan-big/nyan-big.c +++ b/board/nvidia/nyan-big/nyan-big.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -46,20 +47,23 @@ int tegra_board_id(void) int tegra_lcd_pmic_init(int board_id) { - struct udevice *pmic; + struct udevice *dev; int ret; - ret = as3722_get(&pmic); - if (ret) - return -ENOENT; + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_as3722), &dev); + if (ret) { + debug("%s: Failed to find PMIC\n", __func__); + return ret; + } if (board_id == 0) - as3722_write(pmic, 0x00, 0x3c); + pmic_reg_write(dev, 0x00, 0x3c); else - as3722_write(pmic, 0x00, 0x50); - as3722_write(pmic, 0x12, 0x10); - as3722_write(pmic, 0x0c, 0x07); - as3722_write(pmic, 0x20, 0x10); + pmic_reg_write(dev, 0x00, 0x50); + pmic_reg_write(dev, 0x12, 0x10); + pmic_reg_write(dev, 0x0c, 0x07); + pmic_reg_write(dev, 0x20, 0x10); return 0; } diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c index fc4c60c..f31768e 100644 --- a/board/st/stm32f746-disco/stm32f746-disco.c +++ b/board/st/stm32f746-disco/stm32f746-disco.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c index 36e9cd7..9347329 100644 --- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c +++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c @@ -9,20 +9,11 @@ #include #include #include -#include #include #include #include #include -#define RK3399_CPUID_OFF 0x7 -#define RK3399_CPUID_LEN 0x10 - -DECLARE_GLOBAL_DATA_PTR; - -#define RK3399_CPUID_OFF 0x7 -#define RK3399_CPUID_LEN 0x10 - DECLARE_GLOBAL_DATA_PTR; int board_init(void) @@ -107,11 +98,14 @@ static void setup_macaddr(void) static void setup_serial(void) { #if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) + const u32 cpuid_offset = 0x7; + const u32 cpuid_length = 0x10; + struct udevice *dev; int ret, i; - u8 cpuid[RK3399_CPUID_LEN]; - u8 low[RK3399_CPUID_LEN/2], high[RK3399_CPUID_LEN/2]; - char cpuid_str[RK3399_CPUID_LEN * 2 + 1]; + u8 cpuid[cpuid_length]; + u8 low[cpuid_length/2], high[cpuid_length/2]; + char cpuid_str[cpuid_length * 2 + 1]; u64 serialno; char serialno_str[16]; @@ -124,7 +118,7 @@ static void setup_serial(void) } /* read the cpu_id range from the efuses */ - ret = misc_read(dev, RK3399_CPUID_OFF, &cpuid, sizeof(cpuid)); + ret = misc_read(dev, cpuid_offset, &cpuid, sizeof(cpuid)); if (ret) { debug("%s: reading cpuid from the efuses failed\n", __func__); diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c index bf8c8e1..00a31a97 100644 --- a/board/ti/am57xx/board.c +++ b/board/ti/am57xx/board.c @@ -36,11 +36,13 @@ #define board_is_x15() board_ti_is("BBRDX15_") #define board_is_x15_revb1() (board_ti_is("BBRDX15_") && \ - (strncmp("B.10", board_ti_get_rev(), 3) <= 0)) + !strncmp("B.10", board_ti_get_rev(), 3)) +#define board_is_x15_revc() (board_ti_is("BBRDX15_") && \ + !strncmp("C.00", board_ti_get_rev(), 3)) #define board_is_am572x_evm() board_ti_is("AM572PM_") #define board_is_am572x_evm_reva3() \ (board_ti_is("AM572PM_") && \ - (strncmp("A.30", board_ti_get_rev(), 3) <= 0)) + !strncmp("A.30", board_ti_get_rev(), 3)) #define board_is_am572x_idk() board_ti_is("AM572IDK") #define board_is_am571x_idk() board_ti_is("AM571IDK") @@ -474,6 +476,8 @@ static void setup_board_eeprom_env(void) if (board_is_x15()) { if (board_is_x15_revb1()) name = "beagle_x15_revb1"; + else if (board_is_x15_revc()) + name = "beagle_x15_revc"; else name = "beagle_x15"; } else if (board_is_am572x_evm()) { @@ -683,7 +687,8 @@ void recalibrate_iodelay(void) /* Now do the weird minor deltas that should be safe */ if (board_is_x15() || board_is_am572x_evm()) { - if (board_is_x15_revb1() || board_is_am572x_evm_reva3()) { + if (board_is_x15_revb1() || board_is_am572x_evm_reva3() || + board_is_x15_revc()) { pconf = core_padconf_array_delta_x15_sr2_0; pconf_sz = ARRAY_SIZE(core_padconf_array_delta_x15_sr2_0); } else { diff --git a/board/toradex/apalis-tk1/apalis-tk1.c b/board/toradex/apalis-tk1/apalis-tk1.c index c7e519c..5de61e7 100644 --- a/board/toradex/apalis-tk1/apalis-tk1.c +++ b/board/toradex/apalis-tk1/apalis-tk1.c @@ -61,6 +61,7 @@ void pinmux_init(void) #ifdef CONFIG_PCI_TEGRA int tegra_pcie_board_init(void) { + /* TODO: Convert to driver model struct udevice *pmic; int err; @@ -94,6 +95,7 @@ int tegra_pcie_board_init(void) error("failed to set GPIO#2 high: %d\n", err); return err; } + */ /* Reset I210 Gigabit Ethernet Controller */ gpio_request(LAN_RESET_N, "LAN_RESET_N"); @@ -110,6 +112,7 @@ int tegra_pcie_board_init(void) gpio_direction_output(TEGRA_GPIO(O, 6), 0); /* Make sure LDO9 and LDO10 are initially enabled @ 0V */ + /* TODO: Convert to driver model err = as3722_ldo_enable(pmic, 9); if (err < 0) { error("failed to enable LDO9: %d\n", err); @@ -130,6 +133,7 @@ int tegra_pcie_board_init(void) error("failed to set LDO10 voltage: %d\n", err); return err; } + */ mdelay(100); @@ -137,6 +141,7 @@ int tegra_pcie_board_init(void) gpio_set_value(TEGRA_GPIO(O, 6), 1); /* Enable LDO9 and LDO10 for +V3.3_ETH on patched prototypes */ + /* TODO: Convert to driver model err = as3722_ldo_set_voltage(pmic, 9, 0xff); if (err < 0) { error("failed to set LDO9 voltage: %d\n", err); @@ -147,6 +152,7 @@ int tegra_pcie_board_init(void) error("failed to set LDO10 voltage: %d\n", err); return err; } + */ mdelay(100); gpio_set_value(LAN_RESET_N, 1); diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 8971697..81ac78d 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -344,9 +344,9 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, #ifdef CONFIG_BOARD_TYPES printf("Board Type = %ld\n", gd->board_type); #endif -#ifdef CONFIG_SYS_MALLOC_F +#if CONFIG_VAL(SYS_MALLOC_F_LEN) printf("Early malloc usage: %lx / %x\n", gd->malloc_ptr, - CONFIG_SYS_MALLOC_F_LEN); + CONFIG_VAL(SYS_MALLOC_F_LEN)); #endif if (gd->fdt_blob) printf("fdt_blob = %p\n", gd->fdt_blob); diff --git a/cmd/scsi.c b/cmd/scsi.c index 5709718..8e36de1 100644 --- a/cmd/scsi.c +++ b/cmd/scsi.c @@ -36,7 +36,9 @@ static int do_scsi(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) case 2: if (strncmp(argv[1], "res", 3) == 0) { printf("\nReset SCSI\n"); +#ifndef CONFIG_DM_SCSI scsi_bus_reset(NULL); +#endif ret = scsi_scan(true); if (ret) return CMD_RET_FAILURE; diff --git a/cmd/usb.c b/cmd/usb.c index 4fa456e..992d414 100644 --- a/cmd/usb.c +++ b/cmd/usb.c @@ -150,6 +150,8 @@ static void usb_display_string(struct usb_device *dev, int index) static void usb_display_desc(struct usb_device *dev) { + uint packet_size = dev->descriptor.bMaxPacketSize0; + if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) { printf("%d: %s, USB Revision %x.%x\n", dev->devnum, usb_get_class_desc(dev->config.if_desc[0].desc.bInterfaceClass), @@ -171,9 +173,10 @@ static void usb_display_desc(struct usb_device *dev) usb_get_class_desc( dev->config.if_desc[0].desc.bInterfaceClass)); } + if (dev->descriptor.bcdUSB >= cpu_to_le16(0x0300)) + packet_size = 1 << packet_size; printf(" - PacketSize: %d Configurations: %d\n", - dev->descriptor.bMaxPacketSize0, - dev->descriptor.bNumConfigurations); + packet_size, dev->descriptor.bNumConfigurations); printf(" - Vendor: 0x%04x Product 0x%04x Version %d.%d\n", dev->descriptor.idVendor, dev->descriptor.idProduct, (dev->descriptor.bcdDevice>>8) & 0xff, diff --git a/common/Makefile b/common/Makefile index 17a92ea..60681c8 100644 --- a/common/Makefile +++ b/common/Makefile @@ -139,9 +139,11 @@ obj-y += console.o endif obj-$(CONFIG_CROS_EC) += cros_ec.o obj-y += dlmalloc.o -ifdef CONFIG_SYS_MALLOC_F_LEN +ifdef CONFIG_SYS_MALLOC_F +ifneq ($(CONFIG_$(SPL_)SYS_MALLOC_F_LEN),0) obj-y += malloc_simple.o endif +endif obj-y += image.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o obj-$(CONFIG_$(SPL_)OF_LIBFDT) += image-fdt.o diff --git a/common/board_f.c b/common/board_f.c index ffa84e3..19b8055 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -418,7 +418,7 @@ static int reserve_uboot(void) */ gd->relocaddr -= gd->mon_len; gd->relocaddr &= ~(4096 - 1); -#ifdef CONFIG_E500 +#if defined(CONFIG_E500) || defined(CONFIG_MIPS) /* round down to next 64 kB limit so that IVPR stays aligned */ gd->relocaddr &= ~(65536 - 1); #endif @@ -727,7 +727,7 @@ static int initf_bootstage(void) static int initf_console_record(void) { -#if defined(CONFIG_CONSOLE_RECORD) && defined(CONFIG_SYS_MALLOC_F_LEN) +#if defined(CONFIG_CONSOLE_RECORD) && CONFIG_VAL(SYS_MALLOC_F_LEN) return console_record_init(); #else return 0; @@ -736,7 +736,7 @@ static int initf_console_record(void) static int initf_dm(void) { -#if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN) +#if defined(CONFIG_DM) && CONFIG_VAL(SYS_MALLOC_F_LEN) int ret; bootstage_start(BOOTSTATE_ID_ACCUM_DM_F, "dm_f"); diff --git a/common/board_r.c b/common/board_r.c index ecca1ed..985aa95 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -256,7 +256,7 @@ static int initr_malloc(void) { ulong malloc_start; -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) debug("Pre-reloc malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); #endif diff --git a/common/console.c b/common/console.c index c6156f3..01eef55 100644 --- a/common/console.c +++ b/common/console.c @@ -426,12 +426,6 @@ static void pre_console_putc(const char c) unmap_sysmem(buffer); } -static void pre_console_puts(const char *s) -{ - while (*s) - pre_console_putc(*s++); -} - static void print_pre_console_buffer(int flushpoint) { unsigned long in = 0, out = 0; @@ -459,7 +453,6 @@ static void print_pre_console_buffer(int flushpoint) } #else static inline void pre_console_putc(const char c) {} -static inline void pre_console_puts(const char *s) {} static inline void print_pre_console_buffer(int flushpoint) {} #endif @@ -501,41 +494,8 @@ void putc(const char c) void puts(const char *s) { -#ifdef CONFIG_DEBUG_UART - if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { - while (*s) { - int ch = *s++; - - printch(ch); - } - return; - } -#endif -#ifdef CONFIG_CONSOLE_RECORD - if (gd && (gd->flags & GD_FLG_RECORD) && gd->console_out.start) - membuff_put(&gd->console_out, s, strlen(s)); -#endif -#ifdef CONFIG_SILENT_CONSOLE - if (gd->flags & GD_FLG_SILENT) - return; -#endif - -#ifdef CONFIG_DISABLE_CONSOLE - if (gd->flags & GD_FLG_DISABLE_CONSOLE) - return; -#endif - - if (!gd->have_console) - return pre_console_puts(s); - - if (gd->flags & GD_FLG_DEVINIT) { - /* Send to the standard output */ - fputs(stdout, s); - } else { - /* Send directly to the handler */ - pre_console_puts(s); - serial_puts(s); - } + while (*s) + putc(*s++); } #ifdef CONFIG_CONSOLE_RECORD diff --git a/common/dlmalloc.c b/common/dlmalloc.c index fc1e8b3..c37979b 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -1254,7 +1254,7 @@ Void_t* mALLOc(bytes) size_t bytes; INTERNAL_SIZE_T nb; -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) return malloc_simple(bytes); #endif @@ -1522,7 +1522,7 @@ void fREe(mem) Void_t* mem; mchunkptr fwd; /* misc temp for linking */ int islr; /* track whether merging with last_remainder */ -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) /* free() is a no-op - all the memory will be freed on relocation */ if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) return; @@ -1679,7 +1679,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes; /* realloc of null is supposed to be same as malloc */ if (oldmem == NULL) return mALLOc(bytes); -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) { /* This is harder to support and should not be needed */ panic("pre-reloc realloc() is not supported"); @@ -2074,7 +2074,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size; return NULL; else { -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) { MALLOC_ZERO(mem, sz); return mem; @@ -2375,9 +2375,9 @@ int mALLOPt(param_number, value) int param_number; int value; int initf_malloc(void) { -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) assert(gd->malloc_base); /* Set up by crt0.S */ - gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN); gd->malloc_ptr = 0; #endif diff --git a/common/init/board_init.c b/common/init/board_init.c index bf4255b..4a391be 100644 --- a/common/init/board_init.c +++ b/common/init/board_init.c @@ -46,8 +46,8 @@ __weak void arch_setup_gd(struct global_data *gd_ptr) ulong board_init_f_alloc_reserve(ulong top) { /* Reserve early malloc arena */ -#if defined(CONFIG_SYS_MALLOC_F) - top -= CONFIG_SYS_MALLOC_F_LEN; +#if CONFIG_VAL(SYS_MALLOC_F_LEN) + top -= CONFIG_VAL(SYS_MALLOC_F_LEN); #endif /* LAST : reserve GD (rounded up to a multiple of 16 bytes) */ top = rounddown(top-sizeof(struct global_data), 16); @@ -121,11 +121,11 @@ void board_init_f_init_reserve(ulong base) * Use gd as it is now properly set for all architectures. */ -#if defined(CONFIG_SYS_MALLOC_F) +#if CONFIG_VAL(SYS_MALLOC_F_LEN) /* go down one 'early malloc arena' */ gd->malloc_base = base; /* next alloc will be higher by one 'early malloc arena' size */ - base += CONFIG_SYS_MALLOC_F_LEN; + base += CONFIG_VAL(SYS_MALLOC_F_LEN); #endif } diff --git a/common/spl/spl.c b/common/spl/spl.c index 7f3fd92..c56cc6f 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -220,12 +220,12 @@ static int spl_common_init(bool setup_malloc) debug("spl_early_init()\n"); -#if defined(CONFIG_SYS_MALLOC_F_LEN) +#if CONFIG_VAL(SYS_MALLOC_F_LEN) if (setup_malloc) { #ifdef CONFIG_MALLOC_F_ADDR gd->malloc_base = CONFIG_MALLOC_F_ADDR; #endif - gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN); gd->malloc_ptr = 0; } #endif @@ -419,7 +419,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) default: debug("Unsupported OS image.. Jumping nevertheless..\n"); } -#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); #endif @@ -486,7 +486,7 @@ ulong spl_relocate_stack_gd(void) gd_t *new_gd; ulong ptr = CONFIG_SPL_STACK_R_ADDR; -#ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE +#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_SPL_SYS_MALLOC_F_LEN if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; gd->malloc_base = ptr; diff --git a/common/usb_hub.c b/common/usb_hub.c index d135526..70bc6e2 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -55,9 +55,6 @@ struct usb_device_scan { struct list_head list; }; -/* TODO(sjg@chromium.org): Remove this when CONFIG_DM_USB is defined */ -static struct usb_hub_device hub_dev[USB_MAX_HUB]; -static int usb_hub_index; static LIST_HEAD(usb_scan_list); __weak void usb_hub_reset_devices(int port) @@ -65,11 +62,41 @@ __weak void usb_hub_reset_devices(int port) return; } +static inline bool usb_hub_is_superspeed(struct usb_device *hdev) +{ + return hdev->descriptor.bDeviceProtocol == 3; +} + +#ifdef CONFIG_DM_USB +bool usb_hub_is_root_hub(struct udevice *hub) +{ + if (device_get_uclass_id(hub->parent) != UCLASS_USB_HUB) + return true; + + return false; +} + +static int usb_set_hub_depth(struct usb_device *dev, int depth) +{ + if (depth < 0 || depth > 4) + return -EINVAL; + + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_HUB_DEPTH, USB_DIR_OUT | USB_RT_HUB, + depth, 0, NULL, 0, USB_CNTL_TIMEOUT); +} +#endif + static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size) { + unsigned short dtype = USB_DT_HUB; + + if (usb_hub_is_superspeed(dev)) + dtype = USB_DT_SS_HUB; + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, - USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT); + dtype << 8, 0, data, size, USB_CNTL_TIMEOUT); } static int usb_clear_port_feature(struct usb_device *dev, int port, int feature) @@ -95,9 +122,40 @@ static int usb_get_hub_status(struct usb_device *dev, void *data) int usb_get_port_status(struct usb_device *dev, int port, void *data) { - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + int ret; + + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port, - data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT); + data, sizeof(struct usb_port_status), USB_CNTL_TIMEOUT); + +#ifdef CONFIG_DM_USB + if (ret < 0) + return ret; + + /* + * Translate the USB 3.0 hub port status field into the old version + * that U-Boot understands. Do this only when the hub is not root hub. + * For root hub, the port status field has already been translated + * in the host controller driver (see xhci_submit_root() in xhci.c). + * + * Note: this only supports driver model. + */ + + if (!usb_hub_is_root_hub(dev->dev) && usb_hub_is_superspeed(dev)) { + struct usb_port_status *status = (struct usb_port_status *)data; + u16 tmp = (status->wPortStatus) & USB_SS_PORT_STAT_MASK; + + if (status->wPortStatus & USB_SS_PORT_STAT_POWER) + tmp |= USB_PORT_STAT_POWER; + if ((status->wPortStatus & USB_SS_PORT_STAT_SPEED) == + USB_SS_PORT_STAT_SPEED_5GBPS) + tmp |= USB_PORT_STAT_SUPER_SPEED; + + status->wPortStatus = tmp; + } +#endif + + return ret; } @@ -154,6 +212,10 @@ static void usb_hub_power_on(struct usb_hub_device *hub) max(100, (int)pgood_delay) + 1000); } +#ifndef CONFIG_DM_USB +static struct usb_hub_device hub_dev[USB_MAX_HUB]; +static int usb_hub_index; + void usb_hub_reset(void) { usb_hub_index = 0; @@ -170,6 +232,7 @@ static struct usb_hub_device *usb_hub_allocate(void) printf("ERROR: USB_MAX_HUB (%d) reached\n", USB_MAX_HUB); return NULL; } +#endif #define MAX_TRIES 5 @@ -195,8 +258,18 @@ static inline char *portspeed(int portstatus) return speed_str; } -int legacy_hub_port_reset(struct usb_device *dev, int port, - unsigned short *portstat) +/** + * usb_hub_port_reset() - reset a port given its usb_device pointer + * + * Reset a hub port and see if a device is present on that port, providing + * sufficient time for it to show itself. The port status is returned. + * + * @dev: USB device to reset + * @port: Port number to reset (note ports are numbered from 0 here) + * @portstat: Returns port status + */ +static int usb_hub_port_reset(struct usb_device *dev, int port, + unsigned short *portstat) { int err, tries; ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); @@ -269,15 +342,6 @@ int legacy_hub_port_reset(struct usb_device *dev, int port, return 0; } -#ifdef CONFIG_DM_USB -int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat) -{ - struct usb_device *udev = dev_get_parent_priv(dev); - - return legacy_hub_port_reset(udev, port, portstat); -} -#endif - int usb_hub_port_connect_change(struct usb_device *dev, int port) { ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); @@ -311,7 +375,7 @@ int usb_hub_port_connect_change(struct usb_device *dev, int port) } /* Reset the port */ - ret = legacy_hub_port_reset(dev, port, &portstatus); + ret = usb_hub_port_reset(dev, port, &portstatus); if (ret < 0) { if (ret != -ENXIO) printf("cannot reset port %i!?\n", port + 1); @@ -405,8 +469,15 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) portchange = le16_to_cpu(portsts->wPortChange); debug("Port %d Status %X Change %X\n", i + 1, portstatus, portchange); - /* No connection change happened, wait a bit more. */ - if (!(portchange & USB_PORT_STAT_C_CONNECTION)) { + /* + * No connection change happened, wait a bit more. + * + * For some situation, the hub reports no connection change but a + * device is connected to the port (eg: CCS bit is set but CSC is not + * in the PORTSC register of a root hub), ignore such case. + */ + if (!(portchange & USB_PORT_STAT_C_CONNECTION) && + !(portstatus & USB_PORT_STAT_CONNECTION)) { if (get_timer(0) >= hub->connect_timeout) { debug("devnum=%d port=%d: timeout\n", dev->devnum, i + 1); @@ -418,10 +489,6 @@ static int usb_scan_port(struct usb_device_scan *usb_scan) return 0; } - /* Test if the connection came up, and if not exit */ - if (!(portstatus & USB_PORT_STAT_CONNECTION)) - return 0; - /* A new USB device is ready at this point */ debug("devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1); @@ -530,6 +597,20 @@ out: return ret; } +static struct usb_hub_device *usb_get_hub_device(struct usb_device *dev) +{ + struct usb_hub_device *hub; + +#ifndef CONFIG_DM_USB + /* "allocate" Hub device */ + hub = usb_hub_allocate(); +#else + hub = dev_get_uclass_priv(dev->dev); +#endif + + return hub; +} + static int usb_hub_configure(struct usb_device *dev) { int i, length; @@ -541,11 +622,11 @@ static int usb_hub_configure(struct usb_device *dev) __maybe_unused struct usb_hub_status *hubsts; int ret; - /* "allocate" Hub device */ - hub = usb_hub_allocate(); + hub = usb_get_hub_device(dev); if (hub == NULL) return -ENOMEM; hub->pusb_dev = dev; + /* Get the the hub descriptor */ ret = usb_get_hub_descriptor(dev, buffer, 4); if (ret < 0) { @@ -570,17 +651,19 @@ static int usb_hub_configure(struct usb_device *dev) &descriptor->wHubCharacteristics)), &hub->desc.wHubCharacteristics); /* set the bitmap */ - bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0]; + bitmap = (unsigned char *)&hub->desc.u.hs.DeviceRemovable[0]; /* devices not removable by default */ memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); - bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0]; + bitmap = (unsigned char *)&hub->desc.u.hs.PortPowerCtrlMask[0]; memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */ for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++) - hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i]; + hub->desc.u.hs.DeviceRemovable[i] = + descriptor->u.hs.DeviceRemovable[i]; for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++) - hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i]; + hub->desc.u.hs.PortPowerCtrlMask[i] = + descriptor->u.hs.PortPowerCtrlMask[i]; dev->maxchild = descriptor->bNbrPorts; debug("%d ports detected\n", dev->maxchild); @@ -617,6 +700,56 @@ static int usb_hub_configure(struct usb_device *dev) break; } + switch (dev->descriptor.bDeviceProtocol) { + case USB_HUB_PR_FS: + break; + case USB_HUB_PR_HS_SINGLE_TT: + debug("Single TT\n"); + break; + case USB_HUB_PR_HS_MULTI_TT: + ret = usb_set_interface(dev, 0, 1); + if (ret == 0) { + debug("TT per port\n"); + hub->tt.multi = true; + } else { + debug("Using single TT (err %d)\n", ret); + } + break; + case USB_HUB_PR_SS: + /* USB 3.0 hubs don't have a TT */ + break; + default: + debug("Unrecognized hub protocol %d\n", + dev->descriptor.bDeviceProtocol); + break; + } + + /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */ + switch (hubCharacteristics & HUB_CHAR_TTTT) { + case HUB_TTTT_8_BITS: + if (dev->descriptor.bDeviceProtocol != 0) { + hub->tt.think_time = 666; + debug("TT requires at most %d FS bit times (%d ns)\n", + 8, hub->tt.think_time); + } + break; + case HUB_TTTT_16_BITS: + hub->tt.think_time = 666 * 2; + debug("TT requires at most %d FS bit times (%d ns)\n", + 16, hub->tt.think_time); + break; + case HUB_TTTT_24_BITS: + hub->tt.think_time = 666 * 3; + debug("TT requires at most %d FS bit times (%d ns)\n", + 24, hub->tt.think_time); + break; + case HUB_TTTT_32_BITS: + hub->tt.think_time = 666 * 4; + debug("TT requires at most %d FS bit times (%d ns)\n", + 32, hub->tt.think_time); + break; + } + debug("power on to power good time: %dms\n", descriptor->bPwrOn2PwrGood * 2); debug("hub controller current requirement: %dmA\n", @@ -624,7 +757,7 @@ static int usb_hub_configure(struct usb_device *dev) for (i = 0; i < dev->maxchild; i++) debug("port %d is%s removable\n", i + 1, - hub->desc.DeviceRemovable[(i + 1) / 8] & \ + hub->desc.u.hs.DeviceRemovable[(i + 1) / 8] & \ (1 << ((i + 1) % 8)) ? " not" : ""); if (sizeof(struct usb_hub_status) > USB_BUFSIZ) { @@ -653,6 +786,59 @@ static int usb_hub_configure(struct usb_device *dev) debug("%sover-current condition exists\n", (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \ "" : "no "); + +#ifdef CONFIG_DM_USB + /* + * Update USB host controller's internal representation of this hub + * after the hub descriptor is fetched. + */ + ret = usb_update_hub_device(dev); + if (ret < 0 && ret != -ENOSYS) { + debug("%s: failed to update hub device for HCD (%x)\n", + __func__, ret); + return ret; + } + + /* + * A maximum of seven tiers are allowed in a USB topology, and the + * root hub occupies the first tier. The last tier ends with a normal + * USB device. USB 3.0 hubs use a 20-bit field called 'route string' + * to route packets to the designated downstream port. The hub uses a + * hub depth value multiplied by four as an offset into the 'route + * string' to locate the bits it uses to determine the downstream + * port number. + */ + if (usb_hub_is_root_hub(dev->dev)) { + hub->hub_depth = -1; + } else { + struct udevice *hdev; + int depth = 0; + + hdev = dev->dev->parent; + while (!usb_hub_is_root_hub(hdev)) { + depth++; + hdev = hdev->parent; + } + + hub->hub_depth = depth; + + if (usb_hub_is_superspeed(dev)) { + debug("set hub (%p) depth to %d\n", dev, depth); + /* + * This request sets the value that the hub uses to + * determine the index into the 'route string index' + * for this hub. + */ + ret = usb_set_hub_depth(dev, depth); + if (ret < 0) { + debug("%s: failed to set hub depth (%lX)\n", + __func__, dev->status); + return ret; + } + } + } +#endif + usb_hub_power_on(hub); /* @@ -777,6 +963,7 @@ UCLASS_DRIVER(usb_hub) = { .child_pre_probe = usb_child_pre_probe, .per_child_auto_alloc_size = sizeof(struct usb_device), .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata), + .per_device_auto_alloc_size = sizeof(struct usb_hub_device), }; static const struct usb_device_id hub_id_table[] = { diff --git a/configs/apalis-tk1_defconfig b/configs/apalis-tk1_defconfig index 9179aaf..ccff112 100644 --- a/configs/apalis-tk1_defconfig +++ b/configs/apalis-tk1_defconfig @@ -32,7 +32,10 @@ CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_TEGRA=y +CONFIG_DM_PMIC=y CONFIG_PMIC_AS3722=y +CONFIG_DM_REGULATOR=y +CONFIG_REGULATOR_AS3722=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/beaver_defconfig b/configs/beaver_defconfig index 71d6cd5..10fd50d 100644 --- a/configs/beaver_defconfig +++ b/configs/beaver_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_EXT4_WRITE=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_LIVE=y CONFIG_SPL_DM=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y diff --git a/configs/cei-tk1-som_defconfig b/configs/cei-tk1-som_defconfig index 1a5e47d..5623bbf 100644 --- a/configs/cei-tk1-som_defconfig +++ b/configs/cei-tk1-som_defconfig @@ -36,7 +36,10 @@ CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_TEGRA=y +CONFIG_DM_PMIC=y CONFIG_PMIC_AS3722=y +CONFIG_DM_REGULATOR=y +CONFIG_REGULATOR_AS3722=y CONFIG_SYS_NS16550=y CONFIG_TEGRA114_SPI=y CONFIG_USB=y diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig index 8d73f88..7ba75fd 100644 --- a/configs/evb-rk3036_defconfig +++ b/configs/evb-rk3036_defconfig @@ -1,9 +1,13 @@ CONFIG_ARM=y +# CONFIG_SPL_USE_ARCH_MEMCPY is not set +# CONFIG_SPL_USE_ARCH_MEMSET is not set CONFIG_ARCH_ROCKCHIP=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_ROCKCHIP_RK3036=y CONFIG_TARGET_EVB_RK3036=y CONFIG_SPL_STACK_R_ADDR=0x80000 CONFIG_DEFAULT_DEVICE_TREE="rk3036-sdk" +CONFIG_SPL_SYS_MALLOC_F_LEN=0x0 CONFIG_DEBUG_UART=y CONFIG_ENV_IS_NOWHERE=y # CONFIG_DISPLAY_CPUINFO is not set @@ -31,10 +35,11 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_PINCTRL_ROCKCHIP_RK3036=y -# CONFIG_SPL_SERIAL_PRESENT is not set +# CONFIG_SPL_DM_SERIAL is not set CONFIG_DEBUG_UART_BASE=0x20068000 CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYSRESET=y +CONFIG_SPL_TINY_MEMSET=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index 3b605f4..1438f75 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -76,3 +76,7 @@ CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y +CONFIG_USB_KEYBOARD=y +CONFIG_DM_KEYBOARD=y +CONFIG_SYS_USB_EVENT_POLL=y +CONFIG_SYS_STDIO_DEREGISTER=y diff --git a/configs/jetson-tk1_defconfig b/configs/jetson-tk1_defconfig index 65a5832..a533c64 100644 --- a/configs/jetson-tk1_defconfig +++ b/configs/jetson-tk1_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_EXT4_WRITE=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_LIVE=y CONFIG_SPL_DM=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y @@ -36,7 +37,10 @@ CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_TEGRA=y +CONFIG_DM_PMIC=y CONFIG_PMIC_AS3722=y +CONFIG_DM_REGULATOR=y +CONFIG_REGULATOR_AS3722=y CONFIG_SYS_NS16550=y CONFIG_TEGRA114_SPI=y CONFIG_USB=y diff --git a/configs/kylin-rk3036_defconfig b/configs/kylin-rk3036_defconfig index c0faf85..e725e10 100644 --- a/configs/kylin-rk3036_defconfig +++ b/configs/kylin-rk3036_defconfig @@ -1,10 +1,14 @@ CONFIG_ARM=y +# CONFIG_SPL_USE_ARCH_MEMCPY is not set +# CONFIG_SPL_USE_ARCH_MEMSET is not set CONFIG_ARCH_ROCKCHIP=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_ROCKCHIP_RK3036=y CONFIG_TARGET_KYLIN_RK3036=y CONFIG_SPL_STACK_R_ADDR=0x80000 CONFIG_DEFAULT_DEVICE_TREE="rk3036-sdk" CONFIG_ENV_IS_IN_MMC=y +CONFIG_SPL_SYS_MALLOC_F_LEN=0x0 # CONFIG_DISPLAY_CPUINFO is not set CONFIG_SPL_STACK_R=y # CONFIG_CMD_IMLS is not set @@ -20,7 +24,6 @@ CONFIG_CMD_TIME=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set -CONFIG_SPL_PARTITION_UUIDS=y CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_CLK=y @@ -32,9 +35,11 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_PINCTRL_ROCKCHIP_RK3036=y CONFIG_DM_REGULATOR_FIXED=y +# CONFIG_SPL_DM_SERIAL is not set CONFIG_SYSRESET=y CONFIG_USB=y CONFIG_USB_DWC2=y CONFIG_USB_STORAGE=y +CONFIG_SPL_TINY_MEMSET=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index 81e8253..d058753 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -69,6 +69,7 @@ CONFIG_ICH_SPI=y CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y CONFIG_DM_VIDEO=y diff --git a/configs/nyan-big_defconfig b/configs/nyan-big_defconfig index 8183856..03d83c1 100644 --- a/configs/nyan-big_defconfig +++ b/configs/nyan-big_defconfig @@ -38,6 +38,7 @@ CONFIG_CMD_EXT4_WRITE=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_LIVE=y CONFIG_SPL_DM=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y @@ -50,6 +51,7 @@ CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_PMIC=y CONFIG_PMIC_AS3722=y CONFIG_DM_REGULATOR=y +CONFIG_REGULATOR_AS3722=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_PWM_TEGRA=y CONFIG_DEBUG_UART_BASE=0x70006000 diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig index e03e017..121dcf2 100644 --- a/configs/odroid-c2_defconfig +++ b/configs/odroid-c2_defconfig @@ -14,9 +14,11 @@ CONFIG_ENV_IS_NOWHERE=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_MMC=y # CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_OF_CONTROL=y CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM_GPIO=y CONFIG_DM_MMC=y CONFIG_MMC_MESON_GX=y CONFIG_DM_ETH=y diff --git a/configs/p2371-2180_defconfig b/configs/p2371-2180_defconfig index d04f052..4345fb0 100644 --- a/configs/p2371-2180_defconfig +++ b/configs/p2371-2180_defconfig @@ -22,6 +22,7 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_NFS is not set CONFIG_CMD_EXT4_WRITE=y +CONFIG_OF_LIVE=y CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_DFU_SF=y diff --git a/configs/uniphier_ld11_defconfig b/configs/uniphier_ld11_defconfig deleted file mode 100644 index 9601dcc..0000000 --- a/configs/uniphier_ld11_defconfig +++ /dev/null @@ -1,41 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARCH_UNIPHIER=y -CONFIG_SYS_TEXT_BASE=0x84000000 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_SERIAL_SUPPORT=y -CONFIG_ARCH_UNIPHIER_LD11_SINGLE=y -CONFIG_MICRO_SUPPORT_CARD=y -CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld11-ref" -# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set -CONFIG_SPL=y -CONFIG_SPL_NOR_SUPPORT=y -CONFIG_HUSH_PARSER=y -CONFIG_CMD_CONFIG=y -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_ENV_EXISTS is not set -CONFIG_CMD_GPT=y -CONFIG_CMD_MMC=y -CONFIG_CMD_I2C=y -CONFIG_CMD_USB=y -# CONFIG_CMD_FPGA is not set -CONFIG_CMD_GPIO=y -CONFIG_CMD_TFTPPUT=y -CONFIG_CMD_PING=y -CONFIG_CMD_CACHE=y -CONFIG_CMD_TIME=y -# CONFIG_CMD_MISC is not set -CONFIG_CMD_FAT=y -# CONFIG_SPL_DOS_PARTITION is not set -# CONFIG_SPL_EFI_PARTITION is not set -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_SPL_OF_TRANSLATE=y -CONFIG_GPIO_UNIPHIER=y -CONFIG_MISC=y -CONFIG_I2C_EEPROM=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_SDMA=y -CONFIG_MMC_SDHCI_CADENCE=y -CONFIG_USB=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_GENERIC=y -CONFIG_USB_STORAGE=y diff --git a/configs/uniphier_ld20_defconfig b/configs/uniphier_ld20_defconfig deleted file mode 100644 index b5255a6..0000000 --- a/configs/uniphier_ld20_defconfig +++ /dev/null @@ -1,40 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARCH_UNIPHIER=y -CONFIG_SYS_TEXT_BASE=0x84000000 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_SERIAL_SUPPORT=y -CONFIG_ARCH_UNIPHIER_LD20_SINGLE=y -CONFIG_MICRO_SUPPORT_CARD=y -CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld20-ref" -# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set -CONFIG_SPL=y -CONFIG_SPL_NOR_SUPPORT=y -CONFIG_HUSH_PARSER=y -CONFIG_CMD_CONFIG=y -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_ENV_EXISTS is not set -CONFIG_CMD_GPT=y -CONFIG_CMD_MMC=y -CONFIG_CMD_I2C=y -CONFIG_CMD_USB=y -# CONFIG_CMD_FPGA is not set -CONFIG_CMD_GPIO=y -CONFIG_CMD_TFTPPUT=y -CONFIG_CMD_PING=y -CONFIG_CMD_CACHE=y -CONFIG_CMD_TIME=y -# CONFIG_CMD_MISC is not set -CONFIG_CMD_FAT=y -# CONFIG_SPL_DOS_PARTITION is not set -# CONFIG_SPL_EFI_PARTITION is not set -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_SPL_OF_TRANSLATE=y -CONFIG_GPIO_UNIPHIER=y -CONFIG_MISC=y -CONFIG_I2C_EEPROM=y -CONFIG_MMC_UNIPHIER=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_CADENCE=y -CONFIG_USB=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_STORAGE=y diff --git a/configs/uniphier_ld4_sld8_defconfig b/configs/uniphier_ld4_sld8_defconfig index 2685432..c3b1234 100644 --- a/configs/uniphier_ld4_sld8_defconfig +++ b/configs/uniphier_ld4_sld8_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/uniphier_pro4_defconfig b/configs/uniphier_pro4_defconfig index a00e583..72bd99a 100644 --- a/configs/uniphier_pro4_defconfig +++ b/configs/uniphier_pro4_defconfig @@ -28,6 +28,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/uniphier_pxs2_ld6b_defconfig b/configs/uniphier_pxs2_ld6b_defconfig index d4af18a..a409872 100644 --- a/configs/uniphier_pxs2_ld6b_defconfig +++ b/configs/uniphier_pxs2_ld6b_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/uniphier_sld3_defconfig b/configs/uniphier_sld3_defconfig index 0f810ee..b9d89ef 100644 --- a/configs/uniphier_sld3_defconfig +++ b/configs/uniphier_sld3_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/uniphier_v8_defconfig b/configs/uniphier_v8_defconfig index 73bdaa8..d71b8b7 100644 --- a/configs/uniphier_v8_defconfig +++ b/configs/uniphier_v8_defconfig @@ -23,6 +23,7 @@ CONFIG_CMD_CACHE=y CONFIG_CMD_TIME=y # CONFIG_CMD_MISC is not set CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_GPIO_UNIPHIER=y CONFIG_MISC=y diff --git a/doc/README.uniphier b/doc/README.uniphier index f79659c..f21c9d0 100644 --- a/doc/README.uniphier +++ b/doc/README.uniphier @@ -5,7 +5,7 @@ U-Boot for UniPhier SoC family Recommended toolchains ---------------------- -The UniPhir platform is well tested with Linaro toolchanis. +The UniPhier platform is well tested with Linaro toolchains. You can download pre-built toolchains from: http://www.linaro.org/downloads/ @@ -14,97 +14,97 @@ You can download pre-built toolchains from: Compile the source ------------------ -sLD3 reference board: - $ make uniphier_sld3_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- +The source can be configured and built with the following commands: -LD4 reference board: - $ make uniphier_ld4_sld8_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- + $ make + $ make CROSS_COMPILE= DEVICE_TREE= -sLD8 reference board: - $ make uniphier_ld4_sld8_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-sld8-ref +The recommended is `arm-linux-gnueabihf-` for 32bit SoCs, +`aarch64-linux-gnu-` for 64bit SoCs, but you may wish to change it to use your +favorite compiler. -Pro4 reference board: - $ make uniphier_pro4_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- +The following tables show and for each board. -Pro4 Ace board: - $ make uniphier_pro4_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-pro4-ace +32bit SoC boards: -Pro4 Sanji board: - $ make uniphier_pro4_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-pro4-sanji + Board | | +---------------|------------------------------|------------------------------ +sLD3 reference | uniphier_sld3_defconfig | uniphier-sld3-ref (default) +LD4 reference | uniphier_ld4_sld8_defconfig | uniphier-ld4-ref (default) +sld8 reference | uniphier_ld4_sld8_defconfig | uniphier-sld8-def +Pro4 reference | uniphier_pro4_defconfig | uniphier-pro4-ref (default) +Pro4 Ace | uniphier_pro4_defconfig | uniphier-pro4-ace +Pro4 Sanji | uniphier_pro4_defconfig | uniphier-pro4-sanji +Pro5 4KBOX | uniphier_pxs2_ld6b_defconfig | uniphier-pro5-4kbox +PXs2 Gentil | uniphier_pxs2_ld6b_defconfig | uniphier-pxs2-gentil +PXs2 Vodka | uniphier_pxs2_ld6b_defconfig | uniphier-pxs2-vodka (default) +LD6b reference | uniphier_pxs2_ld6b_defconfig | uniphier-ld6b-ref -Pro5 4KBOX Board: - $ make uniphier_pxs2_ld6b_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-pro5-4kbox +64bit SoC boards: -PXs2 Gentil board: - $ make uniphier_pxs2_ld6b_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-pxs2-gentil + Board | | +---------------|-----------------------|---------------------------- +LD11 reference | uniphier_v8_defconfig | uniphier-ld11-ref +LD11 Global | uniphier_v8_defconfig | uniphier-ld11-global +LD20 reference | uniphier_v8_defconfig | uniphier-ld20-ref (default) +LD20 Global | uniphier_v8_defconfig | uniphier-ld20-global -PXs2 Vodka board: - $ make uniphier_pxs2_ld6b_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- +For example, to compile the source for PXs2 Vodka board, run the following: -LD6b reference board: $ make uniphier_pxs2_ld6b_defconfig - $ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-ld6b-ref + $ make CROSS_COMPILE=arm-linux-gnueabihf- DEVICE_TREE=uniphier-pxs2-vodka -LD11 reference board: - $ make uniphier_ld11_defconfig - $ make CROSS_COMPILE=aarch64-linux-gnu- +The device tree marked as (default) can be omitted. `uniphier-pxs2-vodka` is +the default device tree for the configuration `uniphier_pxs2_ld6b_defconfig`, +so the following gives the same result. -LD20 reference board: - $ make uniphier_ld20_defconfig - $ make CROSS_COMPILE=aarch64-linux-gnu- - -PXs3 reference board: - $ make uniphier_v8_defconfig - $ make CROSS_COMPILE=aarch64-linux-gnu- DEVICE_TREE=uniphier-pxs3-ref + $ make uniphier_pxs2_ld6b_defconfig + $ make CROSS_COMPILE=arm-linux-gnueabihf- -You may wish to change the "CROSS_COMPILE=..." to use your favorite compiler. +Booting 32bit SoC boards +------------------------ -Burn U-Boot images to NAND --------------------------- +The build command will generate the following: +- u-boot.bin +- spl/u-boot.bin -Write the following to the NAND device: +U-Boot can boot UniPhier 32bit SoC boards by itself. Flash the generated images +to the storage device (NAND or eMMC) on your board. - spl/u-boot-spl.bin at the offset address 0x00000000 - u-boot.bin at the offset address 0x00020000 -or +The `u-boot-with-spl.bin` is the concatenation of the two (with appropriate +padding), so you can also do: - u-boot-with-spl.bin at the offset address 0x00000000 If a TFTP server is available, the images can be easily updated. Just copy the u-boot-spl.bin and u-boot.bin to the TFTP public directory, -and then run the following command at the U-Boot command line: +and run the following command at the U-Boot command line: - => run nandupdate +To update the images in NAND: + => run nandupdate -Burn U-Boot images to eMMC --------------------------- +To update the images in eMMC: -Write the following to the Boot partition 1 of the eMMC device: + => run emmcupdate - - spl/u-boot-spl.bin at the offset address 0x00000000 - - u-boot.bin at the offset address 0x00020000 -or +Booting 64bit SoC boards +------------------------ - - u-boot-with-spl.bin at the offset address 0x00000000 +The build command will generate the following: +- u-boot.bin -If a TFTP server is available, the images can be easily updated. -Just copy the u-boot-spl.bin and u-boot.bin to the TFTP public directory, -and then run the following command at the U-Boot command line: +However, U-Boot is not the first stage loader for UniPhier 64bit SoC boards. +U-Boot serves as a non-secure boot loader loaded by [ARM Trusted Firmware], +so you need to provide the `u-boot.bin` to the build command of ARM Trusted +Firmware. - => run emmcupdate +[ARM Trusted Firmware]: https://github.com/ARM-software/arm-trusted-firmware UniPhier specific commands @@ -179,4 +179,4 @@ newer SoCs. Even if it is, EA[25] is not connected on most of the boards. -- Masahiro Yamada -Jan. 2017 +Jul. 2017 diff --git a/doc/device-tree-bindings/ram/st,stm32-fmc.txt b/doc/device-tree-bindings/ram/st,stm32-fmc.txt index 3d1392c..99f76d5 100644 --- a/doc/device-tree-bindings/ram/st,stm32-fmc.txt +++ b/doc/device-tree-bindings/ram/st,stm32-fmc.txt @@ -40,12 +40,19 @@ Example: pinctrl-names = "default"; status = "okay"; - mr-nbanks = <1>; /* sdram memory configuration from sdram datasheet */ - bank1: bank@0 { - st,sdram-control = /bits/ 8 ; - st,sdram-timing = /bits/ 8 ; - }; -} + }; + + /* sdram memory configuration from sdram datasheet */ + bank2: bank@1 { + st,sdram-control = /bits/ 8 ; + st,sdram-timing = /bits/ 8 ; + }; + } diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index afff301..136d3d7 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -159,8 +159,8 @@ the '/images' node should have the following layout: Mandatory properties: - description : Textual description of the component sub-image - type : Name of component sub-image type, supported types are: - "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem", - "flat_dt" and others (see uimage_type in common/image.c). + "standalone", "kernel", "kernel_noload", "ramdisk", "firmware", "script", + "filesystem", "flat_dt" and others (see uimage_type in common/image.c). - data : Path to the external file which contains this node's binary data. - compression : Compression used by included data. Supported compressions are "gzip" and "bzip2". If no compression is used compression property diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6da412d..606347f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1183,11 +1183,6 @@ int ahci_probe_scsi(struct udevice *ahci_dev) ret = ahci_start_ports(uc_priv); if (ret) return ret; - - debug("Scanning %s\n", dev->name); - ret = scsi_scan_dev(dev, true); - if (ret) - return ret; #endif return 0; diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 83b6328..e68d927 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -65,6 +65,8 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk); assert(clk); + clk->dev = NULL; + ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0, index, &args); if (ret) { @@ -102,6 +104,7 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk) int index; debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk); + clk->dev = NULL; index = dev_read_stringlist_search(dev, "clock-names", name); if (index < 0) { @@ -111,6 +114,30 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk) return clk_get_by_index(dev, index, clk); } + +int clk_release_all(struct clk *clk, int count) +{ + int i, ret; + + for (i = 0; i < count; i++) { + debug("%s(clk[%d]=%p)\n", __func__, i, &clk[i]); + + /* check if clock has been previously requested */ + if (!clk[i].dev) + continue; + + ret = clk_disable(&clk[i]); + if (ret && ret != -ENOSYS) + return ret; + + ret = clk_free(&clk[i]); + if (ret && ret != -ENOSYS) + return ret; + } + + return 0; +} + #endif /* OF_CONTROL */ int clk_request(struct udevice *dev, struct clk *clk) diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c index fcdc3c0..255a583 100644 --- a/drivers/clk/clk_stm32f7.c +++ b/drivers/clk/clk_stm32f7.c @@ -12,6 +12,8 @@ #include #include +#include + #define RCC_CR_HSION BIT(0) #define RCC_CR_HSEON BIT(16) #define RCC_CR_HSERDY BIT(17) @@ -83,6 +85,10 @@ struct pll_psc { #define APB_PSC_8 0x6 #define APB_PSC_16 0x7 +struct stm32_clk { + struct stm32_rcc_regs *base; +}; + #if !defined(CONFIG_STM32_HSE_HZ) #error "CONFIG_STM32_HSE_HZ not defined!" #else @@ -104,23 +110,26 @@ struct pll_psc sys_pll_psc = { #endif #endif -int configure_clocks(void) +static int configure_clocks(struct udevice *dev) { + struct stm32_clk *priv = dev_get_priv(dev); + struct stm32_rcc_regs *regs = priv->base; + /* Reset RCC configuration */ - setbits_le32(&STM32_RCC->cr, RCC_CR_HSION); - writel(0, &STM32_RCC->cfgr); /* Reset CFGR */ - clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON + setbits_le32(®s->cr, RCC_CR_HSION); + writel(0, ®s->cfgr); /* Reset CFGR */ + clrbits_le32(®s->cr, (RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON)); - writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */ - clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP); - writel(0, &STM32_RCC->cir); /* Disable all interrupts */ + writel(0x24003010, ®s->pllcfgr); /* Reset value from RM */ + clrbits_le32(®s->cr, RCC_CR_HSEBYP); + writel(0, ®s->cir); /* Disable all interrupts */ /* Configure for HSE+PLL operation */ - setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON); - while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY)) + setbits_le32(®s->cr, RCC_CR_HSEON); + while (!(readl(®s->cr) & RCC_CR_HSERDY)) ; - setbits_le32(&STM32_RCC->cfgr, (( + setbits_le32(®s->cfgr, (( sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT) | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT) | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT))); @@ -132,15 +141,15 @@ int configure_clocks(void) pllcfgr |= sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT; pllcfgr |= ((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT; pllcfgr |= sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT; - writel(pllcfgr, &STM32_RCC->pllcfgr); + writel(pllcfgr, ®s->pllcfgr); /* Enable the main PLL */ - setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON); - while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY)) + setbits_le32(®s->cr, RCC_CR_PLLON); + while (!(readl(®s->cr) & RCC_CR_PLLRDY)) ; /* Enable high performance mode, System frequency up to 200 MHz */ - setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN); + setbits_le32(®s->apb1enr, RCC_APB1ENR_PWREN); setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODEN); /* Infinite wait! */ while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODRDY)) @@ -152,18 +161,20 @@ int configure_clocks(void) ; stm32_flash_latency_cfg(5); - clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1)); - setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL); + clrbits_le32(®s->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1)); + setbits_le32(®s->cfgr, RCC_CFGR_SW_PLL); - while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) != + while ((readl(®s->cfgr) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL) ; return 0; } -unsigned long clock_get(enum clock clck) +static unsigned long stm32_clk_get_rate(struct clk *clk) { + struct stm32_clk *priv = dev_get_priv(clk->dev); + struct stm32_rcc_regs *regs = priv->base; u32 sysclk = 0; u32 shift = 0; /* Prescaler table lookups for clock computation */ @@ -174,53 +185,61 @@ unsigned long clock_get(enum clock clck) 0, 0, 0, 0, 1, 2, 3, 4 }; - if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) == + if ((readl(®s->cfgr) & RCC_CFGR_SWS_MASK) == RCC_CFGR_SWS_PLL) { u16 pllm, plln, pllp; - pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); - plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK) + pllm = (readl(®s->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); + plln = ((readl(®s->pllcfgr) & RCC_PLLCFGR_PLLN_MASK) >> RCC_PLLCFGR_PLLN_SHIFT); - pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK) + pllp = ((((readl(®s->pllcfgr) & RCC_PLLCFGR_PLLP_MASK) >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1); sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp; + } else { + return -EINVAL; } - switch (clck) { - case CLOCK_CORE: - return sysclk; - break; - case CLOCK_AHB: + switch (clk->id) { + /* + * AHB CLOCK: 3 x 32 bits consecutive registers are used : + * AHB1, AHB2 and AHB3 + */ + case STM32F7_AHB1_CLOCK(GPIOA) ... STM32F7_AHB3_CLOCK(QSPI): shift = ahb_psc_table[( - (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK) + (readl(®s->cfgr) & RCC_CFGR_AHB_PSC_MASK) >> RCC_CFGR_HPRE_SHIFT)]; return sysclk >>= shift; break; - case CLOCK_APB1: + /* APB1 CLOCK */ + case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8): shift = apb_psc_table[( - (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK) + (readl(®s->cfgr) & RCC_CFGR_APB1_PSC_MASK) >> RCC_CFGR_PPRE1_SHIFT)]; return sysclk >>= shift; break; - case CLOCK_APB2: + /* APB2 CLOCK */ + case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(LTDC): shift = apb_psc_table[( - (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK) + (readl(®s->cfgr) & RCC_CFGR_APB2_PSC_MASK) >> RCC_CFGR_PPRE2_SHIFT)]; return sysclk >>= shift; break; default: - return 0; + error("clock index %ld out of range\n", clk->id); + return -EINVAL; break; } } static int stm32_clk_enable(struct clk *clk) { + struct stm32_clk *priv = dev_get_priv(clk->dev); + struct stm32_rcc_regs *regs = priv->base; u32 offset = clk->id / 32; u32 bit_index = clk->id % 32; debug("%s: clkid = %ld, offset from AHB1ENR is %d, bit_index = %d\n", __func__, clk->id, offset, bit_index); - setbits_le32(&STM32_RCC->ahb1enr + offset, BIT(bit_index)); + setbits_le32(®s->ahb1enr + offset, BIT(bit_index)); return 0; } @@ -247,7 +266,17 @@ void clock_setup(int peripheral) static int stm32_clk_probe(struct udevice *dev) { debug("%s: stm32_clk_probe\n", __func__); - configure_clocks(); + + struct stm32_clk *priv = dev_get_priv(dev); + fdt_addr_t addr; + + addr = devfdt_get_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base = (struct stm32_rcc_regs *)addr; + + configure_clocks(dev); return 0; } @@ -272,6 +301,7 @@ static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) static struct clk_ops stm32_clk_ops = { .of_xlate = stm32_clk_of_xlate, .enable = stm32_clk_enable, + .get_rate = stm32_clk_get_rate, }; static const struct udevice_id stm32_clk_ids[] = { diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c index 52cad38..e1d9aeb 100644 --- a/drivers/clk/rockchip/clk_rk3368.c +++ b/drivers/clk/rockchip/clk_rk3368.c @@ -283,7 +283,7 @@ U_BOOT_DRIVER(rockchip_rk3368_cru) = { .name = "rockchip_rk3368_cru", .id = UCLASS_CLK, .of_match = rk3368_clk_ids, - .priv_auto_alloc_size = sizeof(struct rk3368_cru), + .priv_auto_alloc_size = sizeof(struct rk3368_clk_priv), .ofdata_to_platdata = rk3368_clk_ofdata_to_platdata, .ops = &rk3368_clk_ops, .bind = rk3368_clk_bind, diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index fb5c4e8..f8b19a4 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -16,10 +16,10 @@ config SPL_DM suitable malloc() implementation. If you are not using the full malloc() enabled by CONFIG_SYS_SPL_MALLOC_START, consider using CONFIG_SYS_MALLOC_SIMPLE. In that case you - must provide CONFIG_SYS_MALLOC_F_LEN to set the size. + must provide CONFIG_SPL_SYS_MALLOC_F_LEN to set the size. In most cases driver model will only allocate a few uclasses and devices in SPL, so 1KB should be enable. See - CONFIG_SYS_MALLOC_F_LEN for more details on how to enable it. + CONFIG_SPL_SYS_MALLOC_F_LEN for more details on how to enable it. config TPL_DM bool "Enable Driver Model for TPL" @@ -29,10 +29,10 @@ config TPL_DM suitable malloc() implementation. If you are not using the full malloc() enabled by CONFIG_SYS_SPL_MALLOC_START, consider using CONFIG_SYS_MALLOC_SIMPLE. In that case you - must provide CONFIG_SYS_MALLOC_F_LEN to set the size. + must provide CONFIG_SPL_SYS_MALLOC_F_LEN to set the size. In most cases driver model will only allocate a few uclasses and devices in SPL, so 1KB should be enough. See - CONFIG_SYS_MALLOC_F_LEN for more details on how to enable it. + CONFIG_SPL_SYS_MALLOC_F_LEN for more details on how to enable it. Disable this for very small implementations. config DM_WARN diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 2bb23ee..c31cba7 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -665,6 +665,13 @@ int of_parse_phandle_with_args(const struct device_node *np, index, out_args); } +int of_count_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name) +{ + return __of_parse_phandle_with_args(np, list_name, cells_name, 0, + -1, NULL); +} + static void of_alias_add(struct alias_prop *ap, struct device_node *np, int id, const char *stem, int stem_len) { diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index fd068b0..c1a2e9f 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -14,6 +14,7 @@ #include #include #include +#include int ofnode_read_u32(ofnode node, const char *propname, u32 *outp) { @@ -198,13 +199,14 @@ fdt_addr_t ofnode_get_addr_index(ofnode node, int index) const __be32 *prop_val; uint flags; u64 size; + int na; - prop_val = of_get_address( - (struct device_node *)ofnode_to_np(node), index, - &size, &flags); + prop_val = of_get_address(ofnode_to_np(node), index, &size, + &flags); if (!prop_val) return FDT_ADDR_T_NONE; - return be32_to_cpup(prop_val); + na = of_n_addr_cells(ofnode_to_np(node)); + return of_read_number(prop_val, na); } else { return fdt_get_base_address(gd->fdt_blob, ofnode_to_offset(node)); @@ -313,6 +315,18 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, return 0; } +int ofnode_count_phandle_with_args(ofnode node, const char *list_name, + const char *cells_name) +{ + if (ofnode_is_np(node)) + return of_count_phandle_with_args(ofnode_to_np(node), + list_name, cells_name); + else + return fdtdec_parse_phandle_with_args(gd->fdt_blob, + ofnode_to_offset(node), list_name, cells_name, + 0, -1, NULL); +} + ofnode ofnode_path(const char *path) { if (of_live_active()) @@ -593,3 +607,23 @@ bool ofnode_pre_reloc(ofnode node) return false; } + +int ofnode_read_resource(ofnode node, uint index, struct resource *res) +{ + if (ofnode_is_np(node)) { + return of_address_to_resource(ofnode_to_np(node), index, res); + } else { + struct fdt_resource fres; + int ret; + + ret = fdt_get_resource(gd->fdt_blob, ofnode_to_offset(node), + "reg", index, &fres); + if (ret < 0) + return -EINVAL; + memset(res, '\0', sizeof(*res)); + res->start = fres.start; + res->end = fres.end; + + return 0; + } +} diff --git a/drivers/core/read.c b/drivers/core/read.c index eafe727..fe40bed 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -114,7 +114,7 @@ int dev_read_phandle(struct udevice *dev) return fdt_get_phandle(gd->fdt_blob, ofnode_to_offset(node)); } -const u32 *dev_read_prop(struct udevice *dev, const char *propname, int *lenp) +const void *dev_read_prop(struct udevice *dev, const char *propname, int *lenp) { return ofnode_get_property(dev_ofnode(dev), propname, lenp); } @@ -159,3 +159,8 @@ int dev_read_enabled(struct udevice *dev) return fdtdec_get_is_enabled(gd->fdt_blob, ofnode_to_offset(node)); } + +int dev_read_resource(struct udevice *dev, uint index, struct resource *res) +{ + return ofnode_read_resource(dev_ofnode(dev), index, res); +} diff --git a/drivers/core/read_extra.c b/drivers/core/read_extra.c index a6d2f34..e94648f 100644 --- a/drivers/core/read_extra.c +++ b/drivers/core/read_extra.c @@ -11,27 +11,4 @@ #include #include -int dev_read_resource(struct udevice *dev, uint index, struct resource *res) -{ - ofnode node = dev_ofnode(dev); - -#ifdef CONFIG_OF_LIVE - if (ofnode_is_np(node)) { - return of_address_to_resource(ofnode_to_np(node), index, res); - } else -#endif - { - struct fdt_resource fres; - int ret; - - ret = fdt_get_resource(gd->fdt_blob, ofnode_to_offset(node), - "reg", index, &fres); - if (ret < 0) - return -EINVAL; - memset(res, '\0', sizeof(*res)); - res->start = fres.start; - res->end = fres.end; - - return 0; - } -} +/* This file can hold non-inlined dev_read_...() functions */ diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index ceb33e3..f6281f4 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -165,18 +165,48 @@ static int dfu_write_buffer_drain(struct dfu_entity *dfu) return ret; } -void dfu_write_transaction_cleanup(struct dfu_entity *dfu) +void dfu_transaction_cleanup(struct dfu_entity *dfu) { /* clear everything */ dfu->crc = 0; dfu->offset = 0; dfu->i_blk_seq_num = 0; - dfu->i_buf_start = dfu_buf; - dfu->i_buf_end = dfu_buf; + dfu->i_buf_start = dfu_get_buf(dfu); + dfu->i_buf_end = dfu->i_buf_start; dfu->i_buf = dfu->i_buf_start; + dfu->r_left = 0; + dfu->b_left = 0; + dfu->bad_skip = 0; + dfu->inited = 0; } +int dfu_transaction_initiate(struct dfu_entity *dfu, bool read) +{ + int ret = 0; + + if (dfu->inited) + return 0; + + dfu_transaction_cleanup(dfu); + + if (dfu->i_buf_start == NULL) + return -ENOMEM; + + dfu->i_buf_end = dfu->i_buf_start + dfu_get_buf_size(); + + if (read) { + ret = dfu->get_medium_size(dfu, &dfu->r_left); + if (ret < 0) + return ret; + debug("%s: %s %lld [B]\n", __func__, dfu->name, dfu->r_left); + } + + dfu->inited = 1; + + return 0; +} + int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) { int ret = 0; @@ -192,7 +222,7 @@ int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) printf("\nDFU complete %s: 0x%08x\n", dfu_hash_algo->name, dfu->crc); - dfu_write_transaction_cleanup(dfu); + dfu_transaction_cleanup(dfu); return ret; } @@ -205,25 +235,14 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) __func__, dfu->name, buf, size, blk_seq_num, dfu->offset, (unsigned long)(dfu->i_buf - dfu->i_buf_start)); - if (!dfu->inited) { - /* initial state */ - dfu->crc = 0; - dfu->offset = 0; - dfu->bad_skip = 0; - dfu->i_blk_seq_num = 0; - dfu->i_buf_start = dfu_get_buf(dfu); - if (dfu->i_buf_start == NULL) - return -ENOMEM; - dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size; - dfu->i_buf = dfu->i_buf_start; - - dfu->inited = 1; - } + ret = dfu_transaction_initiate(dfu, false); + if (ret < 0) + return ret; if (dfu->i_blk_seq_num != blk_seq_num) { printf("%s: Wrong sequence number! [%d] [%d]\n", __func__, dfu->i_blk_seq_num, blk_seq_num); - dfu_write_transaction_cleanup(dfu); + dfu_transaction_cleanup(dfu); return -1; } @@ -247,7 +266,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) if ((dfu->i_buf + size) > dfu->i_buf_end) { ret = dfu_write_buffer_drain(dfu); if (ret) { - dfu_write_transaction_cleanup(dfu); + dfu_transaction_cleanup(dfu); return ret; } } @@ -256,7 +275,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) if ((dfu->i_buf + size) > dfu->i_buf_end) { error("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf, size, dfu->i_buf_end); - dfu_write_transaction_cleanup(dfu); + dfu_transaction_cleanup(dfu); return -1; } @@ -267,7 +286,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) if (size == 0 || (dfu->i_buf + size) > dfu->i_buf_end) { ret = dfu_write_buffer_drain(dfu); if (ret) { - dfu_write_transaction_cleanup(dfu); + dfu_transaction_cleanup(dfu); return ret; } } @@ -334,28 +353,9 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n", __func__, dfu->name, buf, size, blk_seq_num, dfu->i_buf); - if (!dfu->inited) { - dfu->i_buf_start = dfu_get_buf(dfu); - if (dfu->i_buf_start == NULL) - return -ENOMEM; - - dfu->r_left = dfu->get_medium_size(dfu); - if (dfu->r_left < 0) - return dfu->r_left; - - debug("%s: %s %ld [B]\n", __func__, dfu->name, dfu->r_left); - - dfu->i_blk_seq_num = 0; - dfu->crc = 0; - dfu->offset = 0; - dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size; - dfu->i_buf = dfu->i_buf_start; - dfu->b_left = 0; - - dfu->bad_skip = 0; - - dfu->inited = 1; - } + ret = dfu_transaction_initiate(dfu, true); + if (ret < 0) + return ret; if (dfu->i_blk_seq_num != blk_seq_num) { printf("%s: Wrong sequence number! [%d] [%d]\n", @@ -377,17 +377,7 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) dfu_hash_algo->name, dfu->crc); puts("\nUPLOAD ... done\nCtrl+C to exit ...\n"); - dfu->i_blk_seq_num = 0; - dfu->crc = 0; - dfu->offset = 0; - dfu->i_buf_start = dfu_buf; - dfu->i_buf_end = dfu_buf; - dfu->i_buf = dfu->i_buf_start; - dfu->b_left = 0; - - dfu->bad_skip = 0; - - dfu->inited = 0; + dfu_transaction_cleanup(dfu); } return ret; diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index 926ccbd..bb23e7f 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -17,7 +17,7 @@ #include static unsigned char *dfu_file_buf; -static long dfu_file_buf_len; +static u64 dfu_file_buf_len; static long dfu_file_buf_filled; static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, @@ -107,7 +107,7 @@ static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len) } static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu, - void *buf, long *len) + void *buf, u64 *len) { const char *fsname, *opname; char cmd_buf[DFU_CMD_BUF_SIZE]; @@ -150,7 +150,7 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu, sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name); if (op == DFU_OP_WRITE) - sprintf(cmd_buf + strlen(cmd_buf), " %lx", *len); + sprintf(cmd_buf + strlen(cmd_buf), " %llx", *len); debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); @@ -209,23 +209,23 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu) return ret; } -long dfu_get_medium_size_mmc(struct dfu_entity *dfu) +int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 *size) { int ret; - long len; switch (dfu->layout) { case DFU_RAW_ADDR: - return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; + *size = dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; + return 0; case DFU_FS_FAT: case DFU_FS_EXT4: dfu_file_buf_filled = -1; - ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len); + ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, size); if (ret < 0) return ret; - if (len > CONFIG_SYS_DFU_MAX_FILE_SIZE) + if (*size > CONFIG_SYS_DFU_MAX_FILE_SIZE) return -1; - return len; + return 0; default: printf("%s: Layout (%s) not (yet) supported!\n", __func__, dfu_get_layout(dfu->layout)); @@ -237,7 +237,7 @@ static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf, long *len) { int ret; - long file_len; + u64 file_len; if (dfu_file_buf_filled == -1) { ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len); diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c index 97cd608..6dc9ff7 100644 --- a/drivers/dfu/dfu_nand.c +++ b/drivers/dfu/dfu_nand.c @@ -114,9 +114,11 @@ static int dfu_write_medium_nand(struct dfu_entity *dfu, return ret; } -long dfu_get_medium_size_nand(struct dfu_entity *dfu) +int dfu_get_medium_size_nand(struct dfu_entity *dfu, u64 *size) { - return dfu->data.nand.size; + *size = dfu->data.nand.size; + + return 0; } static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf, diff --git a/drivers/dfu/dfu_ram.c b/drivers/dfu/dfu_ram.c index c1b0021..6e3f531 100644 --- a/drivers/dfu/dfu_ram.c +++ b/drivers/dfu/dfu_ram.c @@ -41,9 +41,11 @@ static int dfu_write_medium_ram(struct dfu_entity *dfu, u64 offset, return dfu_transfer_medium_ram(DFU_OP_WRITE, dfu, offset, buf, len); } -long dfu_get_medium_size_ram(struct dfu_entity *dfu) +int dfu_get_medium_size_ram(struct dfu_entity *dfu, u64 *size) { - return dfu->data.ram.size; + *size = dfu->data.ram.size; + + return 0; } static int dfu_read_medium_ram(struct dfu_entity *dfu, u64 offset, diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c index b6d5fe2..2d2586d 100644 --- a/drivers/dfu/dfu_sf.c +++ b/drivers/dfu/dfu_sf.c @@ -12,9 +12,11 @@ #include #include -static long dfu_get_medium_size_sf(struct dfu_entity *dfu) +static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size) { - return dfu->data.sf.size; + *size = dfu->data.sf.size; + + return 0; } static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf, diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index 687cd74..4965583 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -337,11 +337,13 @@ static int gpio_tegra_bind(struct udevice *parent) * This driver does not make use of interrupts, other than to figure * out the number of GPIO banks */ - if (!fdt_getprop(gd->fdt_blob, dev_of_offset(parent), "interrupts", - &len)) - return -EINVAL; + len = dev_read_size(parent, "interrupts"); + if (len < 0) + return len; bank_count = len / 3 / sizeof(u32); - ctlr = (struct gpio_ctlr *)devfdt_get_addr(parent); + ctlr = (struct gpio_ctlr *)dev_read_addr(parent); + if ((ulong)ctlr == FDT_ADDR_T_NONE) + return -EINVAL; } #endif for (bank = 0; bank < bank_count; bank++) { diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c index 055f481..3255e8e 100644 --- a/drivers/i2c/tegra_i2c.c +++ b/drivers/i2c/tegra_i2c.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -365,7 +364,11 @@ static int tegra_i2c_probe(struct udevice *dev) i2c_bus->id = dev->seq; i2c_bus->type = dev_get_driver_data(dev); - i2c_bus->regs = (struct i2c_ctlr *)devfdt_get_addr(dev); + i2c_bus->regs = (struct i2c_ctlr *)dev_read_addr(dev); + if ((ulong)i2c_bus->regs == FDT_ADDR_T_NONE) { + debug("%s: Cannot get regs address\n", __func__); + return -EINVAL; + } ret = reset_get_by_name(dev, "i2c", &i2c_bus->reset_ctl); if (ret) { diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 423d24c..2e3bc91 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -142,7 +142,7 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) { struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); - plat->base = (void *)devfdt_get_addr(dev); + plat->base = (void *)dev_read_addr(dev); return 0; } diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 7d945a1..7474529 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -11,10 +11,10 @@ #include #include #include +#include #include #include #include -#include DECLARE_GLOBAL_DATA_PTR; @@ -599,8 +599,7 @@ static int tegra_mmc_probe(struct udevice *dev) cfg->name = dev->name; - bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), - "bus-width", 1); + bus_width = dev_read_u32_default(dev, "bus-width", 1); cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; cfg->host_caps = 0; @@ -621,7 +620,7 @@ static int tegra_mmc_probe(struct udevice *dev) cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - priv->reg = (void *)devfdt_get_addr(dev); + priv->reg = (void *)dev_read_addr(dev); ret = reset_get_by_name(dev, "sdhci", &priv->reset_ctl); if (ret) { @@ -648,12 +647,10 @@ static int tegra_mmc_probe(struct udevice *dev) return ret; /* These GPIOs are optional */ - gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, - GPIOD_IS_IN); - gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, - GPIOD_IS_IN); - gpio_request_by_name(dev, "power-gpios", 0, - &priv->pwr_gpio, GPIOD_IS_OUT); + gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); + gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); + gpio_request_by_name(dev, "power-gpios", 0, &priv->pwr_gpio, + GPIOD_IS_OUT); if (dm_gpio_is_valid(&priv->pwr_gpio)) dm_gpio_set_value(&priv->pwr_gpio, 1); diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index 7d9c63b..cb5cf8b 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -25,6 +24,7 @@ #include #include +#include #include #ifndef CONFIG_TEGRA186 @@ -220,9 +220,9 @@ struct tegra_pcie_soc { struct tegra_pcie { struct pci_controller hose; - struct fdt_resource pads; - struct fdt_resource afi; - struct fdt_resource cs; + struct resource pads; + struct resource afi; + struct resource cs; struct list_head ports; unsigned long xbar; @@ -364,13 +364,12 @@ static int pci_tegra_write_config(struct udevice *bus, pci_dev_t bdf, return 0; } -static int tegra_pcie_port_parse_dt(const void *fdt, int node, - struct tegra_pcie_port *port) +static int tegra_pcie_port_parse_dt(ofnode node, struct tegra_pcie_port *port) { const u32 *addr; int len; - addr = fdt_getprop(fdt, node, "assigned-addresses", &len); + addr = ofnode_get_property(node, "assigned-addresses", &len); if (!addr) { error("property \"assigned-addresses\" not found"); return -FDT_ERR_NOTFOUND; @@ -382,7 +381,7 @@ static int tegra_pcie_port_parse_dt(const void *fdt, int node, return 0; } -static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes, +static int tegra_pcie_get_xbar_config(ofnode node, u32 lanes, enum tegra_pci_id id, unsigned long *xbar) { switch (id) { @@ -456,14 +455,12 @@ static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes, return -FDT_ERR_NOTFOUND; } -static int tegra_pcie_parse_port_info(const void *fdt, int node, - unsigned int *index, - unsigned int *lanes) +static int tegra_pcie_parse_port_info(ofnode node, uint *index, uint *lanes) { struct fdt_pci_addr addr; int err; - err = fdtdec_get_int(fdt, node, "nvidia,num-lanes", 0); + err = ofnode_read_u32_default(node, "nvidia,num-lanes", -1); if (err < 0) { error("failed to parse \"nvidia,num-lanes\" property"); return err; @@ -471,7 +468,7 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node, *lanes = err; - err = fdtdec_get_pci_addr(fdt, node, 0, "reg", &addr); + err = ofnode_read_pci_addr(node, 0, "reg", &addr); if (err < 0) { error("failed to parse \"reg\" property"); return err; @@ -487,28 +484,26 @@ int __weak tegra_pcie_board_init(void) return 0; } -static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, +static int tegra_pcie_parse_dt(struct udevice *dev, enum tegra_pci_id id, struct tegra_pcie *pcie) { - int err, subnode; + ofnode subnode; u32 lanes = 0; + int err; - err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pads", - &pcie->pads); + err = dev_read_resource(dev, 0, &pcie->pads); if (err < 0) { error("resource \"pads\" not found"); return err; } - err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "afi", - &pcie->afi); + err = dev_read_resource(dev, 1, &pcie->afi); if (err < 0) { error("resource \"afi\" not found"); return err; } - err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "cs", - &pcie->cs); + err = dev_read_resource(dev, 2, &pcie->cs); if (err < 0) { error("resource \"cs\" not found"); return err; @@ -531,12 +526,11 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, } #endif - fdt_for_each_subnode(subnode, fdt, node) { + dev_for_each_subnode(subnode, dev) { unsigned int index = 0, num_lanes = 0; struct tegra_pcie_port *port; - err = tegra_pcie_parse_port_info(fdt, subnode, &index, - &num_lanes); + err = tegra_pcie_parse_port_info(subnode, &index, &num_lanes); if (err < 0) { error("failed to obtain root port info"); continue; @@ -544,7 +538,7 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, lanes |= num_lanes << (index << 3); - if (!fdtdec_get_is_enabled(fdt, subnode)) + if (!ofnode_is_available(subnode)) continue; port = malloc(sizeof(*port)); @@ -555,7 +549,7 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, port->num_lanes = num_lanes; port->index = index; - err = tegra_pcie_port_parse_dt(fdt, subnode, port); + err = tegra_pcie_port_parse_dt(subnode, port); if (err < 0) { free(port); continue; @@ -565,7 +559,8 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, port->pcie = pcie; } - err = tegra_pcie_get_xbar_config(fdt, node, lanes, id, &pcie->xbar); + err = tegra_pcie_get_xbar_config(dev_ofnode(dev), lanes, id, + &pcie->xbar); if (err < 0) { error("invalid lane configuration"); return err; @@ -815,7 +810,7 @@ static int tegra_pcie_setup_translations(struct udevice *bus) /* BAR 0: type 1 extended configuration space */ fpci = 0xfe100000; - size = fdt_resource_size(&pcie->cs); + size = resource_size(&pcie->cs); axi = pcie->cs.start; afi_writel(pcie, axi, AFI_AXI_BAR0_START); @@ -1099,7 +1094,7 @@ static int pci_tegra_ofdata_to_platdata(struct udevice *dev) INIT_LIST_HEAD(&pcie->ports); - if (tegra_pcie_parse_dt(gd->fdt_blob, dev_of_offset(dev), id, pcie)) + if (tegra_pcie_parse_dt(dev, id, pcie)) return -EINVAL; return 0; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 7841554..98f2a1b 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -41,6 +41,24 @@ config PHY_SANDBOX This select a dummy sandbox PHY driver. It used only to implement the unit tests for the phy framework +config NOP_PHY + bool "NOP PHY driver" + depends on PHY + help + Support for a no-op PHY driver (stubbed PHY driver). + + This is useful when a driver uses the PHY framework but no real PHY + hardware exists. + +config SPL_NOP_PHY + bool "NOP PHY driver in SPL" + depends on SPL_PHY + help + Support for a no-op PHY driver (stubbed PHY driver) in the SPL. + + This is useful when a driver uses the PHY framework but no real PHY + hardware exists. + config PIPE3_PHY bool "Support omap's PIPE3 PHY" depends on PHY && ARCH_OMAP2PLUS diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 6ce96d2..ab56c46 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -6,5 +6,6 @@ # obj-$(CONFIG_$(SPL_)PHY) += phy-uclass.o +obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c new file mode 100644 index 0000000..2201cc3 --- /dev/null +++ b/drivers/phy/nop-phy.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * Written by Jean-Jacques Hiblot + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static const struct udevice_id nop_phy_ids[] = { + { .compatible = "nop-phy" }, + { } +}; + +static struct phy_ops nop_phy_ops = { +}; + +U_BOOT_DRIVER(nop_phy) = { + .name = "nop_phy", + .id = UCLASS_PHY, + .of_match = nop_phy_ids, + .ops = &nop_phy_ops, +}; diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index d8b8d58..68e518f 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -45,6 +45,7 @@ int generic_phy_get_by_index(struct udevice *dev, int index, debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy); assert(phy); + phy->dev = NULL; ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index, &args); if (ret) { diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c index 2fa840c..87c9912 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c @@ -391,14 +391,33 @@ static struct meson_pmx_func meson_gxbb_aobus_functions[] = { FUNCTION(i2c_slave_ao), }; +static struct meson_bank meson_gxbb_periphs_banks[] = { + /* name first last pullen pull dir out in */ + BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), + BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF), 1, 0, 1, 0, 3, 0, 4, 0, 5, 0), + BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), + BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_3, EE_OFF), 1, 20, 1, 20, 3, 20, 4, 20, 5, 20), + BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), + BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 2, 20, 2, 20, 6, 20, 7, 20, 8, 20), + BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_17, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), + BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_3, EE_OFF), 3, 28, 3, 28, 9, 28, 10, 28, 11, 28), +}; + +static struct meson_bank meson_gxbb_aobus_banks[] = { + /* name first last pullen pull dir out in */ + BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), +}; + struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = { .name = "periphs-banks", .pin_base = 14, .groups = meson_gxbb_periphs_groups, .funcs = meson_gxbb_periphs_functions, + .banks = meson_gxbb_periphs_banks, .num_pins = 120, .num_groups = ARRAY_SIZE(meson_gxbb_periphs_groups), .num_funcs = ARRAY_SIZE(meson_gxbb_periphs_functions), + .num_banks = ARRAY_SIZE(meson_gxbb_periphs_banks), }; struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = { @@ -406,9 +425,11 @@ struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = { .pin_base = 0, .groups = meson_gxbb_aobus_groups, .funcs = meson_gxbb_aobus_functions, + .banks = meson_gxbb_aobus_banks, .num_pins = 14, .num_groups = ARRAY_SIZE(meson_gxbb_aobus_groups), .num_funcs = ARRAY_SIZE(meson_gxbb_aobus_functions), + .num_banks = ARRAY_SIZE(meson_gxbb_aobus_banks), }; static const struct udevice_id meson_gxbb_pinctrl_match[] = { diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 6281f52..a860200 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -6,11 +6,14 @@ #include #include +#include +#include #include #include #include #include #include +#include #include "pinctrl-meson.h" @@ -117,6 +120,143 @@ const struct pinctrl_ops meson_pinctrl_ops = { .set_state = pinctrl_generic_set_state, }; +static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset, + enum meson_reg_type reg_type, + unsigned int *reg, unsigned int *bit) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + struct meson_bank *bank = NULL; + struct meson_reg_desc *desc; + unsigned int pin; + int i; + + pin = priv->data->pin_base + offset; + + for (i = 0; i < priv->data->num_banks; i++) { + if (pin >= priv->data->banks[i].first && + pin <= priv->data->banks[i].last) { + bank = &priv->data->banks[i]; + break; + } + } + + if (!bank) + return -EINVAL; + + desc = &bank->regs[reg_type]; + *reg = desc->reg * 4; + *bit = desc->bit + pin - bank->first; + + return 0; +} + +static int meson_gpio_get(struct udevice *dev, unsigned int offset) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_IN, ®, &bit); + if (ret) + return ret; + + return !!(readl(priv->reg_gpio + reg) & BIT(bit)); +} + +static int meson_gpio_set(struct udevice *dev, unsigned int offset, int value) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0); + + return 0; +} + +static int meson_gpio_get_direction(struct udevice *dev, unsigned int offset) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit, val; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit); + if (ret) + return ret; + + val = readl(priv->reg_gpio + reg); + + return (val & BIT(bit)) ? GPIOF_INPUT : GPIOF_OUTPUT; +} + +static int meson_gpio_direction_input(struct udevice *dev, unsigned int offset) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), 1); + + return 0; +} + +static int meson_gpio_direction_output(struct udevice *dev, + unsigned int offset, int value) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + unsigned int reg, bit; + int ret; + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), 0); + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, ®, &bit); + if (ret) + return ret; + + clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0); + + return 0; +} + +static int meson_gpio_probe(struct udevice *dev) +{ + struct meson_pinctrl *priv = dev_get_priv(dev->parent); + struct gpio_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + uc_priv->bank_name = priv->data->name; + uc_priv->gpio_count = priv->data->num_pins; + + return 0; +} + +static const struct dm_gpio_ops meson_gpio_ops = { + .set_value = meson_gpio_set, + .get_value = meson_gpio_get, + .get_function = meson_gpio_get_direction, + .direction_input = meson_gpio_direction_input, + .direction_output = meson_gpio_direction_output, +}; + +static struct driver meson_gpio_driver = { + .name = "meson-gpio", + .id = UCLASS_GPIO, + .probe = meson_gpio_probe, + .ops = &meson_gpio_ops, +}; + static fdt_addr_t parse_address(int offset, const char *name, int na, int ns) { int index, len = 0; @@ -138,9 +278,12 @@ static fdt_addr_t parse_address(int offset, const char *name, int na, int ns) int meson_pinctrl_probe(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev); + struct uclass_driver *drv; + struct udevice *gpio_dev; fdt_addr_t addr; int node, gpio = -1, len; int na, ns; + char *name; na = fdt_address_cells(gd->fdt_blob, dev_of_offset(dev->parent)); if (na < 1) { @@ -168,12 +311,32 @@ int meson_pinctrl_probe(struct udevice *dev) addr = parse_address(gpio, "mux", na, ns); if (addr == FDT_ADDR_T_NONE) { - debug("mux not found\n"); + debug("mux address not found\n"); return -EINVAL; } - priv->reg_mux = (void __iomem *)addr; + + addr = parse_address(gpio, "gpio", na, ns); + if (addr == FDT_ADDR_T_NONE) { + debug("gpio address not found\n"); + return -EINVAL; + } + priv->reg_gpio = (void __iomem *)addr; priv->data = (struct meson_pinctrl_data *)dev_get_driver_data(dev); + /* Lookup GPIO driver */ + drv = lists_uclass_lookup(UCLASS_GPIO); + if (!drv) { + puts("Cannot find GPIO driver\n"); + return -ENOENT; + } + + name = calloc(1, 32); + sprintf(name, "meson-gpio"); + + /* Create child device UCLASS_GPIO and bind it */ + device_bind(dev, &meson_gpio_driver, name, NULL, gpio, &gpio_dev); + dev_set_of_offset(gpio_dev, gpio); + return 0; } diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 4127a60..90d2369 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -28,15 +28,64 @@ struct meson_pinctrl_data { const char *name; struct meson_pmx_group *groups; struct meson_pmx_func *funcs; + struct meson_bank *banks; unsigned int pin_base; unsigned int num_pins; unsigned int num_groups; unsigned int num_funcs; + unsigned int num_banks; }; struct meson_pinctrl { struct meson_pinctrl_data *data; void __iomem *reg_mux; + void __iomem *reg_gpio; +}; + +/** + * struct meson_reg_desc - a register descriptor + * + * @reg: register offset in the regmap + * @bit: bit index in register + * + * The structure describes the information needed to control pull, + * pull-enable, direction, etc. for a single pin + */ +struct meson_reg_desc { + unsigned int reg; + unsigned int bit; +}; + +/** + * enum meson_reg_type - type of registers encoded in @meson_reg_desc + */ +enum meson_reg_type { + REG_PULLEN, + REG_PULL, + REG_DIR, + REG_OUT, + REG_IN, + NUM_REG, +}; + +/** + * struct meson bank + * + * @name: bank name + * @first: first pin of the bank + * @last: last pin of the bank + * @regs: array of register descriptors + * + * A bank represents a set of pins controlled by a contiguous set of + * bits in the domain registers. The structure specifies which bits in + * the regmap control the different functionalities. Each member of + * the @regs array refers to the first pin of the bank. + */ +struct meson_bank { + const char *name; + unsigned int first; + unsigned int last; + struct meson_reg_desc regs[NUM_REG]; }; #define PIN(x, b) (b + x) @@ -65,6 +114,20 @@ struct meson_pinctrl { .num_groups = ARRAY_SIZE(fn ## _groups), \ } +#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \ + { \ + .name = n, \ + .first = f, \ + .last = l, \ + .regs = { \ + [REG_PULLEN] = { per, peb }, \ + [REG_PULL] = { pr, pb }, \ + [REG_DIR] = { dr, db }, \ + [REG_OUT] = { or, ob }, \ + [REG_IN] = { ir, ib }, \ + }, \ + } + #define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x) extern const struct pinctrl_ops meson_pinctrl_ops; diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c index 3c9ae97..a21b640 100644 --- a/drivers/pinctrl/rockchip/pinctrl_rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c @@ -496,16 +496,18 @@ static void pinctrl_rk3288_gmac_config(struct rk3288_grf *grf, int gmac_id) (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(6)) | (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(7))); + rk_clrsetreg(&grf->gpio4bl_iomux, + GPIO4B1_MASK << GPIO4B1_SHIFT, + GPIO4B1_MAC_TXCLK << GPIO4B1_SHIFT); + /* switch GPIO4B1 to 12ma drive-strength */ rk_clrsetreg(&grf->gpio1_e[3][1], GPIO_BIAS_MASK << GPIO_BIAS_SHIFT(1), GPIO_BIAS_12MA << GPIO_BIAS_SHIFT(1)); - /* Set pull normal for GPIO4B1, pull up for GPIO4B0 */ + /* Set pull normal for GPIO4B1 */ rk_clrsetreg(&grf->gpio1_p[3][1], - (GPIO_PULL_MASK << GPIO_PULL_SHIFT(0)) | (GPIO_PULL_MASK << GPIO_PULL_SHIFT(1)), - (GPIO_PULL_UP << GPIO_PULL_SHIFT(0)) | (GPIO_PULL_NORMAL << GPIO_PULL_SHIFT(1))); break; @@ -727,7 +729,7 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, value |= (mask << (shift + 16)) | (muxval << shift); writel(value, addr); - /* Handle pullup/pulldown */ + /* Handle pullup/pulldown/drive-strength */ if (flags) { uint val = 0; @@ -735,10 +737,15 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, val = 1; else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN)) val = 2; + else if (flags & (1 << PIN_CONFIG_DRIVE_STRENGTH)) + val = 3; + shift = (index & 7) * 2; ind = index >> 3; if (banknum == 0) addr = &priv->pmu->gpio0pull[ind]; + else if (flags & (1 << PIN_CONFIG_DRIVE_STRENGTH)) + addr = &priv->grf->gpio1_e[banknum - 1][ind]; else addr = &priv->grf->gpio1_p[banknum - 1][ind]; debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val, @@ -777,6 +784,9 @@ static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config) if (flags < 0) return flags; + if (fdtdec_get_int(blob, pcfg_node, "drive-strength", 0) == 12) + flags |= 1 << PIN_CONFIG_DRIVE_STRENGTH; + ret = rk3288_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2], flags); if (ret) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c index 9c2db1a..e2b234f 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c @@ -59,12 +59,12 @@ static const struct uniphier_pinctrl_group uniphier_ld11_groups[] = { UNIPHIER_PINCTRL_GROUP(i2c3), UNIPHIER_PINCTRL_GROUP(i2c4), UNIPHIER_PINCTRL_GROUP(nand), - UNIPHIER_PINCTRL_GROUP_SPL(system_bus), - UNIPHIER_PINCTRL_GROUP_SPL(system_bus_cs1), - UNIPHIER_PINCTRL_GROUP_SPL(uart0), - UNIPHIER_PINCTRL_GROUP_SPL(uart1), - UNIPHIER_PINCTRL_GROUP_SPL(uart2), - UNIPHIER_PINCTRL_GROUP_SPL(uart3), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), UNIPHIER_PINCTRL_GROUP(usb0), UNIPHIER_PINCTRL_GROUP(usb1), UNIPHIER_PINCTRL_GROUP(usb2), @@ -78,11 +78,11 @@ static const char * const uniphier_ld11_functions[] = { UNIPHIER_PINMUX_FUNCTION(i2c3), UNIPHIER_PINMUX_FUNCTION(i2c4), UNIPHIER_PINMUX_FUNCTION(nand), - UNIPHIER_PINMUX_FUNCTION_SPL(system_bus), - UNIPHIER_PINMUX_FUNCTION_SPL(uart0), - UNIPHIER_PINMUX_FUNCTION_SPL(uart1), - UNIPHIER_PINMUX_FUNCTION_SPL(uart2), - UNIPHIER_PINMUX_FUNCTION_SPL(uart3), + UNIPHIER_PINMUX_FUNCTION(system_bus), + UNIPHIER_PINMUX_FUNCTION(uart0), + UNIPHIER_PINMUX_FUNCTION(uart1), + UNIPHIER_PINMUX_FUNCTION(uart2), + UNIPHIER_PINMUX_FUNCTION(uart3), UNIPHIER_PINMUX_FUNCTION(usb0), UNIPHIER_PINMUX_FUNCTION(usb1), UNIPHIER_PINMUX_FUNCTION(usb2), diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c index 0b0af1c..11d5d98 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c @@ -69,12 +69,12 @@ static const struct uniphier_pinctrl_group uniphier_ld20_groups[] = { UNIPHIER_PINCTRL_GROUP(i2c4), UNIPHIER_PINCTRL_GROUP(nand), UNIPHIER_PINCTRL_GROUP(sd), - UNIPHIER_PINCTRL_GROUP_SPL(system_bus), - UNIPHIER_PINCTRL_GROUP_SPL(system_bus_cs1), - UNIPHIER_PINCTRL_GROUP_SPL(uart0), - UNIPHIER_PINCTRL_GROUP_SPL(uart1), - UNIPHIER_PINCTRL_GROUP_SPL(uart2), - UNIPHIER_PINCTRL_GROUP_SPL(uart3), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), UNIPHIER_PINCTRL_GROUP(usb0), UNIPHIER_PINCTRL_GROUP(usb1), UNIPHIER_PINCTRL_GROUP(usb2), @@ -91,11 +91,11 @@ static const char * const uniphier_ld20_functions[] = { UNIPHIER_PINMUX_FUNCTION(i2c4), UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), - UNIPHIER_PINMUX_FUNCTION_SPL(system_bus), - UNIPHIER_PINMUX_FUNCTION_SPL(uart0), - UNIPHIER_PINMUX_FUNCTION_SPL(uart1), - UNIPHIER_PINMUX_FUNCTION_SPL(uart2), - UNIPHIER_PINMUX_FUNCTION_SPL(uart3), + UNIPHIER_PINMUX_FUNCTION(system_bus), + UNIPHIER_PINMUX_FUNCTION(uart0), + UNIPHIER_PINMUX_FUNCTION(uart1), + UNIPHIER_PINMUX_FUNCTION(uart2), + UNIPHIER_PINMUX_FUNCTION(uart3), UNIPHIER_PINMUX_FUNCTION(usb0), UNIPHIER_PINMUX_FUNCTION(usb1), UNIPHIER_PINMUX_FUNCTION(usb2), diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c index 86752d9..423e48b 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c @@ -78,12 +78,12 @@ static const struct uniphier_pinctrl_group uniphier_pxs3_groups[] = { UNIPHIER_PINCTRL_GROUP(i2c3), UNIPHIER_PINCTRL_GROUP(nand), UNIPHIER_PINCTRL_GROUP(sd), - UNIPHIER_PINCTRL_GROUP_SPL(system_bus), - UNIPHIER_PINCTRL_GROUP_SPL(system_bus_cs1), - UNIPHIER_PINCTRL_GROUP_SPL(uart0), - UNIPHIER_PINCTRL_GROUP_SPL(uart1), - UNIPHIER_PINCTRL_GROUP_SPL(uart2), - UNIPHIER_PINCTRL_GROUP_SPL(uart3), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), UNIPHIER_PINCTRL_GROUP(usb0), UNIPHIER_PINCTRL_GROUP(usb1), UNIPHIER_PINCTRL_GROUP(usb2), @@ -102,11 +102,11 @@ static const char * const uniphier_pxs3_functions[] = { UNIPHIER_PINMUX_FUNCTION(i2c3), UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), - UNIPHIER_PINMUX_FUNCTION_SPL(system_bus), - UNIPHIER_PINMUX_FUNCTION_SPL(uart0), - UNIPHIER_PINMUX_FUNCTION_SPL(uart1), - UNIPHIER_PINMUX_FUNCTION_SPL(uart2), - UNIPHIER_PINMUX_FUNCTION_SPL(uart3), + UNIPHIER_PINMUX_FUNCTION(system_bus), + UNIPHIER_PINMUX_FUNCTION(uart0), + UNIPHIER_PINMUX_FUNCTION(uart1), + UNIPHIER_PINMUX_FUNCTION(uart2), + UNIPHIER_PINMUX_FUNCTION(uart3), UNIPHIER_PINMUX_FUNCTION(usb0), UNIPHIER_PINMUX_FUNCTION(usb1), UNIPHIER_PINMUX_FUNCTION(usb2), diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index f488799..f7bdfa5 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o obj-$(CONFIG_PMIC_ACT8846) += act8846.o -obj-$(CONFIG_PMIC_AS3722) += as3722.o +obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o obj-$(CONFIG_PMIC_MAX8997) += max8997.o obj-$(CONFIG_PMIC_PM8916) += pm8916.o obj-$(CONFIG_PMIC_RK8XX) += rk8xx.o diff --git a/drivers/power/pmic/as3722.c b/drivers/power/pmic/as3722.c index c09e1de..4efe8ee 100644 --- a/drivers/power/pmic/as3722.c +++ b/drivers/power/pmic/as3722.c @@ -11,264 +11,168 @@ #include #include #include - +#include #include +#include -#define AS3722_SD_VOLTAGE(n) (0x00 + (n)) -#define AS3722_GPIO_CONTROL(n) (0x08 + (n)) -#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0) -#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0) -#define AS3722_GPIO_CONTROL_INVERT (1 << 7) -#define AS3722_LDO_VOLTAGE(n) (0x10 + (n)) -#define AS3722_GPIO_SIGNAL_OUT 0x20 -#define AS3722_SD_CONTROL 0x4d -#define AS3722_LDO_CONTROL 0x4e -#define AS3722_ASIC_ID1 0x90 -#define AS3722_DEVICE_ID 0x0c -#define AS3722_ASIC_ID2 0x91 - -int as3722_read(struct udevice *pmic, u8 reg, u8 *value) -{ - int err; - - err = dm_i2c_read(pmic, reg, value, 1); - if (err < 0) - return err; - - return 0; -} +#define AS3722_NUM_OF_REGS 0x92 -int as3722_write(struct udevice *pmic, u8 reg, u8 value) +static int as3722_read(struct udevice *dev, uint reg, uint8_t *buff, int len) { - int err; + int ret; - err = dm_i2c_write(pmic, reg, &value, 1); - if (err < 0) - return err; + ret = dm_i2c_read(dev, reg, buff, len); + if (ret < 0) + return ret; return 0; } -static int as3722_read_id(struct udevice *pmic, u8 *id, u8 *revision) +static int as3722_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) { - int err; + int ret; - err = as3722_read(pmic, AS3722_ASIC_ID1, id); - if (err) { - error("failed to read ID1 register: %d", err); - return err; - } - - err = as3722_read(pmic, AS3722_ASIC_ID2, revision); - if (err) { - error("failed to read ID2 register: %d", err); - return err; - } + ret = dm_i2c_write(dev, reg, buff, len); + if (ret < 0) + return ret; return 0; } -int as3722_sd_enable(struct udevice *pmic, unsigned int sd) +static int as3722_read_id(struct udevice *dev, uint *idp, uint *revisionp) { - u8 value; - int err; - - if (sd > 6) - return -EINVAL; + int ret; - err = as3722_read(pmic, AS3722_SD_CONTROL, &value); - if (err) { - error("failed to read SD control register: %d", err); - return err; + ret = pmic_reg_read(dev, AS3722_ASIC_ID1); + if (ret < 0) { + error("failed to read ID1 register: %d", ret); + return ret; } + *idp = ret; - value |= 1 << sd; - - err = as3722_write(pmic, AS3722_SD_CONTROL, value); - if (err < 0) { - error("failed to write SD control register: %d", err); - return err; + ret = pmic_reg_read(dev, AS3722_ASIC_ID2); + if (ret < 0) { + error("failed to read ID2 register: %d", ret); + return ret; } + *revisionp = ret; return 0; } -int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value) +/* TODO(treding@nvidia.com): Add proper regulator support to avoid this */ +int as3722_sd_set_voltage(struct udevice *dev, unsigned int sd, u8 value) { - int err; + int ret; if (sd > 6) return -EINVAL; - err = as3722_write(pmic, AS3722_SD_VOLTAGE(sd), value); - if (err < 0) { - error("failed to write SD%u voltage register: %d", sd, err); - return err; + ret = pmic_reg_write(dev, AS3722_SD_VOLTAGE(sd), value); + if (ret < 0) { + error("failed to write SD%u voltage register: %d", sd, ret); + return ret; } return 0; } -int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) +int as3722_ldo_set_voltage(struct udevice *dev, unsigned int ldo, u8 value) { - u8 value; - int err; + int ret; if (ldo > 11) return -EINVAL; - err = as3722_read(pmic, AS3722_LDO_CONTROL, &value); - if (err) { - error("failed to read LDO control register: %d", err); - return err; - } - - value |= 1 << ldo; - - err = as3722_write(pmic, AS3722_LDO_CONTROL, value); - if (err < 0) { - error("failed to write LDO control register: %d", err); - return err; - } - - return 0; -} - -int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value) -{ - int err; - - if (ldo > 11) - return -EINVAL; - - err = as3722_write(pmic, AS3722_LDO_VOLTAGE(ldo), value); - if (err < 0) { + ret = pmic_reg_write(dev, AS3722_LDO_VOLTAGE(ldo), value); + if (ret < 0) { error("failed to write LDO%u voltage register: %d", ldo, - err); - return err; + ret); + return ret; } return 0; } -int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, - unsigned long flags) +static int as3722_probe(struct udevice *dev) { - u8 value = 0; - int err; + uint id, revision; + int ret; - if (flags & AS3722_GPIO_OUTPUT_VDDH) - value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; - - if (flags & AS3722_GPIO_INVERT) - value |= AS3722_GPIO_CONTROL_INVERT; - - err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); - if (err) { - error("failed to configure GPIO#%u: %d", gpio, err); - return err; + ret = as3722_read_id(dev, &id, &revision); + if (ret < 0) { + error("failed to read ID: %d", ret); + return ret; } - return 0; -} - -static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio, - unsigned int level) -{ - const char *l; - u8 value; - int err; - - if (gpio > 7) - return -EINVAL; - - err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value); - if (err < 0) { - error("failed to read GPIO signal out register: %d", err); - return err; - } - - if (level == 0) { - value &= ~(1 << gpio); - l = "low"; - } else { - value |= 1 << gpio; - l = "high"; + if (id != AS3722_DEVICE_ID) { + error("unknown device"); + return -ENOENT; } - err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); - if (err) { - error("failed to set GPIO#%u %s: %d", gpio, l, err); - return err; - } + debug("AS3722 revision %#x found on I2C bus %s\n", revision, dev->name); return 0; } -int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio, - unsigned int level) -{ - u8 value; - int err; - - if (gpio > 7) - return -EINVAL; +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) +static const struct pmic_child_info pmic_children_info[] = { + { .prefix = "sd", .driver = "as3722_stepdown"}, + { .prefix = "ldo", .driver = "as3722_ldo"}, + { }, +}; - if (level == 0) - value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; - else - value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; +static int as3722_bind(struct udevice *dev) +{ + struct udevice *gpio_dev; + ofnode regulators_node; + int children; + int ret; - err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); - if (err) { - error("failed to configure GPIO#%u as output: %d", gpio, err); - return err; + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s: %s regulators subnode not found\n", __func__, + dev->name); + return -ENXIO; } - err = as3722_gpio_set(pmic, gpio, level); - if (err < 0) { - error("failed to set GPIO#%u high: %d", gpio, err); - return err; + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + debug("%s: %s - no child found\n", __func__, dev->name); + ret = device_bind_driver(dev, "gpio_as3722", "gpio_as3722", &gpio_dev); + if (ret) { + debug("%s: Cannot bind GPIOs (ret=%d)\n", __func__, ret); + return ret; } return 0; } +#endif -/* Temporary function until we get the pmic framework */ -int as3722_get(struct udevice **devp) +static int as3722_reg_count(struct udevice *dev) { - int bus = 0; - int address = 0x40; - - return i2c_get_chip_for_busnum(bus, address, 1, devp); + return AS3722_NUM_OF_REGS; } -int as3722_init(struct udevice **devp) -{ - struct udevice *pmic; - u8 id, revision; - const unsigned int bus = 0; - const unsigned int address = 0x40; - int err; - - err = i2c_get_chip_for_busnum(bus, address, 1, &pmic); - if (err) - return err; - err = as3722_read_id(pmic, &id, &revision); - if (err < 0) { - error("failed to read ID: %d", err); - return err; - } - - if (id != AS3722_DEVICE_ID) { - error("unknown device"); - return -ENOENT; - } - - debug("AS3722 revision %#x found on I2C bus %u, address %#x\n", - revision, bus, address); - if (devp) - *devp = pmic; - - return 0; -} +static struct dm_pmic_ops as3722_ops = { + .reg_count = as3722_reg_count, + .read = as3722_read, + .write = as3722_write, +}; + +static const struct udevice_id as3722_ids[] = { + { .compatible = "ams,as3722" }, + { } +}; + +U_BOOT_DRIVER(pmic_as3722) = { + .name = "as3722_pmic", + .id = UCLASS_PMIC, + .of_match = as3722_ids, +#if CONFIG_IS_ENABLED(PMIC_CHILDREN) + .bind = as3722_bind, +#endif + .probe = as3722_probe, + .ops = &as3722_ops, +}; diff --git a/drivers/power/pmic/as3722_gpio.c b/drivers/power/pmic/as3722_gpio.c new file mode 100644 index 0000000..d0b681c --- /dev/null +++ b/drivers/power/pmic/as3722_gpio.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2014 NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#define NUM_GPIOS 8 + +int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, + unsigned long flags) +{ + u8 value = 0; + int err; + + if (flags & AS3722_GPIO_OUTPUT_VDDH) + value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; + + if (flags & AS3722_GPIO_INVERT) + value |= AS3722_GPIO_CONTROL_INVERT; + + err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value); + if (err) { + error("failed to configure GPIO#%u: %d", gpio, err); + return err; + } + + return 0; +} + +static int as3722_gpio_set_value(struct udevice *dev, unsigned int gpio, + int level) +{ + struct udevice *pmic = dev_get_parent(dev); + const char *l; + u8 value; + int err; + + if (gpio >= NUM_GPIOS) + return -EINVAL; + + err = pmic_reg_read(pmic, AS3722_GPIO_SIGNAL_OUT); + if (err < 0) { + error("failed to read GPIO signal out register: %d", err); + return err; + } + value = err; + + if (level == 0) { + value &= ~(1 << gpio); + l = "low"; + } else { + value |= 1 << gpio; + l = "high"; + } + + err = pmic_reg_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); + if (err) { + error("failed to set GPIO#%u %s: %d", gpio, l, err); + return err; + } + + return 0; +} + +int as3722_gpio_direction_output(struct udevice *dev, unsigned int gpio, + int value) +{ + struct udevice *pmic = dev_get_parent(dev); + int err; + + if (gpio > 7) + return -EINVAL; + + if (value == 0) + value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; + else + value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; + + err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value); + if (err) { + error("failed to configure GPIO#%u as output: %d", gpio, err); + return err; + } + + err = as3722_gpio_set_value(pmic, gpio, value); + if (err < 0) { + error("failed to set GPIO#%u high: %d", gpio, err); + return err; + } + + return 0; +} + +static int as3722_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + uc_priv->gpio_count = NUM_GPIOS; + uc_priv->bank_name = "as3722_"; + + return 0; +} + +static const struct dm_gpio_ops gpio_as3722_ops = { + .direction_output = as3722_gpio_direction_output, + .set_value = as3722_gpio_set_value, +}; + +U_BOOT_DRIVER(gpio_as3722) = { + .name = "gpio_as3722", + .id = UCLASS_GPIO, + .ops = &gpio_as3722_ops, + .probe = as3722_gpio_probe, +}; diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index f213487..c82a936 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -34,6 +34,15 @@ config REGULATOR_ACT8846 by the PMIC device. This driver is controlled by a device tree node which includes voltage limits. +config REGULATOR_AS3722 + bool "Enable driver for AS7322 regulator" + depends on DM_REGULATOR && PMIC_AS3722 + help + Enable support for the regulator functions of the AS3722. The + driver implements enable/disable for step-down bucks and LDOs, + but does not yet support change voltages. Currently this must be + done using direct register writes to the PMIC. + config DM_REGULATOR_PFUZE100 bool "Enable Driver Model for REGULATOR PFUZE100" depends on DM_REGULATOR && DM_PMIC_PFUZE100 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index ce14d08..18fb870 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR) += regulator-uclass.o obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o +obj-$(CONFIG_REGULATOR_AS3722) += as3722_regulator.o obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o obj-$(CONFIG_DM_REGULATOR_PFUZE100) += pfuze100.o obj-$(CONFIG_REGULATOR_PWM) += pwm_regulator.o diff --git a/drivers/power/regulator/as3722_regulator.c b/drivers/power/regulator/as3722_regulator.c new file mode 100644 index 0000000..3e1e6f1 --- /dev/null +++ b/drivers/power/regulator/as3722_regulator.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2017 Google, Inc + * Written by Simon Glass + * + * Placeholder regulator driver for as3722. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +static int stepdown_get_value(struct udevice *dev) +{ + return -ENOSYS; +} + +static int stepdown_set_value(struct udevice *dev, int uvolt) +{ + return -ENOSYS; +} + +static int stepdown_set_enable(struct udevice *dev, bool enable) +{ + struct udevice *pmic = dev_get_parent(dev); + int sd = dev->driver_data; + int ret; + + ret = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd); + if (ret < 0) { + debug("%s: failed to write SD control register: %d", __func__, + ret); + return ret; + } + + return 0; +} + +static int stepdown_get_enable(struct udevice *dev) +{ + struct udevice *pmic = dev_get_parent(dev); + int sd = dev->driver_data; + int ret; + + ret = pmic_reg_read(pmic, AS3722_SD_CONTROL); + if (ret < 0) { + debug("%s: failed to read SD control register: %d", __func__, + ret); + return ret; + } + + return ret & (1 << sd) ? true : false; +} + +static int ldo_get_value(struct udevice *dev) +{ + return -ENOSYS; +} + +static int ldo_set_value(struct udevice *dev, int uvolt) +{ + return -ENOSYS; +} + +static int ldo_set_enable(struct udevice *dev, bool enable) +{ + struct udevice *pmic = dev_get_parent(dev); + int ldo = dev->driver_data; + int ret; + + ret = pmic_clrsetbits(pmic, AS3722_LDO_CONTROL, 0, 1 << ldo); + if (ret < 0) { + debug("%s: failed to write LDO control register: %d", __func__, + ret); + return ret; + } + + return 0; +} + +static int ldo_get_enable(struct udevice *dev) +{ + struct udevice *pmic = dev_get_parent(dev); + int ldo = dev->driver_data; + int ret; + + ret = pmic_reg_read(pmic, AS3722_LDO_CONTROL); + if (ret < 0) { + debug("%s: failed to read SD control register: %d", __func__, + ret); + return ret; + } + + return ret & (1 << ldo) ? true : false; +} + +static int as3722_stepdown_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_BUCK; + + return 0; +} + +static int as3722_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_LDO; + + return 0; +} + +static const struct dm_regulator_ops as3722_stepdown_ops = { + .get_value = stepdown_get_value, + .set_value = stepdown_set_value, + .get_enable = stepdown_get_enable, + .set_enable = stepdown_set_enable, +}; + +static const struct dm_regulator_ops as3722_ldo_ops = { + .get_value = ldo_get_value, + .set_value = ldo_set_value, + .get_enable = ldo_get_enable, + .set_enable = ldo_set_enable, +}; + +U_BOOT_DRIVER(as3722_stepdown) = { + .name = "as3722_stepdown", + .id = UCLASS_REGULATOR, + .ops = &as3722_stepdown_ops, + .probe = as3722_stepdown_probe, +}; + +U_BOOT_DRIVER(as3722_ldo) = { + .name = "as3722_ldo", + .id = UCLASS_REGULATOR, + .ops = &as3722_ldo_ops, + .probe = as3722_ldo_probe, +}; diff --git a/drivers/power/regulator/pwm_regulator.c b/drivers/power/regulator/pwm_regulator.c index 00a7cca..b63f941 100644 --- a/drivers/power/regulator/pwm_regulator.c +++ b/drivers/power/regulator/pwm_regulator.c @@ -80,18 +80,14 @@ static int pwm_regulator_set_voltage(struct udevice *dev, int uvolt) } ret = pwm_set_config(priv->pwm, priv->pwm_id, - (priv->period_ns / 100) * duty_cycle, priv->period_ns); + priv->period_ns, (priv->period_ns / 100) * duty_cycle); if (ret) { dev_err(dev, "Failed to configure PWM\n"); return ret; } - ret = pwm_set_enable(priv->pwm, priv->pwm_id, true); - if (ret) { - dev_err(dev, "Failed to enable PWM\n"); - return ret; - } priv->volt_uV = uvolt; + return ret; } @@ -144,8 +140,6 @@ static int pwm_regulator_probe(struct udevice *dev) if (priv->init_voltage) pwm_regulator_set_voltage(dev, priv->init_voltage); - pwm_regulator_enable(dev, 1); - return 0; } diff --git a/drivers/pwm/rk_pwm.c b/drivers/pwm/rk_pwm.c index 28de62d..2364c2d 100644 --- a/drivers/pwm/rk_pwm.c +++ b/drivers/pwm/rk_pwm.c @@ -29,6 +29,7 @@ static int rk_pwm_set_invert(struct udevice *dev, uint channel, bool polarity) struct rk_pwm_priv *priv = dev_get_priv(dev); debug("%s: polarity=%u\n", __func__, polarity); + priv->enable_conf &= ~(PWM_DUTY_MASK | PWM_INACTIVE_MASK); if (polarity) priv->enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSTIVE; else diff --git a/drivers/pwm/tegra_pwm.c b/drivers/pwm/tegra_pwm.c index d93ac28..b8acc15 100644 --- a/drivers/pwm/tegra_pwm.c +++ b/drivers/pwm/tegra_pwm.c @@ -59,7 +59,7 @@ static int tegra_pwm_ofdata_to_platdata(struct udevice *dev) { struct tegra_pwm_priv *priv = dev_get_priv(dev); - priv->regs = (struct pwm_ctlr *)devfdt_get_addr(dev); + priv->regs = (struct pwm_ctlr *)dev_read_addr(dev); return 0; } diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c index 902de2b..b1b0289 100644 --- a/drivers/ram/stm32_sdram.c +++ b/drivers/ram/stm32_sdram.c @@ -10,11 +10,99 @@ #include #include #include -#include -#include DECLARE_GLOBAL_DATA_PTR; +struct stm32_fmc_regs { + /* 0x0 */ + u32 bcr1; /* NOR/PSRAM Chip select control register 1 */ + u32 btr1; /* SRAM/NOR-Flash Chip select timing register 1 */ + u32 bcr2; /* NOR/PSRAM Chip select Control register 2 */ + u32 btr2; /* SRAM/NOR-Flash Chip select timing register 2 */ + u32 bcr3; /* NOR/PSRAMChip select Control register 3 */ + u32 btr3; /* SRAM/NOR-Flash Chip select timing register 3 */ + u32 bcr4; /* NOR/PSRAM Chip select Control register 4 */ + u32 btr4; /* SRAM/NOR-Flash Chip select timing register 4 */ + u32 reserved1[24]; + + /* 0x80 */ + u32 pcr; /* NAND Flash control register */ + u32 sr; /* FIFO status and interrupt register */ + u32 pmem; /* Common memory space timing register */ + u32 patt; /* Attribute memory space timing registers */ + u32 reserved2[1]; + u32 eccr; /* ECC result registers */ + u32 reserved3[27]; + + /* 0x104 */ + u32 bwtr1; /* SRAM/NOR-Flash write timing register 1 */ + u32 reserved4[1]; + u32 bwtr2; /* SRAM/NOR-Flash write timing register 2 */ + u32 reserved5[1]; + u32 bwtr3; /* SRAM/NOR-Flash write timing register 3 */ + u32 reserved6[1]; + u32 bwtr4; /* SRAM/NOR-Flash write timing register 4 */ + u32 reserved7[8]; + + /* 0x140 */ + u32 sdcr1; /* SDRAM Control register 1 */ + u32 sdcr2; /* SDRAM Control register 2 */ + u32 sdtr1; /* SDRAM Timing register 1 */ + u32 sdtr2; /* SDRAM Timing register 2 */ + u32 sdcmr; /* SDRAM Mode register */ + u32 sdrtr; /* SDRAM Refresh timing register */ + u32 sdsr; /* SDRAM Status register */ +}; + +/* + * NOR/PSRAM Control register BCR1 + * FMC controller Enable, only availabe for H7 + */ +#define FMC_BCR1_FMCEN BIT(31) + +/* Control register SDCR */ +#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */ +#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */ +#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */ +#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */ +#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */ +#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */ +#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */ +#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */ +#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */ + +/* Timings register SDTR */ +#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */ +#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */ +#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */ +#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */ +#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */ +#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */ +#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */ + +#define FMC_SDCMR_NRFS_SHIFT 5 + +#define FMC_SDCMR_MODE_NORMAL 0 +#define FMC_SDCMR_MODE_START_CLOCK 1 +#define FMC_SDCMR_MODE_PRECHARGE 2 +#define FMC_SDCMR_MODE_AUTOREFRESH 3 +#define FMC_SDCMR_MODE_WRITE_MODE 4 +#define FMC_SDCMR_MODE_SELFREFRESH 5 +#define FMC_SDCMR_MODE_POWERDOWN 6 + +#define FMC_SDCMR_BANK_1 BIT(4) +#define FMC_SDCMR_BANK_2 BIT(3) + +#define FMC_SDCMR_MODE_REGISTER_SHIFT 9 + +#define FMC_SDSR_BUSY BIT(5) + +#define FMC_BUSY_WAIT(regs) do { \ + __asm__ __volatile__ ("dsb" : : : "memory"); \ + while (regs->sdsr & FMC_SDSR_BUSY) \ + ; \ + } while (0) + struct stm32_sdram_control { u8 no_columns; u8 no_rows; @@ -35,11 +123,29 @@ struct stm32_sdram_timing { u8 twr; u8 trcd; }; +enum stm32_fmc_bank { + SDRAM_BANK1, + SDRAM_BANK2, + MAX_SDRAM_BANK, +}; + +enum stm32_fmc_family { + STM32F7_FMC, + STM32H7_FMC, +}; + +struct bank_params { + struct stm32_sdram_control *sdram_control; + struct stm32_sdram_timing *sdram_timing; + u32 sdram_ref_count; + enum stm32_fmc_bank target_bank; +}; + struct stm32_sdram_params { + struct stm32_fmc_regs *base; u8 no_sdram_banks; - struct stm32_sdram_control sdram_control; - struct stm32_sdram_timing sdram_timing; - u32 sdram_ref_count; + struct bank_params bank_params[MAX_SDRAM_BANK]; + enum stm32_fmc_family family; }; #define SDRAM_MODE_BL_SHIFT 0 @@ -49,90 +155,179 @@ struct stm32_sdram_params { int stm32_sdram_init(struct udevice *dev) { struct stm32_sdram_params *params = dev_get_platdata(dev); + struct stm32_sdram_control *control; + struct stm32_sdram_timing *timing; + struct stm32_fmc_regs *regs = params->base; + enum stm32_fmc_bank target_bank; + u32 ctb; /* SDCMR register: Command Target Bank */ + u32 ref_count; + u8 i; + + /* disable the FMC controller */ + if (params->family == STM32H7_FMC) + clrbits_le32(®s->bcr1, FMC_BCR1_FMCEN); + + for (i = 0; i < params->no_sdram_banks; i++) { + control = params->bank_params[i].sdram_control; + timing = params->bank_params[i].sdram_timing; + target_bank = params->bank_params[i].target_bank; + ref_count = params->bank_params[i].sdram_ref_count; + + writel(control->sdclk << FMC_SDCR_SDCLK_SHIFT + | control->cas_latency << FMC_SDCR_CAS_SHIFT + | control->no_banks << FMC_SDCR_NB_SHIFT + | control->memory_width << FMC_SDCR_MWID_SHIFT + | control->no_rows << FMC_SDCR_NR_SHIFT + | control->no_columns << FMC_SDCR_NC_SHIFT + | control->rd_pipe_delay << FMC_SDCR_RPIPE_SHIFT + | control->rd_burst << FMC_SDCR_RBURST_SHIFT, + ®s->sdcr1); + + if (target_bank == SDRAM_BANK2) + writel(control->cas_latency << FMC_SDCR_CAS_SHIFT + | control->no_banks << FMC_SDCR_NB_SHIFT + | control->memory_width << FMC_SDCR_MWID_SHIFT + | control->no_rows << FMC_SDCR_NR_SHIFT + | control->no_columns << FMC_SDCR_NC_SHIFT, + ®s->sdcr2); - writel(params->sdram_control.sdclk << FMC_SDCR_SDCLK_SHIFT - | params->sdram_control.cas_latency << FMC_SDCR_CAS_SHIFT - | params->sdram_control.no_banks << FMC_SDCR_NB_SHIFT - | params->sdram_control.memory_width << FMC_SDCR_MWID_SHIFT - | params->sdram_control.no_rows << FMC_SDCR_NR_SHIFT - | params->sdram_control.no_columns << FMC_SDCR_NC_SHIFT - | params->sdram_control.rd_pipe_delay << FMC_SDCR_RPIPE_SHIFT - | params->sdram_control.rd_burst << FMC_SDCR_RBURST_SHIFT, - &STM32_SDRAM_FMC->sdcr1); - - writel(params->sdram_timing.trcd << FMC_SDTR_TRCD_SHIFT - | params->sdram_timing.trp << FMC_SDTR_TRP_SHIFT - | params->sdram_timing.twr << FMC_SDTR_TWR_SHIFT - | params->sdram_timing.trc << FMC_SDTR_TRC_SHIFT - | params->sdram_timing.tras << FMC_SDTR_TRAS_SHIFT - | params->sdram_timing.txsr << FMC_SDTR_TXSR_SHIFT - | params->sdram_timing.tmrd << FMC_SDTR_TMRD_SHIFT, - &STM32_SDRAM_FMC->sdtr1); - - writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK, - &STM32_SDRAM_FMC->sdcmr); - udelay(200); /* 200 us delay, page 10, "Power-Up" */ - FMC_BUSY_WAIT(); - - writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE, - &STM32_SDRAM_FMC->sdcmr); - udelay(100); - FMC_BUSY_WAIT(); - - writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH - | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr); - udelay(100); - FMC_BUSY_WAIT(); - - writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT - | params->sdram_control.cas_latency << SDRAM_MODE_CAS_SHIFT) - << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, - &STM32_SDRAM_FMC->sdcmr); - udelay(100); - FMC_BUSY_WAIT(); - - writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL, - &STM32_SDRAM_FMC->sdcmr); - FMC_BUSY_WAIT(); - - /* Refresh timer */ - writel((params->sdram_ref_count) << 1, &STM32_SDRAM_FMC->sdrtr); + writel(timing->trcd << FMC_SDTR_TRCD_SHIFT + | timing->trp << FMC_SDTR_TRP_SHIFT + | timing->twr << FMC_SDTR_TWR_SHIFT + | timing->trc << FMC_SDTR_TRC_SHIFT + | timing->tras << FMC_SDTR_TRAS_SHIFT + | timing->txsr << FMC_SDTR_TXSR_SHIFT + | timing->tmrd << FMC_SDTR_TMRD_SHIFT, + ®s->sdtr1); + + if (target_bank == SDRAM_BANK2) + writel(timing->trcd << FMC_SDTR_TRCD_SHIFT + | timing->trp << FMC_SDTR_TRP_SHIFT + | timing->twr << FMC_SDTR_TWR_SHIFT + | timing->trc << FMC_SDTR_TRC_SHIFT + | timing->tras << FMC_SDTR_TRAS_SHIFT + | timing->txsr << FMC_SDTR_TXSR_SHIFT + | timing->tmrd << FMC_SDTR_TMRD_SHIFT, + ®s->sdtr2); + + if (target_bank == SDRAM_BANK1) + ctb = FMC_SDCMR_BANK_1; + else + ctb = FMC_SDCMR_BANK_2; + + writel(ctb | FMC_SDCMR_MODE_START_CLOCK, ®s->sdcmr); + udelay(200); /* 200 us delay, page 10, "Power-Up" */ + FMC_BUSY_WAIT(regs); + + writel(ctb | FMC_SDCMR_MODE_PRECHARGE, ®s->sdcmr); + udelay(100); + FMC_BUSY_WAIT(regs); + + writel((ctb | FMC_SDCMR_MODE_AUTOREFRESH | 7 << FMC_SDCMR_NRFS_SHIFT), + ®s->sdcmr); + udelay(100); + FMC_BUSY_WAIT(regs); + + writel(ctb | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT + | control->cas_latency << SDRAM_MODE_CAS_SHIFT) + << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, + ®s->sdcmr); + udelay(100); + FMC_BUSY_WAIT(regs); + + writel(ctb | FMC_SDCMR_MODE_NORMAL, ®s->sdcmr); + FMC_BUSY_WAIT(regs); + + /* Refresh timer */ + writel(ref_count << 1, ®s->sdrtr); + } + + /* enable the FMC controller */ + if (params->family == STM32H7_FMC) + setbits_le32(®s->bcr1, FMC_BCR1_FMCEN); return 0; } static int stm32_fmc_ofdata_to_platdata(struct udevice *dev) { - int ret; - int node = dev_of_offset(dev); - const void *blob = gd->fdt_blob; struct stm32_sdram_params *params = dev_get_platdata(dev); + struct bank_params *bank_params; + ofnode bank_node; + char *bank_name; + u8 bank = 0; - params->no_sdram_banks = fdtdec_get_uint(blob, node, "mr-nbanks", 1); - debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks); + dev_for_each_subnode(bank_node, dev) { + /* extract the bank index from DT */ + bank_name = (char *)ofnode_get_name(bank_node); + strsep(&bank_name, "@"); + if (!bank_name) { + error("missing sdram bank index"); + return -EINVAL; + } + + bank_params = ¶ms->bank_params[bank]; + strict_strtoul(bank_name, 10, + (long unsigned int *)&bank_params->target_bank); + + if (bank_params->target_bank >= MAX_SDRAM_BANK) { + error("Found bank %d , but only bank 0 and 1 are supported", + bank_params->target_bank); + return -EINVAL; + } - fdt_for_each_subnode(node, blob, node) { - ret = fdtdec_get_byte_array(blob, node, "st,sdram-control", - (u8 *)¶ms->sdram_control, - sizeof(params->sdram_control)); - if (ret) - return ret; - ret = fdtdec_get_byte_array(blob, node, "st,sdram-timing", - (u8 *)¶ms->sdram_timing, - sizeof(params->sdram_timing)); - if (ret) - return ret; - - params->sdram_ref_count = fdtdec_get_int(blob, node, + debug("Find bank %s %u\n", bank_name, bank_params->target_bank); + + params->bank_params[bank].sdram_control = + (struct stm32_sdram_control *) + ofnode_read_u8_array_ptr(bank_node, + "st,sdram-control", + sizeof(struct stm32_sdram_control)); + + if (!params->bank_params[bank].sdram_control) { + error("st,sdram-control not found for %s", + ofnode_get_name(bank_node)); + return -EINVAL; + } + + + params->bank_params[bank].sdram_timing = + (struct stm32_sdram_timing *) + ofnode_read_u8_array_ptr(bank_node, + "st,sdram-timing", + sizeof(struct stm32_sdram_timing)); + + if (!params->bank_params[bank].sdram_timing) { + error("st,sdram-timing not found for %s", + ofnode_get_name(bank_node)); + return -EINVAL; + } + + + bank_params->sdram_ref_count = ofnode_read_u32_default(bank_node, "st,sdram-refcount", 8196); + bank++; } + params->no_sdram_banks = bank; + debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks); + return 0; } static int stm32_fmc_probe(struct udevice *dev) { + struct stm32_sdram_params *params = dev_get_platdata(dev); int ret; + fdt_addr_t addr; + + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + params->base = (struct stm32_fmc_regs *)addr; + params->family = dev_get_driver_data(dev); + #ifdef CONFIG_CLK struct clk clk; @@ -164,7 +359,8 @@ static struct ram_ops stm32_fmc_ops = { }; static const struct udevice_id stm32_fmc_ids[] = { - { .compatible = "st,stm32-fmc" }, + { .compatible = "st,stm32-fmc", .data = STM32F7_FMC }, + { .compatible = "st,stm32h7-fmc", .data = STM32H7_FMC }, { } }; diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c index de3695f..307a297 100644 --- a/drivers/reset/reset-uclass.c +++ b/drivers/reset/reset-uclass.c @@ -42,6 +42,7 @@ int reset_get_by_index(struct udevice *dev, int index, debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index, reset_ctl); + reset_ctl->dev = NULL; ret = dev_read_phandle_with_args(dev, "resets", "#reset-cells", 0, index, &args); @@ -87,6 +88,7 @@ int reset_get_by_name(struct udevice *dev, const char *name, debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name, reset_ctl); + reset_ctl->dev = NULL; index = dev_read_stringlist_search(dev, "reset-names", name); if (index < 0) { @@ -97,6 +99,15 @@ int reset_get_by_name(struct udevice *dev, const char *name, return reset_get_by_index(dev, index, reset_ctl); } +int reset_request(struct reset_ctl *reset_ctl) +{ + struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); + + debug("%s(reset_ctl=%p)\n", __func__, reset_ctl); + + return ops->request(reset_ctl); +} + int reset_free(struct reset_ctl *reset_ctl) { struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); @@ -124,6 +135,29 @@ int reset_deassert(struct reset_ctl *reset_ctl) return ops->rst_deassert(reset_ctl); } +int reset_release_all(struct reset_ctl *reset_ctl, int count) +{ + int i, ret; + + for (i = 0; i < count; i++) { + debug("%s(reset_ctl[%d]=%p)\n", __func__, i, &reset_ctl[i]); + + /* check if reset has been previously requested */ + if (!reset_ctl[i].dev) + continue; + + ret = reset_assert(&reset_ctl[i]); + if (ret) + return ret; + + ret = reset_free(&reset_ctl[i]); + if (ret) + return ret; + } + + return 0; +} + UCLASS_DRIVER(reset) = { .id = UCLASS_RESET, .name = "reset", diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index f360534..9cae9fb 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -23,8 +23,8 @@ DECLARE_GLOBAL_DATA_PTR; */ static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; -#ifndef CONFIG_SYS_MALLOC_F_LEN -#error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work" +#if !CONFIG_VAL(SYS_MALLOC_F_LEN) +#error "Serial is required before relocation - define CONFIG_$(SPL_)SYS_MALLOC_F_LEN to make this work" #endif static int serial_check_stdout(const void *blob, struct udevice **devp) diff --git a/drivers/serial/serial_stm32x7.c b/drivers/serial/serial_stm32x7.c index 61e8167..bf118a7 100644 --- a/drivers/serial/serial_stm32x7.c +++ b/drivers/serial/serial_stm32x7.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "serial_stm32x7.h" DECLARE_GLOBAL_DATA_PTR; @@ -20,16 +19,9 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate) { struct stm32x7_serial_platdata *plat = dev->platdata; struct stm32_usart *const usart = plat->base; - u32 clock, int_div, mantissa, fraction, oversampling; + u32 int_div, mantissa, fraction, oversampling; - if (((u32)usart & STM32_BUS_MASK) == APB1_PERIPH_BASE) - clock = clock_get(CLOCK_APB1); - else if (((u32)usart & STM32_BUS_MASK) == APB2_PERIPH_BASE) - clock = clock_get(CLOCK_APB2); - else - return -EINVAL; - - int_div = DIV_ROUND_CLOSEST(clock, baudrate); + int_div = DIV_ROUND_CLOSEST(plat->clock_rate, baudrate); if (int_div < 16) { oversampling = 8; @@ -102,6 +94,12 @@ static int stm32_serial_probe(struct udevice *dev) } #endif + plat->clock_rate = clk_get_rate(&clk); + if (plat->clock_rate < 0) { + clk_disable(&clk); + return plat->clock_rate; + }; + /* Disable usart-> disable overrun-> enable usart */ clrbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE); setbits_le32(&usart->cr3, USART_CR3_OVRDIS); diff --git a/drivers/serial/serial_stm32x7.h b/drivers/serial/serial_stm32x7.h index facfdba..9fe37af 100644 --- a/drivers/serial/serial_stm32x7.h +++ b/drivers/serial/serial_stm32x7.h @@ -22,6 +22,11 @@ struct stm32_usart { u32 tx_dr; }; +/* Information about a serial port */ +struct stm32x7_serial_platdata { + struct stm32_usart *base; /* address of registers in physical memory */ + unsigned long int clock_rate; +}; #define USART_CR1_OVER8 (1 << 15) #define USART_CR1_TE (1 << 3) diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index f0434a4..ef2b64e 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -165,6 +165,7 @@ struct stm32_qspi_platdata { struct stm32_qspi_priv { struct stm32_qspi_regs *regs; + ulong clock_rate; u32 max_hz; u32 mode; @@ -471,6 +472,13 @@ static int stm32_qspi_probe(struct udevice *bus) dev_err(bus, "failed to enable clock\n"); return ret; } + + priv->clock_rate = clk_get_rate(&clk); + if (priv->clock_rate < 0) { + clk_disable(&clk); + return priv->clock_rate; + } + #endif setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT); @@ -536,7 +544,7 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed) if (speed > plat->max_hz) speed = plat->max_hz; - u32 qspi_clk = clock_get(CLOCK_AHB); + u32 qspi_clk = priv->clock_rate; u32 prescaler = 255; if (speed > 0) { prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1; diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c index 9165934..04b4fce 100644 --- a/drivers/spi/tegra114_spi.c +++ b/drivers/spi/tegra114_spi.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "tegra_spi.h" DECLARE_GLOBAL_DATA_PTR; @@ -100,11 +99,9 @@ struct tegra114_spi_priv { static int tegra114_spi_ofdata_to_platdata(struct udevice *bus) { struct tegra_spi_platdata *plat = bus->platdata; - const void *blob = gd->fdt_blob; - int node = dev_of_offset(bus); - plat->base = devfdt_get_addr(bus); - plat->periph_id = clock_decode_periph_id(blob, node); + plat->base = dev_read_addr(bus); + plat->periph_id = clock_decode_periph_id(bus); if (plat->periph_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id %d\n", __func__, @@ -113,10 +110,10 @@ static int tegra114_spi_ofdata_to_platdata(struct udevice *bus) } /* Use 500KHz as a suitable default */ - plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", - 500000); - plat->deactivate_delay_us = fdtdec_get_int(blob, node, - "spi-deactivate-delay", 0); + plat->frequency = dev_read_u32_default(bus, "spi-max-frequency", + 500000); + plat->deactivate_delay_us = dev_read_u32_default(bus, + "spi-deactivate-delay", 0); debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n", __func__, plat->base, plat->periph_id, plat->frequency, plat->deactivate_delay_us); diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c index 299e1b4..e70210d 100644 --- a/drivers/spi/tegra20_sflash.c +++ b/drivers/spi/tegra20_sflash.c @@ -91,7 +91,7 @@ static int tegra20_sflash_ofdata_to_platdata(struct udevice *bus) int node = dev_of_offset(bus); plat->base = devfdt_get_addr(bus); - plat->periph_id = clock_decode_periph_id(blob, node); + plat->periph_id = clock_decode_periph_id(bus); if (plat->periph_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id %d\n", __func__, diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c index 4cbde7b..f242574 100644 --- a/drivers/spi/tegra20_slink.c +++ b/drivers/spi/tegra20_slink.c @@ -97,7 +97,7 @@ static int tegra30_spi_ofdata_to_platdata(struct udevice *bus) int node = dev_of_offset(bus); plat->base = devfdt_get_addr(bus); - plat->periph_id = clock_decode_periph_id(blob, node); + plat->periph_id = clock_decode_periph_id(bus); if (plat->periph_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id %d\n", __func__, diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c index 6d0b5da..2a35a58 100644 --- a/drivers/spi/tegra210_qspi.c +++ b/drivers/spi/tegra210_qspi.c @@ -100,7 +100,7 @@ static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus) int node = dev_of_offset(bus); plat->base = devfdt_get_addr(bus); - plat->periph_id = clock_decode_periph_id(blob, node); + plat->periph_id = clock_decode_periph_id(bus); if (plat->periph_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id %d\n", __func__, diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c index 9ffda9c..1432858 100644 --- a/drivers/usb/emul/sandbox_hub.c +++ b/drivers/usb/emul/sandbox_hub.c @@ -96,7 +96,12 @@ static struct usb_hub_descriptor hub_desc = { 1 << 7), .bPwrOn2PwrGood = 2, .bHubContrCurrent = 5, - .DeviceRemovable = {0, 0xff}, /* all ports removeable */ + { + { + /* all ports removeable */ + .DeviceRemovable = {0, 0xff} + } + } #if SANDBOX_NUM_PORTS > 8 #error "This code sets up an incorrect mask" #endif diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c index a60e948..cd4d9e6 100644 --- a/drivers/usb/gadget/f_thor.c +++ b/drivers/usb/gadget/f_thor.c @@ -891,6 +891,7 @@ static void thor_func_disable(struct usb_function *f) } if (dev->out_ep->driver_data) { + free(dev->out_req->buf); dev->out_req->buf = NULL; usb_ep_free_request(dev->out_ep, dev->out_req); usb_ep_disable(dev->out_ep); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index bc2c1f1..67ad72b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -31,6 +31,13 @@ config USB_XHCI_MVEBU SoCs, which includes Armada8K, Armada3700 and other Armada family SoCs. +config USB_XHCI_PCI + bool "Support for PCI-based xHCI USB controller" + depends on DM_USB + default y if X86 + help + Enables support for the PCI-based xHCI controller. + config USB_XHCI_ROCKCHIP bool "Support for Rockchip on-chip xHCI USB controller" depends on ARCH_ROCKCHIP diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c index fb78462..03f8d32 100644 --- a/drivers/usb/host/ehci-generic.c +++ b/drivers/usb/host/ehci-generic.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -18,43 +20,143 @@ */ struct generic_ehci { struct ehci_ctrl ctrl; + struct clk *clocks; + struct reset_ctl *resets; + struct phy phy; + int clock_count; + int reset_count; }; static int ehci_usb_probe(struct udevice *dev) { + struct generic_ehci *priv = dev_get_priv(dev); struct ehci_hccr *hccr; struct ehci_hcor *hcor; - int i; - - for (i = 0; ; i++) { - struct clk clk; - int ret; - - ret = clk_get_by_index(dev, i, &clk); - if (ret < 0) - break; - if (clk_enable(&clk)) - printf("failed to enable clock %d\n", i); - clk_free(&clk); + int i, err, ret, clock_nb, reset_nb; + + err = 0; + priv->clock_count = 0; + clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks", + "#clock-cells"); + if (clock_nb > 0) { + priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), + GFP_KERNEL); + if (!priv->clocks) + return -ENOMEM; + + for (i = 0; i < clock_nb; i++) { + err = clk_get_by_index(dev, i, &priv->clocks[i]); + + if (err < 0) + break; + err = clk_enable(&priv->clocks[i]); + if (err) { + error("failed to enable clock %d\n", i); + clk_free(&priv->clocks[i]); + goto clk_err; + } + priv->clock_count++; + } + } else { + if (clock_nb != -ENOENT) { + error("failed to get clock phandle(%d)\n", clock_nb); + return clock_nb; + } + } + + priv->reset_count = 0; + reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets", + "#reset-cells"); + if (reset_nb > 0) { + priv->resets = devm_kcalloc(dev, reset_nb, + sizeof(struct reset_ctl), + GFP_KERNEL); + if (!priv->resets) + return -ENOMEM; + + for (i = 0; i < reset_nb; i++) { + err = reset_get_by_index(dev, i, &priv->resets[i]); + if (err < 0) + break; + + if (reset_deassert(&priv->resets[i])) { + error("failed to deassert reset %d\n", i); + reset_free(&priv->resets[i]); + goto reset_err; + } + priv->reset_count++; + } + } else { + if (reset_nb != -ENOENT) { + error("failed to get reset phandle(%d)\n", reset_nb); + goto clk_err; + } } - for (i = 0; ; i++) { - struct reset_ctl reset; - int ret; + err = generic_phy_get_by_index(dev, 0, &priv->phy); + if (err) { + if (err != -ENOENT) { + error("failed to get usb phy\n"); + goto reset_err; + } + } else { - ret = reset_get_by_index(dev, i, &reset); - if (ret < 0) - break; - if (reset_deassert(&reset)) - printf("failed to deassert reset %d\n", i); - reset_free(&reset); + err = generic_phy_init(&priv->phy); + if (err) { + error("failed to init usb phy\n"); + goto reset_err; + } } hccr = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE); hcor = (struct ehci_hcor *)((uintptr_t)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); - return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); + err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); + if (err) + goto phy_err; + + return 0; + +phy_err: + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_exit(&priv->phy); + if (ret) + error("failed to release phy\n"); + } + +reset_err: + ret = reset_release_all(priv->resets, priv->reset_count); + if (ret) + error("failed to assert all resets\n"); +clk_err: + ret = clk_release_all(priv->clocks, priv->clock_count); + if (ret) + error("failed to disable all clocks\n"); + + return err; +} + +static int ehci_usb_remove(struct udevice *dev) +{ + struct generic_ehci *priv = dev_get_priv(dev); + int ret; + + ret = ehci_deregister(dev); + if (ret) + return ret; + + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_exit(&priv->phy); + if (ret) + return ret; + } + + ret = reset_release_all(priv->resets, priv->reset_count); + if (ret) + return ret; + + return clk_release_all(priv->clocks, priv->clock_count); } static const struct udevice_id ehci_usb_ids[] = { @@ -67,7 +169,7 @@ U_BOOT_DRIVER(ehci_generic) = { .id = UCLASS_USB, .of_match = ehci_usb_ids, .probe = ehci_usb_probe, - .remove = ehci_deregister, + .remove = ehci_usb_remove, .ops = &ehci_usb_ops, .priv_auto_alloc_size = sizeof(struct generic_ehci), .flags = DM_FLAG_ALLOC_PRIV_DMA, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 13aa70d..3243c1d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -52,8 +52,8 @@ static struct descriptor { 0, /* wHubCharacteristics */ 10, /* bPwrOn2PwrGood */ 0, /* bHubCntrCurrent */ - {}, /* Device removable */ - {} /* at most 7 ports! XXX */ + { /* Device removable */ + } /* at most 7 ports! XXX */ }, { 0x12, /* bLength */ @@ -148,9 +148,12 @@ static void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg, static uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port) { - if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) { + int max_ports = HCS_N_PORTS(ehci_readl(&ctrl->hccr->cr_hcsparams)); + + if (port < 0 || port >= max_ports) { /* Printing the message would cause a scan failure! */ - debug("The request port(%u) is not configured\n", port); + debug("The request port(%u) exceeds maximum port number\n", + port); return NULL; } @@ -205,6 +208,7 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl) { int i, ret = 0; uint32_t cmd, reg; + int max_ports = HCS_N_PORTS(ehci_readl(&ctrl->hccr->cr_hcsparams)); if (!ctrl || !ctrl->hcor) return -EINVAL; @@ -219,7 +223,7 @@ static int ehci_shutdown(struct ehci_ctrl *ctrl) 100 * 1000); if (!ret) { - for (i = 0; i < CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS; i++) { + for (i = 0; i < max_ports; i++) { reg = ehci_readl(&ctrl->hcor->or_portsc[i]); reg |= EHCI_PS_SUSP; ehci_writel(&ctrl->hcor->or_portsc[i], reg); @@ -937,7 +941,7 @@ unknown: return -1; } -const struct ehci_ops default_ehci_ops = { +static const struct ehci_ops default_ehci_ops = { .set_usb_mode = ehci_set_usbmode, .get_port_speed = ehci_get_port_speed, .powerup_fixup = ehci_powerup_fixup, diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 7dc37f0..1c72330 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "ehci.h" @@ -695,12 +694,11 @@ static void config_clock(const u32 timing[]) static int fdt_decode_usb(struct udevice *dev, struct fdt_usb *config) { - const void *blob = gd->fdt_blob; - int node = dev_of_offset(dev); const char *phy, *mode; - config->reg = (struct usb_ctlr *)devfdt_get_addr(dev); - mode = fdt_getprop(blob, node, "dr_mode", NULL); + config->reg = (struct usb_ctlr *)dev_read_addr(dev); + debug("reg=%p\n", config->reg); + mode = dev_read_string(dev, "dr_mode"); if (mode) { if (0 == strcmp(mode, "host")) config->dr_mode = DR_MODE_HOST; @@ -717,28 +715,24 @@ static int fdt_decode_usb(struct udevice *dev, struct fdt_usb *config) config->dr_mode = DR_MODE_HOST; } - phy = fdt_getprop(blob, node, "phy_type", NULL); + phy = dev_read_string(dev, "phy_type"); config->utmi = phy && 0 == strcmp("utmi", phy); config->ulpi = phy && 0 == strcmp("ulpi", phy); - config->enabled = fdtdec_get_is_enabled(blob, node); - config->has_legacy_mode = fdtdec_get_bool(blob, node, - "nvidia,has-legacy-mode"); - config->periph_id = clock_decode_periph_id(blob, node); + config->has_legacy_mode = dev_read_bool(dev, "nvidia,has-legacy-mode"); + config->periph_id = clock_decode_periph_id(dev); if (config->periph_id == PERIPH_ID_NONE) { debug("%s: Missing/invalid peripheral ID\n", __func__); return -EINVAL; } - gpio_request_by_name_nodev(offset_to_ofnode(node), "nvidia,vbus-gpio", - 0, &config->vbus_gpio, GPIOD_IS_OUT); - gpio_request_by_name_nodev(offset_to_ofnode(node), - "nvidia,phy-reset-gpio", 0, - &config->phy_reset_gpio, GPIOD_IS_OUT); - debug("enabled=%d, legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, " - "vbus=%d, phy_reset=%d, dr_mode=%d\n", - config->enabled, config->has_legacy_mode, config->utmi, - config->ulpi, config->periph_id, - gpio_get_number(&config->vbus_gpio), - gpio_get_number(&config->phy_reset_gpio), config->dr_mode); + gpio_request_by_name(dev, "nvidia,vbus-gpio", 0, &config->vbus_gpio, + GPIOD_IS_OUT); + gpio_request_by_name(dev, "nvidia,phy-reset-gpio", 0, + &config->phy_reset_gpio, GPIOD_IS_OUT); + debug("legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, vbus=%d, phy_reset=%d, dr_mode=%d, reg=%p\n", + config->has_legacy_mode, config->utmi, config->ulpi, + config->periph_id, gpio_get_number(&config->vbus_gpio), + gpio_get_number(&config->phy_reset_gpio), config->dr_mode, + config->reg); return 0; } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2ab830d..7c39bec 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -11,9 +11,8 @@ #include -#if !defined(CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 2 -#endif +/* Section 2.2.3 - N_PORTS */ +#define MAX_HC_PORTS 15 /* * Register Space. @@ -62,7 +61,7 @@ struct ehci_hcor { uint32_t _reserved_1_[6]; uint32_t or_configflag; #define FLAG_CF (1 << 0) /* true: we'll support "high speed" */ - uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS]; + uint32_t or_portsc[MAX_HC_PORTS]; #define PORTSC_PSPD(x) (((x) >> 26) & 0x3) #define PORTSC_PSPD_FS 0x0 #define PORTSC_PSPD_LS 0x1 diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c index f85738f..e22ee97 100644 --- a/drivers/usb/host/ohci-generic.c +++ b/drivers/usb/host/ohci-generic.c @@ -5,7 +5,11 @@ */ #include +#include #include +#include +#include +#include #include "ohci.h" #if !defined(CONFIG_USB_OHCI_NEW) @@ -14,18 +18,133 @@ struct generic_ohci { ohci_t ohci; + struct clk *clocks; /* clock list */ + struct reset_ctl *resets; /* reset list */ + struct phy phy; + int clock_count; /* number of clock in clock list */ + int reset_count; /* number of reset in reset list */ }; static int ohci_usb_probe(struct udevice *dev) { struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev); + struct generic_ohci *priv = dev_get_priv(dev); + int i, err, ret, clock_nb, reset_nb; - return ohci_register(dev, regs); + err = 0; + priv->clock_count = 0; + clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + if (clock_nb > 0) { + priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), + GFP_KERNEL); + if (!priv->clocks) + return -ENOMEM; + + for (i = 0; i < clock_nb; i++) { + err = clk_get_by_index(dev, i, &priv->clocks[i]); + if (err < 0) + break; + + err = clk_enable(&priv->clocks[i]); + if (err) { + error("failed to enable clock %d\n", i); + clk_free(&priv->clocks[i]); + goto clk_err; + } + priv->clock_count++; + } + } else if (clock_nb != -ENOENT) { + error("failed to get clock phandle(%d)\n", clock_nb); + return clock_nb; + } + + priv->reset_count = 0; + reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells"); + if (reset_nb > 0) { + priv->resets = devm_kcalloc(dev, reset_nb, + sizeof(struct reset_ctl), + GFP_KERNEL); + if (!priv->resets) + return -ENOMEM; + + for (i = 0; i < reset_nb; i++) { + err = reset_get_by_index(dev, i, &priv->resets[i]); + if (err < 0) + break; + + err = reset_deassert(&priv->resets[i]); + if (err) { + error("failed to deassert reset %d\n", i); + reset_free(&priv->resets[i]); + goto reset_err; + } + priv->reset_count++; + } + } else if (reset_nb != -ENOENT) { + error("failed to get reset phandle(%d)\n", reset_nb); + goto clk_err; + } + + err = generic_phy_get_by_index(dev, 0, &priv->phy); + if (err) { + if (err != -ENOENT) { + error("failed to get usb phy\n"); + goto reset_err; + } + } else { + + err = generic_phy_init(&priv->phy); + if (err) { + error("failed to init usb phy\n"); + goto reset_err; + } + } + + err = ohci_register(dev, regs); + if (err) + goto phy_err; + + return 0; + +phy_err: + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_exit(&priv->phy); + if (ret) + error("failed to release phy\n"); + } + +reset_err: + ret = reset_release_all(priv->resets, priv->reset_count); + if (ret) + error("failed to assert all resets\n"); +clk_err: + ret = clk_release_all(priv->clocks, priv->clock_count); + if (ret) + error("failed to disable all clocks\n"); + + return err; } static int ohci_usb_remove(struct udevice *dev) { - return ohci_deregister(dev); + struct generic_ohci *priv = dev_get_priv(dev); + int ret; + + ret = ohci_deregister(dev); + if (ret) + return ret; + + if (generic_phy_valid(&priv->phy)) { + ret = generic_phy_exit(&priv->phy); + if (ret) + return ret; + } + + ret = reset_release_all(priv->resets, priv->reset_count); + if (ret) + return ret; + + return clk_release_all(priv->clocks, priv->clock_count); } static const struct udevice_id ohci_usb_ids[] = { diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 110ddc9..0b8a501 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -139,6 +139,17 @@ int usb_reset_root_port(struct usb_device *udev) return ops->reset_root_port(bus, udev); } +int usb_update_hub_device(struct usb_device *udev) +{ + struct udevice *bus = udev->controller_dev; + struct dm_usb_ops *ops = usb_get_ops(bus); + + if (!ops->update_hub_device) + return -ENOSYS; + + return ops->update_hub_device(bus, udev); +} + int usb_stop(void) { struct udevice *bus; @@ -177,7 +188,6 @@ int usb_stop(void) #ifdef CONFIG_USB_STORAGE usb_stor_reset(); #endif - usb_hub_reset(); uc_priv->companion_device_count = 0; usb_started = 0; @@ -230,7 +240,6 @@ int usb_init(void) int ret; asynch_allowed = 1; - usb_hub_reset(); ret = uclass_get(UCLASS_USB, &uc); if (ret) @@ -373,8 +382,8 @@ int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp) } /* returns 0 if no match, 1 if match */ -int usb_match_device(const struct usb_device_descriptor *desc, - const struct usb_device_id *id) +static int usb_match_device(const struct usb_device_descriptor *desc, + const struct usb_device_id *id) { if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && id->idVendor != le16_to_cpu(desc->idVendor)) @@ -410,9 +419,9 @@ int usb_match_device(const struct usb_device_descriptor *desc, } /* returns 0 if no match, 1 if match */ -int usb_match_one_id_intf(const struct usb_device_descriptor *desc, - const struct usb_interface_descriptor *int_desc, - const struct usb_device_id *id) +static int usb_match_one_id_intf(const struct usb_device_descriptor *desc, + const struct usb_interface_descriptor *int_desc, + const struct usb_device_id *id) { /* The interface class, subclass, protocol and number should never be * checked for a match if the device class is Vendor Specific, @@ -445,9 +454,9 @@ int usb_match_one_id_intf(const struct usb_device_descriptor *desc, } /* returns 0 if no match, 1 if match */ -int usb_match_one_id(struct usb_device_descriptor *desc, - struct usb_interface_descriptor *int_desc, - const struct usb_device_id *id) +static int usb_match_one_id(struct usb_device_descriptor *desc, + struct usb_interface_descriptor *int_desc, + const struct usb_device_id *id) { if (!usb_match_device(desc, id)) return 0; @@ -680,7 +689,7 @@ int usb_detect_change(void) return change; } -int usb_child_post_bind(struct udevice *dev) +static int usb_child_post_bind(struct udevice *dev) { struct usb_dev_platdata *plat = dev_get_parent_platdata(dev); int val; diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 33961cd..4191a89 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -9,8 +9,21 @@ */ #include +#include +#include +#include +#include + +#include "xhci.h" #include #include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct xhci_dwc3_platdata { + struct phy usb_phy; +}; void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode) { @@ -19,7 +32,7 @@ void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode) DWC3_GCTL_PRTCAPDIR(mode)); } -void dwc3_phy_reset(struct dwc3 *dwc3_reg) +static void dwc3_phy_reset(struct dwc3 *dwc3_reg) { /* Assert USB3 PHY reset */ setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST); @@ -97,3 +110,79 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL | GFLADJ_30MHZ(val)); } + +#ifdef CONFIG_DM_USB +static int xhci_dwc3_probe(struct udevice *dev) +{ + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); + struct xhci_hcor *hcor; + struct xhci_hccr *hccr; + struct dwc3 *dwc3_reg; + enum usb_dr_mode dr_mode; + int ret; + + hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev)); + hcor = (struct xhci_hcor *)((uintptr_t)hccr + + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); + + ret = generic_phy_get_by_index(dev, 0, &plat->usb_phy); + if (ret) { + if (ret != -ENOENT) { + error("Failed to get USB PHY for %s\n", dev->name); + return ret; + } + } else { + ret = generic_phy_init(&plat->usb_phy); + if (ret) { + error("Can't init USB PHY for %s\n", dev->name); + return ret; + } + } + + dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); + + dwc3_core_init(dwc3_reg); + + dr_mode = usb_get_dr_mode(dev_of_offset(dev)); + if (dr_mode == USB_DR_MODE_UNKNOWN) + /* by default set dual role mode to HOST */ + dr_mode = USB_DR_MODE_HOST; + + dwc3_set_mode(dwc3_reg, dr_mode); + + return xhci_register(dev, hccr, hcor); +} + +static int xhci_dwc3_remove(struct udevice *dev) +{ + struct xhci_dwc3_platdata *plat = dev_get_platdata(dev); + int ret; + + if (generic_phy_valid(&plat->usb_phy)) { + ret = generic_phy_exit(&plat->usb_phy); + if (ret) { + error("Can't deinit USB PHY for %s\n", dev->name); + return ret; + } + } + + return xhci_deregister(dev); +} + +static const struct udevice_id xhci_dwc3_ids[] = { + { .compatible = "snps,dwc3" }, + { } +}; + +U_BOOT_DRIVER(xhci_dwc3) = { + .name = "xhci-dwc3", + .id = UCLASS_USB, + .of_match = xhci_dwc3_ids, + .probe = xhci_dwc3_probe, + .remove = xhci_dwc3_remove, + .ops = &xhci_usb_ops, + .priv_auto_alloc_size = sizeof(struct xhci_ctrl), + .platdata_auto_alloc_size = sizeof(struct xhci_dwc3_platdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 62db51d..d5eab3a 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -96,6 +96,25 @@ static void xhci_ring_free(struct xhci_ring *ring) } /** + * Free the scratchpad buffer array and scratchpad buffers + * + * @ctrl host controller data structure + * @return none + */ +static void xhci_scratchpad_free(struct xhci_ctrl *ctrl) +{ + if (!ctrl->scratchpad) + return; + + ctrl->dcbaa->dev_context_ptrs[0] = 0; + + free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]); + free(ctrl->scratchpad->sp_array); + free(ctrl->scratchpad); + ctrl->scratchpad = NULL; +} + +/** * frees the "xhci_container_ctx" pointer passed * * @param ptr pointer to "xhci_container_ctx" to be freed @@ -155,6 +174,7 @@ void xhci_cleanup(struct xhci_ctrl *ctrl) { xhci_ring_free(ctrl->event_ring); xhci_ring_free(ctrl->cmd_ring); + xhci_scratchpad_free(ctrl); xhci_free_virt_devices(ctrl); free(ctrl->erst.entries); free(ctrl->dcbaa); @@ -320,6 +340,70 @@ struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs) } /** + * Set up the scratchpad buffer array and scratchpad buffers + * + * @ctrl host controller data structure + * @return -ENOMEM if buffer allocation fails, 0 on success + */ +static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl) +{ + struct xhci_hccr *hccr = ctrl->hccr; + struct xhci_hcor *hcor = ctrl->hcor; + struct xhci_scratchpad *scratchpad; + int num_sp; + uint32_t page_size; + void *buf; + int i; + + num_sp = HCS_MAX_SCRATCHPAD(xhci_readl(&hccr->cr_hcsparams2)); + if (!num_sp) + return 0; + + scratchpad = malloc(sizeof(*scratchpad)); + if (!scratchpad) + goto fail_sp; + ctrl->scratchpad = scratchpad; + + scratchpad->sp_array = xhci_malloc(num_sp * sizeof(u64)); + if (!scratchpad->sp_array) + goto fail_sp2; + ctrl->dcbaa->dev_context_ptrs[0] = + cpu_to_le64((uintptr_t)scratchpad->sp_array); + + page_size = xhci_readl(&hcor->or_pagesize) & 0xffff; + for (i = 0; i < 16; i++) { + if ((0x1 & page_size) != 0) + break; + page_size = page_size >> 1; + } + BUG_ON(i == 16); + + page_size = 1 << (i + 12); + buf = memalign(page_size, num_sp * page_size); + if (!buf) + goto fail_sp3; + memset(buf, '\0', num_sp * page_size); + xhci_flush_cache((uintptr_t)buf, num_sp * page_size); + + for (i = 0; i < num_sp; i++) { + uintptr_t ptr = (uintptr_t)buf + i * page_size; + scratchpad->sp_array[i] = cpu_to_le64(ptr); + } + + return 0; + +fail_sp3: + free(scratchpad->sp_array); + +fail_sp2: + free(scratchpad); + ctrl->scratchpad = NULL; + +fail_sp: + return -ENOMEM; +} + +/** * Allocates the Container context * * @param ctrl Host controller data structure @@ -499,6 +583,9 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, xhci_writeq(&ctrl->ir_set->erst_base, val_64); + /* set up the scratchpad buffer array and scratchpad buffers */ + xhci_scratchpad_alloc(ctrl); + /* initializing the virtual devices to NULL */ for (i = 0; i < MAX_HC_SLOTS; ++i) ctrl->devs[i] = NULL; @@ -626,14 +713,21 @@ void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx, * @param udev pointer to the Device Data Structure * @return returns negative value on failure else 0 on success */ -void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id, - int speed, int hop_portnr) +void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, + struct usb_device *udev, int hop_portnr) { struct xhci_virt_device *virt_dev; struct xhci_ep_ctx *ep0_ctx; struct xhci_slot_ctx *slot_ctx; u32 port_num = 0; u64 trb_64 = 0; + int slot_id = udev->slot_id; + int speed = udev->speed; + int route = 0; +#ifdef CONFIG_DM_USB + struct usb_device *dev = udev; + struct usb_hub_device *hub; +#endif virt_dev = ctrl->devs[slot_id]; @@ -644,7 +738,32 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id, slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->in_ctx); /* Only the control endpoint is valid - one endpoint context */ - slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | 0); + slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1)); + +#ifdef CONFIG_DM_USB + /* Calculate the route string for this device */ + port_num = dev->portnr; + while (!usb_hub_is_root_hub(dev->dev)) { + hub = dev_get_uclass_priv(dev->dev); + /* + * Each hub in the topology is expected to have no more than + * 15 ports in order for the route string of a device to be + * unique. SuperSpeed hubs are restricted to only having 15 + * ports, but FS/LS/HS hubs are not. The xHCI specification + * says that if the port number the device is greater than 15, + * that portion of the route string shall be set to 15. + */ + if (port_num > 15) + port_num = 15; + route |= port_num << (hub->hub_depth * 4); + dev = dev_get_parent_priv(dev->dev); + port_num = dev->portnr; + dev = dev_get_parent_priv(dev->dev->parent); + } + + debug("route string %x\n", route); +#endif + slot_ctx->dev_info |= route; switch (speed) { case USB_SPEED_SUPER: @@ -664,6 +783,20 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id, BUG(); } +#ifdef CONFIG_DM_USB + /* Set up TT fields to support FS/LS devices */ + if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) { + dev = dev_get_parent_priv(udev->dev); + if (dev->speed == USB_SPEED_HIGH) { + hub = dev_get_uclass_priv(udev->dev); + if (hub->tt.multi) + slot_ctx->dev_info |= cpu_to_le32(DEV_MTT); + slot_ctx->tt_info |= cpu_to_le32(TT_PORT(udev->portnr)); + slot_ctx->tt_info |= cpu_to_le32(TT_SLOT(dev->slot_id)); + } + } +#endif + port_num = hop_portnr; debug("port_num = %d\n", port_num); diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 63daaa6..e4a0ef4 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -8,66 +8,10 @@ #include #include -#include #include #include - #include "xhci.h" -#ifndef CONFIG_DM_USB - -/* - * Create the appropriate control structures to manage a new XHCI host - * controller. - */ -int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr, - struct xhci_hcor **ret_hcor) -{ - struct xhci_hccr *hccr; - struct xhci_hcor *hcor; - pci_dev_t pdev; - uint32_t cmd; - int len; - - pdev = pci_find_class(PCI_CLASS_SERIAL_USB_XHCI, index); - if (pdev < 0) { - printf("XHCI host controller not found\n"); - return -1; - } - - hccr = (struct xhci_hccr *)pci_map_bar(pdev, - PCI_BASE_ADDRESS_0, PCI_REGION_MEM); - len = HC_LENGTH(xhci_readl(&hccr->cr_capbase)); - hcor = (struct xhci_hcor *)((uint32_t)hccr + len); - - debug("XHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", - (uint32_t)hccr, (uint32_t)hcor, len); - - *ret_hccr = hccr; - *ret_hcor = hcor; - - /* enable busmaster */ - pci_read_config_dword(pdev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - pci_write_config_dword(pdev, PCI_COMMAND, cmd); - - return 0; -} - -/* - * Destroy the appropriate control structures corresponding * to the XHCI host - * controller - */ -void xhci_hcd_stop(int index) -{ -} - -#else - -struct xhci_pci_priv { - struct xhci_ctrl ctrl; /* Needs to come first in this struct! */ -}; - static void xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr, struct xhci_hcor **ret_hcor) { @@ -103,17 +47,6 @@ static int xhci_pci_probe(struct udevice *dev) return xhci_register(dev, hccr, hcor); } -static int xhci_pci_remove(struct udevice *dev) -{ - int ret; - - ret = xhci_deregister(dev); - if (ret) - return ret; - - return 0; -} - static const struct udevice_id xhci_pci_ids[] = { { .compatible = "xhci-pci" }, { } @@ -123,11 +56,11 @@ U_BOOT_DRIVER(xhci_pci) = { .name = "xhci_pci", .id = UCLASS_USB, .probe = xhci_pci_probe, - .remove = xhci_pci_remove, + .remove = xhci_deregister, .of_match = xhci_pci_ids, .ops = &xhci_usb_ops, .platdata_auto_alloc_size = sizeof(struct usb_platdata), - .priv_auto_alloc_size = sizeof(struct xhci_pci_priv), + .priv_auto_alloc_size = sizeof(struct xhci_ctrl), .flags = DM_FLAG_ALLOC_PRIV_DMA, }; @@ -137,5 +70,3 @@ static struct pci_device_id xhci_pci_supported[] = { }; U_BOOT_PCI_DEVICE(xhci_pci, xhci_pci_supported); - -#endif /* CONFIG_DM_USB */ diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2675a8f..579e670 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -280,8 +280,15 @@ void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id, fields[0] = lower_32_bits(val_64); fields[1] = upper_32_bits(val_64); fields[2] = 0; - fields[3] = TRB_TYPE(cmd) | EP_ID_FOR_TRB(ep_index) | - SLOT_ID_FOR_TRB(slot_id) | ctrl->cmd_ring->cycle_state; + fields[3] = TRB_TYPE(cmd) | SLOT_ID_FOR_TRB(slot_id) | + ctrl->cmd_ring->cycle_state; + + /* + * Only 'reset endpoint', 'stop endpoint' and 'set TR dequeue pointer' + * commands need endpoint id encoded. + */ + if (cmd >= TRB_RESET_EP && cmd <= TRB_SET_DEQ) + fields[3] |= EP_ID_FOR_TRB(ep_index); queue_trb(ctrl, ctrl->cmd_ring, false, fields); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3201177..9b82ee5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -50,8 +50,8 @@ static struct descriptor { cpu_to_le16(0x8), /* wHubCharacteristics */ 10, /* bPwrOn2PwrGood */ 0, /* bHubCntrCurrent */ - {}, /* Device removable */ - {} /* at most 7 ports! XXX */ + { /* Device removable */ + } /* at most 7 ports! XXX */ }, { 0x12, /* bLength */ @@ -192,7 +192,7 @@ static int xhci_start(struct xhci_hcor *hcor) * @param hcor pointer to host controller operation registers * @return -EBUSY if XHCI Controller is not halted else status of handshake */ -int xhci_reset(struct xhci_hcor *hcor) +static int xhci_reset(struct xhci_hcor *hcor) { u32 cmd; u32 state; @@ -332,8 +332,8 @@ static int xhci_set_configuration(struct usb_device *udev) ifdesc = &udev->config.if_desc[0]; ctrl_ctx = xhci_get_input_control_ctx(in_ctx); - /* Zero the input context control */ - ctrl_ctx->add_flags = 0; + /* Initialize the input context control */ + ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG); ctrl_ctx->drop_flags = 0; /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */ @@ -415,8 +415,7 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr) * so setting up the slot context. */ debug("Setting up addressable devices %p\n", ctrl->dcbaa); - xhci_setup_addressable_virt_dev(ctrl, udev->slot_id, udev->speed, - root_portnr); + xhci_setup_addressable_virt_dev(ctrl, udev, root_portnr); ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); @@ -481,7 +480,7 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr) * @param udev pointer to the Device Data Structure * @return Returns 0 on succes else return error code on failure */ -int _xhci_alloc_device(struct usb_device *udev) +static int _xhci_alloc_device(struct usb_device *udev) { struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); union xhci_trb *event; @@ -668,12 +667,14 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, uint32_t reg; volatile uint32_t *status_reg; struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); + struct xhci_hccr *hccr = ctrl->hccr; struct xhci_hcor *hcor = ctrl->hcor; + int max_ports = HCS_MAX_PORTS(xhci_readl(&hccr->cr_hcsparams1)); if ((req->requesttype & USB_RT_PORT) && - le16_to_cpu(req->index) > CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS) { - printf("The request port(%d) is not configured\n", - le16_to_cpu(req->index) - 1); + le16_to_cpu(req->index) > max_ports) { + printf("The request port(%d) exceeds maximum port number\n", + le16_to_cpu(req->index) - 1); return -EINVAL; } @@ -727,6 +728,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8): switch (le16_to_cpu(req->value) >> 8) { case USB_DT_HUB: + case USB_DT_SS_HUB: debug("USB_DT_HUB config\n"); srcptr = &descriptor.hub; srclen = 0x8; @@ -1113,26 +1115,6 @@ int usb_lowlevel_stop(int index) #endif /* CONFIG_DM_USB */ #ifdef CONFIG_DM_USB -/* -static struct usb_device *get_usb_device(struct udevice *dev) -{ - struct usb_device *udev; - - if (device_get_uclass_id(dev) == UCLASS_USB) - udev = dev_get_uclass_priv(dev); - else - udev = dev_get_parent_priv(dev); - - return udev; -} -*/ -static bool is_root_hub(struct udevice *dev) -{ - if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) - return true; - - return false; -} static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buffer, int length, @@ -1147,10 +1129,10 @@ static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev, hub = udev->dev; if (device_get_uclass_id(hub) == UCLASS_USB_HUB) { /* Figure out our port number on the root hub */ - if (is_root_hub(hub)) { + if (usb_hub_is_root_hub(hub)) { root_portnr = udev->portnr; } else { - while (!is_root_hub(hub->parent)) + while (!usb_hub_is_root_hub(hub->parent)) hub = hub->parent; uhop = dev_get_parent_priv(hub); root_portnr = uhop->portnr; @@ -1188,6 +1170,64 @@ static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev) return _xhci_alloc_device(udev); } +static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev) +{ + struct xhci_ctrl *ctrl = dev_get_priv(dev); + struct usb_hub_device *hub = dev_get_uclass_priv(udev->dev); + struct xhci_virt_device *virt_dev; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_container_ctx *out_ctx; + struct xhci_container_ctx *in_ctx; + struct xhci_slot_ctx *slot_ctx; + int slot_id = udev->slot_id; + unsigned think_time; + + debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); + + /* Ignore root hubs */ + if (usb_hub_is_root_hub(udev->dev)) + return 0; + + virt_dev = ctrl->devs[slot_id]; + BUG_ON(!virt_dev); + + out_ctx = virt_dev->out_ctx; + in_ctx = virt_dev->in_ctx; + + ctrl_ctx = xhci_get_input_control_ctx(in_ctx); + /* Initialize the input context control */ + ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG); + ctrl_ctx->drop_flags = 0; + + xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size); + + /* slot context */ + xhci_slot_copy(ctrl, in_ctx, out_ctx); + slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx); + + /* Update hub related fields */ + slot_ctx->dev_info |= cpu_to_le32(DEV_HUB); + if (hub->tt.multi && udev->speed == USB_SPEED_HIGH) + slot_ctx->dev_info |= cpu_to_le32(DEV_MTT); + slot_ctx->dev_info2 |= cpu_to_le32(XHCI_MAX_PORTS(udev->maxchild)); + /* + * Set TT think time - convert from ns to FS bit times. + * Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns + * + * 0 = 8 FS bit times, 1 = 16 FS bit times, + * 2 = 24 FS bit times, 3 = 32 FS bit times. + * + * This field shall be 0 if the device is not a high-spped hub. + */ + think_time = hub->tt.think_time; + if (think_time != 0) + think_time = (think_time / 666) - 1; + if (udev->speed == USB_SPEED_HIGH) + slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time)); + + return xhci_configure_endpoints(udev, false); +} + int xhci_register(struct udevice *dev, struct xhci_hccr *hccr, struct xhci_hcor *hcor) { @@ -1240,6 +1280,7 @@ struct dm_usb_ops xhci_usb_ops = { .bulk = xhci_submit_bulk_msg, .interrupt = xhci_submit_int_msg, .alloc_device = xhci_alloc_device, + .update_hub_device = xhci_update_hub_device, }; #endif diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2afa386..a497d9d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -30,7 +30,7 @@ /* Max number of USB devices for any host controller - limit in section 6.1 */ #define MAX_HC_SLOTS 256 /* Section 5.3.3 - MaxPorts */ -#define MAX_HC_PORTS 127 +#define MAX_HC_PORTS 255 /* Up to 16 ms to halt an HC */ #define XHCI_MAX_HALT_USEC (16*1000) @@ -102,8 +102,8 @@ struct xhci_hccr { #define HCS_MAX_INTRS(p) (((p) >> 8) & 0x7ff) /* bits 24:31, Max Ports - max value is 0x7F = 127 ports */ #define HCS_MAX_PORTS_SHIFT 24 -#define HCS_MAX_PORTS_MASK (0x7f << HCS_MAX_PORTS_SHIFT) -#define HCS_MAX_PORTS(p) (((p) >> 24) & 0x7f) +#define HCS_MAX_PORTS_MASK (0xff << HCS_MAX_PORTS_SHIFT) +#define HCS_MAX_PORTS(p) (((p) >> 24) & 0xff) /* HCSPARAMS2 - hcs_params2 - bitmasks */ /* bits 0:3, frames or uframes that SW needs to queue transactions @@ -111,9 +111,10 @@ struct xhci_hccr { #define HCS_IST(p) (((p) >> 0) & 0xf) /* bits 4:7, max number of Event Ring segments */ #define HCS_ERST_MAX(p) (((p) >> 4) & 0xf) +/* bits 21:25 Hi 5 bits of Scratchpad buffers SW must allocate for the HW */ /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ -/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ -#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f) +/* bits 27:31 Lo 5 bits of Scratchpad buffers SW must allocate for the HW */ +#define HCS_MAX_SCRATCHPAD(p) ((((p) >> 16) & 0x3e0) | (((p) >> 27) & 0x1f)) /* HCSPARAMS3 - hcs_params3 - bitmasks */ /* bits 0:7, Max U1 to U0 latency for the roothub ports */ @@ -171,9 +172,7 @@ struct xhci_hcor { volatile uint64_t or_dcbaap; volatile uint32_t or_config; volatile uint32_t reserved_2[241]; - struct xhci_hcor_port_regs portregs[CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS]; - - uint32_t reserved_4[CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS * 254]; + struct xhci_hcor_port_regs portregs[MAX_HC_PORTS]; }; /* USBCMD - USB command - command bitmasks */ @@ -482,10 +481,9 @@ struct xhci_protocol_caps { * @type: Type of context. Used to calculated offsets to contained contexts. * @size: Size of the context data * @bytes: The raw context data given to HW - * @dma: dma address of the bytes * * Represents either a Device or Input context. Holds a pointer to the raw - * memory used for the context (bytes) and dma address of it (dma). + * memory used for the context (bytes). */ struct xhci_container_ctx { unsigned type; @@ -550,12 +548,12 @@ struct xhci_slot_ctx { * The Slot ID of the hub that isolates the high speed signaling from * this low or full-speed device. '0' if attached to root hub port. */ -#define TT_SLOT (0xff) +#define TT_SLOT(p) (((p) & 0xff) << 0) /* * The number of the downstream facing port of the high-speed hub * '0' if the device is not low or full speed. */ -#define TT_PORT (0xff << 8) +#define TT_PORT(p) (((p) & 0xff) << 8) #define TT_THINK_TIME(p) (((p) & 0x3) << 16) /* dev_state bitmasks */ @@ -1038,6 +1036,10 @@ struct xhci_erst { unsigned int erst_size; }; +struct xhci_scratchpad { + u64 *sp_array; +}; + /* * Each segment table entry is 4*32bits long. 1K seems like an ok size: * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, @@ -1225,6 +1227,7 @@ struct xhci_ctrl { struct xhci_intr_reg *ir_set; struct xhci_erst erst; struct xhci_erst_entry entry[ERST_NUM_SEGS]; + struct xhci_scratchpad *scratchpad; struct xhci_virt_device *devs[MAX_HC_SLOTS]; int rootdev; }; @@ -1244,8 +1247,8 @@ void xhci_endpoint_copy(struct xhci_ctrl *ctrl, void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx, struct xhci_container_ctx *out_ctx); -void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id, - int speed, int hop_portnr); +void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, + struct usb_device *udev, int hop_portnr); void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id, u32 ep_index, trb_type cmd); void xhci_acknowledge_event(struct xhci_ctrl *ctrl); diff --git a/drivers/video/tegra124/display.c b/drivers/video/tegra124/display.c index 47752b2..4164fa1 100644 --- a/drivers/video/tegra124/display.c +++ b/drivers/video/tegra124/display.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -334,7 +333,6 @@ static int display_init(struct udevice *dev, void *lcdbase, { struct display_plat *disp_uc_plat; struct dc_ctlr *dc_ctlr; - const void *blob = gd->fdt_blob; struct udevice *dp_dev; const int href_to_sync = 1, vref_to_sync = 1; int panel_bpp = 18; /* default 18 bits per pixel */ @@ -363,9 +361,8 @@ static int display_init(struct udevice *dev, void *lcdbase, return ret; } - dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, dev_of_offset(dev), - "reg"); - if (fdtdec_decode_display_timing(blob, dev_of_offset(dev), 0, timing)) { + dc_ctlr = (struct dc_ctlr *)dev_read_addr(dev); + if (ofnode_decode_display_timing(dev_ofnode(dev), 0, timing)) { debug("%s: Failed to decode display timing\n", __func__); return -EINVAL; } @@ -416,6 +413,7 @@ static int display_init(struct udevice *dev, void *lcdbase, debug("dc: failed to update window\n"); return ret; } + debug("%s: ready\n", __func__); return 0; } diff --git a/drivers/video/tegra124/dp.c b/drivers/video/tegra124/dp.c index c38b3e5..95d743d 100644 --- a/drivers/video/tegra124/dp.c +++ b/drivers/video/tegra124/dp.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -1572,7 +1571,7 @@ static int tegra_dp_ofdata_to_platdata(struct udevice *dev) { struct tegra_dp_plat *plat = dev_get_platdata(dev); - plat->base = devfdt_get_addr(dev); + plat->base = dev_read_addr(dev); return 0; } diff --git a/drivers/video/tegra124/sor.c b/drivers/video/tegra124/sor.c index 4324071..700ab25 100644 --- a/drivers/video/tegra124/sor.c +++ b/drivers/video/tegra124/sor.c @@ -7,9 +7,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -759,15 +759,12 @@ int tegra_dc_sor_attach(struct udevice *dc_dev, struct udevice *dev, const struct display_timing *timing) { struct tegra_dc_sor_data *sor = dev_get_priv(dev); - const void *blob = gd->fdt_blob; struct dc_ctlr *disp_ctrl; u32 reg_val; - int node; /* Use the first display controller */ debug("%s\n", __func__); - node = dev_of_offset(dc_dev); - disp_ctrl = (struct dc_ctlr *)fdtdec_get_addr(blob, node, "reg"); + disp_ctrl = (struct dc_ctlr *)dev_read_addr(dc_dev); tegra_dc_sor_enable_dc(disp_ctrl); tegra_dc_sor_config_panel(sor, 0, link_cfg, timing); @@ -974,16 +971,13 @@ int tegra_dc_sor_detach(struct udevice *dc_dev, struct udevice *dev) { struct tegra_dc_sor_data *sor = dev_get_priv(dev); int dc_reg_ctx[DC_REG_SAVE_SPACE]; - const void *blob = gd->fdt_blob; struct dc_ctlr *disp_ctrl; unsigned long dc_int_mask; - int node; int ret; debug("%s\n", __func__); /* Use the first display controller */ - node = dev_of_offset(dc_dev); - disp_ctrl = (struct dc_ctlr *)fdtdec_get_addr(blob, node, "reg"); + disp_ctrl = (struct dc_ctlr *)dev_read_addr(dev); /* Sleep mode */ tegra_sor_writel(sor, SUPER_STATE1, SUPER_STATE1_ASY_HEAD_OP_SLEEP | @@ -1050,18 +1044,13 @@ static int tegra_sor_set_backlight(struct udevice *dev, int percent) static int tegra_sor_ofdata_to_platdata(struct udevice *dev) { struct tegra_dc_sor_data *priv = dev_get_priv(dev); - const void *blob = gd->fdt_blob; - int node; int ret; - priv->base = (void *)fdtdec_get_addr(blob, dev_of_offset(dev), "reg"); + priv->base = (void *)dev_read_addr(dev); - node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA124_PMC); - if (node < 0) { - debug("%s: Cannot find PMC\n", __func__); - return -ENOENT; - } - priv->pmc_base = (void *)fdtdec_get_addr(blob, node, "reg"); + priv->pmc_base = (void *)syscon_get_first_range(TEGRA_SYSCON_PMC); + if (IS_ERR(priv->pmc_base)) + return PTR_ERR(priv->pmc_base); ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "nvidia,panel", &priv->panel); diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index fb90be9..86bf656 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -88,7 +88,7 @@ typedef struct global_data { #endif unsigned int timebase_h; unsigned int timebase_l; -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) unsigned long malloc_base; /* base address of early malloc() */ unsigned long malloc_limit; /* limit address */ unsigned long malloc_ptr; /* current address */ diff --git a/include/clk.h b/include/clk.h index 5a5c2ff..c5988f7 100644 --- a/include/clk.h +++ b/include/clk.h @@ -98,6 +98,21 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk); * @return 0 if OK, or a negative error code. */ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk); + +/** + * clk_release_all() - Disable (turn off)/Free an array of previously + * requested clocks. + * + * For each clock contained in the clock array, this function will check if + * clock has been previously requested and then will disable and free it. + * + * @clk: A clock struct array that was previously successfully + * requested by clk_request/get_by_*(). + * @count Number of clock contained in the array + * @return zero on success, or -ve error code. + */ +int clk_release_all(struct clk *clk, int count); + #else static inline int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) @@ -110,6 +125,12 @@ static inline int clk_get_by_name(struct udevice *dev, const char *name, { return -ENOSYS; } + +static inline int clk_release_all(struct clk *clk, int count) +{ + return -ENOSYS; +} + #endif /** diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index 0a2bcb2..32c5932 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -560,7 +560,6 @@ #define CONFIG_USB_EHCI_PCI #define CONFIG_EHCI_HCD_INIT_AFTER_RESET #define CONFIG_PCI_EHCI_DEVICE 0 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 2 #endif #undef CONFIG_WATCHDOG /* watchdog disabled */ diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index a91b7df..70e7473 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -82,7 +82,6 @@ #if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD) #define CONFIG_SYS_USB_FAT_BOOT_PARTITION 1 #define CONFIG_USB_XHCI_OMAP -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_OMAP_USB_PHY #define CONFIG_AM437X_USB2PHY2_HOST diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h index 9216998..9976686 100644 --- a/include/configs/am57xx_evm.h +++ b/include/configs/am57xx_evm.h @@ -92,7 +92,6 @@ /* USB xHCI HOST */ #define CONFIG_USB_XHCI_OMAP -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_OMAP_USB_PHY #define CONFIG_OMAP_USB3PHY1_HOST diff --git a/include/configs/cl-som-am57x.h b/include/configs/cl-som-am57x.h index c1cf413..120ac02 100644 --- a/include/configs/cl-som-am57x.h +++ b/include/configs/cl-som-am57x.h @@ -83,7 +83,6 @@ /* USB xHCI HOST */ #define CONFIG_USB_XHCI_OMAP -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_OMAP_USB_PHY #define CONFIG_OMAP_USB3PHY1_HOST diff --git a/include/configs/cm_t43.h b/include/configs/cm_t43.h index f6e0743..7a61107 100644 --- a/include/configs/cm_t43.h +++ b/include/configs/cm_t43.h @@ -60,7 +60,6 @@ /* USB support */ #define CONFIG_USB_XHCI_OMAP -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_OMAP_USB_PHY #define CONFIG_AM437X_USB2PHY2_HOST diff --git a/include/configs/cm_t54.h b/include/configs/cm_t54.h index 69706d2..8a4c333 100644 --- a/include/configs/cm_t54.h +++ b/include/configs/cm_t54.h @@ -56,7 +56,6 @@ #define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ CONFIG_SYS_SCSI_MAX_LUN) /* USB UHH support options */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 76 /* HSIC2 HUB #RESET */ diff --git a/include/configs/corvus.h b/include/configs/corvus.h index ed1a228..0150727 100644 --- a/include/configs/corvus.h +++ b/include/configs/corvus.h @@ -94,9 +94,6 @@ #define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_AT91_WANTS_COMMON_PHY -/* USB */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 2 - #define CONFIG_MTD_DEVICE #define CONFIG_MTD_PARTITIONS diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h index 8566bdc..b509151 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -154,7 +154,6 @@ /* USB xHCI HOST */ #define CONFIG_USB_XHCI_OMAP -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_OMAP_USB_PHY #define CONFIG_OMAP_USB2PHY2_HOST diff --git a/include/configs/ds414.h b/include/configs/ds414.h index a209e6f..c1e9346 100644 --- a/include/configs/ds414.h +++ b/include/configs/ds414.h @@ -68,7 +68,6 @@ #if 0 #undef CONFIG_DM_USB #define CONFIG_USB_XHCI_PCI -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif #if !defined(CONFIG_USB_XHCI_HCD) diff --git a/include/configs/duovero.h b/include/configs/duovero.h index 8efcc94..c4496a7 100644 --- a/include/configs/duovero.h +++ b/include/configs/duovero.h @@ -25,8 +25,6 @@ #define CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS /* USB UHH support options */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 - #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 1 #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 62 diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h index 378219d..3b73bbc 100644 --- a/include/configs/exynos5-common.h +++ b/include/configs/exynos5-common.h @@ -134,9 +134,6 @@ /* Enable Time Command */ /* USB */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 - #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX #define CONFIG_USB_ETHER_SMSC95XX diff --git a/include/configs/firefly-rk3288.h b/include/configs/firefly-rk3288.h index bd39111..d6bb9f6 100644 --- a/include/configs/firefly-rk3288.h +++ b/include/configs/firefly-rk3288.h @@ -8,9 +8,10 @@ #define __CONFIG_H #define ROCKCHIP_DEVICE_SETTINGS \ - "stdin=serial,cros-ec-keyb\0" \ + "stdin=serial,usbkbd\0" \ "stdout=serial,vidconsole\0" \ - "stderr=serial,vidconsole\0" + "stderr=serial,vidconsole\0" \ + "preboot=usb start\0" #include diff --git a/include/configs/k2e_evm.h b/include/configs/k2e_evm.h index 7e45549..a438a1a 100644 --- a/include/configs/k2e_evm.h +++ b/include/configs/k2e_evm.h @@ -15,9 +15,18 @@ /* Platform type */ #define CONFIG_SOC_K2E +#ifdef CONFIG_TI_SECURE_DEVICE +#define DEFAULT_SEC_BOOT_ENV \ + DEFAULT_FIT_TI_ARGS \ + "findfdt=setenv fdtfile ${name_fdt}\0" +#else +#define DEFAULT_SEC_BOOT_ENV +#endif + /* U-Boot general configuration */ #define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \ DEFAULT_FW_INITRAMFS_BOOT_ENV \ + DEFAULT_SEC_BOOT_ENV \ "boot=ubi\0" \ "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \ "root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,2048\0" \ diff --git a/include/configs/k2g_evm.h b/include/configs/k2g_evm.h index b0b4206..1117e5e 100644 --- a/include/configs/k2g_evm.h +++ b/include/configs/k2g_evm.h @@ -23,6 +23,7 @@ DEFAULT_MMC_TI_ARGS \ DEFAULT_PMMC_BOOT_ENV \ DEFAULT_FW_INITRAMFS_BOOT_ENV \ + DEFAULT_FIT_TI_ARGS \ "boot=mmc\0" \ "console=ttyS0,115200n8\0" \ "bootpart=0:2\0" \ @@ -51,11 +52,27 @@ "get_mon_mmc=load mmc ${bootpart} ${addr_mon} ${bootdir}/${name_mon}\0"\ "name_fs=arago-base-tisdk-image-k2g-evm.cpio\0" +#ifndef CONFIG_TI_SECURE_DEVICE #define CONFIG_BOOTCOMMAND \ + "run findfdt; " \ "run envboot; " \ - "run set_name_pmmc init_${boot} init_fw_rd_${boot} " \ - "get_pmmc_${boot} run_pmmc get_mon_${boot} run_mon " \ - "findfdt get_fdt_${boot} get_kern_${boot} run_kern" + "run init_${boot}; " \ + "run get_mon_${boot} run_mon; " \ + "run set_name_pmmc get_pmmc_${boot} run_pmmc; " \ + "run get_kern_${boot}; " \ + "run init_fw_rd_${boot}; " \ + "run get_fdt_${boot}; " \ + "run run_kern" +#else +#define CONFIG_BOOTCOMMAND \ + "run findfdt; " \ + "run envboot; " \ + "run run_mon_hs; " \ + "run init_${boot}; " \ + "run set_name_pmmc get_pmmc_${boot} run_pmmc; " \ + "run get_fit_${boot}; " \ + "bootm ${fit_loadaddr}#${name_fdt}" +#endif /* SPL SPI Loader Configuration */ #define CONFIG_SPL_TEXT_BASE 0x0c080000 diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h index 78b901f..dc0ac7d 100644 --- a/include/configs/k2hk_evm.h +++ b/include/configs/k2hk_evm.h @@ -15,9 +15,18 @@ /* Platform type */ #define CONFIG_SOC_K2HK +#ifdef CONFIG_TI_SECURE_DEVICE +#define DEFAULT_SEC_BOOT_ENV \ + DEFAULT_FIT_TI_ARGS \ + "findfdt=setenv fdtfile ${name_fdt}\0" +#else +#define DEFAULT_SEC_BOOT_ENV +#endif + /* U-Boot general configuration */ #define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \ DEFAULT_FW_INITRAMFS_BOOT_ENV \ + DEFAULT_SEC_BOOT_ENV \ "boot=ubi\0" \ "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \ "root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,2048\0" \ diff --git a/include/configs/ls1012afrdm.h b/include/configs/ls1012afrdm.h index f6f88e8..6b1ba57 100644 --- a/include/configs/ls1012afrdm.h +++ b/include/configs/ls1012afrdm.h @@ -39,7 +39,6 @@ #ifdef CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif #define CONFIG_CMD_MEMINFO diff --git a/include/configs/ls1012aqds.h b/include/configs/ls1012aqds.h index 9e6c7a7..bebb0df 100644 --- a/include/configs/ls1012aqds.h +++ b/include/configs/ls1012aqds.h @@ -124,7 +124,6 @@ #ifdef CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif /* MMC */ diff --git a/include/configs/ls1012ardb.h b/include/configs/ls1012ardb.h index 0705bc5..32c8cec 100644 --- a/include/configs/ls1012ardb.h +++ b/include/configs/ls1012ardb.h @@ -27,7 +27,6 @@ #ifdef CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif /* diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h index 1f2eb52..58f893f 100644 --- a/include/configs/ls1021aiot.h +++ b/include/configs/ls1021aiot.h @@ -26,7 +26,6 @@ #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_XHCI_DWC3 #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif #if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_XHCI_USB) diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 251a66e..83e7e7a 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -413,7 +413,6 @@ unsigned long get_board_ddr_clk(void); #ifdef CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif /* diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index b9e5cdb..0aa6fdd 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -50,7 +50,6 @@ #ifdef CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif #define CONFIG_SYS_CLK_FREQ 100000000 diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h index 415a705..0897da1 100644 --- a/include/configs/ls1043aqds.h +++ b/include/configs/ls1043aqds.h @@ -377,7 +377,6 @@ unsigned long get_board_ddr_clk(void); #ifdef CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif /* diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h index 59e7760..617a712 100644 --- a/include/configs/ls1043ardb.h +++ b/include/configs/ls1043ardb.h @@ -288,7 +288,6 @@ #ifdef CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif #endif diff --git a/include/configs/ls1046aqds.h b/include/configs/ls1046aqds.h index ea99676..bb3d941 100644 --- a/include/configs/ls1046aqds.h +++ b/include/configs/ls1046aqds.h @@ -144,7 +144,6 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_XHCI_DWC3 #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_CMD_USB #define CONFIG_USB_STORAGE #endif diff --git a/include/configs/ls1046ardb.h b/include/configs/ls1046ardb.h index 20a5e7f..8c72291 100644 --- a/include/configs/ls1046ardb.h +++ b/include/configs/ls1046ardb.h @@ -220,7 +220,6 @@ #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_XHCI_DWC3 #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_CMD_USB #define CONFIG_USB_STORAGE #endif diff --git a/include/configs/ls2080aqds.h b/include/configs/ls2080aqds.h index 929ae32..66936c4 100644 --- a/include/configs/ls2080aqds.h +++ b/include/configs/ls2080aqds.h @@ -446,7 +446,6 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #include diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index 0be4c4f..744a789 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -346,7 +346,6 @@ unsigned long get_board_sys_clk(void); #define CONFIG_HAS_FSL_XHCI_USB #define CONFIG_USB_XHCI_FSL #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #undef CONFIG_CMDLINE_EDITING #include diff --git a/include/configs/ma5d4evk.h b/include/configs/ma5d4evk.h index 2744efb..7c28a94 100644 --- a/include/configs/ma5d4evk.h +++ b/include/configs/ma5d4evk.h @@ -96,7 +96,6 @@ * USB */ #ifdef CONFIG_CMD_USB -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 /* USB device */ #define CONFIG_USB_ETHER diff --git a/include/configs/mcx.h b/include/configs/mcx.h index 73fdfbd..3f5fdab 100644 --- a/include/configs/mcx.h +++ b/include/configs/mcx.h @@ -74,7 +74,6 @@ /* EHCI */ #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 57 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX #define CONFIG_USB_ETHER_MCS7830 diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index ae95485..6ea607d 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -20,7 +20,8 @@ #define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,serial\0" \ "stdout=vidconsole,serial\0" \ - "stderr=vidconsole,serial\0" + "stderr=vidconsole,serial\0" \ + "usb_pgood_delay=40\0" #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \ diff --git a/include/configs/mvebu_armada-37xx.h b/include/configs/mvebu_armada-37xx.h index 778cc9e..1307d21 100644 --- a/include/configs/mvebu_armada-37xx.h +++ b/include/configs/mvebu_armada-37xx.h @@ -93,14 +93,7 @@ #define CONFIG_NET_RETRY_COUNT 50 #define CONFIG_PHY_MARVELL -/* USB 2.0 */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 - -/* USB 3.0 */ -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 3 - -#define CONFIG_USB_MAX_CONTROLLER_COUNT (CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS + \ - CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS) +#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3) /* USB ethernet */ #define CONFIG_USB_HOST_ETHER diff --git a/include/configs/mvebu_armada-8k.h b/include/configs/mvebu_armada-8k.h index 53db10f..86ae19c 100644 --- a/include/configs/mvebu_armada-8k.h +++ b/include/configs/mvebu_armada-8k.h @@ -97,14 +97,7 @@ #define CONFIG_ARP_TIMEOUT 200 #define CONFIG_NET_RETRY_COUNT 50 -/* USB 2.0 */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 - -/* USB 3.0 */ -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 3 - -#define CONFIG_USB_MAX_CONTROLLER_COUNT (CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS + \ - CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS) +#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3) /* USB ethernet */ #define CONFIG_USB_HOST_ETHER diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h index 9ae3d18..8338d6d 100644 --- a/include/configs/mx35pdk.h +++ b/include/configs/mx35pdk.h @@ -195,7 +195,6 @@ #define CONFIG_SYS_NAND_LARGEPAGE /* EHCI driver */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 #define CONFIG_EHCI_IS_TDI #define CONFIG_EHCI_HCD_INIT_AFTER_RESET #define CONFIG_USB_EHCI_MXC diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 9552c96..563854d 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -184,7 +184,6 @@ /* USB */ #define CONFIG_USB_EHCI_EXYNOS -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_SMSC95XX diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 4422d5e..2fc6693 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -58,7 +58,6 @@ #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 147 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX #define CONFIG_USB_ETHER_MCS7830 diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h index 834822d..133069a 100644 --- a/include/configs/omap3_overo.h +++ b/include/configs/omap3_overo.h @@ -41,7 +41,6 @@ /* USB EHCI */ #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 183 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 /* commands to include */ diff --git a/include/configs/omap4_panda.h b/include/configs/omap4_panda.h index a973ce6..9951980 100644 --- a/include/configs/omap4_panda.h +++ b/include/configs/omap4_panda.h @@ -17,8 +17,6 @@ */ /* USB UHH support options */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 - #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 1 #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 62 diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h index eb5e6df..9b65009 100644 --- a/include/configs/omap5_uevm.h +++ b/include/configs/omap5_uevm.h @@ -51,7 +51,6 @@ #define CONFIG_SYS_I2C_TCA642X_ADDR 0x22 /* USB UHH support options */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 #define CONFIG_EHCI_HCD_INIT_AFTER_RESET #define CONFIG_OMAP_EHCI_PHY2_RESET_GPIO 80 diff --git a/include/configs/picosam9g45.h b/include/configs/picosam9g45.h index 88f841d..a14739f 100644 --- a/include/configs/picosam9g45.h +++ b/include/configs/picosam9g45.h @@ -97,9 +97,6 @@ #define CONFIG_RESET_PHY_R #define CONFIG_AT91_WANTS_COMMON_PHY -/* USB */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 2 - #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ #define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE diff --git a/include/configs/poplar.h b/include/configs/poplar.h index d59f32a..d2ecd0d 100644 --- a/include/configs/poplar.h +++ b/include/configs/poplar.h @@ -30,7 +30,6 @@ #define CONFIG_PL01X_SERIAL /* USB configuration */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #define CONFIG_SYS_USB_EVENT_POLL #define CONFIG_USB_HOST_ETHER diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h index 7f9f0c5..906c821 100644 --- a/include/configs/rk3328_common.h +++ b/include/configs/rk3328_common.h @@ -63,6 +63,4 @@ #define CONFIG_USB_OHCI_NEW #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1 -/* xhci host */ -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #endif diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h index 54ea97b..3317887 100644 --- a/include/configs/rk3399_common.h +++ b/include/configs/rk3399_common.h @@ -16,8 +16,6 @@ #define CONFIG_SYS_CBSIZE 1024 #define CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_SPL_FRAMEWORK -#define CONFIG_SPL_DRIVERS_MISC_SUPPORT -#define CONFIG_SPL_SERIAL_SUPPORT #if defined(CONFIG_SPL_SPI_SUPPORT) #define CONFIG_SPL_SPI_LOAD #endif @@ -82,7 +80,4 @@ #define CONFIG_USB_ETHER_SMSC95XX #define CONFIG_USB_ETHER_RTL8152 -/* rockchip xhci host driver */ -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 - #endif diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h index 0573571..29a492d 100644 --- a/include/configs/rockchip-common.h +++ b/include/configs/rockchip-common.h @@ -28,6 +28,12 @@ #endif #define CONFIG_RANDOM_UUID + +#ifdef CONFIG_ARM64 +#define ROOT_UUID "B921B045-1DF0-41C3-AF44-4C6F280D3FAE;\0" +#else +#define ROOT_UUID "69DAD710-2CE4-4E3C-B16C-21A1D49ABED3;\0" +#endif #define PARTS_DEFAULT \ "uuid_disk=${uuid_gpt_disk};" \ "name=loader1,start=32K,size=4000K,uuid=${uuid_gpt_loader1};" \ @@ -36,7 +42,7 @@ "name=loader2,size=4MB,uuid=${uuid_gpt_loader2};" \ "name=atf,size=4M,uuid=${uuid_gpt_atf};" \ "name=boot,size=112M,bootable,uuid=${uuid_gpt_boot};" \ - "name=rootfs,size=-,uuid=${uuid_gpt_rootfs};\0" \ + "name=rootfs,size=-,uuid="ROOT_UUID #endif diff --git a/include/configs/sama5d2_ptc.h b/include/configs/sama5d2_ptc.h index b25be97..401f198 100644 --- a/include/configs/sama5d2_ptc.h +++ b/include/configs/sama5d2_ptc.h @@ -65,10 +65,6 @@ /* USB */ #define CONFIG_CMD_USB -#ifdef CONFIG_CMD_USB -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 -#endif - /* USB device */ #define CONFIG_USB_GADGET #define CONFIG_USB_GADGET_DUALSPEED diff --git a/include/configs/snapper9g45.h b/include/configs/snapper9g45.h index 2c5f264..47dd991 100644 --- a/include/configs/snapper9g45.h +++ b/include/configs/snapper9g45.h @@ -60,9 +60,6 @@ #define CONFIG_TFTP_PORT #define CONFIG_TFTP_TSIZE -/* USB */ -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 2 - /* MMC */ #define CONFIG_GENERIC_ATMEL_MCI diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index fefd58f..681c91c 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -310,7 +310,6 @@ extern int soft_i2c_gpio_scl; #define CONFIG_USB_OHCI_NEW #define CONFIG_USB_OHCI_SUNXI #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 #endif #ifdef CONFIG_USB_MUSB_SUNXI diff --git a/include/configs/tam3517-common.h b/include/configs/tam3517-common.h index a9991fc..fb173eb 100644 --- a/include/configs/tam3517-common.h +++ b/include/configs/tam3517-common.h @@ -67,7 +67,6 @@ 115200} /* EHCI */ #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 25 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 /* commands to include */ #define CONFIG_CMD_NAND /* NAND support */ diff --git a/include/configs/tao3530.h b/include/configs/tao3530.h index 38f5bd0..08134f4 100644 --- a/include/configs/tao3530.h +++ b/include/configs/tao3530.h @@ -228,7 +228,6 @@ /* USB EHCI */ #define CONFIG_OMAP_EHCI_PHY1_RESET_GPIO 162 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_SMSC95XX diff --git a/include/configs/tegra114-common.h b/include/configs/tegra114-common.h index 107a0f8..75d2065 100644 --- a/include/configs/tegra114-common.h +++ b/include/configs/tegra114-common.h @@ -63,6 +63,5 @@ /* For USB EHCI controller */ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 #endif /* _TEGRA114_COMMON_H_ */ diff --git a/include/configs/tegra124-common.h b/include/configs/tegra124-common.h index 8cf9bac..0d61753 100644 --- a/include/configs/tegra124-common.h +++ b/include/configs/tegra124-common.h @@ -65,7 +65,6 @@ /* For USB EHCI controller */ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 /* GPU needs setup */ #define CONFIG_TEGRA_GPU diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h index db1cc24..342ffbe 100644 --- a/include/configs/tegra20-common.h +++ b/include/configs/tegra20-common.h @@ -82,7 +82,6 @@ */ #define CONFIG_USB_EHCI_TXFIFO_THRESH 10 #define CONFIG_EHCI_IS_TDI -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 #define CONFIG_SYS_NAND_SELF_INIT #define CONFIG_SYS_NAND_ONFI_DETECTION diff --git a/include/configs/tegra210-common.h b/include/configs/tegra210-common.h index 874fe34d..4c05576 100644 --- a/include/configs/tegra210-common.h +++ b/include/configs/tegra210-common.h @@ -68,7 +68,6 @@ /* For USB EHCI controller */ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 /* GPU needs setup */ #define CONFIG_TEGRA_GPU diff --git a/include/configs/tegra30-common.h b/include/configs/tegra30-common.h index 6083847..c2096fb 100644 --- a/include/configs/tegra30-common.h +++ b/include/configs/tegra30-common.h @@ -64,6 +64,5 @@ /* For USB EHCI controller */ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1 #endif /* _TEGRA30_COMMON_H_ */ diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h index a94748c..ccd7cd7 100644 --- a/include/configs/ti_armv7_common.h +++ b/include/configs/ti_armv7_common.h @@ -53,7 +53,7 @@ #define DEFAULT_FIT_TI_ARGS \ "boot_fit=0\0" \ - "fit_loadaddr=0x88000000\0" \ + "fit_loadaddr=0x87000000\0" \ "fit_bootfile=fitImage\0" \ "update_to_fit=setenv loadaddr ${fit_loadaddr}; setenv bootfile ${fit_bootfile}\0" \ "loadfit=run args_mmc; bootm ${loadaddr}#${fdtfile};\0" \ diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h index 3fadef7..26290ef 100644 --- a/include/configs/ti_armv7_keystone2.h +++ b/include/configs/ti_armv7_keystone2.h @@ -193,7 +193,6 @@ /* USB Configuration */ #define CONFIG_USB_XHCI_KEYSTONE -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_USB_SS_BASE KS2_USB_SS_BASE #define CONFIG_USB_HOST_XHCI_BASE KS2_USB_HOST_XHCI_BASE #define CONFIG_DEV_USB_PHY_BASE KS2_DEV_USB_PHY_BASE @@ -249,7 +248,11 @@ "addr_secdb_key=0xc000000\0" \ "name_kern=zImage\0" \ "addr_mon=0x87000000\0" \ + "addr_non_sec_mon=0x0c087fc0\0" \ + "addr_load_sec_bm=0x0c08c000\0" \ "run_mon=mon_install ${addr_mon}\0" \ + "run_mon_hs=mon_install ${addr_non_sec_mon} " \ + "${addr_load_sec_bm}\0" \ "run_kern=bootz ${loadaddr} ${rd_spec} ${fdtaddr}\0" \ "init_net=run args_all args_net\0" \ "init_nfs=setenv autoload no; dhcp; run args_all args_net\0" \ @@ -263,7 +266,13 @@ "get_kern_ubi=ubifsload ${loadaddr} ${bootdir}/${name_kern}\0" \ "get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \ "get_mon_nfs=nfs ${addr_mon} ${nfs_root}/boot/${name_mon}\0" \ - "get_mon_ubi=ubifsload ${addr_mon} ${bootdir}/${name_mon}\0" \ + "get_mon_ubi=ubifsload ${addr_mon} ${bootdir}/${name_mon}\0" \ + "get_fit_net=dhcp ${fit_loadaddr} ${tftp_root}" \ + "/${fit_bootfile}\0" \ + "get_fit_nfs=nfs ${fit_loadaddr} ${nfs_root}/boot/${fit_bootfile}\0"\ + "get_fit_ubi=ubifsload ${fit_loadaddr} ${bootdir}/${fit_bootfile}\0"\ + "get_fit_mmc=load mmc ${bootpart} ${fit_loadaddr} " \ + "${bootdir}/${fit_bootfile}\0" \ "get_uboot_net=dhcp ${loadaddr} ${tftp_root}/${name_uboot}\0" \ "get_uboot_nfs=nfs ${loadaddr} ${nfs_root}/boot/${name_uboot}\0" \ "burn_uboot_spi=sf probe; sf erase 0 0x80000; " \ @@ -279,6 +288,8 @@ "get_fdt_ramfs=dhcp ${fdtaddr} ${tftp_root}/${name_fdt}\0" \ "get_kern_ramfs=dhcp ${loadaddr} ${tftp_root}/${name_kern}\0" \ "get_mon_ramfs=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \ + "get_fit_ramfs=dhcp ${fit_loadaddr} ${tftp_root}" \ + "/${fit_bootfile}\0" \ "get_fs_ramfs=dhcp ${rdaddr} ${tftp_root}/${name_fs}\0" \ "get_ubi_net=dhcp ${addr_ubi} ${tftp_root}/${name_ubi}\0" \ "get_ubi_nfs=nfs ${addr_ubi} ${nfs_root}/boot/${name_ubi}\0" \ @@ -293,9 +304,21 @@ "1024k(bootloader)ro,512k(params)ro,-(ubifs)\0" #ifndef CONFIG_BOOTCOMMAND +#ifndef CONFIG_TI_SECURE_DEVICE #define CONFIG_BOOTCOMMAND \ - "run init_${boot} get_mon_${boot} run_mon init_fw_rd_${boot} " \ - "get_fdt_${boot} get_kern_${boot} run_kern" + "run init_${boot}; " \ + "run get_mon_${boot} run_mon; " \ + "run get_kern_${boot}; " \ + "run init_fw_rd_${boot}; " \ + "run get_fdt_${boot}; " \ + "run run_kern" +#else +#define CONFIG_BOOTCOMMAND \ + "run run_mon_hs; " \ + "run init_${boot}; " \ + "run get_fit_${boot}; " \ + "bootm ${fit_loadaddr}#${name_fdt}" +#endif #endif #define CONFIG_BOOTARGS \ diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index b8afa81..6f53139 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -77,17 +77,7 @@ #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 1 -#ifdef CONFIG_ARMV8_MULTIENTRY -#define CPU_RELEASE_ADDR 0x80000000 -#define COUNTER_FREQUENCY 50000000 -#define CONFIG_GICV3 -#define GICD_BASE 0x5fe00000 -#if defined(CONFIG_ARCH_UNIPHIER_LD11) -#define GICR_BASE 0x5fe40000 -#elif defined(CONFIG_ARCH_UNIPHIER_LD20) -#define GICR_BASE 0x5fe80000 -#endif -#elif !defined(CONFIG_ARM64) +#if !defined(CONFIG_ARM64) /* Time clock 1MHz */ #define CONFIG_SYS_TIMER_RATE 1000000 #endif @@ -111,9 +101,6 @@ #define CONFIG_SYS_NAND_USE_FLASH_BBT #define CONFIG_SYS_NAND_BAD_BLOCK_POS 0 -/* USB */ -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 4 - /* SD/MMC */ #define CONFIG_SUPPORT_EMMC_BOOT @@ -134,7 +121,7 @@ #define CONFIG_CMDLINE_EDITING /* add command line history */ -#if defined(CONFIG_ARM64) && !defined(CONFIG_ARMV8_MULTIENTRY) +#if defined(CONFIG_ARM64) /* ARM Trusted Firmware */ #define BOOT_IMAGES \ "second_image=unph_bl.bin\0" \ @@ -262,9 +249,7 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE) /* only for SPL */ -#if defined(CONFIG_ARM64) -#define CONFIG_SPL_TEXT_BASE 0x30000000 -#elif defined(CONFIG_ARCH_UNIPHIER_SLD3) || \ +#if defined(CONFIG_ARCH_UNIPHIER_SLD3) || \ defined(CONFIG_ARCH_UNIPHIER_LD4) || \ defined(CONFIG_ARCH_UNIPHIER_SLD8) #define CONFIG_SPL_TEXT_BASE 0x00040000 @@ -272,18 +257,9 @@ #define CONFIG_SPL_TEXT_BASE 0x00100000 #endif -#if defined(CONFIG_ARCH_UNIPHIER_LD11) -#define CONFIG_SPL_STACK (0x30014c00) -#elif defined(CONFIG_ARCH_UNIPHIER_LD20) -#define CONFIG_SPL_STACK (0x3001c000) -#else #define CONFIG_SPL_STACK (0x00100000) -#endif #define CONFIG_SPL_FRAMEWORK -#ifdef CONFIG_ARM64 -#define CONFIG_SPL_BOARD_LOAD_IMAGE -#endif #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x20000 @@ -292,16 +268,7 @@ #define CONFIG_SPL_TARGET "u-boot-with-spl.bin" #define CONFIG_SPL_MAX_FOOTPRINT 0x10000 -#if defined(CONFIG_ARCH_UNIPHIER_LD20) -#define CONFIG_SPL_MAX_SIZE 0x14000 -#else #define CONFIG_SPL_MAX_SIZE 0x10000 -#endif -#if defined(CONFIG_ARCH_UNIPHIER_LD11) -#define CONFIG_SPL_BSS_START_ADDR 0x30012000 -#elif defined(CONFIG_ARCH_UNIPHIER_LD20) -#define CONFIG_SPL_BSS_START_ADDR 0x30016000 -#endif #define CONFIG_SPL_BSS_MAX_SIZE 0x2000 #define CONFIG_SPL_PAD_TO 0x20000 diff --git a/include/configs/vinco.h b/include/configs/vinco.h index dc35b28..adff1b6 100644 --- a/include/configs/vinco.h +++ b/include/configs/vinco.h @@ -63,12 +63,6 @@ #endif -/* USB */ - -#ifdef CONFIG_CMD_USB -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3 -#endif - /* USB device */ #define CONFIG_USB_ETHER #define CONFIG_USB_ETH_RNDIS diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 1be6974..aa1e505 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -128,7 +128,6 @@ * USB configuration */ #define CONFIG_USB_EHCI_PCI -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 12 #define CONFIG_SYS_USB_EVENT_POLL #define CONFIG_USB_HOST_ETHER diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index c30e37c..7c5ec19 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -90,8 +90,6 @@ #define CONFIG_SYS_LOAD_ADDR 0x8000000 #if defined(CONFIG_ZYNQMP_USB) -#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 - #define CONFIG_SYS_DFU_DATA_BUF_SIZE 0x1800000 #define DFU_DEFAULT_POLL_TIMEOUT 300 #define CONFIG_USB_CABLE_CHECK diff --git a/include/dfu.h b/include/dfu.h index f39d3f1..7e322d9 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -110,7 +110,7 @@ struct dfu_entity { struct sf_internal_data sf; } data; - long (*get_medium_size)(struct dfu_entity *dfu); + int (*get_medium_size)(struct dfu_entity *dfu, u64 *size); int (*read_medium)(struct dfu_entity *dfu, u64 offset, void *buf, long *len); @@ -132,7 +132,7 @@ struct dfu_entity { u8 *i_buf; u8 *i_buf_start; u8 *i_buf_end; - long r_left; + u64 r_left; long b_left; u32 bad_skip; /* for nand use */ diff --git a/include/dm/of_access.h b/include/dm/of_access.h index c5ea391..c49d287 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -353,6 +353,24 @@ int of_parse_phandle_with_args(const struct device_node *np, int index, struct of_phandle_args *out_args); /** + * of_count_phandle_with_args() - Count the number of phandle in a list + * + * @np: pointer to a device tree node containing a list + * @list_name: property name that contains a list + * @cells_name: property name that specifies phandles' arguments count + * @return number of phandle found, -ENOENT if + * @list_name does not exist, -EINVAL if a phandle was not found, + * @cells_name could not be found, the arguments were truncated or there + * were too many arguments. + * + * Returns number of phandle found on success, on error returns appropriate + * errno value. + * + */ +int of_count_phandle_with_args(const struct device_node *np, + const char *list_name, const char *cells_name); + +/** * of_alias_scan() - Scan all properties of the 'aliases' node * * The function scans all the properties of the 'aliases' node and populates diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 15ad519..210ddb2 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -15,6 +15,8 @@ /* Enable checks to protect against invalid calls */ #undef OF_CHECKS +struct resource; + /** * ofnode - reference to a device tree node * @@ -433,6 +435,23 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, struct ofnode_phandle_args *out_args); /** + * ofnode_count_phandle_with_args() - Count number of phandle in a list + * + * This function is useful to count phandles into a list. + * Returns number of phandle on success, on error returns appropriate + * errno value. + * + * @node: device tree node containing a list + * @list_name: property name that contains a list + * @cells_name: property name that specifies phandles' arguments count + * @return number of phandle on success, -ENOENT if @list_name does not + * exist, -EINVAL if a phandle was not found, @cells_name could not + * be found. + */ +int ofnode_count_phandle_with_args(ofnode node, const char *list_name, + const char *cells_name); + +/** * ofnode_path() - find a node by full path * * @path: Full path to node, e.g. "/bus/spi@1" @@ -605,4 +624,6 @@ int ofnode_read_simple_size_cells(ofnode node); */ bool ofnode_pre_reloc(ofnode node); +int ofnode_read_resource(ofnode node, uint index, struct resource *res); + #endif diff --git a/include/dm/platform_data/serial_stm32x7.h b/include/dm/platform_data/serial_stm32x7.h deleted file mode 100644 index 328a8a3..0000000 --- a/include/dm/platform_data/serial_stm32x7.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * (C) Copyright 2016 - * Vikas Manocha, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __SERIAL_STM32x7_H -#define __SERIAL_STM32x7_H - -/* Information about a serial port */ -struct stm32x7_serial_platdata { - struct stm32_usart *base; /* address of registers in physical memory */ - unsigned int clock; -}; - -#endif /* __SERIAL_STM32x7_H */ diff --git a/include/dm/read.h b/include/dm/read.h index b86a2f5..c3a4a56 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -44,16 +44,6 @@ static inline bool dev_of_valid(struct udevice *dev) return ofnode_valid(dev_ofnode(dev)); } -/** - * dev_read_resource() - obtain an indexed resource from a device. - * - * @dev: devuce to examine - * @index index of the resource to retrieve (0 = first) - * @res returns the resource - * @return 0 if ok, negative on error - */ -int dev_read_resource(struct udevice *dev, uint index, struct resource *res); - #ifndef CONFIG_DM_DEV_READ_INLINE /** * dev_read_u32_default() - read a 32-bit integer from a device's DT property @@ -209,6 +199,24 @@ int dev_read_phandle_with_args(struct udevice *dev, const char *list_name, struct ofnode_phandle_args *out_args); /** + * dev_count_phandle_with_args() - Return phandle number in a list + * + * This function is usefull to get phandle number contained in a property list. + * For example, this allows to allocate the right amount of memory to keep + * clock's reference contained into the "clocks" property. + * + * + * @dev: device whose node containing a list + * @list_name: property name that contains a list + * @cells_name: property name that specifies phandles' arguments count + * @Returns number of phandle found on success, on error returns appropriate + * errno value. + */ + +int dev_count_phandle_with_args(struct udevice *dev, const char *list_name, + const char *cells_name); + +/** * dev_read_addr_cells() - Get the number of address cells for a device's node * * This walks back up the tree to find the closest #address-cells property @@ -266,7 +274,7 @@ int dev_read_phandle(struct udevice *dev); * @lenp: place to put length on success * @return pointer to property, or NULL if not found */ -const u32 *dev_read_prop(struct udevice *dev, const char *propname, int *lenp); +const void *dev_read_prop(struct udevice *dev, const char *propname, int *lenp); /** * dev_read_alias_seq() - Get the alias sequence number of a node @@ -348,6 +356,16 @@ const uint8_t *dev_read_u8_array_ptr(struct udevice *dev, const char *propname, */ int dev_read_enabled(struct udevice *dev); +/** + * dev_read_resource() - obtain an indexed resource from a device. + * + * @dev: devuce to examine + * @index index of the resource to retrieve (0 = first) + * @res returns the resource + * @return 0 if ok, negative on error + */ +int dev_read_resource(struct udevice *dev, uint index, struct resource *res); + #else /* CONFIG_DM_DEV_READ_INLINE is enabled */ static inline int dev_read_u32_default(struct udevice *dev, @@ -416,6 +434,13 @@ static inline int dev_read_phandle_with_args(struct udevice *dev, out_args); } +static inline int dev_count_phandle_with_args(struct udevice *dev, + const char *list_name, const char *cells_name) +{ + return ofnode_count_phandle_with_args(dev_ofnode(dev), list_name, + cells_name); +} + static inline int dev_read_addr_cells(struct udevice *dev) { /* NOTE: this call should walk up the parent stack */ @@ -443,8 +468,8 @@ static inline int dev_read_phandle(struct udevice *dev) return fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev)); } -static inline const u32 *dev_read_prop(struct udevice *dev, - const char *propname, int *lenp) +static inline const void *dev_read_prop(struct udevice *dev, + const char *propname, int *lenp) { return ofnode_get_property(dev_ofnode(dev), propname, lenp); } @@ -482,6 +507,12 @@ static inline int dev_read_enabled(struct udevice *dev) return fdtdec_get_is_enabled(gd->fdt_blob, dev_of_offset(dev)); } +static inline int dev_read_resource(struct udevice *dev, uint index, + struct resource *res) +{ + return ofnode_read_resource(dev_ofnode(dev), index, res); +} + #endif /* CONFIG_DM_DEV_READ_INLINE */ /** diff --git a/include/dt-bindings/clock/gxbb-clkc.h b/include/dt-bindings/clock/gxbb-clkc.h index 692846c..e3e9f79 100644 --- a/include/dt-bindings/clock/gxbb-clkc.h +++ b/include/dt-bindings/clock/gxbb-clkc.h @@ -5,30 +5,50 @@ #ifndef __GXBB_CLKC_H #define __GXBB_CLKC_H -#define CLKID_CPUCLK 1 #define CLKID_HDMI_PLL 2 #define CLKID_FCLK_DIV2 4 #define CLKID_FCLK_DIV3 5 #define CLKID_FCLK_DIV4 6 +#define CLKID_GP0_PLL 9 #define CLKID_CLK81 12 #define CLKID_MPLL2 15 -#define CLKID_SPI 34 +#define CLKID_SPICC 21 #define CLKID_I2C 22 #define CLKID_SAR_ADC 23 +#define CLKID_RNG0 25 +#define CLKID_UART0 26 +#define CLKID_SPI 34 #define CLKID_ETH 36 +#define CLKID_AIU_GLUE 38 +#define CLKID_IEC958 39 +#define CLKID_I2S_OUT 40 +#define CLKID_MIXER_IFACE 44 +#define CLKID_AIU 47 +#define CLKID_UART1 48 #define CLKID_USB0 50 #define CLKID_USB1 51 #define CLKID_USB 55 #define CLKID_HDMI_PCLK 63 #define CLKID_USB1_DDR_BRIDGE 64 #define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_UART2 68 #define CLKID_SANA 69 #define CLKID_GCLK_VENCI_INT0 77 +#define CLKID_AOCLK_GATE 80 +#define CLKID_IEC958_GATE 81 #define CLKID_AO_I2C 93 #define CLKID_SD_EMMC_A 94 #define CLKID_SD_EMMC_B 95 #define CLKID_SD_EMMC_C 96 #define CLKID_SAR_ADC_CLK 97 #define CLKID_SAR_ADC_SEL 98 +#define CLKID_MALI_0_SEL 100 +#define CLKID_MALI_0 102 +#define CLKID_MALI_1_SEL 103 +#define CLKID_MALI_1 105 +#define CLKID_MALI 106 +#define CLKID_CTS_AMCLK 107 +#define CLKID_CTS_MCLK_I958 110 +#define CLKID_CTS_I958 113 #endif /* __GXBB_CLKC_H */ diff --git a/include/dt-bindings/clock/stm32fx-clock.h b/include/dt-bindings/clock/stm32fx-clock.h new file mode 100644 index 0000000..49bb3c2 --- /dev/null +++ b/include/dt-bindings/clock/stm32fx-clock.h @@ -0,0 +1,59 @@ +/* + * stm32fx-clock.h + * + * Copyright (C) 2016 STMicroelectronics + * Author: Gabriel Fernandez for STMicroelectronics. + * License terms: GNU General Public License (GPL), version 2 + */ + +/* + * List of clocks wich are not derived from system clock (SYSCLOCK) + * + * The index of these clocks is the secondary index of DT bindings + * (see Documentatoin/devicetree/bindings/clock/st,stm32-rcc.txt) + * + * e.g: + ; +*/ + +#ifndef _DT_BINDINGS_CLK_STMFX_H +#define _DT_BINDINGS_CLK_STMFX_H + +#define SYSTICK 0 +#define FCLK 1 +#define CLK_LSI 2 +#define CLK_LSE 3 +#define CLK_HSE_RTC 4 +#define CLK_RTC 5 +#define PLL_VCO_I2S 6 +#define PLL_VCO_SAI 7 +#define CLK_LCD 8 +#define CLK_I2S 9 +#define CLK_SAI1 10 +#define CLK_SAI2 11 +#define CLK_I2SQ_PDIV 12 +#define CLK_SAIQ_PDIV 13 + +#define END_PRIMARY_CLK 14 + +#define CLK_HSI 14 +#define CLK_SYSCLK 15 +#define CLK_HDMI_CEC 16 +#define CLK_SPDIF 17 +#define CLK_USART1 18 +#define CLK_USART2 19 +#define CLK_USART3 20 +#define CLK_UART4 21 +#define CLK_UART5 22 +#define CLK_USART6 23 +#define CLK_UART7 24 +#define CLK_UART8 25 +#define CLK_I2C1 26 +#define CLK_I2C2 27 +#define CLK_I2C3 28 +#define CLK_I2C4 29 +#define CLK_LPTIMER 30 + +#define END_PRIMARY_CLK_F7 31 + +#endif diff --git a/include/dt-bindings/mfd/stm32f7-rcc.h b/include/dt-bindings/mfd/stm32f7-rcc.h new file mode 100644 index 0000000..e36cc69 --- /dev/null +++ b/include/dt-bindings/mfd/stm32f7-rcc.h @@ -0,0 +1,112 @@ +/* + * This header provides constants for the STM32F7 RCC IP + */ + +#ifndef _DT_BINDINGS_MFD_STM32F7_RCC_H +#define _DT_BINDINGS_MFD_STM32F7_RCC_H + +/* AHB1 */ +#define STM32F7_RCC_AHB1_GPIOA 0 +#define STM32F7_RCC_AHB1_GPIOB 1 +#define STM32F7_RCC_AHB1_GPIOC 2 +#define STM32F7_RCC_AHB1_GPIOD 3 +#define STM32F7_RCC_AHB1_GPIOE 4 +#define STM32F7_RCC_AHB1_GPIOF 5 +#define STM32F7_RCC_AHB1_GPIOG 6 +#define STM32F7_RCC_AHB1_GPIOH 7 +#define STM32F7_RCC_AHB1_GPIOI 8 +#define STM32F7_RCC_AHB1_GPIOJ 9 +#define STM32F7_RCC_AHB1_GPIOK 10 +#define STM32F7_RCC_AHB1_CRC 12 +#define STM32F7_RCC_AHB1_BKPSRAM 18 +#define STM32F7_RCC_AHB1_DTCMRAM 20 +#define STM32F7_RCC_AHB1_DMA1 21 +#define STM32F7_RCC_AHB1_DMA2 22 +#define STM32F7_RCC_AHB1_DMA2D 23 +#define STM32F7_RCC_AHB1_ETHMAC 25 +#define STM32F7_RCC_AHB1_ETHMACTX 26 +#define STM32F7_RCC_AHB1_ETHMACRX 27 +#define STM32FF_RCC_AHB1_ETHMACPTP 28 +#define STM32F7_RCC_AHB1_OTGHS 29 +#define STM32F7_RCC_AHB1_OTGHSULPI 30 + +#define STM32F7_AHB1_RESET(bit) (STM32F7_RCC_AHB1_##bit + (0x10 * 8)) +#define STM32F7_AHB1_CLOCK(bit) (STM32F7_RCC_AHB1_##bit) + + +/* AHB2 */ +#define STM32F7_RCC_AHB2_DCMI 0 +#define STM32F7_RCC_AHB2_CRYP 4 +#define STM32F7_RCC_AHB2_HASH 5 +#define STM32F7_RCC_AHB2_RNG 6 +#define STM32F7_RCC_AHB2_OTGFS 7 + +#define STM32F7_AHB2_RESET(bit) (STM32F7_RCC_AHB2_##bit + (0x14 * 8)) +#define STM32F7_AHB2_CLOCK(bit) (STM32F7_RCC_AHB2_##bit + 0x20) + +/* AHB3 */ +#define STM32F7_RCC_AHB3_FMC 0 +#define STM32F7_RCC_AHB3_QSPI 1 + +#define STM32F7_AHB3_RESET(bit) (STM32F7_RCC_AHB3_##bit + (0x18 * 8)) +#define STM32F7_AHB3_CLOCK(bit) (STM32F7_RCC_AHB3_##bit + 0x40) + +/* APB1 */ +#define STM32F7_RCC_APB1_TIM2 0 +#define STM32F7_RCC_APB1_TIM3 1 +#define STM32F7_RCC_APB1_TIM4 2 +#define STM32F7_RCC_APB1_TIM5 3 +#define STM32F7_RCC_APB1_TIM6 4 +#define STM32F7_RCC_APB1_TIM7 5 +#define STM32F7_RCC_APB1_TIM12 6 +#define STM32F7_RCC_APB1_TIM13 7 +#define STM32F7_RCC_APB1_TIM14 8 +#define STM32F7_RCC_APB1_LPTIM1 9 +#define STM32F7_RCC_APB1_WWDG 11 +#define STM32F7_RCC_APB1_SPI2 14 +#define STM32F7_RCC_APB1_SPI3 15 +#define STM32F7_RCC_APB1_SPDIFRX 16 +#define STM32F7_RCC_APB1_UART2 17 +#define STM32F7_RCC_APB1_UART3 18 +#define STM32F7_RCC_APB1_UART4 19 +#define STM32F7_RCC_APB1_UART5 20 +#define STM32F7_RCC_APB1_I2C1 21 +#define STM32F7_RCC_APB1_I2C2 22 +#define STM32F7_RCC_APB1_I2C3 23 +#define STM32F7_RCC_APB1_I2C4 24 +#define STM32F7_RCC_APB1_CAN1 25 +#define STM32F7_RCC_APB1_CAN2 26 +#define STM32F7_RCC_APB1_CEC 27 +#define STM32F7_RCC_APB1_PWR 28 +#define STM32F7_RCC_APB1_DAC 29 +#define STM32F7_RCC_APB1_UART7 30 +#define STM32F7_RCC_APB1_UART8 31 + +#define STM32F7_APB1_RESET(bit) (STM32F7_RCC_APB1_##bit + (0x20 * 8)) +#define STM32F7_APB1_CLOCK(bit) (STM32F7_RCC_APB1_##bit + 0x80) + +/* APB2 */ +#define STM32F7_RCC_APB2_TIM1 0 +#define STM32F7_RCC_APB2_TIM8 1 +#define STM32F7_RCC_APB2_USART1 4 +#define STM32F7_RCC_APB2_USART6 5 +#define STM32F7_RCC_APB2_ADC1 8 +#define STM32F7_RCC_APB2_ADC2 9 +#define STM32F7_RCC_APB2_ADC3 10 +#define STM32F7_RCC_APB2_SDMMC1 11 +#define STM32F7_RCC_APB2_SPI1 12 +#define STM32F7_RCC_APB2_SPI4 13 +#define STM32F7_RCC_APB2_SYSCFG 14 +#define STM32F7_RCC_APB2_TIM9 16 +#define STM32F7_RCC_APB2_TIM10 17 +#define STM32F7_RCC_APB2_TIM11 18 +#define STM32F7_RCC_APB2_SPI5 20 +#define STM32F7_RCC_APB2_SPI6 21 +#define STM32F7_RCC_APB2_SAI1 22 +#define STM32F7_RCC_APB2_SAI2 23 +#define STM32F7_RCC_APB2_LTDC 26 + +#define STM32F7_APB2_RESET(bit) (STM32F7_RCC_APB2_##bit + (0x24 * 8)) +#define STM32F7_APB2_CLOCK(bit) (STM32F7_RCC_APB2_##bit + 0xA0) + +#endif /* _DT_BINDINGS_MFD_STM32F7_RCC_H */ diff --git a/include/dt-structs.h b/include/dt-structs.h index e13afa6..0732c44 100644 --- a/include/dt-structs.h +++ b/include/dt-structs.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef __DT_STTUCTS -#define __DT_STTUCTS +#ifndef __DT_STRUCTS +#define __DT_STRUCTS /* These structures may only be used in SPL */ #if CONFIG_IS_ENABLED(OF_PLATDATA) diff --git a/include/fdtdec.h b/include/fdtdec.h index eda2ffa..4a0947c 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -119,12 +119,6 @@ enum fdt_compat_id { COMPAT_NVIDIA_TEGRA20_EMC, /* Tegra20 memory controller */ COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra20 memory timing table */ COMPAT_NVIDIA_TEGRA20_NAND, /* Tegra2 NAND controller */ - COMPAT_NVIDIA_TEGRA124_PMC, /* Tegra 124 power mgmt controller */ - COMPAT_NVIDIA_TEGRA186_SDMMC, /* Tegra186 SDMMC controller */ - COMPAT_NVIDIA_TEGRA210_SDMMC, /* Tegra210 SDMMC controller */ - COMPAT_NVIDIA_TEGRA124_SDMMC, /* Tegra124 SDMMC controller */ - COMPAT_NVIDIA_TEGRA30_SDMMC, /* Tegra30 SDMMC controller */ - COMPAT_NVIDIA_TEGRA20_SDMMC, /* Tegra20 SDMMC controller */ COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, /* Tegra124 XUSB pad controller */ COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL, diff --git a/include/generic-phy.h b/include/generic-phy.h index 762704c..eac5adc 100644 --- a/include/generic-phy.h +++ b/include/generic-phy.h @@ -122,6 +122,7 @@ struct phy_ops { int (*power_off)(struct phy *phy); }; +#ifdef CONFIG_PHY /** * generic_phy_init() - initialize the PHY port @@ -220,4 +221,56 @@ int generic_phy_get_by_index(struct udevice *user, int index, int generic_phy_get_by_name(struct udevice *user, const char *phy_name, struct phy *phy); +#else /* CONFIG_PHY */ + +static inline int generic_phy_init(struct phy *phy) +{ + return 0; +} + +static inline int generic_phy_exit(struct phy *phy) +{ + return 0; +} + +static inline int generic_phy_reset(struct phy *phy) +{ + return 0; +} + +static inline int generic_phy_power_on(struct phy *phy) +{ + return 0; +} + +static inline int generic_phy_power_off(struct phy *phy) +{ + return 0; +} + +static inline int generic_phy_get_by_index(struct udevice *user, int index, + struct phy *phy) +{ + return 0; +} + +static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_name, + struct phy *phy) +{ + return 0; +} + +#endif /* CONFIG_PHY */ + +/** + * generic_phy_valid() - check if PHY port is valid + * + * @phy: the PHY port to check + * @return TRUE if valid, or FALSE + */ +static inline bool generic_phy_valid(struct phy *phy) +{ + return phy->dev != NULL; +} + #endif /*__GENERIC_PHY_H */ diff --git a/include/os.h b/include/os.h index 049b248..2bf4bdb 100644 --- a/include/os.h +++ b/include/os.h @@ -241,26 +241,6 @@ const char *os_dirent_get_typename(enum os_dirent_t type); int os_get_filesize(const char *fname, loff_t *size); /** - * Write a character to the controlling OS terminal - * - * This bypasses the U-Boot console support and writes directly to the OS - * stdout file descriptor. - * - * @param ch Character to write - */ -void os_putc(int ch); - -/** - * Write a string to the controlling OS terminal - * - * This bypasses the U-Boot console support and writes directly to the OS - * stdout file descriptor. - * - * @param str String to write (note that \n is not appended) - */ -void os_puts(const char *str); - -/** * Write the sandbox RAM buffer to a existing file * * @param fname Filename to write memory to (simple binary format) diff --git a/include/power/as3722.h b/include/power/as3722.h index 0f22482..cb4b188 100644 --- a/include/power/as3722.h +++ b/include/power/as3722.h @@ -7,24 +7,23 @@ #ifndef __POWER_AS3722_H__ #define __POWER_AS3722_H__ -#include - #define AS3722_GPIO_OUTPUT_VDDH (1 << 0) #define AS3722_GPIO_INVERT (1 << 1) -struct udevice; +#define AS3722_DEVICE_ID 0x0c +#define AS3722_SD_VOLTAGE(n) (0x00 + (n)) +#define AS3722_LDO_VOLTAGE(n) (0x10 + (n)) +#define AS3722_SD_CONTROL 0x4d +#define AS3722_LDO_CONTROL 0x4e +#define AS3722_ASIC_ID1 0x90 +#define AS3722_ASIC_ID2 0x91 + +#define AS3722_GPIO_CONTROL(n) (0x08 + (n)) +#define AS3722_GPIO_SIGNAL_OUT 0x20 +#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0) +#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0) +#define AS3722_GPIO_CONTROL_INVERT (1 << 7) -int as3722_init(struct udevice **devp); -int as3722_sd_enable(struct udevice *pmic, unsigned int sd); -int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value); -int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo); -int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value); -int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, - unsigned long flags); -int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio, - unsigned int level); -int as3722_read(struct udevice *pmic, u8 reg, u8 *value); -int as3722_write(struct udevice *pmic, u8 reg, u8 value); -int as3722_get(struct udevice **devp); +int as3722_sd_set_voltage(struct udevice *dev, unsigned int sd, u8 value); #endif /* __POWER_AS3722_H__ */ diff --git a/include/reset.h b/include/reset.h index f45fcf8..7185ade 100644 --- a/include/reset.h +++ b/include/reset.h @@ -100,6 +100,15 @@ int reset_get_by_name(struct udevice *dev, const char *name, struct reset_ctl *reset_ctl); /** + * reset_request - Request a reset signal. + * + * @reset_ctl: A reset control struct. + * + * @return 0 if OK, or a negative error code. + */ +int reset_request(struct reset_ctl *reset_ctl); + +/** * reset_free - Free a previously requested reset signal. * * @reset_ctl: A reset control struct that was previously successfully @@ -135,6 +144,18 @@ int reset_assert(struct reset_ctl *reset_ctl); */ int reset_deassert(struct reset_ctl *reset_ctl); +/** + * reset_release_all - Assert/Free an array of previously requested resets. + * + * For each reset contained in the reset array, this function will check if + * reset has been previously requested and then will assert and free it. + * + * @reset_ctl: A reset struct array that was previously successfully + * requested by reset_get_by_*(). + * @count Number of reset contained in the array + * @return 0 if OK, or a negative error code. + */ +int reset_release_all(struct reset_ctl *reset_ctl, int count); #else static inline int reset_get_by_index(struct udevice *dev, int index, struct reset_ctl *reset_ctl) @@ -162,6 +183,12 @@ static inline int reset_deassert(struct reset_ctl *reset_ctl) { return 0; } + +static inline int reset_release_all(struct reset_ctl *reset_ctl, int count) +{ + return 0; +} + #endif #endif diff --git a/include/usb.h b/include/usb.h index 62f051f..fad0401 100644 --- a/include/usb.h +++ b/include/usb.h @@ -537,6 +537,21 @@ struct usb_hub_status { unsigned short wHubChange; } __attribute__ ((packed)); +/* + * Hub Device descriptor + * USB Hub class device protocols + */ +#define USB_HUB_PR_FS 0 /* Full speed hub */ +#define USB_HUB_PR_HS_NO_TT 0 /* Hi-speed hub without TT */ +#define USB_HUB_PR_HS_SINGLE_TT 1 /* Hi-speed hub with single TT */ +#define USB_HUB_PR_HS_MULTI_TT 2 /* Hi-speed hub with multiple TT */ +#define USB_HUB_PR_SS 3 /* Super speed hub */ + +/* Transaction Translator Think Times, in bits */ +#define HUB_TTTT_8_BITS 0x00 +#define HUB_TTTT_16_BITS 0x20 +#define HUB_TTTT_24_BITS 0x40 +#define HUB_TTTT_32_BITS 0x60 /* Hub descriptor */ struct usb_hub_descriptor { @@ -546,10 +561,20 @@ struct usb_hub_descriptor { unsigned short wHubCharacteristics; unsigned char bPwrOn2PwrGood; unsigned char bHubContrCurrent; - unsigned char DeviceRemovable[(USB_MAXCHILDREN+1+7)/8]; - unsigned char PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8]; - /* DeviceRemovable and PortPwrCtrlMask want to be variable-length - bitmaps that hold max 255 entries. (bit0 is ignored) */ + /* 2.0 and 3.0 hubs differ here */ + union { + struct { + /* add 1 bit for hub status change; round to bytes */ + __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8]; + __u8 PortPowerCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8]; + } __attribute__ ((packed)) hs; + + struct { + __u8 bHubHdrDecLat; + __le16 wHubDelay; + __le16 DeviceRemovable; + } __attribute__ ((packed)) ss; + } u; } __attribute__ ((packed)); @@ -560,6 +585,8 @@ struct usb_hub_device { ulong connect_timeout; /* Device connection timeout in ms */ ulong query_delay; /* Device query delay in ms */ int overcurrent_count[USB_MAXCHILDREN]; /* Over-current counter */ + int hub_depth; /* USB 3.0 hub depth */ + struct usb_tt tt; /* Transaction Translator */ }; #ifdef CONFIG_DM_USB @@ -731,6 +758,14 @@ struct dm_usb_ops { * reset_root_port() - Reset usb root port */ int (*reset_root_port)(struct udevice *bus, struct usb_device *udev); + + /** + * update_hub_device() - Update HCD's internal representation of hub + * + * After a hub descriptor is fetched, notify HCD so that its internal + * representation of this hub can be updated (xHCI) + */ + int (*update_hub_device)(struct udevice *bus, struct usb_device *udev); }; #define usb_get_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops) @@ -766,6 +801,14 @@ int usb_setup_device(struct usb_device *dev, bool do_read, struct usb_device *parent); /** + * usb_hub_is_root_hub() - Test whether a hub device is root hub or not + * + * @hub: USB hub device to test + * @return: true if the hub device is root hub, false otherwise. + */ +bool usb_hub_is_root_hub(struct udevice *hub); + +/** * usb_hub_scan() - Scan a hub and find its devices * * @hub: Hub device to scan @@ -861,24 +904,6 @@ bool usb_device_has_child_on_port(struct usb_device *parent, int port); int usb_hub_probe(struct usb_device *dev, int ifnum); void usb_hub_reset(void); -/** - * legacy_hub_port_reset() - reset a port given its usb_device pointer - * - * Reset a hub port and see if a device is present on that port, providing - * sufficient time for it to show itself. The port status is returned. - * - * With driver model this moves to hub_port_reset() and is passed a struct - * udevice. - * - * @dev: USB device to reset - * @port: Port number to reset (note ports are numbered from 0 here) - * @portstat: Returns port status - */ -int legacy_hub_port_reset(struct usb_device *dev, int port, - unsigned short *portstat); - -int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat); - /* * usb_find_usb2_hub_address_port() - Get hub address and port for TT setting * @@ -914,6 +939,17 @@ int usb_new_device(struct usb_device *dev); int usb_alloc_device(struct usb_device *dev); /** + * update_hub_device() - Update HCD's internal representation of hub + * + * After a hub descriptor is fetched, notify HCD so that its internal + * representation of this hub can be updated. + * + * @dev: Hub device + * @return 0 if OK, -ve on error + */ +int usb_update_hub_device(struct usb_device *dev); + +/** * usb_emul_setup_device() - Set up a new USB device emulation * * This is normally called when a new emulation device is bound. It tells @@ -926,7 +962,7 @@ int usb_alloc_device(struct usb_device *dev); * @desc_list: List of points or USB descriptors, terminated by NULL. * The first entry must be struct usb_device_descriptor, * and others follow on after that. - * @return 0 if OK, -ve on error + * @return 0 if OK, -ENOSYS if not implemented, other -ve on error */ int usb_emul_setup_device(struct udevice *dev, int maxpacketsize, struct usb_string *strings, void **desc_list); diff --git a/include/usb_defs.h b/include/usb_defs.h index 8214ba9..b7f2ead 100644 --- a/include/usb_defs.h +++ b/include/usb_defs.h @@ -93,6 +93,7 @@ #define USB_DT_REPORT (USB_TYPE_CLASS | 0x02) #define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) #define USB_DT_HUB (USB_TYPE_CLASS | 0x09) +#define USB_DT_SS_HUB (USB_TYPE_CLASS | 0x0a) /* Descriptor sizes per descriptor type */ #define USB_DT_DEVICE_SIZE 18 @@ -261,12 +262,17 @@ /* * Changes to wPortStatus bit field in USB 3.0 - * See USB 3.0 spec Table 10-11 + * See USB 3.0 spec Table 10-10 */ #define USB_SS_PORT_STAT_LINK_STATE 0x01e0 #define USB_SS_PORT_STAT_POWER 0x0200 #define USB_SS_PORT_STAT_SPEED 0x1c00 #define USB_SS_PORT_STAT_SPEED_5GBPS 0x0000 +/* Bits that are the same from USB 2.0 */ +#define USB_SS_PORT_STAT_MASK (USB_PORT_STAT_CONNECTION | \ + USB_PORT_STAT_ENABLE | \ + USB_PORT_STAT_OVERCURRENT | \ + USB_PORT_STAT_RESET) /* wPortChange bits */ #define USB_PORT_STAT_C_CONNECTION 0x0001 @@ -287,6 +293,7 @@ #define HUB_CHAR_LPSM 0x0003 #define HUB_CHAR_COMPOUND 0x0004 #define HUB_CHAR_OCPM 0x0018 +#define HUB_CHAR_TTTT 0x0060 /* TT Think Time mask */ /* * Hub Status & Hub Change bit masks @@ -300,6 +307,20 @@ /* Mask for wIndex in get/set port feature */ #define USB_HUB_PORT_MASK 0xf +/* Hub class request codes */ +#define USB_REQ_SET_HUB_DEPTH 0x0c + +/* + * As of USB 2.0, full/low speed devices are segregated into trees. + * One type grows from USB 1.1 host controllers (OHCI, UHCI etc). + * The other type grows from high speed hubs when they connect to + * full/low speed devices using "Transaction Translators" (TTs). + */ +struct usb_tt { + bool multi; /* true means one TT per port */ + unsigned think_time; /* think time in ns */ +}; + /* * CBI style */ diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c index 221ebbf..b04f7c6 100644 --- a/lib/asm-offsets.c +++ b/lib/asm-offsets.c @@ -28,7 +28,7 @@ int main(void) DEFINE(GD_SIZE, sizeof(struct global_data)); DEFINE(GD_BD, offsetof(struct global_data, bd)); -#ifdef CONFIG_SYS_MALLOC_F_LEN +#if CONFIG_VAL(SYS_MALLOC_F_LEN) DEFINE(GD_MALLOC_BASE, offsetof(struct global_data, malloc_base)); #endif diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index 452ab5d..f1afd9c 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -48,7 +48,7 @@ static efi_status_t setup_memory(struct efi_priv *priv) return ret; memset(gd, '\0', sizeof(*gd)); - gd->malloc_base = (ulong)efi_malloc(priv, CONFIG_SYS_MALLOC_F_LEN, + gd->malloc_base = (ulong)efi_malloc(priv, CONFIG_VAL(SYS_MALLOC_F_LEN), &ret); if (!gd->malloc_base) return ret; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index fbb48bf..d2dbd0f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -34,12 +34,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"), COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"), COMPAT(NVIDIA_TEGRA20_NAND, "nvidia,tegra20-nand"), - COMPAT(NVIDIA_TEGRA124_PMC, "nvidia,tegra124-pmc"), - COMPAT(NVIDIA_TEGRA186_SDMMC, "nvidia,tegra186-sdhci"), - COMPAT(NVIDIA_TEGRA210_SDMMC, "nvidia,tegra210-sdhci"), - COMPAT(NVIDIA_TEGRA124_SDMMC, "nvidia,tegra124-sdhci"), - COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"), - COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"), COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"), COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"), COMPAT(SMSC_LAN9215, "smsc,lan9215"), diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 93f0bf4..2d642de 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -4868,7 +4868,6 @@ CONFIG_SYS_UNSPEC_STRID CONFIG_SYS_USBCTRL CONFIG_SYS_USBD_BASE CONFIG_SYS_USB_EHCI_CPU_INIT -CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS CONFIG_SYS_USB_EHCI_REGS_BASE CONFIG_SYS_USB_FAT_BOOT_PARTITION CONFIG_SYS_USB_HOST @@ -4877,7 +4876,6 @@ CONFIG_SYS_USB_OHCI_CPU_INIT CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS CONFIG_SYS_USB_OHCI_REGS_BASE CONFIG_SYS_USB_OHCI_SLOT_NAME -CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS CONFIG_SYS_USER_SWITCHES_BASE CONFIG_SYS_USE_BOOT_NORFLASH CONFIG_SYS_USE_DATAFLASH @@ -5196,7 +5194,6 @@ CONFIG_USB_XHCI_EXYNOS CONFIG_USB_XHCI_FSL CONFIG_USB_XHCI_KEYSTONE CONFIG_USB_XHCI_OMAP -CONFIG_USB_XHCI_PCI CONFIG_USER_LOWLEVEL_INIT CONFIG_USE_FDT CONFIG_USE_INTERRUPT diff --git a/tools/.gitignore b/tools/.gitignore index 6ec71f5..ac0c979 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -11,6 +11,7 @@ /img2srec /kwboot /dumpimage +/mips-relocs /mkenvimage /mkimage /mkexynosspl diff --git a/tools/Makefile b/tools/Makefile index 62a7921..0743677 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -211,6 +211,8 @@ hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela hostprogs-y += fdtgrep fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o +hostprogs-$(CONFIG_MIPS) += mips-relocs + # We build some files with extra pedantic flags to try to minimize things # that won't build on some weird host compiler -- though there are lots of # exceptions for files that aren't complaint. diff --git a/tools/mips-relocs.c b/tools/mips-relocs.c new file mode 100644 index 0000000..8be69d3 --- /dev/null +++ b/tools/mips-relocs.c @@ -0,0 +1,432 @@ +/* + * MIPS Relocation Data Generator + * + * Copyright (c) 2017 Imagination Technologies Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define hdr_field(pfx, idx, field) ({ \ + uint64_t _val; \ + unsigned int _size; \ + \ + if (is_64) { \ + _val = pfx##hdr64[idx].field; \ + _size = sizeof(pfx##hdr64[0].field); \ + } else { \ + _val = pfx##hdr32[idx].field; \ + _size = sizeof(pfx##hdr32[0].field); \ + } \ + \ + switch (_size) { \ + case 1: \ + break; \ + case 2: \ + _val = is_be ? be16toh(_val) : le16toh(_val); \ + break; \ + case 4: \ + _val = is_be ? be32toh(_val) : le32toh(_val); \ + break; \ + case 8: \ + _val = is_be ? be64toh(_val) : le64toh(_val); \ + break; \ + } \ + \ + _val; \ +}) + +#define set_hdr_field(pfx, idx, field, val) ({ \ + uint64_t _val; \ + unsigned int _size; \ + \ + if (is_64) \ + _size = sizeof(pfx##hdr64[0].field); \ + else \ + _size = sizeof(pfx##hdr32[0].field); \ + \ + switch (_size) { \ + case 1: \ + _val = val; \ + break; \ + case 2: \ + _val = is_be ? htobe16(val) : htole16(val); \ + break; \ + case 4: \ + _val = is_be ? htobe32(val) : htole32(val); \ + break; \ + case 8: \ + _val = is_be ? htobe64(val) : htole64(val); \ + break; \ + default: \ + /* We should never reach here */ \ + _val = 0; \ + assert(0); \ + break; \ + } \ + \ + if (is_64) \ + pfx##hdr64[idx].field = _val; \ + else \ + pfx##hdr32[idx].field = _val; \ +}) + +#define ehdr_field(field) \ + hdr_field(e, 0, field) +#define phdr_field(idx, field) \ + hdr_field(p, idx, field) +#define shdr_field(idx, field) \ + hdr_field(s, idx, field) + +#define set_phdr_field(idx, field, val) \ + set_hdr_field(p, idx, field, val) +#define set_shdr_field(idx, field, val) \ + set_hdr_field(s, idx, field, val) + +#define shstr(idx) (&shstrtab[idx]) + +bool is_64, is_be; +uint64_t text_base; + +struct mips_reloc { + uint8_t type; + uint64_t offset; +} *relocs; +size_t relocs_sz, relocs_idx; + +static int add_reloc(unsigned int type, uint64_t off) +{ + struct mips_reloc *new; + size_t new_sz; + + switch (type) { + case R_MIPS_NONE: + case R_MIPS_LO16: + case R_MIPS_PC16: + case R_MIPS_HIGHER: + case R_MIPS_HIGHEST: + case R_MIPS_PC21_S2: + case R_MIPS_PC26_S2: + /* Skip these relocs */ + return 0; + + default: + break; + } + + if (relocs_idx == relocs_sz) { + new_sz = relocs_sz ? relocs_sz * 2 : 128; + new = realloc(relocs, new_sz * sizeof(*relocs)); + if (!new) { + fprintf(stderr, "Out of memory\n"); + return -ENOMEM; + } + + relocs = new; + relocs_sz = new_sz; + } + + relocs[relocs_idx++] = (struct mips_reloc){ + .type = type, + .offset = off, + }; + + return 0; +} + +static int parse_mips32_rel(const void *_rel) +{ + const Elf32_Rel *rel = _rel; + uint32_t off, type; + + off = is_be ? be32toh(rel->r_offset) : le32toh(rel->r_offset); + off -= text_base; + + type = is_be ? be32toh(rel->r_info) : le32toh(rel->r_info); + type = ELF32_R_TYPE(type); + + return add_reloc(type, off); +} + +static int parse_mips64_rela(const void *_rel) +{ + const Elf64_Rela *rel = _rel; + uint64_t off, type; + + off = is_be ? be64toh(rel->r_offset) : le64toh(rel->r_offset); + off -= text_base; + + type = rel->r_info >> (64 - 8); + + return add_reloc(type, off); +} + +static void output_uint(uint8_t **buf, uint64_t val) +{ + uint64_t tmp; + + do { + tmp = val & 0x7f; + val >>= 7; + tmp |= !!val << 7; + *(*buf)++ = tmp; + } while (val); +} + +static int compare_relocs(const void *a, const void *b) +{ + const struct mips_reloc *ra = a, *rb = b; + + return ra->offset - rb->offset; +} + +int main(int argc, char *argv[]) +{ + unsigned int i, j, i_rel_shdr, sh_type, sh_entsize, sh_entries; + size_t rel_size, rel_actual_size, load_sz; + const char *shstrtab, *sh_name, *rel_pfx; + int (*parse_fn)(const void *rel); + uint8_t *buf_start, *buf; + const Elf32_Ehdr *ehdr32; + const Elf64_Ehdr *ehdr64; + uintptr_t sh_offset; + Elf32_Phdr *phdr32; + Elf64_Phdr *phdr64; + Elf32_Shdr *shdr32; + Elf64_Shdr *shdr64; + struct stat st; + int err, fd; + void *elf; + bool skip; + + fd = open(argv[1], O_RDWR); + if (fd == -1) { + fprintf(stderr, "Unable to open input file %s\n", argv[1]); + err = errno; + goto out_ret; + } + + err = fstat(fd, &st); + if (err) { + fprintf(stderr, "Unable to fstat() input file\n"); + goto out_close_fd; + } + + elf = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (elf == MAP_FAILED) { + fprintf(stderr, "Unable to mmap() input file\n"); + err = errno; + goto out_close_fd; + } + + ehdr32 = elf; + ehdr64 = elf; + + if (memcmp(&ehdr32->e_ident[EI_MAG0], ELFMAG, SELFMAG)) { + fprintf(stderr, "Input file is not an ELF\n"); + err = -EINVAL; + goto out_free_relocs; + } + + if (ehdr32->e_ident[EI_VERSION] != EV_CURRENT) { + fprintf(stderr, "Unrecognised ELF version\n"); + err = -EINVAL; + goto out_free_relocs; + } + + switch (ehdr32->e_ident[EI_CLASS]) { + case ELFCLASS32: + is_64 = false; + break; + case ELFCLASS64: + is_64 = true; + break; + default: + fprintf(stderr, "Unrecognised ELF class\n"); + err = -EINVAL; + goto out_free_relocs; + } + + switch (ehdr32->e_ident[EI_DATA]) { + case ELFDATA2LSB: + is_be = false; + break; + case ELFDATA2MSB: + is_be = true; + break; + default: + fprintf(stderr, "Unrecognised ELF data encoding\n"); + err = -EINVAL; + goto out_free_relocs; + } + + if (ehdr_field(e_type) != ET_EXEC) { + fprintf(stderr, "Input ELF is not an executable\n"); + printf("type 0x%lx\n", ehdr_field(e_type)); + err = -EINVAL; + goto out_free_relocs; + } + + if (ehdr_field(e_machine) != EM_MIPS) { + fprintf(stderr, "Input ELF does not target MIPS\n"); + err = -EINVAL; + goto out_free_relocs; + } + + phdr32 = elf + ehdr_field(e_phoff); + phdr64 = elf + ehdr_field(e_phoff); + shdr32 = elf + ehdr_field(e_shoff); + shdr64 = elf + ehdr_field(e_shoff); + shstrtab = elf + shdr_field(ehdr_field(e_shstrndx), sh_offset); + + i_rel_shdr = UINT_MAX; + for (i = 0; i < ehdr_field(e_shnum); i++) { + sh_name = shstr(shdr_field(i, sh_name)); + + if (!strcmp(sh_name, ".rel")) { + i_rel_shdr = i; + continue; + } + + if (!strcmp(sh_name, ".text")) { + text_base = shdr_field(i, sh_addr); + continue; + } + } + if (i_rel_shdr == UINT_MAX) { + fprintf(stderr, "Unable to find .rel section\n"); + err = -EINVAL; + goto out_free_relocs; + } + if (!text_base) { + fprintf(stderr, "Unable to find .text base address\n"); + err = -EINVAL; + goto out_free_relocs; + } + + rel_pfx = is_64 ? ".rela." : ".rel."; + + for (i = 0; i < ehdr_field(e_shnum); i++) { + sh_type = shdr_field(i, sh_type); + if ((sh_type != SHT_REL) && (sh_type != SHT_RELA)) + continue; + + sh_name = shstr(shdr_field(i, sh_name)); + if (strncmp(sh_name, rel_pfx, strlen(rel_pfx))) { + if (strcmp(sh_name, ".rel") && strcmp(sh_name, ".rel.dyn")) + fprintf(stderr, "WARNING: Unexpected reloc section name '%s'\n", sh_name); + continue; + } + + /* + * Skip reloc sections which either don't correspond to another + * section in the ELF, or whose corresponding section isn't + * loaded as part of the U-Boot binary (ie. doesn't have the + * alloc flags set). + */ + skip = true; + for (j = 0; j < ehdr_field(e_shnum); j++) { + if (strcmp(&sh_name[strlen(rel_pfx) - 1], shstr(shdr_field(j, sh_name)))) + continue; + + skip = !(shdr_field(j, sh_flags) & SHF_ALLOC); + break; + } + if (skip) + continue; + + sh_offset = shdr_field(i, sh_offset); + sh_entsize = shdr_field(i, sh_entsize); + sh_entries = shdr_field(i, sh_size) / sh_entsize; + + if (sh_type == SHT_REL) { + if (is_64) { + fprintf(stderr, "REL-style reloc in MIPS64 ELF?\n"); + err = -EINVAL; + goto out_free_relocs; + } else { + parse_fn = parse_mips32_rel; + } + } else { + if (is_64) { + parse_fn = parse_mips64_rela; + } else { + fprintf(stderr, "RELA-style reloc in MIPS32 ELF?\n"); + err = -EINVAL; + goto out_free_relocs; + } + } + + for (j = 0; j < sh_entries; j++) { + err = parse_fn(elf + sh_offset + (j * sh_entsize)); + if (err) + goto out_free_relocs; + } + } + + /* Sort relocs in ascending order of offset */ + qsort(relocs, relocs_idx, sizeof(*relocs), compare_relocs); + + /* Make reloc offsets relative to their predecessor */ + for (i = relocs_idx - 1; i > 0; i--) + relocs[i].offset -= relocs[i - 1].offset; + + /* Write the relocations to the .rel section */ + buf = buf_start = elf + shdr_field(i_rel_shdr, sh_offset); + for (i = 0; i < relocs_idx; i++) { + output_uint(&buf, relocs[i].type); + output_uint(&buf, relocs[i].offset >> 2); + } + + /* Write a terminating R_MIPS_NONE (0) */ + output_uint(&buf, R_MIPS_NONE); + + /* Ensure the relocs didn't overflow the .rel section */ + rel_size = shdr_field(i_rel_shdr, sh_size); + rel_actual_size = buf - buf_start; + if (rel_actual_size > rel_size) { + fprintf(stderr, "Relocs overflowed .rel section\n"); + return -ENOMEM; + } + + /* Update the .rel section's size */ + set_shdr_field(i_rel_shdr, sh_size, rel_actual_size); + + /* Shrink the PT_LOAD program header filesz (ie. shrink u-boot.bin) */ + for (i = 0; i < ehdr_field(e_phnum); i++) { + if (phdr_field(i, p_type) != PT_LOAD) + continue; + + load_sz = phdr_field(i, p_filesz); + load_sz -= rel_size - rel_actual_size; + set_phdr_field(i, p_filesz, load_sz); + break; + } + + /* Make sure data is written back to the file */ + err = msync(elf, st.st_size, MS_SYNC); + if (err) { + fprintf(stderr, "Failed to msync: %d\n", errno); + goto out_free_relocs; + } + +out_free_relocs: + free(relocs); + munmap(elf, st.st_size); +out_close_fd: + close(fd); +out_ret: + return err; +}