summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt136
-rw-r--r--MAINTAINERS8
-rw-r--r--Makefile19
-rw-r--r--arch/arc/dts/axs10x_mb.dtsi2
-rw-r--r--arch/arc/dts/hsdk.dts2
-rw-r--r--arch/arm/Kconfig8
-rw-r--r--arch/arm/dts/Makefile8
-rw-r--r--arch/arm/dts/am335x-brppt1-spi.dts2
-rw-r--r--arch/arm/dts/am437x-idk-evm.dts2
-rw-r--r--arch/arm/dts/am437x-sk-evm.dts2
-rw-r--r--arch/arm/dts/armada-370-xp.dtsi133
-rw-r--r--arch/arm/dts/armada-3720-db.dts2
-rw-r--r--arch/arm/dts/armada-3720-espressobin.dts2
-rw-r--r--arch/arm/dts/armada-3720-turris-mox.dts2
-rw-r--r--arch/arm/dts/armada-385-amc.dts166
-rw-r--r--arch/arm/dts/armada-385-atl-x530-u-boot.dtsi4
-rw-r--r--arch/arm/dts/armada-385-db-88f6820-amc.dts146
-rw-r--r--arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi2
-rw-r--r--arch/arm/dts/armada-38x-controlcenterdc.dts4
-rw-r--r--arch/arm/dts/armada-38x-solidrun-microsom.dtsi2
-rw-r--r--arch/arm/dts/armada-8040-clearfog-gt-8k.dts2
-rw-r--r--arch/arm/dts/armada-xp-98dx3236.dtsi343
-rw-r--r--arch/arm/dts/armada-xp-98dx3336.dtsi39
-rw-r--r--arch/arm/dts/armada-xp-98dx4251.dtsi54
-rw-r--r--arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi24
-rw-r--r--arch/arm/dts/armada-xp-db-xc3-24g4xg.dts110
-rw-r--r--arch/arm/dts/armada-xp-gp.dts167
-rw-r--r--arch/arm/dts/armada-xp-maxbcm.dts24
-rw-r--r--arch/arm/dts/armada-xp-mv78230.dtsi55
-rw-r--r--arch/arm/dts/armada-xp-mv78260.dtsi58
-rw-r--r--arch/arm/dts/armada-xp-mv78460.dtsi58
-rw-r--r--arch/arm/dts/armada-xp-synology-ds414.dts199
-rw-r--r--arch/arm/dts/armada-xp-theadorable.dts69
-rw-r--r--arch/arm/dts/armada-xp.dtsi214
-rw-r--r--arch/arm/dts/at91-sama5d2_xplained.dts2
-rw-r--r--arch/arm/dts/at91-sama5d4_xplained.dts2
-rw-r--r--arch/arm/dts/at91-sama5d4ek.dts2
-rw-r--r--arch/arm/dts/at91sam9n12ek.dts2
-rw-r--r--arch/arm/dts/at91sam9x5ek.dtsi2
-rw-r--r--arch/arm/dts/bcm63158.dtsi80
-rw-r--r--arch/arm/dts/bcm6858.dtsi80
-rw-r--r--arch/arm/dts/bcm963158.dts32
-rw-r--r--arch/arm/dts/bcm968580xref.dts32
-rw-r--r--arch/arm/dts/bk4r1.dts4
-rw-r--r--arch/arm/dts/da850-evm-u-boot.dtsi2
-rw-r--r--arch/arm/dts/exynos5250-snow.dts2
-rw-r--r--arch/arm/dts/exynos5250-spring.dts2
-rw-r--r--arch/arm/dts/exynos5420-peach-pit.dts2
-rw-r--r--arch/arm/dts/fsl-ls1012a-2g5rdb.dts2
-rw-r--r--arch/arm/dts/fsl-ls1012a-frdm.dtsi2
-rw-r--r--arch/arm/dts/fsl-ls1012a-frwy.dts2
-rw-r--r--arch/arm/dts/fsl-ls1012a-qds.dtsi8
-rw-r--r--arch/arm/dts/fsl-ls1012a-rdb.dtsi2
-rw-r--r--arch/arm/dts/fsl-ls1043a-qds.dtsi8
-rw-r--r--arch/arm/dts/fsl-ls1043a-rdb.dts2
-rw-r--r--arch/arm/dts/fsl-ls1046a-qds.dtsi8
-rw-r--r--arch/arm/dts/fsl-ls1046a-rdb.dts4
-rw-r--r--arch/arm/dts/fsl-ls1088a-qds.dts10
-rw-r--r--arch/arm/dts/fsl-ls1088a-rdb.dts4
-rw-r--r--arch/arm/dts/fsl-ls2080a-qds.dts8
-rw-r--r--arch/arm/dts/fsl-ls2080a-rdb.dts2
-rw-r--r--arch/arm/dts/fsl-ls2081a-rdb.dts6
-rw-r--r--arch/arm/dts/fsl-ls2088a-rdb-qspi.dts6
-rw-r--r--arch/arm/dts/imx53-kp-u-boot.dtsi10
-rw-r--r--arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi4
-rw-r--r--arch/arm/dts/imx6sx-sdb-u-boot.dtsi4
-rw-r--r--arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi2
-rw-r--r--arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi2
-rw-r--r--arch/arm/dts/imx6ull-14x14-evk.dts2
-rw-r--r--arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi2
-rw-r--r--arch/arm/dts/keystone-k2e-evm.dts2
-rw-r--r--arch/arm/dts/keystone-k2g-evm.dts4
-rw-r--r--arch/arm/dts/keystone-k2g-ice.dts2
-rw-r--r--arch/arm/dts/keystone-k2hk-evm.dts2
-rw-r--r--arch/arm/dts/keystone-k2l-evm.dts2
-rw-r--r--arch/arm/dts/kirkwood-atl-sbx81lifkw.dts2
-rw-r--r--arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts2
-rw-r--r--arch/arm/dts/kirkwood-dreamplug.dts2
-rw-r--r--arch/arm/dts/kirkwood-lsxl.dtsi2
-rw-r--r--arch/arm/dts/kirkwood-netxbig.dtsi2
-rw-r--r--arch/arm/dts/kirkwood-ns2-common.dtsi2
-rw-r--r--arch/arm/dts/kirkwood-synology.dtsi2
-rw-r--r--arch/arm/dts/ls1021a-iot.dtsi4
-rw-r--r--arch/arm/dts/ls1021a-qds.dtsi2
-rw-r--r--arch/arm/dts/ls1021a-twr.dtsi4
-rw-r--r--arch/arm/dts/mt7629-rfb.dts2
-rw-r--r--arch/arm/dts/omap5-u-boot.dtsi2
-rw-r--r--arch/arm/dts/r8a77970-eagle-u-boot.dts2
-rw-r--r--arch/arm/dts/rk3288-veyron.dtsi2
-rw-r--r--arch/arm/dts/rk3368-lion.dts2
-rw-r--r--arch/arm/dts/rk3399-gru.dtsi2
-rw-r--r--arch/arm/dts/rk3399-puma.dtsi2
-rw-r--r--arch/arm/dts/rv1108-evb.dts2
-rw-r--r--arch/arm/dts/sama5d27_som1.dtsi2
-rw-r--r--arch/arm/dts/sama5d3xmb.dtsi2
-rw-r--r--arch/arm/dts/sama5d3xmb_cmp.dtsi2
-rw-r--r--arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_is1.dts2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_sr1500.dts2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi4
-rw-r--r--arch/arm/dts/stm32f746-disco.dts2
-rw-r--r--arch/arm/dts/stm32f769-disco.dts2
-rw-r--r--arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi120
-rw-r--r--arch/arm/dts/stm32mp157-pinctrl.dtsi81
-rw-r--r--arch/arm/dts/stm32mp157-u-boot.dtsi6
-rw-r--r--arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi199
-rw-r--r--arch/arm/dts/stm32mp157a-dk1.dts262
-rw-r--r--arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi6
-rw-r--r--arch/arm/dts/stm32mp157c-dk2.dts67
-rw-r--r--arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi40
-rw-r--r--arch/arm/dts/stm32mp157c-ed1.dts55
-rw-r--r--arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi25
-rw-r--r--arch/arm/dts/stm32mp157c-ev1.dts118
-rw-r--r--arch/arm/dts/stm32mp157c.dtsi281
-rw-r--r--arch/arm/dts/stv0991.dts2
-rw-r--r--arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts68
-rw-r--r--arch/arm/dts/zynq-zed.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1232-revA.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1254-revA.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1275-revA.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1275-revB.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts2
-rw-r--r--arch/arm/dts/zynqmp-zcu102-revA.dts2
-rw-r--r--arch/arm/dts/zynqmp-zcu104-revA.dts2
-rw-r--r--arch/arm/dts/zynqmp-zcu104-revC.dts2
-rw-r--r--arch/arm/dts/zynqmp-zcu106-revA.dts2
-rw-r--r--arch/arm/dts/zynqmp-zcu111-revA.dts2
-rw-r--r--arch/arm/include/asm/arch-sunxi/spl.h2
-rw-r--r--arch/arm/include/asm/gpio.h3
-rw-r--r--arch/arm/mach-kirkwood/cpu.c74
-rw-r--r--arch/arm/mach-kirkwood/include/mach/cpu.h13
-rw-r--r--arch/arm/mach-kirkwood/include/mach/soc.h2
-rw-r--r--arch/arm/mach-mvebu/Kconfig34
-rw-r--r--arch/arm/mach-mvebu/Makefile2
-rw-r--r--arch/arm/mach-mvebu/cpu.c46
-rw-r--r--arch/arm/mach-mvebu/include/mach/config.h2
-rw-r--r--arch/arm/mach-mvebu/include/mach/cpu.h3
-rw-r--r--arch/arm/mach-mvebu/include/mach/soc.h31
-rw-r--r--arch/arm/mach-mvebu/mbus.c9
-rw-r--r--arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c8
-rw-r--r--arch/arm/mach-stm32mp/Kconfig29
-rw-r--r--arch/arm/mach-stm32mp/Makefile3
-rw-r--r--arch/arm/mach-stm32mp/bsec.c60
-rw-r--r--arch/arm/mach-stm32mp/cmd_poweroff.c24
-rw-r--r--arch/arm/mach-stm32mp/config.mk15
-rw-r--r--arch/arm/mach-stm32mp/cpu.c214
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32.h23
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h64
-rw-r--r--arch/arm/mach-stm32mp/include/mach/sys_proto.h12
-rw-r--r--arch/arm/mach-stm32mp/psci.c8
-rw-r--r--arch/arm/mach-stm32mp/spl.c39
-rw-r--r--arch/arm/mach-stm32mp/syscon.c9
-rw-r--r--arch/arm/mach-sunxi/Kconfig6
-rw-r--r--arch/arm/mach-sunxi/board.c2
-rw-r--r--arch/arm/mach-sunxi/dram_sun8i_a33.c2
-rw-r--r--arch/mips/dts/Makefile1
-rw-r--r--arch/mips/dts/ap121.dts2
-rw-r--r--arch/mips/dts/ap143.dts7
-rw-r--r--arch/mips/dts/ap152.dts48
-rw-r--r--arch/mips/dts/brcm,bcm6838.dtsi27
-rw-r--r--arch/mips/dts/brcm,bcm968380gerg.dts12
-rw-r--r--arch/mips/dts/comtrend,ar-5315u.dts2
-rw-r--r--arch/mips/dts/comtrend,ar-5387un.dts2
-rw-r--r--arch/mips/dts/gardena-smart-gateway-mt7688.dts4
-rw-r--r--arch/mips/dts/jr2_pcb110.dts78
-rw-r--r--arch/mips/dts/jr2_pcb111.dts402
-rw-r--r--arch/mips/dts/linkit-smart-7688.dts2
-rw-r--r--arch/mips/dts/luton_pcb090.dts2
-rw-r--r--arch/mips/dts/luton_pcb091.dts2
-rw-r--r--arch/mips/dts/mscc,jr2.dtsi116
-rw-r--r--arch/mips/dts/mscc,ocelot_pcb.dtsi2
-rw-r--r--arch/mips/dts/mscc,servalt.dtsi40
-rw-r--r--arch/mips/dts/netgear,cg3100d.dts2
-rw-r--r--arch/mips/dts/qca953x.dtsi31
-rw-r--r--arch/mips/dts/qca956x.dtsi87
-rw-r--r--arch/mips/dts/sagem,f@st1704.dts2
-rw-r--r--arch/mips/dts/serval2_pcb112.dts46
-rw-r--r--arch/mips/dts/serval_pcb105.dts2
-rw-r--r--arch/mips/dts/serval_pcb106.dts2
-rw-r--r--arch/mips/dts/servalt_pcb116.dts27
-rw-r--r--arch/mips/dts/tplink_wdr4300.dts2
-rw-r--r--arch/mips/lib/bootm.c19
-rw-r--r--arch/mips/mach-ath79/Kconfig14
-rw-r--r--arch/mips/mach-ath79/Makefile1
-rw-r--r--arch/mips/mach-ath79/include/mach/ar71xx_regs.h77
-rw-r--r--arch/mips/mach-ath79/include/mach/ath79.h3
-rw-r--r--arch/mips/mach-ath79/qca956x/Makefile5
-rw-r--r--arch/mips/mach-ath79/qca956x/clk.c419
-rw-r--r--arch/mips/mach-ath79/qca956x/cpu.c9
-rw-r--r--arch/mips/mach-ath79/qca956x/ddr.c308
-rw-r--r--arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S193
-rw-r--r--arch/mips/mach-ath79/reset.c271
-rw-r--r--arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h2
-rw-r--r--arch/mips/mach-mt7620/Kconfig4
-rw-r--r--arch/nds32/dts/ae3xx.dts2
-rw-r--r--arch/riscv/dts/ae350_32.dts2
-rw-r--r--arch/riscv/dts/ae350_64.dts2
-rw-r--r--arch/sandbox/dts/test.dts5
-rw-r--r--arch/sandbox/include/asm/sdl.h4
-rw-r--r--arch/sandbox/include/asm/types.h12
-rw-r--r--arch/sandbox/lib/pci_io.c2
-rw-r--r--arch/x86/dts/bayleybay.dts2
-rw-r--r--arch/x86/dts/baytrail_som-db5800-som-6867.dts2
-rw-r--r--arch/x86/dts/cherryhill.dts2
-rw-r--r--arch/x86/dts/chromebook_link.dts2
-rw-r--r--arch/x86/dts/chromebook_samus.dts2
-rw-r--r--arch/x86/dts/chromebox_panther.dts2
-rw-r--r--arch/x86/dts/conga-qeval20-qa3-e3845.dts2
-rw-r--r--arch/x86/dts/cougarcanyon2.dts2
-rw-r--r--arch/x86/dts/crownbay.dts2
-rw-r--r--arch/x86/dts/dfi-bt700.dtsi2
-rw-r--r--arch/x86/dts/galileo.dts2
-rw-r--r--arch/x86/dts/minnowmax.dts2
-rw-r--r--board/CZ.NIC/turris_omnia/turris_omnia.c2
-rw-r--r--board/Marvell/db-xc3-24g4xg/.gitignore1
-rw-r--r--board/Marvell/db-xc3-24g4xg/MAINTAINERS7
-rw-r--r--board/Marvell/db-xc3-24g4xg/Makefile14
-rw-r--r--board/Marvell/db-xc3-24g4xg/README4
-rw-r--r--board/Marvell/db-xc3-24g4xg/binary.011
-rw-r--r--board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c68
-rw-r--r--board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in12
-rw-r--r--board/Synology/ds414/ds414.c4
-rw-r--r--board/alliedtelesis/x530/x530.c48
-rw-r--r--board/maxbcm/maxbcm.c2
-rw-r--r--board/mscc/jr2/jr2.c23
-rw-r--r--board/qca/ap152/Kconfig15
-rw-r--r--board/qca/ap152/MAINTAINERS6
-rw-r--r--board/qca/ap152/Makefile3
-rw-r--r--board/qca/ap152/ap152.c81
-rw-r--r--board/solidrun/clearfog/README23
-rw-r--r--board/st/stm32mp1/MAINTAINERS5
-rw-r--r--board/st/stm32mp1/README85
-rw-r--r--board/st/stm32mp1/board.c47
-rw-r--r--board/st/stm32mp1/spl.c12
-rw-r--r--board/st/stm32mp1/stm32mp1.c405
-rw-r--r--board/sunxi/MAINTAINERS7
-rw-r--r--board/theadorable/theadorable.c38
-rw-r--r--cmd/Kconfig6
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/sf.c3
-rw-r--r--cmd/wdt.c174
-rw-r--r--common/fdt_support.c6
-rw-r--r--common/spl/spl_spi.c2
-rw-r--r--common/usb_kbd.c24
-rw-r--r--configs/ap152_defconfig49
-rw-r--r--configs/bananapi_m2_plus_h3_defconfig2
-rw-r--r--configs/bananapi_m2_plus_h5_defconfig2
-rw-r--r--configs/bananapi_m2_zero_defconfig2
-rw-r--r--configs/bcm963158_ram_defconfig3
-rw-r--r--configs/bcm968380gerg_ram_defconfig2
-rw-r--r--configs/bcm968580xref_ram_defconfig3
-rw-r--r--configs/da850_am18xxevm_defconfig4
-rw-r--r--configs/da850evm_defconfig4
-rw-r--r--configs/db-88f6820-amc_defconfig2
-rw-r--r--configs/db-mv784mp-gp_defconfig1
-rw-r--r--configs/db-xc3-24g4xg_defconfig55
-rw-r--r--configs/dns325_defconfig2
-rw-r--r--configs/dreamplug_defconfig2
-rw-r--r--configs/ds109_defconfig2
-rw-r--r--configs/ds414_defconfig1
-rw-r--r--configs/emlid_neutis_n5_devboard_defconfig1
-rw-r--r--configs/goflexhome_defconfig2
-rw-r--r--configs/guruplug_defconfig2
-rw-r--r--configs/libretech_all_h3_cc_h2_plus_defconfig2
-rw-r--r--configs/libretech_all_h3_cc_h3_defconfig2
-rw-r--r--configs/libretech_all_h3_cc_h5_defconfig2
-rw-r--r--configs/linkit-smart-7688-ram_defconfig15
-rw-r--r--configs/linkit-smart-7688_defconfig15
-rw-r--r--configs/lschlv2_defconfig6
-rw-r--r--configs/lsxhl_defconfig6
-rw-r--r--configs/mscc_jr2_defconfig10
-rw-r--r--configs/mscc_luton_defconfig4
-rw-r--r--configs/mscc_ocelot_defconfig4
-rw-r--r--configs/mscc_serval_defconfig4
-rw-r--r--configs/mscc_servalt_defconfig10
-rw-r--r--configs/nanopi_m1_defconfig2
-rw-r--r--configs/nanopi_m1_plus_defconfig2
-rw-r--r--configs/nanopi_neo2_defconfig1
-rw-r--r--configs/nanopi_neo_air_defconfig2
-rw-r--r--configs/nanopi_neo_defconfig2
-rw-r--r--configs/nanopi_neo_plus2_defconfig1
-rw-r--r--configs/nas220_defconfig2
-rw-r--r--configs/oceanic_5205_5inmfd_defconfig20
-rw-r--r--configs/orangepi_2_defconfig2
-rw-r--r--configs/orangepi_lite_defconfig2
-rw-r--r--configs/orangepi_one_defconfig2
-rw-r--r--configs/orangepi_pc2_defconfig1
-rw-r--r--configs/orangepi_pc_defconfig2
-rw-r--r--configs/orangepi_pc_plus_defconfig2
-rw-r--r--configs/orangepi_plus2e_defconfig2
-rw-r--r--configs/orangepi_plus_defconfig2
-rw-r--r--configs/orangepi_prime_defconfig1
-rw-r--r--configs/orangepi_r1_defconfig2
-rw-r--r--configs/orangepi_zero_defconfig2
-rw-r--r--configs/orangepi_zero_plus2_defconfig1
-rw-r--r--configs/orangepi_zero_plus_defconfig1
-rw-r--r--configs/pine64-lts_defconfig1
-rw-r--r--configs/sandbox64_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--configs/sheevaplug_defconfig1
-rw-r--r--configs/stm32mp15_basic_defconfig24
-rw-r--r--configs/stm32mp15_trusted_defconfig70
-rw-r--r--configs/theadorable_debug_defconfig1
-rw-r--r--configs/turris_omnia_defconfig1
-rw-r--r--configs/x530_defconfig5
-rw-r--r--doc/README.chromium296
-rw-r--r--doc/README.chromium-chainload239
-rw-r--r--doc/device-tree-bindings/i2c/i2c.txt5
-rw-r--r--doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt59
-rw-r--r--doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt2
-rw-r--r--doc/device-tree-bindings/spi/spi-atcspi200.txt2
-rw-r--r--doc/device-tree-bindings/spi/spi-stm32-qspi.txt2
-rw-r--r--doc/git-mailrc6
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/ata/ahci_mvebu.c1
-rw-r--r--drivers/ata/sata_mv.c354
-rw-r--r--drivers/clk/altera/clk-arria10.c3
-rw-r--r--drivers/clk/at91/pmc.c2
-rw-r--r--drivers/clk/clk_stm32mp1.c2
-rw-r--r--drivers/core/ofnode.c21
-rw-r--r--drivers/core/syscon-uclass.c83
-rw-r--r--drivers/core/util.c40
-rw-r--r--drivers/ddr/marvell/axp/xor_regs.h4
-rw-r--r--drivers/dma/bcm6348-iudma.c6
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/bcm6345_gpio.c12
-rw-r--r--drivers/i2c/i2c-uclass.c24
-rw-r--r--drivers/i2c/muxes/Kconfig11
-rw-r--r--drivers/i2c/muxes/pca954x.c10
-rw-r--r--drivers/i2c/mxc_i2c.c19
-rw-r--r--drivers/misc/i2c_eeprom.c26
-rw-r--r--drivers/misc/stm32mp_fuse.c28
-rw-r--r--drivers/mtd/mtdcore.c6
-rw-r--r--drivers/mtd/nand/raw/Kconfig11
-rw-r--r--drivers/mtd/nand/raw/Makefile1
-rw-r--r--drivers/mtd/nand/raw/stm32_fmc2_nand.c1092
-rw-r--r--drivers/mtd/nand/spi/gigadevice.c79
-rw-r--r--drivers/mtd/spi/Kconfig6
-rw-r--r--drivers/mtd/spi/sf_probe.c1
-rw-r--r--drivers/mtd/spi/spi-nor-core.c14
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c7
-rw-r--r--drivers/net/ag7xxx.c328
-rw-r--r--drivers/net/mscc_eswitch/Kconfig14
-rw-r--r--drivers/net/mscc_eswitch/Makefile2
-rw-r--r--drivers/net/mscc_eswitch/jr2_switch.c1075
-rw-r--r--drivers/net/mscc_eswitch/ocelot_switch.c27
-rw-r--r--drivers/net/mscc_eswitch/servalt_switch.c622
-rw-r--r--drivers/phy/Kconfig8
-rw-r--r--drivers/phy/Makefile1
-rw-r--r--drivers/phy/mt76x8-usb-phy.c161
-rw-r--r--drivers/pinctrl/Kconfig19
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/ath79/Makefile2
-rw-r--r--drivers/pinctrl/pinctrl-stmfx.c431
-rw-r--r--drivers/pinctrl/pinctrl-uclass.c36
-rw-r--r--drivers/power/pmic/Kconfig6
-rw-r--r--drivers/power/pmic/Makefile2
-rw-r--r--drivers/power/pmic/stpmic1.c255
-rw-r--r--drivers/power/pmic/stpmu1.c95
-rw-r--r--drivers/power/regulator/Kconfig14
-rw-r--r--drivers/power/regulator/Makefile2
-rw-r--r--drivers/power/regulator/stpmic1.c672
-rw-r--r--drivers/power/regulator/stpmu1.c671
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_ram.c3
-rw-r--r--drivers/spi/Kconfig3
-rw-r--r--drivers/spi/cadence_qspi.c2
-rw-r--r--drivers/spi/cadence_qspi.h2
-rw-r--r--drivers/spi/cadence_qspi_apb.c7
-rw-r--r--drivers/spi/fsl_dspi.c30
-rw-r--r--drivers/spi/spi-mem.c2
-rw-r--r--drivers/spi/spi-uclass.c4
-rw-r--r--drivers/spi/stm32_qspi.c625
-rw-r--r--drivers/sysreset/sysreset_syscon.c15
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/console_normal.c3
-rw-r--r--drivers/video/console_rotate.c7
-rw-r--r--drivers/video/pwm_backlight.c11
-rw-r--r--drivers/video/vidconsole-uclass.c111
-rw-r--r--drivers/video/video-uclass.c1
-rw-r--r--drivers/watchdog/Kconfig1
-rw-r--r--drivers/watchdog/orion_wdt.c27
-rw-r--r--dts/Kconfig8
-rw-r--r--include/configs/ap152.h50
-rw-r--r--include/configs/clearfog.h2
-rw-r--r--include/configs/db-88f6720.h2
-rw-r--r--include/configs/db-88f6820-amc.h2
-rw-r--r--include/configs/db-88f6820-gp.h6
-rw-r--r--include/configs/db-mv784mp-gp.h2
-rw-r--r--include/configs/db-xc3-24g4xg.h41
-rw-r--r--include/configs/ds414.h2
-rw-r--r--include/configs/helios4.h2
-rw-r--r--include/configs/lsxl.h23
-rw-r--r--include/configs/mvebu_armada-8k.h4
-rw-r--r--include/configs/stm32mp1.h62
-rw-r--r--include/configs/sunxi-common.h1
-rw-r--r--include/configs/theadorable.h2
-rw-r--r--include/configs/turris_mox.h4
-rw-r--r--include/configs/turris_omnia.h3
-rw-r--r--include/configs/vcoreiii.h4
-rw-r--r--include/dm/pinctrl.h12
-rw-r--r--include/dm/util.h26
-rw-r--r--include/dt-bindings/mfd/st,stpmic1.h46
-rw-r--r--include/dt-bindings/mfd/st,stpmu1.h60
-rw-r--r--include/dt-bindings/mscc/jr2_data.h19
-rw-r--r--include/fdtdec.h169
-rw-r--r--include/i2c.h2
-rw-r--r--include/linux/mtd/mtd.h2
-rw-r--r--include/power/stpmic1.h117
-rw-r--r--include/power/stpmu1.h85
-rw-r--r--include/spi.h9
-rw-r--r--include/video.h2
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/fdtdec.c227
-rw-r--r--lib/fdtdec_test.c216
-rw-r--r--lib/libfdt/fdt_ro.c31
-rw-r--r--lib/vsprintf.c2
-rw-r--r--scripts/Makefile.lib1
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c31
-rw-r--r--scripts/dtc/libfdt/libfdt.h19
-rw-r--r--scripts/dtc/libfdt/libfdt_env.h1
-rw-r--r--test/dm/syscon.c7
-rw-r--r--tools/kwbimage.c7
-rw-r--r--tools/mkimage.c23
427 files changed, 14211 insertions, 3337 deletions
diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
new file mode 100644
index 00000000000..bac4afa3b19
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
@@ -0,0 +1,136 @@
+*** Reserved memory regions ***
+
+Reserved memory is specified as a node under the /reserved-memory node.
+The operating system shall exclude reserved memory from normal usage
+one can create child nodes describing particular reserved (excluded from
+normal use) memory regions. Such memory regions are usually designed for
+the special usage by various device drivers.
+
+Parameters for each memory region can be encoded into the device tree
+with the following nodes:
+
+/reserved-memory node
+---------------------
+#address-cells, #size-cells (required) - standard definition
+ - Should use the same values as the root node
+ranges (required) - standard definition
+ - Should be empty
+
+/reserved-memory/ child nodes
+-----------------------------
+Each child of the reserved-memory node specifies one or more regions of
+reserved memory. Each child node may either use a 'reg' property to
+specify a specific range of reserved memory, or a 'size' property with
+optional constraints to request a dynamically allocated block of memory.
+
+Following the generic-names recommended practice, node names should
+reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
+address (@<address>) should be appended to the name if the node is a
+static allocation.
+
+Properties:
+Requires either a) or b) below.
+a) static allocation
+ reg (required) - standard definition
+b) dynamic allocation
+ size (required) - length based on parent's #size-cells
+ - Size in bytes of memory to reserve.
+ alignment (optional) - length based on parent's #size-cells
+ - Address boundary for alignment of allocation.
+ alloc-ranges (optional) - prop-encoded-array (address, length pairs).
+ - Specifies regions of memory that are
+ acceptable to allocate from.
+
+If both reg and size are present, then the reg property takes precedence
+and size is ignored.
+
+Additional properties:
+compatible (optional) - standard definition
+ - may contain the following strings:
+ - shared-dma-pool: This indicates a region of memory meant to be
+ used as a shared pool of DMA buffers for a set of devices. It can
+ be used by an operating system to instantiate the necessary pool
+ management subsystem if necessary.
+ - vendor specific string in the form <vendor>,[<device>-]<usage>
+no-map (optional) - empty property
+ - Indicates the operating system must not create a virtual mapping
+ of the region as part of its standard mapping of system memory,
+ nor permit speculative access to it under any circumstances other
+ than under the control of the device driver using the region.
+reusable (optional) - empty property
+ - The operating system can use the memory in this region with the
+ limitation that the device driver(s) owning the region need to be
+ able to reclaim it back. Typically that means that the operating
+ system can use that region to store volatile or cached data that
+ can be otherwise regenerated or migrated elsewhere.
+
+Linux implementation note:
+- If a "linux,cma-default" property is present, then Linux will use the
+ region for the default pool of the contiguous memory allocator.
+
+- If a "linux,dma-default" property is present, then Linux will use the
+ region for the default pool of the consistent DMA allocator.
+
+Device node references to reserved memory
+-----------------------------------------
+Regions in the /reserved-memory node may be referenced by other device
+nodes by adding a memory-region property to the device node.
+
+memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
+
+Example
+-------
+This example defines 3 contiguous regions are defined for Linux kernel:
+one default of all device drivers (named linux,cma@72000000 and 64MiB in size),
+one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and
+one for multimedia processing (named multimedia-memory@77000000, 64MiB).
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0x40000000 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x4000000>;
+ alignment = <0x2000>;
+ linux,cma-default;
+ };
+
+ display_reserved: framebuffer@78000000 {
+ reg = <0x78000000 0x800000>;
+ };
+
+ multimedia_reserved: multimedia@77000000 {
+ compatible = "acme,multimedia-memory";
+ reg = <0x77000000 0x4000000>;
+ };
+ };
+
+ /* ... */
+
+ fb0: video@12300000 {
+ memory-region = <&display_reserved>;
+ /* ... */
+ };
+
+ scaler: scaler@12500000 {
+ memory-region = <&multimedia_reserved>;
+ /* ... */
+ };
+
+ codec: codec@12600000 {
+ memory-region = <&multimedia_reserved>;
+ /* ... */
+ };
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index f9ee4281d94..c77abba1e5b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -295,7 +295,9 @@ F: drivers/misc/stm32mp_fuse.c
F: drivers/mmc/stm32_sdmmc2.c
F: drivers/phy/phy-stm32-usbphyc.c
F: drivers/pinctrl/pinctrl_stm32.c
+F: drivers/power/pmic/stpmic1.c
F: drivers/power/regulator/stm32-vrefbuf.c
+F: drivers/power/regulator/stpmic1.c
F: drivers/ram/stm32mp1/
F: drivers/misc/stm32_rcc.c
F: drivers/reset/stm32-reset.c
@@ -308,7 +310,7 @@ F: arch/arm/cpu/armv7/stv0991/
F: arch/arm/include/asm/arch-stv0991/
ARM SUNXI
-M: Jagan Teki <jagan@openedev.com>
+M: Jagan Teki <jagan@amarulasolutions.com>
M: Maxime Ripard <maxime.ripard@bootlin.com>
S: Maintained
T: git git://git.denx.de/u-boot-sunxi.git
@@ -689,14 +691,14 @@ T: git git://git.denx.de/u-boot-sh.git
F: arch/sh/
SPI
-M: Jagan Teki <jagan@openedev.com>
+M: Jagan Teki <jagan@amarulasolutions.com>
S: Maintained
T: git git://git.denx.de/u-boot-spi.git
F: drivers/spi/
F: include/spi*
SPI-NOR
-M: Jagan Teki <jagan@openedev.com>
+M: Jagan Teki <jagan@amarulasolutions.com>
M: Vignesh R <vigneshr@ti.com>
S: Maintained
F: drivers/mtd/spi/
diff --git a/Makefile b/Makefile
index 9709e763864..2824a6e1594 100644
--- a/Makefile
+++ b/Makefile
@@ -945,11 +945,22 @@ ifneq ($(CONFIG_DM_USB)$(CONFIG_OF_CONTROL)$(CONFIG_BLK),yyy)
@echo >&2 "===================================================="
endif
endif
-ifeq ($(CONFIG_LIBATA)$(CONFIG_MVSATA_IDE),y)
-ifneq ($(CONFIG_DM_SCSI),y)
+ifeq ($(CONFIG_MVSATA_IDE),y)
@echo >&2 "===================== WARNING ======================"
- @echo >&2 "This board does not use CONFIG_DM_SCSI. Please update"
- @echo >&2 "the storage controller to use CONFIG_DM_SCSI before the v2019.07 release."
+ @echo >&2 "This board does use CONFIG_MVSATA_IDE which is not"
+ @echo >&2 "ported to driver-model (DM) yet. Please update the storage"
+ @echo >&2 "controller driver to use CONFIG_AHCI before the v2019.07"
+ @echo >&2 "release."
+ @echo >&2 "Failure to update by the deadline may result in board removal."
+ @echo >&2 "See doc/driver-model/MIGRATION.txt for more info."
+ @echo >&2 "===================================================="
+endif
+ifeq ($(CONFIG_LIBATA),y)
+ifneq ($(CONFIG_AHCI),y)
+ @echo >&2 "===================== WARNING ======================"
+ @echo >&2 "This board does use CONFIG_LIBATA but has CONFIG_AHCI not"
+ @echo >&2 "enabled. Please update the storage controller driver to use"
+ @echo >&2 "CONFIG_AHCI before the v2019.07 release."
@echo >&2 "Failure to update by the deadline may result in board removal."
@echo >&2 "See doc/driver-model/MIGRATION.txt for more info."
@echo >&2 "===================================================="
diff --git a/arch/arc/dts/axs10x_mb.dtsi b/arch/arc/dts/axs10x_mb.dtsi
index dfc03810ca0..b5aacd5170e 100644
--- a/arch/arc/dts/axs10x_mb.dtsi
+++ b/arch/arc/dts/axs10x_mb.dtsi
@@ -71,7 +71,7 @@
clock-names = "spi_clk";
cs-gpio = <&cs_gpio 0>;
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <4000000>;
};
diff --git a/arch/arc/dts/hsdk.dts b/arch/arc/dts/hsdk.dts
index f024b96925e..5e9ba054a4c 100644
--- a/arch/arc/dts/hsdk.dts
+++ b/arch/arc/dts/hsdk.dts
@@ -96,7 +96,7 @@
clock-names = "spi_clk";
cs-gpio = <&cs_gpio 0>;
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <4000000>;
};
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 398dbef1cb8..4640f3b3bd3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1403,11 +1403,15 @@ config ARCH_STM32MP
select SYSRESET
select SYS_THUMB_BUILD
imply CMD_DM
+ imply CMD_POWEROFF
+ imply ENV_VARS_UBOOT_RUNTIME_CONFIG
help
Support for STM32MP SoC family developed by STMicroelectronics,
MPUs based on ARM cortex A core
- U-BOOT is running in DDR and SPL support is the unsecure First Stage
- BootLoader (FSBL)
+ U-BOOT is running in DDR, loaded by the First Stage BootLoader (FSBL).
+ FSBL can be TF-A: Trusted Firmware for Cortex A, for trusted boot
+ chain.
+ SPL is the unsecure FSBL for the basic boot chain.
config ARCH_ROCKCHIP
bool "Support Rockchip SoCs"
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 65e0f66c789..8167cdb4e85 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -138,7 +138,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \
armada-388-clearfog.dtb \
armada-388-gp.dtb \
armada-388-helios4.dtb \
- armada-385-amc.dtb \
+ armada-385-db-88f6820-amc.dtb \
armada-385-turris-omnia.dtb \
armada-7040-db.dtb \
armada-7040-db-nand.dtb \
@@ -151,7 +151,8 @@ dtb-$(CONFIG_ARCH_MVEBU) += \
armada-xp-theadorable.dtb \
armada-38x-controlcenterdc.dtb \
armada-385-atl-x530.dtb \
- armada-385-atl-x530DP.dtb
+ armada-385-atl-x530DP.dtb \
+ armada-xp-db-xc3-24g4xg.dtb
dtb-$(CONFIG_ARCH_UNIPHIER_LD11) += \
uniphier-ld11-global.dtb \
@@ -475,6 +476,7 @@ dtb-$(CONFIG_MACH_SUN50I) += \
sun50i-a64-amarula-relic.dtb \
sun50i-a64-bananapi-m64.dtb \
sun50i-a64-nanopi-a64.dtb \
+ sun50i-a64-oceanic-5205-5inmfd.dtb \
sun50i-a64-olinuxino.dtb \
sun50i-a64-orangepi-win.dtb \
sun50i-a64-pine64-lts.dtb \
@@ -686,6 +688,8 @@ dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb
dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb
dtb-$(CONFIG_TARGET_STM32MP1) += \
+ stm32mp157a-dk1.dtb \
+ stm32mp157c-dk2.dtb \
stm32mp157c-ed1.dtb \
stm32mp157c-ev1.dtb
diff --git a/arch/arm/dts/am335x-brppt1-spi.dts b/arch/arm/dts/am335x-brppt1-spi.dts
index 522ed509020..01ab74be5ed 100644
--- a/arch/arm/dts/am335x-brppt1-spi.dts
+++ b/arch/arm/dts/am335x-brppt1-spi.dts
@@ -169,7 +169,7 @@
spi_flash: spiflash@0 {
u-boot,dm-spl;
u-boot,dm-pre-reloc;
- compatible = "spidev", "spi-flash";
+ compatible = "spidev", "jedec,spi-nor";
spi-max-frequency = <24000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/am437x-idk-evm.dts b/arch/arm/dts/am437x-idk-evm.dts
index 28e3e1ba32a..19d1462d158 100644
--- a/arch/arm/dts/am437x-idk-evm.dts
+++ b/arch/arm/dts/am437x-idk-evm.dts
@@ -339,7 +339,7 @@
spi-max-frequency = <48000000>;
m25p80@0 {
- compatible = "mx66l51235l", "spi-flash";
+ compatible = "mx66l51235l", "jedec,spi-nor";
spi-max-frequency = <48000000>;
reg = <0>;
spi-cpol;
diff --git a/arch/arm/dts/am437x-sk-evm.dts b/arch/arm/dts/am437x-sk-evm.dts
index 927d8d3e882..dc8fcde4586 100644
--- a/arch/arm/dts/am437x-sk-evm.dts
+++ b/arch/arm/dts/am437x-sk-evm.dts
@@ -568,7 +568,7 @@
spi-max-frequency = <48000000>;
m25p80@0 {
- compatible = "mx66l51235l","spi-flash";
+ compatible = "mx66l51235l","jedec,spi-nor";
spi-max-frequency = <48000000>;
reg = <0>;
spi-cpol;
diff --git a/arch/arm/dts/armada-370-xp.dtsi b/arch/arm/dts/armada-370-xp.dtsi
index 0b2a78d3930..e4c35d4e98f 100644
--- a/arch/arm/dts/armada-370-xp.dtsi
+++ b/arch/arm/dts/armada-370-xp.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Device Tree Include file for Marvell Armada 370 and Armada XP SoC
*
@@ -8,50 +9,10 @@
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
* Ben Dooks <ben.dooks@codethink.co.uk>
*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
* This file contains the definitions that are common to the Armada
* 370 and Armada XP SoC.
*/
-/include/ "skeleton64.dtsi"
-
#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
/ {
@@ -86,7 +47,7 @@
pcie-mem-aperture = <0xf8000000 0x7e00000>;
pcie-io-aperture = <0xffe00000 0x100000>;
- devbus-bootcs {
+ devbus_bootcs: devbus-bootcs {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
@@ -96,7 +57,7 @@
status = "disabled";
};
- devbus-cs0 {
+ devbus_cs0: devbus-cs0 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
@@ -106,7 +67,7 @@
status = "disabled";
};
- devbus-cs1 {
+ devbus_cs1: devbus-cs1 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
@@ -116,7 +77,7 @@
status = "disabled";
};
- devbus-cs2 {
+ devbus_cs2: devbus-cs2 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
@@ -126,7 +87,7 @@
status = "disabled";
};
- devbus-cs3 {
+ devbus_cs3: devbus-cs3 {
compatible = "marvell,mvebu-devbus";
reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
@@ -141,34 +102,13 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
- u-boot,dm-pre-reloc;
- rtc@10300 {
+ rtc: rtc@10300 {
compatible = "marvell,orion-rtc";
reg = <0x10300 0x20>;
interrupts = <50>;
};
- spi0: spi@10600 {
- reg = <0x10600 0x28>;
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- interrupts = <30>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- spi1: spi@10680 {
- reg = <0x10680 0x28>;
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <1>;
- interrupts = <92>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
i2c0: i2c@11000 {
compatible = "marvell,mv64xxx-i2c";
#address-cells = <1>;
@@ -235,33 +175,38 @@
msi-controller;
};
- coherency-fabric@20200 {
+ coherencyfab: coherency-fabric@20200 {
compatible = "marvell,coherency-fabric";
reg = <0x20200 0xb0>, <0x21010 0x1c>;
};
- timer@20300 {
+ timer: timer@20300 {
reg = <0x20300 0x30>, <0x21040 0x30>;
interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
};
- watchdog@20300 {
+ watchdog: watchdog@20300 {
reg = <0x20300 0x34>, <0x20704 0x4>;
};
- pmsu@22000 {
+ cpurst: cpurst@20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x8>;
+ };
+
+ pmsu: pmsu@22000 {
compatible = "marvell,armada-370-pmsu";
reg = <0x22000 0x1000>;
};
- usb@50000 {
+ usb0: usb@50000 {
compatible = "marvell,orion-ehci";
reg = <0x50000 0x500>;
interrupts = <45>;
status = "disabled";
};
- usb@51000 {
+ usb1: usb@51000 {
compatible = "marvell,orion-ehci";
reg = <0x51000 0x500>;
interrupts = <46>;
@@ -275,7 +220,7 @@
status = "disabled";
};
- mdio: mdio {
+ mdio: mdio@72004 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
@@ -290,7 +235,7 @@
status = "disabled";
};
- sata@a0000 {
+ sata: sata@a0000 {
compatible = "marvell,armada-370-sata";
reg = <0xa0000 0x5000>;
interrupts = <55>;
@@ -309,7 +254,7 @@
status = "disabled";
};
- mvsdio@d4000 {
+ sdio: mvsdio@d4000 {
compatible = "marvell,orion-sdio";
reg = <0xd4000 0x200>;
interrupts = <54>;
@@ -321,6 +266,42 @@
status = "disabled";
};
};
+
+ spi0: spi@10600 {
+ reg = <MBUS_ID(0xf0, 0x01) 0x10600 0x28>, /* control */
+ <MBUS_ID(0x01, 0x1e) 0 0xffffffff>, /* CS0 */
+ <MBUS_ID(0x01, 0x5e) 0 0xffffffff>, /* CS1 */
+ <MBUS_ID(0x01, 0x9e) 0 0xffffffff>, /* CS2 */
+ <MBUS_ID(0x01, 0xde) 0 0xffffffff>, /* CS3 */
+ <MBUS_ID(0x01, 0x1f) 0 0xffffffff>, /* CS4 */
+ <MBUS_ID(0x01, 0x5f) 0 0xffffffff>, /* CS5 */
+ <MBUS_ID(0x01, 0x9f) 0 0xffffffff>, /* CS6 */
+ <MBUS_ID(0x01, 0xdf) 0 0xffffffff>; /* CS7 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ interrupts = <30>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ spi1: spi@10680 {
+ reg = <MBUS_ID(0xf0, 0x01) 0x10680 0x28>, /* control */
+ <MBUS_ID(0x01, 0x1a) 0 0xffffffff>, /* CS0 */
+ <MBUS_ID(0x01, 0x5a) 0 0xffffffff>, /* CS1 */
+ <MBUS_ID(0x01, 0x9a) 0 0xffffffff>, /* CS2 */
+ <MBUS_ID(0x01, 0xda) 0 0xffffffff>, /* CS3 */
+ <MBUS_ID(0x01, 0x1b) 0 0xffffffff>, /* CS4 */
+ <MBUS_ID(0x01, 0x5b) 0 0xffffffff>, /* CS5 */
+ <MBUS_ID(0x01, 0x9b) 0 0xffffffff>, /* CS6 */
+ <MBUS_ID(0x01, 0xdb) 0 0xffffffff>; /* CS7 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ interrupts = <92>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
};
clocks {
diff --git a/arch/arm/dts/armada-3720-db.dts b/arch/arm/dts/armada-3720-db.dts
index 770c08aa7dd..1b219c423bd 100644
--- a/arch/arm/dts/armada-3720-db.dts
+++ b/arch/arm/dts/armada-3720-db.dts
@@ -131,7 +131,7 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p128", "spi-flash";
+ compatible = "st,m25p128", "jedec,spi-nor";
reg = <0>; /* Chip select 0 */
spi-max-frequency = <50000000>;
m25p,fast-read;
diff --git a/arch/arm/dts/armada-3720-espressobin.dts b/arch/arm/dts/armada-3720-espressobin.dts
index 7bfccb0435a..84e2c2adbae 100644
--- a/arch/arm/dts/armada-3720-espressobin.dts
+++ b/arch/arm/dts/armada-3720-espressobin.dts
@@ -118,7 +118,7 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p128", "spi-flash";
+ compatible = "st,m25p128", "jedec,spi-nor";
reg = <0>; /* Chip select 0 */
spi-max-frequency = <50000000>;
m25p,fast-read;
diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts
index 14bec0977e9..c36a5b8895a 100644
--- a/arch/arm/dts/armada-3720-turris-mox.dts
+++ b/arch/arm/dts/armada-3720-turris-mox.dts
@@ -115,7 +115,7 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,s25fl064l", "spi-flash";
+ compatible = "st,s25fl064l", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <20000000>;
m25p,fast-read;
diff --git a/arch/arm/dts/armada-385-amc.dts b/arch/arm/dts/armada-385-amc.dts
deleted file mode 100644
index c9ccbb57fff..00000000000
--- a/arch/arm/dts/armada-385-amc.dts
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Device Tree file for Marvell Armada 385 development board
- * (DB-88F6820-AMC)
- *
- * Copyright (C) 2014 Marvell
- *
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without
- * any warranty of any kind, whether express or implied.
- *
- * Or, alternatively,
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/dts-v1/;
-#include "armada-385.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- model = "Marvell Armada 385 AMC";
- compatible = "marvell,a385-amc", "marvell,armada385", "marvell,armada380";
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- aliases {
- ethernet0 = &eth0;
- ethernet1 = &eth2;
- i2c0 = &i2c0;
- spi1 = &spi1;
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x80000000>; /* 2 GB */
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
-
- internal-regs {
- i2c@11000 {
- clock-frequency = <100000>;
- u-boot,i2c-slave-addr = <0x0>;
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
- status = "okay";
- };
-
- serial@12000 {
- /*
- * Exported on the micro USB connector CON16
- * through an FTDI
- */
-
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
- status = "okay";
- u-boot,dm-pre-reloc;
- };
-
- ethernet@34000 {
- status = "okay";
- phy = <&phy1>;
- phy-mode = "sgmii";
- };
-
- usb@58000 {
- status = "okay";
- };
-
- ethernet@70000 {
- pinctrl-names = "default";
- /*
- * The Reference Clock 0 is used to provide a
- * clock to the PHY
- */
- pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
- status = "okay";
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- };
-
-
- mdio@72004 {
- pinctrl-names = "default";
- pinctrl-0 = <&mdio_pins>;
-
- phy0: ethernet-phy@1 {
- reg = <1>;
- };
-
- phy1: ethernet-phy@0 {
- reg = <0>;
- };
- };
-
- flash@d0000 {
- status = "okay";
- num-cs = <1>;
- marvell,nand-keep-config;
- marvell,nand-enable-arbiter;
- nand-on-flash-bbt;
- };
- };
-
- pcie {
- status = "okay";
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- };
- };
-};
-
-&spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>;
- status = "okay";
- u-boot,dm-pre-reloc;
-
- spi-flash@0 {
- u-boot,dm-pre-reloc;
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "st,m25p128", "jedec,spi-nor", "spi-flash";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <50000000>;
- m25p,fast-read;
- };
-};
-
-&refclk {
- clock-frequency = <20000000>;
-};
diff --git a/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi b/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi
index 7074a73537f..79b694cb84b 100644
--- a/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi
+++ b/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi
@@ -11,3 +11,7 @@
&uart0 {
u-boot,dm-pre-reloc;
};
+
+&watchdog {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/armada-385-db-88f6820-amc.dts b/arch/arm/dts/armada-385-db-88f6820-amc.dts
new file mode 100644
index 00000000000..59a425f6b15
--- /dev/null
+++ b/arch/arm/dts/armada-385-db-88f6820-amc.dts
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Device Tree file for Marvell Armada 385 AMC board
+ * (DB-88F6820-AMC)
+ *
+ * Copyright (C) 2017 Allied Telesis Labs
+ */
+
+/dts-v1/;
+#include "armada-385.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Marvell Armada 385 AMC";
+ compatible = "marvell,a385-db-amc", "marvell,armada385", "marvell,armada380";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ ethernet0 = &eth0;
+ ethernet1 = &eth2;
+ i2c0 = &i2c0;
+ spi1 = &spi1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000>; /* 2GB */
+ };
+
+ soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+ };
+};
+
+&i2c0 {
+ u-boot,i2c-slave-addr = <0x0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+};
+
+&uart0 {
+ /*
+ * Exported on the micro USB connector CON3
+ * through an FTDI
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+ u-boot,dm-pre-reloc;
+};
+
+
+&eth0 {
+ pinctrl-names = "default";
+ /*
+ * The Reference Clock 0 is used to provide a
+ * clock to the PHY
+ */
+ pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+ status = "okay";
+ phy = <&phy0>;
+ phy-mode = "rgmii-id";
+};
+
+&eth2 {
+ status = "okay";
+ phy = <&phy1>;
+ phy-mode = "sgmii";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+
+
+&mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ phy0: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&nand_controller {
+ status = "okay";
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+};
+
+&pciec {
+ status = "okay";
+};
+
+&pcie1 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ status = "okay";
+ u-boot,dm-pre-reloc;
+
+ spi-flash@0 {
+ u-boot,dm-pre-reloc;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <50000000>;
+ m25p,fast-read;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ reg = <0x00000000 0x00100000>;
+ label = "u-boot";
+ };
+ partition@100000 {
+ reg = <0x00100000 0x00040000>;
+ label = "u-boot-env";
+ };
+ };
+ };
+};
+
+&refclk {
+ clock-frequency = <20000000>;
+};
diff --git a/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi b/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi
index 904429b9742..1b46797583d 100644
--- a/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi
+++ b/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi
@@ -42,7 +42,7 @@
u-boot,dm-pre-reloc;
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/armada-38x-controlcenterdc.dts b/arch/arm/dts/armada-38x-controlcenterdc.dts
index bad7c60f19c..5063a798df7 100644
--- a/arch/arm/dts/armada-38x-controlcenterdc.dts
+++ b/arch/arm/dts/armada-38x-controlcenterdc.dts
@@ -573,14 +573,14 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "n25q016a", "spi-flash";
+ compatible = "n25q016a", "jedec,spi-nor";
reg = <0>; /* Chip select 0 */
spi-max-frequency = <108000000>;
};
spi-flash@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "n25q128a11", "spi-flash";
+ compatible = "n25q128a11", "jedec,spi-nor";
reg = <1>; /* Chip select 1 */
spi-max-frequency = <108000000>;
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi
index 74f58de85c4..a2627223ce3 100644
--- a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi
+++ b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi
@@ -86,7 +86,7 @@
w25q32: spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "w25q32", "jedec,spi-nor", "spi-flash";
+ compatible = "w25q32", "jedec,spi-nor";
reg = <0>; /* Chip select 0 */
spi-max-frequency = <3000000>;
status = "disabled";
diff --git a/arch/arm/dts/armada-8040-clearfog-gt-8k.dts b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts
index cdff44aca5a..720c95082b6 100644
--- a/arch/arm/dts/armada-8040-clearfog-gt-8k.dts
+++ b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts
@@ -240,7 +240,7 @@
status = "okay";
spi-flash@0 {
- compatible = "jedec,spi-nor", "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <10000000>;
diff --git a/arch/arm/dts/armada-xp-98dx3236.dtsi b/arch/arm/dts/armada-xp-98dx3236.dtsi
new file mode 100644
index 00000000000..5df1d1848db
--- /dev/null
+++ b/arch/arm/dts/armada-xp-98dx3236.dtsi
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree Include file for Marvell 98dx3236 family SoC
+ *
+ * Copyright (C) 2016 Allied Telesis Labs
+ *
+ * Contains definitions specific to the 98dx3236 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+#include "armada-370-xp.dtsi"
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ model = "Marvell 98DX3236 SoC";
+ compatible = "marvell,armadaxp-98dx3236", "marvell,armada-370-xp";
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "marvell,98dx3236-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <0>;
+ clocks = <&cpuclk 0>;
+ clock-latency = <1000000>;
+ };
+ };
+
+ soc {
+ compatible = "marvell,armadaxp-mbus", "simple-bus";
+
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
+ MBUS_ID(0x03, 0x00) 0 0 0xa8000000 0x4000000
+ MBUS_ID(0x08, 0x00) 0 0 0xac000000 0x100000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>;
+ };
+
+ /*
+ * 98DX3236 has 1 x1 PCIe unit Gen2.0
+ */
+ pciec: pcie@82000000 {
+ compatible = "marvell,armada-xp-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ msi-parent = <&mpic>;
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
+ 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>;
+
+ pcie1: pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ bus-range = <0x00 0xff>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &mpic 58>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gateclk 5>;
+ status = "disabled";
+ };
+ };
+
+ internal-regs {
+ sdramc: sdramc@1400 {
+ compatible = "marvell,armada-xp-sdram-controller";
+ reg = <0x1400 0x500>;
+ };
+
+ L2: l2-cache@8000 {
+ compatible = "marvell,aurora-system-cache";
+ reg = <0x08000 0x1000>;
+ cache-id-part = <0x100>;
+ cache-level = <2>;
+ cache-unified;
+ wt-override;
+ };
+
+ gpio0: gpio@18100 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18100 0x40>;
+ ngpios = <32>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <82>, <83>, <84>, <85>;
+ };
+
+ /* does not exist */
+ gpio1: gpio@18140 {
+ compatible = "marvell,orion-gpio";
+ reg = <0x18140 0x40>;
+ status = "disabled";
+ };
+
+ gpio2: gpio@18180 { /* rework some properties */
+ compatible = "marvell,orion-gpio";
+ reg = <0x18180 0x40>;
+ ngpios = <1>; /* only gpio #32 */
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <87>;
+ };
+
+ systemc: system-controller@18200 {
+ compatible = "marvell,armada-370-xp-system-controller";
+ reg = <0x18200 0x500>;
+ };
+
+ gateclk: clock-gating-control@18220 {
+ compatible = "marvell,mv98dx3236-gating-clock";
+ reg = <0x18220 0x4>;
+ clocks = <&coreclk 0>;
+ #clock-cells = <1>;
+ };
+
+ cpuclk: clock-complex@18700 {
+ #clock-cells = <1>;
+ compatible = "marvell,mv98dx3236-cpu-clock";
+ reg = <0x18700 0x24>, <0x1c054 0x10>;
+ clocks = <&coreclk 1>;
+ };
+
+ corediv-clock@18740 {
+ status = "disabled";
+ };
+
+ cpu-config@21000 {
+ compatible = "marvell,armada-xp-cpu-config";
+ reg = <0x21000 0x8>;
+ };
+
+ ethernet@70000 {
+ compatible = "marvell,armada-xp-neta";
+ };
+
+ ethernet@74000 {
+ compatible = "marvell,armada-xp-neta";
+ };
+
+ xor1: xor@f0800 {
+ compatible = "marvell,orion-xor";
+ reg = <0xf0800 0x100
+ 0xf0a00 0x100>;
+ clocks = <&gateclk 22>;
+ status = "okay";
+
+ xor10 {
+ interrupts = <51>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor11 {
+ interrupts = <52>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+
+ nand_controller: nand@d0000 {
+ clocks = <&dfx_coredivclk 0>;
+ };
+
+ xor0: xor@f0900 {
+ compatible = "marvell,orion-xor";
+ reg = <0xF0900 0x100
+ 0xF0B00 0x100>;
+ clocks = <&gateclk 28>;
+ status = "okay";
+
+ xor00 {
+ interrupts = <94>;
+ dmacap,memcpy;
+ dmacap,xor;
+ };
+ xor01 {
+ interrupts = <95>;
+ dmacap,memcpy;
+ dmacap,xor;
+ dmacap,memset;
+ };
+ };
+ };
+
+ dfx: dfx-server@ac000000 {
+ compatible = "marvell,dfx-server", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x08, 0x00) 0 0x100000>;
+ reg = <MBUS_ID(0x08, 0x00) 0 0x100000>;
+
+ thermal: thermal@f8078 {
+ compatible = "marvell,armada380-thermal";
+ reg = <0xf8078 0x4>, <0xf8074 0x4>;
+ status = "okay";
+ };
+
+ coreclk: mvebu-sar@f8204 {
+ compatible = "marvell,mv98dx3236-core-clock";
+ reg = <0xf8204 0x4>;
+ #clock-cells = <1>;
+ };
+
+ dfx_coredivclk: corediv-clock@f8268 {
+ compatible = "marvell,mv98dx3236-corediv-clock";
+ reg = <0xf8268 0xc>;
+ #clock-cells = <1>;
+ clocks = <&mainpll>;
+ clock-output-names = "nand";
+ };
+ };
+
+ switch: switch@a8000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x03, 0x00) 0 0x100000>;
+
+ pp0: packet-processor@0 {
+ compatible = "marvell,prestera-98dx3236", "marvell,prestera";
+ reg = <0 0x4000000>;
+ interrupts = <33>, <34>, <35>;
+ dfx = <&dfx>;
+ };
+ };
+ };
+
+ clocks {
+ /* 25 MHz reference crystal */
+ refclk: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+ };
+};
+
+&i2c0 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x100>;
+};
+
+&i2c1 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x100>;
+};
+
+&mpic {
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+};
+
+&rtc {
+ status = "disabled";
+};
+
+&timer {
+ compatible = "marvell,armada-xp-timer";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+};
+
+&watchdog {
+ compatible = "marvell,armada-xp-wdt";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+};
+
+&cpurst {
+ reg = <0x20800 0x20>;
+};
+
+&usb0 {
+ clocks = <&gateclk 18>;
+};
+
+&usb1 {
+ clocks = <&gateclk 19>;
+};
+
+&pinctrl {
+ compatible = "marvell,98dx3236-pinctrl";
+
+ nand_pins: nand-pins {
+ marvell,pins = "mpp20", "mpp21", "mpp22",
+ "mpp23", "mpp24", "mpp25",
+ "mpp26", "mpp27", "mpp28",
+ "mpp29", "mpp30";
+ marvell,function = "dev";
+ };
+
+ nand_rb: nand-rb {
+ marvell,pins = "mpp19";
+ marvell,function = "nand";
+ };
+
+ spi0_pins: spi0-pins {
+ marvell,pins = "mpp0", "mpp1",
+ "mpp2", "mpp3";
+ marvell,function = "spi0";
+ };
+};
+
+&spi0 {
+ compatible = "marvell,armada-xp-spi", "marvell,orion-spi";
+ pinctrl-0 = <&spi0_pins>;
+ pinctrl-names = "default";
+};
+
+&sdio {
+ status = "disabled";
+};
diff --git a/arch/arm/dts/armada-xp-98dx3336.dtsi b/arch/arm/dts/armada-xp-98dx3336.dtsi
new file mode 100644
index 00000000000..1d9d8a8ea60
--- /dev/null
+++ b/arch/arm/dts/armada-xp-98dx3336.dtsi
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree Include file for Marvell 98dx3336 family SoC
+ *
+ * Copyright (C) 2016 Allied Telesis Labs
+ *
+ * Contains definitions specific to the 98dx3236 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+#include "armada-xp-98dx3236.dtsi"
+
+/ {
+ model = "Marvell 98DX3336 SoC";
+ compatible = "marvell,armadaxp-98dx3336", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp";
+
+ cpus {
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ clock-latency = <1000000>;
+ };
+ };
+
+ soc {
+ internal-regs {
+ resume@20980 {
+ compatible = "marvell,98dx3336-resume-ctrl";
+ reg = <0x20980 0x10>;
+ };
+ };
+ };
+};
+
+&pp0 {
+ compatible = "marvell,prestera-98dx3336", "marvell,prestera";
+};
diff --git a/arch/arm/dts/armada-xp-98dx4251.dtsi b/arch/arm/dts/armada-xp-98dx4251.dtsi
new file mode 100644
index 00000000000..48ffdc72bfc
--- /dev/null
+++ b/arch/arm/dts/armada-xp-98dx4251.dtsi
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree Include file for Marvell 98dx4521 family SoC
+ *
+ * Copyright (C) 2016 Allied Telesis Labs
+ *
+ * Contains definitions specific to the 98dx4521 SoC that are not
+ * common to all Armada XP SoCs.
+ */
+
+#include "armada-xp-98dx3236.dtsi"
+
+/ {
+ model = "Marvell 98DX4251 SoC";
+ compatible = "marvell,armadaxp-98dx4251", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp";
+
+ cpus {
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "marvell,sheeva-v7";
+ reg = <1>;
+ clocks = <&cpuclk 1>;
+ clock-latency = <1000000>;
+ };
+ };
+
+ soc {
+ internal-regs {
+ resume@20980 {
+ compatible = "marvell,98dx3336-resume-ctrl";
+ reg = <0x20980 0x10>;
+ };
+ };
+ };
+};
+
+&sdio {
+ status = "okay";
+};
+
+&pinctrl {
+ compatible = "marvell,98dx4251-pinctrl";
+
+ sdio_pins: sdio-pins {
+ marvell,pins = "mpp5", "mpp6", "mpp7",
+ "mpp8", "mpp9", "mpp10";
+ marvell,function = "sd0";
+ };
+};
+
+&pp0 {
+ compatible = "marvell,prestera-98dx4251", "marvell,prestera";
+ interrupts = <33>, <34>, <35>, <36>;
+};
diff --git a/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi b/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi
new file mode 100644
index 00000000000..90cad85506d
--- /dev/null
+++ b/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
+
+&nand_controller {
+ compatible="marvell,mvebu-pxa3xx-nand";
+ status = "okay";
+ label = "pxa3xx_nand-0";
+ nand-rb = <0>;
+ marvell,nand-keep-config;
+ nand-on-flash-bbt;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+};
+
+&spi0 {
+ u-boot,dm-pre-reloc;
+
+ spi-flash@0 {
+ u-boot,dm-pre-reloc;
+ };
+};
diff --git a/arch/arm/dts/armada-xp-db-xc3-24g4xg.dts b/arch/arm/dts/armada-xp-db-xc3-24g4xg.dts
new file mode 100644
index 00000000000..d4b52881e6f
--- /dev/null
+++ b/arch/arm/dts/armada-xp-db-xc3-24g4xg.dts
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for DB-XC3-24G4XG board
+ *
+ * Copyright (C) 2016 Allied Telesis Labs
+ *
+ * Based on armada-xp-db.dts
+ *
+ * Note: this Device Tree assumes that the bootloader has remapped the
+ * internal registers to 0xf1000000 (instead of the default
+ * 0xd0000000). The 0xf1000000 is the default used by the recent,
+ * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier
+ * boards were delivered with an older version of the bootloader that
+ * left internal registers mapped at 0xd0000000. If you are in this
+ * situation, you should either update your bootloader (preferred
+ * solution) or the below Device Tree should be adjusted.
+ */
+
+/dts-v1/;
+#include "armada-xp-98dx3336.dtsi"
+#include "armada-xp-db-xc3-24g4xg-u-boot.dtsi"
+
+/ {
+ model = "DB-XC3-24G4XG";
+ compatible = "marvell,armadaxp-98dx3336", "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ bootargs = "console=ttyS0,115200 earlyprintk";
+ };
+
+ aliases {
+ spi0 = &spi0;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x00000000 0 0x40000000>; /* 1 GB */
+ };
+};
+
+&L2 {
+ arm,parity-enable;
+ marvell,ecc-enable;
+};
+
+&devbus_bootcs {
+ status = "okay";
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <16>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <100000>;
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ m25p,fast-read;
+
+ partition@u-boot {
+ reg = <0x00000000 0x00100000>;
+ label = "u-boot";
+ };
+ partition@u-boot-env {
+ reg = <0x00100000 0x00040000>;
+ label = "u-boot-env";
+ };
+ partition@unused {
+ reg = <0x00140000 0x00ec0000>;
+ label = "unused";
+ };
+
+ };
+};
diff --git a/arch/arm/dts/armada-xp-gp.dts b/arch/arm/dts/armada-xp-gp.dts
index 27799d1254e..1139e9469a8 100644
--- a/arch/arm/dts/armada-xp-gp.dts
+++ b/arch/arm/dts/armada-xp-gp.dts
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Device Tree file for Marvell Armada XP development board
* (DB-MV784MP-GP)
@@ -8,44 +9,6 @@
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
* Note: this Device Tree assumes that the bootloader has remapped the
* internal registers to 0xf1000000 (instead of the default
* 0xd0000000). The 0xf1000000 is the default used by the recent,
@@ -68,11 +31,7 @@
stdout-path = "serial0:115200n8";
};
- aliases {
- spi0 = &spi0;
- };
-
- memory {
+ memory@0 {
device_type = "memory";
/*
* 8 GB of plug-in RAM modules by default.The amount
@@ -98,7 +57,10 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
- MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>;
devbus-bootcs {
status = "okay";
@@ -128,31 +90,9 @@
};
};
- pcie-controller {
- status = "okay";
-
- /*
- * The 3 slots are physically present as
- * standard PCIe slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- pcie@9,0 {
- /* Port 2, Lane 0 */
- status = "okay";
- };
- pcie@10,0 {
- /* Port 3, Lane 0 */
- status = "okay";
- };
- };
-
internal-regs {
serial@12000 {
status = "okay";
- u-boot,dm-pre-reloc;
};
serial@12100 {
status = "okay";
@@ -177,43 +117,33 @@
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 {
- reg = <16>;
- };
-
- phy1: ethernet-phy@1 {
- reg = <17>;
- };
-
- phy2: ethernet-phy@2 {
- reg = <18>;
- };
-
- phy3: ethernet-phy@3 {
- reg = <19>;
- };
- };
-
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
};
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
};
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
};
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
};
/* Front-side USB slot */
@@ -226,27 +156,72 @@
status = "okay";
};
- spi0: spi@10600 {
+ bm@c0000 {
status = "okay";
- u-boot,dm-pre-reloc;
-
- spi-flash@0 {
- u-boot,dm-pre-reloc;
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "n25q128a13", "jedec,spi-nor";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <108000000>;
- };
};
nand@d0000 {
status = "okay";
+ label = "pxa3xx_nand-0";
num-cs = <1>;
marvell,nand-keep-config;
- marvell,nand-enable-arbiter;
nand-on-flash-bbt;
};
};
+
+ bm-bppi {
+ status = "okay";
+ };
+ };
+};
+
+&pciec {
+ status = "okay";
+
+ /*
+ * The 3 slots are physically present as
+ * standard PCIe slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@9,0 {
+ /* Port 2, Lane 0 */
+ status = "okay";
+ };
+ pcie@a,0 {
+ /* Port 3, Lane 0 */
+ status = "okay";
+ };
+};
+
+&mdio {
+ phy0: ethernet-phy@0 {
+ reg = <16>;
+ };
+
+ phy1: ethernet-phy@1 {
+ reg = <17>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <18>;
+ };
+
+ phy3: ethernet-phy@3 {
+ reg = <19>;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
};
};
diff --git a/arch/arm/dts/armada-xp-maxbcm.dts b/arch/arm/dts/armada-xp-maxbcm.dts
index d7d7f65c85f..921eb708625 100644
--- a/arch/arm/dts/armada-xp-maxbcm.dts
+++ b/arch/arm/dts/armada-xp-maxbcm.dts
@@ -225,18 +225,6 @@
status = "okay";
};
- spi0: spi@10600 {
- status = "okay";
-
- spi-flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "n25q128a13", "jedec,spi-nor";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <108000000>;
- };
- };
-
nand@d0000 {
status = "okay";
num-cs = <1>;
@@ -247,3 +235,15 @@
};
};
};
+
+&spi0 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <108000000>;
+ };
+};
diff --git a/arch/arm/dts/armada-xp-mv78230.dtsi b/arch/arm/dts/armada-xp-mv78230.dtsi
index f6bab9fb20a..8558bf6bb54 100644
--- a/arch/arm/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/dts/armada-xp-mv78230.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Device Tree Include file for Marvell Armada XP family SoC
*
@@ -5,44 +6,6 @@
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
* Contains definitions specific to the Armada XP MV78230 SoC that are not
* common to all Armada XP SoCs.
*/
@@ -207,25 +170,33 @@
internal-regs {
gpio0: gpio@18100 {
- compatible = "marvell,orion-gpio";
- reg = <0x18100 0x40>;
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
+ reg = <0x18100 0x40>, <0x181c0 0x08>;
+ reg-names = "gpio", "pwm";
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
+ #pwm-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <82>, <83>, <84>, <85>;
+ clocks = <&coreclk 0>;
};
gpio1: gpio@18140 {
- compatible = "marvell,orion-gpio";
- reg = <0x18140 0x40>;
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
+ reg = <0x18140 0x40>, <0x181c8 0x08>;
+ reg-names = "gpio", "pwm";
ngpios = <17>;
gpio-controller;
#gpio-cells = <2>;
+ #pwm-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <87>, <88>, <89>;
+ clocks = <&coreclk 0>;
};
};
};
diff --git a/arch/arm/dts/armada-xp-mv78260.dtsi b/arch/arm/dts/armada-xp-mv78260.dtsi
index d39231f69d9..2d85fe8ac32 100644
--- a/arch/arm/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/dts/armada-xp-mv78260.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Device Tree Include file for Marvell Armada XP family SoC
*
@@ -5,44 +6,6 @@
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
* Contains definitions specific to the Armada XP MV78260 SoC that are not
* common to all Armada XP SoCs.
*/
@@ -294,29 +257,38 @@
internal-regs {
gpio0: gpio@18100 {
- compatible = "marvell,orion-gpio";
- reg = <0x18100 0x40>;
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
+ reg = <0x18100 0x40>, <0x181c0 0x08>;
+ reg-names = "gpio", "pwm";
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
+ #pwm-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <82>, <83>, <84>, <85>;
+ clocks = <&coreclk 0>;
};
gpio1: gpio@18140 {
- compatible = "marvell,orion-gpio";
- reg = <0x18140 0x40>;
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
+ reg = <0x18140 0x40>, <0x181c8 0x08>;
+ reg-names = "gpio", "pwm";
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
+ #pwm-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <87>, <88>, <89>, <90>;
+ clocks = <&coreclk 0>;
};
gpio2: gpio@18180 {
- compatible = "marvell,orion-gpio";
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
reg = <0x18180 0x40>;
ngpios = <3>;
gpio-controller;
diff --git a/arch/arm/dts/armada-xp-mv78460.dtsi b/arch/arm/dts/armada-xp-mv78460.dtsi
index c642565d1bc..230a3fd36b3 100644
--- a/arch/arm/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/dts/armada-xp-mv78460.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Device Tree Include file for Marvell Armada XP family SoC
*
@@ -5,44 +6,6 @@
*
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
* Contains definitions specific to the Armada XP MV78460 SoC that are not
* common to all Armada XP SoCs.
*/
@@ -333,29 +296,38 @@
internal-regs {
gpio0: gpio@18100 {
- compatible = "marvell,orion-gpio";
- reg = <0x18100 0x40>;
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
+ reg = <0x18100 0x40>, <0x181c0 0x08>;
+ reg-names = "gpio", "pwm";
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
+ #pwm-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <82>, <83>, <84>, <85>;
+ clocks = <&coreclk 0>;
};
gpio1: gpio@18140 {
- compatible = "marvell,orion-gpio";
- reg = <0x18140 0x40>;
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
+ reg = <0x18140 0x40>, <0x181c8 0x08>;
+ reg-names = "gpio", "pwm";
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
+ #pwm-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <87>, <88>, <89>, <90>;
+ clocks = <&coreclk 0>;
};
gpio2: gpio@18180 {
- compatible = "marvell,orion-gpio";
+ compatible = "marvell,armada-370-gpio",
+ "marvell,orion-gpio";
reg = <0x18180 0x40>;
ngpios = <3>;
gpio-controller;
diff --git a/arch/arm/dts/armada-xp-synology-ds414.dts b/arch/arm/dts/armada-xp-synology-ds414.dts
index 0a60ddfa414..861967cd7e8 100644
--- a/arch/arm/dts/armada-xp-synology-ds414.dts
+++ b/arch/arm/dts/armada-xp-synology-ds414.dts
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Device Tree file for Synology DS414
*
* Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
* Note: this Device Tree assumes that the bootloader has remapped the
* internal registers to 0xf1000000 (instead of the old 0xd0000000).
* The 0xf1000000 is the default used by the recent, DT-capable, U-Boot
@@ -42,36 +38,16 @@
spi0 = &spi0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x00000000 0 0x40000000>; /* 1GB */
};
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
-
- pcie-controller {
- status = "okay";
-
- /*
- * Connected to Marvell 88SX7042 SATA-II controller
- * handling the four disks.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
-
- /*
- * Connected to EtronTech EJ168A XHCI controller
- * providing the two rear USB 3.0 ports.
- */
- pcie@5,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
- };
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000
+ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>;
internal-regs {
@@ -80,64 +56,6 @@
status = "disabled";
};
- spi0: spi@10600 {
- status = "okay";
- u-boot,dm-pre-reloc;
-
- spi-flash@0 {
- u-boot,dm-pre-reloc;
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "micron,n25q064";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <20000000>;
-
- /*
- * Warning!
- *
- * Synology u-boot uses its compiled-in environment
- * and it seems Synology did not care to change u-boot
- * default configuration in order to allow saving a
- * modified environment at a sensible location. So,
- * if you do a 'saveenv' under u-boot, your modified
- * environment will be saved at 1MB after the start
- * of the flash, i.e. in the middle of the uImage.
- * For that reason, it is strongly advised not to
- * change the default environment, unless you know
- * what you are doing.
- */
- partition@00000000 { /* u-boot */
- label = "RedBoot";
- reg = <0x00000000 0x000d0000>; /* 832KB */
- };
-
- partition@000c0000 { /* uImage */
- label = "zImage";
- reg = <0x000d0000 0x002d0000>; /* 2880KB */
- };
-
- partition@003a0000 { /* uInitramfs */
- label = "rd.gz";
- reg = <0x003a0000 0x00430000>; /* 4250KB */
- };
-
- partition@007d0000 { /* MAC address and serial number */
- label = "vendor";
- reg = <0x007d0000 0x00010000>; /* 64KB */
- };
-
- partition@007e0000 {
- label = "RedBoot config";
- reg = <0x007e0000 0x00010000>; /* 64KB */
- };
-
- partition@007f0000 {
- label = "FIS directory";
- reg = <0x007f0000 0x00010000>; /* 64KB */
- };
- };
- };
-
i2c@11000 {
clock-frequency = <400000>;
status = "okay";
@@ -179,16 +97,6 @@
status = "okay";
};
- mdio {
- phy0: ethernet-phy@0 { /* Marvell 88E1512 */
- reg = <0>;
- };
-
- phy1: ethernet-phy@1 { /* Marvell 88E1512 */
- reg = <1>;
- };
- };
-
ethernet@70000 {
status = "okay";
pinctrl-0 = <&ge0_rgmii_pins>;
@@ -215,7 +123,7 @@
&sata3_pwr_pin &sata4_pwr_pin>;
pinctrl-names = "default";
- sata1_regulator: sata1-regulator {
+ sata1_regulator: sata1-regulator@1 {
compatible = "regulator-fixed";
reg = <1>;
regulator-name = "SATA1 Power";
@@ -228,7 +136,7 @@
gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- sata2_regulator: sata2-regulator {
+ sata2_regulator: sata2-regulator@2 {
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "SATA2 Power";
@@ -241,7 +149,7 @@
gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
};
- sata3_regulator: sata3-regulator {
+ sata3_regulator: sata3-regulator@3 {
compatible = "regulator-fixed";
reg = <3>;
regulator-name = "SATA3 Power";
@@ -254,7 +162,7 @@
gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
- sata4_regulator: sata4-regulator {
+ sata4_regulator: sata4-regulator@4 {
compatible = "regulator-fixed";
reg = <4>;
regulator-name = "SATA4 Power";
@@ -269,6 +177,39 @@
};
};
+&pciec {
+ status = "okay";
+
+ /*
+ * Connected to Marvell 88SX7042 SATA-II controller
+ * handling the four disks.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+
+ /*
+ * Connected to EtronTech EJ168A XHCI controller
+ * providing the two rear USB 3.0 ports.
+ */
+ pcie@5,0 {
+ /* Port 1, Lane 0 */
+ status = "okay";
+ };
+};
+
+
+&mdio {
+ phy0: ethernet-phy@0 { /* Marvell 88E1512 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 { /* Marvell 88E1512 */
+ reg = <1>;
+ };
+};
+
&pinctrl {
sata1_pwr_pin: sata1-pwr-pin {
marvell,pins = "mpp42";
@@ -335,3 +276,59 @@
marvell,function = "gpio";
};
};
+
+&spi0 {
+ status = "okay";
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q064", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <20000000>;
+
+ /*
+ * Warning!
+ *
+ * Synology u-boot uses its compiled-in environment
+ * and it seems Synology did not care to change u-boot
+ * default configuration in order to allow saving a
+ * modified environment at a sensible location. So,
+ * if you do a 'saveenv' under u-boot, your modified
+ * environment will be saved at 1MB after the start
+ * of the flash, i.e. in the middle of the uImage.
+ * For that reason, it is strongly advised not to
+ * change the default environment, unless you know
+ * what you are doing.
+ */
+ partition@0 { /* u-boot */
+ label = "RedBoot";
+ reg = <0x00000000 0x000d0000>; /* 832KB */
+ };
+
+ partition@c0000 { /* uImage */
+ label = "zImage";
+ reg = <0x000d0000 0x002d0000>; /* 2880KB */
+ };
+
+ partition@3a0000 { /* uInitramfs */
+ label = "rd.gz";
+ reg = <0x003a0000 0x00430000>; /* 4250KB */
+ };
+
+ partition@7d0000 { /* MAC address and serial number */
+ label = "vendor";
+ reg = <0x007d0000 0x00010000>; /* 64KB */
+ };
+
+ partition@7e0000 {
+ label = "RedBoot config";
+ reg = <0x007e0000 0x00010000>; /* 64KB */
+ };
+
+ partition@7f0000 {
+ label = "FIS directory";
+ reg = <0x007f0000 0x00010000>; /* 64KB */
+ };
+ };
+};
diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts
index 5695e9b7585..5b18d62c3c5 100644
--- a/arch/arm/dts/armada-xp-theadorable.dts
+++ b/arch/arm/dts/armada-xp-theadorable.dts
@@ -126,40 +126,6 @@
status = "okay";
};
- spi0: spi@10600 {
- status = "okay";
- u-boot,dm-pre-reloc;
-
- spi-flash@0 {
- u-boot,dm-pre-reloc;
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "n25q128a13", "jedec,spi-nor", "spi-flash";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <27777777>;
- };
-
- fpga@1 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spi-generic-device";
- reg = <1>; /* Chip select 1 */
- spi-max-frequency = <27777777>;
- };
- };
-
- spi1: spi@10680 {
- status = "okay";
-
- fpga@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spi-generic-device";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <27777777>;
- };
- };
-
/* The LCD controller is only used on this board */
lcd0: lcd-controller@e0000 {
compatible = "marvell,armada-xp-lcd";
@@ -188,6 +154,41 @@
};
};
+&spi0 {
+ status = "okay";
+ u-boot,dm-pre-reloc;
+
+ spi-flash@0 {
+ u-boot,dm-pre-reloc;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q128a13", "jedec,spi-nor";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <27777777>;
+ };
+
+ fpga@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-generic-device";
+ reg = <1>; /* Chip select 1 */
+ spi-max-frequency = <27777777>;
+ };
+};
+
+&spi1 {
+ status = "okay";
+
+ fpga@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-generic-device";
+ reg = <0>; /* Chip select 0 */
+ spi-max-frequency = <27777777>;
+ };
+};
+
+
&pciec {
status = "okay";
diff --git a/arch/arm/dts/armada-xp.dtsi b/arch/arm/dts/armada-xp.dtsi
index 3fac39e41d7..d856d960227 100644
--- a/arch/arm/dts/armada-xp.dtsi
+++ b/arch/arm/dts/armada-xp.dtsi
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Device Tree Include file for Marvell Armada XP family SoC
*
@@ -8,44 +9,6 @@
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
* Ben Dooks <ben.dooks@codethink.co.uk>
*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Or, alternatively
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
* Contains definitions specific to the Armada XP SoC that are not
* common to all Armada SoCs.
*/
@@ -53,6 +16,9 @@
#include "armada-370-xp.dtsi"
/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
model = "Marvell Armada XP family SoC";
compatible = "marvell,armadaxp", "marvell,armada-370-xp";
@@ -71,12 +37,12 @@
};
internal-regs {
- sdramc@1400 {
+ sdramc: sdramc@1400 {
compatible = "marvell,armada-xp-sdram-controller";
reg = <0x1400 0x500>;
};
- L2: l2-cache {
+ L2: l2-cache@8000 {
compatible = "marvell,aurora-system-cache";
reg = <0x08000 0x1000>;
cache-id-part = <0x100>;
@@ -85,29 +51,6 @@
wt-override;
};
- spi0: spi@10600 {
- compatible = "marvell,armada-xp-spi",
- "marvell,orion-spi";
- pinctrl-0 = <&spi0_pins>;
- pinctrl-names = "default";
- };
-
- spi1: spi@10680 {
- compatible = "marvell,armada-xp-spi",
- "marvell,orion-spi";
- };
-
-
- i2c0: i2c@11000 {
- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11000 0x100>;
- };
-
- i2c1: i2c@11100 {
- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11100 0x100>;
- };
-
uart2: serial@12200 {
compatible = "snps,dw-apb-uart";
pinctrl-0 = <&uart2_pins>;
@@ -132,7 +75,7 @@
status = "disabled";
};
- system-controller@18200 {
+ systemc: system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0x18200 0x500>;
};
@@ -150,7 +93,7 @@
#clock-cells = <1>;
};
- thermal@182b0 {
+ thermal: thermal@182b0 {
compatible = "marvell,armadaxp-thermal";
reg = <0x182b0 0x4
0x184d0 0x4>;
@@ -164,25 +107,9 @@
clocks = <&coreclk 1>;
};
- interrupt-controller@20a00 {
- reg = <0x20a00 0x2d0>, <0x21070 0x58>;
- };
-
- timer@20300 {
- compatible = "marvell,armada-xp-timer";
- clocks = <&coreclk 2>, <&refclk>;
- clock-names = "nbclk", "fixed";
- };
-
- watchdog@20300 {
- compatible = "marvell,armada-xp-wdt";
- clocks = <&coreclk 2>, <&refclk>;
- clock-names = "nbclk", "fixed";
- };
-
- cpurst@20800 {
- compatible = "marvell,armada-370-cpu-reset";
- reg = <0x20800 0x20>;
+ cpu-config@21000 {
+ compatible = "marvell,armada-xp-cpu-config";
+ reg = <0x21000 0x8>;
};
eth2: ethernet@30000 {
@@ -193,15 +120,7 @@
status = "disabled";
};
- usb@50000 {
- clocks = <&gateclk 18>;
- };
-
- usb@51000 {
- clocks = <&gateclk 19>;
- };
-
- usb@52000 {
+ usb2: usb@52000 {
compatible = "marvell,orion-ehci";
reg = <0x52000 0x500>;
interrupts = <47>;
@@ -209,7 +128,7 @@
status = "disabled";
};
- xor@60900 {
+ xor1: xor@60900 {
compatible = "marvell,orion-xor";
reg = <0x60900 0x100
0x60b00 0x100>;
@@ -237,7 +156,27 @@
compatible = "marvell,armada-xp-neta";
};
- xor@f0900 {
+ cesa: crypto@90000 {
+ compatible = "marvell,armada-xp-crypto";
+ reg = <0x90000 0x10000>;
+ reg-names = "regs";
+ interrupts = <48>, <49>;
+ clocks = <&gateclk 23>, <&gateclk 23>;
+ clock-names = "cesa0", "cesa1";
+ marvell,crypto-srams = <&crypto_sram0>,
+ <&crypto_sram1>;
+ marvell,crypto-sram-size = <0x800>;
+ };
+
+ bm: bm@c0000 {
+ compatible = "marvell,armada-380-neta-bm";
+ reg = <0xc0000 0xac>;
+ clocks = <&gateclk 13>;
+ internal-mem = <&bm_bppi>;
+ status = "disabled";
+ };
+
+ xor0: xor@f0900 {
compatible = "marvell,orion-xor";
reg = <0xF0900 0x100
0xF0B00 0x100>;
@@ -257,6 +196,35 @@
};
};
};
+
+ crypto_sram0: sa-sram0 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x09) 0 0x800>;
+ clocks = <&gateclk 23>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x09) 0 0x800>;
+ };
+
+ crypto_sram1: sa-sram1 {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x09, 0x05) 0 0x800>;
+ clocks = <&gateclk 23>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>;
+ };
+
+ bm_bppi: bm-bppi {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&gateclk 13>;
+ no-memory-wc;
+ status = "disabled";
+ };
};
clocks {
@@ -269,6 +237,44 @@
};
};
+&i2c0 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11000 0x100>;
+};
+
+&i2c1 {
+ compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+ reg = <0x11100 0x100>;
+};
+
+&mpic {
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+};
+
+&timer {
+ compatible = "marvell,armada-xp-timer";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+};
+
+&watchdog {
+ compatible = "marvell,armada-xp-wdt";
+ clocks = <&coreclk 2>, <&refclk>;
+ clock-names = "nbclk", "fixed";
+};
+
+&cpurst {
+ reg = <0x20800 0x20>;
+};
+
+&usb0 {
+ clocks = <&gateclk 18>;
+};
+
+&usb1 {
+ clocks = <&gateclk 19>;
+};
+
&pinctrl {
ge0_gmii_pins: ge0-gmii-pins {
marvell,pins =
@@ -309,6 +315,12 @@
marvell,function = "spi0";
};
+ spi1_pins: spi1-pins {
+ marvell,pins = "mpp13", "mpp14",
+ "mpp16", "mpp17";
+ marvell,function = "spi1";
+ };
+
uart2_pins: uart2-pins {
marvell,pins = "mpp42", "mpp43";
marvell,function = "uart2";
@@ -319,3 +331,15 @@
marvell,function = "uart3";
};
};
+
+&spi0 {
+ compatible = "marvell,armada-xp-spi", "marvell,orion-spi";
+ pinctrl-0 = <&spi0_pins>;
+ pinctrl-names = "default";
+};
+
+&spi1 {
+ compatible = "marvell,armada-xp-spi", "marvell,orion-spi";
+ pinctrl-0 = <&spi1_pins>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm/dts/at91-sama5d2_xplained.dts b/arch/arm/dts/at91-sama5d2_xplained.dts
index 33064b390a6..c0708feeb7b 100644
--- a/arch/arm/dts/at91-sama5d2_xplained.dts
+++ b/arch/arm/dts/at91-sama5d2_xplained.dts
@@ -110,7 +110,7 @@
u-boot,dm-pre-reloc;
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/at91-sama5d4_xplained.dts b/arch/arm/dts/at91-sama5d4_xplained.dts
index 58a0e60d184..7da5086865b 100644
--- a/arch/arm/dts/at91-sama5d4_xplained.dts
+++ b/arch/arm/dts/at91-sama5d4_xplained.dts
@@ -117,7 +117,7 @@
status = "okay";
spi_flash@0 {
u-boot,dm-pre-reloc;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/at91-sama5d4ek.dts b/arch/arm/dts/at91-sama5d4ek.dts
index a5d75452cf3..c1d657814df 100644
--- a/arch/arm/dts/at91-sama5d4ek.dts
+++ b/arch/arm/dts/at91-sama5d4ek.dts
@@ -137,7 +137,7 @@
status = "okay";
spi_flash@0 {
u-boot,dm-pre-reloc;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/at91sam9n12ek.dts b/arch/arm/dts/at91sam9n12ek.dts
index 888bda15aae..64a7abf639f 100644
--- a/arch/arm/dts/at91sam9n12ek.dts
+++ b/arch/arm/dts/at91sam9n12ek.dts
@@ -112,7 +112,7 @@
status = "okay";
cs-gpios = <&pioA 14 0>, <0>, <0>, <0>;
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/at91sam9x5ek.dtsi b/arch/arm/dts/at91sam9x5ek.dtsi
index f2a532d605d..1f7f37b687c 100644
--- a/arch/arm/dts/at91sam9x5ek.dtsi
+++ b/arch/arm/dts/at91sam9x5ek.dtsi
@@ -121,7 +121,7 @@
status = "okay";
cs-gpios = <&pioA 14 0>, <0>, <0>, <0>;
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/bcm63158.dtsi b/arch/arm/dts/bcm63158.dtsi
index 6a3fbc90939..4f41f627387 100644
--- a/arch/arm/dts/bcm63158.dtsi
+++ b/arch/arm/dts/bcm63158.dtsi
@@ -98,5 +98,85 @@
compatible = "wdt-reboot";
wdt = <&wdt1>;
};
+
+ gpio0: gpio-controller@0xff800500 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800500 0x0 0x4>,
+ <0x0 0xff800520 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio1: gpio-controller@0xff800504 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800504 0x0 0x4>,
+ <0x0 0xff800524 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio2: gpio-controller@0xff800508 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800508 0x0 0x4>,
+ <0x0 0xff800528 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio3: gpio-controller@0xff80050c {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff80050c 0x0 0x4>,
+ <0x0 0xff80052c 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio4: gpio-controller@0xff800510 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800510 0x0 0x4>,
+ <0x0 0xff800530 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio5: gpio-controller@0xff800514 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800514 0x0 0x4>,
+ <0x0 0xff800534 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio6: gpio-controller@0xff800518 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800518 0x0 0x4>,
+ <0x0 0xff800538 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio7: gpio-controller@0xff80051c {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff80051c 0x0 0x4>,
+ <0x0 0xff80053c 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/dts/bcm6858.dtsi b/arch/arm/dts/bcm6858.dtsi
index 23b80c67a64..5d5e64db081 100644
--- a/arch/arm/dts/bcm6858.dtsi
+++ b/arch/arm/dts/bcm6858.dtsi
@@ -98,5 +98,85 @@
compatible = "wdt-reboot";
wdt = <&wdt1>;
};
+
+ gpio0: gpio-controller@0xff800500 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800500 0x0 0x4>,
+ <0x0 0xff800520 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio1: gpio-controller@0xff800504 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800504 0x0 0x4>,
+ <0x0 0xff800524 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio2: gpio-controller@0xff800508 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800508 0x0 0x4>,
+ <0x0 0xff800528 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio3: gpio-controller@0xff80050c {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff80050c 0x0 0x4>,
+ <0x0 0xff80052c 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio4: gpio-controller@0xff800510 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800510 0x0 0x4>,
+ <0x0 0xff800530 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio5: gpio-controller@0xff800514 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800514 0x0 0x4>,
+ <0x0 0xff800534 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio6: gpio-controller@0xff800518 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff800518 0x0 0x4>,
+ <0x0 0xff800538 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio7: gpio-controller@0xff80051c {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x0 0xff80051c 0x0 0x4>,
+ <0x0 0xff80053c 0x0 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/dts/bcm963158.dts b/arch/arm/dts/bcm963158.dts
index dc5afb5a24a..b5c825b052b 100644
--- a/arch/arm/dts/bcm963158.dts
+++ b/arch/arm/dts/bcm963158.dts
@@ -29,3 +29,35 @@
u-boot,dm-pre-reloc;
status = "okay";
};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio2 {
+ status = "okay";
+};
+
+&gpio3 {
+ status = "okay";
+};
+
+&gpio4 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&gpio6 {
+ status = "okay";
+};
+
+&gpio7 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/bcm968580xref.dts b/arch/arm/dts/bcm968580xref.dts
index 0c59f94710c..15febb030f1 100644
--- a/arch/arm/dts/bcm968580xref.dts
+++ b/arch/arm/dts/bcm968580xref.dts
@@ -29,3 +29,35 @@
u-boot,dm-pre-reloc;
status = "okay";
};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio2 {
+ status = "okay";
+};
+
+&gpio3 {
+ status = "okay";
+};
+
+&gpio4 {
+ status = "okay";
+};
+
+&gpio5 {
+ status = "okay";
+};
+
+&gpio6 {
+ status = "okay";
+};
+
+&gpio7 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/bk4r1.dts b/arch/arm/dts/bk4r1.dts
index 866b80e0b0b..16c60268fba 100644
--- a/arch/arm/dts/bk4r1.dts
+++ b/arch/arm/dts/bk4r1.dts
@@ -32,7 +32,7 @@
qflash0: spi_flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <108000000>;
reg = <0>;
};
@@ -40,7 +40,7 @@
qflash1: spi_flash@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <66000000>;
reg = <1>;
};
diff --git a/arch/arm/dts/da850-evm-u-boot.dtsi b/arch/arm/dts/da850-evm-u-boot.dtsi
index ab9368b9d3a..1683f3472e4 100644
--- a/arch/arm/dts/da850-evm-u-boot.dtsi
+++ b/arch/arm/dts/da850-evm-u-boot.dtsi
@@ -13,7 +13,7 @@
};
&flash {
- compatible = "m25p64", "spi-flash";
+ compatible = "m25p64", "jedec,spi-nor";
};
&mmc0 {
diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts
index 7587dc0ff24..e41f2d3041e 100644
--- a/arch/arm/dts/exynos5250-snow.dts
+++ b/arch/arm/dts/exynos5250-snow.dts
@@ -232,7 +232,7 @@
spi@12d30000 {
spi-max-frequency = <50000000>;
firmware_storage_spi: flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
};
};
diff --git a/arch/arm/dts/exynos5250-spring.dts b/arch/arm/dts/exynos5250-spring.dts
index c7553208ade..77e7a6b9e45 100644
--- a/arch/arm/dts/exynos5250-spring.dts
+++ b/arch/arm/dts/exynos5250-spring.dts
@@ -149,7 +149,7 @@
spi@12d30000 {
spi-max-frequency = <50000000>;
firmware_storage_spi: flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
};
};
diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts
index 4a96a18110a..a68c3b51746 100644
--- a/arch/arm/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/dts/exynos5420-peach-pit.dts
@@ -257,7 +257,7 @@
spi@12d30000 { /* spi1 */
spi-max-frequency = <50000000>;
firmware_storage_spi: flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
/*
diff --git a/arch/arm/dts/fsl-ls1012a-2g5rdb.dts b/arch/arm/dts/fsl-ls1012a-2g5rdb.dts
index cdd4ce45aaf..fecef88e080 100644
--- a/arch/arm/dts/fsl-ls1012a-2g5rdb.dts
+++ b/arch/arm/dts/fsl-ls1012a-2g5rdb.dts
@@ -27,7 +27,7 @@
qflash0: s25fl128s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls1012a-frdm.dtsi b/arch/arm/dts/fsl-ls1012a-frdm.dtsi
index 9cb3de1d40c..a357793bfac 100644
--- a/arch/arm/dts/fsl-ls1012a-frdm.dtsi
+++ b/arch/arm/dts/fsl-ls1012a-frdm.dtsi
@@ -21,7 +21,7 @@
qflash0: s25fl128s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls1012a-frwy.dts b/arch/arm/dts/fsl-ls1012a-frwy.dts
index a56909ab92f..7242af51e43 100644
--- a/arch/arm/dts/fsl-ls1012a-frwy.dts
+++ b/arch/arm/dts/fsl-ls1012a-frwy.dts
@@ -28,7 +28,7 @@
qflash0: w25q16dw@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls1012a-qds.dtsi b/arch/arm/dts/fsl-ls1012a-qds.dtsi
index 661af0e49e6..a330597b6c0 100644
--- a/arch/arm/dts/fsl-ls1012a-qds.dtsi
+++ b/arch/arm/dts/fsl-ls1012a-qds.dtsi
@@ -20,7 +20,7 @@
dflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <1000000>; /* input clock */
};
@@ -28,7 +28,7 @@
dflash1: sst25wf040b {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
reg = <1>;
};
@@ -36,7 +36,7 @@
dflash2: en25s64 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
reg = <2>;
};
@@ -49,7 +49,7 @@
qflash0: s25fl128s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls1012a-rdb.dtsi b/arch/arm/dts/fsl-ls1012a-rdb.dtsi
index 757e2eb3519..f053e789c25 100644
--- a/arch/arm/dts/fsl-ls1012a-rdb.dtsi
+++ b/arch/arm/dts/fsl-ls1012a-rdb.dtsi
@@ -21,7 +21,7 @@
qflash0: s25fl128s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls1043a-qds.dtsi b/arch/arm/dts/fsl-ls1043a-qds.dtsi
index 3841aee11e4..70e1a6a53f1 100644
--- a/arch/arm/dts/fsl-ls1043a-qds.dtsi
+++ b/arch/arm/dts/fsl-ls1043a-qds.dtsi
@@ -24,7 +24,7 @@
dflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <1000000>; /* input clock */
spi-cpol;
spi-cpha;
@@ -34,7 +34,7 @@
dflash1: sst25wf040b {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
spi-cpol;
spi-cpha;
@@ -44,7 +44,7 @@
dflash2: en25s64 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
spi-cpol;
spi-cpha;
@@ -59,7 +59,7 @@
qflash0: s25fl128s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls1043a-rdb.dts b/arch/arm/dts/fsl-ls1043a-rdb.dts
index c42cad70348..721b158169d 100644
--- a/arch/arm/dts/fsl-ls1043a-rdb.dts
+++ b/arch/arm/dts/fsl-ls1043a-rdb.dts
@@ -26,7 +26,7 @@
dspiflash: n25q12a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <1000000>; /* input clock */
};
diff --git a/arch/arm/dts/fsl-ls1046a-qds.dtsi b/arch/arm/dts/fsl-ls1046a-qds.dtsi
index ada8a859b10..c95f44fc361 100644
--- a/arch/arm/dts/fsl-ls1046a-qds.dtsi
+++ b/arch/arm/dts/fsl-ls1046a-qds.dtsi
@@ -24,7 +24,7 @@
dflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <1000000>; /* input clock */
spi-cpol;
spi-cpha;
@@ -34,7 +34,7 @@
dflash1: sst25wf040b {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
spi-cpol;
spi-cpha;
@@ -44,7 +44,7 @@
dflash2: en25s64 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
spi-cpol;
spi-cpha;
@@ -59,7 +59,7 @@
qflash0: s25fl128s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls1046a-rdb.dts b/arch/arm/dts/fsl-ls1046a-rdb.dts
index ba30fd262ac..a05c9e9b9ea 100644
--- a/arch/arm/dts/fsl-ls1046a-rdb.dts
+++ b/arch/arm/dts/fsl-ls1046a-rdb.dts
@@ -26,7 +26,7 @@
qflash0: s25fs512s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
@@ -34,7 +34,7 @@
qflash1: s25fs512s@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <1>;
};
diff --git a/arch/arm/dts/fsl-ls1088a-qds.dts b/arch/arm/dts/fsl-ls1088a-qds.dts
index 4ea451c1b6a..8fbb52f0e09 100644
--- a/arch/arm/dts/fsl-ls1088a-qds.dts
+++ b/arch/arm/dts/fsl-ls1088a-qds.dts
@@ -62,7 +62,7 @@
dflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <1000000>; /* input clock */
};
@@ -70,7 +70,7 @@
dflash1: sst25wf040b {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
reg = <1>;
};
@@ -78,7 +78,7 @@
dflash2: en25s64 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3500000>;
reg = <2>;
};
@@ -91,7 +91,7 @@
qflash0: s25fs512s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
@@ -99,7 +99,7 @@
qflash1: s25fs512s@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <1>;
};
diff --git a/arch/arm/dts/fsl-ls1088a-rdb.dts b/arch/arm/dts/fsl-ls1088a-rdb.dts
index f30bbb7247c..765d1e3d74e 100644
--- a/arch/arm/dts/fsl-ls1088a-rdb.dts
+++ b/arch/arm/dts/fsl-ls1088a-rdb.dts
@@ -24,7 +24,7 @@
qflash0: s25fs512s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
@@ -32,7 +32,7 @@
qflash1: s25fs512s@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <1>;
};
diff --git a/arch/arm/dts/fsl-ls2080a-qds.dts b/arch/arm/dts/fsl-ls2080a-qds.dts
index 39fbc1b79c1..2a0a5280d07 100644
--- a/arch/arm/dts/fsl-ls2080a-qds.dts
+++ b/arch/arm/dts/fsl-ls2080a-qds.dts
@@ -26,7 +26,7 @@
dflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3000000>;
spi-cpol;
spi-cpha;
@@ -35,7 +35,7 @@
dflash1: sst25wf040b {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3000000>;
spi-cpol;
spi-cpha;
@@ -44,7 +44,7 @@
dflash2: en25s64 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3000000>;
spi-cpol;
spi-cpha;
@@ -59,7 +59,7 @@
qflash0: s25fs256s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/fsl-ls2080a-rdb.dts b/arch/arm/dts/fsl-ls2080a-rdb.dts
index e7567cfa231..0a87caeba96 100644
--- a/arch/arm/dts/fsl-ls2080a-rdb.dts
+++ b/arch/arm/dts/fsl-ls2080a-rdb.dts
@@ -25,7 +25,7 @@
dflash0: n25q512a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3000000>;
spi-cpol;
spi-cpha;
diff --git a/arch/arm/dts/fsl-ls2081a-rdb.dts b/arch/arm/dts/fsl-ls2081a-rdb.dts
index 73e2683d59b..b0b7ef08a02 100644
--- a/arch/arm/dts/fsl-ls2081a-rdb.dts
+++ b/arch/arm/dts/fsl-ls2081a-rdb.dts
@@ -28,7 +28,7 @@
dflash0: n25q512a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3000000>;
spi-cpol;
spi-cpha;
@@ -43,7 +43,7 @@
qflash0: s25fs512s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
@@ -51,7 +51,7 @@
qflash1: s25fs512s@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <1>;
};
diff --git a/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts b/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts
index b6d4f0f6af1..bf97d138fc2 100644
--- a/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts
+++ b/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts
@@ -28,7 +28,7 @@
dflash0: n25q512a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <3000000>;
spi-cpol;
spi-cpha;
@@ -43,7 +43,7 @@
qflash0: s25fs512s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
@@ -51,7 +51,7 @@
qflash1: s25fs512s@1 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <1>;
};
diff --git a/arch/arm/dts/imx53-kp-u-boot.dtsi b/arch/arm/dts/imx53-kp-u-boot.dtsi
new file mode 100644
index 00000000000..acab9b3657e
--- /dev/null
+++ b/arch/arm/dts/imx53-kp-u-boot.dtsi
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2019
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ *
+ * SPDX-License-Identifier: GPL-2.0+ or X11
+ */
+
+&pmic {
+ u-boot,i2c-transaction-bytes = <3>;
+};
diff --git a/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi b/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi
index f5c68d707c3..549461df71e 100644
--- a/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi
+++ b/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi
@@ -7,10 +7,10 @@
num-cs = <2>;
flash0: n25q256a@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
};
flash1: n25q256a@1 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
};
};
diff --git a/arch/arm/dts/imx6sx-sdb-u-boot.dtsi b/arch/arm/dts/imx6sx-sdb-u-boot.dtsi
index 8e592cded9f..8f9236da0f3 100644
--- a/arch/arm/dts/imx6sx-sdb-u-boot.dtsi
+++ b/arch/arm/dts/imx6sx-sdb-u-boot.dtsi
@@ -7,10 +7,10 @@
num-cs = <2>;
flash0: n25q256a@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
};
flash1: n25q256a@1 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
};
};
diff --git a/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi b/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi
index db640d6e674..77cb461a215 100644
--- a/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi
@@ -5,6 +5,6 @@
&qspi {
flash0: n25q256a@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
};
}; \ No newline at end of file
diff --git a/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi b/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi
index db640d6e674..77cb461a215 100644
--- a/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi
@@ -5,6 +5,6 @@
&qspi {
flash0: n25q256a@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
};
}; \ No newline at end of file
diff --git a/arch/arm/dts/imx6ull-14x14-evk.dts b/arch/arm/dts/imx6ull-14x14-evk.dts
index 8a1b67d6bbf..9ebcfe1f4ea 100644
--- a/arch/arm/dts/imx6ull-14x14-evk.dts
+++ b/arch/arm/dts/imx6ull-14x14-evk.dts
@@ -455,7 +455,7 @@
#address-cells = <1>;
#size-cells = <1>;
/* compatible = "micron,n25q256a"; */
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <29000000>;
spi-nor,ddr-quad-read-dummy = <6>;
reg = <0>;
diff --git a/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi b/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi
index 2ce6961096f..585af6d211f 100644
--- a/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi
+++ b/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi
@@ -5,6 +5,6 @@
&qspi1 {
flash0: mx25l51245g@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
};
};
diff --git a/arch/arm/dts/keystone-k2e-evm.dts b/arch/arm/dts/keystone-k2e-evm.dts
index 3be8b532525..9288df21ce1 100644
--- a/arch/arm/dts/keystone-k2e-evm.dts
+++ b/arch/arm/dts/keystone-k2e-evm.dts
@@ -123,7 +123,7 @@
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11", "spi-flash";
+ compatible = "Micron,n25q128a11", "jedec,spi-nor";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/keystone-k2g-evm.dts b/arch/arm/dts/keystone-k2g-evm.dts
index 4820c7e50da..7c5deef8083 100644
--- a/arch/arm/dts/keystone-k2g-evm.dts
+++ b/arch/arm/dts/keystone-k2g-evm.dts
@@ -74,7 +74,7 @@
spi_nor: flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
m25p,fast-read;
reg = <0>;
@@ -96,7 +96,7 @@
status = "okay";
flash0: m25p80@0 {
- compatible = "s25fl512s","spi-flash";
+ compatible = "s25fl512s","jedec,spi-nor";
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
diff --git a/arch/arm/dts/keystone-k2g-ice.dts b/arch/arm/dts/keystone-k2g-ice.dts
index b67332fed5b..ecca2dfac1a 100644
--- a/arch/arm/dts/keystone-k2g-ice.dts
+++ b/arch/arm/dts/keystone-k2g-ice.dts
@@ -39,7 +39,7 @@
status = "okay";
flash0: m25p80@0 {
- compatible = "s25fl256s1", "spi-flash";
+ compatible = "s25fl256s1", "jedec,spi-nor";
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
diff --git a/arch/arm/dts/keystone-k2hk-evm.dts b/arch/arm/dts/keystone-k2hk-evm.dts
index 76a675f1e46..84c58d75ada 100644
--- a/arch/arm/dts/keystone-k2hk-evm.dts
+++ b/arch/arm/dts/keystone-k2hk-evm.dts
@@ -151,7 +151,7 @@
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11", "spi-flash";
+ compatible = "Micron,n25q128a11", "jedec,spi-nor";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/keystone-k2l-evm.dts b/arch/arm/dts/keystone-k2l-evm.dts
index b5c56176bf6..91cefdf2aa9 100644
--- a/arch/arm/dts/keystone-k2l-evm.dts
+++ b/arch/arm/dts/keystone-k2l-evm.dts
@@ -100,7 +100,7 @@
nor_flash: n25q128a11@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "Micron,n25q128a11", "spi-flash";
+ compatible = "Micron,n25q128a11", "jedec,spi-nor";
spi-max-frequency = <54000000>;
m25p,fast-read;
reg = <0>;
diff --git a/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts b/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts
index e5b1efa1415..4ae74f4316e 100644
--- a/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts
+++ b/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts
@@ -78,7 +78,7 @@
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p128", "jedec,spi-nor", "spi-flash";
+ compatible = "st,m25p128", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
mode = <0>;
diff --git a/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts b/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts
index c2344499362..6e3418f2461 100644
--- a/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts
+++ b/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts
@@ -92,7 +92,7 @@
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p128", "jedec,spi-nor", "spi-flash";
+ compatible = "st,m25p128", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
mode = <0>;
diff --git a/arch/arm/dts/kirkwood-dreamplug.dts b/arch/arm/dts/kirkwood-dreamplug.dts
index ccd74dd7fb3..e9eea22fc93 100644
--- a/arch/arm/dts/kirkwood-dreamplug.dts
+++ b/arch/arm/dts/kirkwood-dreamplug.dts
@@ -47,7 +47,7 @@
m25p40@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mxicy,mx25l1606e", "jedec,spi-nor", "spi-flash";
+ compatible = "mxicy,mx25l1606e", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
mode = <0>;
diff --git a/arch/arm/dts/kirkwood-lsxl.dtsi b/arch/arm/dts/kirkwood-lsxl.dtsi
index 479a750d1d8..c99c0da0937 100644
--- a/arch/arm/dts/kirkwood-lsxl.dtsi
+++ b/arch/arm/dts/kirkwood-lsxl.dtsi
@@ -79,7 +79,7 @@
m25p40@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "m25p40", "jedec,spi-nor", "spi-flash";
+ compatible = "m25p40", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <25000000>;
mode = <0>;
diff --git a/arch/arm/dts/kirkwood-netxbig.dtsi b/arch/arm/dts/kirkwood-netxbig.dtsi
index 135ac8021c8..b5737026e24 100644
--- a/arch/arm/dts/kirkwood-netxbig.dtsi
+++ b/arch/arm/dts/kirkwood-netxbig.dtsi
@@ -32,7 +32,7 @@
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mxicy,mx25l4005a", "jedec,spi-nor", "spi-flash";
+ compatible = "mxicy,mx25l4005a", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <20000000>;
mode = <0>;
diff --git a/arch/arm/dts/kirkwood-ns2-common.dtsi b/arch/arm/dts/kirkwood-ns2-common.dtsi
index f997bb4df20..51530ea8662 100644
--- a/arch/arm/dts/kirkwood-ns2-common.dtsi
+++ b/arch/arm/dts/kirkwood-ns2-common.dtsi
@@ -30,7 +30,7 @@
flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "mxicy,mx25l4005a", "jedec,spi-nor", "spi-flash";
+ compatible = "mxicy,mx25l4005a", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <20000000>;
mode = <0>;
diff --git a/arch/arm/dts/kirkwood-synology.dtsi b/arch/arm/dts/kirkwood-synology.dtsi
index b80d8ee3709..c97ed29a0a0 100644
--- a/arch/arm/dts/kirkwood-synology.dtsi
+++ b/arch/arm/dts/kirkwood-synology.dtsi
@@ -201,7 +201,7 @@
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "st,m25p80", "jedec,spi-nor", "spi-flash";
+ compatible = "st,m25p80", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <20000000>;
mode = <0>;
diff --git a/arch/arm/dts/ls1021a-iot.dtsi b/arch/arm/dts/ls1021a-iot.dtsi
index d27b6014207..44dd9b61d3f 100644
--- a/arch/arm/dts/ls1021a-iot.dtsi
+++ b/arch/arm/dts/ls1021a-iot.dtsi
@@ -27,7 +27,7 @@
qflash0: n25q128a13@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
@@ -40,7 +40,7 @@
dspiflash: at26df081a@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <16000000>;
spi-cpol;
spi-cpha;
diff --git a/arch/arm/dts/ls1021a-qds.dtsi b/arch/arm/dts/ls1021a-qds.dtsi
index f7783e51653..b12102abfa3 100644
--- a/arch/arm/dts/ls1021a-qds.dtsi
+++ b/arch/arm/dts/ls1021a-qds.dtsi
@@ -43,7 +43,7 @@
qflash0: s25fl128s@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/ls1021a-twr.dtsi b/arch/arm/dts/ls1021a-twr.dtsi
index 928e1002585..5d3275ced91 100644
--- a/arch/arm/dts/ls1021a-twr.dtsi
+++ b/arch/arm/dts/ls1021a-twr.dtsi
@@ -30,7 +30,7 @@
qflash0: n25q128a13@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
};
@@ -43,7 +43,7 @@
dspiflash: at26df081a@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <16000000>;
spi-cpol;
spi-cpha;
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
index 95d10aa6d32..4612218a1eb 100644
--- a/arch/arm/dts/mt7629-rfb.dts
+++ b/arch/arm/dts/mt7629-rfb.dts
@@ -62,7 +62,7 @@
status = "okay";
spi-flash@0{
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
u-boot,dm-pre-reloc;
};
diff --git a/arch/arm/dts/omap5-u-boot.dtsi b/arch/arm/dts/omap5-u-boot.dtsi
index 54a7285e6e1..1b1d765fae0 100644
--- a/arch/arm/dts/omap5-u-boot.dtsi
+++ b/arch/arm/dts/omap5-u-boot.dtsi
@@ -68,7 +68,7 @@
u-boot,dm-spl;
m25p80@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
u-boot,dm-spl;
};
};
diff --git a/arch/arm/dts/r8a77970-eagle-u-boot.dts b/arch/arm/dts/r8a77970-eagle-u-boot.dts
index 5b17f1d1f0b..eb868eda414 100644
--- a/arch/arm/dts/r8a77970-eagle-u-boot.dts
+++ b/arch/arm/dts/r8a77970-eagle-u-boot.dts
@@ -44,7 +44,7 @@
flash0: spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "s25fs512s", "spi-flash", "jedec,spi-nor";
+ compatible = "s25fs512s", "jedec,spi-nor";
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
diff --git a/arch/arm/dts/rk3288-veyron.dtsi b/arch/arm/dts/rk3288-veyron.dtsi
index 49ba3f3f143..916dd486de0 100644
--- a/arch/arm/dts/rk3288-veyron.dtsi
+++ b/arch/arm/dts/rk3288-veyron.dtsi
@@ -307,7 +307,7 @@
spi_flash: spiflash@0 {
u-boot,dm-pre-reloc;
- compatible = "spidev", "spi-flash";
+ compatible = "spidev", "jedec,spi-nor";
spi-max-frequency = <20000000>; /* Reduce for Dediprog em100 pro */
reg = <0>;
};
diff --git a/arch/arm/dts/rk3368-lion.dts b/arch/arm/dts/rk3368-lion.dts
index 5e578b175b5..28145420837 100644
--- a/arch/arm/dts/rk3368-lion.dts
+++ b/arch/arm/dts/rk3368-lion.dts
@@ -185,7 +185,7 @@
#size-cells = <0>;
spiflash: w25q32dw@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <49500000>;
spi-cpol;
diff --git a/arch/arm/dts/rk3399-gru.dtsi b/arch/arm/dts/rk3399-gru.dtsi
index df19263accb..4cdb4320b76 100644
--- a/arch/arm/dts/rk3399-gru.dtsi
+++ b/arch/arm/dts/rk3399-gru.dtsi
@@ -552,7 +552,7 @@ ap_i2c_audio: &i2c8 {
spi_flash: spiflash@0 {
u-boot,dm-pre-reloc;
- compatible = "jedec,spi-nor", "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
/* May run faster once verified. */
diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi
index 8304f67192c..aec13a28f1a 100644
--- a/arch/arm/dts/rk3399-puma.dtsi
+++ b/arch/arm/dts/rk3399-puma.dtsi
@@ -658,7 +658,7 @@
spiflash: w25q32dw@0 {
u-boot,dm-pre-reloc;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <49500000>;
spi-cpol;
diff --git a/arch/arm/dts/rv1108-evb.dts b/arch/arm/dts/rv1108-evb.dts
index ccb9969da0e..c91776bc106 100644
--- a/arch/arm/dts/rv1108-evb.dts
+++ b/arch/arm/dts/rv1108-evb.dts
@@ -45,7 +45,7 @@
&sfc {
status = "okay";
flash@0 {
- compatible = "gd25q256","spi-flash";
+ compatible = "gd25q256","jedec,spi-nor";
reg = <0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
diff --git a/arch/arm/dts/sama5d27_som1.dtsi b/arch/arm/dts/sama5d27_som1.dtsi
index 9efcf635ad5..ea7540bcfcf 100644
--- a/arch/arm/dts/sama5d27_som1.dtsi
+++ b/arch/arm/dts/sama5d27_som1.dtsi
@@ -66,7 +66,7 @@
u-boot,dm-pre-reloc;
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
spi-rx-bus-width = <4>;
diff --git a/arch/arm/dts/sama5d3xmb.dtsi b/arch/arm/dts/sama5d3xmb.dtsi
index f9ef905ff54..c75b76aef2a 100644
--- a/arch/arm/dts/sama5d3xmb.dtsi
+++ b/arch/arm/dts/sama5d3xmb.dtsi
@@ -35,7 +35,7 @@
u-boot,dm-pre-reloc;
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
u-boot,dm-pre-reloc;
diff --git a/arch/arm/dts/sama5d3xmb_cmp.dtsi b/arch/arm/dts/sama5d3xmb_cmp.dtsi
index 9792b2a9d08..5566fde5148 100644
--- a/arch/arm/dts/sama5d3xmb_cmp.dtsi
+++ b/arch/arm/dts/sama5d3xmb_cmp.dtsi
@@ -32,7 +32,7 @@
dmas = <0>, <0>; /* Do not use DMA for spi0 */
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
};
diff --git a/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi
index c44d1ee2fa1..e75f2902c54 100644
--- a/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi
@@ -30,7 +30,7 @@
};
&flash {
- compatible = "n25q00", "spi-flash";
+ compatible = "n25q00", "jedec,spi-nor";
u-boot,dm-pre-reloc;
};
diff --git a/arch/arm/dts/socfpga_cyclone5_is1.dts b/arch/arm/dts/socfpga_cyclone5_is1.dts
index b7054bfd5af..93e4d45ad2b 100644
--- a/arch/arm/dts/socfpga_cyclone5_is1.dts
+++ b/arch/arm/dts/socfpga_cyclone5_is1.dts
@@ -91,7 +91,7 @@
u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <1>;
- compatible = "n25q00", "spi-flash";
+ compatible = "n25q00", "jedec,spi-nor";
reg = <0>; /* chip select */
spi-max-frequency = <100000000>;
m25p,fast-read;
diff --git a/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi
index 9436e0fa8b1..2fafd7e399d 100644
--- a/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi
@@ -34,7 +34,7 @@
};
&flash0 {
- compatible = "n25q00", "spi-flash";
+ compatible = "n25q00", "jedec,spi-nor";
u-boot,dm-pre-reloc;
partition@qspi-boot {
diff --git a/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi
index 648f1bd01d7..7ef30531f4a 100644
--- a/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi
@@ -30,7 +30,7 @@
};
&flash {
- compatible = "n25q00", "spi-flash";
+ compatible = "n25q00", "jedec,spi-nor";
u-boot,dm-pre-reloc;
};
diff --git a/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi
index 31bd1dba0ff..1003115cead 100644
--- a/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi
@@ -30,7 +30,7 @@
};
&flash {
- compatible = "n25q256a", "spi-flash";
+ compatible = "n25q256a", "jedec,spi-nor";
u-boot,dm-pre-reloc;
};
diff --git a/arch/arm/dts/socfpga_cyclone5_sr1500.dts b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
index 6a6c29be79b..1a18c4f3baf 100644
--- a/arch/arm/dts/socfpga_cyclone5_sr1500.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
@@ -99,7 +99,7 @@
u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <1>;
- compatible = "n25q00", "spi-flash";
+ compatible = "n25q00", "jedec,spi-nor";
reg = <0>; /* chip select */
spi-max-frequency = <100000000>;
m25p,fast-read;
diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
index 360b946ba23..e05ca8279a9 100644
--- a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
@@ -29,11 +29,11 @@
u-boot,dm-pre-reloc;
n25q128@0 {
- compatible = "n25q128", "spi-flash";
+ compatible = "n25q128", "jedec,spi-nor";
u-boot,dm-pre-reloc;
};
n25q00@1 {
- compatible = "n25q00", "spi-flash";
+ compatible = "n25q00", "jedec,spi-nor";
u-boot,dm-pre-reloc;
};
};
diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts
index 7ef33d63813..babd37f1c11 100644
--- a/arch/arm/dts/stm32f746-disco.dts
+++ b/arch/arm/dts/stm32f746-disco.dts
@@ -297,7 +297,7 @@
qflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "micron,n25q128a13", "spi-flash";
+ compatible = "micron,n25q128a13", "jedec,spi-nor";
spi-max-frequency = <108000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
diff --git a/arch/arm/dts/stm32f769-disco.dts b/arch/arm/dts/stm32f769-disco.dts
index 1e8ef742cea..a23d02d3008 100644
--- a/arch/arm/dts/stm32f769-disco.dts
+++ b/arch/arm/dts/stm32f769-disco.dts
@@ -246,7 +246,7 @@
qflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "micron,n25q128a13", "spi-flash";
+ compatible = "micron,n25q128a13", "jedec,spi-nor";
spi-max-frequency = <108000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
new file mode 100644
index 00000000000..7d9b95ccf16
--- /dev/null
+++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * STM32MP157C DK1/DK2 BOARD configuration
+ * 1x DDR3L 4Gb, 16-bit, 533MHz.
+ * Reference used NT5CC256M16DP-DI from NANYA
+ *
+ * DDR type / Platform DDR3/3L
+ * freq 533MHz
+ * width 16
+ * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G
+ * DDR density 4
+ * timing mode optimized
+ * Scheduling/QoS options : type = 2
+ * address mapping : RBC
+ * Tc > + 85C : N
+ */
+#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.43"
+#define DDR_MEM_SPEED 533
+#define DDR_MEM_SIZE 0x20000000
+
+#define DDR_MSTR 0x00041401
+#define DDR_MRCTRL0 0x00000010
+#define DDR_MRCTRL1 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00800000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00400010
+#define DDR_HWLPCTL 0x00000000
+#define DDR_RFSHCTL0 0x00210000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0081008B
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_DRAMTMG0 0x121B2414
+#define DDR_DRAMTMG1 0x000A041C
+#define DDR_DRAMTMG2 0x0608090F
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x08040608
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020002
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x00001005
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_ZQCTL0 0xC2000040
+#define DDR_DFITMG0 0x02060105
+#define DDR_DFITMG1 0x00000202
+#define DDR_DFILPCFG0 0x07000000
+#define DDR_DFIUPD0 0xC0400003
+#define DDR_DFIUPD1 0x00000000
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIPHYMSTR 0x00000000
+#define DDR_ADDRMAP1 0x00070707
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x1F000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x06060606
+#define DDR_ADDRMAP6 0x0F060606
+#define DDR_ADDRMAP9 0x00000000
+#define DDR_ADDRMAP10 0x00000000
+#define DDR_ADDRMAP11 0x00000000
+#define DDR_ODTCFG 0x06000600
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00000C01
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x01000001
+#define DDR_PERFLPR1 0x08000200
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000010
+#define DDR_PCFGR_0 0x00010000
+#define DDR_PCFGW_0 0x00000000
+#define DDR_PCFGQOS0_0 0x02100C03
+#define DDR_PCFGQOS1_0 0x00800100
+#define DDR_PCFGWQOS0_0 0x01100C03
+#define DDR_PCFGWQOS1_0 0x01000200
+#define DDR_PCFGR_1 0x00010000
+#define DDR_PCFGW_1 0x00000000
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
+#define DDR_PCFGWQOS1_1 0x01000200
+#define DDR_PGCR 0x01442E02
+#define DDR_PTR0 0x0022AA5B
+#define DDR_PTR1 0x04841104
+#define DDR_PTR2 0x042DA068
+#define DDR_ACIOCR 0x10400812
+#define DDR_DXCCR 0x00000C40
+#define DDR_DSGCR 0xF200001F
+#define DDR_DCR 0x0000000B
+#define DDR_DTPR0 0x38D488D0
+#define DDR_DTPR1 0x098B00D8
+#define DDR_DTPR2 0x10023600
+#define DDR_MR0 0x00000840
+#define DDR_MR1 0x00000000
+#define DDR_MR2 0x00000208
+#define DDR_MR3 0x00000000
+#define DDR_ODTCR 0x00010000
+#define DDR_ZQ0CR1 0x00000038
+#define DDR_DX0GCR 0x0000CE81
+#define DDR_DX0DLLCR 0x40000000
+#define DDR_DX0DQTR 0xFFFFFFFF
+#define DDR_DX0DQSTR 0x3DB02000
+#define DDR_DX1GCR 0x0000CE81
+#define DDR_DX1DLLCR 0x40000000
+#define DDR_DX1DQTR 0xFFFFFFFF
+#define DDR_DX1DQSTR 0x3DB02000
+#define DDR_DX2GCR 0x0000CE81
+#define DDR_DX2DLLCR 0x40000000
+#define DDR_DX2DQTR 0xFFFFFFFF
+#define DDR_DX2DQSTR 0x3DB02000
+#define DDR_DX3GCR 0x0000CE81
+#define DDR_DX3DLLCR 0x40000000
+#define DDR_DX3DQTR 0xFFFFFFFF
+#define DDR_DX3DQSTR 0x3DB02000
+
+#include "stm32mp15-ddr.dtsi"
diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi
index 85da5926551..c0698754861 100644
--- a/arch/arm/dts/stm32mp157-pinctrl.dtsi
+++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi
@@ -148,6 +148,13 @@
gpio-ranges = <&pinctrl 0 160 8>;
};
+ adc12_usb_pwr_pins_a: adc12-usb-pwr-pins-0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* ADC12 in18 */
+ <STM32_PINMUX('A', 5, ANALOG)>; /* ADC12 in19 */
+ };
+ };
+
cec_pins_a: cec-0 {
pins {
pinmux = <STM32_PINMUX('A', 15, AF4)>;
@@ -157,6 +164,52 @@
};
};
+ ethernet0_rgmii_pins_a: rgmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
+ <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <3>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */
+ <STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */
+ bias-disable;
+ };
+ };
+
+ ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
+ <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
+ <STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */
+ };
+ };
+
i2c1_pins_a: i2c1-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
@@ -187,6 +240,19 @@
};
};
+ m_can1_pins_a: m-can1-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
+ slew-rate = <1>;
+ drive-push-pull;
+ bias-disable;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */
+ bias-disable;
+ };
+ };
+
pwm2_pins_a: pwm2-0 {
pins {
pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
@@ -360,6 +426,21 @@
slew-rate = <0>;
};
};
+
+ spi1_pins_a: spi1-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */
+ <STM32_PINMUX('Z', 2, AF5)>; /* SPI1_MOSI */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('Z', 1, AF5)>; /* SPI1_MISO */
+ bias-disable;
+ };
+ };
};
};
};
diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp157-u-boot.dtsi
index 90d13f35c46..ab6f673ea24 100644
--- a/arch/arm/dts/stm32mp157-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157-u-boot.dtsi
@@ -17,6 +17,8 @@
gpio9 = &gpioj;
gpio10 = &gpiok;
gpio25 = &gpioz;
+ pinctrl0 = &pinctrl;
+ pinctrl1 = &pinctrl_z;
};
config {
@@ -39,6 +41,10 @@
};
};
+&bsec {
+ u-boot,dm-pre-reloc;
+};
+
&clk_hsi {
u-boot,dm-pre-reloc;
};
diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
new file mode 100644
index 00000000000..af7acfa0375
--- /dev/null
+++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright : STMicroelectronics 2018
+ */
+
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp157-u-boot.dtsi"
+#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi"
+
+/ {
+ aliases {
+ i2c3 = &i2c4;
+ mmc0 = &sdmmc1;
+ };
+ config {
+ u-boot,boot-led = "heartbeat";
+ u-boot,error-led = "error";
+ st,adc_usb_pd = <&adc1 18>, <&adc1 19>;
+ };
+ led {
+ red {
+ label = "error";
+ gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ status = "okay";
+ };
+
+ blue {
+ default-state = "on";
+ };
+ };
+};
+
+&adc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&adc12_usb_pwr_pins_a>;
+ vdd-supply = <&vdd>;
+ vdda-supply = <&vdd>;
+ vref-supply = <&vrefbuf>;
+ status = "okay";
+ adc1: adc@0 {
+ /*
+ * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19.
+ * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C:
+ * 5 * (56 + 47kOhms) * 5pF => 2.5us.
+ * Use arbitrary margin here (e.g. 5µs).
+ */
+ st,min-sample-time-nsecs = <5000>;
+ /* ANA0, ANA1, USB Type-C CC1 & CC2 */
+ st,adc-channels = <0 1 18 19>;
+ status = "okay";
+ };
+};
+
+&clk_hse {
+ st,digbypass;
+};
+
+&i2c4 {
+ u-boot,dm-pre-reloc;
+};
+
+&i2c4_pins_a {
+ u-boot,dm-pre-reloc;
+ pins {
+ u-boot,dm-pre-reloc;
+ };
+};
+
+&pmic {
+ u-boot,dm-pre-reloc;
+};
+
+&rcc {
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MCU_PLL3P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_DISABLED
+ >;
+
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 0 /*MCU*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 0 /*MCO2*/
+ >;
+
+ st,pkcs = <
+ CLK_CKPER_HSE
+ CLK_FMC_ACLK
+ CLK_QSPI_ACLK
+ CLK_ETH_DISABLED
+ CLK_SDMMC12_PLL4P
+ CLK_DSI_DSIPLL
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_SPI2S1_PLL3Q
+ CLK_SPI2S23_PLL3Q
+ CLK_SPI45_HSI
+ CLK_SPI6_HSI
+ CLK_I2C46_HSI
+ CLK_SDMMC3_PLL4P
+ CLK_USBO_USBPHY
+ CLK_ADC_CKPER
+ CLK_CEC_LSE
+ CLK_I2C12_HSI
+ CLK_I2C35_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ CLK_UART35_HSI
+ CLK_UART6_HSI
+ CLK_UART78_HSI
+ CLK_SPDIF_PLL4P
+ CLK_FDCAN_PLL4Q
+ CLK_SAI1_PLL3Q
+ CLK_SAI2_PLL3Q
+ CLK_SAI3_PLL3Q
+ CLK_SAI4_PLL3Q
+ CLK_RNG1_LSI
+ CLK_RNG2_LSI
+ CLK_LPTIM1_PCLK1
+ CLK_LPTIM23_PCLK3
+ CLK_LPTIM45_LSE
+ >;
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1: st,pll@0 {
+ cfg = < 2 80 0 0 0 PQR(1,0,0) >;
+ frac = < 0x800 >;
+ u-boot,dm-pre-reloc;
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+ pll2: st,pll@1 {
+ cfg = < 2 65 1 0 0 PQR(1,1,1) >;
+ frac = < 0x1400 >;
+ u-boot,dm-pre-reloc;
+ };
+
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
+ pll3: st,pll@2 {
+ cfg = < 1 33 1 16 36 PQR(1,1,1) >;
+ frac = < 0x1a04 >;
+ u-boot,dm-pre-reloc;
+ };
+
+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
+ pll4: st,pll@3 {
+ cfg = < 3 98 5 7 7 PQR(1,1,1) >;
+ u-boot,dm-pre-reloc;
+ };
+};
+
+&sdmmc1 {
+ u-boot,dm-spl;
+};
+
+&sdmmc1_b4_pins_a {
+ u-boot,dm-spl;
+ pins {
+ u-boot,dm-spl;
+ };
+};
+
+&uart4 {
+ u-boot,dm-pre-reloc;
+};
+
+&uart4_pins_a {
+ u-boot,dm-pre-reloc;
+ pins1 {
+ u-boot,dm-pre-reloc;
+ };
+ pins2 {
+ u-boot,dm-pre-reloc;
+ };
+};
+
+&usbotg_hs {
+ usb1600;
+ hnp-srp-disable;
+};
+
+&v3v3 {
+ regulator-always-on;
+};
diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts
new file mode 100644
index 00000000000..0882765d0c9
--- /dev/null
+++ b/arch/arm/dts/stm32mp157a-dk1.dts
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+
+#include "stm32mp157c.dtsi"
+#include "stm32mp157-pinctrl.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/mfd/st,stpmic1.h>
+
+/ {
+ model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
+ compatible = "st,stm32mp157a-dk1", "st,stm32mp157";
+
+ aliases {
+ ethernet0 = &ethernet0;
+ serial0 = &uart4;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@c0000000 {
+ reg = <0xc0000000 0x20000000>;
+ };
+
+ led {
+ compatible = "gpio-leds";
+ blue {
+ label = "heartbeat";
+ gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "off";
+ };
+ };
+};
+
+&ethernet0 {
+ status = "okay";
+ pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+ pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
+ pinctrl-names = "default", "sleep";
+ phy-mode = "rgmii";
+ max-speed = <1000>;
+ phy-handle = <&phy0>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+ /delete-property/dmas;
+ /delete-property/dma-names;
+
+ pmic: stpmic@33 {
+ compatible = "st,stpmic1";
+ reg = <0x33>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "okay";
+
+ st,main-control-register = <0x04>;
+ st,vin-control-register = <0xc0>;
+ st,usb-control-register = <0x20>;
+
+ regulators {
+ compatible = "st,stpmic1-regulators";
+
+ ldo1-supply = <&v3v3>;
+ ldo3-supply = <&vdd_ddr>;
+ ldo6-supply = <&v3v3>;
+ pwr_sw1-supply = <&bst_out>;
+ pwr_sw2-supply = <&bst_out>;
+
+ vddcore: buck1 {
+ regulator-name = "vddcore";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd_ddr: buck2 {
+ regulator-name = "vdd_ddr";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ vdd: buck3 {
+ regulator-name = "vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ st,mask-reset;
+ regulator-initial-mode = <0>;
+ regulator-over-current-protection;
+ };
+
+ v3v3: buck4 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ regulator-initial-mode = <0>;
+ };
+
+ v1v8_audio: ldo1 {
+ regulator-name = "v1v8_audio";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ interrupts = <IT_CURLIM_LDO1 0>;
+ };
+
+ v3v3_hdmi: ldo2 {
+ regulator-name = "v3v3_hdmi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ interrupts = <IT_CURLIM_LDO2 0>;
+ };
+
+ vtt_ddr: ldo3 {
+ regulator-name = "vtt_ddr";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <750000>;
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ vdd_usb: ldo4 {
+ regulator-name = "vdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ interrupts = <IT_CURLIM_LDO4 0>;
+ };
+
+ vdda: ldo5 {
+ regulator-name = "vdda";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ interrupts = <IT_CURLIM_LDO5 0>;
+ regulator-boot-on;
+ };
+
+ v1v2_hdmi: ldo6 {
+ regulator-name = "v1v2_hdmi";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ interrupts = <IT_CURLIM_LDO6 0>;
+
+ };
+
+ vref_ddr: vref_ddr {
+ regulator-name = "vref_ddr";
+ regulator-always-on;
+ regulator-over-current-protection;
+ };
+
+ bst_out: boost {
+ regulator-name = "bst_out";
+ interrupts = <IT_OCP_BOOST 0>;
+ };
+
+ vbus_otg: pwr_sw1 {
+ regulator-name = "vbus_otg";
+ interrupts = <IT_OCP_OTG 0>;
+ regulator-active-discharge;
+ };
+
+ vbus_sw: pwr_sw2 {
+ regulator-name = "vbus_sw";
+ interrupts = <IT_OCP_SWOUT 0>;
+ regulator-active-discharge;
+ };
+ };
+
+ onkey {
+ compatible = "st,stpmic1-onkey";
+ interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 1>;
+ interrupt-names = "onkey-falling", "onkey-rising";
+ status = "okay";
+ };
+
+ watchdog {
+ compatible = "st,stpmic1-wdt";
+ status = "disabled";
+ };
+ };
+};
+
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&pwr {
+ pwr-supply = <&vdd>;
+};
+
+&rng1 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_a>;
+ broken-cd;
+ st,neg-edge;
+ bus-width = <4>;
+ vmmc-supply = <&v3v3>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ status = "okay";
+};
+
+&usbh_ehci {
+ phys = <&usbphyc_port0>;
+ phy-names = "usb";
+ status = "okay";
+};
+
+&usbphyc {
+ vdd3v3-supply = <&vdd_usb>;
+ status = "okay";
+};
+
+&vrefbuf {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ vdda-supply = <&vdd>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
new file mode 100644
index 00000000000..06ef3a4095f
--- /dev/null
+++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright : STMicroelectronics 2018
+ */
+
+#include "stm32mp157a-dk1-u-boot.dtsi"
diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts
new file mode 100644
index 00000000000..9a81d2d4728
--- /dev/null
+++ b/arch/arm/dts/stm32mp157c-dk2.dts
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+
+#include "stm32mp157a-dk1.dts"
+
+/ {
+ model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
+ compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
+};
+
+&dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ phy-dsi-supply = <&reg18>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi_in: endpoint {
+ remote-endpoint = <&ltdc_ep1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dsi_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+
+ panel@0 {
+ compatible = "orisetech,otm8009a";
+ reg = <0>;
+ reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+&ltdc {
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ltdc_ep1_out: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&dsi_in>;
+ };
+ };
+};
diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
index 70bbf667042..55f99037b26 100644
--- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
@@ -9,9 +9,14 @@
/ {
aliases {
+ i2c3 = &i2c4;
mmc0 = &sdmmc1;
mmc1 = &sdmmc2;
- i2c3 = &i2c4;
+ };
+
+ config {
+ st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
+ st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
};
led {
@@ -43,14 +48,8 @@
st,digbypass;
};
-&uart4_pins_a {
+&i2c4 {
u-boot,dm-pre-reloc;
- pins1 {
- u-boot,dm-pre-reloc;
- };
- pins2 {
- u-boot,dm-pre-reloc;
- };
};
&i2c4_pins_a {
@@ -60,14 +59,6 @@
};
};
-&uart4 {
- u-boot,dm-pre-reloc;
-};
-
-&i2c4 {
- u-boot,dm-pre-reloc;
-};
-
&pmic {
u-boot,dm-pre-reloc;
};
@@ -165,8 +156,6 @@
};
};
-/* SPL part **************************************/
-/* MMC1 boot */
&sdmmc1_b4_pins_a {
u-boot,dm-spl;
pins {
@@ -185,7 +174,6 @@
u-boot,dm-spl;
};
-/* MMC2 boot */
&sdmmc2_b4_pins_a {
u-boot,dm-spl;
pins {
@@ -203,3 +191,17 @@
&sdmmc2 {
u-boot,dm-spl;
};
+
+&uart4 {
+ u-boot,dm-pre-reloc;
+};
+
+&uart4_pins_a {
+ u-boot,dm-pre-reloc;
+ pins1 {
+ u-boot,dm-pre-reloc;
+ };
+ pins2 {
+ u-boot,dm-pre-reloc;
+ };
+};
diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts
index 7a9b742d364..2664c9ce904 100644
--- a/arch/arm/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/dts/stm32mp157c-ed1.dts
@@ -8,20 +8,24 @@
#include "stm32mp157c.dtsi"
#include "stm32mp157-pinctrl.dtsi"
#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/mfd/st,stpmu1.h>
+#include <dt-bindings/mfd/st,stpmic1.h>
/ {
model = "STMicroelectronics STM32MP157C eval daughter";
compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
chosen {
- stdout-path = "serial3:115200n8";
+ stdout-path = "serial0:115200n8";
};
memory@c0000000 {
reg = <0xC0000000 0x40000000>;
};
+ aliases {
+ serial0 = &uart4;
+ };
+
sd_switch: regulator-sd_switch {
compatible = "regulator-gpio";
regulator-name = "sd_switch";
@@ -36,15 +40,8 @@
};
};
-&rng1 {
- status = "okay";
-};
-
-&timers6 {
+&hwspinlock {
status = "okay";
- timer@5 {
- status = "okay";
- };
};
&i2c4 {
@@ -54,8 +51,8 @@
i2c-scl-falling-time-ns = <20>;
status = "okay";
- pmic: stpmu1@33 {
- compatible = "st,stpmu1";
+ pmic: stpmic1@33 {
+ compatible = "st,stpmic1";
reg = <0x33>;
interrupts = <0 2>;
interrupt-parent = <&gpioa>;
@@ -68,7 +65,7 @@
st,usb_control_register = <0x30>;
regulators {
- compatible = "st,stpmu1-regulators";
+ compatible = "st,stpmic1-regulators";
ldo1-supply = <&v3v3>;
ldo2-supply = <&v3v3>;
@@ -321,10 +318,27 @@
};
};
+&iwdg2 {
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&pinctrl {
+ hwlocks = <&hwspinlock 0>;
+};
+
&pwr {
pwr-supply = <&vdd>;
};
+&rng1 {
+ status = "okay";
+};
+
+&rtc {
+ status = "okay";
+};
+
&sdmmc1 {
pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
broken-cd;
@@ -355,6 +369,13 @@
status = "okay";
};
+&timers6 {
+ status = "okay";
+ timer@5 {
+ status = "okay";
+ };
+};
+
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&uart4_pins_a>;
@@ -365,14 +386,6 @@
usb33d-supply = <&usb33>;
};
-&hwspinlock {
- status = "okay";
-};
-
-&pinctrl {
- hwlocks = <&hwspinlock 0>;
-};
-
&usbphyc_port0 {
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
diff --git a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi
index 30b173478c6..8b92b1fa2ee 100644
--- a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi
@@ -7,29 +7,23 @@
/ {
aliases {
- spi0 = &qspi;
+ gpio26 = &stmfx_pinctrl;
i2c1 = &i2c2;
i2c4 = &i2c5;
+ pinctrl2 = &stmfx_pinctrl;
+ spi0 = &qspi;
};
};
&flash0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
+ u-boot,dm-spl;
};
&flash1 {
- compatible = "spi-flash";
-};
-
-&v3v3 {
- regulator-always-on;
-};
-
-&usbotg_hs {
- g-tx-fifo-size = <576>;
+ compatible = "jedec,spi-nor";
};
-/* SPL part **************************************/
&qspi {
u-boot,dm-spl;
};
@@ -61,7 +55,10 @@
};
};
-&flash0 {
- u-boot,dm-spl;
+&usbotg_hs {
+ g-tx-fifo-size = <576>;
};
+&v3v3 {
+ regulator-always-on;
+};
diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts
index 902a42bee29..a6ee37924fe 100644
--- a/arch/arm/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/dts/stm32mp157c-ev1.dts
@@ -11,6 +11,21 @@
model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ serial0 = &uart4;
+ ethernet0 = &ethernet0;
+ };
+
+ panel_backlight: panel-backlight {
+ compatible = "gpio-backlight";
+ gpios = <&gpiod 13 GPIO_ACTIVE_LOW>;
+ default-on;
+ status = "okay";
+ };
};
&cec {
@@ -19,12 +34,88 @@
status = "okay";
};
+&dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi_in: endpoint {
+ remote-endpoint = <&ltdc_ep0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dsi_out: endpoint {
+ remote-endpoint = <&dsi_panel_in>;
+ };
+ };
+ };
+
+ panel-dsi@0 {
+ compatible = "raydium,rm68200";
+ reg = <0>;
+ reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>;
+ backlight = <&panel_backlight>;
+ status = "okay";
+
+ port {
+ dsi_panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+&ethernet0 {
+ status = "okay";
+ pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+ pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
+ pinctrl-names = "default", "sleep";
+ phy-mode = "rgmii";
+ max-speed = <1000>;
+ phy-handle = <&phy0>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
&i2c2 {
pinctrl-names = "default";
pinctrl-0 = <&i2c2_pins_a>;
i2c-scl-rising-time-ns = <185>;
i2c-scl-falling-time-ns = <20>;
status = "okay";
+
+ stmfx: stmfx@42 {
+ compatible = "st,stmfx-0300";
+ reg = <0x42>;
+ interrupts = <8 IRQ_TYPE_EDGE_RISING>;
+ interrupt-parent = <&gpioi>;
+ vdd-supply = <&v3v3>;
+
+ stmfx_pinctrl: stmfx-pin-controller {
+ compatible = "st,stmfx-0300-pinctrl";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&stmfx_pinctrl 0 0 24>;
+ status = "disabled";
+ };
+ };
};
&i2c5 {
@@ -35,6 +126,26 @@
status = "okay";
};
+&ltdc {
+ status = "okay";
+
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ltdc_ep0_out: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&dsi_in>;
+ };
+ };
+};
+
+&m_can1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&m_can1_pins_a>;
+ status = "okay";
+};
+
&qspi {
pinctrl-names = "default";
pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
@@ -60,6 +171,12 @@
};
};
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins_a>;
+ status = "disabled";
+};
+
&timers2 {
status = "disabled";
pwm {
@@ -106,6 +223,7 @@
&usbotg_hs {
pinctrl-names = "default";
pinctrl-0 = <&usbotg_hs_pins_a>;
+ dr_mode = "peripheral";
phys = <&usbphyc_port1 0>;
phy-names = "usb2-phy";
status = "okay";
diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi
index 37cadfa30c9..7eb4bee31cf 100644
--- a/arch/arm/dts/stm32mp157c.dtsi
+++ b/arch/arm/dts/stm32mp157c.dtsi
@@ -29,7 +29,7 @@
};
psci {
- compatible = "arm,psci";
+ compatible = "arm,psci-1.0";
method = "smc";
cpu_off = <0x84000002>;
cpu_on = <0x84000003>;
@@ -106,26 +106,6 @@
};
};
- pm_domain {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "st,stm32mp157c-pd";
-
- pd_core_ret: core-ret-power-domain@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- #power-domain-cells = <0>;
- label = "CORE-RETENTION";
-
- pd_core: core-power-domain@2 {
- reg = <2>;
- #power-domain-cells = <0>;
- label = "CORE";
- };
- };
- };
-
soc {
compatible = "simple-bus";
#address-cells = <1>;
@@ -339,6 +319,34 @@
};
};
+ spi2: spi@4000b000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x4000b000 0x400>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI2_K>;
+ resets = <&rcc SPI2_R>;
+ dmas = <&dmamux1 39 0x400 0x05>,
+ <&dmamux1 40 0x400 0x05>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi3: spi@4000c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x4000c000 0x400>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI3_K>;
+ resets = <&rcc SPI3_R>;
+ dmas = <&dmamux1 61 0x400 0x05>,
+ <&dmamux1 62 0x400 0x05>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
usart2: serial@4000e000 {
compatible = "st,stm32h7-uart";
reg = <0x4000e000 0x400>;
@@ -522,6 +530,34 @@
status = "disabled";
};
+ spi1: spi@44004000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x44004000 0x400>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI1_K>;
+ resets = <&rcc SPI1_R>;
+ dmas = <&dmamux1 37 0x400 0x05>,
+ <&dmamux1 38 0x400 0x05>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ spi4: spi@44005000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x44005000 0x400>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI4_K>;
+ resets = <&rcc SPI4_R>;
+ dmas = <&dmamux1 83 0x400 0x05>,
+ <&dmamux1 84 0x400 0x05>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
timers15: timer@44006000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -584,6 +620,116 @@
};
};
+ spi5: spi@44009000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x44009000 0x400>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI5_K>;
+ resets = <&rcc SPI5_R>;
+ dmas = <&dmamux1 85 0x400 0x05>,
+ <&dmamux1 86 0x400 0x05>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+ dfsdm: dfsdm@4400d000 {
+ compatible = "st,stm32mp1-dfsdm";
+ reg = <0x4400d000 0x800>;
+ clocks = <&rcc DFSDM_K>;
+ clock-names = "dfsdm";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ dfsdm0: filter@0 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <0>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 101 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm1: filter@1 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <1>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 102 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm2: filter@2 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <2>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 103 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm3: filter@3 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <3>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 104 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm4: filter@4 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <4>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 91 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ dfsdm5: filter@5 {
+ compatible = "st,stm32-dfsdm-adc";
+ #io-channel-cells = <1>;
+ reg = <5>;
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&dmamux1 92 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+ };
+
+ m_can1: can@4400e000 {
+ compatible = "bosch,m_can";
+ reg = <0x4400e000 0x400>, <0x44011000 0x2800>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+ clock-names = "hclk", "cclk";
+ bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+ status = "disabled";
+ };
+
+ m_can2: can@4400f000 {
+ compatible = "bosch,m_can";
+ reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
+ reg-names = "m_can", "message_ram";
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+ clock-names = "hclk", "cclk";
+ bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+ status = "disabled";
+ };
+
dma1: dma@48000000 {
compatible = "st,stm32-dma";
reg = <0x48000000 0x400>;
@@ -647,6 +793,8 @@
reg = <0x0>;
interrupt-parent = <&adc>;
interrupts = <0>;
+ dmas = <&dmamux1 9 0x400 0x01>;
+ dma-names = "rx";
status = "disabled";
};
@@ -656,6 +804,8 @@
reg = <0x100>;
interrupt-parent = <&adc>;
interrupts = <1>;
+ dmas = <&dmamux1 10 0x400 0x01>;
+ dma-names = "rx";
status = "disabled";
};
};
@@ -675,7 +825,7 @@
};
usbotg_hs: usb-otg@49000000 {
- compatible = "st,stm32mp1-hsotg", "snps,dwc2";
+ compatible = "snps,dwc2";
reg = <0x49000000 0x10000>;
clocks = <&rcc USBO_K>;
clock-names = "otg";
@@ -686,7 +836,6 @@
g-np-tx-fifo-size = <32>;
g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
dr_mode = "otg";
- power-domains = <&pd_core>;
status = "disabled";
};
@@ -753,8 +902,8 @@
reg = <0x5000d000 0x400>;
};
- syscfg: system-config@50020000 {
- compatible = "st,stm32-syscfg", "syscon";
+ syscfg: syscon@50020000 {
+ compatible = "st,stm32mp157-syscfg", "syscon";
reg = <0x50020000 0x400>;
};
@@ -853,6 +1002,18 @@
status = "disabled";
};
+ hash1: hash@54002000 {
+ compatible = "st,stm32f756-hash";
+ reg = <0x54002000 0x400>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc HASH1>;
+ resets = <&rcc HASH1_R>;
+ dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0>;
+ dma-names = "in";
+ dma-maxburst = <2>;
+ status = "disabled";
+ };
+
rng1: rng@54003000 {
compatible = "st,stm32-rng";
reg = <0x54003000 0x400>;
@@ -871,7 +1032,7 @@
dma-requests = <48>;
};
- qspi: qspi@58003000 {
+ qspi: spi@58003000 {
compatible = "st,stm32f469-qspi";
reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
reg-names = "qspi", "qspi_mm";
@@ -915,6 +1076,36 @@
status = "disabled";
};
+ stmmac_axi_config_0: stmmac-axi-config {
+ snps,wr_osr_lmt = <0x7>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,blen = <0 0 0 0 16 8 4>;
+ };
+
+ ethernet0: ethernet@5800a000 {
+ compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800a000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "syscfg-clk";
+ clocks = <&rcc ETHMAC>,
+ <&rcc ETHTX>,
+ <&rcc ETHRX>,
+ <&rcc ETHSTP>,
+ <&rcc SYSCFG>;
+ st,syscon = <&syscfg 0x4>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_0>;
+ snps,tso;
+ status = "disabled";
+ };
+
usbh_ohci: usbh-ohci@5800c000 {
compatible = "generic-ohci";
reg = <0x5800c000 0x1000>;
@@ -955,6 +1146,14 @@
status = "disabled";
};
+ iwdg2: watchdog@5a002000 {
+ compatible = "st,stm32mp1-iwdg";
+ reg = <0x5a002000 0x400>;
+ clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
+ clock-names = "pclk", "lsi";
+ status = "disabled";
+ };
+
usbphyc: usbphyc@5a006000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -983,6 +1182,20 @@
status = "disabled";
};
+ spi6: spi@5c001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32h7-spi";
+ reg = <0x5c001000 0x400>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc SPI6_K>;
+ resets = <&rcc SPI6_R>;
+ dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>,
+ <&mdma1 35 0x0 0x40002 0x0 0x0>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
i2c4: i2c@5c002000 {
compatible = "st,stm32f7-i2c";
reg = <0x5c002000 0x400>;
@@ -996,6 +1209,22 @@
status = "disabled";
};
+ rtc: rtc@5c004000 {
+ compatible = "st,stm32mp1-rtc";
+ reg = <0x5c004000 0x400>;
+ clocks = <&rcc RTCAPB>, <&rcc RTC>;
+ clock-names = "pclk", "rtc_ck";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ bsec: nvmem@5c005000 {
+ compatible = "st,stm32mp15-bsec";
+ reg = <0x5c005000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
i2c6: i2c@5c009000 {
compatible = "st,stm32f7-i2c";
reg = <0x5c009000 0x400>;
diff --git a/arch/arm/dts/stv0991.dts b/arch/arm/dts/stv0991.dts
index 98bd5dfc70f..b04e89971c7 100644
--- a/arch/arm/dts/stv0991.dts
+++ b/arch/arm/dts/stv0991.dts
@@ -40,7 +40,7 @@
flash0: n25q32@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>; /* chip select */
spi-max-frequency = <50000000>;
m25p,fast-read;
diff --git a/arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts b/arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts
new file mode 100644
index 00000000000..6a2154525d1
--- /dev/null
+++ b/arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Oceanic Systems (UK) Ltd.
+ * Copyright (C) 2019 Amarula Solutions B.V.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-a64-sopine.dtsi"
+
+/ {
+ model = "Oceanic 5205 5inMFD";
+ compatible = "oceanic,5205-5inmfd", "allwinner,sun50i-a64";
+
+ aliases {
+ ethernet0 = &emac;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ phy-mode = "rgmii";
+ phy-handle = <&ext_rgmii_phy>;
+ phy-supply = <&reg_dc1sw>;
+ allwinner,tx-delay-ps = <600>;
+ status = "okay";
+};
+
+&mdio {
+ ext_rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&reg_dc1sw {
+ regulator-name = "vcc-phy";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pb_pins>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/dts/zynq-zed.dts b/arch/arm/dts/zynq-zed.dts
index d2b7fc2c994..7a540b63f47 100644
--- a/arch/arm/dts/zynq-zed.dts
+++ b/arch/arm/dts/zynq-zed.dts
@@ -53,7 +53,7 @@
status = "okay";
num-cs = <1>;
flash@0 {
- compatible = "spansion,s25fl256s", "spi-flash";
+ compatible = "spansion,s25fl256s", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <30000000>;
m25p,fast-read;
diff --git a/arch/arm/dts/zynqmp-zc1232-revA.dts b/arch/arm/dts/zynqmp-zc1232-revA.dts
index 5c212ba468e..6117f83c474 100644
--- a/arch/arm/dts/zynqmp-zc1232-revA.dts
+++ b/arch/arm/dts/zynqmp-zc1232-revA.dts
@@ -41,7 +41,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB FIXME */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB FIXME */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1254-revA.dts b/arch/arm/dts/zynqmp-zc1254-revA.dts
index 881aacc5825..6ac8346d23d 100644
--- a/arch/arm/dts/zynqmp-zc1254-revA.dts
+++ b/arch/arm/dts/zynqmp-zc1254-revA.dts
@@ -41,7 +41,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1275-revA.dts b/arch/arm/dts/zynqmp-zc1275-revA.dts
index 7403f153e44..82c30a3fbef 100644
--- a/arch/arm/dts/zynqmp-zc1275-revA.dts
+++ b/arch/arm/dts/zynqmp-zc1275-revA.dts
@@ -41,7 +41,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1275-revB.dts b/arch/arm/dts/zynqmp-zc1275-revB.dts
index 1a7975b551d..0473503afaf 100644
--- a/arch/arm/dts/zynqmp-zc1275-revB.dts
+++ b/arch/arm/dts/zynqmp-zc1275-revB.dts
@@ -42,7 +42,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
index 9768dfe0446..8824f5cc027 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
@@ -101,7 +101,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* Micron MT25QU512ABB8ESF */
+ compatible = "m25p80", "jedec,spi-nor"; /* Micron MT25QU512ABB8ESF */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
index 9afbbb63b49..84c2904dc20 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
@@ -180,7 +180,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts
index 0e96a361882..6e228717131 100644
--- a/arch/arm/dts/zynqmp-zcu102-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu102-revA.dts
@@ -521,7 +521,7 @@
status = "okay";
is-dual = <1>;
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts
index 431dff52fe6..c7a3cdcf61d 100644
--- a/arch/arm/dts/zynqmp-zcu104-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu104-revA.dts
@@ -169,7 +169,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* n25q512a 128MiB */
+ compatible = "m25p80", "jedec,spi-nor"; /* n25q512a 128MiB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts
index 623d2c96cda..7df16b047ce 100644
--- a/arch/arm/dts/zynqmp-zcu104-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu104-revC.dts
@@ -176,7 +176,7 @@
&qspi {
status = "okay";
flash@0 {
- compatible = "m25p80", "spi-flash"; /* n25q512a 128MiB */
+ compatible = "m25p80", "jedec,spi-nor"; /* n25q512a 128MiB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu106-revA.dts b/arch/arm/dts/zynqmp-zcu106-revA.dts
index 00f6e30ef34..9fd3953fb44 100644
--- a/arch/arm/dts/zynqmp-zcu106-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu106-revA.dts
@@ -495,7 +495,7 @@
status = "okay";
is-dual = <1>;
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts
index 58021be9bfd..2e28a3934fd 100644
--- a/arch/arm/dts/zynqmp-zcu111-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu111-revA.dts
@@ -432,7 +432,7 @@
status = "okay";
is-dual = <1>;
flash@0 {
- compatible = "m25p80", "spi-flash"; /* 32MB */
+ compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
#address-cells = <1>;
#size-cells = <1>;
reg = <0x0>;
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index 4baba38b004..8c916e8c752 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -28,6 +28,8 @@
#define SUNXI_BOOTED_FROM_NAND 1
#define SUNXI_BOOTED_FROM_MMC2 2
#define SUNXI_BOOTED_FROM_SPI 3
+#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
+#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
/* boot head definition from sun4i boot code */
struct boot_file_head {
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index 3039e66bf9f..992a84152cf 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -1,5 +1,6 @@
#if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \
- !defined(CONFIG_ARCH_K3)
+ !defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
+ !defined(CONFIG_ARCH_BCM63158)
#include <asm/arch/gpio.h>
#endif
#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-kirkwood/cpu.c b/arch/arm/mach-kirkwood/cpu.c
index d54de53f31d..8f8e3003854 100644
--- a/arch/arm/mach-kirkwood/cpu.c
+++ b/arch/arm/mach-kirkwood/cpu.c
@@ -46,69 +46,31 @@ unsigned int kw_winctrl_calcsize(unsigned int sizeval)
return (0x0000ffff & j);
}
-/*
- * kw_config_adr_windows - Configure address Windows
- *
- * There are 8 address windows supported by Kirkwood Soc to addess different
- * devices. Each window can be configured for size, BAR and remap addr
- * Below configuration is standard for most of the cases
- *
- * If remap function not used, remap_lo must be set as base
- *
- * Reference Documentation:
- * Mbus-L to Mbus Bridge Registers Configuration.
- * (Sec 25.1 and 25.3 of Datasheet)
- */
-int kw_config_adr_windows(void)
-{
- struct kwwin_registers *winregs =
- (struct kwwin_registers *)KW_CPU_WIN_BASE;
-
+static struct mbus_win windows[] = {
/* Window 0: PCIE MEM address space */
- writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE,
- KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl);
-
- writel(KW_DEFADR_PCI_MEM, &winregs[0].base);
- writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo);
- writel(0x0, &winregs[0].remap_hi);
+ { KW_DEFADR_PCI_MEM, 1024 * 1024 * 256,
+ KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_MEM },
/* Window 1: PCIE IO address space */
- writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE,
- KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl);
- writel(KW_DEFADR_PCI_IO, &winregs[1].base);
- writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo);
- writel(0x0, &winregs[1].remap_hi);
+ { KW_DEFADR_PCI_IO, 1024 * 64,
+ KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_IO },
/* Window 2: NAND Flash address space */
- writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY,
- KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl);
- writel(KW_DEFADR_NANDF, &winregs[2].base);
- writel(KW_DEFADR_NANDF, &winregs[2].remap_lo);
- writel(0x0, &winregs[2].remap_hi);
+ { KW_DEFADR_NANDF, 1024 * 1024 * 128,
+ KWCPU_TARGET_MEMORY, KWCPU_ATTR_NANDFLASH },
/* Window 3: SPI Flash address space */
- writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY,
- KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl);
- writel(KW_DEFADR_SPIF, &winregs[3].base);
- writel(KW_DEFADR_SPIF, &winregs[3].remap_lo);
- writel(0x0, &winregs[3].remap_hi);
+ { KW_DEFADR_SPIF, 1024 * 1024 * 128,
+ KWCPU_TARGET_MEMORY, KWCPU_ATTR_SPIFLASH },
/* Window 4: BOOT Memory address space */
- writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY,
- KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl);
- writel(KW_DEFADR_BOOTROM, &winregs[4].base);
+ { KW_DEFADR_BOOTROM, 1024 * 1024 * 128,
+ KWCPU_TARGET_MEMORY, KWCPU_ATTR_BOOTROM },
/* Window 5: Security SRAM address space */
- writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM,
- KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl);
- writel(KW_DEFADR_SASRAM, &winregs[5].base);
-
- /* Window 6-7: Disabled */
- writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl);
- writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl);
-
- return 0;
-}
+ { KW_DEFADR_SASRAM, 1024 * 64,
+ KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM },
+};
/*
* SYSRSTn Duration Counter Support
@@ -221,15 +183,13 @@ int arch_cpu_init(void)
struct kwcpu_registers *cpureg =
(struct kwcpu_registers *)KW_CPU_REG_BASE;
- /* Linux expects` the internal registers to be at 0xf1000000 */
+ /* Linux expects the internal registers to be at 0xf1000000 */
writel(KW_REGS_PHY_BASE, KW_OFFSET_REG);
/* Enable and invalidate L2 cache in write through mode */
writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg);
invalidate_l2_cache();
- kw_config_adr_windows();
-
#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
/*
* Configures the I/O voltage of the pads connected to Egigabit
@@ -291,11 +251,13 @@ int arch_misc_init(void)
temp |= (1 << 22);
writefr_extra_feature_reg(temp);
- icache_enable();
/* Change reset vector to address 0x0 */
temp = get_cr();
set_cr(temp & ~CR_V);
+ /* Configure mbus windows */
+ mvebu_mbus_probe(windows, ARRAY_SIZE(windows));
+
/* checks and execute resset to factory event */
kw_sysrst_check();
diff --git a/arch/arm/mach-kirkwood/include/mach/cpu.h b/arch/arm/mach-kirkwood/include/mach/cpu.h
index 91d21518d85..ea42182cf9c 100644
--- a/arch/arm/mach-kirkwood/include/mach/cpu.h
+++ b/arch/arm/mach-kirkwood/include/mach/cpu.h
@@ -63,12 +63,18 @@ enum kwcpu_attrib {
*/
#define KW_DEFADR_PCI_MEM 0x90000000
#define KW_DEFADR_PCI_IO 0xC0000000
-#define KW_DEFADR_PCI_IO_REMAP 0xC0000000
#define KW_DEFADR_SASRAM 0xC8010000
#define KW_DEFADR_NANDF 0xD8000000
#define KW_DEFADR_SPIF 0xE8000000
#define KW_DEFADR_BOOTROM 0xF8000000
+struct mbus_win {
+ u32 base;
+ u32 size;
+ u8 target;
+ u8 attr;
+};
+
/*
* read feroceon/sheeva core extra feature register
* using co-proc instruction
@@ -135,13 +141,16 @@ struct kwgpio_registers {
u32 irq_level;
};
+/* Needed for dynamic (board-specific) mbus configuration */
+extern struct mvebu_mbus_state mbus_state;
+
/*
* functions
*/
unsigned int mvebu_sdram_bar(enum memory_bank bank);
unsigned int mvebu_sdram_bs(enum memory_bank bank);
void mvebu_sdram_size_adjust(enum memory_bank bank);
-int kw_config_adr_windows(void);
+int mvebu_mbus_probe(struct mbus_win windows[], int count);
void mvebu_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
unsigned int gpp0_oe, unsigned int gpp1_oe);
int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15,
diff --git a/arch/arm/mach-kirkwood/include/mach/soc.h b/arch/arm/mach-kirkwood/include/mach/soc.h
index 227707ae4c9..1d7f2828cd3 100644
--- a/arch/arm/mach-kirkwood/include/mach/soc.h
+++ b/arch/arm/mach-kirkwood/include/mach/soc.h
@@ -31,7 +31,7 @@
#define KW_RTC_BASE (KW_REGISTER(0x10300))
#define KW_NANDF_BASE (KW_REGISTER(0x10418))
#define MVEBU_SPI_BASE (KW_REGISTER(0x10600))
-#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000))
+#define MVEBU_CPU_WIN_BASE (KW_REGISTER(0x20000))
#define KW_CPU_REG_BASE (KW_REGISTER(0x20100))
#define MVEBU_TIMER_BASE (KW_REGISTER(0x20300))
#define KW_REG_PCIE_BASE (KW_REGISTER(0x40000))
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 7dda04e0e34..f5fd60d7845 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -9,10 +9,10 @@ config ARMADA_32BIT
select ARCH_MISC_INIT
select BOARD_EARLY_INIT_F
select CPU_V7A
- select SPL_DM
- select SPL_DM_SEQ_ALIAS
- select SPL_OF_CONTROL
- select SPL_SIMPLE_BUS
+ select SPL_DM if SPL
+ select SPL_DM_SEQ_ALIAS if SPL
+ select SPL_OF_CONTROL if SPL
+ select SPL_SIMPLE_BUS if SPL
select SUPPORT_SPL
config ARMADA_64BIT
@@ -46,7 +46,7 @@ config ARMADA_8K
# Armada PLL frequency (used for NAND clock generation)
config SYS_MVEBU_PLL_CLOCK
int
- default "2000000000" if ARMADA_XP || ARMADA_3700 || ARMADA_8K
+ default "2000000000" if ARMADA_XP || ARMADA_3700 || ARMADA_8K || ARMADA_MSYS
default "1000000000" if ARMADA_38X || ARMADA_375
# Armada XP/38x SoC types...
@@ -63,6 +63,22 @@ config MV78460
bool
select ARMADA_XP
+config ARMADA_MSYS
+ bool
+ select ARMADA_32BIT
+
+config 98DX4251
+ bool
+ select ARMADA_MSYS
+
+config 98DX3336
+ bool
+ select ARMADA_MSYS
+
+config 98DX3236
+ bool
+ select ARMADA_MSYS
+
config 88F6820
bool
select ARMADA_38X
@@ -136,6 +152,10 @@ config TARGET_X530
bool "Support Allied Telesis x530"
select 88F6820
+config TARGET_DB_XC3_24G4XG
+ bool "Support DB-XC3-24G4XG"
+ select 98DX3336
+
endchoice
config SYS_BOARD
@@ -154,6 +174,7 @@ config SYS_BOARD
default "theadorable" if TARGET_THEADORABLE
default "a38x" if TARGET_CONTROLCENTERDC
default "x530" if TARGET_X530
+ default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG
config SYS_CONFIG_NAME
default "clearfog" if TARGET_CLEARFOG
@@ -171,6 +192,7 @@ config SYS_CONFIG_NAME
default "turris_mox" if TARGET_TURRIS_MOX
default "controlcenterdc" if TARGET_CONTROLCENTERDC
default "x530" if TARGET_X530
+ default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG
config SYS_VENDOR
default "Marvell" if TARGET_DB_MV784MP_GP
@@ -179,6 +201,8 @@ config SYS_VENDOR
default "Marvell" if TARGET_DB_88F6820_GP
default "Marvell" if TARGET_DB_88F6820_AMC
default "Marvell" if TARGET_MVEBU_ARMADA_8K
+ default "Marvell" if TARGET_DB_XC3_24G4XG
+ default "Marvell" if TARGET_MVEBU_DB_88F7040
default "solidrun" if TARGET_CLEARFOG
default "kobol" if TARGET_HELIOS4
default "Synology" if TARGET_DS414
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index ee2eca91348..02d3ce27ee7 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -14,6 +14,7 @@ ifdef CONFIG_KIRKWOOD
obj-y = dram.o
obj-y += gpio.o
+obj-y += mbus.o
obj-y += timer.o
else # CONFIG_KIRKWOOD
@@ -24,6 +25,7 @@ ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ARMADA_375) += ../../../drivers/ddr/marvell/axp/xor.o
obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o
obj-$(CONFIG_ARMADA_XP) += ../../../drivers/ddr/marvell/axp/xor.o
+obj-$(CONFIG_ARMADA_MSYS) += ../../../drivers/ddr/marvell/axp/xor.o
obj-$(CONFIG_MVEBU_EFUSE) += efuse.o
extra-y += kwbimage.cfg
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index 919d05c88c7..c5b3df46aab 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -23,6 +23,11 @@ static struct mbus_win windows[] = {
/* NOR */
{ MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE,
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM },
+
+#ifdef CONFIG_ARMADA_MSYS
+ /* DFX */
+ { MBUS_DFX_BASE, MBUS_DFX_SIZE, CPU_TARGET_DFX, 0 },
+#endif
};
void lowlevel_init(void)
@@ -121,6 +126,14 @@ static const struct sar_freq_modes sar_freq_tab[] = {
{ 0x13, 0x0, 2000, 1000, 933 },
{ 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */
};
+#elif defined(CONFIG_ARMADA_MSYS)
+static const struct sar_freq_modes sar_freq_tab[] = {
+ { 0x0, 0x0, 400, 400, 400 },
+ { 0x2, 0x0, 667, 333, 667 },
+ { 0x3, 0x0, 800, 400, 800 },
+ { 0x5, 0x0, 800, 400, 800 },
+ { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */
+};
#else
/* SAR frequency values for Armada XP */
static const struct sar_freq_modes sar_freq_tab[] = {
@@ -144,7 +157,7 @@ void get_sar_freq(struct sar_freq_modes *sar_freq)
u32 freq;
int i;
-#if defined(CONFIG_ARMADA_375)
+#if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_MSYS)
val = readl(CONFIG_SAR2_REG); /* SAR - Sample At Reset */
#else
val = readl(CONFIG_SAR_REG); /* SAR - Sample At Reset */
@@ -160,7 +173,7 @@ void get_sar_freq(struct sar_freq_modes *sar_freq)
#endif
for (i = 0; sar_freq_tab[i].val != 0xff; i++) {
if (sar_freq_tab[i].val == freq) {
-#if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_38X)
+#if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_MSYS)
*sar_freq = sar_freq_tab[i];
return;
#else
@@ -270,6 +283,20 @@ int print_cpuinfo(void)
}
}
+ if (mvebu_soc_family() == MVEBU_SOC_MSYS) {
+ switch (revid) {
+ case 3:
+ puts("A0");
+ break;
+ case 4:
+ puts("A1");
+ break;
+ default:
+ printf("?? (%x)", revid);
+ break;
+ }
+ }
+
get_sar_freq(&sar_freq);
printf(" at %d MHz\n", sar_freq.p_clk);
@@ -472,6 +499,8 @@ u32 mvebu_get_nand_clock(void)
if (mvebu_soc_family() == MVEBU_SOC_A38X)
reg = MVEBU_DFX_DIV_CLK_CTRL(1);
+ else if (mvebu_soc_family() == MVEBU_SOC_MSYS)
+ reg = MVEBU_DFX_DIV_CLK_CTRL(8);
else
reg = MVEBU_CORE_DIV_CLK_CTRL(1);
@@ -501,7 +530,6 @@ int board_mmc_init(bd_t *bis)
}
#endif
-#ifdef CONFIG_SCSI_AHCI_PLAT
#define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0
#define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4
@@ -545,11 +573,19 @@ static void ahci_mvebu_regret_option(void __iomem *base)
writel(0x80, base + AHCI_VENDOR_SPECIFIC_0_DATA);
}
-void scsi_init(void)
+int board_ahci_enable(void)
{
- printf("MVEBU SATA INIT\n");
ahci_mvebu_mbus_config((void __iomem *)MVEBU_SATA0_BASE);
ahci_mvebu_regret_option((void __iomem *)MVEBU_SATA0_BASE);
+
+ return 0;
+}
+
+#ifdef CONFIG_SCSI_AHCI_PLAT
+void scsi_init(void)
+{
+ printf("MVEBU SATA INIT\n");
+ board_ahci_enable();
ahci_init((void __iomem *)MVEBU_SATA0_BASE);
}
#endif
diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h
index 71c4f70efc9..bbcfcfd1419 100644
--- a/arch/arm/mach-mvebu/include/mach/config.h
+++ b/arch/arm/mach-mvebu/include/mach/config.h
@@ -17,7 +17,7 @@
#include <asm/arch/soc.h>
#if defined(CONFIG_ARMADA_XP) || defined(CONFIG_ARMADA_375) \
- || defined(CONFIG_ARMADA_38X)
+ || defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_MSYS)
/*
* Set this for the common xor register definitions needed in dram.c
* for A38x as well here.
diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h
index 9e23043a485..b9153d86c66 100644
--- a/arch/arm/mach-mvebu/include/mach/cpu.h
+++ b/arch/arm/mach-mvebu/include/mach/cpu.h
@@ -34,6 +34,7 @@ enum cpu_target {
CPU_TARGET_PCIE02 = 0x4,
CPU_TARGET_ETH01 = 0x7,
CPU_TARGET_PCIE13 = 0x8,
+ CPU_TARGET_DFX = 0x8,
CPU_TARGET_SASRAM = 0x9,
CPU_TARGET_SATA01 = 0xa, /* A38X */
CPU_TARGET_NAND = 0xd,
@@ -79,6 +80,8 @@ enum {
#define MBUS_PCI_IO_SIZE (64 << 10)
#define MBUS_SPI_BASE 0xF4000000
#define MBUS_SPI_SIZE (8 << 20)
+#define MBUS_DFX_BASE 0xF6000000
+#define MBUS_DFX_SIZE (1 << 20)
#define MBUS_BOOTROM_BASE 0xF8000000
#define MBUS_BOOTROM_SIZE (8 << 20)
diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h
index 01577f469b0..f666ee24243 100644
--- a/arch/arm/mach-mvebu/include/mach/soc.h
+++ b/arch/arm/mach-mvebu/include/mach/soc.h
@@ -76,7 +76,11 @@
#define MVEBU_NAND_BASE (MVEBU_REGISTER(0xd0000))
#define MVEBU_SDIO_BASE (MVEBU_REGISTER(0xd8000))
#define MVEBU_LCD_BASE (MVEBU_REGISTER(0xe0000))
+#ifdef CONFIG_ARMADA_MSYS
+#define MVEBU_DFX_BASE (MBUS_DFX_BASE)
+#else
#define MVEBU_DFX_BASE (MVEBU_REGISTER(0xe4000))
+#endif
#define SOC_COHERENCY_FABRIC_CTRL_REG (MVEBU_REGISTER(0x20200))
#define MBUS_ERR_PROP_EN (1 << 8)
@@ -96,9 +100,20 @@
#define SPI_PUP_EN BIT(5)
#define MVEBU_CORE_DIV_CLK_CTRL(i) (MVEBU_CLOCK_BASE + ((i) * 0x8))
+#ifdef CONFIG_ARMADA_MSYS
+#define MVEBU_DFX_DIV_CLK_CTRL(i) (MVEBU_DFX_BASE + 0xf8000 + 0x250 + ((i) * 0x4))
+#define NAND_ECC_DIVCKL_RATIO_OFFS 6
+#define NAND_ECC_DIVCKL_RATIO_MASK (0xF << NAND_ECC_DIVCKL_RATIO_OFFS)
+#else
#define MVEBU_DFX_DIV_CLK_CTRL(i) (MVEBU_DFX_BASE + 0x250 + ((i) * 0x4))
+#endif
+#ifdef CONFIG_ARMADA_MSYS
+#define NAND_ECC_DIVCKL_RATIO_OFFS 6
+#define NAND_ECC_DIVCKL_RATIO_MASK (0xF << NAND_ECC_DIVCKL_RATIO_OFFS)
+#else
#define NAND_ECC_DIVCKL_RATIO_OFFS 8
#define NAND_ECC_DIVCKL_RATIO_MASK (0x3F << NAND_ECC_DIVCKL_RATIO_OFFS)
+#endif
#define SDRAM_MAX_CS 4
#define SDRAM_ADDR_MASK 0xFF000000
@@ -149,6 +164,22 @@
#define BOOT_FROM_SPI 0x32
#define BOOT_FROM_MMC 0x30
#define BOOT_FROM_MMC_ALT 0x31
+#elif defined(CONFIG_ARMADA_MSYS)
+/* SAR values for MSYS */
+#define CONFIG_SAR_REG (MBUS_DFX_BASE + 0xf8200)
+#define CONFIG_SAR2_REG (MBUS_DFX_BASE + 0xf8204)
+
+#define SAR_CPU_FREQ_OFFS 18
+#define SAR_CPU_FREQ_MASK (0x7 << SAR_CPU_FREQ_OFFS)
+#define SAR_BOOT_DEVICE_OFFS 11
+#define SAR_BOOT_DEVICE_MASK (0x7 << SAR_BOOT_DEVICE_OFFS)
+
+#define BOOT_DEV_SEL_OFFS 11
+#define BOOT_DEV_SEL_MASK (0x7 << BOOT_DEV_SEL_OFFS)
+
+#define BOOT_FROM_NAND 0x1
+#define BOOT_FROM_UART 0x2
+#define BOOT_FROM_SPI 0x3
#else
/* SAR values for Armada XP */
#define CONFIG_SAR_REG (MVEBU_REGISTER(0x18230))
diff --git a/arch/arm/mach-mvebu/mbus.c b/arch/arm/mach-mvebu/mbus.c
index df4c5cb2d71..c68e93ba100 100644
--- a/arch/arm/mach-mvebu/mbus.c
+++ b/arch/arm/mach-mvebu/mbus.c
@@ -344,6 +344,11 @@ static void mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
}
}
mbus_dram_info.num_cs = cs;
+
+#if defined(CONFIG_ARMADA_MSYS)
+ /* Disable MBUS Err Prop - in order to avoid data aborts */
+ clrbits_le32(mbus->mbuswins_base + 0x200, BIT(8));
+#endif
}
static const struct mvebu_mbus_soc_data
@@ -405,6 +410,7 @@ int mvebu_mbus_del_window(phys_addr_t base, size_t size)
return 0;
}
+#ifndef CONFIG_KIRKWOOD
static void mvebu_mbus_get_lowest_base(struct mvebu_mbus_state *mbus,
phys_addr_t *base)
{
@@ -451,6 +457,7 @@ static void mvebu_config_mbus_bridge(struct mvebu_mbus_state *mbus)
val = (size / (64 << 10)) - 1;
writel((val << 16) | 0x1, MBUS_BRIDGE_WIN_CTRL_REG);
}
+#endif
int mbus_dt_setup_win(struct mvebu_mbus_state *mbus,
u32 base, u32 size, u8 target, u8 attr)
@@ -471,12 +478,14 @@ int mbus_dt_setup_win(struct mvebu_mbus_state *mbus,
return -ENOMEM;
}
+#ifndef CONFIG_KIRKWOOD
/*
* Re-configure the mbus bridge registers each time this function
* is called. Since it may get called from the board code in
* later boot stages as well.
*/
mvebu_config_mbus_bridge(mbus);
+#endif
return 0;
}
diff --git a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c
index 569840ff471..c8c92988645 100644
--- a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c
+++ b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c
@@ -35,7 +35,7 @@ int pex_local_dev_num_set(u32 pex_if, u32 dev_num);
#define ETM_MODULE_DETECT 2
#define PEX_MODE_GET(satr) ((satr & 0x6) >> 1)
-#define PEX_CAPABILITY_GET(satr) (satr & 1)
+#define PEX_CAPABILITY_GET(satr, port) ((satr >> port) & 1)
#define MV_PEX_UNIT_TO_IF(pex_unit) ((pex_unit < 3) ? (pex_unit * 4) : 9)
/* Static parametes */
@@ -176,7 +176,7 @@ u8 board_cpu_freq_get(void)
return ((sar_msb & 0x100000) >> 17) | ((sar & 0xe00000) >> 21);
}
-__weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode)
+__weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(void)
{
u32 board_id;
u32 serdes_cfg_val = 0; /* default */
@@ -352,7 +352,7 @@ int serdes_phy_config(void)
DEBUG_WR_REG(CPU_AVS_CONTROL2_REG, cpu_avs);
}
- info = board_serdes_cfg_get(PEX_MODE_GET(satr11));
+ info = board_serdes_cfg_get();
if (info == NULL) {
DEBUG_INIT_S("Hight speed PHY Error #1\n");
@@ -675,7 +675,7 @@ int serdes_phy_config(void)
tmp |= (0x1 << 4);
if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)
tmp |= (0x4 << 4);
- if (0 == PEX_CAPABILITY_GET(satr11))
+ if (0 == PEX_CAPABILITY_GET(satr11, pex_unit))
tmp |= 0x1;
else
tmp |= 0x2;
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index 8a929fa9132..73aa3827122 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -17,7 +17,7 @@ config SPL
select SPL_DM_RESET
select SPL_SERIAL_SUPPORT
select SPL_SYSCON
- select SPL_DRIVERS_MISC_SUPPORT
+ imply SPL_DISPLAY_PRINT
imply SPL_LIBDISK_SUPPORT
config SYS_SOC
@@ -25,18 +25,31 @@ config SYS_SOC
config TARGET_STM32MP1
bool "Support stm32mp1xx"
- select ARCH_SUPPORT_PSCI
+ select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED
select CPU_V7A
- select CPU_V7_HAS_NONSEC
+ select CPU_V7_HAS_NONSEC if !STM32MP1_TRUSTED
select CPU_V7_HAS_VIRT
select PINCTRL_STM32
select STM32_RCC
select STM32_RESET
select SYS_ARCH_TIMER
- select SYSRESET_SYSCON
+ imply SYSRESET_PSCI if STM32MP1_TRUSTED
+ imply SYSRESET_SYSCON if !STM32MP1_TRUSTED
help
target STMicroelectronics SOC STM32MP1 family
+ STM32MP157, STM32MP153 or STM32MP151
STMicroelectronics MPU with core ARMv7
+ dual core A7 for STM32MP157/3, monocore for STM32MP151
+
+config STM32MP1_TRUSTED
+ bool "Support trusted boot with TF-A"
+ default y if !SPL
+ select ARM_SMCCC
+ help
+ Say Y here to enable boot with TF-A
+ Trusted boot chain is :
+ BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32
+ TF-A monitor provides proprietary smc to manage secure devices
config SYS_TEXT_BASE
prompt "U-Boot base address"
@@ -46,6 +59,9 @@ config SYS_TEXT_BASE
when DDR driver is used:
DDR + 1MB (0xC0100000)
+config NR_DRAM_BANKS
+ default 1
+
config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2
hex "Partition on MMC2 to use to load U-Boot from"
depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
@@ -54,9 +70,6 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2
Partition on the second MMC to load U-Boot from when the MMC is being
used in raw mode
-source "board/st/stm32mp1/Kconfig"
-
-# currently activated for debug / should be deactivated for real product
if DEBUG_UART
config DEBUG_UART_BOARD_INIT
@@ -71,4 +84,6 @@ config DEBUG_UART_CLOCK
default 64000000
endif
+source "board/st/stm32mp1/Kconfig"
+
endif
diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index f59ced5ee1b..1493914a110 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -11,6 +11,9 @@ ifdef CONFIG_SPL_BUILD
obj-y += spl.o
else
obj-y += bsec.o
+ifndef CONFIG_STM32MP1_TRUSTED
+obj-$(CONFIG_SYSRESET) += cmd_poweroff.o
+endif
endif
obj-$(CONFIG_ARMV7_PSCI) += psci.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
index d087a313892..9ed8d8c56c3 100644
--- a/arch/arm/mach-stm32mp/bsec.c
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -8,9 +8,12 @@
#include <misc.h>
#include <asm/io.h>
#include <linux/iopoll.h>
+#include <asm/arch/stm32mp1_smc.h>
+#include <linux/arm-smccc.h>
#define BSEC_OTP_MAX_VALUE 95
+#ifndef CONFIG_STM32MP1_TRUSTED
#define BSEC_TIMEOUT_US 10000
/* BSEC REGISTER OFFSET (base relative) */
@@ -168,7 +171,7 @@ static int bsec_shadow_register(u32 base, u32 otp)
ret = bsec_power_safmem(base, true);
if (ret)
return ret;
- power_up = 1;
+ power_up = true;
}
/* set BSEC_OTP_CTRL_OFF with the otp value*/
writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF);
@@ -270,6 +273,7 @@ static int bsec_program_otp(long base, u32 val, u32 otp)
return ret;
}
+#endif /* CONFIG_STM32MP1_TRUSTED */
/* BSEC MISC driver *******************************************************/
struct stm32mp_bsec_platdata {
@@ -278,6 +282,11 @@ struct stm32mp_bsec_platdata {
static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc(STM32_SMC_BSEC,
+ STM32_SMC_READ_OTP,
+ otp, 0, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
u32 tmp_data = 0;
int ret;
@@ -299,27 +308,46 @@ static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
/* restore shadow value */
ret = bsec_write_shadow(plat->base, tmp_data, otp);
return ret;
+#endif
}
static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc(STM32_SMC_BSEC,
+ STM32_SMC_READ_SHADOW,
+ otp, 0, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_read_shadow(plat->base, val, otp);
+#endif
}
static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc_exec(STM32_SMC_BSEC,
+ STM32_SMC_PROG_OTP,
+ otp, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_program_otp(plat->base, val, otp);
+#endif
}
static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
{
+#ifdef CONFIG_STM32MP1_TRUSTED
+ return stm32_smc_exec(STM32_SMC_BSEC,
+ STM32_SMC_WRITE_SHADOW,
+ otp, val);
+#else
struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
return bsec_write_shadow(plat->base, val, otp);
+#endif
}
static int stm32mp_bsec_read(struct udevice *dev, int offset,
@@ -405,8 +433,23 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev)
return 0;
}
+#ifndef CONFIG_STM32MP1_TRUSTED
+static int stm32mp_bsec_probe(struct udevice *dev)
+{
+ int otp;
+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+ /* update unlocked shadow for OTP cleared by the rom code */
+ for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++)
+ if (!bsec_read_SR_lock(plat->base, otp))
+ bsec_shadow_register(plat->base, otp);
+
+ return 0;
+}
+#endif
+
static const struct udevice_id stm32mp_bsec_ids[] = {
- { .compatible = "st,stm32mp-bsec" },
+ { .compatible = "st,stm32mp15-bsec" },
{}
};
@@ -417,14 +460,7 @@ U_BOOT_DRIVER(stm32mp_bsec) = {
.ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
.ops = &stm32mp_bsec_ops,
-};
-
-/* bsec IP is not present in device tee, manage IP address by platdata */
-static struct stm32mp_bsec_platdata stm32_bsec_platdata = {
- .base = STM32_BSEC_BASE,
-};
-
-U_BOOT_DEVICE(stm32mp_bsec) = {
- .name = "stm32mp_bsec",
- .platdata = &stm32_bsec_platdata,
+#ifndef CONFIG_STM32MP1_TRUSTED
+ .probe = stm32mp_bsec_probe,
+#endif
};
diff --git a/arch/arm/mach-stm32mp/cmd_poweroff.c b/arch/arm/mach-stm32mp/cmd_poweroff.c
new file mode 100644
index 00000000000..f54dd1daf23
--- /dev/null
+++ b/arch/arm/mach-stm32mp/cmd_poweroff.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <command.h>
+#include <sysreset.h>
+
+int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret;
+
+ puts("poweroff ...\n");
+ mdelay(100);
+
+ ret = sysreset_walk(SYSRESET_POWER);
+
+ if (ret == -EINPROGRESS)
+ mdelay(1000);
+
+ /*NOTREACHED when power off*/
+ return CMD_RET_FAILURE;
+}
diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk
index f371aac75bd..403af2a225e 100644
--- a/arch/arm/mach-stm32mp/config.mk
+++ b/arch/arm/mach-stm32mp/config.mk
@@ -3,7 +3,20 @@
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
#
-ALL-$(CONFIG_SPL_BUILD) += u-boot-spl.stm32
+ifndef CONFIG_SPL
+ALL-y += u-boot.stm32
+else
+ifdef CONFIG_SPL_BUILD
+ALL-y += u-boot-spl.stm32
+endif
+endif
+
+MKIMAGEFLAGS_u-boot.stm32 = -T stm32image -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
+
+u-boot.stm32: MKIMAGEOUTPUT = u-boot.stm32.log
+
+u-boot.stm32: u-boot.bin FORCE
+ $(call if_changed,mkimage)
MKIMAGEFLAGS_u-boot-spl.stm32 = -T stm32image -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE)
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index b8933587adb..7b4431c9c75 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -18,6 +18,7 @@
#define RCC_DBGCFGR (STM32_RCC_BASE + 0x080C)
#define RCC_BDCR (STM32_RCC_BASE + 0x0140)
#define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x0208)
+#define RCC_MP_AHB5ENSETR (STM32_RCC_BASE + 0x0210)
#define RCC_BDCR_VSWRST BIT(31)
#define RCC_BDCR_RTCSRC GENMASK(17, 16)
#define RCC_DBGCFGR_DBGCKEN BIT(8)
@@ -44,6 +45,9 @@
#define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16)
#define DBGMCU_IDC_REV_ID_SHIFT 16
+/* GPIOZ registers */
+#define GPIOZ_SECCFGR 0x54004030
+
/* boot interface from Bootrom
* - boot instance = bit 31:16
* - boot device = bit 15:0
@@ -55,10 +59,32 @@
#define BOOTROM_INSTANCE_SHIFT 16
/* BSEC OTP index */
+#define BSEC_OTP_RPN 1
#define BSEC_OTP_SERIAL 13
+#define BSEC_OTP_PKG 16
#define BSEC_OTP_MAC 57
+/* Device Part Number (RPN) = OTP_DATA1 lower 8 bits */
+#define RPN_SHIFT 0
+#define RPN_MASK GENMASK(7, 0)
+
+/* Package = bit 27:29 of OTP16
+ * - 100: LBGA448 (FFI) => AA = LFBGA 18x18mm 448 balls p. 0.8mm
+ * - 011: LBGA354 (LCI) => AB = LFBGA 16x16mm 359 balls p. 0.8mm
+ * - 010: TFBGA361 (FFC) => AC = TFBGA 12x12mm 361 balls p. 0.5mm
+ * - 001: TFBGA257 (LCC) => AD = TFBGA 10x10mm 257 balls p. 0.5mm
+ * - others: Reserved
+ */
+#define PKG_SHIFT 27
+#define PKG_MASK GENMASK(2, 0)
+
+#define PKG_AA_LBGA448 4
+#define PKG_AB_LBGA354 3
+#define PKG_AC_TFBGA361 2
+#define PKG_AD_TFBGA257 1
+
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+#ifndef CONFIG_STM32MP1_TRUSTED
static void security_init(void)
{
/* Disable the backup domain write protection */
@@ -113,7 +139,12 @@ static void security_init(void)
* Bit 16 ITAMP1E: RTC power domain supply monitoring
*/
writel(0x0, TAMP_CR1);
+
+ /* GPIOZ: deactivate the security */
+ writel(BIT(0), RCC_MP_AHB5ENSETR);
+ writel(0x0, GPIOZ_SECCFGR);
}
+#endif /* CONFIG_STM32MP1_TRUSTED */
/*
* Debug init
@@ -127,13 +158,19 @@ static void dbgmcu_init(void)
}
#endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */
-static u32 get_bootmode(void)
+#if !defined(CONFIG_STM32MP1_TRUSTED) && \
+ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
+/* get bootmode from ROM code boot context: saved in TAMP register */
+static void update_bootmode(void)
{
u32 boot_mode;
-#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR);
u32 bootrom_device, bootrom_instance;
+ /* enable TAMP clock = RTCAPBEN */
+ writel(BIT(8), RCC_MP_APB5ENSETR);
+
+ /* read bootrom context */
bootrom_device =
(bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT;
bootrom_instance =
@@ -147,12 +184,14 @@ static u32 get_bootmode(void)
clrsetbits_le32(TAMP_BOOT_CONTEXT,
TAMP_BOOT_MODE_MASK,
boot_mode << TAMP_BOOT_MODE_SHIFT);
-#else
- /* read TAMP backup register */
- boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
- TAMP_BOOT_MODE_SHIFT;
+}
#endif
- return boot_mode;
+
+u32 get_bootmode(void)
+{
+ /* read bootmode from TAMP backup register */
+ return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
+ TAMP_BOOT_MODE_SHIFT;
}
/*
@@ -167,16 +206,18 @@ int arch_cpu_init(void)
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
dbgmcu_init();
-
+#ifndef CONFIG_STM32MP1_TRUSTED
security_init();
+ update_bootmode();
+#endif
#endif
- /* get bootmode from BootRom context: saved in TAMP register */
boot_mode = get_bootmode();
if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART)
gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
#if defined(CONFIG_DEBUG_UART) && \
+ !defined(CONFIG_STM32MP1_TRUSTED) && \
(!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
else
debug_uart_init();
@@ -203,25 +244,94 @@ u32 get_cpu_rev(void)
return (read_idc() & DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT;
}
+static u32 get_otp(int index, int shift, int mask)
+{
+ int ret;
+ struct udevice *dev;
+ u32 otp = 0;
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec),
+ &dev);
+
+ if (!ret)
+ ret = misc_read(dev, STM32_BSEC_SHADOW(index),
+ &otp, sizeof(otp));
+
+ return (otp >> shift) & mask;
+}
+
+/* Get Device Part Number (RPN) from OTP */
+static u32 get_cpu_rpn(void)
+{
+ return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK);
+}
+
u32 get_cpu_type(void)
{
- return (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT;
+ u32 id;
+
+ id = (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT;
+
+ return (id << 16) | get_cpu_rpn();
+}
+
+/* Get Package options from OTP */
+static u32 get_cpu_package(void)
+{
+ return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK);
}
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
- char *cpu_s, *cpu_r;
+ char *cpu_s, *cpu_r, *pkg;
+ /* MPUs Part Numbers */
switch (get_cpu_type()) {
- case CPU_STMP32MP15x:
- cpu_s = "15x";
+ case CPU_STM32MP157Cxx:
+ cpu_s = "157C";
+ break;
+ case CPU_STM32MP157Axx:
+ cpu_s = "157A";
+ break;
+ case CPU_STM32MP153Cxx:
+ cpu_s = "153C";
+ break;
+ case CPU_STM32MP153Axx:
+ cpu_s = "153A";
+ break;
+ case CPU_STM32MP151Cxx:
+ cpu_s = "151C";
+ break;
+ case CPU_STM32MP151Axx:
+ cpu_s = "151A";
+ break;
+ default:
+ cpu_s = "????";
+ break;
+ }
+
+ /* Package */
+ switch (get_cpu_package()) {
+ case PKG_AA_LBGA448:
+ pkg = "AA";
+ break;
+ case PKG_AB_LBGA354:
+ pkg = "AB";
+ break;
+ case PKG_AC_TFBGA361:
+ pkg = "AC";
+ break;
+ case PKG_AD_TFBGA257:
+ pkg = "AD";
break;
default:
- cpu_s = "?";
+ pkg = "??";
break;
}
+ /* REVISION */
switch (get_cpu_rev()) {
case CPU_REVA:
cpu_r = "A";
@@ -234,7 +344,7 @@ int print_cpuinfo(void)
break;
}
- printf("CPU: STM32MP%s.%s\n", cpu_s, cpu_r);
+ printf("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r);
return 0;
}
@@ -242,20 +352,48 @@ int print_cpuinfo(void)
static void setup_boot_mode(void)
{
+ const u32 serial_addr[] = {
+ STM32_USART1_BASE,
+ STM32_USART2_BASE,
+ STM32_USART3_BASE,
+ STM32_UART4_BASE,
+ STM32_UART5_BASE,
+ STM32_USART6_BASE,
+ STM32_UART7_BASE,
+ STM32_UART8_BASE
+ };
char cmd[60];
u32 boot_ctx = readl(TAMP_BOOT_CONTEXT);
u32 boot_mode =
(boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
+ u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK);
+ struct udevice *dev;
+ int alias;
- pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d\n",
- __func__, boot_ctx, boot_mode, instance);
-
+ pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n",
+ __func__, boot_ctx, boot_mode, instance, forced_mode);
switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
case BOOT_SERIAL_UART:
- sprintf(cmd, "%d", instance);
- env_set("boot_device", "uart");
+ if (instance > ARRAY_SIZE(serial_addr))
+ break;
+ /* serial : search associated alias in devicetree */
+ sprintf(cmd, "serial@%x", serial_addr[instance]);
+ if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev))
+ break;
+ if (fdtdec_get_alias_seq(gd->fdt_blob, "serial",
+ dev_of_offset(dev), &alias))
+ break;
+ sprintf(cmd, "%d", alias);
+ env_set("boot_device", "serial");
env_set("boot_instance", cmd);
+
+ /* restore console on uart when not used */
+ if (gd->cur_serial_dev != dev) {
+ gd->flags &= ~(GD_FLG_SILENT |
+ GD_FLG_DISABLE_CONSOLE);
+ printf("serial boot with console enabled!\n");
+ }
break;
case BOOT_SERIAL_USB:
env_set("boot_device", "usb");
@@ -279,6 +417,36 @@ static void setup_boot_mode(void)
pr_debug("unexpected boot mode = %x\n", boot_mode);
break;
}
+
+ switch (forced_mode) {
+ case BOOT_FASTBOOT:
+ printf("Enter fastboot!\n");
+ env_set("preboot", "env set preboot; fastboot 0");
+ break;
+ case BOOT_STM32PROG:
+ env_set("boot_device", "usb");
+ env_set("boot_instance", "0");
+ break;
+ case BOOT_UMS_MMC0:
+ case BOOT_UMS_MMC1:
+ case BOOT_UMS_MMC2:
+ printf("Enter UMS!\n");
+ instance = forced_mode - BOOT_UMS_MMC0;
+ sprintf(cmd, "env set preboot; ums 0 mmc %d", instance);
+ env_set("preboot", cmd);
+ break;
+ case BOOT_RECOVERY:
+ env_set("preboot", "env set preboot; run altbootcmd");
+ break;
+ case BOOT_NORMAL:
+ break;
+ default:
+ pr_debug("unexpected forced boot mode = %x\n", forced_mode);
+ break;
+ }
+
+ /* clear TAMP for next reboot */
+ clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL);
}
/*
@@ -304,7 +472,7 @@ static int setup_mac_address(void)
if (ret)
return ret;
- ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET,
+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC),
otp, sizeof(otp));
if (ret < 0)
return ret;
@@ -342,12 +510,12 @@ static int setup_serial_number(void)
if (ret)
return ret;
- ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET,
+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_SERIAL),
otp, sizeof(otp));
if (ret < 0)
return ret;
- sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]);
+ sprintf(serial_string, "%08X%08X%08X", otp[0], otp[1], otp[2]);
env_set("serial#", serial_string);
return 0;
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index 5d0bdca1787..c526c88e3ee 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -13,13 +13,10 @@
#define STM32_RCC_BASE 0x50000000
#define STM32_PWR_BASE 0x50001000
#define STM32_DBGMCU_BASE 0x50081000
-#define STM32_BSEC_BASE 0x5C005000
#define STM32_TZC_BASE 0x5C006000
#define STM32_ETZPC_BASE 0x5C007000
#define STM32_TAMP_BASE 0x5C00A000
-#ifdef CONFIG_DEBUG_UART_BASE
-/* hardcoded value can be only used for DEBUG UART */
#define STM32_USART1_BASE 0x5C000000
#define STM32_USART2_BASE 0x4000E000
#define STM32_USART3_BASE 0x4000F000
@@ -28,7 +25,6 @@
#define STM32_USART6_BASE 0x44003000
#define STM32_UART7_BASE 0x40018000
#define STM32_UART8_BASE 0x40019000
-#endif
#define STM32_SYSRAM_BASE 0x2FFC0000
#define STM32_SYSRAM_SIZE SZ_256K
@@ -40,8 +36,10 @@
/* enumerated used to identify the SYSCON driver instance */
enum {
STM32MP_SYSCON_UNKNOWN,
- STM32MP_SYSCON_STGEN,
+ STM32MP_SYSCON_ETZPC,
STM32MP_SYSCON_PWR,
+ STM32MP_SYSCON_STGEN,
+ STM32MP_SYSCON_SYSCFG,
};
/*
@@ -95,10 +93,25 @@ enum boot_device {
#define TAMP_BOOT_MODE_SHIFT 8
#define TAMP_BOOT_DEVICE_MASK GENMASK(7, 4)
#define TAMP_BOOT_INSTANCE_MASK GENMASK(3, 0)
+#define TAMP_BOOT_FORCED_MASK GENMASK(7, 0)
+
+enum forced_boot_mode {
+ BOOT_NORMAL = 0x00,
+ BOOT_FASTBOOT = 0x01,
+ BOOT_RECOVERY = 0x02,
+ BOOT_STM32PROG = 0x03,
+ BOOT_UMS_MMC0 = 0x10,
+ BOOT_UMS_MMC1 = 0x11,
+ BOOT_UMS_MMC2 = 0x12,
+};
/* offset used for BSEC driver: misc_read and misc_write */
#define STM32_BSEC_SHADOW_OFFSET 0x0
+#define STM32_BSEC_SHADOW(id) (STM32_BSEC_SHADOW_OFFSET + (id) * 4)
#define STM32_BSEC_OTP_OFFSET 0x80000000
+#define STM32_BSEC_OTP(id) (STM32_BSEC_OTP_OFFSET + (id) * 4)
+
+#define BSEC_OTP_BOARD 59
#endif /* __ASSEMBLY__*/
#endif /* _MACH_STM32_H_ */
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h
new file mode 100644
index 00000000000..8130546b273
--- /dev/null
+++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef __STM32MP1_SMC_H__
+#define __STM32MP1_SMC_H__
+
+#include <linux/arm-smccc.h>
+
+/*
+ * SMC function IDs for STM32 Service queries
+ * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF
+ * like this is defined in SMC calling Convention by ARM
+ * for SiP (silicon Partner)
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+#define STM32_SMC_VERSION 0x82000000
+
+/* Secure Service access from Non-secure */
+#define STM32_SMC_BSEC 0x82001003
+
+/* Service for BSEC */
+#define STM32_SMC_READ_SHADOW 0x01
+#define STM32_SMC_PROG_OTP 0x02
+#define STM32_SMC_WRITE_SHADOW 0x03
+#define STM32_SMC_READ_OTP 0x04
+#define STM32_SMC_READ_ALL 0x05
+#define STM32_SMC_WRITE_ALL 0x06
+
+/* SMC error codes */
+#define STM32_SMC_OK 0x0
+#define STM32_SMC_NOT_SUPPORTED -1
+#define STM32_SMC_FAILED -2
+#define STM32_SMC_INVALID_PARAMS -3
+
+#define stm32_smc_exec(svc, op, data1, data2) \
+ stm32_smc(svc, op, data1, data2, NULL)
+
+#ifdef CONFIG_ARM_SMCCC
+static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(svc, op, data1, data2, 0, 0, 0, 0, &res);
+
+ if (res.a0) {
+ pr_err("%s: Failed to exec in secure mode (err = %ld)\n",
+ __func__, res.a0);
+ return -EINVAL;
+ }
+ if (result)
+ *result = (u32)res.a1;
+
+ return 0;
+}
+#else
+static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result)
+{
+ return 0;
+}
+#endif
+
+#endif /* __STM32MP1_SMC_H__ */
diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
index 41d4b40bcb4..71a3ba794d1 100644
--- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h
+++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h
@@ -3,9 +3,15 @@
* Copyright (C) 2015-2017, STMicroelectronics - All Rights Reserved
*/
-#define CPU_STMP32MP15x 0x500
+/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0)*/
+#define CPU_STM32MP157Cxx 0x05000000
+#define CPU_STM32MP157Axx 0x05000001
+#define CPU_STM32MP153Cxx 0x05000024
+#define CPU_STM32MP153Axx 0x05000025
+#define CPU_STM32MP151Cxx 0x0500002E
+#define CPU_STM32MP151Axx 0x0500002F
-/* return CPU_STMP32MPxx constants */
+/* return CPU_STMP32MP...Xxx constants */
u32 get_cpu_type(void);
#define CPU_REVA 0x1000
@@ -13,3 +19,5 @@ u32 get_cpu_type(void);
/* return CPU_REV constants */
u32 get_cpu_rev(void);
+/* return boot mode */
+u32 get_bootmode(void);
diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c
index 6ed2482080c..c2dff38c368 100644
--- a/arch/arm/mach-stm32mp/psci.c
+++ b/arch/arm/mach-stm32mp/psci.c
@@ -103,7 +103,13 @@ int __secure psci_affinity_info(u32 function_id, u32 target_affinity,
int __secure psci_migrate_info_type(u32 function_id)
{
- /* Trusted OS is either not present or does not require migration */
+ /*
+ * in Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+ * return 2 = Trusted OS is either not present or does not require
+ * migration, system of this type does not require the caller
+ * to use the MIGRATE function.
+ * MIGRATE function calls return NOT_SUPPORTED.
+ */
return 2;
}
diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index 790973e8b6e..a3b0d6f3825 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -7,13 +7,14 @@
#include <dm.h>
#include <spl.h>
#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <linux/libfdt.h>
u32 spl_boot_device(void)
{
u32 boot_mode;
- boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
- TAMP_BOOT_MODE_SHIFT;
+ boot_mode = get_bootmode();
switch (boot_mode) {
case BOOT_FLASH_SD_1:
@@ -22,6 +23,21 @@ u32 spl_boot_device(void)
case BOOT_FLASH_SD_2:
case BOOT_FLASH_EMMC_2:
return BOOT_DEVICE_MMC2;
+ case BOOT_SERIAL_UART_1:
+ case BOOT_SERIAL_UART_2:
+ case BOOT_SERIAL_UART_3:
+ case BOOT_SERIAL_UART_4:
+ case BOOT_SERIAL_UART_5:
+ case BOOT_SERIAL_UART_6:
+ case BOOT_SERIAL_UART_7:
+ case BOOT_SERIAL_UART_8:
+ return BOOT_DEVICE_UART;
+ case BOOT_SERIAL_USB_OTG:
+ return BOOT_DEVICE_USB;
+ case BOOT_FLASH_NAND_FMC:
+ return BOOT_DEVICE_NAND;
+ case BOOT_FLASH_NOR_QSPI:
+ return BOOT_DEVICE_SPI;
}
return BOOT_DEVICE_MMC1;
@@ -44,6 +60,21 @@ int spl_boot_partition(const u32 boot_device)
}
}
+#ifdef CONFIG_SPL_DISPLAY_PRINT
+void spl_display_print(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ const char *model;
+
+ /* same code than show_board_info() but not compiled for SPL
+ * see CONFIG_DISPLAY_BOARDINFO & common/board_info.c
+ */
+ model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+ if (model)
+ printf("Model: %s\n", model);
+}
+#endif
+
void board_init_f(ulong dummy)
{
struct udevice *dev;
@@ -80,7 +111,7 @@ void board_init_f(ulong dummy)
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
- debug("DRAM init failed: %d\n", ret);
- return;
+ printf("DRAM init failed: %d\n", ret);
+ hang();
}
}
diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c
index eb7f435f10c..242f8340abb 100644
--- a/arch/arm/mach-stm32mp/syscon.c
+++ b/arch/arm/mach-stm32mp/syscon.c
@@ -9,10 +9,11 @@
#include <asm/arch/stm32.h>
static const struct udevice_id stm32mp_syscon_ids[] = {
- { .compatible = "st,stm32-stgen",
- .data = STM32MP_SYSCON_STGEN },
- { .compatible = "st,stm32mp1-pwr",
- .data = STM32MP_SYSCON_PWR },
+ { .compatible = "st,stm32mp1-etzpc", .data = STM32MP_SYSCON_ETZPC },
+ { .compatible = "st,stm32mp1-pwr", .data = STM32MP_SYSCON_PWR },
+ { .compatible = "st,stm32-stgen", .data = STM32MP_SYSCON_STGEN },
+ { .compatible = "st,stm32mp157-syscfg",
+ .data = STM32MP_SYSCON_SYSCFG },
{ }
};
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 152deb04e90..8110f23ff67 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -426,10 +426,11 @@ endif
config DRAM_ZQ
int "sunxi dram zq value"
- default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I
+ default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \
+ MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T
default 127 if MACH_SUN7I
default 14779 if MACH_SUN8I_V3S
- default 3881979 if MACH_SUN8I_R40 || MACH_SUN50I_H6
+ default 3881979 if MACH_SUNXI_H3_H5 || MACH_SUN8I_R40 || MACH_SUN50I_H6
default 4145117 if MACH_SUN9I
default 3881915 if MACH_SUN50I
---help---
@@ -438,6 +439,7 @@ config DRAM_ZQ
config DRAM_ODT_EN
bool "sunxi dram odt enable"
default y if MACH_SUN8I_A23
+ default y if MACH_SUNXI_H3_H5
default y if MACH_SUN8I_R40
default y if MACH_SUN50I
default y if MACH_SUN50I_H6
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index b74eaf2a0e4..c6dd7b8e54b 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -240,10 +240,12 @@ uint32_t sunxi_get_boot_device(void)
boot_source = readb(SPL_ADDR + 0x28);
switch (boot_source) {
case SUNXI_BOOTED_FROM_MMC0:
+ case SUNXI_BOOTED_FROM_MMC0_HIGH:
return BOOT_DEVICE_MMC1;
case SUNXI_BOOTED_FROM_NAND:
return BOOT_DEVICE_NAND;
case SUNXI_BOOTED_FROM_MMC2:
+ case SUNXI_BOOTED_FROM_MMC2_HIGH:
return BOOT_DEVICE_MMC2;
case SUNXI_BOOTED_FROM_SPI:
return BOOT_DEVICE_SPI;
diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c
index 1da2727f987..5da01922bfa 100644
--- a/arch/arm/mach-sunxi/dram_sun8i_a33.c
+++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c
@@ -152,7 +152,7 @@ static void auto_set_timing_para(struct dram_para *para)
reg_val &= ~(0xff << 8);
reg_val &= ~(0xff << 0);
reg_val |= (0x33 << 8);
- reg_val |= (0x8 << 0);
+ reg_val |= (0x10 << 0);
writel(reg_val, &mctl_ctl->dramtmg8);
/* Set phy interface time */
reg_val = (0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8)
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index 665d3cc8c1c..3522e6cdc82 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_MT7620) += \
linkit-smart-7688.dtb
dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
+dtb-$(CONFIG_TARGET_AP152) += ap152.dtb
dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb
dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb
dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
diff --git a/arch/mips/dts/ap121.dts b/arch/mips/dts/ap121.dts
index 4ca1c704ca4..f30af502161 100644
--- a/arch/mips/dts/ap121.dts
+++ b/arch/mips/dts/ap121.dts
@@ -34,7 +34,7 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
memory-map = <0x9f000000 0x00800000>;
spi-max-frequency = <25000000>;
reg = <0>;
diff --git a/arch/mips/dts/ap143.dts b/arch/mips/dts/ap143.dts
index 6aedd87db9a..93a098052c7 100644
--- a/arch/mips/dts/ap143.dts
+++ b/arch/mips/dts/ap143.dts
@@ -34,9 +34,14 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
memory-map = <0x9f000000 0x00800000>;
spi-max-frequency = <25000000>;
reg = <0>;
};
};
+
+&gmac1 {
+ status = "okay";
+ phy-mode = "rgmii";
+};
diff --git a/arch/mips/dts/ap152.dts b/arch/mips/dts/ap152.dts
new file mode 100644
index 00000000000..1722290c731
--- /dev/null
+++ b/arch/mips/dts/ap152.dts
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com>
+ */
+
+/dts-v1/;
+#include "qca956x.dtsi"
+
+/ {
+ model = "AP152 Reference Board";
+ compatible = "qca,ap152", "qca,qca956x";
+
+ aliases {
+ spi0 = &spi0;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&gmac0 {
+ phy-mode = "sgmii";
+ status = "okay";
+};
+
+&xtal {
+ clock-frequency = <25000000>;
+};
+
+&uart0 {
+ clock-frequency = <25000000>;
+ status = "okay";
+};
+
+&spi0 {
+ spi-max-frequency = <25000000>;
+ status = "okay";
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ memory-map = <0x9f000000 0x01000000>;
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
diff --git a/arch/mips/dts/brcm,bcm6838.dtsi b/arch/mips/dts/brcm,bcm6838.dtsi
index b6f95591476..c060802e8a4 100644
--- a/arch/mips/dts/brcm,bcm6838.dtsi
+++ b/arch/mips/dts/brcm,bcm6838.dtsi
@@ -98,5 +98,32 @@
status = "disabled";
};
+
+ gpio_lo: gpio-controller@14e00100 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x14e00100 0x4>, <0x14e0012c 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio_mid0: gpio-controller@14e00104 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x14e00104 0x4>, <0x14e00130 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
+
+ gpio_mid1: gpio-controller@14e00108 {
+ compatible = "brcm,bcm6345-gpio";
+ reg = <0x14e00108 0x4>, <0x14e00134 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/mips/dts/brcm,bcm968380gerg.dts b/arch/mips/dts/brcm,bcm968380gerg.dts
index 513045ee051..98471e3894d 100644
--- a/arch/mips/dts/brcm,bcm968380gerg.dts
+++ b/arch/mips/dts/brcm,bcm968380gerg.dts
@@ -38,3 +38,15 @@
label = "bcm968380gerg:green:usb";
};
};
+
+&gpio_lo {
+ status = "okay";
+};
+
+&gpio_mid0 {
+ status = "okay";
+};
+
+&gpio_mid1 {
+ status = "okay";
+};
diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts
index eb60aaa8d5f..28443b3b0fd 100644
--- a/arch/mips/dts/comtrend,ar-5315u.dts
+++ b/arch/mips/dts/comtrend,ar-5315u.dts
@@ -110,7 +110,7 @@
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts
index 03e3851ab15..12ace64621b 100644
--- a/arch/mips/dts/comtrend,ar-5387un.dts
+++ b/arch/mips/dts/comtrend,ar-5387un.dts
@@ -94,7 +94,7 @@
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts
index 75f6037e96a..eedde89dfd8 100644
--- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts
+++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts
@@ -10,7 +10,7 @@
/ {
compatible = "gardena,smart-gateway-mt7688", "ralink,mt7628a-soc";
- model = "Gardena smart-Gateway-MT7688";
+ model = "GARDENA smart Gateway (MT7688)";
aliases {
serial0 = &uart0;
@@ -97,7 +97,7 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash", "jedec,spi-nor";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <40000000>;
reg = <0>;
};
diff --git a/arch/mips/dts/jr2_pcb110.dts b/arch/mips/dts/jr2_pcb110.dts
index ddc30ff76a9..6562221794e 100644
--- a/arch/mips/dts/jr2_pcb110.dts
+++ b/arch/mips/dts/jr2_pcb110.dts
@@ -5,6 +5,7 @@
/dts-v1/;
#include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
/ {
model = "Jaguar2 Cu8-Sfp16 PCB110 Reference Board";
@@ -43,7 +44,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
};
@@ -72,3 +73,78 @@
sgpio-ports = <0x3f00ffff>;
gpio-ranges = <&sgpio2 0 0 96>;
};
+
+&mdio1 {
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ };
+ phy5: ethernet-phy@5 {
+ reg = <5>;
+ };
+ phy6: ethernet-phy@6 {
+ reg = <6>;
+ };
+ phy7: ethernet-phy@7 {
+ reg = <7>;
+ };
+};
+
+&switch {
+ ethernet-ports {
+
+ port0: port@0 {
+ reg = <0>;
+ phy-handle = <&phy0>;
+ phys = <&serdes_hsio 0 SERDES1G(1) PHY_MODE_SGMII>;
+ };
+ port1: port@1 {
+ reg = <1>;
+ phy-handle = <&phy1>;
+ phys = <&serdes_hsio 1 SERDES1G(2) PHY_MODE_SGMII>;
+ };
+ port2: port@2 {
+ reg = <2>;
+ phy-handle = <&phy2>;
+ phys = <&serdes_hsio 2 SERDES1G(3) PHY_MODE_SGMII>;
+ };
+ port3: port@3 {
+ reg = <3>;
+ phy-handle = <&phy3>;
+ phys = <&serdes_hsio 3 SERDES1G(4) PHY_MODE_SGMII>;
+ };
+ port4: port@4 {
+ reg = <4>;
+ phy-handle = <&phy4>;
+ phys = <&serdes_hsio 4 SERDES1G(5) PHY_MODE_SGMII>;
+ };
+ port5: port@5 {
+ reg = <5>;
+ phy-handle = <&phy5>;
+ phys = <&serdes_hsio 5 SERDES1G(6) PHY_MODE_SGMII>;
+ };
+ port6: port@6 {
+ reg = <6>;
+ phy-handle = <&phy6>;
+ phys = <&serdes_hsio 6 SERDES1G(7) PHY_MODE_SGMII>;
+ };
+ port7: port@7 {
+ reg = <7>;
+ phy-handle = <&phy7>;
+ phys = <&serdes_hsio 7 SERDES1G(8) PHY_MODE_SGMII>;
+ };
+ };
+};
diff --git a/arch/mips/dts/jr2_pcb111.dts b/arch/mips/dts/jr2_pcb111.dts
index 4d411b6dc4e..74305a8f331 100644
--- a/arch/mips/dts/jr2_pcb111.dts
+++ b/arch/mips/dts/jr2_pcb111.dts
@@ -5,6 +5,7 @@
/dts-v1/;
#include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
/ {
model = "Jaguar2 Cu48 PCB111 Reference Board";
@@ -43,7 +44,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
};
@@ -72,3 +73,402 @@
sgpio-ports = <0xff000000>;
gpio-ranges = <&sgpio2 0 0 96>;
};
+
+&mdio1 {
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ };
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ };
+ phy5: ethernet-phy@5 {
+ reg = <5>;
+ };
+ phy6: ethernet-phy@6 {
+ reg = <6>;
+ };
+ phy7: ethernet-phy@7 {
+ reg = <7>;
+ };
+ phy8: ethernet-phy@8 {
+ reg = <8>;
+ };
+ phy9: ethernet-phy@9 {
+ reg = <9>;
+ };
+ phy10: ethernet-phy@10 {
+ reg = <10>;
+ };
+ phy11: ethernet-phy@11 {
+ reg = <11>;
+ };
+ phy12: ethernet-phy@12 {
+ reg = <12>;
+ };
+ phy13: ethernet-phy@13 {
+ reg = <13>;
+ };
+ phy14: ethernet-phy@14 {
+ reg = <14>;
+ };
+ phy15: ethernet-phy@15 {
+ reg = <15>;
+ };
+ phy16: ethernet-phy@16 {
+ reg = <16>;
+ };
+ phy17: ethernet-phy@17 {
+ reg = <17>;
+ };
+ phy18: ethernet-phy@18 {
+ reg = <18>;
+ };
+ phy19: ethernet-phy@19 {
+ reg = <19>;
+ };
+ phy20: ethernet-phy@20 {
+ reg = <20>;
+ };
+ phy21: ethernet-phy@21 {
+ reg = <21>;
+ };
+ phy22: ethernet-phy@22 {
+ reg = <22>;
+ };
+ phy23: ethernet-phy@23 {
+ reg = <23>;
+ };
+};
+
+&mdio2 {
+ status = "okay";
+
+ phy24: ethernet-phy@24 {
+ reg = <0>;
+ };
+ phy25: ethernet-phy@25 {
+ reg = <1>;
+ };
+ phy26: ethernet-phy@26 {
+ reg = <2>;
+ };
+ phy27: ethernet-phy@27 {
+ reg = <3>;
+ };
+ phy28: ethernet-phy@28 {
+ reg = <4>;
+ };
+ phy29: ethernet-phy@29 {
+ reg = <5>;
+ };
+ phy30: ethernet-phy@30 {
+ reg = <6>;
+ };
+ phy31: ethernet-phy@31 {
+ reg = <7>;
+ };
+ phy32: ethernet-phy@32 {
+ reg = <8>;
+ };
+ phy33: ethernet-phy@33 {
+ reg = <9>;
+ };
+ phy34: ethernet-phy@34 {
+ reg = <10>;
+ };
+ phy35: ethernet-phy@35 {
+ reg = <11>;
+ };
+ phy36: ethernet-phy@36 {
+ reg = <12>;
+ };
+ phy37: ethernet-phy@37 {
+ reg = <13>;
+ };
+ phy38: ethernet-phy@38 {
+ reg = <14>;
+ };
+ phy39: ethernet-phy@39 {
+ reg = <15>;
+ };
+ phy40: ethernet-phy@40 {
+ reg = <16>;
+ };
+ phy41: ethernet-phy@41 {
+ reg = <17>;
+ };
+ phy42: ethernet-phy@42 {
+ reg = <18>;
+ };
+ phy43: ethernet-phy@43 {
+ reg = <19>;
+ };
+ phy44: ethernet-phy@44 {
+ reg = <20>;
+ };
+ phy45: ethernet-phy@45 {
+ reg = <21>;
+ };
+ phy46: ethernet-phy@46 {
+ reg = <22>;
+ };
+ phy47: ethernet-phy@47 {
+ reg = <23>;
+ };
+};
+
+&switch {
+ ethernet-ports {
+ port0: port@0 {
+ reg = <0>;
+ phy-handle = <&phy0>;
+ phys = <&serdes_hsio 0 SERDES6G(4) PHY_MODE_QSGMII>;
+ };
+ port1: port@1 {
+ reg = <1>;
+ phy-handle = <&phy1>;
+ phys = <&serdes_hsio 1 0xff PHY_MODE_QSGMII>;
+ };
+ port2: port@2 {
+ reg = <2>;
+ phy-handle = <&phy2>;
+ phys = <&serdes_hsio 2 0xff PHY_MODE_QSGMII>;
+ };
+ port3: port@3 {
+ reg = <3>;
+ phy-handle = <&phy3>;
+ phys = <&serdes_hsio 3 0xff PHY_MODE_QSGMII>;
+ };
+ port4: port@4 {
+ reg = <4>;
+ phy-handle = <&phy4>;
+ phys = <&serdes_hsio 4 SERDES6G(5) PHY_MODE_QSGMII>;
+ };
+ port5: port@5 {
+ reg = <5>;
+ phy-handle = <&phy5>;
+ phys = <&serdes_hsio 5 0xff PHY_MODE_QSGMII>;
+ };
+ port6: port@6 {
+ reg = <6>;
+ phy-handle = <&phy6>;
+ phys = <&serdes_hsio 6 0xff PHY_MODE_QSGMII>;
+ };
+ port7: port@7 {
+ reg = <7>;
+ phy-handle = <&phy7>;
+ phys = <&serdes_hsio 7 0xff PHY_MODE_QSGMII>;
+ };
+ port8: port@8 {
+ reg = <8>;
+ phy-handle = <&phy8>;
+ phys = <&serdes_hsio 8 SERDES6G(6) PHY_MODE_QSGMII>;
+ };
+ port9: port@9 {
+ reg = <9>;
+ phy-handle = <&phy9>;
+ phys = <&serdes_hsio 9 0xff PHY_MODE_QSGMII>;
+ };
+ port10: port@10 {
+ reg = <10>;
+ phy-handle = <&phy10>;
+ phys = <&serdes_hsio 10 0xff PHY_MODE_QSGMII>;
+ };
+ port11: port@11 {
+ reg = <11>;
+ phy-handle = <&phy11>;
+ phys = <&serdes_hsio 11 0xff PHY_MODE_QSGMII>;
+ };
+ port12: port@12 {
+ reg = <12>;
+ phy-handle = <&phy12>;
+ phys = <&serdes_hsio 12 SERDES6G(7) PHY_MODE_QSGMII>;
+ };
+ port13: port@13 {
+ reg = <13>;
+ phy-handle = <&phy13>;
+ phys = <&serdes_hsio 13 0xff PHY_MODE_QSGMII>;
+ };
+ port14: port@14 {
+ reg = <14>;
+ phy-handle = <&phy14>;
+ phys = <&serdes_hsio 14 0xff PHY_MODE_QSGMII>;
+ };
+ port15: port@15 {
+ reg = <15>;
+ phy-handle = <&phy15>;
+ phys = <&serdes_hsio 15 0xff PHY_MODE_QSGMII>;
+ };
+ port16: port@16 {
+ reg = <16>;
+ phy-handle = <&phy16>;
+ phys = <&serdes_hsio 16 SERDES6G(8) PHY_MODE_QSGMII>;
+ };
+ port17: port@17 {
+ reg = <17>;
+ phy-handle = <&phy17>;
+ phys = <&serdes_hsio 17 0xff PHY_MODE_QSGMII>;
+ };
+ port18: port@18 {
+ reg = <18>;
+ phy-handle = <&phy18>;
+ phys = <&serdes_hsio 18 0xff PHY_MODE_QSGMII>;
+ };
+ port19: port@19 {
+ reg = <19>;
+ phy-handle = <&phy19>;
+ phys = <&serdes_hsio 19 0xff PHY_MODE_QSGMII>;
+ };
+ port20: port@20 {
+ reg = <20>;
+ phy-handle = <&phy20>;
+ phys = <&serdes_hsio 20 SERDES6G(9) PHY_MODE_QSGMII>;
+ };
+ port21: port@21 {
+ reg = <21>;
+ phy-handle = <&phy21>;
+ phys = <&serdes_hsio 21 0xff PHY_MODE_QSGMII>;
+ };
+ port22: port@22 {
+ reg = <22>;
+ phy-handle = <&phy22>;
+ phys = <&serdes_hsio 22 0xff PHY_MODE_QSGMII>;
+ };
+ port23: port@23 {
+ reg = <23>;
+ phy-handle = <&phy23>;
+ phys = <&serdes_hsio 23 0xff PHY_MODE_QSGMII>;
+ };
+ port24: port@24 {
+ reg = <24>;
+ phy-handle = <&phy24>;
+ phys = <&serdes_hsio 24 SERDES6G(10) PHY_MODE_QSGMII>;
+ };
+ port25: port@25 {
+ reg = <25>;
+ phy-handle = <&phy25>;
+ phys = <&serdes_hsio 25 0xff PHY_MODE_QSGMII>;
+ };
+ port26: port@26 {
+ reg = <26>;
+ phy-handle = <&phy26>;
+ phys = <&serdes_hsio 26 0xff PHY_MODE_QSGMII>;
+ };
+ port27: port@27 {
+ reg = <27>;
+ phy-handle = <&phy27>;
+ phys = <&serdes_hsio 27 0xff PHY_MODE_QSGMII>;
+ };
+ port28: port@28 {
+ reg = <28>;
+ phy-handle = <&phy28>;
+ phys = <&serdes_hsio 28 SERDES6G(11) PHY_MODE_QSGMII>;
+ };
+ port29: port@29 {
+ reg = <29>;
+ phy-handle = <&phy29>;
+ phys = <&serdes_hsio 29 0xff PHY_MODE_QSGMII>;
+ };
+ port30: port@30 {
+ reg = <30>;
+ phy-handle = <&phy30>;
+ phys = <&serdes_hsio 30 0xff PHY_MODE_QSGMII>;
+ };
+ port31: port@31 {
+ reg = <31>;
+ phy-handle = <&phy31>;
+ phys = <&serdes_hsio 31 0xff PHY_MODE_QSGMII>;
+ };
+ port32: port@32 {
+ reg = <32>;
+ phy-handle = <&phy32>;
+ phys = <&serdes_hsio 32 SERDES6G(12) PHY_MODE_QSGMII>;
+ };
+ port33: port@33 {
+ reg = <33>;
+ phy-handle = <&phy33>;
+ phys = <&serdes_hsio 33 0xff PHY_MODE_QSGMII>;
+ };
+ port34: port@34 {
+ reg = <34>;
+ phy-handle = <&phy34>;
+ phys = <&serdes_hsio 34 0xff PHY_MODE_QSGMII>;
+ };
+ port35: port@35 {
+ reg = <35>;
+ phy-handle = <&phy35>;
+ phys = <&serdes_hsio 35 0xff PHY_MODE_QSGMII>;
+ };
+ port36: port@36 {
+ reg = <36>;
+ phy-handle = <&phy36>;
+ phys = <&serdes_hsio 36 SERDES6G(13) PHY_MODE_QSGMII>;
+ };
+ port37: port@37 {
+ reg = <37>;
+ phy-handle = <&phy37>;
+ phys = <&serdes_hsio 37 0xff PHY_MODE_QSGMII>;
+ };
+ port38: port@38 {
+ reg = <38>;
+ phy-handle = <&phy38>;
+ phys = <&serdes_hsio 38 0xff PHY_MODE_QSGMII>;
+ };
+ port39: port@39 {
+ reg = <39>;
+ phy-handle = <&phy39>;
+ phys = <&serdes_hsio 39 0xff PHY_MODE_QSGMII>;
+ };
+ port40: port@40 {
+ reg = <40>;
+ phy-handle = <&phy40>;
+ phys = <&serdes_hsio 40 SERDES6G(14) PHY_MODE_QSGMII>;
+ };
+ port41: port@41 {
+ reg = <41>;
+ phy-handle = <&phy41>;
+ phys = <&serdes_hsio 41 0xff PHY_MODE_QSGMII>;
+ };
+ port42: port@42 {
+ reg = <42>;
+ phy-handle = <&phy42>;
+ phys = <&serdes_hsio 42 0xff PHY_MODE_QSGMII>;
+ };
+ port43: port@43 {
+ reg = <43>;
+ phy-handle = <&phy43>;
+ phys = <&serdes_hsio 43 0xff PHY_MODE_QSGMII>;
+ };
+ port44: port@44 {
+ reg = <44>;
+ phy-handle = <&phy44>;
+ phys = <&serdes_hsio 44 SERDES6G(15) PHY_MODE_QSGMII>;
+ };
+ port45: port@45 {
+ reg = <45>;
+ phy-handle = <&phy45>;
+ phys = <&serdes_hsio 45 0xff PHY_MODE_QSGMII>;
+ };
+ port46: port@46 {
+ reg = <46>;
+ phy-handle = <&phy46>;
+ phys = <&serdes_hsio 46 0xff PHY_MODE_QSGMII>;
+ };
+ port47: port@47 {
+ reg = <47>;
+ phy-handle = <&phy47>;
+ phys = <&serdes_hsio 47 0xff PHY_MODE_QSGMII>;
+ };
+ };
+};
diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts
index c9db136f30f..bb104021747 100644
--- a/arch/mips/dts/linkit-smart-7688.dts
+++ b/arch/mips/dts/linkit-smart-7688.dts
@@ -38,7 +38,7 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash", "jedec,spi-nor";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <25000000>;
reg = <0>;
};
diff --git a/arch/mips/dts/luton_pcb090.dts b/arch/mips/dts/luton_pcb090.dts
index 315172b19c5..fe457bae9d5 100644
--- a/arch/mips/dts/luton_pcb090.dts
+++ b/arch/mips/dts/luton_pcb090.dts
@@ -48,7 +48,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
spi-cs-high;
diff --git a/arch/mips/dts/luton_pcb091.dts b/arch/mips/dts/luton_pcb091.dts
index 9b4d628797e..f684cc8dd63 100644
--- a/arch/mips/dts/luton_pcb091.dts
+++ b/arch/mips/dts/luton_pcb091.dts
@@ -54,7 +54,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
spi-cs-high;
diff --git a/arch/mips/dts/mscc,jr2.dtsi b/arch/mips/dts/mscc,jr2.dtsi
index 090092607b5..7f5a96fecdc 100644
--- a/arch/mips/dts/mscc,jr2.dtsi
+++ b/arch/mips/dts/mscc,jr2.dtsi
@@ -183,5 +183,121 @@
gpio-bank-name = "sgpio2_";
sgpio-clock = <0x14>;
};
+
+ switch: switch@1010000 {
+ compatible = "mscc,vsc7454-switch";
+ reg = <0x01040000 0x0100>, // VTSS_TO_DEV_0
+ <0x01050000 0x0100>, // VTSS_TO_DEV_1
+ <0x01060000 0x0100>, // VTSS_TO_DEV_2
+ <0x01070000 0x0100>, // VTSS_TO_DEV_3
+ <0x01080000 0x0100>, // VTSS_TO_DEV_4
+ <0x01090000 0x0100>, // VTSS_TO_DEV_5
+ <0x010a0000 0x0100>, // VTSS_TO_DEV_6
+ <0x010b0000 0x0100>, // VTSS_TO_DEV_7
+ <0x010c0000 0x0100>, // VTSS_TO_DEV_8
+ <0x010d0000 0x0100>, // VTSS_TO_DEV_9
+ <0x010e0000 0x0100>, // VTSS_TO_DEV_10
+ <0x010f0000 0x0100>, // VTSS_TO_DEV_11
+ <0x01100000 0x0100>, // VTSS_TO_DEV_12
+ <0x01110000 0x0100>, // VTSS_TO_DEV_13
+ <0x01120000 0x0100>, // VTSS_TO_DEV_14
+ <0x01130000 0x0100>, // VTSS_TO_DEV_15
+ <0x01140000 0x0100>, // VTSS_TO_DEV_16
+ <0x01150000 0x0100>, // VTSS_TO_DEV_17
+ <0x01160000 0x0100>, // VTSS_TO_DEV_18
+ <0x01170000 0x0100>, // VTSS_TO_DEV_19
+ <0x01180000 0x0100>, // VTSS_TO_DEV_20
+ <0x01190000 0x0100>, // VTSS_TO_DEV_21
+ <0x011a0000 0x0100>, // VTSS_TO_DEV_22
+ <0x011b0000 0x0100>, // VTSS_TO_DEV_23
+ <0x011c0000 0x0100>, // VTSS_TO_DEV_24
+ <0x011d0000 0x0100>, // VTSS_TO_DEV_25
+ <0x011e0000 0x0100>, // VTSS_TO_DEV_26
+ <0x011f0000 0x0100>, // VTSS_TO_DEV_27
+ <0x01200000 0x0100>, // VTSS_TO_DEV_28
+ <0x01210000 0x0100>, // VTSS_TO_DEV_29
+ <0x01220000 0x0100>, // VTSS_TO_DEV_30
+ <0x01230000 0x0100>, // VTSS_TO_DEV_31
+ <0x01240000 0x0100>, // VTSS_TO_DEV_32
+ <0x01250000 0x0100>, // VTSS_TO_DEV_33
+ <0x01260000 0x0100>, // VTSS_TO_DEV_34
+ <0x01270000 0x0100>, // VTSS_TO_DEV_35
+ <0x01280000 0x0100>, // VTSS_TO_DEV_36
+ <0x01290000 0x0100>, // VTSS_TO_DEV_37
+ <0x012a0000 0x0100>, // VTSS_TO_DEV_38
+ <0x012b0000 0x0100>, // VTSS_TO_DEV_39
+ <0x012c0000 0x0100>, // VTSS_TO_DEV_40
+ <0x012d0000 0x0100>, // VTSS_TO_DEV_41
+ <0x012e0000 0x0100>, // VTSS_TO_DEV_42
+ <0x012f0000 0x0100>, // VTSS_TO_DEV_43
+ <0x01300000 0x0100>, // VTSS_TO_DEV_44
+ <0x01310000 0x0100>, // VTSS_TO_DEV_45
+ <0x01320000 0x0100>, // VTSS_TO_DEV_46
+ <0x01330000 0x0100>, // VTSS_TO_DEV_47
+ <0x01f00000 0x100000>, // ANA_AC
+ <0x01d00000 0x100000>, // ANA_CL
+ <0x01e00000 0x100000>, // ANA_L2
+ <0x01410000 0x10000>, // ASM
+ <0x01460000 0x10000>, // HSIO
+ <0x01420000 0x00000>, // LRN
+ <0x017d0000 0x10000>, // QFWD
+ <0x01020000 0x20000>, // QS
+ <0x017e0000 0x10000>, // QSYS
+ <0x01b00000 0x80000>; // REW
+ reg-names = "port0", "port1", "port2", "port3", "port4",
+ "port5", "port6", "port7", "port8", "port9",
+ "port10", "port11", "port12", "port13",
+ "port14", "port15", "port16", "port17",
+ "port18", "port19", "port20", "port21",
+ "port22", "port23", "port24", "port25",
+ "port26", "port27", "port28", "port29",
+ "port30", "port31", "port32", "port33",
+ "port34", "port35", "port36", "port37",
+ "port38", "port39", "port40", "port41",
+ "port42", "port43", "port44", "port45",
+ "port46", "port47", "ana_ac", "ana_cl",
+ "ana_l2", "asm", "hsio", "lrn", "qfwd",
+ "qs", "qsys", "rew";
+ status = "okay";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ mdio0: mdio@010100c8 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mscc,jr2-miim";
+ reg = <0x010100c8 0x24>;
+ status = "disabled";
+ };
+
+ mdio1: mdio@010100ec {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mscc,jr2-miim";
+ reg = <0x010100ec 0x24>;
+ status = "disabled";
+ };
+
+ mdio2: mdio@01010110 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mscc,jr2-miim";
+ reg = <0x01010110 0x24>;
+ status = "disabled";
+ };
+
+ hsio: syscon@10d0000 {
+ compatible = "mscc,jr2-hsio", "syscon", "simple-mfd";
+ reg = <0x10d0000 0x10000>;
+
+ serdes_hsio: serdes_hsio {
+ compatible = "mscc,vsc7454-serdes";
+ #phy-cells = <3>;
+ };
+ };
};
};
diff --git a/arch/mips/dts/mscc,ocelot_pcb.dtsi b/arch/mips/dts/mscc,ocelot_pcb.dtsi
index 90725d3b941..885b5643f7c 100644
--- a/arch/mips/dts/mscc,ocelot_pcb.dtsi
+++ b/arch/mips/dts/mscc,ocelot_pcb.dtsi
@@ -29,7 +29,7 @@
pinctrl-names = "default";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
};
diff --git a/arch/mips/dts/mscc,servalt.dtsi b/arch/mips/dts/mscc,servalt.dtsi
index 4beb7a38d0c..45ae2de5e87 100644
--- a/arch/mips/dts/mscc,servalt.dtsi
+++ b/arch/mips/dts/mscc,servalt.dtsi
@@ -145,5 +145,45 @@
#gpio-cells = <2>;
gpio-ranges = <&sgpio 0 0 128>;
};
+
+ switch: switch@1010000 {
+ compatible = "mscc,vsc7437-switch";
+ reg = <0x01030000 0x0100>, // VTSS_TO_DEV_0
+ <0x01040000 0x0100>, // VTSS_TO_DEV_1
+ <0x01f00000 0x100000>, // ANA_AC
+ <0x01d00000 0x100000>, // ANA_CL
+ <0x01e00000 0x100000>, // ANA_L2
+ <0x01120000 0x10000>, // ASM
+ <0x01130000 0x00000>, // LRN
+ <0x017d0000 0x10000>, // QFWD
+ <0x01020000 0x20000>, // QS
+ <0x017e0000 0x10000>, // QSYS
+ <0x01b00000 0x80000>; // REW
+ reg-names = "port0", "port1",
+ "ana_ac", "ana_cl", "ana_l2", "asm", "lrn",
+ "qfwd", "qs", "qsys", "rew";
+ status = "okay";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ mdio0: mdio@010100c4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mscc,jr2-miim";
+ reg = <0x010100c4 0x24>;
+ status = "disabled";
+ };
+
+ mdio1: mdio@010100e8 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mscc,jr2-miim";
+ reg = <0x010100e8 0x24>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/mips/dts/netgear,cg3100d.dts b/arch/mips/dts/netgear,cg3100d.dts
index a3d4cd56a23..a42a0da2dd6 100644
--- a/arch/mips/dts/netgear,cg3100d.dts
+++ b/arch/mips/dts/netgear,cg3100d.dts
@@ -93,7 +93,7 @@
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/mips/dts/qca953x.dtsi b/arch/mips/dts/qca953x.dtsi
index ba29ea287e2..90d34ddbbfb 100644
--- a/arch/mips/dts/qca953x.dtsi
+++ b/arch/mips/dts/qca953x.dtsi
@@ -65,6 +65,37 @@
status = "disabled";
};
+
+ gmac0: eth0@0x19000000 {
+ compatible = "qca,ag953x-mac";
+ reg = <0x19000000 0x200>;
+ phy = <&phy4>;
+ phy-mode = "rmii";
+
+ status = "disabled";
+ };
+
+ gmac1: eth1@0x1a000000 {
+ compatible = "qca,ag953x-mac";
+ reg = <0x1a000000 0x200>;
+ phy = <&phy0>;
+ phy-mode = "rgmii";
+
+ status = "disabled";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ phy-mode = "rmii";
+ };
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ phy-mode = "rmii";
+ };
+ };
+ };
};
spi0: spi@1f000000 {
diff --git a/arch/mips/dts/qca956x.dtsi b/arch/mips/dts/qca956x.dtsi
new file mode 100644
index 00000000000..6cb360b3f86
--- /dev/null
+++ b/arch/mips/dts/qca956x.dtsi
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com>
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "qca,qca956x";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "mips,mips74Kc";
+ reg = <0>;
+ };
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ xtal: xtal {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-output-names = "xtal";
+ };
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ ranges;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ apb {
+ compatible = "simple-bus";
+ ranges;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@18020000 {
+ compatible = "ns16550";
+ reg = <0x18020000 0x20>;
+ reg-shift = <2>;
+
+ status = "disabled";
+ };
+
+ gmac0: eth@0x19000000 {
+ compatible = "qca,ag956x-mac";
+ reg = <0x19000000 0x200>;
+ phy = <&phy0>;
+ phy-mode = "sgmii";
+
+ status = "disabled";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+ };
+ };
+
+ spi0: spi@1f000000 {
+ compatible = "qca,ar7100-spi";
+ reg = <0x1f000000 0x10>;
+
+ status = "disabled";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
diff --git a/arch/mips/dts/sagem,f@st1704.dts b/arch/mips/dts/sagem,f@st1704.dts
index ec6846dd9f2..98ed353f207 100644
--- a/arch/mips/dts/sagem,f@st1704.dts
+++ b/arch/mips/dts/sagem,f@st1704.dts
@@ -59,7 +59,7 @@
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/mips/dts/serval2_pcb112.dts b/arch/mips/dts/serval2_pcb112.dts
index fe025f4c42a..5777a773b17 100644
--- a/arch/mips/dts/serval2_pcb112.dts
+++ b/arch/mips/dts/serval2_pcb112.dts
@@ -5,6 +5,7 @@
/dts-v1/;
#include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
/ {
model = "Serval2 NID PCB112 Reference Board";
@@ -43,7 +44,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
};
@@ -58,3 +59,46 @@
status = "okay";
sgpio-ports = <0x3fe0ffff>;
};
+
+&mdio0 {
+ status = "okay";
+
+ phy16: ethernet-phy@16 {
+ reg = <16>;
+ };
+ phy17: ethernet-phy@17 {
+ reg = <17>;
+ };
+ phy18: ethernet-phy@18 {
+ reg = <18>;
+ };
+ phy19: ethernet-phy@19 {
+ reg = <19>;
+ };
+};
+
+&switch {
+ ethernet-ports {
+
+ port0: port@0 {
+ reg = <24>;
+ phy-handle = <&phy16>;
+ phys = <&serdes_hsio 24 SERDES6G(0) PHY_MODE_SGMII>;
+ };
+ port1: port@1 {
+ reg = <25>;
+ phy-handle = <&phy17>;
+ phys = <&serdes_hsio 25 SERDES6G(1) PHY_MODE_SGMII>;
+ };
+ port2: port@2 {
+ reg = <26>;
+ phy-handle = <&phy18>;
+ phys = <&serdes_hsio 26 SERDES6G(2) PHY_MODE_SGMII>;
+ };
+ port3: port@3 {
+ reg = <27>;
+ phy-handle = <&phy19>;
+ phys = <&serdes_hsio 27 SERDES6G(3) PHY_MODE_SGMII>;
+ };
+ };
+};
diff --git a/arch/mips/dts/serval_pcb105.dts b/arch/mips/dts/serval_pcb105.dts
index d0d6facba22..1598669447f 100644
--- a/arch/mips/dts/serval_pcb105.dts
+++ b/arch/mips/dts/serval_pcb105.dts
@@ -43,7 +43,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
spi-cs-high;
diff --git a/arch/mips/dts/serval_pcb106.dts b/arch/mips/dts/serval_pcb106.dts
index 11982498d71..fb3524bb31e 100644
--- a/arch/mips/dts/serval_pcb106.dts
+++ b/arch/mips/dts/serval_pcb106.dts
@@ -43,7 +43,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
spi-cs-high;
diff --git a/arch/mips/dts/servalt_pcb116.dts b/arch/mips/dts/servalt_pcb116.dts
index fb3331204b3..313b0998e6b 100644
--- a/arch/mips/dts/servalt_pcb116.dts
+++ b/arch/mips/dts/servalt_pcb116.dts
@@ -43,7 +43,7 @@
&spi0 {
status = "okay";
spi-flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <18000000>; /* input clock */
reg = <0>; /* CS0 */
spi-cs-high;
@@ -54,3 +54,28 @@
status = "okay";
sgpio-ports = <0x0000fe7f>;
};
+
+&mdio0 {
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
+&switch {
+ ethernet-ports {
+
+ port0: port@0 {
+ reg = <0>;
+ phy-handle = <&phy0>;
+ };
+ port1: port@1 {
+ reg = <1>;
+ phy-handle = <&phy1>;
+ };
+ };
+};
diff --git a/arch/mips/dts/tplink_wdr4300.dts b/arch/mips/dts/tplink_wdr4300.dts
index 96cf0da5bfb..2bcad6d201b 100644
--- a/arch/mips/dts/tplink_wdr4300.dts
+++ b/arch/mips/dts/tplink_wdr4300.dts
@@ -35,7 +35,7 @@
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
memory-map = <0x1e000000 0x00800000>;
spi-max-frequency = <25000000>;
reg = <0>;
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index deca5189e33..35152cb3f64 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -215,23 +215,6 @@ static void linux_env_legacy(bootm_headers_t *images)
}
}
-static int boot_reloc_ramdisk(bootm_headers_t *images)
-{
- ulong rd_len = images->rd_end - images->rd_start;
-
- /*
- * In case of legacy uImage's, relocation of ramdisk is already done
- * by do_bootm_states() and should not repeated in 'bootm prep'.
- */
- if (images->state & BOOTM_STATE_RAMDISK) {
- debug("## Ramdisk already relocated\n");
- return 0;
- }
-
- return boot_ramdisk_high(&images->lmb, images->rd_start,
- rd_len, &images->initrd_start, &images->initrd_end);
-}
-
static int boot_reloc_fdt(bootm_headers_t *images)
{
/*
@@ -270,8 +253,6 @@ static int boot_setup_fdt(bootm_headers_t *images)
static void boot_prep_linux(bootm_headers_t *images)
{
- boot_reloc_ramdisk(images);
-
if (CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && images->ft_len) {
boot_reloc_fdt(images);
boot_setup_fdt(images);
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
index bc86f591df8..bdb23b57658 100644
--- a/arch/mips/mach-ath79/Kconfig
+++ b/arch/mips/mach-ath79/Kconfig
@@ -33,6 +33,15 @@ config SOC_QCA953X
help
This supports QCA/Atheros qca953x family SOCs.
+config SOC_QCA956X
+ bool
+ select MIPS_TUNE_74KC
+ select SUPPORTS_BIG_ENDIAN
+ select SUPPORTS_CPU_MIPS32_R1
+ select SUPPORTS_CPU_MIPS32_R2
+ help
+ This supports QCA/Atheros qca956x family SOCs.
+
choice
prompt "Board select"
@@ -44,6 +53,10 @@ config TARGET_AP143
bool "AP143 Reference Board"
select SOC_QCA953X
+config TARGET_AP152
+ bool "AP152 Reference Board"
+ select SOC_QCA956X
+
config BOARD_TPLINK_WDR4300
bool "TP-Link WDR4300 Board"
select SOC_AR934X
@@ -52,6 +65,7 @@ endchoice
source "board/qca/ap121/Kconfig"
source "board/qca/ap143/Kconfig"
+source "board/qca/ap152/Kconfig"
source "board/tplink/wdr4300/Kconfig"
endmenu
diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile
index 7aa40c65d30..fbd40c02bec 100644
--- a/arch/mips/mach-ath79/Makefile
+++ b/arch/mips/mach-ath79/Makefile
@@ -7,3 +7,4 @@ obj-y += dram.o
obj-$(CONFIG_SOC_AR933X) += ar933x/
obj-$(CONFIG_SOC_AR934X) += ar934x/
obj-$(CONFIG_SOC_QCA953X) += qca953x/
+obj-$(CONFIG_SOC_QCA956X) += qca956x/
diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
index 5d371bb5828..5888f6eb288 100644
--- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
+++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h
@@ -194,6 +194,9 @@
#define QCA956X_WMAC_BASE \
(AR71XX_APB_BASE + 0x00100000)
#define QCA956X_WMAC_SIZE 0x20000
+#define QCA956X_RTC_BASE \
+ (AR71XX_APB_BASE + 0x00107000)
+#define QCA956X_RTC_SIZE 0x1000
#define QCA956X_EHCI0_BASE 0x1b000000
#define QCA956X_EHCI1_BASE 0x1b400000
#define QCA956X_EHCI_SIZE 0x200
@@ -201,6 +204,10 @@
(AR71XX_APB_BASE + 0x00070000)
#define QCA956X_GMAC_SIZE 0x64
+#define QCA956X_SRIF_BASE \
+ (AR71XX_APB_BASE + 0x00116000)
+#define QCA956X_SRIF_SIZE 0x1000
+
/*
* DDR_CTRL block
*/
@@ -278,6 +285,18 @@
#define QCA953X_DDR_REG_CTL_CONF 0x108
#define QCA953X_DDR_REG_CONFIG3 0x15c
+#define QCA956X_DDR_REG_TAP_CTRL2 0x24
+#define QCA956X_DDR_REG_TAP_CTRL3 0x28
+#define QCA956X_DDR_REG_DDR2_CONFIG 0xb8
+#define QCA956X_DDR_REG_DDR2_EMR2 0xbc
+#define QCA956X_DDR_REG_DDR2_EMR3 0xc0
+#define QCA956X_DDR_REG_BURST 0xc4
+#define QCA956X_DDR_REG_BURST2 0xc8
+#define QCA956X_DDR_REG_TIMEOUT_MAX 0xcc
+#define QCA956X_DDR_REG_FSM_WAIT_CTRL 0xe4
+#define QCA956X_DDR_REG_CTL_CONF 0x108
+#define QCA956X_DDR_REG_DDR3_CONFIG 0x15c
+
/*
* PLL block
*/
@@ -519,6 +538,13 @@
#define QCA956X_PLL_DDR_CONFIG_REG 0x08
#define QCA956X_PLL_DDR_CONFIG1_REG 0x0c
#define QCA956X_PLL_CLK_CTRL_REG 0x10
+#define QCA956X_PLL_SWITCH_CLK_CTRL_REG 0x28
+#define QCA956X_PLL_ETH_XMII_CTRL_REG 0x30
+#define QCA956X_PLL_DDR_DIT_FRAC_REG 0x38
+#define QCA956X_PLL_DDR_DIT2_FRAC_REG 0x3c
+#define QCA956X_PLL_CPU_DIT_FRAC_REG 0x40
+#define QCA956X_PLL_CPU_DIT2_FRAC_REG 0x44
+#define QCA956X_PLL_ETH_SGMII_SERDES_REG 0x4c
#define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
#define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
@@ -528,7 +554,7 @@
#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT 0
#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK 0x1f
#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT 5
-#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x3fff
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x1fff
#define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT 18
#define QCA956X_PLL_CPU_CONFIG1_NINT_MASK 0x1ff
@@ -540,7 +566,7 @@
#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT 0
#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK 0x1f
#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT 5
-#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x3fff
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x1fff
#define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT 18
#define QCA956X_PLL_DDR_CONFIG1_NINT_MASK 0x1ff
@@ -756,6 +782,17 @@
#define QCA955X_RESET_MBOX BIT(1)
#define QCA955X_RESET_I2S BIT(0)
+#define QCA956X_RESET_EXTERNAL BIT(28)
+#define QCA956X_RESET_FULL_CHIP BIT(24)
+#define QCA956X_RESET_GE1_MDIO BIT(23) /* Reserved in datasheet */
+#define QCA956X_RESET_GE0_MDIO BIT(22)
+#define QCA956X_RESET_GE1_MAC BIT(13) /* Reserved in datasheet */
+#define QCA956X_RESET_SGMII_ASSERT BIT(12)
+#define QCA956X_RESET_GE0_MAC BIT(9)
+#define QCA956X_RESET_SGMII BIT(8)
+#define QCA956X_RESET_SGMII_ANALOG BIT(2)
+#define QCA956X_RESET_SWITCH BIT(0)
+
#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18)
#define AR933X_BOOTSTRAP_DDR2 BIT(13)
#define AR933X_BOOTSTRAP_EEPBUSY BIT(4)
@@ -1099,8 +1136,12 @@
#define QCA953X_GPIO_IN_MUX_UART0_SIN 9
#define QCA953X_GPIO_IN_MUX_SPI_DATA_IN 8
+#define QCA956X_GPIO(x) BIT(x)
+#define QCA956X_GPIO_MUX_MASK(x) (0xff << (x))
#define QCA956X_GPIO_OUT_MUX_GE0_MDO 32
#define QCA956X_GPIO_OUT_MUX_GE0_MDC 33
+#define QCA956X_GPIO_IN_MUX_UART0_SIN 0x12
+#define QCA956X_GPIO_OUT_MUX_UART0_SOUT 0x16
#define AR71XX_GPIO_COUNT 16
#define AR7240_GPIO_COUNT 18
@@ -1179,6 +1220,25 @@
#define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT 13
#define QCA953X_SRIF_DPLL2_OUTDIV_MASK 0x7
+#define QCA956X_SRIF_BB_DPLL1_REG 0x180
+#define QCA956X_SRIF_BB_DPLL2_REG 0x184
+#define QCA956X_SRIF_BB_DPLL3_REG 0x188
+
+#define QCA956X_SRIF_CPU_DPLL1_REG 0xf00
+#define QCA956X_SRIF_CPU_DPLL2_REG 0xf04
+#define QCA956X_SRIF_CPU_DPLL3_REG 0xf08
+
+#define QCA956X_SRIF_DDR_DPLL1_REG 0xec0
+#define QCA956X_SRIF_DDR_DPLL2_REG 0xec4
+#define QCA956X_SRIF_DDR_DPLL3_REG 0xec8
+
+#define QCA956X_SRIF_PCIE_DPLL1_REG 0xc80
+#define QCA956X_SRIF_PCIE_DPLL2_REG 0xc84
+#define QCA956X_SRIF_PCIE_DPLL3_REG 0xc88
+
+#define QCA956X_SRIF_PMU1_REG 0xcc0
+#define QCA956X_SRIF_PMU2_REG 0xcc4
+
/*
* MII_CTRL block
*/
@@ -1261,4 +1321,17 @@
#define QCA955X_ETH_CFG_RGMII_EN BIT(0)
#define QCA955X_ETH_CFG_GE0_SGMII BIT(6)
+/*
+ * QCA956X GMAC Interface
+ */
+
+#define QCA956X_GMAC_REG_ETH_CFG 0x00
+#define QCA956X_GMAC_REG_SGMII_RESET 0x14
+#define QCA956X_GMAC_REG_SGMII_SERDES 0x18
+#define QCA956X_GMAC_REG_MR_AN_CTRL 0x1c
+#define QCA956X_GMAC_REG_SGMII_CONFIG 0x34
+#define QCA956X_GMAC_REG_SGMII_DEBUG 0x58
+
+#define QCA956X_ETH_CFG_GE0_SGMII BIT(6)
+
#endif /* __ASM_AR71XX_H */
diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h
index 5de7a43f79e..0fde5079b16 100644
--- a/arch/mips/mach-ath79/include/mach/ath79.h
+++ b/arch/mips/mach-ath79/include/mach/ath79.h
@@ -2,6 +2,7 @@
/*
* Atheros AR71XX/AR724X/AR913X common definitions
*
+ * Copyright (C) 2018-2019 Rosy Song <rosysong@rosinson.com>
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
@@ -146,4 +147,6 @@ int ath79_usb_reset(void);
void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
+void qca956x_pll_init(void);
+void qca956x_ddr_init(void);
#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/mach-ath79/qca956x/Makefile b/arch/mips/mach-ath79/qca956x/Makefile
new file mode 100644
index 00000000000..3f5fc0363f1
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += cpu.o
+obj-y += clk.o
+obj-y += ddr.o qca956x-ddr-tap.o
diff --git a/arch/mips/mach-ath79/qca956x/clk.c b/arch/mips/mach-ath79/qca956x/clk.c
new file mode 100644
index 00000000000..33a44cfff48
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/clk.c
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ath79.h>
+#include <wait_bit.h>
+
+#define PLL_SRIF_DPLL2_KI_LSB 29
+#define PLL_SRIF_DPLL2_KI_MASK 0x60000000
+#define PLL_SRIF_DPLL2_KI_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_KI_LSB) & PLL_SRIF_DPLL2_KI_MASK)
+#define PLL_SRIF_DPLL2_KD_LSB 25
+#define PLL_SRIF_DPLL2_KD_MASK 0x1e000000
+#define PLL_SRIF_DPLL2_KD_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_KD_LSB) & PLL_SRIF_DPLL2_KD_MASK)
+#define PLL_SRIF_DPLL2_PLL_PWD_LSB 22
+#define PLL_SRIF_DPLL2_PLL_PWD_MASK 0x00400000
+#define PLL_SRIF_DPLL2_PLL_PWD_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_PLL_PWD_LSB) & PLL_SRIF_DPLL2_PLL_PWD_MASK)
+#define PLL_SRIF_DPLL2_OUTDIV_LSB 19
+#define PLL_SRIF_DPLL2_OUTDIV_MASK 0x00380000
+#define PLL_SRIF_DPLL2_OUTDIV_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_OUTDIV_LSB) & PLL_SRIF_DPLL2_OUTDIV_MASK)
+#define PLL_SRIF_DPLL2_PHASE_SHIFT_LSB 12
+#define PLL_SRIF_DPLL2_PHASE_SHIFT_MASK 0x0007f000
+#define PLL_SRIF_DPLL2_PHASE_SHIFT_SET(x) \
+ (((x) << PLL_SRIF_DPLL2_PHASE_SHIFT_LSB) & PLL_SRIF_DPLL2_PHASE_SHIFT_MASK)
+#define CPU_PLL_CONFIG_PLLPWD_LSB 30
+#define CPU_PLL_CONFIG_PLLPWD_MASK 0x40000000
+#define CPU_PLL_CONFIG_PLLPWD_SET(x) \
+ (((x) << CPU_PLL_CONFIG_PLLPWD_LSB) & CPU_PLL_CONFIG_PLLPWD_MASK)
+#define CPU_PLL_CONFIG_OUTDIV_LSB 19
+#define CPU_PLL_CONFIG_OUTDIV_MASK 0x00380000
+#define CPU_PLL_CONFIG_OUTDIV_SET(x) \
+ (((x) << CPU_PLL_CONFIG_OUTDIV_LSB) & CPU_PLL_CONFIG_OUTDIV_MASK)
+#define CPU_PLL_CONFIG_RANGE_LSB 17
+#define CPU_PLL_CONFIG_RANGE_MASK 0x00060000
+#define CPU_PLL_CONFIG_RANGE_SET(x) \
+ (((x) << CPU_PLL_CONFIG_RANGE_LSB) & CPU_PLL_CONFIG_RANGE_MASK)
+#define CPU_PLL_CONFIG_REFDIV_LSB 12
+#define CPU_PLL_CONFIG_REFDIV_MASK 0x0001f000
+#define CPU_PLL_CONFIG_REFDIV_SET(x) \
+ (((x) << CPU_PLL_CONFIG_REFDIV_LSB) & CPU_PLL_CONFIG_REFDIV_MASK)
+#define CPU_PLL_CONFIG1_NINT_LSB 18
+#define CPU_PLL_CONFIG1_NINT_MASK 0x07fc0000
+#define CPU_PLL_CONFIG1_NINT_SET(x) \
+ (((x) << CPU_PLL_CONFIG1_NINT_LSB) & CPU_PLL_CONFIG1_NINT_MASK)
+#define CPU_PLL_DITHER1_DITHER_EN_LSB 31
+#define CPU_PLL_DITHER1_DITHER_EN_MASK 0x80000000
+#define CPU_PLL_DITHER1_DITHER_EN_SET(x) \
+ (((x) << CPU_PLL_DITHER1_DITHER_EN_LSB) & CPU_PLL_DITHER1_DITHER_EN_MASK)
+#define CPU_PLL_DITHER1_UPDATE_COUNT_LSB 24
+#define CPU_PLL_DITHER1_UPDATE_COUNT_MASK 0x3f000000
+#define CPU_PLL_DITHER1_UPDATE_COUNT_SET(x) \
+ (((x) << CPU_PLL_DITHER1_UPDATE_COUNT_LSB) & CPU_PLL_DITHER1_UPDATE_COUNT_MASK)
+#define CPU_PLL_DITHER1_NFRAC_STEP_LSB 18
+#define CPU_PLL_DITHER1_NFRAC_STEP_MASK 0x00fc0000
+#define CPU_PLL_DITHER1_NFRAC_STEP_SET(x) \
+ (((x) << CPU_PLL_DITHER1_NFRAC_STEP_LSB) & CPU_PLL_DITHER1_NFRAC_STEP_MASK)
+#define CPU_PLL_DITHER1_NFRAC_MIN_LSB 0
+#define CPU_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
+#define CPU_PLL_DITHER1_NFRAC_MIN_SET(x) \
+ (((x) << CPU_PLL_DITHER1_NFRAC_MIN_LSB) & CPU_PLL_DITHER1_NFRAC_MIN_MASK)
+#define CPU_PLL_DITHER2_NFRAC_MAX_LSB 0
+#define CPU_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
+#define CPU_PLL_DITHER2_NFRAC_MAX_SET(x) \
+ (((x) << CPU_PLL_DITHER2_NFRAC_MAX_LSB) & CPU_PLL_DITHER2_NFRAC_MAX_MASK)
+#define DDR_PLL_CONFIG_PLLPWD_LSB 30
+#define DDR_PLL_CONFIG_PLLPWD_MASK 0x40000000
+#define DDR_PLL_CONFIG_PLLPWD_SET(x) \
+ (((x) << DDR_PLL_CONFIG_PLLPWD_LSB) & DDR_PLL_CONFIG_PLLPWD_MASK)
+#define DDR_PLL_CONFIG_OUTDIV_LSB 23
+#define DDR_PLL_CONFIG_OUTDIV_MASK 0x03800000
+#define DDR_PLL_CONFIG_OUTDIV_SET(x) \
+ (((x) << DDR_PLL_CONFIG_OUTDIV_LSB) & DDR_PLL_CONFIG_OUTDIV_MASK)
+#define DDR_PLL_CONFIG_RANGE_LSB 21
+#define DDR_PLL_CONFIG_RANGE_MASK 0x00600000
+#define DDR_PLL_CONFIG_RANGE_SET(x) \
+ (((x) << DDR_PLL_CONFIG_RANGE_LSB) & DDR_PLL_CONFIG_RANGE_MASK)
+#define DDR_PLL_CONFIG_REFDIV_LSB 16
+#define DDR_PLL_CONFIG_REFDIV_MASK 0x001f0000
+#define DDR_PLL_CONFIG_REFDIV_SET(x) \
+ (((x) << DDR_PLL_CONFIG_REFDIV_LSB) & DDR_PLL_CONFIG_REFDIV_MASK)
+#define DDR_PLL_CONFIG1_NINT_LSB 18
+#define DDR_PLL_CONFIG1_NINT_MASK 0x07fc0000
+#define DDR_PLL_CONFIG1_NINT_SET(x) \
+ (((x) << DDR_PLL_CONFIG1_NINT_LSB) & DDR_PLL_CONFIG1_NINT_MASK)
+#define DDR_PLL_DITHER1_DITHER_EN_LSB 31
+#define DDR_PLL_DITHER1_DITHER_EN_MASK 0x80000000
+#define DDR_PLL_DITHER1_DITHER_EN_SET(x) \
+ (((x) << DDR_PLL_DITHER1_DITHER_EN_LSB) & DDR_PLL_DITHER1_DITHER_EN_MASK)
+#define DDR_PLL_DITHER1_UPDATE_COUNT_LSB 27
+#define DDR_PLL_DITHER1_UPDATE_COUNT_MASK 0x78000000
+#define DDR_PLL_DITHER1_UPDATE_COUNT_SET(x) \
+ (((x) << DDR_PLL_DITHER1_UPDATE_COUNT_LSB) & DDR_PLL_DITHER1_UPDATE_COUNT_MASK)
+#define DDR_PLL_DITHER1_NFRAC_STEP_LSB 20
+#define DDR_PLL_DITHER1_NFRAC_STEP_MASK 0x07f00000
+#define DDR_PLL_DITHER1_NFRAC_STEP_SET(x) \
+ (((x) << DDR_PLL_DITHER1_NFRAC_STEP_LSB) & DDR_PLL_DITHER1_NFRAC_STEP_MASK)
+#define DDR_PLL_DITHER1_NFRAC_MIN_LSB 0
+#define DDR_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff
+#define DDR_PLL_DITHER1_NFRAC_MIN_SET(x) \
+ (((x) << DDR_PLL_DITHER1_NFRAC_MIN_LSB) & DDR_PLL_DITHER1_NFRAC_MIN_MASK)
+#define DDR_PLL_DITHER2_NFRAC_MAX_LSB 0
+#define DDR_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff
+#define DDR_PLL_DITHER2_NFRAC_MAX_SET(x) \
+ (((x) << DDR_PLL_DITHER2_NFRAC_MAX_LSB) & DDR_PLL_DITHER2_NFRAC_MAX_MASK)
+#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB 24
+#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK 0x01000000
+#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB 21
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK 0x00200000
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB 20
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK 0x00100000
+#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK)
+#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB 15
+#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK 0x000f8000
+#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK)
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB 10
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK 0x00007c00
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB 5
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK 0x000003e0
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK)
+#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB 4
+#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK 0x00000010
+#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK)
+#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB 3
+#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK 0x00000008
+#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK)
+#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB 2
+#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK 0x00000004
+#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(x) \
+ (((x) << CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK)
+
+#define CPU_PLL_CONFIG1_NINT_VAL CPU_PLL_CONFIG1_NINT_SET(0x1f)
+#define CPU_PLL_CONFIG_REF_DIV_VAL CPU_PLL_CONFIG_REFDIV_SET(0x1)
+#define CPU_PLL_CONFIG_RANGE_VAL CPU_PLL_CONFIG_RANGE_SET(0)
+#define CPU_PLL_CONFIG_OUT_DIV_VAL1 CPU_PLL_CONFIG_OUTDIV_SET(0)
+#define CPU_PLL_CONFIG_OUT_DIV_VAL2 CPU_PLL_CONFIG_OUTDIV_SET(0)
+#define CPU_PLL_DITHER1_VAL CPU_PLL_DITHER1_DITHER_EN_SET(0) | \
+ CPU_PLL_DITHER1_NFRAC_MIN_SET(0) | \
+ CPU_PLL_DITHER1_NFRAC_STEP_SET(0) | \
+ CPU_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
+#define CPU_PLL_DITHER2_VAL CPU_PLL_DITHER2_NFRAC_MAX_SET(0x0)
+#define DDR_PLL_CONFIG1_NINT_VAL DDR_PLL_CONFIG1_NINT_SET(0x1a)
+#define DDR_PLL_CONFIG_REF_DIV_VAL DDR_PLL_CONFIG_REFDIV_SET(0x1)
+#define DDR_PLL_CONFIG_RANGE_VAL DDR_PLL_CONFIG_RANGE_SET(0)
+#define DDR_PLL_CONFIG_OUT_DIV_VAL1 DDR_PLL_CONFIG_OUTDIV_SET(0)
+#define DDR_PLL_CONFIG_OUT_DIV_VAL2 DDR_PLL_CONFIG_OUTDIV_SET(0)
+#define DDR_PLL_DITHER1_VAL DDR_PLL_DITHER1_DITHER_EN_SET(0) | \
+ DDR_PLL_DITHER1_NFRAC_MIN_SET(0) | \
+ DDR_PLL_DITHER1_NFRAC_STEP_SET(0) | \
+ DDR_PLL_DITHER1_UPDATE_COUNT_SET(0x0)
+#define DDR_PLL_DITHER2_VAL DDR_PLL_DITHER2_NFRAC_MAX_SET(0x0)
+#define AHB_CLK_FROM_DDR CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(0)
+#define CPU_AND_DDR_CLK_FROM_DDR \
+ CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(0)
+#define CPU_AND_DDR_CLK_FROM_CPU \
+ CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(0)
+#define CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL \
+ CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(0x2)
+#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV \
+ CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(0)
+#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV \
+ CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(0)
+
+static inline void set_val(u32 _reg, u32 _mask, u32 _val)
+{
+ void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE, MAP_NOCACHE);
+ writel((readl(pll_regs + _reg) & (~(_mask))) | _val, pll_regs + _reg);
+}
+
+#define cpu_pll_set(_mask, _val) \
+ set_val(QCA956X_PLL_CPU_CONFIG_REG, _mask, _val)
+
+#define ddr_pll_set(_mask, _val) \
+ set_val(QCA956X_PLL_DDR_CONFIG_REG, _mask, _val)
+
+#define cpu_ddr_control_set(_mask, _val) \
+ set_val(QCA956X_PLL_CLK_CTRL_REG, _mask, _val)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static u32 qca956x_get_xtal(void)
+{
+ u32 val;
+
+ val = ath79_get_bootstrap();
+ if (val & QCA956X_BOOTSTRAP_REF_CLK_40)
+ return 40000000;
+ else
+ return 25000000;
+}
+
+int get_serial_clock(void)
+{
+ return qca956x_get_xtal();
+}
+
+void qca956x_pll_init(void)
+{
+ void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE,
+ QCA956X_SRIF_SIZE, MAP_NOCACHE);
+ void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE, MAP_NOCACHE);
+
+ /* 8.16.2 Baseband DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(1) |
+ PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_BB_DPLL2_REG);
+
+ /* 8.16.2 PCIE DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(3) |
+ PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_PCIE_DPLL2_REG);
+
+ /* 8.16.2 DDR DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
+ srif_regs + QCA956X_SRIF_DDR_DPLL2_REG);
+
+ /* 8.16.2 CPU DPLL2 */
+ writel(PLL_SRIF_DPLL2_KI_SET(1) | PLL_SRIF_DPLL2_KD_SET(7) |
+ PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6),
+ srif_regs + QCA956X_SRIF_CPU_DPLL2_REG);
+
+ /* pll_bypass_set */
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1));
+
+ /* init_cpu_pll */
+ cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(1));
+ cpu_pll_set(CPU_PLL_CONFIG_REFDIV_MASK, CPU_PLL_CONFIG_REF_DIV_VAL);
+ cpu_pll_set(CPU_PLL_CONFIG_RANGE_MASK, CPU_PLL_CONFIG_RANGE_VAL);
+ cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL1);
+ set_val(QCA956X_PLL_CPU_CONFIG1_REG, CPU_PLL_CONFIG1_NINT_MASK, \
+ CPU_PLL_CONFIG1_NINT_VAL);
+
+ /* init_ddr_pll */
+ ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(1));
+ ddr_pll_set(DDR_PLL_CONFIG_REFDIV_MASK, DDR_PLL_CONFIG_REF_DIV_VAL);
+ ddr_pll_set(DDR_PLL_CONFIG_RANGE_MASK, DDR_PLL_CONFIG_RANGE_VAL);
+ ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL1);
+ set_val(QCA956X_PLL_DDR_CONFIG1_REG, DDR_PLL_CONFIG1_NINT_MASK,
+ DDR_PLL_CONFIG1_NINT_VAL);
+
+ /* init_ahb_pll */
+ writel(CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL | AHB_CLK_FROM_DDR |
+ CPU_AND_DDR_CLK_FROM_DDR | CPU_AND_DDR_CLK_FROM_CPU |
+ CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV | CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV |
+ CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1) |
+ CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1) |
+ CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1), pll_regs + QCA956X_PLL_CLK_CTRL_REG);
+
+ /* ddr_pll_dither_unset */
+ writel(DDR_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_DDR_DIT_FRAC_REG);
+ writel(DDR_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_DDR_DIT2_FRAC_REG);
+
+ /* cpu_pll_dither_unset */
+ writel(CPU_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_CPU_DIT_FRAC_REG);
+ writel(CPU_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_CPU_DIT2_FRAC_REG);
+
+ /* pll_pwd_unset */
+ cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(0));
+ ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(0));
+
+ /* outdiv_unset */
+ cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL2);
+ ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL2);
+
+ /* pll_bypass_unset */
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(0));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(0));
+ cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK,
+ CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(0));
+
+ while (readl(pll_regs + QCA956X_PLL_CPU_CONFIG_REG) & 0x8000000)
+ /* NOP */;
+
+ while (readl(pll_regs + QCA956X_PLL_DDR_CONFIG_REG) & 0x8000000)
+ /* NOP */;
+}
+
+int get_clocks(void)
+{
+ void __iomem *regs;
+ u32 ref_rate, cpu_rate, ddr_rate, ahb_rate;
+ u32 out_div, ref_div, postdiv, nint, hfrac, lfrac, clk_ctrl;
+ u32 pll, cpu_pll, ddr_pll, misc;
+
+ /*
+ * QCA956x timer init workaround has to be applied right before setting
+ * up the clock. Else, there will be no jiffies
+ */
+ regs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ misc = readl(regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
+ writel(misc, regs + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+ MAP_NOCACHE);
+ pll = readl(regs + QCA956X_PLL_CPU_CONFIG_REG);
+ out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
+
+ pll = readl(regs + QCA956X_PLL_CPU_CONFIG1_REG);
+ nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
+ hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK;
+ lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK;
+
+ ref_rate = qca956x_get_xtal();
+
+ cpu_pll = nint * ref_rate / ref_div;
+ cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
+ cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
+ cpu_pll /= (1 << out_div);
+
+ pll = readl(regs + QCA956X_PLL_DDR_CONFIG_REG);
+ out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
+ pll = readl(regs + QCA956X_PLL_DDR_CONFIG1_REG);
+ nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
+ hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK;
+ lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK;
+
+ ddr_pll = nint * ref_rate / ref_div;
+ ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
+ ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
+ ddr_pll /= (1 << out_div);
+
+ clk_ctrl = readl(regs + QCA956X_PLL_CLK_CTRL_REG);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
+ cpu_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL)
+ cpu_rate = ddr_pll / (postdiv + 1);
+ else
+ cpu_rate = cpu_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
+ ddr_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL)
+ ddr_rate = cpu_pll / (postdiv + 1);
+ else
+ ddr_rate = ddr_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
+ ahb_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
+ ahb_rate = ddr_pll / (postdiv + 1);
+ else
+ ahb_rate = cpu_pll / (postdiv + 1);
+
+ gd->cpu_clk = cpu_rate;
+ gd->mem_clk = ddr_rate;
+ gd->bus_clk = ahb_rate;
+
+ debug("cpu_clk=%u, ddr_clk=%u, bus_clk=%u\n",
+ cpu_rate, ddr_rate, ahb_rate);
+
+ return 0;
+}
+
+ulong get_bus_freq(ulong dummy)
+{
+ if (!gd->bus_clk)
+ get_clocks();
+ return gd->bus_clk;
+}
+
+ulong get_ddr_freq(ulong dummy)
+{
+ if (!gd->mem_clk)
+ get_clocks();
+ return gd->mem_clk;
+}
diff --git a/arch/mips/mach-ath79/qca956x/cpu.c b/arch/mips/mach-ath79/qca956x/cpu.c
new file mode 100644
index 00000000000..08a8c84e72d
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/cpu.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
+ */
+
+#include <common.h>
+
+/* The lowlevel_init() is not needed on QCA956X */
+void lowlevel_init(void) {}
diff --git a/arch/mips/mach-ath79/qca956x/ddr.c b/arch/mips/mach-ath79/qca956x/ddr.c
new file mode 100644
index 00000000000..fb2230430c6
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/ddr.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
+ *
+ * Based on QSDK
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ath79.h>
+
+#define DDR_FSM_WAIT_CTRL_VAL 0xa12
+#define DDR_CTL_CONFIG_SRAM_TSEL_LSB 30
+#define DDR_CTL_CONFIG_SRAM_TSEL_MASK 0xc0000000
+#define DDR_CTL_CONFIG_SRAM_TSEL_SET(x) \
+ (((x) << DDR_CTL_CONFIG_SRAM_TSEL_LSB) & DDR_CTL_CONFIG_SRAM_TSEL_MASK)
+#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB 20
+#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK 0x00100000
+#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB 19
+#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK 0x00080000
+#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB 18
+#define DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK 0x00040000
+#define DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB 17
+#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK 0x00020000
+#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB 16
+#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK 0x00010000
+#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB 15
+#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK 0x00008000
+#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB 14
+#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK 0x00004000
+#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK)
+#define DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB 6
+#define DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK 0x00000040
+#define DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(x) \
+ (((x) << DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB) & DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK)
+#define DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB 2
+#define DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK 0x00000004
+#define DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(x) \
+ (((x) << DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB) & DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK)
+#define DDR_CTL_CONFIG_HALF_WIDTH_LSB 1
+#define DDR_CTL_CONFIG_HALF_WIDTH_MASK 0x00000002
+#define DDR_CTL_CONFIG_HALF_WIDTH_SET(x) \
+ (((x) << DDR_CTL_CONFIG_HALF_WIDTH_LSB) & DDR_CTL_CONFIG_HALF_WIDTH_MASK)
+#define DDR_CONFIG_CAS_LATENCY_MSB_LSB 31
+#define DDR_CONFIG_CAS_LATENCY_MSB_MASK 0x80000000
+#define DDR_CONFIG_CAS_LATENCY_MSB_SET(x) \
+ (((x) << DDR_CONFIG_CAS_LATENCY_MSB_LSB) & DDR_CONFIG_CAS_LATENCY_MSB_MASK)
+#define DDR_CONFIG_OPEN_PAGE_LSB 30
+#define DDR_CONFIG_OPEN_PAGE_MASK 0x40000000
+#define DDR_CONFIG_OPEN_PAGE_SET(x) \
+ (((x) << DDR_CONFIG_OPEN_PAGE_LSB) & DDR_CONFIG_OPEN_PAGE_MASK)
+#define DDR_CONFIG_CAS_LATENCY_LSB 27
+#define DDR_CONFIG_CAS_LATENCY_MASK 0x38000000
+#define DDR_CONFIG_CAS_LATENCY_SET(x) \
+ (((x) << DDR_CONFIG_CAS_LATENCY_LSB) & DDR_CONFIG_CAS_LATENCY_MASK)
+#define DDR_CONFIG_TMRD_LSB 23
+#define DDR_CONFIG_TMRD_MASK 0x07800000
+#define DDR_CONFIG_TMRD_SET(x) \
+ (((x) << DDR_CONFIG_TMRD_LSB) & DDR_CONFIG_TMRD_MASK)
+#define DDR_CONFIG_TRFC_LSB 17
+#define DDR_CONFIG_TRFC_MASK 0x007e0000
+#define DDR_CONFIG_TRFC_SET(x) \
+ (((x) << DDR_CONFIG_TRFC_LSB) & DDR_CONFIG_TRFC_MASK)
+#define DDR_CONFIG_TRRD_LSB 13
+#define DDR_CONFIG_TRRD_MASK 0x0001e000
+#define DDR_CONFIG_TRRD_SET(x) \
+ (((x) << DDR_CONFIG_TRRD_LSB) & DDR_CONFIG_TRRD_MASK)
+#define DDR_CONFIG_TRP_LSB 9
+#define DDR_CONFIG_TRP_MASK 0x00001e00
+#define DDR_CONFIG_TRP_SET(x) \
+ (((x) << DDR_CONFIG_TRP_LSB) & DDR_CONFIG_TRP_MASK)
+#define DDR_CONFIG_TRCD_LSB 5
+#define DDR_CONFIG_TRCD_MASK 0x000001e0
+#define DDR_CONFIG_TRCD_SET(x) \
+ (((x) << DDR_CONFIG_TRCD_LSB) & DDR_CONFIG_TRCD_MASK)
+#define DDR_CONFIG_TRAS_LSB 0
+#define DDR_CONFIG_TRAS_MASK 0x0000001f
+#define DDR_CONFIG_TRAS_SET(x) \
+ (((x) << DDR_CONFIG_TRAS_LSB) & DDR_CONFIG_TRAS_MASK)
+#define DDR_CONFIG2_HALF_WIDTH_LOW_LSB 31
+#define DDR_CONFIG2_HALF_WIDTH_LOW_MASK 0x80000000
+#define DDR_CONFIG2_HALF_WIDTH_LOW_SET(x) \
+ (((x) << DDR_CONFIG2_HALF_WIDTH_LOW_LSB) & DDR_CONFIG2_HALF_WIDTH_LOW_MASK)
+#define DDR_CONFIG2_SWAP_A26_A27_LSB 30
+#define DDR_CONFIG2_SWAP_A26_A27_MASK 0x40000000
+#define DDR_CONFIG2_SWAP_A26_A27_SET(x) \
+ (((x) << DDR_CONFIG2_SWAP_A26_A27_LSB) & DDR_CONFIG2_SWAP_A26_A27_MASK)
+#define DDR_CONFIG2_GATE_OPEN_LATENCY_LSB 26
+#define DDR_CONFIG2_GATE_OPEN_LATENCY_MASK 0x3c000000
+#define DDR_CONFIG2_GATE_OPEN_LATENCY_SET(x) \
+ (((x) << DDR_CONFIG2_GATE_OPEN_LATENCY_LSB) & DDR_CONFIG2_GATE_OPEN_LATENCY_MASK)
+#define DDR_CONFIG2_TWTR_LSB 21
+#define DDR_CONFIG2_TWTR_MASK 0x03e00000
+#define DDR_CONFIG2_TWTR_SET(x) \
+ (((x) << DDR_CONFIG2_TWTR_LSB) & DDR_CONFIG2_TWTR_MASK)
+#define DDR_CONFIG2_TRTP_LSB 17
+#define DDR_CONFIG2_TRTP_MASK 0x001e0000
+#define DDR_CONFIG2_TRTP_SET(x) \
+ (((x) << DDR_CONFIG2_TRTP_LSB) & DDR_CONFIG2_TRTP_MASK)
+#define DDR_CONFIG2_TRTW_LSB 12
+#define DDR_CONFIG2_TRTW_MASK 0x0001f000
+#define DDR_CONFIG2_TRTW_SET(x) \
+ (((x) << DDR_CONFIG2_TRTW_LSB) & DDR_CONFIG2_TRTW_MASK)
+#define DDR_CONFIG2_TWR_LSB 8
+#define DDR_CONFIG2_TWR_MASK 0x00000f00
+#define DDR_CONFIG2_TWR_SET(x) \
+ (((x) << DDR_CONFIG2_TWR_LSB) & DDR_CONFIG2_TWR_MASK)
+#define DDR_CONFIG2_CKE_LSB 7
+#define DDR_CONFIG2_CKE_MASK 0x00000080
+#define DDR_CONFIG2_CKE_SET(x) \
+ (((x) << DDR_CONFIG2_CKE_LSB) & DDR_CONFIG2_CKE_MASK)
+#define DDR_CONFIG2_CNTL_OE_EN_LSB 5
+#define DDR_CONFIG2_CNTL_OE_EN_MASK 0x00000020
+#define DDR_CONFIG2_CNTL_OE_EN_SET(x) \
+ (((x) << DDR_CONFIG2_CNTL_OE_EN_LSB) & DDR_CONFIG2_CNTL_OE_EN_MASK)
+#define DDR_CONFIG2_BURST_LENGTH_LSB 0
+#define DDR_CONFIG2_BURST_LENGTH_MASK 0x0000000f
+#define DDR_CONFIG2_BURST_LENGTH_SET(x) \
+ (((x) << DDR_CONFIG2_BURST_LENGTH_LSB) & DDR_CONFIG2_BURST_LENGTH_MASK)
+#define RST_BOOTSTRAP_ADDRESS 0x180600b0
+#define PMU2_SWREGMSB_LSB 22
+#define PMU2_SWREGMSB_MASK 0xffc00000
+#define PMU2_SWREGMSB_SET(x) \
+ (((x) << PMU2_SWREGMSB_LSB) & PMU2_SWREGMSB_MASK)
+#define PMU2_PGM_LSB 21
+#define PMU2_PGM_MASK 0x00200000
+#define PMU2_PGM_SET(x) \
+ (((x) << PMU2_PGM_LSB) & PMU2_PGM_MASK)
+
+#define CPU_DDR_SYNC_MODE DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(0)
+
+/*
+* DDR2 DDR1
+* 0x40c3 25MHz 0x4186 25Mhz
+* 0x4138 40MHz 0x4270 40Mhz
+*/
+#define CFG_DDR2_REFRESH_VAL 0x40c3
+#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x1) | \
+ DDR_CONFIG_OPEN_PAGE_SET(0x1) | DDR_CONFIG_CAS_LATENCY_SET(0x4) | \
+ DDR_CONFIG_TMRD_SET(0x6) | DDR_CONFIG_TRFC_SET(0x16) | \
+ DDR_CONFIG_TRRD_SET(0x7) | DDR_CONFIG_TRP_SET(0xb) | \
+ DDR_CONFIG_TRCD_SET(0xb) | DDR_CONFIG_TRAS_SET(0)
+#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
+ DDR_CONFIG2_SWAP_A26_A27_SET(0x0) | DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0xa) | \
+ DDR_CONFIG2_TWTR_SET(0x16) | DDR_CONFIG2_TRTP_SET(0xa) | \
+ DDR_CONFIG2_TRTW_SET(0xe) | DDR_CONFIG2_TWR_SET(0x2) | \
+ DDR_CONFIG2_CKE_SET(0x1) | DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
+ DDR_CONFIG2_BURST_LENGTH_SET(0x8)
+
+#define CFG_DDR2_CONFIG3_VAL 0x0000000e
+#define CFG_DDR2_EXT_MODE_VAL1 0x782
+#define CFG_DDR2_EXT_MODE_VAL2 0x402
+#define CFG_DDR2_MODE_VAL_INIT 0xb53
+#define CFG_DDR2_MODE_VAL 0xa53
+#define CFG_DDR2_TAP_VAL 0x10
+#define CFG_DDR2_EN_TWL_VAL 0x00001e91
+#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
+
+#define CFG_DDR_CTL_CONFIG DDR_CTL_CONFIG_SRAM_TSEL_SET(0x1) | \
+ DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(0x1) | \
+ DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(0x1)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void qca956x_ddr_init(void)
+{
+ u32 ddr_config, ddr_config2, ddr_config3, mod_val, \
+ mod_val_init, cycle_val, tap_val, ctl_config;
+ void __iomem *ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
+ MAP_NOCACHE);
+ void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE, QCA956X_SRIF_SIZE,
+ MAP_NOCACHE);
+
+ ddr_config = CFG_DDR2_CONFIG_VAL;
+ ddr_config2 = CFG_DDR2_CONFIG2_VAL;
+ ddr_config3 = CFG_DDR2_CONFIG3_VAL;
+ mod_val_init = CFG_DDR2_MODE_VAL_INIT;
+ mod_val = CFG_DDR2_MODE_VAL;
+ tap_val = CFG_DDR2_TAP_VAL;
+ cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16;
+ ctl_config = CFG_DDR_CTL_CONFIG | DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(0x1) |
+ DDR_CTL_CONFIG_HALF_WIDTH_SET(0x1) | CPU_DDR_SYNC_MODE;
+
+ writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL);
+ udelay(10);
+
+ writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL);
+ udelay(10);
+
+ writel(ctl_config, ddr_regs + QCA956X_DDR_REG_CTL_CONF);
+ udelay(10);
+
+ writel(cycle_val, ddr_regs + AR71XX_DDR_REG_RD_CYCLE);
+ udelay(100);
+
+ writel(0x74444444, ddr_regs + QCA956X_DDR_REG_BURST);
+ udelay(100);
+
+ writel(0x44444444, ddr_regs + QCA956X_DDR_REG_BURST2);
+ udelay(100);
+
+ writel(DDR_FSM_WAIT_CTRL_VAL, ddr_regs + QCA956X_DDR_REG_FSM_WAIT_CTRL);
+ udelay(100);
+
+ writel(0xfffff, ddr_regs + QCA956X_DDR_REG_TIMEOUT_MAX);
+ udelay(100);
+
+ writel(ddr_config, ddr_regs + AR71XX_DDR_REG_CONFIG);
+ udelay(100);
+
+ writel(ddr_config2, ddr_regs + AR71XX_DDR_REG_CONFIG2);
+ udelay(100);
+
+ writel(ddr_config3, ddr_regs + QCA956X_DDR_REG_DDR3_CONFIG);
+ udelay(100);
+
+ writel(CFG_DDR2_EN_TWL_VAL, ddr_regs + QCA956X_DDR_REG_DDR2_CONFIG);
+ udelay(100);
+
+ writel(ddr_config2 | 0x80, ddr_regs + AR71XX_DDR_REG_CONFIG2); /* CKE Enable */
+ udelay(100);
+
+ writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Precharge */
+ udelay(10);
+
+ writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR2);
+ writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR2 */
+ udelay(10);
+
+ writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR3);
+ writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR3 */
+ udelay(10);
+
+ /* EMR DLL enable, Reduced Driver Impedance control, Differential DQS disabled */
+ writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR);
+ udelay(100);
+
+ writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR write */
+ udelay(10);
+
+ writel(mod_val_init, ddr_regs + AR71XX_DDR_REG_MODE);
+ udelay(1000);
+
+ writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); /* MR Write */
+ udelay(10);
+
+ writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Precharge */
+ udelay(10);
+
+ writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Auto Refresh */
+ udelay(10);
+
+ writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Auto Refresh */
+ udelay(10);
+
+ /* Issue MRS to remove DLL out-of-reset */
+ writel(mod_val, ddr_regs + AR71XX_DDR_REG_MODE);
+ udelay(100);
+
+ writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); /* MR write */
+ udelay(100);
+
+ writel(CFG_DDR2_EXT_MODE_VAL1, ddr_regs + AR71XX_DDR_REG_EMR);
+ udelay(100);
+
+ writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR write */
+ udelay(100);
+
+ writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR);
+ udelay(100);
+
+ writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR write */
+ udelay(100);
+
+ writel(CFG_DDR2_REFRESH_VAL, ddr_regs + AR71XX_DDR_REG_REFRESH);
+ udelay(100);
+
+ writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0);
+ writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1);
+ writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL2);
+ writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL3);
+
+ writel(0x633c8176, srif_regs + QCA956X_SRIF_PMU1_REG);
+ /* Set DDR2 Voltage to 1.8 volts */
+ writel(PMU2_SWREGMSB_SET(0x40) | PMU2_PGM_SET(0x1),
+ srif_regs + QCA956X_SRIF_PMU2_REG);
+}
diff --git a/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
new file mode 100644
index 00000000000..db54b575fbc
--- /dev/null
+++ b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
+ *
+ * Based on QSDK
+ */
+
+#include <config.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <mach/ar71xx_regs.h>
+
+ .set noreorder
+
+LEAF(ddr_tap_tuning)
+ li a0, 0xbd001f00
+ sw zero, 0x0(a0) /* Place where the tap values are saved and used for SWEEP */
+ sw zero, 0x4(a0) /* Place where the number of passing taps are saved. */
+ sw zero, 0x14(a0) /* Place where the last pass tap value is stored */
+ li a1, 0xaa55aa55 /* Indicates that the First pass tap value is not found */
+ sw a1, 0x10(a0) /* Place where the First pass tap value is stored */
+ nop
+
+ li a0, CKSEG1ADDR(AR71XX_RESET_BASE) /* RESET_BASE_ADDRESS */
+ lw a1, 0x1c(a0) /* Reading the RST_RESET_ADDRESS */
+ li a2, 0x08000000 /* Setting the RST_RESET_RTC_RESET */
+ or a1, a1, a2
+ sw a1, 0x1c(a0)
+
+ li a3, 0xffffffff
+ xor a2, a2, a3
+ and a1, a1, a2
+ sw a1, 0x1c(a0) /* Taking the RTC out of RESET */
+ nop
+
+ li a0, CKSEG1ADDR(QCA956X_RTC_BASE) /* RTC_BASE_ADDRESS */
+ li a1, 0x1
+ sw a1, 0x0040(a0) /* RTC_SYNC_RESET_ADDRESS */
+
+ li a2, 0x2
+
+_poll_for_RTC_ON:
+ lw a1, 0x0044(a0) /* RTC_SYNC_STATUS_ADDRESS */
+ and a1, a2, a1
+ bne a1, a2, _poll_for_RTC_ON
+ nop
+
+_CHANGE_TAPS:
+ li t0, 0xbd001f00 /* Read the current value of the TAP for programming */
+ lw t1, 0x0(t0)
+ li t2, 0x00000000
+ or t3, t1, t2
+
+ li t0, 0xb8000000 /* DDR_BASE_ADDRESS */
+ sw t3, 0x1c(t0) /* TAP_CONTROL_0_ADDRESS */
+ sw t3, 0x20(t0) /* TAP_CONTROL_1_ADDRESS */
+ sw t3, 0x24(t0) /* TAP_CONTROL_2_ADDRESS */
+ sw t3, 0x28(t0) /* TAP_CONTROL_3_ADDRESS */
+
+ li t1, 0x00000010 /* Running the test 8 times */
+ sw t1, 0x0068(t0) /* PERF_COMP_ADDR_1_ADDRESS */
+
+ li t1, 0xfa5de83f /* 4 Row Address Bits, 4 Column Address Bits, 2 BA bits */
+ sw t1, 0x002c(t0) /* PERF_MASK_ADDR_0_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x0070(t0) /* PERF_COMP_AHB_GE0_1_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x0040(t0) /* PERF_COMP_AHB_GE1_0_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x0078(t0) /* PERF_COMP_AHB_GE1_1_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x0034(t0) /* PERF_MASK_AHB_GE0_0_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x006c(t0) /* PERF_MASK_AHB_GE0_1_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x003c(t0) /* PERF_MASK_AHB_GE1_0_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x0074(t0) /* PERF_MASK_AHB_GE1_1_ADDRESS */
+
+ li t1, 0x0000ffff
+ sw t1, 0x0038(t0) /* PERF_COMP_AHB_GE0_0_ADDRESS */
+
+ li t1, 0x00000001
+ sw t1, 0x011c(t0) /* DDR_BIST_ADDRESS */
+
+ li t2, 0x1
+
+_bist_done_poll:
+ lw t1, 0x0120(t0) /* DDR_BIST_STATUS_ADDRESS */
+ and t1, t1, t2
+ bne t1, t2, _bist_done_poll
+ nop
+
+ lw t1, 0x0120(t0) /* DDR_BIST_STATUS_ADDRESS */
+ li t4, 0x000001fe
+ and t2, t1, t4
+ srl t2, t2, 0x1 /* no. of Pass Runs */
+
+ li t5, 0x00000000
+ sw t5, 0x011c(t0) /* DDR_BIST_ADDRESS - Stop the DDR BIST test */
+
+ li t5, 0x0001fe00
+ and t5, t5, t1
+ bnez t5, _iterate_tap /* This is a redundant compare but nevertheless - Comparing the FAILS */
+ nop
+
+ lw t1, 0x0068(t0) /* PERF_COMP_ADDR_1_ADDRESS */
+ li t3, 0x000001fe
+ and t3, t3, t1
+ srl t3, t3, 0x1 /* No. of runs in the config register. */
+ bne t3, t2, _iterate_tap
+ nop
+
+pass_tap:
+ li t0, 0xbd001f00
+ lw t1, 0x4(t0)
+ addiu t1, t1, 0x1
+ sw t1, 0x4(t0)
+
+ li t0, 0xbd001f10
+ lw t1, 0x0(t0)
+ li t2, 0xaa55aa55
+ beq t1, t2, _first_pass
+ nop
+
+ li t0, 0xbd001f00
+ lw t1, 0x0(t0)
+ li t0, 0xbd001f10
+ sw t1, 0x4(t0)
+ nop
+ b _iterate_tap
+ nop
+
+_first_pass:
+ li t0, 0xbd001f00
+ lw t1, 0x0(t0)
+ li t0, 0xbd001f10
+ sw t1, 0x0(t0)
+ sw t1, 0x4(t0)
+ nop
+
+_iterate_tap:
+ li t0, 0xbd001f00
+ lw t1, 0x0(t0)
+ li t2, 0x3f
+ beq t1, t2, _STOP_TEST
+ nop
+
+ addiu t1, t1, 0x1
+ sw t1, 0x0(t0)
+ nop
+ b _CHANGE_TAPS
+ nop
+
+_STOP_TEST:
+ li t0, 0xbd001f00
+ lw t1, 0x4(t0)
+ bnez t1, _load_center_tap
+ nop
+
+ li t3, 0x8 /* Default Tap to be used */
+ b _load_tap_into_reg
+ nop
+
+_load_center_tap:
+ li t0, 0xbd001f10
+ lw t1, 0x0(t0)
+ lw t2, 0x4(t0)
+ add t3, t1, t2
+ srl t3, t3, 0x1
+ li t4, 0x3f
+ and t3, t3, t4
+
+_load_tap_into_reg:
+ li t0, 0xb8000000
+ sw t3, 0x1c(t0) /* TAP_CONTROL_0_ADDRESS */
+ sw t3, 0x20(t0) /* TAP_CONTROL_1_ADDRESS */
+ sw t3, 0x24(t0) /* TAP_CONTROL_2_ADDRESS */
+ sw t3, 0x28(t0) /* TAP_CONTROL_3_ADDRESS */
+
+ nop
+ jr ra
+ nop
+ END(ddr_tap_tuning)
diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c
index 6a94d886f94..0ab3ab6383c 100644
--- a/arch/mips/mach-ath79/reset.c
+++ b/arch/mips/mach-ath79/reset.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
+ * Copyright (C) 2018-2019 Rosy Song <rosysong@rosinson.com>
*/
#include <common.h>
@@ -11,6 +12,44 @@
#include <mach/ath79.h>
#include <mach/ar71xx_regs.h>
+/* QCA956X ETH_SGMII_SERDES Registers */
+#define SGMII_SERDES_RES_CALIBRATION_LSB 23
+#define SGMII_SERDES_RES_CALIBRATION_MASK 0x07800000
+#define SGMII_SERDES_RES_CALIBRATION_SET(x) \
+ (((x) << SGMII_SERDES_RES_CALIBRATION_LSB) & SGMII_SERDES_RES_CALIBRATION_MASK)
+#define SGMII_SERDES_CDR_BW_LSB 1
+#define SGMII_SERDES_CDR_BW_MASK 0x00000006
+#define SGMII_SERDES_CDR_BW_SET(x) \
+ (((x) << SGMII_SERDES_CDR_BW_LSB) & SGMII_SERDES_CDR_BW_MASK)
+#define SGMII_SERDES_TX_DR_CTRL_LSB 4
+#define SGMII_SERDES_TX_DR_CTRL_MASK 0x00000070
+#define SGMII_SERDES_TX_DR_CTRL_SET(x) \
+ (((x) << SGMII_SERDES_TX_DR_CTRL_LSB) & SGMII_SERDES_TX_DR_CTRL_MASK)
+#define SGMII_SERDES_PLL_BW_LSB 8
+#define SGMII_SERDES_PLL_BW_MASK 0x00000100
+#define SGMII_SERDES_PLL_BW_SET(x) \
+ (((x) << SGMII_SERDES_PLL_BW_LSB) & SGMII_SERDES_PLL_BW_MASK)
+#define SGMII_SERDES_EN_SIGNAL_DETECT_LSB 16
+#define SGMII_SERDES_EN_SIGNAL_DETECT_MASK 0x00010000
+#define SGMII_SERDES_EN_SIGNAL_DETECT_SET(x) \
+ (((x) << SGMII_SERDES_EN_SIGNAL_DETECT_LSB) & SGMII_SERDES_EN_SIGNAL_DETECT_MASK)
+#define SGMII_SERDES_FIBER_SDO_LSB 17
+#define SGMII_SERDES_FIBER_SDO_MASK 0x00020000
+#define SGMII_SERDES_FIBER_SDO_SET(x) \
+ (((x) << SGMII_SERDES_FIBER_SDO_LSB) & SGMII_SERDES_FIBER_SDO_MASK)
+#define SGMII_SERDES_VCO_REG_LSB 27
+#define SGMII_SERDES_VCO_REG_MASK 0x78000000
+#define SGMII_SERDES_VCO_REG_SET(x) \
+ (((x) << SGMII_SERDES_VCO_REG_LSB) & SGMII_SERDES_VCO_REG_MASK)
+#define SGMII_SERDES_VCO_FAST_LSB 9
+#define SGMII_SERDES_VCO_FAST_MASK 0x00000200
+#define SGMII_SERDES_VCO_FAST_GET(x) \
+ (((x) & SGMII_SERDES_VCO_FAST_MASK) >> SGMII_SERDES_VCO_FAST_LSB)
+#define SGMII_SERDES_VCO_SLOW_LSB 10
+#define SGMII_SERDES_VCO_SLOW_MASK 0x00000400
+#define SGMII_SERDES_VCO_SLOW_GET(x) \
+ (((x) & SGMII_SERDES_VCO_SLOW_MASK) >> SGMII_SERDES_VCO_SLOW_LSB)
+
void _machine_restart(void)
{
void __iomem *base;
@@ -152,6 +191,236 @@ static int eth_init_qca953x(void)
return 0;
}
+static int qca956x_sgmii_cal(void)
+{
+ int i;
+ u32 reg, rev_sgmii_val;
+ u32 vco_fast, vco_slow;
+ u32 start_val = 0, end_val = 0;
+ void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
+ MAP_NOCACHE);
+ void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+ MAP_NOCACHE);
+ void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII;
+
+ writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
+
+ reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+ vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
+ vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
+
+ /* Set resistor calibration from 0000 to 1111 */
+ for (i = 0; i < 0x10; i++) {
+ reg = (readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
+ ~SGMII_SERDES_RES_CALIBRATION_MASK) |
+ SGMII_SERDES_RES_CALIBRATION_SET(i);
+ writel(reg, gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+
+ udelay(50);
+
+ reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+ if (vco_fast != SGMII_SERDES_VCO_FAST_GET(reg) ||
+ vco_slow != SGMII_SERDES_VCO_SLOW_GET(reg)) {
+ if (start_val == 0) {
+ start_val = i;
+ end_val = i;
+ } else {
+ end_val = i;
+ }
+ }
+ vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
+ vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
+ }
+
+ if (start_val == 0)
+ rev_sgmii_val = 0x7;
+ else
+ rev_sgmii_val = (start_val + end_val) >> 1;
+
+ writel((readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
+ ~SGMII_SERDES_RES_CALIBRATION_MASK) |
+ SGMII_SERDES_RES_CALIBRATION_SET(rev_sgmii_val),
+ gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+
+ writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
+
+ reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+ writel(SGMII_SERDES_CDR_BW_SET(3) | SGMII_SERDES_TX_DR_CTRL_SET(1) |
+ SGMII_SERDES_PLL_BW_SET(1) | SGMII_SERDES_EN_SIGNAL_DETECT_SET(1) |
+ SGMII_SERDES_FIBER_SDO_SET(1) | SGMII_SERDES_VCO_REG_SET(3) | reg,
+ gregs + QCA956X_GMAC_REG_SGMII_SERDES);
+
+ setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+ clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+
+ while (!(readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) & BIT(15)))
+ /* NOP */;
+
+ return 0;
+}
+
+static int qca956x_sgmii_setup(void)
+{
+ int i;
+ u32 s = 0, reg = 0;
+ u32 _regs[] = {
+ BIT(4), /* HW_RX_125M_N */
+ BIT(2), /* RX_125M_N */
+ BIT(3), /* TX_125M_N */
+ BIT(0), /* RX_CLK_N */
+ BIT(1), /* TX_CLK_N */
+ };
+ void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
+ MAP_NOCACHE);
+
+ /* Force sgmii mode */
+ writel(BIT(6) | BIT(15) | BIT(8), gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+ udelay(10);
+ writel(0x2 | BIT(5) | (0x2 << 6), gregs + QCA956X_GMAC_REG_SGMII_CONFIG);
+
+ /* SGMII reset sequence sugguest by qca systems team. */
+ writel(0, gregs + QCA956X_GMAC_REG_SGMII_RESET);
+ for (i = 0; i < ARRAY_SIZE(_regs); i++) {
+ reg |= _regs[i];
+ writel(reg, gregs + QCA956X_GMAC_REG_SGMII_RESET);
+ }
+
+ writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
+ gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+
+ /*
+ * WARNING: Across resets SGMII link status goes to weird state.
+ * if 0xb8070058 (SGMII_DEBUG Register) reads other than 0xf or 0x10
+ * for sure we are in bad state.
+ * Issue a PHY RESET in MR_AN_CONTROL_ADDRESS to keep going.
+ */
+ i = 0;
+ s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
+ while (!(s == 0xf || s == 0x10)) {
+ writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) | BIT(15),
+ gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+ udelay(100);
+ writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
+ gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
+ if (i++ == 10)
+ break;
+ s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
+ }
+
+ return 0;
+}
+
+static int qca956x_s17_reset(void)
+{
+ void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+ MAP_NOCACHE);
+ void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
+ QCA956X_RESET_EXTERNAL | QCA956X_RESET_SGMII_ANALOG |
+ QCA956X_RESET_SWITCH;
+ /* Bits(Reserved in datasheet) should be set to 1 */
+ const u32 mask_r = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
+ QCA956X_RESET_EXTERNAL;
+
+ setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+ clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask_r);
+ mdelay(1);
+
+ /* Reset s17 switch(GPIO11) SYS_RST_L */
+ writel(readl(regs + AR71XX_GPIO_REG_OE) & ~BIT(11),
+ regs + AR71XX_GPIO_REG_OE);
+ udelay(100);
+
+ writel(readl(regs + AR71XX_GPIO_REG_OUT) & ~BIT(11),
+ regs + AR71XX_GPIO_REG_OUT);
+ udelay(100);
+ writel(readl(regs + AR71XX_GPIO_REG_OUT) | BIT(11),
+ regs + AR71XX_GPIO_REG_OUT);
+
+ return 0;
+}
+
+static int qca956x_init_mdio(void)
+{
+ u32 reg;
+ void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+ MAP_NOCACHE);
+ void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
+ MAP_NOCACHE);
+ const u32 mask = QCA956X_RESET_GE0_MDIO | QCA956X_RESET_GE0_MAC |
+ QCA956X_RESET_GE1_MDIO | QCA956X_RESET_GE1_MAC;
+
+ setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+ clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
+ mdelay(1);
+
+ /* GPIO4 as MDI */
+ reg = readl(regs + QCA956X_GPIO_REG_IN_ENABLE3);
+ reg &= ~(0xff << 16);
+ reg |= (0x4 << 16);
+ writel(reg, regs + QCA956X_GPIO_REG_IN_ENABLE3);
+
+ /* GPIO4 as MDO */
+ reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC1);
+ reg &= ~0xff;
+ reg |= 0x20;
+ writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC1);
+
+ /* Init MDC(GPIO3) / MDIO(GPIO4) */
+ reg = readl(regs + AR71XX_GPIO_REG_OE);
+ reg &= ~BIT(4);
+ writel(reg, regs + AR71XX_GPIO_REG_OE);
+ udelay(100);
+
+ reg = readl(regs + AR71XX_GPIO_REG_OE);
+ reg &= ~BIT(3);
+ writel(reg, regs + AR71XX_GPIO_REG_OE);
+ udelay(100);
+
+ /* GPIO3 as MDI */
+ reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC0);
+ reg &= ~(0xff << 24);
+ reg |= (0x21 << 24);
+ writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC0);
+
+ return 0;
+}
+
+static int eth_init_qca956x(void)
+{
+ void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
+ MAP_NOCACHE);
+ void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
+ MAP_NOCACHE);
+
+ qca956x_sgmii_cal();
+ qca956x_s17_reset();
+ qca956x_init_mdio();
+
+ if (ath79_get_bootstrap() & QCA956X_BOOTSTRAP_REF_CLK_40)
+ writel(0x45500, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
+ else
+ writel(0xc5200, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
+
+ qca956x_sgmii_setup();
+
+ writel((3 << 16) | (3 << 14) | (1 << 0) | (1 << 6),
+ gregs + QCA956X_GMAC_REG_ETH_CFG);
+
+ writel((1 << 31) | (2 << 28) | (2 << 26) | (1 << 25),
+ pregs + QCA956X_PLL_ETH_XMII_CTRL_REG);
+ mdelay(1);
+
+ return 0;
+}
+
int ath79_eth_reset(void)
{
/*
@@ -164,6 +433,8 @@ int ath79_eth_reset(void)
return eth_init_ar934x();
if (soc_is_qca953x())
return eth_init_qca953x();
+ if (soc_is_qca956x())
+ return eth_init_qca956x();
return -EINVAL;
}
diff --git a/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h
index f6e724588a9..493eaad1df7 100644
--- a/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h
+++ b/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h
@@ -17,4 +17,6 @@
#define GPIO_GPIO_ALT(x) (0x74 + 4 * (x))
#define GPIO_GPIO_ALT1(x) (0x7c + 4 * (x))
+#define GCB_PHY_CFG 0x118
+
#endif
diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig
index 4ebcb4b053c..a9834439993 100644
--- a/arch/mips/mach-mt7620/Kconfig
+++ b/arch/mips/mach-mt7620/Kconfig
@@ -22,12 +22,12 @@ choice
prompt "Board select"
config BOARD_GARDENA_SMART_GATEWAY_MT7688
- bool "Gardena Smart Gateway"
+ bool "GARDENA smart Gateway"
depends on SOC_MT7620
select BOARD_LATE_INIT
select SUPPORTS_BOOT_RAM
help
- Gardena Smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
+ GARDENA smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
and 8 MiB of flash (SPI NOR) and additional SPI NAND storage.
config BOARD_LINKIT_SMART_7688
diff --git a/arch/nds32/dts/ae3xx.dts b/arch/nds32/dts/ae3xx.dts
index 272eb3359ab..7bba2a2bf09 100644
--- a/arch/nds32/dts/ae3xx.dts
+++ b/arch/nds32/dts/ae3xx.dts
@@ -93,7 +93,7 @@
clocks = <&spiclk>;
interrupts = <3 4>;
flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
spi-cpol;
diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
index 2ec01a5ce79..cb6ee13f16d 100644
--- a/arch/riscv/dts/ae350_32.dts
+++ b/arch/riscv/dts/ae350_32.dts
@@ -256,7 +256,7 @@
interrupts = <4 4>;
interrupt-parent = <&plic0>;
flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
spi-cpol;
diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
index cde5cdeff83..705491a8e4d 100644
--- a/arch/riscv/dts/ae350_64.dts
+++ b/arch/riscv/dts/ae350_64.dts
@@ -256,7 +256,7 @@
interrupts = <4 4>;
interrupt-parent = <&plic0>;
flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
spi-cpol;
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 87d8e5bcc98..8b2d6451c64 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -493,6 +493,7 @@
compatible = "denx,u-boot-probe-test";
first-syscon = <&syscon0>;
second-sys-ctrl = <&another_system_controller>;
+ third-syscon = <&syscon2>;
};
};
@@ -578,7 +579,7 @@
cs-gpios = <0>, <&gpio_a 0>;
spi.bin@0 {
reg = <0>;
- compatible = "spansion,m25p16", "spi-flash";
+ compatible = "spansion,m25p16", "jedec,spi-nor";
spi-max-frequency = <40000000>;
sandbox,filename = "spi.bin";
};
@@ -597,7 +598,7 @@
0x38 8>;
};
- syscon@2 {
+ syscon2: syscon@2 {
compatible = "simple-mfd", "syscon";
reg = <0x40 5
0x48 6
diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h
index 1027b59e732..c45dbddd700 100644
--- a/arch/sandbox/include/asm/sdl.h
+++ b/arch/sandbox/include/asm/sdl.h
@@ -104,7 +104,7 @@ static inline int sandbox_sdl_sound_start(uint frequency)
return -ENODEV;
}
-int sandbox_sdl_sound_play(const void *data, uint count)
+static inline int sandbox_sdl_sound_play(const void *data, uint count)
{
return -ENODEV;
}
@@ -114,7 +114,7 @@ static inline int sandbox_sdl_sound_stop(void)
return -ENODEV;
}
-int sandbox_sdl_sound_init(int rate, int channels)
+static inline int sandbox_sdl_sound_init(int rate, int channels)
{
return -ENODEV;
}
diff --git a/arch/sandbox/include/asm/types.h b/arch/sandbox/include/asm/types.h
index 7cd56b41474..c1a5d2af828 100644
--- a/arch/sandbox/include/asm/types.h
+++ b/arch/sandbox/include/asm/types.h
@@ -18,21 +18,21 @@ typedef unsigned short umode_t;
/*
* Number of bits in a C 'long' on this architecture.
*/
-#ifdef CONFIG_PHYS64
+#ifdef CONFIG_PHYS_64BIT
#define BITS_PER_LONG 64
-#else /* CONFIG_PHYS64 */
+#else /* CONFIG_PHYS_64BIT */
#define BITS_PER_LONG 32
-#endif /* CONFIG_PHYS64 */
+#endif /* CONFIG_PHYS_64BIT */
-#ifdef CONFIG_PHYS64
+#ifdef CONFIG_PHYS_64BIT
typedef unsigned long long dma_addr_t;
typedef u64 phys_addr_t;
typedef u64 phys_size_t;
-#else /* CONFIG_PHYS64 */
+#else /* CONFIG_PHYS_64BIT */
typedef unsigned long dma_addr_t;
typedef u32 phys_addr_t;
typedef u32 phys_size_t;
-#endif /* CONFIG_PHYS64 */
+#endif /* CONFIG_PHYS_64BIT */
#endif /* __KERNEL__ */
diff --git a/arch/sandbox/lib/pci_io.c b/arch/sandbox/lib/pci_io.c
index 5039973cd7a..01822c60695 100644
--- a/arch/sandbox/lib/pci_io.c
+++ b/arch/sandbox/lib/pci_io.c
@@ -34,7 +34,7 @@ int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
return 0;
}
- debug("%s: failed: addr=%x\n", __func__, paddr);
+ debug("%s: failed: addr=%pap\n", __func__, &paddr);
return -ENOSYS;
}
diff --git a/arch/x86/dts/bayleybay.dts b/arch/x86/dts/bayleybay.dts
index 291dc07ff60..d0168e88dbd 100644
--- a/arch/x86/dts/bayleybay.dts
+++ b/arch/x86/dts/bayleybay.dts
@@ -175,7 +175,7 @@
#size-cells = <1>;
reg = <0>;
compatible = "winbond,w25q64dw",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/baytrail_som-db5800-som-6867.dts b/arch/x86/dts/baytrail_som-db5800-som-6867.dts
index 4e8a761ce87..5abbc66ce98 100644
--- a/arch/x86/dts/baytrail_som-db5800-som-6867.dts
+++ b/arch/x86/dts/baytrail_som-db5800-som-6867.dts
@@ -199,7 +199,7 @@
#size-cells = <1>;
reg = <0>;
compatible = "macronix,mx25l6405d",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/cherryhill.dts b/arch/x86/dts/cherryhill.dts
index 39e2d2fa4b2..37146fde2ba 100644
--- a/arch/x86/dts/cherryhill.dts
+++ b/arch/x86/dts/cherryhill.dts
@@ -147,7 +147,7 @@
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
- compatible = "macronix,mx25u6435f", "spi-flash";
+ compatible = "macronix,mx25u6435f", "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
index c5653feac72..09488f13b58 100644
--- a/arch/x86/dts/chromebook_link.dts
+++ b/arch/x86/dts/chromebook_link.dts
@@ -429,7 +429,7 @@
u-boot,dm-pre-reloc;
reg = <0>;
compatible = "winbond,w25q64",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts
index ad687ce2cc3..35211ed81b1 100644
--- a/arch/x86/dts/chromebook_samus.dts
+++ b/arch/x86/dts/chromebook_samus.dts
@@ -567,7 +567,7 @@
#address-cells = <1>;
reg = <0>;
compatible = "winbond,w25q64",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/chromebox_panther.dts b/arch/x86/dts/chromebox_panther.dts
index f56e482944b..bcd4c4d9c1b 100644
--- a/arch/x86/dts/chromebox_panther.dts
+++ b/arch/x86/dts/chromebox_panther.dts
@@ -47,7 +47,7 @@
#address-cells = <1>;
reg = <0>;
compatible = "winbond,w25q64",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/conga-qeval20-qa3-e3845.dts b/arch/x86/dts/conga-qeval20-qa3-e3845.dts
index 5884dbc277d..70b8c045193 100644
--- a/arch/x86/dts/conga-qeval20-qa3-e3845.dts
+++ b/arch/x86/dts/conga-qeval20-qa3-e3845.dts
@@ -186,7 +186,7 @@
#size-cells = <1>;
reg = <0>;
compatible = "stmicro,n25q064a",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/cougarcanyon2.dts b/arch/x86/dts/cougarcanyon2.dts
index 9801790083f..c6ba811e059 100644
--- a/arch/x86/dts/cougarcanyon2.dts
+++ b/arch/x86/dts/cougarcanyon2.dts
@@ -154,7 +154,7 @@
spi-flash@0 {
reg = <0>;
- compatible = "winbond,w25q64bv", "spi-flash";
+ compatible = "winbond,w25q64bv", "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
};
};
diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts
index 8938a94e770..f492c35875b 100644
--- a/arch/x86/dts/crownbay.dts
+++ b/arch/x86/dts/crownbay.dts
@@ -224,7 +224,7 @@
spi-flash@0 {
reg = <0>;
compatible = "sst,25vf016b",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xffe00000 0x00200000>;
};
};
diff --git a/arch/x86/dts/dfi-bt700.dtsi b/arch/x86/dts/dfi-bt700.dtsi
index 51d33e772fc..e9930cb0436 100644
--- a/arch/x86/dts/dfi-bt700.dtsi
+++ b/arch/x86/dts/dfi-bt700.dtsi
@@ -197,7 +197,7 @@
#size-cells = <1>;
reg = <0>;
compatible = "stmicro,n25q064a",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts
index 3a5d168268d..5de4568679a 100644
--- a/arch/x86/dts/galileo.dts
+++ b/arch/x86/dts/galileo.dts
@@ -139,7 +139,7 @@
#address-cells = <1>;
reg = <0>;
compatible = "winbond,w25q64",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts
index 6c65fb9611c..f4cdb2c3cd2 100644
--- a/arch/x86/dts/minnowmax.dts
+++ b/arch/x86/dts/minnowmax.dts
@@ -199,7 +199,7 @@
#size-cells = <1>;
reg = <0>;
compatible = "stmicro,n25q064a",
- "spi-flash";
+ "jedec,spi-nor";
memory-map = <0xff800000 0x00800000>;
rw-mrc-cache {
label = "rw-mrc-cache";
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index c7f6479a0cf..c21d2f3ffa6 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -379,7 +379,7 @@ int board_init(void)
puts("Cannot find Armada 385 watchdog!\n");
} else {
puts("Enabling Armada 385 watchdog.\n");
- wdt_start(watchdog_dev, (u32) 25000000 * 120, 0);
+ wdt_start(watchdog_dev, 120000, 0);
}
# endif
diff --git a/board/Marvell/db-xc3-24g4xg/.gitignore b/board/Marvell/db-xc3-24g4xg/.gitignore
new file mode 100644
index 00000000000..775b9346b85
--- /dev/null
+++ b/board/Marvell/db-xc3-24g4xg/.gitignore
@@ -0,0 +1 @@
+kwbimage.cfg
diff --git a/board/Marvell/db-xc3-24g4xg/MAINTAINERS b/board/Marvell/db-xc3-24g4xg/MAINTAINERS
new file mode 100644
index 00000000000..2b27e48181b
--- /dev/null
+++ b/board/Marvell/db-xc3-24g4xg/MAINTAINERS
@@ -0,0 +1,7 @@
+DB-XC3-24G4XG BOARD
+M: Chris Packham <chris.packham@alliedtelesis.co.nz>
+S: Maintained
+F: board/Marvell/db-xc3-24g4xg/
+F: include/configs/db-xc3-24g4xg.h
+F: configs/db-xc3-24g4xg_defconfig
+F: arch/arm/dts/armada-xp-db-xc3-24g4xg.dts
diff --git a/board/Marvell/db-xc3-24g4xg/Makefile b/board/Marvell/db-xc3-24g4xg/Makefile
new file mode 100644
index 00000000000..4dd57902d47
--- /dev/null
+++ b/board/Marvell/db-xc3-24g4xg/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2015 Stefan Roese <sr@denx.de>
+
+obj-y := db-xc3-24g4xg.o
+extra-y := kwbimage.cfg
+
+quiet_cmd_sed = SED $@
+ cmd_sed = sed $(SEDFLAGS_$(@F)) $< >$(dir $<)$(@F)
+
+SEDFLAGS_kwbimage.cfg =-e "s|^BINARY.*|BINARY $(srctree)/$(@D)/binary.0 0000005b 00000068|"
+$(src)/kwbimage.cfg: $(src)/kwbimage.cfg.in include/autoconf.mk \
+ include/config/auto.conf
+ $(call if_changed,sed)
diff --git a/board/Marvell/db-xc3-24g4xg/README b/board/Marvell/db-xc3-24g4xg/README
new file mode 100644
index 00000000000..5e479b433e4
--- /dev/null
+++ b/board/Marvell/db-xc3-24g4xg/README
@@ -0,0 +1,4 @@
+To generate binary.0 from Marvell's bin_hdr.elf use the following command
+
+ arm-softfloat-linux-gnueabi-objcopy -S -O binary bin_hdr.elf \
+ board/Marvell/db-xc3-24g4xg/binary.0
diff --git a/board/Marvell/db-xc3-24g4xg/binary.0 b/board/Marvell/db-xc3-24g4xg/binary.0
new file mode 100644
index 00000000000..8dd687286a0
--- /dev/null
+++ b/board/Marvell/db-xc3-24g4xg/binary.0
@@ -0,0 +1,11 @@
+--------
+WARNING:
+--------
+This file should contain the bin_hdr generated by the original Marvell
+U-Boot implementation. As this is currently not included in this
+U-Boot version, we have added this placeholder, so that the U-Boot
+image can be generated without errors.
+
+If you have a known to be working bin_hdr for your board, then you
+just need to replace this text file here with the binary header
+and recompile U-Boot.
diff --git a/board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c b/board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c
new file mode 100644
index 00000000000..cae428ffd06
--- /dev/null
+++ b/board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/gpio.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * These values and defines are taken from the Marvell U-Boot version
+ * "u-boot-2013.01-2016_T1.0.eng_drop_v6"
+ */
+#define DB_DX_AC3_GPP_OUT_ENA_LOW (~(BIT(0) | BIT(2) | BIT(3) | BIT(4) | BIT(6) | BIT(12) \
+ | BIT(13) | BIT(16) | BIT(17) | BIT(20) | BIT(29) | BIT(30)))
+#define DB_DX_AC3_GPP_OUT_ENA_MID (~(0))
+#define DB_DX_AC3_GPP_OUT_VAL_LOW (BIT(0) | BIT(2) | BIT(3) | BIT(4) | BIT(6) | BIT(12) \
+ | BIT(13) | BIT(16) | BIT(17) | BIT(20) | BIT(29) | BIT(30))
+#define DB_DX_AC3_GPP_OUT_VAL_MID 0x0
+#define DB_DX_AC3_GPP_POL_LOW 0x0
+#define DB_DX_AC3_GPP_POL_MID 0x0
+
+int board_early_init_f(void)
+{
+ /* Configure MPP */
+ writel(0x00142222, MVEBU_MPP_BASE + 0x00);
+ writel(0x11122000, MVEBU_MPP_BASE + 0x04);
+ writel(0x44444004, MVEBU_MPP_BASE + 0x08);
+ writel(0x14444444, MVEBU_MPP_BASE + 0x0c);
+ writel(0x00000001, MVEBU_MPP_BASE + 0x10);
+
+ /* Set GPP Out value */
+ writel(DB_DX_AC3_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
+ writel(DB_DX_AC3_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
+
+ /* Set GPP Polarity */
+ writel(DB_DX_AC3_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
+ writel(DB_DX_AC3_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);
+
+ /* Set GPP Out Enable */
+ writel(DB_DX_AC3_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
+ writel(DB_DX_AC3_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
+
+ return 0;
+}
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
+
+ return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+ puts("Board: " CONFIG_SYS_BOARD "\n");
+
+ return 0;
+}
+#endif
diff --git a/board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in b/board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in
new file mode 100644
index 00000000000..b8bb7a6eb75
--- /dev/null
+++ b/board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in
@@ -0,0 +1,12 @@
+#
+# Copyright (C) 2014 Stefan Roese <sr@denx.de>
+#
+
+# Armada XP uses version 1 image format
+VERSION 1
+
+# Boot Media configurations
+BOOT_FROM spi
+
+# Binary Header (bin_hdr) with DDR3 training code
+BINARY board/Marvell/db-xc3-24g4xg/binary.0 0000005b 00000068
diff --git a/board/Synology/ds414/ds414.c b/board/Synology/ds414/ds414.c
index eb3694ea6e7..d23e97c9b91 100644
--- a/board/Synology/ds414/ds414.c
+++ b/board/Synology/ds414/ds414.c
@@ -115,14 +115,14 @@ MV_DRAM_MODES *ddr3_get_static_ddr_mode(void)
return &ds414_ddr_modes[0];
}
-MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode)
+MV_BIN_SERDES_CFG *board_serdes_cfg_get(void)
{
return &ds414_serdes_cfg[0];
}
u8 board_sat_r_get(u8 dev_num, u8 reg)
{
- return (0x1 << 1 | 1);
+ return 0xf; /* All PEX ports support PCIe Gen2 */
}
int board_early_init_f(void)
diff --git a/board/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c
index d7d1942fe68..6934fd80173 100644
--- a/board/alliedtelesis/x530/x530.c
+++ b/board/alliedtelesis/x530/x530.c
@@ -7,6 +7,7 @@
#include <command.h>
#include <dm.h>
#include <i2c.h>
+#include <wdt.h>
#include <asm/gpio.h>
#include <linux/mbus.h>
#include <linux/io.h>
@@ -24,6 +25,10 @@ DECLARE_GLOBAL_DATA_PTR;
#define CONFIG_NVS_LOCATION 0xf4800000
#define CONFIG_NVS_SIZE (512 << 10)
+#ifdef CONFIG_WATCHDOG
+static struct udevice *watchdog_dev;
+#endif
+
static struct serdes_map board_serdes_map[] = {
{PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
{DEFAULT_SERDES, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
@@ -75,6 +80,10 @@ struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
int board_early_init_f(void)
{
+#ifdef CONFIG_WATCHDOG
+ watchdog_dev = NULL;
+#endif
+
/* Configure MPP */
writel(0x00001111, MVEBU_MPP_BASE + 0x00);
writel(0x00000000, MVEBU_MPP_BASE + 0x04);
@@ -88,6 +97,17 @@ int board_early_init_f(void)
return 0;
}
+void spl_board_init(void)
+{
+#ifdef CONFIG_WATCHDOG
+ int ret;
+
+ ret = uclass_get_device(UCLASS_WDT, 0, &watchdog_dev);
+ if (!ret)
+ wdt_start(watchdog_dev, 120000, 0);
+#endif
+}
+
int board_init(void)
{
/* address of boot parameters */
@@ -100,9 +120,37 @@ int board_init(void)
/* DEV_READYn is not needed for NVS, ignore it when accessing CS1 */
writel(0x00004001, MVEBU_DEV_BUS_BASE + 0xc8);
+ spl_board_init();
+
return 0;
}
+void arch_preboot_os(void)
+{
+#ifdef CONFIG_WATCHDOG
+ wdt_stop(watchdog_dev);
+#endif
+}
+
+#ifdef CONFIG_WATCHDOG
+void watchdog_reset(void)
+{
+ static ulong next_reset = 0;
+ ulong now;
+
+ if (!watchdog_dev)
+ return;
+
+ now = timer_get_us();
+
+ /* Do not reset the watchdog too often */
+ if (now > next_reset) {
+ wdt_reset(watchdog_dev);
+ next_reset = now + 1000;
+ }
+}
+#endif
+
static int led_7seg_init(unsigned int segments)
{
int node;
diff --git a/board/maxbcm/maxbcm.c b/board/maxbcm/maxbcm.c
index e8f8f7ba5b4..395904f8c87 100644
--- a/board/maxbcm/maxbcm.c
+++ b/board/maxbcm/maxbcm.c
@@ -95,7 +95,7 @@ MV_DRAM_MODES *ddr3_get_static_ddr_mode(void)
return &maxbcm_ddr_modes[0];
}
-MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode)
+MV_BIN_SERDES_CFG *board_serdes_cfg_get(void)
{
return &maxbcm_serdes_cfg[0];
}
diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c
index 58a4a04162b..6e5ef4c97f4 100644
--- a/board/mscc/jr2/jr2.c
+++ b/board/mscc/jr2/jr2.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <asm/io.h>
#include <led.h>
+#include <miiphy.h>
enum {
BOARD_TYPE_PCB110 = 0xAABBCE00,
@@ -64,6 +65,28 @@ static void vcoreiii_gpio_set_alternate(int gpio, int mode)
}
}
+int board_phy_config(struct phy_device *phydev)
+{
+ if (gd->board_type == BOARD_TYPE_PCB110 ||
+ gd->board_type == BOARD_TYPE_PCB112) {
+ phy_write(phydev, 0, 31, 0x10);
+ phy_write(phydev, 0, 18, 0x80F0);
+ while (phy_read(phydev, 0, 18) & 0x8000)
+ ;
+ phy_write(phydev, 0, 31, 0);
+ }
+ if (gd->board_type == BOARD_TYPE_PCB111) {
+ phy_write(phydev, 0, 31, 0x10);
+ phy_write(phydev, 0, 18, 0x80A0);
+ while (phy_read(phydev, 0, 18) & 0x8000)
+ ;
+ phy_write(phydev, 0, 14, 0x800);
+ phy_write(phydev, 0, 31, 0);
+ }
+
+ return 0;
+}
+
void board_debug_uart_init(void)
{
/* too early for the pinctrl driver, so configure the UART pins here */
diff --git a/board/qca/ap152/Kconfig b/board/qca/ap152/Kconfig
new file mode 100644
index 00000000000..f6ad498e85c
--- /dev/null
+++ b/board/qca/ap152/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_AP152
+
+config SYS_VENDOR
+ default "qca"
+
+config SYS_BOARD
+ default "ap152"
+
+config SYS_CONFIG_NAME
+ default "ap152"
+
+config SYS_TEXT_BASE
+ default 0x9f000000
+
+endif
diff --git a/board/qca/ap152/MAINTAINERS b/board/qca/ap152/MAINTAINERS
new file mode 100644
index 00000000000..785ec2766d1
--- /dev/null
+++ b/board/qca/ap152/MAINTAINERS
@@ -0,0 +1,6 @@
+AP152 BOARD
+M: Rosy Song <rosysong@rosinson.com>
+S: Maintained
+F: board/qca/ap152/
+F: include/configs/ap152.h
+F: configs/ap152_defconfig
diff --git a/board/qca/ap152/Makefile b/board/qca/ap152/Makefile
new file mode 100644
index 00000000000..4270afa1291
--- /dev/null
+++ b/board/qca/ap152/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y = ap152.o
diff --git a/board/qca/ap152/ap152.c b/board/qca/ap152/ap152.c
new file mode 100644
index 00000000000..30cd56563b9
--- /dev/null
+++ b/board/qca/ap152/ap152.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <mach/ar71xx_regs.h>
+#include <mach/ddr.h>
+#include <mach/ath79.h>
+#include <debug_uart.h>
+
+#define RST_RESET_RTC_RESET_LSB 27
+#define RST_RESET_RTC_RESET_MASK 0x08000000
+#define RST_RESET_RTC_RESET_SET(x) \
+ (((x) << RST_RESET_RTC_RESET_LSB) & RST_RESET_RTC_RESET_MASK)
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+ void __iomem *regs;
+ u32 val;
+
+ regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+ MAP_NOCACHE);
+
+ /* UART : RX18, TX22 done
+ * GPIO18 as input, GPIO22 as output
+ */
+ val = readl(regs + AR71XX_GPIO_REG_OE);
+ val |= QCA956X_GPIO(18);
+ val &= ~QCA956X_GPIO(22);
+ writel(val, regs + AR71XX_GPIO_REG_OE);
+
+ /*
+ * Enable GPIO22 as UART0_SOUT
+ */
+ val = readl(regs + QCA956X_GPIO_REG_OUT_FUNC5);
+ val &= ~QCA956X_GPIO_MUX_MASK(16);
+ val |= QCA956X_GPIO_OUT_MUX_UART0_SOUT << 16;
+ writel(val, regs + QCA956X_GPIO_REG_OUT_FUNC5);
+
+ /*
+ * Enable GPIO18 as UART0_SIN
+ */
+ val = readl(regs + QCA956X_GPIO_REG_IN_ENABLE0);
+ val &= ~QCA956X_GPIO_MUX_MASK(8);
+ val |= QCA956X_GPIO_IN_MUX_UART0_SIN << 8;
+ writel(val, regs + QCA956X_GPIO_REG_IN_ENABLE0);
+
+ /*
+ * Enable GPIO22 output
+ */
+ val = readl(regs + AR71XX_GPIO_REG_OUT);
+ val |= QCA956X_GPIO(22);
+ writel(val, regs + AR71XX_GPIO_REG_OUT);
+}
+#endif
+
+int board_early_init_f(void)
+{
+ u32 reg;
+ void __iomem *rst_regs = map_physmem(AR71XX_RESET_BASE,
+ AR71XX_RESET_SIZE, MAP_NOCACHE);
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ /* CPU:775, DDR:650, AHB:258 */
+ qca956x_pll_init();
+ qca956x_ddr_init();
+#endif
+
+ /* Take WMAC out of reset */
+ reg = readl(rst_regs + QCA956X_RESET_REG_RESET_MODULE);
+ reg &= (~RST_RESET_RTC_RESET_SET(1));
+ writel(reg, rst_regs + QCA956X_RESET_REG_RESET_MODULE);
+
+ ath79_eth_reset();
+ return 0;
+}
diff --git a/board/solidrun/clearfog/README b/board/solidrun/clearfog/README
index a7bc0d4e23f..0b0e98de90a 100644
--- a/board/solidrun/clearfog/README
+++ b/board/solidrun/clearfog/README
@@ -17,6 +17,29 @@ $ sudo dd if=u-boot-spl.kwb of=/dev/sdX bs=512 seek=1
Please use the correct device node for your setup instead
of "/dev/sdX" here!
+Install U-Boot on eMMC:
+-----------------------
+
+The ROM loads the bootloader from eMMC first boot partition at offset 0. This
+is unlike load from SD card that is at offset 512. As a result, the offset of
+the main U-Boot image on the eMMC boot partition changes. Set
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR to 0x140 for SPL to load U-Boot from
+the correct location.
+
+To make SPL load the main U-Boot image from the eMMC boot partition enable
+eMMC boot acknowledgement and boot partition with the following U-Boot
+command:
+
+ mmc partconf 0 1 1 0
+
+Install U-Boot on eMMC boot partition from Linux running on Clearfog:
+
+ echo 0 > /sys/block/mmcblk0boot0/force_ro
+ dd if=u-boot-spl.kwb of=/dev/mmcblk0boot0
+
+Note that the SD card is not accessible when the Clearfog SOM has eMMC.
+Consider initial boot from UART (see below).
+
Boot selection:
---------------
diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS
index 48d8fd2c3f2..0a2eddbe03d 100644
--- a/board/st/stm32mp1/MAINTAINERS
+++ b/board/st/stm32mp1/MAINTAINERS
@@ -2,7 +2,8 @@ STM32MP1 BOARD
M: Patrick Delaunay <patrick.delaunay@st.com>
L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers)
S: Maintained
+F: arch/arm/dts/stm32mp157*
F: board/st/stm32mp1
-F: include/configs/stm32mp1.h
F: configs/stm32mp15_basic_defconfig
-F: arch/arm/dts/stm32mp157*
+F: configs/stm32mp15_trusted_defconfig
+F: include/configs/stm32mp1.h
diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README
index 174e6db1484..1cd3534ae4e 100644
--- a/board/st/stm32mp1/README
+++ b/board/st/stm32mp1/README
@@ -28,14 +28,15 @@ Everything is supported in Linux but U-Boot is limited to:
And the necessary drivers
1. I2C
-2. STPMU1
-2. STPMU1 (PMIC and regulator)
+2. STPMIC1 (PMIC and regulator)
3. Clock, Reset, Sysreset
4. Fuse
Currently the following boards are supported:
+ stm32mp157c-ev1
+ stm32mp157c-ed1
++ stm32mp157a-dk1
++ stm32mp157c-dk2
3. Boot Sequences
=================
@@ -45,15 +46,22 @@ BootRom => FSBL in SYSRAM => SSBL in DDR => OS (Linux Kernel)
with FSBL = First Stage Bootloader
SSBL = Second Stage Bootloader
-One boot configuration is supported:
+2 boot configurations are supported:
- The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig)
+1) The "Trusted" boot chain (defconfig_file : stm32mp15_trusted_defconfig)
+ BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot
+ TF-A performs a full initialization of Secure peripherals and installs a
+ secure monitor.
+ U-Boot is running in normal world and uses TF-A monitor
+ to access to secure resources
+
+2) The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig)
BootRom => FSBL = U-Boot SPL => SSBL = U-Boot
SPL has limited security initialisation
U-Boot is running in secure mode and provide a secure monitor to the kernel
with only PSCI support (Power State Coordination Interface defined by ARM)
-All the STM32MP1 board supported by U-Boot use the same generic board
+All the STM32MP1 boards supported by U-Boot use the same generic board
stm32mp1 which support all the bootable devices.
Each board is configurated only with the associated device tree.
@@ -64,12 +72,18 @@ Each board is configurated only with the associated device tree.
You need to select the appropriate device tree for your board,
the supported device trees for stm32mp157 are:
-+ ev1: eval board with pmic stpmu1 (ev1 = mother board + daughter ed1)
++ ev1: eval board with pmic stpmic1 (ev1 = mother board + daughter ed1)
dts: stm32mp157c-ev1
-+ ed1: daughter board with pmic stpmu1
++ ed1: daughter board with pmic stpmic1
dts: stm32mp157c-ed1
++ dk1: Discovery board
+ dts: stm32mp157a-dk1
+
++ dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel
+ dts: stm32mp157c-dk2
+
5. Build Procedure
==================
@@ -90,12 +104,14 @@ the supported device trees for stm32mp157 are:
# export KBUILD_OUTPUT=/path/to/output
for example: use one output directory for each configuration
+ # export KBUILD_OUTPUT=stm32mp15_trusted
# export KBUILD_OUTPUT=stm32mp15_basic
-4. Configure the U-Boot:
+4. Configure U-Boot:
# make <defconfig_file>
+ - For trusted boot mode : "stm32mp15_trusted_defconfig"
- For basic boot mode: "stm32mp15_basic_defconfig"
5. Configure the device-tree and build the U-Boot image:
@@ -104,16 +120,26 @@ the supported device trees for stm32mp157 are:
example:
- basic boot on ev1
+ a) trusted boot on ev1
+ # export KBUILD_OUTPUT=stm32mp15_trusted
+ # make stm32mp15_trusted_defconfig
+ # make DEVICE_TREE=stm32mp157c-ev1 all
+
+ b) basic boot on ev1
# export KBUILD_OUTPUT=stm32mp15_basic
# make stm32mp15_basic_defconfig
# make DEVICE_TREE=stm32mp157c-ev1 all
- basic boot on ed1
+ c) basic boot on ed1
# export KBUILD_OUTPUT=stm32mp15_basic
# make stm32mp15_basic_defconfig
# make DEVICE_TREE=stm32mp157c-ed1 all
+ d) basic boot on dk2
+ # export KBUILD_OUTPUT=stm32mp15_basic
+ # make stm32mp15_basic_defconfig
+ # make DEVICE_TREE=stm32mp157c-dk2 all
+
6. Output files
BootRom and TF-A expect binaries with STM32 image header
@@ -122,6 +148,11 @@ the supported device trees for stm32mp157 are:
So in the output directory (selected by KBUILD_OUTPUT),
you can found the needed files:
+ a) For Trusted boot
+ + FSBL = tf-a.stm32 (provided by TF-A compilation)
+ + SSBL = u-boot.stm32
+
+ b) For Basic boot
+ FSBL = spl/u-boot-spl.stm32
+ SSBL = u-boot.img
@@ -135,13 +166,22 @@ You can select the boot mode, on the board ed1 with the switch SW1
-----------------------------------
Reserved 0 0 0
NOR 0 0 1
- SD-Card 1 1 1
SD-Card 1 0 1
eMMC 0 1 0
NAND 0 1 1
Recovery 1 1 0
Recovery 0 0 0
+- on board DK1/DK2 with the switch SW1 : BOOT0, BOOT2
+ (BOOT1 forced to 0, NOR not supported)
+
+ --------------------------
+ Boot Mode BOOT2 BOOT0
+ --------------------------
+ Reserved 1 0
+ SD-Card 1 1
+ Recovery 0 0
+
Recovery is a boot from serial link (UART/USB) and it is used with
STM32CubeProgrammer tool to load executable in RAM and to update the flash
devices available on the board (NOR/NAND/eMMC/SDCARD).
@@ -158,14 +198,14 @@ The minimal requirements for STMP32MP1 boot up to U-Boot are:
- one ssbl partition for U-Boot
Then the minimal GPT partition is:
- ----- ------- --------- -------------
- | Num | Name | Size | Content |
- ----- ------- -------- --------------
+ ----- ------- --------- --------------
+ | Num | Name | Size | Content |
+ ----- ------- -------- ---------------
| 1 | fsbl1 | 256 KiB | TF-A or SPL |
| 2 | fsbl2 | 256 KiB | TF-A or SPL |
- | 3 | ssbl | enought | U-Boot |
- | * | - | - | Boot/Rootfs|
- ----- ------- --------- -------------
+ | 3 | ssbl | enought | U-Boot |
+ | * | - | - | Boot/Rootfs |
+ ----- ------- --------- --------------
(*) add bootable partition for extlinux.conf
following Generic Distribution
@@ -189,7 +229,7 @@ for example: with gpt table with 128 entries
you can add other partitions for kernel
one partition rootfs for example:
- -n 3:5154: -c 4:rootfs
+ -n 4:5154: -c 4:rootfs \
c) copy the FSBL (2 times) and SSBL file on the correct partition.
in this example in partition 1 to 3
@@ -199,6 +239,11 @@ for example: with gpt table with 128 entries
# dd if=u-boot-spl.stm32 of=/dev/mmcblk0p2
# dd if=u-boot.img of=/dev/mmcblk0p3
+ for trusted boot mode :
+ # dd if=tf-a.stm32 of=/dev/mmcblk0p1
+ # dd if=tf-a.stm32 of=/dev/mmcblk0p2
+ # dd if=u-boot.stm32 of=/dev/mmcblk0p3
+
To boot from SDCard, select BootPinMode = 1 1 1 and reset.
8. Prepare eMMC
@@ -208,7 +253,7 @@ You can use U-Boot to copy binary in eMMC.
In the next example, you need to boot from SDCARD and the images (u-boot-spl.stm32, u-boot.img)
are presents on SDCARD (mmc 0) in ext4 partition 4 (bootfs).
-To boot from SDCard, select BootPinMode = 1 1 1 and reset.
+To boot from SDCard, select BootPinMode = 1 0 1 and reset.
Then you update the eMMC with the next U-Boot command :
@@ -227,7 +272,7 @@ b) copy SPL on eMMC on firts boot partition
# mmc write ${fileaddr} 0 200
# mmc partconf 1 1 1 0
-b) copy U-Boot in first GPT partition of eMMC
+c) copy U-Boot in first GPT partition of eMMC
# ext4load mmc 0:4 0xC0000000 u-boot.img
# mmc dev 1
diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c
index 5f31ea99f59..5c1acca20d7 100644
--- a/board/st/stm32mp1/board.c
+++ b/board/st/stm32mp1/board.c
@@ -8,7 +8,7 @@
#include <asm/io.h>
#include <asm/arch/ddr.h>
#include <power/pmic.h>
-#include <power/stpmu1.h>
+#include <power/stpmic1.h>
#ifdef CONFIG_DEBUG_UART_BOARD_INIT
void board_debug_uart_init(void)
@@ -37,64 +37,65 @@ void board_debug_uart_init(void)
}
#endif
-#ifdef CONFIG_PMIC_STPMU1
+#ifdef CONFIG_PMIC_STPMIC1
int board_ddr_power_init(void)
{
struct udevice *dev;
int ret;
ret = uclass_get_device_by_driver(UCLASS_PMIC,
- DM_GET_DRIVER(pmic_stpmu1), &dev);
+ DM_GET_DRIVER(pmic_stpmic1), &dev);
if (ret)
/* No PMIC on board */
return 0;
- /* Set LDO3 to sync mode */
- ret = pmic_reg_read(dev, STPMU1_LDOX_CTRL_REG(STPMU1_LDO3));
+ /* VTT = Set LDO3 to sync mode */
+ ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
if (ret < 0)
return ret;
- ret &= ~STPMU1_LDO3_MODE;
- ret &= ~STPMU1_LDO12356_OUTPUT_MASK;
- ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
+ ret &= ~STPMIC1_LDO3_MODE;
+ ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+ ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
- ret = pmic_reg_write(dev, STPMU1_LDOX_CTRL_REG(STPMU1_LDO3),
+ ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
ret);
if (ret < 0)
return ret;
- /* Set BUCK2 to 1.35V */
+ /* VDD_DDR = Set BUCK2 to 1.35V */
ret = pmic_clrsetbits(dev,
- STPMU1_BUCKX_CTRL_REG(STPMU1_BUCK2),
- STPMU1_BUCK_OUTPUT_MASK,
- STPMU1_BUCK2_1350000V);
+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+ STPMIC1_BUCK_VOUT_MASK,
+ STPMIC1_BUCK2_1350000V);
if (ret < 0)
return ret;
- /* Enable BUCK2 and VREF */
+ /* Enable VDD_DDR = BUCK2 */
ret = pmic_clrsetbits(dev,
- STPMU1_BUCKX_CTRL_REG(STPMU1_BUCK2),
- STPMU1_BUCK_EN, STPMU1_BUCK_EN);
+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+ STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
if (ret < 0)
return ret;
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
- ret = pmic_clrsetbits(dev, STPMU1_VREF_CTRL_REG,
- STPMU1_VREF_EN, STPMU1_VREF_EN);
+ /* Enable VREF */
+ ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
+ STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
if (ret < 0)
return ret;
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
/* Enable LDO3 */
ret = pmic_clrsetbits(dev,
- STPMU1_LDOX_CTRL_REG(STPMU1_LDO3),
- STPMU1_LDO_EN, STPMU1_LDO_EN);
+ STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+ STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
if (ret < 0)
return ret;
- mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
return 0;
}
diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c
index f3db0d63853..a7844f244bc 100644
--- a/board/st/stm32mp1/spl.c
+++ b/board/st/stm32mp1/spl.c
@@ -11,22 +11,22 @@
#include <asm/io.h>
#include <post.h>
#include <power/pmic.h>
-#include <power/stpmu1.h>
+#include <power/stpmic1.h>
#include <asm/arch/ddr.h>
void spl_board_init(void)
{
/* Keep vdd on during the reset cycle */
-#if defined(CONFIG_PMIC_STPMU1) && defined(CONFIG_SPL_POWER_SUPPORT)
+#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT)
struct udevice *dev;
int ret;
ret = uclass_get_device_by_driver(UCLASS_PMIC,
- DM_GET_DRIVER(pmic_stpmu1), &dev);
+ DM_GET_DRIVER(pmic_stpmic1), &dev);
if (!ret)
pmic_clrsetbits(dev,
- STPMU1_MASK_RESET_BUCK,
- STPMU1_MASK_RESET_BUCK3,
- STPMU1_MASK_RESET_BUCK3);
+ STPMIC1_BUCKS_MRST_CR,
+ STPMIC1_MRST_BUCK(STPMIC1_BUCK3),
+ STPMIC1_MRST_BUCK(STPMIC1_BUCK3));
#endif
}
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 54feca0ecff..24d299ac33b 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -2,20 +2,57 @@
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
*/
-#include <config.h>
#include <common.h>
-#include <led.h>
+#include <adc.h>
+#include <config.h>
#include <clk.h>
#include <dm.h>
#include <generic-phy.h>
+#include <led.h>
+#include <misc.h>
#include <phy.h>
#include <reset.h>
+#include <syscon.h>
#include <usb.h>
-#include <asm/arch/stm32.h>
#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/stm32.h>
#include <power/regulator.h>
#include <usb/dwc2_udc.h>
+/* SYSCFG registers */
+#define SYSCFG_BOOTR 0x00
+#define SYSCFG_PMCSETR 0x04
+#define SYSCFG_IOCTRLSETR 0x18
+#define SYSCFG_ICNR 0x1C
+#define SYSCFG_CMPCR 0x20
+#define SYSCFG_CMPENSETR 0x24
+#define SYSCFG_PMCCLRR 0x44
+
+#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
+#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
+
+#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0)
+#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1)
+#define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2)
+#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3)
+#define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4)
+
+#define SYSCFG_CMPCR_SW_CTRL BIT(1)
+#define SYSCFG_CMPCR_READY BIT(8)
+
+#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
+
+#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16)
+#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17)
+
+#define SYSCFG_PMCSETR_ETH_SELMII BIT(20)
+
+#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21)
+#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII (0 << 21)
+#define SYSCFG_PMCSETR_ETH_SEL_RGMII (1 << 21)
+#define SYSCFG_PMCSETR_ETH_SEL_RMII (4 << 21)
+
/*
* Get a global data pointer
*/
@@ -26,6 +63,98 @@ DECLARE_GLOBAL_DATA_PTR;
#define STM32MP_GGPIO 0x38
#define STM32MP_GGPIO_VBUS_SENSING BIT(21)
+#define USB_WARNING_LOW_THRESHOLD_UV 660000
+#define USB_START_LOW_THRESHOLD_UV 1230000
+#define USB_START_HIGH_THRESHOLD_UV 2100000
+
+int checkboard(void)
+{
+ int ret;
+ char *mode;
+ u32 otp;
+ struct udevice *dev;
+ const char *fdt_compat;
+ int fdt_compat_len;
+
+ if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED))
+ mode = "trusted";
+ else
+ mode = "basic";
+
+ printf("Board: stm32mp1 in %s mode", mode);
+ fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
+ &fdt_compat_len);
+ if (fdt_compat && fdt_compat_len)
+ printf(" (%s)", fdt_compat);
+ puts("\n");
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec),
+ &dev);
+
+ if (!ret)
+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
+ &otp, sizeof(otp));
+ if (!ret && otp) {
+ printf("Board: MB%04x Var%d Rev.%c-%02d\n",
+ otp >> 16,
+ (otp >> 12) & 0xF,
+ ((otp >> 8) & 0xF) - 1 + 'A',
+ otp & 0xF);
+ }
+
+ return 0;
+}
+
+static void board_key_check(void)
+{
+#if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
+ ofnode node;
+ struct gpio_desc gpio;
+ enum forced_boot_mode boot_mode = BOOT_NORMAL;
+
+ node = ofnode_path("/config");
+ if (!ofnode_valid(node)) {
+ debug("%s: no /config node?\n", __func__);
+ return;
+ }
+#ifdef CONFIG_FASTBOOT
+ if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
+ &gpio, GPIOD_IS_IN)) {
+ debug("%s: could not find a /config/st,fastboot-gpios\n",
+ __func__);
+ } else {
+ if (dm_gpio_get_value(&gpio)) {
+ puts("Fastboot key pressed, ");
+ boot_mode = BOOT_FASTBOOT;
+ }
+
+ dm_gpio_free(NULL, &gpio);
+ }
+#endif
+#ifdef CONFIG_CMD_STM32PROG
+ if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
+ &gpio, GPIOD_IS_IN)) {
+ debug("%s: could not find a /config/st,stm32prog-gpios\n",
+ __func__);
+ } else {
+ if (dm_gpio_get_value(&gpio)) {
+ puts("STM32Programmer key pressed, ");
+ boot_mode = BOOT_STM32PROG;
+ }
+ dm_gpio_free(NULL, &gpio);
+ }
+#endif
+
+ if (boot_mode != BOOT_NORMAL) {
+ puts("entering download mode...\n");
+ clrsetbits_le32(TAMP_BOOT_CONTEXT,
+ TAMP_BOOT_FORCED_MASK,
+ boot_mode);
+ }
+#endif
+}
+
static struct dwc2_plat_otg_data stm32mp_otg_data = {
.usb_gusbcfg = STM32MP_GUSBCFG,
};
@@ -170,6 +299,145 @@ clk_err:
return ret;
}
+static int get_led(struct udevice **dev, char *led_string)
+{
+ char *led_name;
+ int ret;
+
+ led_name = fdtdec_get_config_string(gd->fdt_blob, led_string);
+ if (!led_name) {
+ pr_debug("%s: could not find %s config string\n",
+ __func__, led_string);
+ return -ENOENT;
+ }
+ ret = led_get_by_label(led_name, dev);
+ if (ret) {
+ debug("%s: get=%d\n", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int setup_led(enum led_state_t cmd)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = get_led(&dev, "u-boot,boot-led");
+ if (ret)
+ return ret;
+
+ ret = led_set_state(dev, cmd);
+ return ret;
+}
+
+static int board_check_usb_power(void)
+{
+ struct ofnode_phandle_args adc_args;
+ struct udevice *adc;
+ struct udevice *led;
+ ofnode node;
+ unsigned int raw;
+ int max_uV = 0;
+ int ret, uV, adc_count;
+ u8 i, nb_blink;
+
+ node = ofnode_path("/config");
+ if (!ofnode_valid(node)) {
+ debug("%s: no /config node?\n", __func__);
+ return -ENOENT;
+ }
+
+ /*
+ * Retrieve the ADC channels devices and get measurement
+ * for each of them
+ */
+ adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd",
+ "#io-channel-cells");
+ if (adc_count < 0) {
+ if (adc_count == -ENOENT)
+ return 0;
+
+ pr_err("%s: can't find adc channel (%d)\n", __func__,
+ adc_count);
+
+ return adc_count;
+ }
+
+ for (i = 0; i < adc_count; i++) {
+ if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd",
+ "#io-channel-cells", 0, i,
+ &adc_args)) {
+ pr_debug("%s: can't find /config/st,adc_usb_pd\n",
+ __func__);
+ return 0;
+ }
+
+ ret = uclass_get_device_by_ofnode(UCLASS_ADC, adc_args.node,
+ &adc);
+
+ if (ret) {
+ pr_err("%s: Can't get adc device(%d)\n", __func__,
+ ret);
+ return ret;
+ }
+
+ ret = adc_channel_single_shot(adc->name, adc_args.args[0],
+ &raw);
+ if (ret) {
+ pr_err("%s: single shot failed for %s[%d]!\n",
+ __func__, adc->name, adc_args.args[0]);
+ return ret;
+ }
+ /* Convert to uV */
+ if (!adc_raw_to_uV(adc, raw, &uV)) {
+ if (uV > max_uV)
+ max_uV = uV;
+ pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__,
+ adc->name, adc_args.args[0], raw, uV);
+ } else {
+ pr_err("%s: Can't get uV value for %s[%d]\n",
+ __func__, adc->name, adc_args.args[0]);
+ }
+ }
+
+ /*
+ * If highest value is inside 1.23 Volts and 2.10 Volts, that means
+ * board is plugged on an USB-C 3A power supply and boot process can
+ * continue.
+ */
+ if (max_uV > USB_START_LOW_THRESHOLD_UV &&
+ max_uV < USB_START_HIGH_THRESHOLD_UV)
+ return 0;
+
+ /* Display warning message and make u-boot,error-led blinking */
+ pr_err("\n*******************************************\n");
+
+ if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) {
+ pr_err("* WARNING 500mA power supply detected *\n");
+ nb_blink = 2;
+ } else {
+ pr_err("* WARNING 1.5A power supply detected *\n");
+ nb_blink = 3;
+ }
+
+ pr_err("* Current too low, use a 3A power supply! *\n");
+ pr_err("*******************************************\n\n");
+
+ ret = get_led(&led, "u-boot,error-led");
+ if (ret)
+ return ret;
+
+ for (i = 0; i < nb_blink * 2; i++) {
+ led_set_state(led, LEDST_TOGGLE);
+ mdelay(125);
+ }
+ led_set_state(led, LEDST_ON);
+
+ return 0;
+}
+
int board_usb_cleanup(int index, enum usb_init_type init)
{
/* Reset usbotg */
@@ -180,19 +448,146 @@ int board_usb_cleanup(int index, enum usb_init_type init)
return 0;
}
-int board_late_init(void)
+static void sysconf_init(void)
{
- return 0;
+#ifndef CONFIG_STM32MP1_TRUSTED
+ u8 *syscfg;
+#ifdef CONFIG_DM_REGULATOR
+ struct udevice *pwr_dev;
+ struct udevice *pwr_reg;
+ struct udevice *dev;
+ int ret;
+ u32 otp = 0;
+#endif
+ u32 bootr;
+
+ syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
+
+ /* interconnect update : select master using the port 1 */
+ /* LTDC = AXI_M9 */
+ /* GPU = AXI_M8 */
+ /* today information is hardcoded in U-Boot */
+ writel(BIT(9), syscfg + SYSCFG_ICNR);
+
+ /* disable Pull-Down for boot pin connected to VDD */
+ bootr = readl(syscfg + SYSCFG_BOOTR);
+ bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
+ bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
+ writel(bootr, syscfg + SYSCFG_BOOTR);
+
+#ifdef CONFIG_DM_REGULATOR
+ /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
+ * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
+ * The customer will have to disable this for low frequencies
+ * or if AFMUX is selected but the function not used, typically for
+ * TRACE. Otherwise, impact on power consumption.
+ *
+ * WARNING:
+ * enabling High Speed mode while VDD>2.7V
+ * with the OTP product_below_2v5 (OTP 18, BIT 13)
+ * erroneously set to 1 can damage the IC!
+ * => U-Boot set the register only if VDD < 2.7V (in DT)
+ * but this value need to be consistent with board design
+ */
+ ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev);
+ if (!ret) {
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec),
+ &dev);
+ if (ret) {
+ pr_err("Can't find stm32mp_bsec driver\n");
+ return;
+ }
+
+ ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
+ if (!ret)
+ otp = otp & BIT(13);
+
+ /* get VDD = pwr-supply */
+ ret = device_get_supply_regulator(pwr_dev, "pwr-supply",
+ &pwr_reg);
+
+ /* check if VDD is Low Voltage */
+ if (!ret) {
+ if (regulator_get_value(pwr_reg) < 2700000) {
+ writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
+ SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
+ SYSCFG_IOCTRLSETR_HSLVEN_ETH |
+ SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
+ SYSCFG_IOCTRLSETR_HSLVEN_SPI,
+ syscfg + SYSCFG_IOCTRLSETR);
+
+ if (!otp)
+ pr_err("product_below_2v5=0: HSLVEN protected by HW\n");
+ } else {
+ if (otp)
+ pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
+ }
+ } else {
+ debug("VDD unknown");
+ }
+ }
+#endif
+
+ /* activate automatic I/O compensation
+ * warning: need to ensure CSI enabled and ready in clock driver
+ */
+ writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
+
+ while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY))
+ ;
+ clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
+#endif
}
/* board dependent setup after realloc */
int board_init(void)
{
+ struct udevice *dev;
+
/* address of boot parameters */
gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
+ /* probe all PINCTRL for hog */
+ for (uclass_first_device(UCLASS_PINCTRL, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ pr_debug("probe pincontrol = %s\n", dev->name);
+ }
+
+ board_key_check();
+
+ sysconf_init();
+
if (IS_ENABLED(CONFIG_LED))
led_default_state();
return 0;
}
+
+int board_late_init(void)
+{
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+ const void *fdt_compat;
+ int fdt_compat_len;
+
+ fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
+ &fdt_compat_len);
+ if (fdt_compat && fdt_compat_len) {
+ if (strncmp(fdt_compat, "st,", 3) != 0)
+ env_set("board_name", fdt_compat);
+ else
+ env_set("board_name", fdt_compat + 3);
+ }
+#endif
+
+ /* for DK1/DK2 boards */
+ board_check_usb_power();
+
+ return 0;
+}
+
+void board_quiesce_devices(void)
+{
+ setup_led(LEDST_OFF);
+}
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 8e2f90fc68c..338f374e56e 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -341,6 +341,11 @@ M: FUKAUMI Naoki <naobsd@gmail.com>
S: Maintained
F: configs/Nintendo_NES_Classic_Edition_defconfig
+OCEANIC 5205 5INMFD BOARD
+M: Jagan Teki <jagan@amarulasolutions.com>
+S: Maintained
+F: configs/oceanic_5205_5inmfd_defconfig
+
OLIMEX A20-SOM204 BOARD
M: Stefan Mavrodiev <stefan@olimex.com>
S: Maintained
@@ -348,7 +353,7 @@ F: configs/A20-Olimex-SOM204-EVB_defconfig
F: configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
ORANGEPI LITE2 BOARD
-M: Jagan Teki <jagan@openedev.com>
+M: Jagan Teki <jagan@amarulasolutions.com>
S: Maintained
F: configs/orangepi_lite2_defconfig
diff --git a/board/theadorable/theadorable.c b/board/theadorable/theadorable.c
index dd6def5e6e7..d42350319cc 100644
--- a/board/theadorable/theadorable.c
+++ b/board/theadorable/theadorable.c
@@ -1,11 +1,15 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright (C) 2015-2016 Stefan Roese <sr@denx.de>
+ * Copyright (C) 2015-2019 Stefan Roese <sr@denx.de>
*/
#include <common.h>
+#include <console.h>
#include <i2c.h>
#include <pci.h>
+#if !defined(CONFIG_SPL_BUILD)
+#include <bootcount.h>
+#endif
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
@@ -42,6 +46,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define STM_I2C_BUS 1
#define STM_I2C_ADDR 0x27
#define REBOOT_DELAY 1000 /* reboot-delay in ms */
+#define ABORT_TIMEOUT 3000 /* 3 seconds reboot abort timeout */
/* DDR3 static configuration */
static MV_DRAM_MC_INIT ddr3_theadorable[MV_MAX_DDR3_STATIC_SIZE] = {
@@ -127,15 +132,15 @@ MV_DRAM_MODES *ddr3_get_static_ddr_mode(void)
return &board_ddr_modes[0];
}
-MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode)
+MV_BIN_SERDES_CFG *board_serdes_cfg_get(void)
{
return &theadorable_serdes_cfg[0];
}
u8 board_sat_r_get(u8 dev_num, u8 reg)
{
- /* Bit 0 enables PCI 2.0 link capabilities instead of PCI 1.x */
- return 0x01;
+ /* Bit x enables PCI 2.0 link capabilities instead of PCI 1.x */
+ return 0xe; /* PEX port 0 is PCIe Gen1, PEX port 1..3 PCIe Gen2 */
}
int board_early_init_f(void)
@@ -218,7 +223,7 @@ int board_eth_init(bd_t *bis)
}
#endif
-#ifdef CONFIG_BOARD_LATE_INIT
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_LATE_INIT)
int board_late_init(void)
{
pci_dev_t bdf;
@@ -232,6 +237,7 @@ int board_late_init(void)
*/
bdf = pci_find_device(PCI_VENDOR_ID_PLX, 0x8619, 0);
if (bdf == -1) {
+ unsigned long start_time = get_timer(0);
u8 i2c_buf[8];
int ret;
@@ -239,6 +245,28 @@ int board_late_init(void)
bootcount = bootcount_load();
printf("Failed to find PLX PEX-switch (bootcount=%ld)\n",
bootcount);
+
+ /*
+ * The user can exit this boot-loop in the error case by
+ * hitting Ctrl-C. So wait some time for this key here.
+ */
+ printf("Continue booting with Ctrl-C, otherwise rebooting\n");
+ do {
+ /* Handle control-c and timeouts */
+ if (ctrlc()) {
+ printf("PEX error boot-loop aborted!\n");
+ return 0;
+ }
+ } while (get_timer(start_time) < ABORT_TIMEOUT);
+
+
+ /*
+ * At this stage the bootcounter has not been incremented
+ * yet. We need to do this manually here to get an actually
+ * working bootcounter in this error case.
+ */
+ bootcount_inc();
+
if (bootcount > PEX_SWITCH_NOT_FOUNT_LIMIT) {
printf("Issuing power-switch via uC!\n");
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 0b07b3b9d77..2bdbfcb3d09 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1101,6 +1101,12 @@ config CMD_VIRTIO
help
VirtIO block device support
+config CMD_WDT
+ bool "wdt"
+ depends on WDT
+ help
+ This provides commands to control the watchdog timer devices.
+
config CMD_AXI
bool "axi"
depends on AXI
diff --git a/cmd/Makefile b/cmd/Makefile
index acb85f49fba..6b1c6b094e6 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -142,6 +142,7 @@ obj-$(CONFIG_CMD_UBIFS) += ubifs.o
obj-$(CONFIG_CMD_UNIVERSE) += universe.o
obj-$(CONFIG_CMD_UNZIP) += unzip.o
obj-$(CONFIG_CMD_VIRTIO) += virtio.o
+obj-$(CONFIG_CMD_WDT) += wdt.o
obj-$(CONFIG_CMD_LZMADEC) += lzmadec.o
obj-$(CONFIG_CMD_USB) += usb.o disk.o
diff --git a/cmd/sf.c b/cmd/sf.c
index 738ef0e46dc..6ccf98ae512 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -81,14 +81,13 @@ static int do_spi_flash_probe(int argc, char * const argv[])
{
unsigned int bus = CONFIG_SF_DEFAULT_BUS;
unsigned int cs = CONFIG_SF_DEFAULT_CS;
+ /* In DM mode, defaults speed and mode will be taken from DT */
unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
unsigned int mode = CONFIG_SF_DEFAULT_MODE;
char *endp;
#ifdef CONFIG_DM_SPI_FLASH
struct udevice *new, *bus_dev;
int ret;
- /* In DM mode defaults will be taken from DT */
- speed = 0, mode = 0;
#else
struct spi_flash *new;
#endif
diff --git a/cmd/wdt.c b/cmd/wdt.c
new file mode 100644
index 00000000000..647d9899b43
--- /dev/null
+++ b/cmd/wdt.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Watchdog commands
+ *
+ * Copyright (c) 2019 Michael Walle <michael@walle.cc>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <wdt.h>
+
+static struct udevice *currdev;
+
+static int do_wdt_list(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_WDT, &uc);
+ if (ret)
+ return CMD_RET_FAILURE;
+
+ uclass_foreach_dev(dev, uc)
+ printf("%s (%s)\n", dev->name, dev->driver->name);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_dev(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int ret;
+
+ if (argc > 1) {
+ ret = uclass_get_device_by_name(UCLASS_WDT, argv[1], &currdev);
+ if (ret) {
+ printf("Can't get the watchdog timer: %s\n", argv[1]);
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ if (!currdev) {
+ printf("No watchdog timer device set!\n");
+ return CMD_RET_FAILURE;
+ }
+ printf("dev: %s\n", currdev->name);
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int check_currdev(void)
+{
+ if (!currdev) {
+ printf("No device set, use 'wdt dev' first\n");
+ return CMD_RET_FAILURE;
+ }
+ return 0;
+}
+
+static int do_wdt_start(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int ret;
+ u64 timeout;
+ ulong flags = 0;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ ret = check_currdev();
+ if (ret)
+ return ret;
+
+ timeout = simple_strtoull(argv[1], NULL, 0);
+ if (argc > 2)
+ flags = simple_strtoul(argv[2], NULL, 0);
+
+ ret = wdt_start(currdev, timeout, flags);
+ if (ret == -ENOSYS) {
+ printf("Starting watchdog timer not supported.\n");
+ return CMD_RET_FAILURE;
+ } else if (ret) {
+ printf("Starting watchdog timer failed (%d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_stop(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int ret;
+
+ ret = check_currdev();
+ if (ret)
+ return ret;
+
+ ret = wdt_stop(currdev);
+ if (ret == -ENOSYS) {
+ printf("Stopping watchdog timer not supported.\n");
+ return CMD_RET_FAILURE;
+ } else if (ret) {
+ printf("Stopping watchdog timer failed (%d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_reset(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int ret;
+
+ ret = check_currdev();
+ if (ret)
+ return ret;
+
+ ret = wdt_reset(currdev);
+ if (ret == -ENOSYS) {
+ printf("Resetting watchdog timer not supported.\n");
+ return CMD_RET_FAILURE;
+ } else if (ret) {
+ printf("Resetting watchdog timer failed (%d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_wdt_expire(cmd_tbl_t *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int ret;
+ ulong flags = 0;
+
+ ret = check_currdev();
+ if (ret)
+ return ret;
+
+ if (argc > 1)
+ flags = simple_strtoul(argv[1], NULL, 0);
+
+ ret = wdt_expire_now(currdev, flags);
+ if (ret == -ENOSYS) {
+ printf("Expiring watchdog timer not supported.\n");
+ return CMD_RET_FAILURE;
+ } else if (ret) {
+ printf("Expiring watchdog timer failed (%d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+static char wdt_help_text[] =
+ "list - list watchdog devices\n"
+ "wdt dev [<name>] - get/set current watchdog device\n"
+ "wdt start <timeout ms> [flags] - start watchdog timer\n"
+ "wdt stop - stop watchdog timer\n"
+ "wdt reset - reset watchdog timer\n"
+ "wdt expire [flags] - expire watchdog timer immediately\n";
+
+U_BOOT_CMD_WITH_SUBCMDS(wdt, "Watchdog sub-system", wdt_help_text,
+ U_BOOT_SUBCMD_MKENT(list, 1, 1, do_wdt_list),
+ U_BOOT_SUBCMD_MKENT(dev, 2, 1, do_wdt_dev),
+ U_BOOT_SUBCMD_MKENT(start, 3, 1, do_wdt_start),
+ U_BOOT_SUBCMD_MKENT(stop, 1, 1, do_wdt_stop),
+ U_BOOT_SUBCMD_MKENT(reset, 1, 1, do_wdt_reset),
+ U_BOOT_SUBCMD_MKENT(expire, 2, 1, do_wdt_expire));
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 42583e3ed8c..ab08a0114fe 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -456,12 +456,6 @@ int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks)
if (!banks)
return 0;
- for (i = 0; i < banks; i++)
- if (start[i] == 0 && size[i] == 0)
- break;
-
- banks = i;
-
len = fdt_pack_reg(blob, tmp, start, size, banks);
err = fdt_setprop(blob, nodeoffset, "reg", tmp, len);
diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c
index 8cd4830a39b..9b74473377f 100644
--- a/common/spl/spl_spi.c
+++ b/common/spl/spl_spi.c
@@ -77,6 +77,8 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
/*
* Load U-Boot image from SPI flash into RAM
+ * In DM mode: defaults speed and mode will be
+ * taken from DT when available
*/
flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 020f0d4117f..cc99c6be072 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -145,6 +145,12 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, char c)
data->usb_kbd_buffer[data->usb_in_pointer] = c;
}
+static void usb_kbd_put_sequence(struct usb_kbd_pdata *data, char *s)
+{
+ for (; *s; s++)
+ usb_kbd_put_queue(data, *s);
+}
+
/*
* Set the LEDs. Since this is used in the irq routine, the control job is
* issued with a timeout of 0. This means, that the job is queued without
@@ -235,9 +241,25 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode,
}
/* Report keycode if any */
- if (keycode) {
+ if (keycode)
debug("%c", keycode);
+
+ switch (keycode) {
+ case 0x0e: /* Down arrow key */
+ usb_kbd_put_sequence(data, "\e[B");
+ break;
+ case 0x10: /* Up arrow key */
+ usb_kbd_put_sequence(data, "\e[A");
+ break;
+ case 0x06: /* Right arrow key */
+ usb_kbd_put_sequence(data, "\e[C");
+ break;
+ case 0x02: /* Left arrow key */
+ usb_kbd_put_sequence(data, "\e[D");
+ break;
+ default:
usb_kbd_put_queue(data, keycode);
+ break;
}
return 0;
diff --git a/configs/ap152_defconfig b/configs/ap152_defconfig
new file mode 100644
index 00000000000..21cb6eb7424
--- /dev/null
+++ b/configs/ap152_defconfig
@@ -0,0 +1,49 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x9F000000
+CONFIG_SYS_MALLOC_F_LEN=0x800
+CONFIG_SYS_CACHE_SIZE_AUTO=y
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0xb8020000
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_ARCH_ATH79=y
+CONFIG_TARGET_AP152=y
+CONFIG_DEBUG_UART=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs"
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SYS_PROMPT="ap152 # "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi-flash.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-flash.0:256k(u-boot),64k(u-boot-env),6336k(rootfs),1472k(uImage),64k(ART)"
+# CONFIG_ISO_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="ap152"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+# CONFIG_NET is not set
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_DATAFLASH=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PINCTRL=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_ATH79_SPI=y
+CONFIG_LZMA=y
diff --git a/configs/bananapi_m2_plus_h3_defconfig b/configs/bananapi_m2_plus_h3_defconfig
index 597618fb900..4e4734655fc 100644
--- a/configs/bananapi_m2_plus_h3_defconfig
+++ b/configs/bananapi_m2_plus_h3_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MACPWR="PD6"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/bananapi_m2_plus_h5_defconfig b/configs/bananapi_m2_plus_h5_defconfig
index e7c10dbdf2d..29dd892d7f0 100644
--- a/configs/bananapi_m2_plus_h5_defconfig
+++ b/configs/bananapi_m2_plus_h5_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MACPWR="PD6"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/bananapi_m2_zero_defconfig b/configs/bananapi_m2_zero_defconfig
index 91302eb49cf..8546674b239 100644
--- a/configs/bananapi_m2_zero_defconfig
+++ b/configs/bananapi_m2_zero_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=408
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MMC0_CD_PIN=""
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
diff --git a/configs/bcm963158_ram_defconfig b/configs/bcm963158_ram_defconfig
index fc55e98550a..5659249fdf3 100644
--- a/configs/bcm963158_ram_defconfig
+++ b/configs/bcm963158_ram_defconfig
@@ -20,6 +20,7 @@ CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_LZMADEC is not set
# CONFIG_CMD_UNZIP is not set
# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
CONFIG_CMD_CACHE=y
CONFIG_DOS_PARTITION=y
CONFIG_ISO_PARTITION=y
@@ -28,6 +29,8 @@ CONFIG_DEFAULT_DEVICE_TREE="bcm963158"
# CONFIG_NET is not set
CONFIG_BLK=y
CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_BCM6345_GPIO=y
# CONFIG_MMC is not set
CONFIG_SPECIFY_CONSOLE_INDEX=y
# CONFIG_SPL_SERIAL_PRESENT is not set
diff --git a/configs/bcm968380gerg_ram_defconfig b/configs/bcm968380gerg_ram_defconfig
index 61661bd756c..fa9dc85d638 100644
--- a/configs/bcm968380gerg_ram_defconfig
+++ b/configs/bcm968380gerg_ram_defconfig
@@ -24,6 +24,7 @@ CONFIG_CMD_LICENSE=y
# CONFIG_CMD_CRC32 is not set
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
# CONFIG_CMD_LOADS is not set
# CONFIG_CMD_MISC is not set
CONFIG_DEFAULT_DEVICE_TREE="brcm,bcm968380gerg"
@@ -31,6 +32,7 @@ CONFIG_DEFAULT_DEVICE_TREE="brcm,bcm968380gerg"
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_HAVE_BLOCK_DEVICE=y
CONFIG_DM_GPIO=y
+CONFIG_BCM6345_GPIO=y
CONFIG_LED=y
CONFIG_LED_BCM6328=y
CONFIG_LED_BLINK=y
diff --git a/configs/bcm968580xref_ram_defconfig b/configs/bcm968580xref_ram_defconfig
index e8cb3a0d2a9..456ece72d5c 100644
--- a/configs/bcm968580xref_ram_defconfig
+++ b/configs/bcm968580xref_ram_defconfig
@@ -15,6 +15,7 @@ CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_BOOTEFI_SELFTEST=y
+CONFIG_CMD_GPIO=y
CONFIG_DOS_PARTITION=y
CONFIG_ISO_PARTITION=y
CONFIG_EFI_PARTITION=y
@@ -22,6 +23,8 @@ CONFIG_DEFAULT_DEVICE_TREE="bcm968580xref"
# CONFIG_NET is not set
CONFIG_BLK=y
CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_BCM6345_GPIO=y
# CONFIG_MMC is not set
CONFIG_SPECIFY_CONSOLE_INDEX=y
# CONFIG_SPL_SERIAL_PRESENT is not set
diff --git a/configs/da850_am18xxevm_defconfig b/configs/da850_am18xxevm_defconfig
index b8c16baf9a9..419224104af 100644
--- a/configs/da850_am18xxevm_defconfig
+++ b/configs/da850_am18xxevm_defconfig
@@ -39,10 +39,6 @@ CONFIG_SPL_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
CONFIG_SPL_OF_PLATDATA=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_USE_ENV_SPI_MAX_HZ=y
-CONFIG_ENV_SPI_MAX_HZ=0
-CONFIG_USE_ENV_SPI_MODE=y
-CONFIG_ENV_SPI_MODE=0
CONFIG_DM=y
CONFIG_SPL_DM=y
CONFIG_DA8XX_GPIO=y
diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig
index 4083dcbae69..4b09ba10a67 100644
--- a/configs/da850evm_defconfig
+++ b/configs/da850evm_defconfig
@@ -43,10 +43,6 @@ CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_USE_ENV_SPI_MAX_HZ=y
-CONFIG_ENV_SPI_MAX_HZ=0
-CONFIG_USE_ENV_SPI_MODE=y
-CONFIG_ENV_SPI_MODE=0
CONFIG_DM=y
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
diff --git a/configs/db-88f6820-amc_defconfig b/configs/db-88f6820-amc_defconfig
index dcf2a25395e..e8ba5184c4d 100644
--- a/configs/db-88f6820-amc_defconfig
+++ b/configs/db-88f6820-amc_defconfig
@@ -41,7 +41,7 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_EFI_PARTITION=y
# CONFIG_PARTITION_UUIDS is not set
# CONFIG_SPL_PARTITION_UUIDS is not set
-CONFIG_DEFAULT_DEVICE_TREE="armada-385-amc"
+CONFIG_DEFAULT_DEVICE_TREE="armada-385-db-88f6820-amc"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=50000000
diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig
index 98e47ee9563..078bd230504 100644
--- a/configs/db-mv784mp-gp_defconfig
+++ b/configs/db-mv784mp-gp_defconfig
@@ -46,6 +46,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_SPL_OF_TRANSLATE=y
CONFIG_SATA_MV=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_NAND=y
CONFIG_NAND_PXA3XX=y
diff --git a/configs/db-xc3-24g4xg_defconfig b/configs/db-xc3-24g4xg_defconfig
new file mode 100644
index 00000000000..0285ccaa365
--- /dev/null
+++ b/configs/db-xc3-24g4xg_defconfig
@@ -0,0 +1,55 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_SYS_TEXT_BASE=0x00800000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_TARGET_DB_XC3_24G4XG=y
+CONFIG_BUILD_TARGET="u-boot.kwb"
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_SYS_ALT_MEMTEST=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_I2C=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_UBI=y
+CONFIG_DEFAULT_DEVICE_TREE="armada-xp-db-xc3-24g4xg"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_BLK=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MVTWSI=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_MTD_DEVICE=y
+CONFIG_NAND=y
+CONFIG_NAND_PXA3XX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_PCI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_SYS_NS16550=y
+CONFIG_KIRKWOOD_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
diff --git a/configs/dns325_defconfig b/configs/dns325_defconfig
index 5a766981603..ba8b053680b 100644
--- a/configs/dns325_defconfig
+++ b/configs/dns325_defconfig
@@ -30,6 +30,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-dns325"
CONFIG_ENV_IS_IN_NAND=y
CONFIG_DM=y
CONFIG_MVSATA_IDE=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_MVGBE=y
CONFIG_MII=y
@@ -37,5 +38,6 @@ CONFIG_DM_RTC=y
CONFIG_RTC_MV=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
diff --git a/configs/dreamplug_defconfig b/configs/dreamplug_defconfig
index 8202848ebf7..eae36f9c0eb 100644
--- a/configs/dreamplug_defconfig
+++ b/configs/dreamplug_defconfig
@@ -27,6 +27,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_DM=y
CONFIG_MVSATA_IDE=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
@@ -40,5 +41,6 @@ CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_KIRKWOOD_SPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
diff --git a/configs/ds109_defconfig b/configs/ds109_defconfig
index 29d5f98d76c..22996e893d6 100644
--- a/configs/ds109_defconfig
+++ b/configs/ds109_defconfig
@@ -22,6 +22,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_DM=y
CONFIG_MVSATA_IDE=y
+CONFIG_BLK=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MVTWSI=y
# CONFIG_MMC is not set
@@ -37,5 +38,6 @@ CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_KIRKWOOD_SPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_FS_EXT4=y
diff --git a/configs/ds414_defconfig b/configs/ds414_defconfig
index 62cad538883..9e936494b2b 100644
--- a/configs/ds414_defconfig
+++ b/configs/ds414_defconfig
@@ -43,6 +43,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_MTD_DEVICE=y
CONFIG_SPI_FLASH=y
diff --git a/configs/emlid_neutis_n5_devboard_defconfig b/configs/emlid_neutis_n5_devboard_defconfig
index 3df0ca13f04..19e8d792556 100644
--- a/configs/emlid_neutis_n5_devboard_defconfig
+++ b/configs/emlid_neutis_n5_devboard_defconfig
@@ -4,6 +4,7 @@ CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=408
CONFIG_DRAM_ZQ=3881977
+# CONFIG_DRAM_ODT_EN is not set
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/goflexhome_defconfig b/configs/goflexhome_defconfig
index c04bf0ea574..568b74fd830 100644
--- a/configs/goflexhome_defconfig
+++ b/configs/goflexhome_defconfig
@@ -31,6 +31,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-goflexnet"
CONFIG_ENV_IS_IN_NAND=y
CONFIG_DM=y
CONFIG_MVSATA_IDE=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_MVGBE=y
CONFIG_MII=y
@@ -38,5 +39,6 @@ CONFIG_DM_RTC=y
CONFIG_RTC_MV=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
diff --git a/configs/guruplug_defconfig b/configs/guruplug_defconfig
index 9998e48ab9c..8ae7e20bafd 100644
--- a/configs/guruplug_defconfig
+++ b/configs/guruplug_defconfig
@@ -31,6 +31,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-guruplug-server-plus"
CONFIG_ENV_IS_IN_NAND=y
CONFIG_DM=y
CONFIG_MVSATA_IDE=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_MVGBE=y
CONFIG_MII=y
@@ -38,6 +39,7 @@ CONFIG_DM_RTC=y
CONFIG_RTC_MV=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_LZMA=y
diff --git a/configs/libretech_all_h3_cc_h2_plus_defconfig b/configs/libretech_all_h3_cc_h2_plus_defconfig
index 8f3144895c6..3bccd604291 100644
--- a/configs/libretech_all_h3_cc_h2_plus_defconfig
+++ b/configs/libretech_all_h3_cc_h2_plus_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/libretech_all_h3_cc_h3_defconfig b/configs/libretech_all_h3_cc_h3_defconfig
index e5e0f593a7d..c00ab01fdda 100644
--- a/configs/libretech_all_h3_cc_h3_defconfig
+++ b/configs/libretech_all_h3_cc_h3_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/libretech_all_h3_cc_h5_defconfig b/configs/libretech_all_h3_cc_h5_defconfig
index e4a93bde481..5843f34325b 100644
--- a/configs/libretech_all_h3_cc_h5_defconfig
+++ b/configs/libretech_all_h3_cc_h5_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig
index 2d3ab7e35c3..649db0f67d0 100644
--- a/configs/linkit-smart-7688-ram_defconfig
+++ b/configs/linkit-smart-7688-ram_defconfig
@@ -20,17 +20,22 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PART=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
+CONFIG_CMD_FS_GENERIC=y
+# CONFIG_DOS_PARTITION is not set
CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
-CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
@@ -46,6 +51,7 @@ CONFIG_PHYLIB=y
CONFIG_PHY_FIXED=y
CONFIG_MT7628_ETH=y
CONFIG_PHY=y
+CONFIG_MT76X8_USB_PHY=y
CONFIG_POWER_DOMAIN=y
CONFIG_RAM=y
CONFIG_DM_RESET=y
@@ -54,5 +60,12 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
CONFIG_SYSRESET_SYSCON=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_STORAGE=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT=y
CONFIG_LZMA=y
CONFIG_LZO=y
diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig
index ad34aaf640c..41aa900e562 100644
--- a/configs/linkit-smart-7688_defconfig
+++ b/configs/linkit-smart-7688_defconfig
@@ -24,17 +24,22 @@ CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PART=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_TIME=y
+CONFIG_CMD_FS_GENERIC=y
+# CONFIG_DOS_PARTITION is not set
CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
# CONFIG_DM_DEVICE_REMOVE is not set
-CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_BLK=y
CONFIG_CLK=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
@@ -50,6 +55,7 @@ CONFIG_PHYLIB=y
CONFIG_PHY_FIXED=y
CONFIG_MT7628_ETH=y
CONFIG_PHY=y
+CONFIG_MT76X8_USB_PHY=y
CONFIG_POWER_DOMAIN=y
CONFIG_RAM=y
CONFIG_DM_RESET=y
@@ -58,5 +64,12 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
CONFIG_SYSRESET_SYSCON=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_STORAGE=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT=y
CONFIG_LZMA=y
CONFIG_LZO=y
diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig
index 16d9c9226f0..c550798bcd4 100644
--- a/configs/lschlv2_defconfig
+++ b/configs/lschlv2_defconfig
@@ -16,7 +16,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_MISC_INIT_R=y
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_IDE=y
+CONFIG_CMD_SATA=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
@@ -26,7 +26,8 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-lschlv2"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
-CONFIG_MVSATA_IDE=y
+CONFIG_SATA_MV=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
@@ -39,4 +40,5 @@ CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_KIRKWOOD_SPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig
index b6eba4a4ba1..efcce455a48 100644
--- a/configs/lsxhl_defconfig
+++ b/configs/lsxhl_defconfig
@@ -16,7 +16,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_MISC_INIT_R=y
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_IDE=y
+CONFIG_CMD_SATA=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
@@ -26,7 +26,8 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-lsxhl"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM=y
-CONFIG_MVSATA_IDE=y
+CONFIG_SATA_MV=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
@@ -39,4 +40,5 @@ CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_KIRKWOOD_SPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig
index 95562b7cd85..d6e4bd4f9ac 100644
--- a/configs/mscc_jr2_defconfig
+++ b/configs/mscc_jr2_defconfig
@@ -28,7 +28,10 @@ CONFIG_CMD_MEMTEST=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
-# CONFIG_CMD_NET is not set
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:1m(UBoot),256k(Env),256k(Env.bk)"
@@ -38,10 +41,6 @@ CONFIG_OF_LIST="jr2_pcb110 jr2_pcb111 serval2_pcb112"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_USE_ENV_SPI_MAX_HZ=y
-CONFIG_ENV_SPI_MAX_HZ=0
-CONFIG_USE_ENV_SPI_MODE=y
-CONFIG_ENV_SPI_MODE=0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_CLK=y
CONFIG_DM_GPIO=y
@@ -66,3 +65,4 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_LZMA=y
+CONFIG_MSCC_JR2_SWITCH=y
diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig
index 162a5142489..0fdd9b8f3f7 100644
--- a/configs/mscc_luton_defconfig
+++ b/configs/mscc_luton_defconfig
@@ -44,10 +44,6 @@ CONFIG_OF_LIST="luton_pcb090 luton_pcb091"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_USE_ENV_SPI_MAX_HZ=y
-CONFIG_ENV_SPI_MAX_HZ=0
-CONFIG_USE_ENV_SPI_MODE=y
-CONFIG_ENV_SPI_MODE=0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_CLK=y
CONFIG_DM_GPIO=y
diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig
index b0dcfaf2df8..edc476d143f 100644
--- a/configs/mscc_ocelot_defconfig
+++ b/configs/mscc_ocelot_defconfig
@@ -43,10 +43,6 @@ CONFIG_OF_LIST="ocelot_pcb120 ocelot_pcb123"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_USE_ENV_SPI_MAX_HZ=y
-CONFIG_ENV_SPI_MAX_HZ=0
-CONFIG_USE_ENV_SPI_MODE=y
-CONFIG_ENV_SPI_MODE=0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_CLK=y
CONFIG_DM_GPIO=y
diff --git a/configs/mscc_serval_defconfig b/configs/mscc_serval_defconfig
index f2c95632bd0..146188bb0c9 100644
--- a/configs/mscc_serval_defconfig
+++ b/configs/mscc_serval_defconfig
@@ -35,10 +35,6 @@ CONFIG_OF_LIST="serval_pcb106 serval_pcb105"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_USE_ENV_SPI_MAX_HZ=y
-CONFIG_ENV_SPI_MAX_HZ=0
-CONFIG_USE_ENV_SPI_MODE=y
-CONFIG_ENV_SPI_MODE=0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_CLK=y
CONFIG_DM_GPIO=y
diff --git a/configs/mscc_servalt_defconfig b/configs/mscc_servalt_defconfig
index 027aaa44d56..924cf6ad013 100644
--- a/configs/mscc_servalt_defconfig
+++ b/configs/mscc_servalt_defconfig
@@ -24,7 +24,6 @@ CONFIG_CMD_MEMTEST=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
-# CONFIG_CMD_NET is not set
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=spi_flash"
CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:1m(UBoot),256k(Env),256k(Env.bk)"
@@ -33,10 +32,6 @@ CONFIG_DEFAULT_DEVICE_TREE="servalt_pcb116"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_USE_ENV_SPI_MAX_HZ=y
-CONFIG_ENV_SPI_MAX_HZ=0
-CONFIG_USE_ENV_SPI_MODE=y
-CONFIG_ENV_SPI_MODE=0
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_CLK=y
CONFIG_DM_GPIO=y
@@ -59,3 +54,8 @@ CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_LZMA=y
+CONFIG_CMD_DHCP=y
+# CONFIG_NET_TFTP_VARS is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_MSCC_SERVALT_SWITCH=y
diff --git a/configs/nanopi_m1_defconfig b/configs/nanopi_m1_defconfig
index b3a7870ea9a..af7fa0b20b2 100644
--- a/configs/nanopi_m1_defconfig
+++ b/configs/nanopi_m1_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=408
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
diff --git a/configs/nanopi_m1_plus_defconfig b/configs/nanopi_m1_plus_defconfig
index b83cdf2e1cc..84e152546b6 100644
--- a/configs/nanopi_m1_plus_defconfig
+++ b/configs/nanopi_m1_plus_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=408
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MMC0_CD_PIN="PH13"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/nanopi_neo2_defconfig b/configs/nanopi_neo2_defconfig
index 9de893adfaf..2d44135bbc7 100644
--- a/configs/nanopi_neo2_defconfig
+++ b/configs/nanopi_neo2_defconfig
@@ -4,6 +4,7 @@ CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=672
CONFIG_DRAM_ZQ=3881977
+# CONFIG_DRAM_ODT_EN is not set
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
diff --git a/configs/nanopi_neo_air_defconfig b/configs/nanopi_neo_air_defconfig
index 33f9c0746c1..bd099c8d671 100644
--- a/configs/nanopi_neo_air_defconfig
+++ b/configs/nanopi_neo_air_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=408
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
# CONFIG_VIDEO_DE2 is not set
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/nanopi_neo_defconfig b/configs/nanopi_neo_defconfig
index 40f5bd176e5..074b172061f 100644
--- a/configs/nanopi_neo_defconfig
+++ b/configs/nanopi_neo_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=408
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
# CONFIG_VIDEO_DE2 is not set
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/nanopi_neo_plus2_defconfig b/configs/nanopi_neo_plus2_defconfig
index 88c76a55e53..11cb8f61b03 100644
--- a/configs/nanopi_neo_plus2_defconfig
+++ b/configs/nanopi_neo_plus2_defconfig
@@ -4,6 +4,7 @@ CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=408
CONFIG_DRAM_ZQ=3881977
+# CONFIG_DRAM_ODT_EN is not set
CONFIG_MACPWR="PD6"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/nas220_defconfig b/configs/nas220_defconfig
index 6bd308bb826..a244b8d6916 100644
--- a/configs/nas220_defconfig
+++ b/configs/nas220_defconfig
@@ -31,6 +31,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-blackarmor-nas220"
CONFIG_ENV_IS_IN_NAND=y
CONFIG_DM=y
CONFIG_MVSATA_IDE=y
+CONFIG_BLK=y
# CONFIG_MMC is not set
CONFIG_MVGBE=y
CONFIG_MII=y
@@ -38,5 +39,6 @@ CONFIG_DM_RTC=y
CONFIG_RTC_MV=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
diff --git a/configs/oceanic_5205_5inmfd_defconfig b/configs/oceanic_5205_5inmfd_defconfig
new file mode 100644
index 00000000000..34fe6f52735
--- /dev/null
+++ b/configs/oceanic_5205_5inmfd_defconfig
@@ -0,0 +1,20 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SPL=y
+CONFIG_MACH_SUN50I=y
+CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
+CONFIG_SUNXI_DRAM_LPDDR3_STOCK=y
+CONFIG_DRAM_CLK=552
+CONFIG_DRAM_ZQ=3881949
+CONFIG_MMC0_CD_PIN=""
+CONFIG_SPL_SPI_SUNXI=y
+CONFIG_NR_DRAM_BANKS=1
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-oceanic-5205-5inmfd"
+CONFIG_SUN8I_EMAC=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/orangepi_2_defconfig b/configs/orangepi_2_defconfig
index ab6566e49a8..ce3cc8352cf 100644
--- a/configs/orangepi_2_defconfig
+++ b/configs/orangepi_2_defconfig
@@ -4,8 +4,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_USB1_VBUS_PIN="PG13"
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/orangepi_lite_defconfig b/configs/orangepi_lite_defconfig
index 1092a852503..490f5a3aae4 100644
--- a/configs/orangepi_lite_defconfig
+++ b/configs/orangepi_lite_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
diff --git a/configs/orangepi_one_defconfig b/configs/orangepi_one_defconfig
index 404fdd91197..949fc5d40f7 100644
--- a/configs/orangepi_one_defconfig
+++ b/configs/orangepi_one_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig
index ad837382c8e..a5bac5b2926 100644
--- a/configs/orangepi_pc2_defconfig
+++ b/configs/orangepi_pc2_defconfig
@@ -4,6 +4,7 @@ CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=672
CONFIG_DRAM_ZQ=3881977
+# CONFIG_DRAM_ODT_EN is not set
CONFIG_MACPWR="PD6"
CONFIG_SPL_SPI_SUNXI=y
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig
index de11df755e4..79d623719e3 100644
--- a/configs/orangepi_pc_defconfig
+++ b/configs/orangepi_pc_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=624
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL_I2C_SUPPORT=y
diff --git a/configs/orangepi_pc_plus_defconfig b/configs/orangepi_pc_plus_defconfig
index ce26cfaf9b5..31e9bcf0b3f 100644
--- a/configs/orangepi_pc_plus_defconfig
+++ b/configs/orangepi_pc_plus_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=624
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/orangepi_plus2e_defconfig b/configs/orangepi_plus2e_defconfig
index b0813e4e10b..f31fd28a4f6 100644
--- a/configs/orangepi_plus2e_defconfig
+++ b/configs/orangepi_plus2e_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MACPWR="PD6"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig
index 05023737a95..8a9ea272c3c 100644
--- a/configs/orangepi_plus_defconfig
+++ b/configs/orangepi_plus_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=672
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
CONFIG_MACPWR="PD6"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_USB1_VBUS_PIN="PG13"
diff --git a/configs/orangepi_prime_defconfig b/configs/orangepi_prime_defconfig
index 20ae6df5a0d..0d64eebc099 100644
--- a/configs/orangepi_prime_defconfig
+++ b/configs/orangepi_prime_defconfig
@@ -4,6 +4,7 @@ CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=672
CONFIG_DRAM_ZQ=3881977
+# CONFIG_DRAM_ODT_EN is not set
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
diff --git a/configs/orangepi_r1_defconfig b/configs/orangepi_r1_defconfig
index 05c3b08b766..6492d8580c1 100644
--- a/configs/orangepi_r1_defconfig
+++ b/configs/orangepi_r1_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=624
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
# CONFIG_VIDEO_DE2 is not set
CONFIG_SPL_SPI_SUNXI=y
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/orangepi_zero_defconfig b/configs/orangepi_zero_defconfig
index 44fc18b7b1e..b881a848317 100644
--- a/configs/orangepi_zero_defconfig
+++ b/configs/orangepi_zero_defconfig
@@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=624
-CONFIG_DRAM_ZQ=3881979
-CONFIG_DRAM_ODT_EN=y
# CONFIG_VIDEO_DE2 is not set
CONFIG_SPL_SPI_SUNXI=y
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/orangepi_zero_plus2_defconfig b/configs/orangepi_zero_plus2_defconfig
index e62b3cb1504..ab0d12e750a 100644
--- a/configs/orangepi_zero_plus2_defconfig
+++ b/configs/orangepi_zero_plus2_defconfig
@@ -4,6 +4,7 @@ CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=672
CONFIG_DRAM_ZQ=3881977
+# CONFIG_DRAM_ODT_EN is not set
CONFIG_MMC0_CD_PIN="PH13"
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_NR_DRAM_BANKS=1
diff --git a/configs/orangepi_zero_plus_defconfig b/configs/orangepi_zero_plus_defconfig
index cc8b8c7f9ab..37ca6dff374 100644
--- a/configs/orangepi_zero_plus_defconfig
+++ b/configs/orangepi_zero_plus_defconfig
@@ -4,6 +4,7 @@ CONFIG_SPL=y
CONFIG_MACH_SUN50I_H5=y
CONFIG_DRAM_CLK=624
CONFIG_DRAM_ZQ=3881977
+# CONFIG_DRAM_ODT_EN is not set
CONFIG_NR_DRAM_BANKS=1
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_FLASH is not set
diff --git a/configs/pine64-lts_defconfig b/configs/pine64-lts_defconfig
index fd3cdeec858..a8331377872 100644
--- a/configs/pine64-lts_defconfig
+++ b/configs/pine64-lts_defconfig
@@ -16,4 +16,5 @@ CONFIG_NR_DRAM_BANKS=1
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-lts"
CONFIG_SUN8I_EMAC=y
CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index da4bdced310..c04ecd915ae 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -194,6 +194,7 @@ CONFIG_CMD_DHRYSTONE=y
CONFIG_TPM=y
CONFIG_LZ4=y
CONFIG_ERRNO_STR=y
+CONFIG_TEST_FDTDEC=y
CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 193e41896cb..bb508a8d02e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -215,6 +215,7 @@ CONFIG_CMD_DHRYSTONE=y
CONFIG_TPM=y
CONFIG_LZ4=y
CONFIG_ERRNO_STR=y
+CONFIG_TEST_FDTDEC=y
CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
diff --git a/configs/sheevaplug_defconfig b/configs/sheevaplug_defconfig
index 04b00cdea9d..ec527fceb6f 100644
--- a/configs/sheevaplug_defconfig
+++ b/configs/sheevaplug_defconfig
@@ -39,6 +39,7 @@ CONFIG_DM_RTC=y
CONFIG_RTC_MV=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_LZMA=y
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index d20b2ab3508..6781adb81e7 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -1,11 +1,12 @@
CONFIG_ARM=y
CONFIG_ARCH_STM32MP=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x3000
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL=y
CONFIG_TARGET_STM32MP1=y
CONFIG_DISTRO_DEFAULTS=y
-CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_BOOTCOMMAND="run bootcmd_stm32mp"
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3
CONFIG_SPL_I2C_SUPPORT=y
@@ -18,8 +19,10 @@ CONFIG_SYS_PROMPT="STM32MP> "
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_IMPORTENV is not set
CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
CONFIG_CMD_ADC=y
CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
@@ -27,12 +30,21 @@ CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_SPL_DOS_PARTITION is not set
CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1"
CONFIG_STM32_ADC=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
+CONFIG_FASTBOOT_BUF_SIZE=0x02000000
+CONFIG_FASTBOOT_USB_DEV=1
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_DM_HWSPINLOCK=y
CONFIG_HWSPINLOCK_STM32=y
CONFIG_DM_I2C=y
@@ -43,15 +55,16 @@ CONFIG_DM_MMC=y
CONFIG_STM32_SDMMC2=y
CONFIG_PHY=y
CONFIG_PHY_STM32_USBPHYC=y
-# CONFIG_PINCTRL_FULL is not set
+CONFIG_PINCONF=y
# CONFIG_SPL_PINCTRL_FULL is not set
+CONFIG_PINCTRL_STMFX=y
CONFIG_DM_PMIC=y
# CONFIG_SPL_PMIC_CHILDREN is not set
-CONFIG_PMIC_STPMU1=y
+CONFIG_PMIC_STPMIC1=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_REGULATOR_STM32_VREFBUF=y
-CONFIG_DM_REGULATOR_STPMU1=y
+CONFIG_DM_REGULATOR_STPMIC1=y
CONFIG_SERIAL_RX_BUFFER=y
CONFIG_STM32_SERIAL=y
CONFIG_USB=y
@@ -64,4 +77,3 @@ CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
CONFIG_USB_GADGET_VENDOR_NUM=0x0483
CONFIG_USB_GADGET_PRODUCT_NUM=0x5720
CONFIG_USB_GADGET_DWC2_OTG=y
-CONFIG_USB_GADGET_DOWNLOAD=y
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
new file mode 100644
index 00000000000..a050cee6918
--- /dev/null
+++ b/configs/stm32mp15_trusted_defconfig
@@ -0,0 +1,70 @@
+CONFIG_ARM=y
+CONFIG_ARCH_STM32MP=y
+CONFIG_SYS_MALLOC_F_LEN=0x3000
+CONFIG_TARGET_STM32MP1=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_BOOTCOMMAND="run bootcmd_stm32mp"
+CONFIG_SYS_PROMPT="STM32MP> "
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_ADC=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_FUSE=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1"
+CONFIG_STM32_ADC=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
+CONFIG_FASTBOOT_BUF_SIZE=0x02000000
+CONFIG_FASTBOOT_USB_DEV=1
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_DM_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_STM32=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_STM32F7=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_STM32_SDMMC2=y
+CONFIG_PHY=y
+CONFIG_PHY_STM32_USBPHYC=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_STMFX=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_STPMIC1=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_DM_REGULATOR_STM32_VREFBUF=y
+CONFIG_DM_REGULATOR_STPMIC1=y
+CONFIG_SERIAL_RX_BUFFER=y
+CONFIG_STM32_SERIAL=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0483
+CONFIG_USB_GADGET_PRODUCT_NUM=0x5720
+CONFIG_USB_GADGET_DWC2_OTG=y
diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig
index fb9307aaf58..3736aec537d 100644
--- a/configs/theadorable_debug_defconfig
+++ b/configs/theadorable_debug_defconfig
@@ -51,6 +51,7 @@ CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_OF_TRANSLATE=y
CONFIG_SATA_MV=y
+CONFIG_BLK=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_RAM=y
CONFIG_FPGA_ALTERA=y
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index c406b257533..85f214148a8 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -43,6 +43,7 @@ CONFIG_ATSHA204A=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_MV=y
CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_SPANSION=y
CONFIG_PHY_MARVELL=y
CONFIG_PHY_GIGE=y
CONFIG_MVNETA=y
diff --git a/configs/x530_defconfig b/configs/x530_defconfig
index cd18e9eb454..c893c44452b 100644
--- a/configs/x530_defconfig
+++ b/configs/x530_defconfig
@@ -19,6 +19,8 @@ CONFIG_SILENT_CONSOLE=y
CONFIG_SILENT_U_BOOT_ONLY=y
CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC=y
CONFIG_MISC_INIT_R=y
+CONFIG_SPL_BOARD_INIT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
CONFIG_CMD_MEMINFO=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
@@ -72,3 +74,6 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
+CONFIG_WATCHDOG=y
+CONFIG_WDT=y
+CONFIG_WDT_ORION=y
diff --git a/doc/README.chromium b/doc/README.chromium
index 45eaeced2da..096bc4f1f7f 100644
--- a/doc/README.chromium
+++ b/doc/README.chromium
@@ -1,239 +1,177 @@
-Running U-Boot from coreboot on Chromebooks
-===========================================
+Chromium OS Support in U-Boot
+=============================
-U-Boot can be used as a secondary boot loader in a few situations such as from
-UEFI and coreboot (see README.x86). Recent Chromebooks use coreboot even on
-ARM platforms to start up the machine.
+Introduction
+------------
-This document aims to provide a guide to booting U-Boot on a Chromebook. It
-is only a starting point, and there are many guides on the interwebs. But
-placing this information in the U-Boot tree should make it easier to find for
-those who use U-Boot habitually.
+This describes how to use U-Boot with Chromium OS. Several options are
+available:
-Most of these platforms are supported by U-Boot natively, but it is risky to
-replace the ROM unless you have a servo board and cable to restore it with.
+ - Running U-Boot from the 'altfw' feature, which is available on selected
+ Chromebooks from 2019 onwards (initially Grunt). Press '1' from the
+ developer-mode screen to get into U-Boot. See here for details:
+ https://sites.google.com/a/chromium.org/dev/chromium-os/poking-around-your-chrome-os-device?pli=1
+ - Running U-Boot from the disk partition. This involves signing U-Boot and
+ placing it on the disk, for booting as a 'kernel'. See
+ README.chromium-chainload for information on this. This is the only
+ option on non-U-Boot Chromebooks from 2013 to 2018 and is somewhat
+ more involved.
-For all of these the standard U-Boot build instructions apply. For example on
-ARM:
+ - Running U-Boot with Chromium OS verified boot. This allows U-Boot to be
+ used instead of either or both of depthcharge (a bootloader which forked
+ from U-Boot in 2013) and coreboot. See below for more information on
+ this.
- sudo apt install gcc-arm-linux-gnueabi
- mkdir b
- make O=b/nyan_big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all
-You can obtain the vbutil_kernel utility here:
+U-Boot with Chromium OS verified boot
+-------------------------------------
- https://drive.google.com/open?id=0B7WYZbZ9zd-3dHlVVXo4VXE2T0U
+To obtain:
+ git clone https://github.com/sglass68/u-boot.git
+ cd u-boot
+ git checkout cros-master
-Snow (Samsung ARM Chromebook)
------------------------------
+To build for sandbox:
-See here:
+ UB=/tmp/b/chromeos_sandbox # U-Boot build directory
+ CROS=/home/sglass/cosarm # Chromium OS directory
+ make O=$UB/chromeos_sandbox_defconfig
+ make O=$UB -j20 -s VBOOT_SOURCE=$CROS/src/platform/vboot_reference \
+ MAKEFLAGS_VBOOT=DEBUG=1 QUIET=1
-https://www.chromium.org/chromium-os/firmware-porting-guide/using-nv-u-boot-on-the-samsung-arm-chromebook
+Replace sandbox with another supported target.
+This produces $UB/image.bin which contains the firmware binaries in a SPI
+flash image.
-Nyan-big
---------
-
-Compiled based on information here:
-https://lists.denx.de/pipermail/u-boot/2015-March/209530.html
-https://git.collabora.com/cgit/user/tomeu/u-boot.git/commit/?h=nyan-big
-https://lists.denx.de/pipermail/u-boot/2017-May/289491.html
-https://github.com/chromeos-nvidia-androidtv/gnu-linux-on-acer-chromebook-13#copy-data-to-the-sd-card
-
-1. Build U-Boot
-
- mkdir b
- make -j8 O=b/nyan-big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all
-
-
-2. Select a .its file
-
-Select something from doc/chromium which matches your board, or create your
-own.
-
-Note that the device tree node is required, even though it is not actually
-used by U-Boot. This is because the Chromebook expects to pass it to the
-kernel, and crashes if it is not present.
-
-
-3. Build and sign an image
-
- ./b/nyan-big/tools/mkimage -f doc/chromium/nyan-big.its u-boot-chromium.fit
- echo test >dummy.txt
- vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \
- --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \
- --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
- --bootloader dummy.txt --pack u-boot.kpart
-
-
-4. Prepare an SD card
-
- DISK=/dev/sdc # Replace with your actual SD card device
- sudo cgpt create $DISK
- sudo cgpt add -b 34 -s 32768 -P 1 -S 1 -t kernel $DISK
- sudo cgpt add -b 32802 -s 2000000 -t rootfs $DISK
- sudo gdisk $DISK # Enter command 'w' to write a protective MBR to the disk
-
-
-5. Write U-Boot to the SD card
+To run on sandbox:
- sudo dd if=u-boot.kpart of=/dev/sdc1; sync
+ $UB/tpl/u-boot-tpl -d $UB/u-boot.dtb.out \
+ -L6 -c "host bind 0 $CROS/src/build/images/cheza/latest/chromiumos_image.bin; vboot go auto" \
+ -l -w -s state.dtb -r
+To run on other boards:
+ Install image.bin in the SPI flash of your device
+ Boot your system
-6. Start it up
-Reboot the device in dev mode. Make sure that you have USB booting enabled. To
-do this, login as root (via Ctrl-Alt-forward_arrow) and type
-'enable_dev_usb_boot'. You only need to do this once.
+Sandbox
+-------
-Reboot the device with the SD card inserted. Press Clrl-U at the developer
-mode screen. It should show something like the following on the display:
+Most Chromium OS development with U-Boot is undertaken using sandbox. There is
+a sandbox target available (chromeos_sandbox) which allows running U-Boot on
+a Linux machine completion with emulations of the display, TPM, disk, etc.
- U-Boot 2017.07-00637-g242eb42-dirty (May 22 2017 - 06:14:21 -0600)
+Running sandbox starts TPL, which contains the first phase of vboot, providing
+a device tree and binding a Chromium OS disk image for use to find kernels
+(any Chromium OS image will do). It also saves driver state between U-Boot
+phases into state.dtb and will automatically ensure that memory is shared
+between all phases. TPL will jump to SPL and then on to U-Boot proper.
- Model: Acer Chromebook 13 CB5-311
- Board: Google/NVIDIA Nyan-big, ID: 1
+It is possible to run with debugging on, e.g.
- Net: No ethernet found.
- Hit any key to stop autoboot: 0
- Tegra124 (Nyan-big) #
+ gdb --args $UB/tpl/u-boot-tpl -d ....
+Breakpoints can be set in any U-Boot phase. Overall this is a good debugging
+environment for new verified-boot features.
-7. Known problems
-On the serial console the word MMC is chopped at the start of the line:
+Samus
+-----
-C: sdhci@700b0000: 2, sdhci@700b0400: 1, sdhci@700b0600: 0
+Basic support is available for samus, using the chromeos_samus target. If you
+have an em100, use:
-This is likely due to some problem with change-over of the serial driver
-during relocation (or perhaps updating the clock setup in board_init()).
+ sudo em100 -s -c W25Q128FW -d $UB/image.bin -t -r
+to write the image and then boot samus (Power-Refresh).
-9. Notes
-To check that you copied the u-boot.its file correctly, use these commands.
-You should see that the data at 0x100 in u-boot-chromium.fit is the first few
-bytes of U-Boot:
+Boot flow
+---------
- hd u-boot-chromium.fit |head -20
- ...
- 00000100 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................|
+Verified boot starts in TPL, which selects the A or B SPL, which in turn selects
+the A or B U-Boot. Then this jumps to the selected kernel. If anything goes
+wrong, the device reboots and the recovery SPL and U-Boot are used instead.
- hd b/nyan-big/u-boot.bin |head
- 00000000 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................|
+More details are available here:
+ https://www.chromium.org/chromium-os/chromiumos-design-docs/firmware-boot-and-recovery
-The 'data' property of the FIT is set up to start at offset 0x100 bytes into
-the file. The change to CONFIG_SYS_TEXT_BASE is also an offset of 0x100 bytes
-from the load address. If this changes, you either need to modify U-Boot to be
-fully relocatable, or expect it to hang.
+New uclasses
+------------
-chromebook_jerry
-----------------
+Several uclasses are provided in cros/:
-The instruction are similar to those for Nyan with changes as noted below:
+ UCLASS_CROS_AUX_FW Chrome OS auxiliary firmware
+ UCLASS_CROS_FWSTORE Chrome OS firmware storage
+ UCLASS_CROS_NVDATA Chrome OS non-volatile data device
+ UCLASS_CROS_VBOOT_EC Chrome OS vboot EC operations
+ UCLASS_CROS_VBOOT_FLAG Chrome OS verified boot flag
-1. Patch U-Boot
+The existing UCLASS_CROS_EC is also used.
-Open include/configs/rk3288_common.h
-Change:
-
-#define CONFIG_SYS_TEXT_BASE 0x00100000
-
-to:
-
-#define CONFIG_SYS_TEXT_BASE 0x02000100
-
-
-
-2. Build U-Boot
-
- mkdir b
- make -j8 O=b/chromebook_jerry CROSS_COMPILE=arm-linux-gnueabi- \
- chromebook_jerry_defconfig all
-
-
-3. See above
-
-4. Build and sign an image
-
- ./b/chromebook_jerry/tools/mkimage -f doc/chromium/chromebook_jerry.its \
- u-boot-chromium.fit
- echo test >dummy.txt
- vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \
- --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \
- --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
- --bootloader dummy.txt --pack u-boot.kpart
-
-
-5. See above
+Commands
+--------
-6. See above
+A new 'vboot' command is provided to run particular vboot stages. The most
+useful command is 'vboot go auto', which continues where the last stage left
+off.
-7. Start it up
+Note that TPL and SPL do not supports commands as yet, so the vboot code is
+called directly from the SPL boot devices (BOOT_DEVICE_CROS_VBOOT). See
+cros_load_image_tpl() and cros_load_image_spl() which both call
+vboot_run_auto().
-Reboot the device in dev mode. Make sure that you have USB booting enabled. To
-do this, login as root (via Ctrl-Alt-forward_arrow) and type
-'enable_dev_usb_boot'. You only need to do this once.
-Reboot the device with the SD card inserted. Press Clrl-U at the developer
-mode screen. It should show something like the following on the display:
+Config options
+--------------
- U-Boot 2017.05-00649-g72acdbf-dirty (May 29 2017 - 14:57:05 -0600)
+The main option is CONFIG_CHROMEOS, which enables a wide array of other options
+so that the required features are present.
- Model: Google Jerry
- Net: Net Initialization Skipped
- No ethernet found.
- Hit any key to stop autoboot: 0
+Device-tree config
+------------------
-8. Known problems
+Various options are available which control the operation of verified boot.
+See cros/dts/bindings/config.txt for details. Most config is handled at run-
+time, although build-time config (with Kconfig) could also be added fairly
+easily.
-None as yet.
+Porting to other hardware
+-------------------------
-9. Notes
+A basic port to samus (Chromebook Pixel 2015) is in a basic working state,
+using the chromeos_samus target. Patches will likely be forthcoming in early
+2019. Ports to an ARM board and coreboot (for x86 Chromebooks) are in the
+dreaming state.
-None as yet.
+Tests
+-----
-Other notes
-===========
+Chromium OS firmware has a very limited set of tests. The tests that originally
+existed in U-Boot were not brought over to coreboot or depthcharge.
-flashrom
---------
+The U-Boot tests ('make check') do operate, but at present there are no
+Chromium OS tests available. These will hopefully come together over time. Of
+course the above sandbox feature provides a sort of functional test and can
+detecte problems that affect the flow or particular vboot features.
- Used to make a backup of your firmware, or to replace it.
- See: https://www.chromium.org/chromium-os/packages/cros-flashrom
+TO DO
+-----
+- Support for booting from coreboot (patches expected March 2019)
+- Support for booting from an ARM board, e.g. bob
-coreboot
---------
-Coreboot itself is not designed to actually boot an OS. Instead, a program
-called Depthcharge is used. This originally came out of U-Boot and was then
-heavily hacked and modified such that is is almost unrecognisable. It does
-include a very small part of the U-Boot command-line interface but is not
-usable as a general-purpose boot loader.
-
-In addition, it has a very unusual design in that it does not do device init
-itself, but instead relies on coreboot. This is similar to (in U-Boot) having
-a SPI driver with an empty probe() method, relying on whatever was set up
-beforehand. It can be quite hard to figure out between these two code bases
-what settings are actually used. When chain-loading into U-Boot we must be
-careful to reinit anything that U-Boot expects. If not, some peripherals (or
-the whole machine) may not work. This makes the process of chainloading more
-complicated than it could be on some platforms.
-
-Finally, it supports only a subset of the U-Boot's FIT format. In particular
-it uses a fixed address to load the FIT and does not support load/exec
-addresses. This means that U-Boot must be able to boot from whatever
-address Depthcharge happens to use (it is the CONFIG_KERNEL_START setting
-in Depthcharge). In practice this means that the data in the kernel@1 FIT node
-(see above) must start at the same address as U-Boot's CONFIG_SYS_TEXT_BASE.
+Simon Glass
+sjg@chromium.org
+7 October 2018
diff --git a/doc/README.chromium-chainload b/doc/README.chromium-chainload
new file mode 100644
index 00000000000..45eaeced2da
--- /dev/null
+++ b/doc/README.chromium-chainload
@@ -0,0 +1,239 @@
+Running U-Boot from coreboot on Chromebooks
+===========================================
+
+U-Boot can be used as a secondary boot loader in a few situations such as from
+UEFI and coreboot (see README.x86). Recent Chromebooks use coreboot even on
+ARM platforms to start up the machine.
+
+This document aims to provide a guide to booting U-Boot on a Chromebook. It
+is only a starting point, and there are many guides on the interwebs. But
+placing this information in the U-Boot tree should make it easier to find for
+those who use U-Boot habitually.
+
+Most of these platforms are supported by U-Boot natively, but it is risky to
+replace the ROM unless you have a servo board and cable to restore it with.
+
+
+For all of these the standard U-Boot build instructions apply. For example on
+ARM:
+
+ sudo apt install gcc-arm-linux-gnueabi
+ mkdir b
+ make O=b/nyan_big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all
+
+You can obtain the vbutil_kernel utility here:
+
+ https://drive.google.com/open?id=0B7WYZbZ9zd-3dHlVVXo4VXE2T0U
+
+
+Snow (Samsung ARM Chromebook)
+-----------------------------
+
+See here:
+
+https://www.chromium.org/chromium-os/firmware-porting-guide/using-nv-u-boot-on-the-samsung-arm-chromebook
+
+
+Nyan-big
+--------
+
+Compiled based on information here:
+https://lists.denx.de/pipermail/u-boot/2015-March/209530.html
+https://git.collabora.com/cgit/user/tomeu/u-boot.git/commit/?h=nyan-big
+https://lists.denx.de/pipermail/u-boot/2017-May/289491.html
+https://github.com/chromeos-nvidia-androidtv/gnu-linux-on-acer-chromebook-13#copy-data-to-the-sd-card
+
+1. Build U-Boot
+
+ mkdir b
+ make -j8 O=b/nyan-big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all
+
+
+2. Select a .its file
+
+Select something from doc/chromium which matches your board, or create your
+own.
+
+Note that the device tree node is required, even though it is not actually
+used by U-Boot. This is because the Chromebook expects to pass it to the
+kernel, and crashes if it is not present.
+
+
+3. Build and sign an image
+
+ ./b/nyan-big/tools/mkimage -f doc/chromium/nyan-big.its u-boot-chromium.fit
+ echo test >dummy.txt
+ vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \
+ --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \
+ --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
+ --bootloader dummy.txt --pack u-boot.kpart
+
+
+4. Prepare an SD card
+
+ DISK=/dev/sdc # Replace with your actual SD card device
+ sudo cgpt create $DISK
+ sudo cgpt add -b 34 -s 32768 -P 1 -S 1 -t kernel $DISK
+ sudo cgpt add -b 32802 -s 2000000 -t rootfs $DISK
+ sudo gdisk $DISK # Enter command 'w' to write a protective MBR to the disk
+
+
+5. Write U-Boot to the SD card
+
+ sudo dd if=u-boot.kpart of=/dev/sdc1; sync
+
+
+6. Start it up
+
+Reboot the device in dev mode. Make sure that you have USB booting enabled. To
+do this, login as root (via Ctrl-Alt-forward_arrow) and type
+'enable_dev_usb_boot'. You only need to do this once.
+
+Reboot the device with the SD card inserted. Press Clrl-U at the developer
+mode screen. It should show something like the following on the display:
+
+ U-Boot 2017.07-00637-g242eb42-dirty (May 22 2017 - 06:14:21 -0600)
+
+ Model: Acer Chromebook 13 CB5-311
+ Board: Google/NVIDIA Nyan-big, ID: 1
+
+ Net: No ethernet found.
+ Hit any key to stop autoboot: 0
+ Tegra124 (Nyan-big) #
+
+
+7. Known problems
+
+On the serial console the word MMC is chopped at the start of the line:
+
+C: sdhci@700b0000: 2, sdhci@700b0400: 1, sdhci@700b0600: 0
+
+This is likely due to some problem with change-over of the serial driver
+during relocation (or perhaps updating the clock setup in board_init()).
+
+
+9. Notes
+
+To check that you copied the u-boot.its file correctly, use these commands.
+You should see that the data at 0x100 in u-boot-chromium.fit is the first few
+bytes of U-Boot:
+
+ hd u-boot-chromium.fit |head -20
+ ...
+ 00000100 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................|
+
+ hd b/nyan-big/u-boot.bin |head
+ 00000000 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................|
+
+
+The 'data' property of the FIT is set up to start at offset 0x100 bytes into
+the file. The change to CONFIG_SYS_TEXT_BASE is also an offset of 0x100 bytes
+from the load address. If this changes, you either need to modify U-Boot to be
+fully relocatable, or expect it to hang.
+
+
+chromebook_jerry
+----------------
+
+The instruction are similar to those for Nyan with changes as noted below:
+
+1. Patch U-Boot
+
+Open include/configs/rk3288_common.h
+
+Change:
+
+#define CONFIG_SYS_TEXT_BASE 0x00100000
+
+to:
+
+#define CONFIG_SYS_TEXT_BASE 0x02000100
+
+
+
+2. Build U-Boot
+
+ mkdir b
+ make -j8 O=b/chromebook_jerry CROSS_COMPILE=arm-linux-gnueabi- \
+ chromebook_jerry_defconfig all
+
+
+3. See above
+
+4. Build and sign an image
+
+ ./b/chromebook_jerry/tools/mkimage -f doc/chromium/chromebook_jerry.its \
+ u-boot-chromium.fit
+ echo test >dummy.txt
+ vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \
+ --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \
+ --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \
+ --bootloader dummy.txt --pack u-boot.kpart
+
+
+5. See above
+
+6. See above
+
+7. Start it up
+
+Reboot the device in dev mode. Make sure that you have USB booting enabled. To
+do this, login as root (via Ctrl-Alt-forward_arrow) and type
+'enable_dev_usb_boot'. You only need to do this once.
+
+Reboot the device with the SD card inserted. Press Clrl-U at the developer
+mode screen. It should show something like the following on the display:
+
+ U-Boot 2017.05-00649-g72acdbf-dirty (May 29 2017 - 14:57:05 -0600)
+
+ Model: Google Jerry
+ Net: Net Initialization Skipped
+ No ethernet found.
+ Hit any key to stop autoboot: 0
+
+
+8. Known problems
+
+None as yet.
+
+
+9. Notes
+
+None as yet.
+
+
+Other notes
+===========
+
+flashrom
+--------
+
+ Used to make a backup of your firmware, or to replace it.
+
+ See: https://www.chromium.org/chromium-os/packages/cros-flashrom
+
+
+coreboot
+--------
+
+Coreboot itself is not designed to actually boot an OS. Instead, a program
+called Depthcharge is used. This originally came out of U-Boot and was then
+heavily hacked and modified such that is is almost unrecognisable. It does
+include a very small part of the U-Boot command-line interface but is not
+usable as a general-purpose boot loader.
+
+In addition, it has a very unusual design in that it does not do device init
+itself, but instead relies on coreboot. This is similar to (in U-Boot) having
+a SPI driver with an empty probe() method, relying on whatever was set up
+beforehand. It can be quite hard to figure out between these two code bases
+what settings are actually used. When chain-loading into U-Boot we must be
+careful to reinit anything that U-Boot expects. If not, some peripherals (or
+the whole machine) may not work. This makes the process of chainloading more
+complicated than it could be on some platforms.
+
+Finally, it supports only a subset of the U-Boot's FIT format. In particular
+it uses a fixed address to load the FIT and does not support load/exec
+addresses. This means that U-Boot must be able to boot from whatever
+address Depthcharge happens to use (it is the CONFIG_KERNEL_START setting
+in Depthcharge). In practice this means that the data in the kernel@1 FIT node
+(see above) must start at the same address as U-Boot's CONFIG_SYS_TEXT_BASE.
diff --git a/doc/device-tree-bindings/i2c/i2c.txt b/doc/device-tree-bindings/i2c/i2c.txt
index de818d4713f..9698e4899b5 100644
--- a/doc/device-tree-bindings/i2c/i2c.txt
+++ b/doc/device-tree-bindings/i2c/i2c.txt
@@ -12,6 +12,10 @@ property which allows the chip offset length to be selected.
Optional properties:
- u-boot,i2c-offset-len - length of chip offset in bytes. If omitted the
default value of 1 is used.
+- u-boot,i2c-transaction-bytes - the length of single I2C transaction on
+ the bus. Some devices require more than single byte transmission
+ (e.g. mc34708 mfd). This information is necessary to correctly
+ initialize (put into idle state) I2C bus after soft reset.
- gpios = <sda ...>, <scl ...>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&i2c_xfer>;
@@ -28,6 +32,7 @@ i2c4: i2c@12ca0000 {
compatible = "google,cros-ec";
i2c-max-frequency = <100000>;
u-boot,i2c-offset-len = <0>;
+ u-boot,i2c-transaction-bytes = <3>;
ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>;
};
};
diff --git a/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt
new file mode 100644
index 00000000000..70e76be2a3f
--- /dev/null
+++ b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt
@@ -0,0 +1,59 @@
+STMicroelectronics Flexible Memory Controller 2 (FMC2)
+NAND Interface
+
+Required properties:
+- compatible: Should be one of:
+ * st,stm32mp15-fmc2
+- reg: NAND flash controller memory areas.
+ First region contains the register location.
+ Regions 2 to 4 respectively contain the data, command,
+ and address space for CS0.
+ Regions 5 to 7 contain the same areas for CS1.
+- interrupts: The interrupt number
+- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
+- clocks: The clock needed by the NAND flash controller
+
+Optional properties:
+- resets: Reference to a reset controller asserting the FMC controller
+- dmas: DMA specifiers (see: dma/stm32-mdma.txt)
+- dma-names: Must be "tx", "rx" and "ecc"
+
+Optional children nodes:
+Children nodes represent the available NAND chips.
+
+Optional properties:
+- nand-on-flash-bbt: see nand.txt
+- nand-ecc-strength: see nand.txt
+- nand-ecc-step-size: see nand.txt
+
+The following ECC strength and step size are currently supported:
+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming)
+ - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
+ - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default)
+
+Example:
+
+ fmc: nand-controller@58002000 {
+ compatible = "st,stm32mp15-fmc2";
+ reg = <0x58002000 0x1000>,
+ <0x80000000 0x1000>,
+ <0x88010000 0x1000>,
+ <0x88020000 0x1000>,
+ <0x81000000 0x1000>,
+ <0x89010000 0x1000>,
+ <0x89020000 0x1000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc FMC_K>;
+ resets = <&rcc FMC_R>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&fmc_pins_a>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ nand@0 {
+ reg = <0>;
+ nand-on-flash-bbt;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
diff --git a/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt b/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
index a1b559668ff..a376c6fba5d 100644
--- a/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
+++ b/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
@@ -42,7 +42,7 @@ Example:
status = "okay";
spi_flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
};
diff --git a/doc/device-tree-bindings/spi/spi-atcspi200.txt b/doc/device-tree-bindings/spi/spi-atcspi200.txt
index 9c0630b5003..e67b3425f0d 100644
--- a/doc/device-tree-bindings/spi/spi-atcspi200.txt
+++ b/doc/device-tree-bindings/spi/spi-atcspi200.txt
@@ -28,7 +28,7 @@ Example:
clocks = <&spiclk>;
interrupts = <3 4>;
flash@0 {
- compatible = "spi-flash";
+ compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0>;
spi-cpol;
diff --git a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt b/doc/device-tree-bindings/spi/spi-stm32-qspi.txt
index 6c7da1d76c1..cec3e1250ce 100644
--- a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt
+++ b/doc/device-tree-bindings/spi/spi-stm32-qspi.txt
@@ -29,7 +29,7 @@ Example:
qflash0: n25q128a {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "micron,n25q128a13", "spi-flash";
+ compatible = "micron,n25q128a13", "jedec,spi-nor";
spi-max-frequency = <108000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
diff --git a/doc/git-mailrc b/doc/git-mailrc
index b75ebab02ba..f989792e8d3 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -24,9 +24,8 @@ alias dinh Dinh Nguyen <dinguyen@kernel.org>
alias hs Heiko Schocher <hs@denx.de>
alias iwamatsu Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
alias jaehoon Jaehoon Chung <jh80.chung@samsung.com>
-alias jagan Jagan Teki <jagan@openedev.com>
+alias jagan Jagan Teki <jagan@amarulasolutions.com>
alias jhersh Joe Hershberger <joe.hershberger@ni.com>
-alias luka Luka Perkov <luka.perkov@sartura.hr>
alias lukma Lukasz Majewski <lukma@denx.de>
alias macpaul Macpaul Lin <macpaul@andestech.com>
alias marex Marek Vasut <marex@denx.de>
@@ -35,7 +34,6 @@ alias masahiro Masahiro Yamada <yamada.masahiro@socionext.com>
alias mateusz Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
alias maxime Maxime Ripard <maxime.ripard@free-electrons.com>
alias monstr Michal Simek <monstr@monstr.eu>
-alias prafulla Prafulla Wadaskar <prafulla@marvell.com>
alias prom Minkyu Kang <mk7.kang@samsung.com>
alias ptomsich Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
alias sbabic Stefano Babic <sbabic@denx.de>
@@ -56,7 +54,7 @@ alias arm uboot, aaribaud, trini
alias at91 uboot, abiessmann
alias davinci ti
alias imx uboot, sbabic
-alias kirkwood uboot, prafulla, luka, stroese
+alias kirkwood uboot, stroese
alias omap ti
alias pxa uboot, marex
alias rmobile uboot, iwamatsu
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 49a056e9416..7ebee75c0a5 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -81,7 +81,9 @@ config MVSATA_IDE
config SATA_MV
bool "Enable Marvell SATA controller driver support"
+ select AHCI
select LIBATA
+ depends on BLK
help
Enable this driver to support the SATA controller found in
some Marvell SoCs.
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c
index 6e3f17ee276..48a9d00d147 100644
--- a/drivers/ata/ahci_mvebu.c
+++ b/drivers/ata/ahci_mvebu.c
@@ -44,6 +44,7 @@ static int mvebu_ahci_probe(struct udevice *dev)
}
static const struct udevice_id mvebu_ahci_ids[] = {
+ { .compatible = "marvell,armada-380-ahci" },
{ .compatible = "marvell,armada-3700-ahci" },
{ .compatible = "marvell,armada-8k-ahci" },
{ }
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index a168196fd4d..2a630d46c14 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -3,7 +3,7 @@
* Copyright (C) Excito Elektronik i Skåne AB, 2010.
* Author: Tor Krill <tor@excito.com>
*
- * Copyright (C) 2015 Stefan Roese <sr@denx.de>
+ * Copyright (C) 2015, 2019 Stefan Roese <sr@denx.de>
*/
/*
@@ -32,6 +32,10 @@
*/
#include <common.h>
+#include <ahci.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
#include <fis.h>
#include <libata.h>
#include <malloc.h>
@@ -40,11 +44,10 @@
#include <asm/io.h>
#include <linux/mbus.h>
+#include <asm/arch/soc.h>
#if defined(CONFIG_KIRKWOOD)
-#include <asm/arch/kirkwood.h>
#define SATAHC_BASE KW_SATA_BASE
#else
-#include <asm/arch/soc.h>
#define SATAHC_BASE MVEBU_AXP_SATA_BASE
#endif
@@ -214,8 +217,8 @@ struct crqb {
#define CRQB_SECTCOUNT_COUNT_EXP_MASK (0xff << 8)
#define CRQB_SECTCOUNT_COUNT_EXP_SHIFT 8
-#define MVSATA_WIN_CONTROL(w) (MVEBU_AXP_SATA_BASE + 0x30 + ((w) << 4))
-#define MVSATA_WIN_BASE(w) (MVEBU_AXP_SATA_BASE + 0x34 + ((w) << 4))
+#define MVSATA_WIN_CONTROL(w) (SATAHC_BASE + 0x30 + ((w) << 4))
+#define MVSATA_WIN_BASE(w) (SATAHC_BASE + 0x34 + ((w) << 4))
struct eprd {
u32 phyaddr_low;
@@ -256,6 +259,7 @@ struct mv_priv {
u16 pio;
u16 mwdma;
u16 udma;
+ int dev_nr;
void *crqb_alloc;
struct crqb *request;
@@ -278,9 +282,9 @@ static int ata_wait_register(u32 *addr, u32 mask, u32 val, u32 timeout_msec)
}
/* Cut from sata_mv in linux kernel */
-static int mv_stop_edma_engine(int port)
+static int mv_stop_edma_engine(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
int i;
/* Disable eDMA. The disable bit auto clears. */
@@ -299,9 +303,9 @@ static int mv_stop_edma_engine(int port)
return -1;
}
-static int mv_start_edma_engine(int port)
+static int mv_start_edma_engine(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
u32 tmp;
/* Check preconditions */
@@ -351,12 +355,12 @@ static int mv_start_edma_engine(int port)
return 0;
}
-static int mv_reset_channel(int port)
+static int mv_reset_channel(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
/* Make sure edma is stopped */
- mv_stop_edma_engine(port);
+ mv_stop_edma_engine(dev, port);
out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ATARST);
udelay(25); /* allow reset propagation */
@@ -366,11 +370,11 @@ static int mv_reset_channel(int port)
return 0;
}
-static void mv_reset_port(int port)
+static void mv_reset_port(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
- mv_reset_channel(port);
+ mv_reset_channel(dev, port);
out_le32(priv->regbase + EDMA_CMD, 0x0);
out_le32(priv->regbase + EDMA_CFG, 0x101f);
@@ -392,9 +396,9 @@ static void mv_reset_one_hc(void)
out_le32(SATAHC_BASE + SATAHC_ICR, 0x00);
}
-static int probe_port(int port)
+static int probe_port(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
int tries, tries2, set15 = 0;
u32 tmp;
@@ -446,7 +450,7 @@ static int probe_port(int port)
tmp &= ~SIR_CFG_GEN2EN;
out_le32(priv->regbase + SIR_ICFG, tmp);
- mv_reset_channel(port);
+ mv_reset_channel(dev, port);
}
}
@@ -455,9 +459,9 @@ static int probe_port(int port)
}
/* Get request queue in pointer */
-static int get_reqip(int port)
+static int get_reqip(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
u32 tmp;
tmp = in_le32(priv->regbase + EDMA_RQIPR) & EDMA_RQIPR_IPMASK;
@@ -466,9 +470,9 @@ static int get_reqip(int port)
return tmp;
}
-static void set_reqip(int port, int reqin)
+static void set_reqip(struct udevice *dev, int port, int reqin)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
u32 tmp;
tmp = in_le32(priv->regbase + EDMA_RQIPR) & ~EDMA_RQIPR_IPMASK;
@@ -477,17 +481,17 @@ static void set_reqip(int port, int reqin)
}
/* Get next available slot, ignoring possible overwrite */
-static int get_next_reqip(int port)
+static int get_next_reqip(struct udevice *dev, int port)
{
- int slot = get_reqip(port);
+ int slot = get_reqip(dev, port);
slot = (slot + 1) % REQUEST_QUEUE_SIZE;
return slot;
}
/* Get response queue in pointer */
-static int get_rspip(int port)
+static int get_rspip(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
u32 tmp;
tmp = in_le32(priv->regbase + EDMA_RSIPR) & EDMA_RSIPR_IPMASK;
@@ -497,9 +501,9 @@ static int get_rspip(int port)
}
/* Get response queue out pointer */
-static int get_rspop(int port)
+static int get_rspop(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
u32 tmp;
tmp = in_le32(priv->regbase + EDMA_RSOPR) & EDMA_RSOPR_OPMASK;
@@ -508,15 +512,15 @@ static int get_rspop(int port)
}
/* Get next response queue pointer */
-static int get_next_rspop(int port)
+static int get_next_rspop(struct udevice *dev, int port)
{
- return (get_rspop(port) + 1) % RESPONSE_QUEUE_SIZE;
+ return (get_rspop(dev, port) + 1) % RESPONSE_QUEUE_SIZE;
}
/* Set response queue pointer */
-static void set_rspop(int port, int reqin)
+static void set_rspop(struct udevice *dev, int port, int reqin)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
u32 tmp;
tmp = in_le32(priv->regbase + EDMA_RSOPR) & ~EDMA_RSOPR_OPMASK;
@@ -525,7 +529,8 @@ static void set_rspop(int port, int reqin)
out_le32(priv->regbase + EDMA_RSOPR, tmp);
}
-static int wait_dma_completion(int port, int index, u32 timeout_msec)
+static int wait_dma_completion(struct udevice *dev, int port, int index,
+ u32 timeout_msec)
{
u32 tmp, res;
@@ -538,13 +543,13 @@ static int wait_dma_completion(int port, int index, u32 timeout_msec)
return res;
}
-static void process_responses(int port)
+static void process_responses(struct udevice *dev, int port)
{
#ifdef DEBUG
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
#endif
u32 tmp;
- u32 outind = get_rspop(port);
+ u32 outind = get_rspop(dev, port);
/* Ack interrupts */
tmp = in_le32(SATAHC_BASE + SATAHC_ICR);
@@ -555,20 +560,21 @@ static void process_responses(int port)
tmp &= ~(BIT(4));
out_le32(SATAHC_BASE + SATAHC_ICR, tmp);
- while (get_rspip(port) != outind) {
+ while (get_rspip(dev, port) != outind) {
#ifdef DEBUG
debug("Response index %d flags %08x on port %d\n", outind,
priv->response[outind].flags, port);
#endif
- outind = get_next_rspop(port);
- set_rspop(port, outind);
+ outind = get_next_rspop(dev, port);
+ set_rspop(dev, port, outind);
}
}
-static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis,
+static int mv_ata_exec_ata_cmd(struct udevice *dev, int port,
+ struct sata_fis_h2d *cfis,
u8 *buffer, u32 len, u32 iswrite)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
struct crqb *req;
int slot;
u32 start;
@@ -579,7 +585,7 @@ static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis,
}
/* Initialize request */
- slot = get_reqip(port);
+ slot = get_reqip(dev, port);
memset(&priv->request[slot], 0, sizeof(struct crqb));
req = &priv->request[slot];
@@ -633,16 +639,16 @@ static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis,
start + ALIGN(sizeof(*req), ARCH_DMA_MINALIGN));
/* Trigger operation */
- slot = get_next_reqip(port);
- set_reqip(port, slot);
+ slot = get_next_reqip(dev, port);
+ set_reqip(dev, port, slot);
/* Wait for completion */
- if (wait_dma_completion(port, slot, 10000)) {
+ if (wait_dma_completion(dev, port, slot, 10000)) {
printf("ATA operation timed out\n");
return -1;
}
- process_responses(port);
+ process_responses(dev, port);
/* Invalidate data on read */
if (buffer && len) {
@@ -654,7 +660,8 @@ static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis,
return len;
}
-static u32 mv_sata_rw_cmd_ext(int port, lbaint_t start, u32 blkcnt,
+static u32 mv_sata_rw_cmd_ext(struct udevice *dev, int port, lbaint_t start,
+ u32 blkcnt,
u8 *buffer, int is_write)
{
struct sata_fis_h2d cfis;
@@ -678,14 +685,14 @@ static u32 mv_sata_rw_cmd_ext(int port, lbaint_t start, u32 blkcnt,
cfis.sector_count_exp = (blkcnt >> 8) & 0xff;
cfis.sector_count = blkcnt & 0xff;
- res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt,
- is_write);
+ res = mv_ata_exec_ata_cmd(dev, port, &cfis, buffer,
+ ATA_SECT_SIZE * blkcnt, is_write);
return res >= 0 ? blkcnt : res;
}
-static u32 mv_sata_rw_cmd(int port, lbaint_t start, u32 blkcnt, u8 *buffer,
- int is_write)
+static u32 mv_sata_rw_cmd(struct udevice *dev, int port, lbaint_t start,
+ u32 blkcnt, u8 *buffer, int is_write)
{
struct sata_fis_h2d cfis;
lbaint_t block;
@@ -705,20 +712,21 @@ static u32 mv_sata_rw_cmd(int port, lbaint_t start, u32 blkcnt, u8 *buffer,
cfis.lba_low = block & 0xff;
cfis.sector_count = (u8)(blkcnt & 0xff);
- res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt,
- is_write);
+ res = mv_ata_exec_ata_cmd(dev, port, &cfis, buffer,
+ ATA_SECT_SIZE * blkcnt, is_write);
return res >= 0 ? blkcnt : res;
}
-static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt,
- void *buffer, int is_write)
+static u32 ata_low_level_rw(struct udevice *dev, int port, lbaint_t blknr,
+ lbaint_t blkcnt, void *buffer, int is_write)
{
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
lbaint_t start, blks;
u8 *addr;
int max_blks;
- debug("%s: %ld %ld\n", __func__, blknr, blkcnt);
+ debug("%s: " LBAFU " " LBAFU "\n", __func__, blknr, blkcnt);
start = blknr;
blks = blkcnt;
@@ -727,22 +735,22 @@ static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt,
max_blks = MV_ATA_MAX_SECTORS;
do {
if (blks > max_blks) {
- if (sata_dev_desc[dev].lba48) {
- mv_sata_rw_cmd_ext(dev, start, max_blks, addr,
- is_write);
+ if (desc->lba48) {
+ mv_sata_rw_cmd_ext(dev, port, start, max_blks,
+ addr, is_write);
} else {
- mv_sata_rw_cmd(dev, start, max_blks, addr,
- is_write);
+ mv_sata_rw_cmd(dev, port, start, max_blks,
+ addr, is_write);
}
start += max_blks;
blks -= max_blks;
addr += ATA_SECT_SIZE * max_blks;
} else {
- if (sata_dev_desc[dev].lba48) {
- mv_sata_rw_cmd_ext(dev, start, blks, addr,
+ if (desc->lba48) {
+ mv_sata_rw_cmd_ext(dev, port, start, blks, addr,
is_write);
} else {
- mv_sata_rw_cmd(dev, start, blks, addr,
+ mv_sata_rw_cmd(dev, port, start, blks, addr,
is_write);
}
start += blks;
@@ -754,11 +762,11 @@ static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt,
return blkcnt;
}
-static int mv_ata_exec_ata_cmd_nondma(int port,
+static int mv_ata_exec_ata_cmd_nondma(struct udevice *dev, int port,
struct sata_fis_h2d *cfis, u8 *buffer,
u32 len, u32 iswrite)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
int i;
u16 *tp;
@@ -791,7 +799,7 @@ static int mv_ata_exec_ata_cmd_nondma(int port,
return len;
}
-static int mv_sata_identify(int port, u16 *id)
+static int mv_sata_identify(struct udevice *dev, int port, u16 *id)
{
struct sata_fis_h2d h2d;
@@ -803,13 +811,13 @@ static int mv_sata_identify(int port, u16 *id)
/* Give device time to get operational */
mdelay(10);
- return mv_ata_exec_ata_cmd_nondma(port, &h2d, (u8 *)id,
+ return mv_ata_exec_ata_cmd_nondma(dev, port, &h2d, (u8 *)id,
ATA_ID_WORDS * 2, READ_CMD);
}
-static void mv_sata_xfer_mode(int port, u16 *id)
+static void mv_sata_xfer_mode(struct udevice *dev, int port, u16 *id)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
priv->pio = id[ATA_ID_PIO_MODES];
priv->mwdma = id[ATA_ID_MWDMA_MODES];
@@ -818,9 +826,9 @@ static void mv_sata_xfer_mode(int port, u16 *id)
priv->udma);
}
-static void mv_sata_set_features(int port)
+static void mv_sata_set_features(struct udevice *dev, int port)
{
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
struct sata_fis_h2d cfis;
u8 udma_cap;
@@ -842,53 +850,7 @@ static void mv_sata_set_features(int port)
if (udma_cap == ATA_UDMA3)
cfis.sector_count = XFER_UDMA_3;
- mv_ata_exec_ata_cmd_nondma(port, &cfis, NULL, 0, READ_CMD);
-}
-
-int mv_sata_spin_down(int dev)
-{
- struct sata_fis_h2d cfis;
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv;
-
- if (priv->link == 0) {
- debug("No device on port: %d\n", dev);
- return 1;
- }
-
- memset(&cfis, 0, sizeof(struct sata_fis_h2d));
-
- cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
- cfis.command = ATA_CMD_STANDBY;
-
- return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD);
-}
-
-int mv_sata_spin_up(int dev)
-{
- struct sata_fis_h2d cfis;
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv;
-
- if (priv->link == 0) {
- debug("No device on port: %d\n", dev);
- return 1;
- }
-
- memset(&cfis, 0, sizeof(struct sata_fis_h2d));
-
- cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D;
- cfis.command = ATA_CMD_IDLE;
-
- return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD);
-}
-
-ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer)
-{
- return ata_low_level_rw(dev, blknr, blkcnt, buffer, READ_CMD);
-}
-
-ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer)
-{
- return ata_low_level_rw(dev, blknr, blkcnt, (void *)buffer, WRITE_CMD);
+ mv_ata_exec_ata_cmd_nondma(dev, port, &cfis, NULL, 0, READ_CMD);
}
/*
@@ -916,25 +878,17 @@ static void mvsata_ide_conf_mbus_windows(void)
}
}
-int init_sata(int dev)
+static int sata_mv_init_sata(struct udevice *dev, int port)
{
- struct mv_priv *priv;
+ struct mv_priv *priv = dev_get_platdata(dev);
- debug("Initialize sata dev: %d\n", dev);
+ debug("Initialize sata dev: %d\n", port);
- if (dev < 0 || dev >= CONFIG_SYS_SATA_MAX_DEVICE) {
- printf("Invalid sata device %d\n", dev);
+ if (port < 0 || port >= CONFIG_SYS_SATA_MAX_DEVICE) {
+ printf("Invalid sata device %d\n", port);
return -1;
}
- priv = (struct mv_priv *)malloc(sizeof(struct mv_priv));
- if (!priv) {
- printf("Failed to allocate memory for private sata data\n");
- return -ENOMEM;
- }
-
- memset((void *)priv, 0, sizeof(struct mv_priv));
-
/* Allocate and align request buffer */
priv->crqb_alloc = malloc(sizeof(struct crqb) * REQUEST_QUEUE_SIZE +
CRQB_ALIGN);
@@ -959,11 +913,9 @@ int init_sata(int dev)
priv->response = (struct crpb *)(((u32) priv->crpb_alloc + CRPB_ALIGN) &
~(CRPB_ALIGN - 1));
- sata_dev_desc[dev].priv = (void *)priv;
-
- sprintf(priv->name, "SATA%d", dev);
+ sprintf(priv->name, "SATA%d", port);
- priv->regbase = dev == 0 ? SATA0_BASE : SATA1_BASE;
+ priv->regbase = port == 0 ? SATA0_BASE : SATA1_BASE;
if (!hw_init) {
debug("Initialize sata hw\n");
@@ -972,9 +924,9 @@ int init_sata(int dev)
mvsata_ide_conf_mbus_windows();
}
- mv_reset_port(dev);
+ mv_reset_port(dev, port);
- if (probe_port(dev)) {
+ if (probe_port(dev, port)) {
priv->link = 0;
return -ENODEV;
}
@@ -983,19 +935,15 @@ int init_sata(int dev)
return 0;
}
-int reset_sata(int dev)
-{
- return 0;
-}
-
-int scan_sata(int port)
+static int sata_mv_scan_sata(struct udevice *dev, int port)
{
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+ struct mv_priv *priv = dev_get_platdata(dev);
unsigned char serial[ATA_ID_SERNO_LEN + 1];
unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
unsigned char product[ATA_ID_PROD_LEN + 1];
u64 n_sectors;
u16 *id;
- struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv;
if (!priv->link)
return -ENODEV;
@@ -1006,7 +954,7 @@ int scan_sata(int port)
return -ENOMEM;
}
- mv_sata_identify(port, id);
+ mv_sata_identify(dev, port, id);
ata_swap_buf_le16(id, ATA_ID_WORDS);
#ifdef DEBUG
ata_dump_id(id);
@@ -1014,23 +962,23 @@ int scan_sata(int port)
/* Serial number */
ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
- memcpy(sata_dev_desc[port].product, serial, sizeof(serial));
+ memcpy(desc->product, serial, sizeof(serial));
/* Firmware version */
ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
- memcpy(sata_dev_desc[port].revision, firmware, sizeof(firmware));
+ memcpy(desc->revision, firmware, sizeof(firmware));
/* Product model */
ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
- memcpy(sata_dev_desc[port].vendor, product, sizeof(product));
+ memcpy(desc->vendor, product, sizeof(product));
/* Total sectors */
n_sectors = ata_id_n_sectors(id);
- sata_dev_desc[port].lba = n_sectors;
+ desc->lba = n_sectors;
/* Check if support LBA48 */
if (ata_id_has_lba48(id)) {
- sata_dev_desc[port].lba48 = 1;
+ desc->lba48 = 1;
debug("Device support LBA48\n");
}
@@ -1038,13 +986,111 @@ int scan_sata(int port)
priv->queue_depth = ata_id_queue_depth(id);
/* Get the xfer mode from device */
- mv_sata_xfer_mode(port, id);
+ mv_sata_xfer_mode(dev, port, id);
/* Set the xfer mode to highest speed */
- mv_sata_set_features(port);
+ mv_sata_set_features(dev, port);
/* Start up */
- mv_start_edma_engine(port);
+ mv_start_edma_engine(dev, port);
+
+ return 0;
+}
+
+static ulong sata_mv_read(struct udevice *blk, lbaint_t blknr,
+ lbaint_t blkcnt, void *buffer)
+{
+ struct mv_priv *priv = dev_get_platdata(blk);
+
+ return ata_low_level_rw(blk, priv->dev_nr, blknr, blkcnt,
+ buffer, READ_CMD);
+}
+
+static ulong sata_mv_write(struct udevice *blk, lbaint_t blknr,
+ lbaint_t blkcnt, const void *buffer)
+{
+ struct mv_priv *priv = dev_get_platdata(blk);
+
+ return ata_low_level_rw(blk, priv->dev_nr, blknr, blkcnt,
+ (void *)buffer, WRITE_CMD);
+}
+
+static const struct blk_ops sata_mv_blk_ops = {
+ .read = sata_mv_read,
+ .write = sata_mv_write,
+};
+
+U_BOOT_DRIVER(sata_mv_driver) = {
+ .name = "sata_mv_blk",
+ .id = UCLASS_BLK,
+ .ops = &sata_mv_blk_ops,
+ .platdata_auto_alloc_size = sizeof(struct mv_priv),
+};
+
+static int sata_mv_probe(struct udevice *dev)
+{
+ const void *blob = gd->fdt_blob;
+ int node = dev_of_offset(dev);
+ struct mv_priv *priv;
+ struct udevice *blk;
+ int nr_ports;
+ int ret;
+ int i;
+
+ /* Get number of ports of this SATA controller */
+ nr_ports = min(fdtdec_get_int(blob, node, "nr-ports", -1),
+ CONFIG_SYS_SATA_MAX_DEVICE);
+
+ for (i = 0; i < nr_ports; i++) {
+ ret = blk_create_devicef(dev, "sata_mv_blk", "blk",
+ IF_TYPE_SATA, -1, 512, 0, &blk);
+ if (ret) {
+ debug("Can't create device\n");
+ return ret;
+ }
+
+ priv = dev_get_platdata(blk);
+ priv->dev_nr = i;
+
+ /* Init SATA port */
+ ret = sata_mv_init_sata(blk, i);
+ if (ret) {
+ debug("%s: Failed to init bus\n", __func__);
+ return ret;
+ }
+
+ /* Scan SATA port */
+ ret = sata_mv_scan_sata(blk, i);
+ if (ret) {
+ debug("%s: Failed to scan bus\n", __func__);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int sata_mv_scan(struct udevice *dev)
+{
+ /* Nothing to do here */
return 0;
}
+
+static const struct udevice_id sata_mv_ids[] = {
+ { .compatible = "marvell,armada-370-sata" },
+ { .compatible = "marvell,orion-sata" },
+ { }
+};
+
+struct ahci_ops sata_mv_ahci_ops = {
+ .scan = sata_mv_scan,
+};
+
+U_BOOT_DRIVER(sata_mv_ahci) = {
+ .name = "sata_mv_ahci",
+ .id = UCLASS_AHCI,
+ .of_match = sata_mv_ids,
+ .ops = &sata_mv_ahci_ops,
+ .probe = sata_mv_probe,
+};
diff --git a/drivers/clk/altera/clk-arria10.c b/drivers/clk/altera/clk-arria10.c
index 612a1718dcb..179869df45f 100644
--- a/drivers/clk/altera/clk-arria10.c
+++ b/drivers/clk/altera/clk-arria10.c
@@ -254,7 +254,8 @@ static int socfpga_a10_clk_bind(struct udevice *dev)
fdt_node_check_compatible(fdt, offset, "fixed-clock"))
continue;
- if (pre_reloc_only && !dm_fdt_pre_reloc(fdt, offset))
+ if (pre_reloc_only &&
+ !dm_ofnode_pre_reloc(offset_to_ofnode(offset)))
continue;
ret = device_bind_driver_to_node(dev, "clk-a10", name,
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 7cfbabc96d3..6b55ec59d6d 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -61,7 +61,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
offset > 0;
offset = fdt_next_subnode(fdt, offset)) {
if (pre_reloc_only &&
- !dm_fdt_pre_reloc(fdt, offset))
+ !dm_ofnode_pre_reloc(offset_to_ofnode(offset)))
continue;
/*
* If this node has "compatible" property, this is not
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index aebc6f0a34c..24859fd054e 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -15,10 +15,12 @@
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#ifndef CONFIG_STM32MP1_TRUSTED
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
/* activate clock tree initialization in the driver */
#define STM32MP1_CLOCK_TREE_INIT
#endif
+#endif
#define MAX_HSI_HZ 64000000
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 0e584c12dc8..785f5c3acf7 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -254,14 +254,13 @@ int ofnode_read_size(ofnode node, const char *propname)
fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
{
int na, ns;
- fdt_size_t size;
if (ofnode_is_np(node)) {
const __be32 *prop_val;
uint flags;
prop_val = of_get_address(ofnode_to_np(node), index,
- (u64 *)&size, &flags);
+ NULL, &flags);
if (!prop_val)
return FDT_ADDR_T_NONE;
@@ -278,7 +277,7 @@ fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
ns = ofnode_read_simple_size_cells(ofnode_get_parent(node));
return fdtdec_get_addr_size_fixed(gd->fdt_blob,
ofnode_to_offset(node), "reg",
- index, na, ns, &size, true);
+ index, na, ns, NULL, true);
}
return FDT_ADDR_T_NONE;
@@ -700,18 +699,18 @@ int ofnode_read_simple_size_cells(ofnode node)
bool ofnode_pre_reloc(ofnode node)
{
+#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD)
+ /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass
+ * had property dm-pre-reloc or u-boot,dm-spl/tpl.
+ * They are removed in final dtb (fdtgrep 2nd pass)
+ */
+ return true;
+#else
if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
return true;
if (ofnode_read_bool(node, "u-boot,dm-pre-proper"))
return true;
-#ifdef CONFIG_TPL_BUILD
- if (ofnode_read_bool(node, "u-boot,dm-tpl"))
- return true;
-#elif defined(CONFIG_SPL_BUILD)
- if (ofnode_read_bool(node, "u-boot,dm-spl"))
- return true;
-#else
/*
* In regular builds individual spl and tpl handling both
* count as handled pre-relocation for later second init.
@@ -719,9 +718,9 @@ bool ofnode_pre_reloc(ofnode node)
if (ofnode_read_bool(node, "u-boot,dm-spl") ||
ofnode_read_bool(node, "u-boot,dm-tpl"))
return true;
-#endif
return false;
+#endif
}
int ofnode_read_resource(ofnode node, uint index, struct resource *res)
diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c
index afac6d6e37e..5bb38e329cb 100644
--- a/drivers/core/syscon-uclass.c
+++ b/drivers/core/syscon-uclass.c
@@ -57,18 +57,64 @@ static int syscon_pre_probe(struct udevice *dev)
#endif
}
+static int syscon_probe_by_ofnode(ofnode node, struct udevice **devp)
+{
+ struct udevice *dev, *parent;
+ int ret;
+
+ /* found node with "syscon" compatible, not bounded to SYSCON UCLASS */
+ if (!ofnode_device_is_compatible(node, "syscon")) {
+ dev_dbg(dev, "invalid compatible for syscon device\n");
+ return -EINVAL;
+ }
+
+ /* bound to driver with same ofnode or to root if not found */
+ if (device_find_global_by_ofnode(node, &parent))
+ parent = dm_root();
+
+ /* force bound to syscon class */
+ ret = device_bind_driver_to_node(parent, "syscon",
+ ofnode_get_name(node),
+ node, &dev);
+ if (ret) {
+ dev_dbg(dev, "unable to bound syscon device\n");
+ return ret;
+ }
+ ret = device_probe(dev);
+ if (ret) {
+ dev_dbg(dev, "unable to probe syscon device\n");
+ return ret;
+ }
+
+ *devp = dev;
+ return 0;
+}
+
struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev,
const char *name)
{
struct udevice *syscon;
struct regmap *r;
+ u32 phandle;
+ ofnode node;
int err;
err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
name, &syscon);
if (err) {
- dev_dbg(dev, "unable to find syscon device\n");
- return ERR_PTR(err);
+ /* found node with "syscon" compatible, not bounded to SYSCON */
+ err = ofnode_read_u32(dev_ofnode(dev), name, &phandle);
+ if (err)
+ return ERR_PTR(err);
+
+ node = ofnode_get_by_phandle(phandle);
+ if (!ofnode_valid(node)) {
+ dev_dbg(dev, "unable to find syscon device\n");
+ return ERR_PTR(-EINVAL);
+ }
+ err = syscon_probe_by_ofnode(node, &syscon);
+ if (err)
+ return ERR_PTR(-ENODEV);
}
r = syscon_get_regmap(syscon);
@@ -152,29 +198,18 @@ U_BOOT_DRIVER(generic_syscon) = {
*/
struct regmap *syscon_node_to_regmap(ofnode node)
{
- struct udevice *dev, *parent;
- int ret;
-
- if (!uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev))
- return syscon_get_regmap(dev);
-
- if (!ofnode_device_is_compatible(node, "syscon"))
- return ERR_PTR(-EINVAL);
+ struct udevice *dev;
+ struct regmap *r;
- /* bound to driver with same ofnode or to root if not found */
- if (device_find_global_by_ofnode(node, &parent))
- parent = dm_root();
+ if (uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev))
+ if (syscon_probe_by_ofnode(node, &dev))
+ return ERR_PTR(-ENODEV);
- /* force bound to syscon class */
- ret = device_bind_driver_to_node(parent, "syscon",
- ofnode_get_name(node),
- node, &dev);
- if (ret)
- return ERR_PTR(ret);
-
- ret = device_probe(dev);
- if (ret)
- return ERR_PTR(ret);
+ r = syscon_get_regmap(dev);
+ if (!r) {
+ dev_dbg(dev, "unable to find regmap\n");
+ return ERR_PTR(-ENODEV);
+ }
- return syscon_get_regmap(dev);
+ return r;
}
diff --git a/drivers/core/util.c b/drivers/core/util.c
index 27a68487034..96e47dc7070 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -31,42 +31,18 @@ int list_count_items(struct list_head *head)
return count;
}
-bool dm_fdt_pre_reloc(const void *blob, int offset)
-{
- if (fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
- return true;
-
-#ifdef CONFIG_TPL_BUILD
- if (fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL))
- return true;
-#elif defined(CONFIG_SPL_BUILD)
- if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL))
- return true;
-#else
- /*
- * In regular builds individual spl and tpl handling both
- * count as handled pre-relocation for later second init.
- */
- if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL) ||
- fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL))
- return true;
-#endif
-
- return false;
-}
-
bool dm_ofnode_pre_reloc(ofnode node)
{
+#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD)
+ /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass
+ * had property dm-pre-reloc or u-boot,dm-spl/tpl.
+ * They are removed in final dtb (fdtgrep 2nd pass)
+ */
+ return true;
+#else
if (ofnode_read_bool(node, "u-boot,dm-pre-reloc"))
return true;
-#ifdef CONFIG_TPL_BUILD
- if (ofnode_read_bool(node, "u-boot,dm-tpl"))
- return true;
-#elif defined(CONFIG_SPL_BUILD)
- if (ofnode_read_bool(node, "u-boot,dm-spl"))
- return true;
-#else
/*
* In regular builds individual spl and tpl handling both
* count as handled pre-relocation for later second init.
@@ -74,7 +50,7 @@ bool dm_ofnode_pre_reloc(ofnode node)
if (ofnode_read_bool(node, "u-boot,dm-spl") ||
ofnode_read_bool(node, "u-boot,dm-tpl"))
return true;
-#endif
return false;
+#endif
}
diff --git a/drivers/ddr/marvell/axp/xor_regs.h b/drivers/ddr/marvell/axp/xor_regs.h
index db5c4196739..d779e564189 100644
--- a/drivers/ddr/marvell/axp/xor_regs.h
+++ b/drivers/ddr/marvell/axp/xor_regs.h
@@ -13,7 +13,11 @@
#define XOR_UNIT(chan) ((chan) >> 1)
#define XOR_CHAN(chan) ((chan) & 1)
+#ifdef CONFIG_ARMADA_MSYS
+#define MV_XOR_REGS_OFFSET(unit) (0xF0800)
+#else
#define MV_XOR_REGS_OFFSET(unit) (0x60900)
+#endif
#define MV_XOR_REGS_BASE(unit) (MV_XOR_REGS_OFFSET(unit))
/* XOR Engine Control Register Map */
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
index 1d3c192cfe5..e7bd1b2350f 100644
--- a/drivers/dma/bcm6348-iudma.c
+++ b/drivers/dma/bcm6348-iudma.c
@@ -324,6 +324,9 @@ static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata)
struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring;
int ret;
+ if (!ch_priv->running)
+ return -EINVAL;
+
/* get dma ring descriptor address */
dma_desc += ch_priv->desc_id;
@@ -369,6 +372,9 @@ static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len,
struct bcm6348_dma_desc *dma_desc;
uint16_t status;
+ if (!ch_priv->running)
+ return -EINVAL;
+
/* flush cache */
bcm6348_iudma_fdc(src, len);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b103180cf37..b3e4ecc50e1 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -23,7 +23,7 @@ config ALTERA_PIO
config BCM6345_GPIO
bool "BCM6345 GPIO driver"
- depends on DM_GPIO && ARCH_BMIPS
+ depends on DM_GPIO && (ARCH_BMIPS || ARCH_BCM6858 || ARCH_BCM63158)
help
This driver supports the GPIO banks on BCM6345 SoCs.
diff --git a/drivers/gpio/bcm6345_gpio.c b/drivers/gpio/bcm6345_gpio.c
index d1f6cfa8405..71a978cf407 100644
--- a/drivers/gpio/bcm6345_gpio.c
+++ b/drivers/gpio/bcm6345_gpio.c
@@ -22,7 +22,7 @@ static int bcm6345_gpio_get_value(struct udevice *dev, unsigned offset)
{
struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
- return !!(readl_be(priv->reg_data) & BIT(offset));
+ return !!(readl(priv->reg_data) & BIT(offset));
}
static int bcm6345_gpio_set_value(struct udevice *dev, unsigned offset,
@@ -31,9 +31,9 @@ static int bcm6345_gpio_set_value(struct udevice *dev, unsigned offset,
struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
if (value)
- setbits_be32(priv->reg_data, BIT(offset));
+ setbits_32(priv->reg_data, BIT(offset));
else
- clrbits_be32(priv->reg_data, BIT(offset));
+ clrbits_32(priv->reg_data, BIT(offset));
return 0;
}
@@ -42,9 +42,9 @@ static int bcm6345_gpio_set_direction(void __iomem *dirout, unsigned offset,
bool input)
{
if (input)
- clrbits_be32(dirout, BIT(offset));
+ clrbits_32(dirout, BIT(offset));
else
- setbits_be32(dirout, BIT(offset));
+ setbits_32(dirout, BIT(offset));
return 0;
}
@@ -70,7 +70,7 @@ static int bcm6345_gpio_get_function(struct udevice *dev, unsigned offset)
{
struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
- if (readl_be(priv->reg_dirout) & BIT(offset))
+ if (readl(priv->reg_dirout) & BIT(offset))
return GPIOF_OUTPUT;
else
return GPIOF_INPUT;
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 49e23a0a4bf..e47abf18333 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -593,6 +593,29 @@ int i2c_chip_ofdata_to_platdata(struct udevice *dev, struct dm_i2c_chip *chip)
}
#endif
+static int i2c_pre_probe(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
+ unsigned int max = 0;
+ ofnode node;
+ int ret;
+
+ i2c->max_transaction_bytes = 0;
+ dev_for_each_subnode(node, dev) {
+ ret = ofnode_read_u32(node,
+ "u-boot,i2c-transaction-bytes",
+ &max);
+ if (!ret && max > i2c->max_transaction_bytes)
+ i2c->max_transaction_bytes = max;
+ }
+
+ debug("%s: I2C bus: %s max transaction bytes: %d\n", __func__,
+ dev->name, i2c->max_transaction_bytes);
+#endif
+ return 0;
+}
+
static int i2c_post_probe(struct udevice *dev)
{
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
@@ -674,6 +697,7 @@ UCLASS_DRIVER(i2c) = {
.post_bind = i2c_post_bind,
.init = i2c_uclass_init,
.priv_auto_alloc_size = sizeof(struct i2c_priv),
+ .pre_probe = i2c_pre_probe,
.post_probe = i2c_post_probe,
.per_device_auto_alloc_size = sizeof(struct dm_i2c_bus),
.per_child_platdata_auto_alloc_size = sizeof(struct dm_i2c_chip),
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index b0da67ce2c6..68f15261be7 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -29,11 +29,12 @@ config I2C_MUX_PCA954x
tristate "TI PCA954x I2C Mux/switches"
depends on I2C_MUX
help
- If you say yes here you get support for the TI PCA954x
- I2C mux/switch devices. It is x width I2C multiplexer which enables to
- partitioning I2C bus and connect multiple devices with the same address
- to the same I2C controller where driver handles proper routing to
- target i2c device. PCA9544 and PCA9548 are supported.
+ If you say yes here you get support for the TI PCA954x I2C mux/switch
+ devices. It is x width I2C multiplexer which enables to partitioning
+ I2C bus and connect multiple devices with the same address to the same
+ I2C controller where driver handles proper routing to target i2c
+ device. Supported chips are PCA9543, PCA9544, PCA9547, PCA9548 and
+ PCA9646.
config I2C_MUX_GPIO
tristate "GPIO-based I2C multiplexer"
diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c
index bd4e9abe5f3..a630ce991d0 100644
--- a/drivers/i2c/muxes/pca954x.c
+++ b/drivers/i2c/muxes/pca954x.c
@@ -15,6 +15,7 @@
DECLARE_GLOBAL_DATA_PTR;
enum pca_type {
+ PCA9543,
PCA9544,
PCA9547,
PCA9548,
@@ -22,7 +23,7 @@ enum pca_type {
};
struct chip_desc {
- u8 enable;
+ u8 enable; /* Enable mask in ctl register (used for muxes only) */
enum muxtype {
pca954x_ismux = 0,
pca954x_isswi,
@@ -37,6 +38,10 @@ struct pca954x_priv {
};
static const struct chip_desc chips[] = {
+ [PCA9543] = {
+ .muxtype = pca954x_isswi,
+ .width = 2,
+ },
[PCA9544] = {
.enable = 0x4,
.muxtype = pca954x_ismux,
@@ -48,12 +53,10 @@ static const struct chip_desc chips[] = {
.width = 8,
},
[PCA9548] = {
- .enable = 0x8,
.muxtype = pca954x_isswi,
.width = 8,
},
[PCA9646] = {
- .enable = 0x0,
.muxtype = pca954x_isswi,
.width = 4,
},
@@ -89,6 +92,7 @@ static const struct i2c_mux_ops pca954x_ops = {
};
static const struct udevice_id pca954x_ids[] = {
+ { .compatible = "nxp,pca9543", .data = PCA9543 },
{ .compatible = "nxp,pca9544", .data = PCA9544 },
{ .compatible = "nxp,pca9547", .data = PCA9547 },
{ .compatible = "nxp,pca9548", .data = PCA9548 },
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 9999d9fe5e4..5420afbc8e0 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -354,9 +354,10 @@ int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus)
int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus)
{
struct udevice *bus = i2c_bus->bus;
+ struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
struct gpio_desc *scl_gpio = &i2c_bus->scl_gpio;
struct gpio_desc *sda_gpio = &i2c_bus->sda_gpio;
- int sda, scl;
+ int sda, scl, idle_sclks;
int i, ret = 0;
ulong elapsed, start_time;
@@ -380,8 +381,22 @@ int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus)
if ((sda & scl) == 1)
goto exit; /* Bus is idle already */
+ /*
+ * In most cases it is just enough to generate 8 + 1 SCLK
+ * clocks to recover I2C slave device from 'stuck' state
+ * (when for example SW reset was performed, in the middle of
+ * I2C transmission).
+ *
+ * However, there are devices which send data in packets of
+ * N bytes (N > 1). In such case we do need N * 8 + 1 SCLK
+ * clocks.
+ */
+ idle_sclks = 8 + 1;
+
+ if (i2c->max_transaction_bytes > 0)
+ idle_sclks = i2c->max_transaction_bytes * 8 + 1;
/* Send high and low on the SCL line */
- for (i = 0; i < 9; i++) {
+ for (i = 0; i < idle_sclks; i++) {
dm_gpio_set_dir_flags(scl_gpio, GPIOD_IS_OUT);
dm_gpio_set_value(scl_gpio, 0);
udelay(50);
diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c
index 29ad87c1d7b..f25d0540075 100644
--- a/drivers/misc/i2c_eeprom.c
+++ b/drivers/misc/i2c_eeprom.c
@@ -5,6 +5,7 @@
#include <common.h>
#include <linux/err.h>
+#include <linux/kernel.h>
#include <dm.h>
#include <i2c.h>
#include <i2c_eeprom.h>
@@ -38,7 +39,24 @@ static int i2c_eeprom_std_read(struct udevice *dev, int offset, uint8_t *buf,
static int i2c_eeprom_std_write(struct udevice *dev, int offset,
const uint8_t *buf, int size)
{
- return -ENODEV;
+ struct i2c_eeprom *priv = dev_get_priv(dev);
+ int ret;
+
+ while (size > 0) {
+ int write_size = min_t(int, size, priv->pagesize);
+
+ ret = dm_i2c_write(dev, offset, buf, write_size);
+ if (ret)
+ return ret;
+
+ offset += write_size;
+ buf += write_size;
+ size -= write_size;
+
+ udelay(10000);
+ }
+
+ return 0;
}
static const struct i2c_eeprom_ops i2c_eeprom_std_ops = {
@@ -50,6 +68,12 @@ static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev)
{
struct i2c_eeprom *priv = dev_get_priv(dev);
u64 data = dev_get_driver_data(dev);
+ u32 pagesize;
+
+ if (dev_read_u32(dev, "pagesize", &pagesize) == 0) {
+ priv->pagesize = pagesize;
+ return 0;
+ }
/* 6 bit -> page size of up to 2^63 (should be sufficient) */
priv->pagewidth = data & 0x3F;
diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c
index 33943a231b1..8dc246b0dbe 100644
--- a/drivers/misc/stm32mp_fuse.c
+++ b/drivers/misc/stm32mp_fuse.c
@@ -9,8 +9,10 @@
#include <errno.h>
#include <dm/device.h>
#include <dm/uclass.h>
+#include <power/stpmic1.h>
#define STM32MP_OTP_BANK 0
+#define STM32MP_NVM_BANK 1
/*
* The 'fuse' command API
@@ -34,6 +36,13 @@ int fuse_read(u32 bank, u32 word, u32 *val)
ret = 0;
break;
+#ifdef CONFIG_PMIC_STPMIC1
+ case STM32MP_NVM_BANK:
+ *val = 0;
+ ret = stpmic1_shadow_read_byte(word, (u8 *)val);
+ break;
+#endif /* CONFIG_PMIC_STPMIC1 */
+
default:
printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
ret = -EINVAL;
@@ -62,6 +71,12 @@ int fuse_prog(u32 bank, u32 word, u32 val)
ret = 0;
break;
+#ifdef CONFIG_PMIC_STPMIC1
+ case STM32MP_NVM_BANK:
+ ret = stpmic1_nvm_write_byte(word, (u8 *)&val);
+ break;
+#endif /* CONFIG_PMIC_STPMIC1 */
+
default:
printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
ret = -EINVAL;
@@ -89,6 +104,13 @@ int fuse_sense(u32 bank, u32 word, u32 *val)
ret = 0;
break;
+#ifdef CONFIG_PMIC_STPMIC1
+ case STM32MP_NVM_BANK:
+ *val = 0;
+ ret = stpmic1_nvm_read_byte(word, (u8 *)val);
+ break;
+#endif /* CONFIG_PMIC_STPMIC1 */
+
default:
printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
ret = -EINVAL;
@@ -117,6 +139,12 @@ int fuse_override(u32 bank, u32 word, u32 val)
ret = 0;
break;
+#ifdef CONFIG_PMIC_STPMIC1
+ case STM32MP_NVM_BANK:
+ ret = stpmic1_shadow_write_byte(word, (u8 *)&val);
+ break;
+#endif /* CONFIG_PMIC_STPMIC1 */
+
default:
printf("stm32mp %s: wrong value for bank %i\n",
__func__, bank);
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index cb7ca38d074..89ac8229f58 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1051,13 +1051,13 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs,
return -EINVAL;
if (ops->ooblen) {
- u64 maxooblen;
+ size_t maxooblen;
if (ops->ooboffs >= mtd_oobavail(mtd, ops))
return -EINVAL;
- maxooblen = ((mtd_div_by_ws(mtd->size, mtd) -
- mtd_div_by_ws(offs, mtd)) *
+ maxooblen = ((size_t)(mtd_div_by_ws(mtd->size, mtd) -
+ mtd_div_by_ws(offs, mtd)) *
mtd_oobavail(mtd, ops)) - ops->ooboffs;
if (ops->ooblen > maxooblen)
return -EINVAL;
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 7f76e5ecef4..dc087ab641e 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -256,6 +256,17 @@ config NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS
This flag prevent U-boot reconfigure NAND flash controller and reuse
the NAND timing from 1st stage bootloader.
+config NAND_STM32_FMC2
+ bool "Support for NAND controller on STM32MP SoCs"
+ depends on ARCH_STM32MP
+ select SYS_NAND_SELF_INIT
+ imply CMD_NAND
+ help
+ Enables support for NAND Flash chips on SoCs containing the FMC2
+ NAND controller. This controller is found on STM32MP SoCs.
+ The controller supports a maximum 8k page size and supports
+ a maximum 8-bit correction error per sector of 512 bytes.
+
comment "Generic NAND options"
config SYS_NAND_BLOCK_SIZE
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index c61e3f38391..b10e718d150 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
obj-$(CONFIG_NAND_PLAT) += nand_plat.o
obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o
+obj-$(CONFIG_NAND_STM32_FMC2) += stm32_fmc2_nand.o
else # minimal SPL drivers
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
new file mode 100644
index 00000000000..2bb749d7f73
--- /dev/null
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -0,0 +1,1092 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) STMicroelectronics 2019
+ * Author: Christophe Kerello <christophe.kerello@st.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <nand.h>
+#include <reset.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+
+/* Bad block marker length */
+#define FMC2_BBM_LEN 2
+
+/* ECC step size */
+#define FMC2_ECC_STEP_SIZE 512
+
+/* Command delay */
+#define FMC2_RB_DELAY_US 30
+
+/* Max chip enable */
+#define FMC2_MAX_CE 2
+
+/* Timings */
+#define FMC2_THIZ 1
+#define FMC2_TIO 8000
+#define FMC2_TSYNC 3000
+#define FMC2_PCR_TIMING_MASK 0xf
+#define FMC2_PMEM_PATT_TIMING_MASK 0xff
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1 0x0
+#define FMC2_PCR 0x80
+#define FMC2_SR 0x84
+#define FMC2_PMEM 0x88
+#define FMC2_PATT 0x8c
+#define FMC2_HECCR 0x94
+#define FMC2_BCHISR 0x254
+#define FMC2_BCHICR 0x258
+#define FMC2_BCHPBR1 0x260
+#define FMC2_BCHPBR2 0x264
+#define FMC2_BCHPBR3 0x268
+#define FMC2_BCHPBR4 0x26c
+#define FMC2_BCHDSR0 0x27c
+#define FMC2_BCHDSR1 0x280
+#define FMC2_BCHDSR2 0x284
+#define FMC2_BCHDSR3 0x288
+#define FMC2_BCHDSR4 0x28c
+
+/* Register: FMC2_BCR1 */
+#define FMC2_BCR1_FMC2EN BIT(31)
+
+/* Register: FMC2_PCR */
+#define FMC2_PCR_PWAITEN BIT(1)
+#define FMC2_PCR_PBKEN BIT(2)
+#define FMC2_PCR_PWID_MASK GENMASK(5, 4)
+#define FMC2_PCR_PWID(x) (((x) & 0x3) << 4)
+#define FMC2_PCR_PWID_BUSWIDTH_8 0
+#define FMC2_PCR_PWID_BUSWIDTH_16 1
+#define FMC2_PCR_ECCEN BIT(6)
+#define FMC2_PCR_ECCALG BIT(8)
+#define FMC2_PCR_TCLR_MASK GENMASK(12, 9)
+#define FMC2_PCR_TCLR(x) (((x) & 0xf) << 9)
+#define FMC2_PCR_TCLR_DEFAULT 0xf
+#define FMC2_PCR_TAR_MASK GENMASK(16, 13)
+#define FMC2_PCR_TAR(x) (((x) & 0xf) << 13)
+#define FMC2_PCR_TAR_DEFAULT 0xf
+#define FMC2_PCR_ECCSS_MASK GENMASK(19, 17)
+#define FMC2_PCR_ECCSS(x) (((x) & 0x7) << 17)
+#define FMC2_PCR_ECCSS_512 1
+#define FMC2_PCR_ECCSS_2048 3
+#define FMC2_PCR_BCHECC BIT(24)
+#define FMC2_PCR_WEN BIT(25)
+
+/* Register: FMC2_SR */
+#define FMC2_SR_NWRF BIT(6)
+
+/* Register: FMC2_PMEM */
+#define FMC2_PMEM_MEMSET(x) (((x) & 0xff) << 0)
+#define FMC2_PMEM_MEMWAIT(x) (((x) & 0xff) << 8)
+#define FMC2_PMEM_MEMHOLD(x) (((x) & 0xff) << 16)
+#define FMC2_PMEM_MEMHIZ(x) (((x) & 0xff) << 24)
+#define FMC2_PMEM_DEFAULT 0x0a0a0a0a
+
+/* Register: FMC2_PATT */
+#define FMC2_PATT_ATTSET(x) (((x) & 0xff) << 0)
+#define FMC2_PATT_ATTWAIT(x) (((x) & 0xff) << 8)
+#define FMC2_PATT_ATTHOLD(x) (((x) & 0xff) << 16)
+#define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24)
+#define FMC2_PATT_DEFAULT 0x0a0a0a0a
+
+/* Register: FMC2_BCHISR */
+#define FMC2_BCHISR_DERF BIT(1)
+#define FMC2_BCHISR_EPBRF BIT(4)
+
+/* Register: FMC2_BCHICR */
+#define FMC2_BCHICR_CLEAR_IRQ GENMASK(4, 0)
+
+/* Register: FMC2_BCHDSR0 */
+#define FMC2_BCHDSR0_DUE BIT(0)
+#define FMC2_BCHDSR0_DEF BIT(1)
+#define FMC2_BCHDSR0_DEN_MASK GENMASK(7, 4)
+#define FMC2_BCHDSR0_DEN_SHIFT 4
+
+/* Register: FMC2_BCHDSR1 */
+#define FMC2_BCHDSR1_EBP1_MASK GENMASK(12, 0)
+#define FMC2_BCHDSR1_EBP2_MASK GENMASK(28, 16)
+#define FMC2_BCHDSR1_EBP2_SHIFT 16
+
+/* Register: FMC2_BCHDSR2 */
+#define FMC2_BCHDSR2_EBP3_MASK GENMASK(12, 0)
+#define FMC2_BCHDSR2_EBP4_MASK GENMASK(28, 16)
+#define FMC2_BCHDSR2_EBP4_SHIFT 16
+
+/* Register: FMC2_BCHDSR3 */
+#define FMC2_BCHDSR3_EBP5_MASK GENMASK(12, 0)
+#define FMC2_BCHDSR3_EBP6_MASK GENMASK(28, 16)
+#define FMC2_BCHDSR3_EBP6_SHIFT 16
+
+/* Register: FMC2_BCHDSR4 */
+#define FMC2_BCHDSR4_EBP7_MASK GENMASK(12, 0)
+#define FMC2_BCHDSR4_EBP8_MASK GENMASK(28, 16)
+#define FMC2_BCHDSR4_EBP8_SHIFT 16
+
+#define FMC2_NSEC_PER_SEC 1000000000L
+
+enum stm32_fmc2_ecc {
+ FMC2_ECC_HAM = 1,
+ FMC2_ECC_BCH4 = 4,
+ FMC2_ECC_BCH8 = 8
+};
+
+struct stm32_fmc2_timings {
+ u8 tclr;
+ u8 tar;
+ u8 thiz;
+ u8 twait;
+ u8 thold_mem;
+ u8 tset_mem;
+ u8 thold_att;
+ u8 tset_att;
+};
+
+struct stm32_fmc2_nand {
+ struct nand_chip chip;
+ struct stm32_fmc2_timings timings;
+ int ncs;
+ int cs_used[FMC2_MAX_CE];
+};
+
+static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
+{
+ return container_of(chip, struct stm32_fmc2_nand, chip);
+}
+
+struct stm32_fmc2_nfc {
+ struct nand_hw_control base;
+ struct stm32_fmc2_nand nand;
+ struct nand_ecclayout ecclayout;
+ void __iomem *io_base;
+ void __iomem *data_base[FMC2_MAX_CE];
+ void __iomem *cmd_base[FMC2_MAX_CE];
+ void __iomem *addr_base[FMC2_MAX_CE];
+ struct clk clk;
+
+ u8 cs_assigned;
+ int cs_sel;
+};
+
+static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_hw_control *base)
+{
+ return container_of(base, struct stm32_fmc2_nfc, base);
+}
+
+/* Timings configuration */
+static void stm32_fmc2_timings_init(struct nand_chip *chip)
+{
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
+ struct stm32_fmc2_timings *timings = &nand->timings;
+ u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+ u32 pmem, patt;
+
+ /* Set tclr/tar timings */
+ pcr &= ~FMC2_PCR_TCLR_MASK;
+ pcr |= FMC2_PCR_TCLR(timings->tclr);
+ pcr &= ~FMC2_PCR_TAR_MASK;
+ pcr |= FMC2_PCR_TAR(timings->tar);
+
+ /* Set tset/twait/thold/thiz timings in common bank */
+ pmem = FMC2_PMEM_MEMSET(timings->tset_mem);
+ pmem |= FMC2_PMEM_MEMWAIT(timings->twait);
+ pmem |= FMC2_PMEM_MEMHOLD(timings->thold_mem);
+ pmem |= FMC2_PMEM_MEMHIZ(timings->thiz);
+
+ /* Set tset/twait/thold/thiz timings in attribut bank */
+ patt = FMC2_PATT_ATTSET(timings->tset_att);
+ patt |= FMC2_PATT_ATTWAIT(timings->twait);
+ patt |= FMC2_PATT_ATTHOLD(timings->thold_att);
+ patt |= FMC2_PATT_ATTHIZ(timings->thiz);
+
+ writel(pcr, fmc2->io_base + FMC2_PCR);
+ writel(pmem, fmc2->io_base + FMC2_PMEM);
+ writel(patt, fmc2->io_base + FMC2_PATT);
+}
+
+/* Controller configuration */
+static void stm32_fmc2_setup(struct nand_chip *chip)
+{
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+
+ /* Configure ECC algorithm (default configuration is Hamming) */
+ pcr &= ~FMC2_PCR_ECCALG;
+ pcr &= ~FMC2_PCR_BCHECC;
+ if (chip->ecc.strength == FMC2_ECC_BCH8) {
+ pcr |= FMC2_PCR_ECCALG;
+ pcr |= FMC2_PCR_BCHECC;
+ } else if (chip->ecc.strength == FMC2_ECC_BCH4) {
+ pcr |= FMC2_PCR_ECCALG;
+ }
+
+ /* Set buswidth */
+ pcr &= ~FMC2_PCR_PWID_MASK;
+ if (chip->options & NAND_BUSWIDTH_16)
+ pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
+
+ /* Set ECC sector size */
+ pcr &= ~FMC2_PCR_ECCSS_MASK;
+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
+
+ writel(pcr, fmc2->io_base + FMC2_PCR);
+}
+
+/* Select target */
+static void stm32_fmc2_select_chip(struct mtd_info *mtd, int chipnr)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
+
+ if (chipnr < 0 || chipnr >= nand->ncs)
+ return;
+
+ if (nand->cs_used[chipnr] == fmc2->cs_sel)
+ return;
+
+ fmc2->cs_sel = nand->cs_used[chipnr];
+ chip->IO_ADDR_R = fmc2->data_base[fmc2->cs_sel];
+ chip->IO_ADDR_W = fmc2->data_base[fmc2->cs_sel];
+
+ /* FMC2 setup routine */
+ stm32_fmc2_setup(chip);
+
+ /* Apply timings */
+ stm32_fmc2_timings_init(chip);
+}
+
+/* Set bus width to 16-bit or 8-bit */
+static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set)
+{
+ u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+
+ pcr &= ~FMC2_PCR_PWID_MASK;
+ if (set)
+ pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
+ writel(pcr, fmc2->io_base + FMC2_PCR);
+}
+
+/* Enable/disable ECC */
+static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
+{
+ u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+
+ pcr &= ~FMC2_PCR_ECCEN;
+ if (enable)
+ pcr |= FMC2_PCR_ECCEN;
+ writel(pcr, fmc2->io_base + FMC2_PCR);
+}
+
+/* Clear irq sources in case of bch is used */
+static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
+{
+ writel(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
+}
+
+/* Send command and address cycles */
+static void stm32_fmc2_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE) {
+ writeb(cmd, fmc2->cmd_base[fmc2->cs_sel]);
+ return;
+ }
+
+ writeb(cmd, fmc2->addr_base[fmc2->cs_sel]);
+}
+
+/*
+ * Enable ECC logic and reset syndrome/parity bits previously calculated
+ * Syndrome/parity bits is cleared by setting the ECCEN bit to 0
+ */
+static void stm32_fmc2_hwctl(struct mtd_info *mtd, int mode)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+
+ stm32_fmc2_set_ecc(fmc2, false);
+
+ if (chip->ecc.strength != FMC2_ECC_HAM) {
+ u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+
+ if (mode == NAND_ECC_WRITE)
+ pcr |= FMC2_PCR_WEN;
+ else
+ pcr &= ~FMC2_PCR_WEN;
+ writel(pcr, fmc2->io_base + FMC2_PCR);
+
+ stm32_fmc2_clear_bch_irq(fmc2);
+ }
+
+ stm32_fmc2_set_ecc(fmc2, true);
+}
+
+/*
+ * ECC Hamming calculation
+ * ECC is 3 bytes for 512 bytes of data (supports error correction up to
+ * max of 1-bit)
+ */
+static int stm32_fmc2_ham_calculate(struct mtd_info *mtd, const u8 *data,
+ u8 *ecc)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ u32 heccr, sr;
+ int ret;
+
+ ret = readl_poll_timeout(fmc2->io_base + FMC2_SR, sr,
+ sr & FMC2_SR_NWRF, 10000);
+ if (ret < 0) {
+ pr_err("Ham timeout\n");
+ return ret;
+ }
+
+ heccr = readl(fmc2->io_base + FMC2_HECCR);
+
+ ecc[0] = heccr;
+ ecc[1] = heccr >> 8;
+ ecc[2] = heccr >> 16;
+
+ /* Disable ecc */
+ stm32_fmc2_set_ecc(fmc2, false);
+
+ return 0;
+}
+
+static int stm32_fmc2_ham_correct(struct mtd_info *mtd, u8 *dat,
+ u8 *read_ecc, u8 *calc_ecc)
+{
+ u8 bit_position = 0, b0, b1, b2;
+ u32 byte_addr = 0, b;
+ u32 i, shifting = 1;
+
+ /* Indicate which bit and byte is faulty (if any) */
+ b0 = read_ecc[0] ^ calc_ecc[0];
+ b1 = read_ecc[1] ^ calc_ecc[1];
+ b2 = read_ecc[2] ^ calc_ecc[2];
+ b = b0 | (b1 << 8) | (b2 << 16);
+
+ /* No errors */
+ if (likely(!b))
+ return 0;
+
+ /* Calculate bit position */
+ for (i = 0; i < 3; i++) {
+ switch (b % 4) {
+ case 2:
+ bit_position += shifting;
+ case 1:
+ break;
+ default:
+ return -EBADMSG;
+ }
+ shifting <<= 1;
+ b >>= 2;
+ }
+
+ /* Calculate byte position */
+ shifting = 1;
+ for (i = 0; i < 9; i++) {
+ switch (b % 4) {
+ case 2:
+ byte_addr += shifting;
+ case 1:
+ break;
+ default:
+ return -EBADMSG;
+ }
+ shifting <<= 1;
+ b >>= 2;
+ }
+
+ /* Flip the bit */
+ dat[byte_addr] ^= (1 << bit_position);
+
+ return 1;
+}
+
+/*
+ * ECC BCH calculation and correction
+ * ECC is 7/13 bytes for 512 bytes of data (supports error correction up to
+ * max of 4-bit/8-bit)
+ */
+
+static int stm32_fmc2_bch_calculate(struct mtd_info *mtd, const u8 *data,
+ u8 *ecc)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ u32 bchpbr, bchisr;
+ int ret;
+
+ /* Wait until the BCH code is ready */
+ ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr,
+ bchisr & FMC2_BCHISR_EPBRF, 10000);
+ if (ret < 0) {
+ pr_err("Bch timeout\n");
+ return ret;
+ }
+
+ /* Read parity bits */
+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR1);
+ ecc[0] = bchpbr;
+ ecc[1] = bchpbr >> 8;
+ ecc[2] = bchpbr >> 16;
+ ecc[3] = bchpbr >> 24;
+
+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR2);
+ ecc[4] = bchpbr;
+ ecc[5] = bchpbr >> 8;
+ ecc[6] = bchpbr >> 16;
+
+ if (chip->ecc.strength == FMC2_ECC_BCH8) {
+ ecc[7] = bchpbr >> 24;
+
+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR3);
+ ecc[8] = bchpbr;
+ ecc[9] = bchpbr >> 8;
+ ecc[10] = bchpbr >> 16;
+ ecc[11] = bchpbr >> 24;
+
+ bchpbr = readl(fmc2->io_base + FMC2_BCHPBR4);
+ ecc[12] = bchpbr;
+ }
+
+ /* Disable ecc */
+ stm32_fmc2_set_ecc(fmc2, false);
+
+ return 0;
+}
+
+/* BCH algorithm correction */
+static int stm32_fmc2_bch_correct(struct mtd_info *mtd, u8 *dat,
+ u8 *read_ecc, u8 *calc_ecc)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ u32 bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4, bchisr;
+ u16 pos[8];
+ int i, ret, den, eccsize = chip->ecc.size;
+ unsigned int nb_errs = 0;
+
+ /* Wait until the decoding error is ready */
+ ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr,
+ bchisr & FMC2_BCHISR_DERF, 10000);
+ if (ret < 0) {
+ pr_err("Bch timeout\n");
+ return ret;
+ }
+
+ bchdsr0 = readl(fmc2->io_base + FMC2_BCHDSR0);
+ bchdsr1 = readl(fmc2->io_base + FMC2_BCHDSR1);
+ bchdsr2 = readl(fmc2->io_base + FMC2_BCHDSR2);
+ bchdsr3 = readl(fmc2->io_base + FMC2_BCHDSR3);
+ bchdsr4 = readl(fmc2->io_base + FMC2_BCHDSR4);
+
+ /* Disable ECC */
+ stm32_fmc2_set_ecc(fmc2, false);
+
+ /* No errors found */
+ if (likely(!(bchdsr0 & FMC2_BCHDSR0_DEF)))
+ return 0;
+
+ /* Too many errors detected */
+ if (unlikely(bchdsr0 & FMC2_BCHDSR0_DUE))
+ return -EBADMSG;
+
+ pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK;
+ pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT;
+ pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK;
+ pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT;
+ pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK;
+ pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT;
+ pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK;
+ pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT;
+
+ den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT;
+ for (i = 0; i < den; i++) {
+ if (pos[i] < eccsize * 8) {
+ __change_bit(pos[i], (unsigned long *)dat);
+ nb_errs++;
+ }
+ }
+
+ return nb_errs;
+}
+
+static int stm32_fmc2_read_page(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *buf,
+ int oob_required, int page)
+{
+ int i, s, stat, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps;
+ int eccstrength = chip->ecc.strength;
+ u8 *p = buf;
+ u8 *ecc_calc = chip->buffers->ecccalc;
+ u8 *ecc_code = chip->buffers->ecccode;
+ unsigned int max_bitflips = 0;
+
+ for (i = mtd->writesize + FMC2_BBM_LEN, s = 0; s < eccsteps;
+ s++, i += eccbytes, p += eccsize) {
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+
+ /* Read the nand page sector (512 bytes) */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, s * eccsize, -1);
+ chip->read_buf(mtd, p, eccsize);
+
+ /* Read the corresponding ECC bytes */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, i, -1);
+ chip->read_buf(mtd, ecc_code, eccbytes);
+
+ /* Correct the data */
+ stat = chip->ecc.correct(mtd, p, ecc_code, ecc_calc);
+ if (stat == -EBADMSG)
+ /* Check for empty pages with bitflips */
+ stat = nand_check_erased_ecc_chunk(p, eccsize,
+ ecc_code, eccbytes,
+ NULL, 0,
+ eccstrength);
+
+ if (stat < 0) {
+ mtd->ecc_stats.failed++;
+ } else {
+ mtd->ecc_stats.corrected += stat;
+ max_bitflips = max_t(unsigned int, max_bitflips, stat);
+ }
+ }
+
+ /* Read oob */
+ if (oob_required) {
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+ }
+
+ return max_bitflips;
+}
+
+/* Controller initialization */
+static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2)
+{
+ u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+ u32 bcr1 = readl(fmc2->io_base + FMC2_BCR1);
+
+ /* Set CS used to undefined */
+ fmc2->cs_sel = -1;
+
+ /* Enable wait feature and nand flash memory bank */
+ pcr |= FMC2_PCR_PWAITEN;
+ pcr |= FMC2_PCR_PBKEN;
+
+ /* Set buswidth to 8 bits mode for identification */
+ pcr &= ~FMC2_PCR_PWID_MASK;
+
+ /* ECC logic is disabled */
+ pcr &= ~FMC2_PCR_ECCEN;
+
+ /* Default mode */
+ pcr &= ~FMC2_PCR_ECCALG;
+ pcr &= ~FMC2_PCR_BCHECC;
+ pcr &= ~FMC2_PCR_WEN;
+
+ /* Set default ECC sector size */
+ pcr &= ~FMC2_PCR_ECCSS_MASK;
+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048);
+
+ /* Set default tclr/tar timings */
+ pcr &= ~FMC2_PCR_TCLR_MASK;
+ pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT);
+ pcr &= ~FMC2_PCR_TAR_MASK;
+ pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT);
+
+ /* Enable FMC2 controller */
+ bcr1 |= FMC2_BCR1_FMC2EN;
+
+ writel(bcr1, fmc2->io_base + FMC2_BCR1);
+ writel(pcr, fmc2->io_base + FMC2_PCR);
+ writel(FMC2_PMEM_DEFAULT, fmc2->io_base + FMC2_PMEM);
+ writel(FMC2_PATT_DEFAULT, fmc2->io_base + FMC2_PATT);
+}
+
+/* Controller timings */
+static void stm32_fmc2_calc_timings(struct nand_chip *chip,
+ const struct nand_sdr_timings *sdrt)
+{
+ struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+ struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
+ struct stm32_fmc2_timings *tims = &nand->timings;
+ unsigned long hclk = clk_get_rate(&fmc2->clk);
+ unsigned long hclkp = FMC2_NSEC_PER_SEC / (hclk / 1000);
+ int tar, tclr, thiz, twait, tset_mem, tset_att, thold_mem, thold_att;
+
+ tar = hclkp;
+ if (tar < sdrt->tAR_min)
+ tar = sdrt->tAR_min;
+ tims->tar = DIV_ROUND_UP(tar, hclkp) - 1;
+ if (tims->tar > FMC2_PCR_TIMING_MASK)
+ tims->tar = FMC2_PCR_TIMING_MASK;
+
+ tclr = hclkp;
+ if (tclr < sdrt->tCLR_min)
+ tclr = sdrt->tCLR_min;
+ tims->tclr = DIV_ROUND_UP(tclr, hclkp) - 1;
+ if (tims->tclr > FMC2_PCR_TIMING_MASK)
+ tims->tclr = FMC2_PCR_TIMING_MASK;
+
+ tims->thiz = FMC2_THIZ;
+ thiz = (tims->thiz + 1) * hclkp;
+
+ /*
+ * tWAIT > tRP
+ * tWAIT > tWP
+ * tWAIT > tREA + tIO
+ */
+ twait = hclkp;
+ if (twait < sdrt->tRP_min)
+ twait = sdrt->tRP_min;
+ if (twait < sdrt->tWP_min)
+ twait = sdrt->tWP_min;
+ if (twait < sdrt->tREA_max + FMC2_TIO)
+ twait = sdrt->tREA_max + FMC2_TIO;
+ tims->twait = DIV_ROUND_UP(twait, hclkp);
+ if (tims->twait == 0)
+ tims->twait = 1;
+ else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK)
+ tims->twait = FMC2_PMEM_PATT_TIMING_MASK;
+
+ /*
+ * tSETUP_MEM > tCS - tWAIT
+ * tSETUP_MEM > tALS - tWAIT
+ * tSETUP_MEM > tDS - (tWAIT - tHIZ)
+ */
+ tset_mem = hclkp;
+ if (sdrt->tCS_min > twait && (tset_mem < sdrt->tCS_min - twait))
+ tset_mem = sdrt->tCS_min - twait;
+ if (sdrt->tALS_min > twait && (tset_mem < sdrt->tALS_min - twait))
+ tset_mem = sdrt->tALS_min - twait;
+ if (twait > thiz && (sdrt->tDS_min > twait - thiz) &&
+ (tset_mem < sdrt->tDS_min - (twait - thiz)))
+ tset_mem = sdrt->tDS_min - (twait - thiz);
+ tims->tset_mem = DIV_ROUND_UP(tset_mem, hclkp);
+ if (tims->tset_mem == 0)
+ tims->tset_mem = 1;
+ else if (tims->tset_mem > FMC2_PMEM_PATT_TIMING_MASK)
+ tims->tset_mem = FMC2_PMEM_PATT_TIMING_MASK;
+
+ /*
+ * tHOLD_MEM > tCH
+ * tHOLD_MEM > tREH - tSETUP_MEM
+ * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT)
+ */
+ thold_mem = hclkp;
+ if (thold_mem < sdrt->tCH_min)
+ thold_mem = sdrt->tCH_min;
+ if (sdrt->tREH_min > tset_mem &&
+ (thold_mem < sdrt->tREH_min - tset_mem))
+ thold_mem = sdrt->tREH_min - tset_mem;
+ if ((sdrt->tRC_min > tset_mem + twait) &&
+ (thold_mem < sdrt->tRC_min - (tset_mem + twait)))
+ thold_mem = sdrt->tRC_min - (tset_mem + twait);
+ if ((sdrt->tWC_min > tset_mem + twait) &&
+ (thold_mem < sdrt->tWC_min - (tset_mem + twait)))
+ thold_mem = sdrt->tWC_min - (tset_mem + twait);
+ tims->thold_mem = DIV_ROUND_UP(thold_mem, hclkp);
+ if (tims->thold_mem == 0)
+ tims->thold_mem = 1;
+ else if (tims->thold_mem > FMC2_PMEM_PATT_TIMING_MASK)
+ tims->thold_mem = FMC2_PMEM_PATT_TIMING_MASK;
+
+ /*
+ * tSETUP_ATT > tCS - tWAIT
+ * tSETUP_ATT > tCLS - tWAIT
+ * tSETUP_ATT > tALS - tWAIT
+ * tSETUP_ATT > tRHW - tHOLD_MEM
+ * tSETUP_ATT > tDS - (tWAIT - tHIZ)
+ */
+ tset_att = hclkp;
+ if (sdrt->tCS_min > twait && (tset_att < sdrt->tCS_min - twait))
+ tset_att = sdrt->tCS_min - twait;
+ if (sdrt->tCLS_min > twait && (tset_att < sdrt->tCLS_min - twait))
+ tset_att = sdrt->tCLS_min - twait;
+ if (sdrt->tALS_min > twait && (tset_att < sdrt->tALS_min - twait))
+ tset_att = sdrt->tALS_min - twait;
+ if (sdrt->tRHW_min > thold_mem &&
+ (tset_att < sdrt->tRHW_min - thold_mem))
+ tset_att = sdrt->tRHW_min - thold_mem;
+ if (twait > thiz && (sdrt->tDS_min > twait - thiz) &&
+ (tset_att < sdrt->tDS_min - (twait - thiz)))
+ tset_att = sdrt->tDS_min - (twait - thiz);
+ tims->tset_att = DIV_ROUND_UP(tset_att, hclkp);
+ if (tims->tset_att == 0)
+ tims->tset_att = 1;
+ else if (tims->tset_att > FMC2_PMEM_PATT_TIMING_MASK)
+ tims->tset_att = FMC2_PMEM_PATT_TIMING_MASK;
+
+ /*
+ * tHOLD_ATT > tALH
+ * tHOLD_ATT > tCH
+ * tHOLD_ATT > tCLH
+ * tHOLD_ATT > tCOH
+ * tHOLD_ATT > tDH
+ * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM
+ * tHOLD_ATT > tADL - tSETUP_MEM
+ * tHOLD_ATT > tWH - tSETUP_MEM
+ * tHOLD_ATT > tWHR - tSETUP_MEM
+ * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT)
+ * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT)
+ */
+ thold_att = hclkp;
+ if (thold_att < sdrt->tALH_min)
+ thold_att = sdrt->tALH_min;
+ if (thold_att < sdrt->tCH_min)
+ thold_att = sdrt->tCH_min;
+ if (thold_att < sdrt->tCLH_min)
+ thold_att = sdrt->tCLH_min;
+ if (thold_att < sdrt->tCOH_min)
+ thold_att = sdrt->tCOH_min;
+ if (thold_att < sdrt->tDH_min)
+ thold_att = sdrt->tDH_min;
+ if ((sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC > tset_mem) &&
+ (thold_att < sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem))
+ thold_att = sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem;
+ if (sdrt->tADL_min > tset_mem &&
+ (thold_att < sdrt->tADL_min - tset_mem))
+ thold_att = sdrt->tADL_min - tset_mem;
+ if (sdrt->tWH_min > tset_mem &&
+ (thold_att < sdrt->tWH_min - tset_mem))
+ thold_att = sdrt->tWH_min - tset_mem;
+ if (sdrt->tWHR_min > tset_mem &&
+ (thold_att < sdrt->tWHR_min - tset_mem))
+ thold_att = sdrt->tWHR_min - tset_mem;
+ if ((sdrt->tRC_min > tset_att + twait) &&
+ (thold_att < sdrt->tRC_min - (tset_att + twait)))
+ thold_att = sdrt->tRC_min - (tset_att + twait);
+ if ((sdrt->tWC_min > tset_att + twait) &&
+ (thold_att < sdrt->tWC_min - (tset_att + twait)))
+ thold_att = sdrt->tWC_min - (tset_att + twait);
+ tims->thold_att = DIV_ROUND_UP(thold_att, hclkp);
+ if (tims->thold_att == 0)
+ tims->thold_att = 1;
+ else if (tims->thold_att > FMC2_PMEM_PATT_TIMING_MASK)
+ tims->thold_att = FMC2_PMEM_PATT_TIMING_MASK;
+}
+
+static int stm32_fmc2_setup_interface(struct mtd_info *mtd, int chipnr,
+ const struct nand_data_interface *conf)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ const struct nand_sdr_timings *sdrt;
+
+ sdrt = nand_get_sdr_timings(conf);
+ if (IS_ERR(sdrt))
+ return PTR_ERR(sdrt);
+
+ if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
+ return 0;
+
+ stm32_fmc2_calc_timings(chip, sdrt);
+
+ /* Apply timings */
+ stm32_fmc2_timings_init(chip);
+
+ return 0;
+}
+
+/* NAND callbacks setup */
+static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip)
+{
+ chip->ecc.hwctl = stm32_fmc2_hwctl;
+
+ /*
+ * Specific callbacks to read/write a page depending on
+ * the algo used (Hamming, BCH).
+ */
+ if (chip->ecc.strength == FMC2_ECC_HAM) {
+ /* Hamming is used */
+ chip->ecc.calculate = stm32_fmc2_ham_calculate;
+ chip->ecc.correct = stm32_fmc2_ham_correct;
+ chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 4 : 3;
+ chip->ecc.options |= NAND_ECC_GENERIC_ERASED_CHECK;
+ return;
+ }
+
+ /* BCH is used */
+ chip->ecc.read_page = stm32_fmc2_read_page;
+ chip->ecc.calculate = stm32_fmc2_bch_calculate;
+ chip->ecc.correct = stm32_fmc2_bch_correct;
+
+ if (chip->ecc.strength == FMC2_ECC_BCH8)
+ chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 14 : 13;
+ else
+ chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 8 : 7;
+}
+
+/* FMC2 caps */
+static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength)
+{
+ /* Hamming */
+ if (strength == FMC2_ECC_HAM)
+ return 4;
+
+ /* BCH8 */
+ if (strength == FMC2_ECC_BCH8)
+ return 14;
+
+ /* BCH4 */
+ return 8;
+}
+
+NAND_ECC_CAPS_SINGLE(stm32_fmc2_ecc_caps, stm32_fmc2_calc_ecc_bytes,
+ FMC2_ECC_STEP_SIZE,
+ FMC2_ECC_HAM, FMC2_ECC_BCH4, FMC2_ECC_BCH8);
+
+/* FMC2 probe */
+static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2,
+ ofnode node)
+{
+ struct stm32_fmc2_nand *nand = &fmc2->nand;
+ u32 cs[FMC2_MAX_CE];
+ int ret, i;
+
+ if (!ofnode_get_property(node, "reg", &nand->ncs))
+ return -EINVAL;
+
+ nand->ncs /= sizeof(u32);
+ if (!nand->ncs) {
+ pr_err("Invalid reg property size\n");
+ return -EINVAL;
+ }
+
+ ret = ofnode_read_u32_array(node, "reg", cs, nand->ncs);
+ if (ret < 0) {
+ pr_err("Could not retrieve reg property\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < nand->ncs; i++) {
+ if (cs[i] > FMC2_MAX_CE) {
+ pr_err("Invalid reg value: %d\n",
+ nand->cs_used[i]);
+ return -EINVAL;
+ }
+
+ if (fmc2->cs_assigned & BIT(cs[i])) {
+ pr_err("Cs already assigned: %d\n",
+ nand->cs_used[i]);
+ return -EINVAL;
+ }
+
+ fmc2->cs_assigned |= BIT(cs[i]);
+ nand->cs_used[i] = cs[i];
+ }
+
+ nand->chip.flash_node = ofnode_to_offset(node);
+
+ return 0;
+}
+
+static int stm32_fmc2_parse_dt(struct udevice *dev,
+ struct stm32_fmc2_nfc *fmc2)
+{
+ ofnode child;
+ int ret, nchips = 0;
+
+ dev_for_each_subnode(child, dev)
+ nchips++;
+
+ if (!nchips) {
+ pr_err("NAND chip not defined\n");
+ return -EINVAL;
+ }
+
+ if (nchips > 1) {
+ pr_err("Too many NAND chips defined\n");
+ return -EINVAL;
+ }
+
+ dev_for_each_subnode(child, dev) {
+ ret = stm32_fmc2_parse_child(fmc2, child);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int stm32_fmc2_probe(struct udevice *dev)
+{
+ struct stm32_fmc2_nfc *fmc2 = dev_get_priv(dev);
+ struct stm32_fmc2_nand *nand = &fmc2->nand;
+ struct nand_chip *chip = &nand->chip;
+ struct mtd_info *mtd = &chip->mtd;
+ struct nand_ecclayout *ecclayout;
+ struct resource resource;
+ struct reset_ctl reset;
+ int oob_index, chip_cs, mem_region, ret, i;
+
+ spin_lock_init(&fmc2->controller.lock);
+ init_waitqueue_head(&fmc2->controller.wq);
+
+ ret = stm32_fmc2_parse_dt(dev, fmc2);
+ if (ret)
+ return ret;
+
+ /* Get resources */
+ ret = dev_read_resource(dev, 0, &resource);
+ if (ret) {
+ pr_err("Resource io_base not found");
+ return ret;
+ }
+ fmc2->io_base = (void __iomem *)resource.start;
+
+ for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE;
+ chip_cs++, mem_region += 3) {
+ if (!(fmc2->cs_assigned & BIT(chip_cs)))
+ continue;
+
+ ret = dev_read_resource(dev, mem_region, &resource);
+ if (ret) {
+ pr_err("Resource data_base not found for cs%d",
+ chip_cs);
+ return ret;
+ }
+ fmc2->data_base[chip_cs] = (void __iomem *)resource.start;
+
+ ret = dev_read_resource(dev, mem_region + 1, &resource);
+ if (ret) {
+ pr_err("Resource cmd_base not found for cs%d",
+ chip_cs);
+ return ret;
+ }
+ fmc2->cmd_base[chip_cs] = (void __iomem *)resource.start;
+
+ ret = dev_read_resource(dev, mem_region + 2, &resource);
+ if (ret) {
+ pr_err("Resource addr_base not found for cs%d",
+ chip_cs);
+ return ret;
+ }
+ fmc2->addr_base[chip_cs] = (void __iomem *)resource.start;
+ }
+
+ /* Enable the clock */
+ ret = clk_get_by_index(dev, 0, &fmc2->clk);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&fmc2->clk);
+ if (ret)
+ return ret;
+
+ /* Reset */
+ ret = reset_get_by_index(dev, 0, &reset);
+ if (!ret) {
+ reset_assert(&reset);
+ udelay(2);
+ reset_deassert(&reset);
+ }
+
+ /* FMC2 init routine */
+ stm32_fmc2_init(fmc2);
+
+ chip->controller = &fmc2->base;
+ chip->select_chip = stm32_fmc2_select_chip;
+ chip->setup_data_interface = stm32_fmc2_setup_interface;
+ chip->cmd_ctrl = stm32_fmc2_cmd_ctrl;
+ chip->chip_delay = FMC2_RB_DELAY_US;
+ chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
+ NAND_USE_BOUNCE_BUFFER;
+
+ /* Default ECC settings */
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.size = FMC2_ECC_STEP_SIZE;
+ chip->ecc.strength = FMC2_ECC_BCH8;
+
+ /* Scan to find existence of the device */
+ ret = nand_scan_ident(mtd, nand->ncs, NULL);
+ if (ret)
+ return ret;
+
+ /*
+ * Only NAND_ECC_HW mode is actually supported
+ * Hamming => ecc.strength = 1
+ * BCH4 => ecc.strength = 4
+ * BCH8 => ecc.strength = 8
+ * ECC sector size = 512
+ */
+ if (chip->ecc.mode != NAND_ECC_HW) {
+ pr_err("Nand_ecc_mode is not well defined in the DT\n");
+ return -EINVAL;
+ }
+
+ ret = nand_check_ecc_caps(chip, &stm32_fmc2_ecc_caps,
+ mtd->oobsize - FMC2_BBM_LEN);
+ if (ret) {
+ pr_err("No valid ECC settings set\n");
+ return ret;
+ }
+
+ if (chip->bbt_options & NAND_BBT_USE_FLASH)
+ chip->bbt_options |= NAND_BBT_NO_OOB;
+
+ /* NAND callbacks setup */
+ stm32_fmc2_nand_callbacks_setup(chip);
+
+ /* Define ECC layout */
+ ecclayout = &fmc2->ecclayout;
+ ecclayout->eccbytes = chip->ecc.bytes *
+ (mtd->writesize / chip->ecc.size);
+ oob_index = FMC2_BBM_LEN;
+ for (i = 0; i < ecclayout->eccbytes; i++, oob_index++)
+ ecclayout->eccpos[i] = oob_index;
+ ecclayout->oobfree->offset = oob_index;
+ ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset;
+ chip->ecc.layout = ecclayout;
+
+ /* Configure bus width to 16-bit */
+ if (chip->options & NAND_BUSWIDTH_16)
+ stm32_fmc2_set_buswidth_16(fmc2, true);
+
+ /* Scan the device to fill MTD data-structures */
+ ret = nand_scan_tail(mtd);
+ if (ret)
+ return ret;
+
+ return nand_register(0, mtd);
+}
+
+static const struct udevice_id stm32_fmc2_match[] = {
+ { .compatible = "st,stm32mp15-fmc2" },
+ { /* Sentinel */ }
+};
+
+U_BOOT_DRIVER(stm32_fmc2_nand) = {
+ .name = "stm32_fmc2_nand",
+ .id = UCLASS_MTD,
+ .of_match = stm32_fmc2_match,
+ .probe = stm32_fmc2_probe,
+ .priv_auto_alloc_size = sizeof(struct stm32_fmc2_nfc),
+};
+
+void board_nand_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_MTD,
+ DM_GET_DRIVER(stm32_fmc2_nand),
+ &dev);
+ if (ret && ret != -ENODEV)
+ pr_err("Failed to initialize STM32 FMC2 NAND controller. (error %d)\n",
+ ret);
+}
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
index 0bade208084..3681c5eed9a 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -12,12 +12,11 @@
#endif
#include <linux/mtd/spinand.h>
-#define SPINAND_MFR_GIGADEVICE 0xc8
+#define SPINAND_MFR_GIGADEVICE 0xC8
+#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
+#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
-#define GIGADEVICE_STATUS_ECC_MASK GENMASK(5, 4)
-#define GIGADEVICE_STATUS_ECC_NO_BITFLIPS (0 << 4)
-#define GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS (1 << 4)
-#define GIGADEVICE_STATUS_ECC_8_BITFLIPS (3 << 4)
+#define GD5FXGQ4XEXXG_REG_STATUS2 0xf0
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
@@ -35,8 +34,8 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
SPINAND_PROG_LOAD(false, 0, NULL, 0));
-static int gd5f1gq4u_ooblayout_ecc(struct mtd_info *mtd, int section,
- struct mtd_oob_region *region)
+static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
{
if (section)
return -ERANGE;
@@ -47,38 +46,49 @@ static int gd5f1gq4u_ooblayout_ecc(struct mtd_info *mtd, int section,
return 0;
}
-static int gd5f1gq4u_ooblayout_free(struct mtd_info *mtd, int section,
- struct mtd_oob_region *region)
+static int gd5fxgq4xexxg_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
{
if (section)
return -ERANGE;
- /* Reserve 2 bytes for the BBM. */
- region->offset = 2;
- region->length = 62;
+ /* Reserve 1 bytes for the BBM. */
+ region->offset = 1;
+ region->length = 63;
return 0;
}
-static const struct mtd_ooblayout_ops gd5f1gq4u_ooblayout = {
- .ecc = gd5f1gq4u_ooblayout_ecc,
- .free = gd5f1gq4u_ooblayout_free,
-};
-
-static int gd5f1gq4u_ecc_get_status(struct spinand_device *spinand,
- u8 status)
+static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
{
- if (status)
- debug("%s (%d): status=%02x\n", __func__, __LINE__, status);
+ u8 status2;
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4XEXXG_REG_STATUS2,
+ &status2);
+ int ret;
- switch (status & GIGADEVICE_STATUS_ECC_MASK) {
+ switch (status & STATUS_ECC_MASK) {
case STATUS_ECC_NO_BITFLIPS:
return 0;
- case GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS:
- return 7;
-
- case GIGADEVICE_STATUS_ECC_8_BITFLIPS:
+ case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
+ /*
+ * Read status2 register to determine a more fine grained
+ * bit error status
+ */
+ ret = spi_mem_exec_op(spinand->slave, &op);
+ if (ret)
+ return ret;
+
+ /*
+ * 4 ... 7 bits are flipped (1..4 can't be detected, so
+ * report the maximum of 4 in this case
+ */
+ /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
+ return ((status & STATUS_ECC_MASK) >> 2) |
+ ((status2 & STATUS_ECC_MASK) >> 4);
+
+ case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
return 8;
case STATUS_ECC_UNCOR_ERROR:
@@ -91,16 +101,21 @@ static int gd5f1gq4u_ecc_get_status(struct spinand_device *spinand,
return -EINVAL;
}
+static const struct mtd_ooblayout_ops gd5fxgq4xexxg_ooblayout = {
+ .ecc = gd5fxgq4xexxg_ooblayout_ecc,
+ .free = gd5fxgq4xexxg_ooblayout_free,
+};
+
static const struct spinand_info gigadevice_spinand_table[] = {
- SPINAND_INFO("GD5F1GQ4UC", 0xd1,
+ SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
- NAND_ECCREQ(8, 2048),
+ NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
0,
- SPINAND_ECCINFO(&gd5f1gq4u_ooblayout,
- gd5f1gq4u_ecc_get_status)),
+ SPINAND_ECCINFO(&gd5fxgq4xexxg_ooblayout,
+ gd5fxgq4xexxg_ecc_get_status)),
};
static int gigadevice_spinand_detect(struct spinand_device *spinand)
@@ -109,8 +124,8 @@ static int gigadevice_spinand_detect(struct spinand_device *spinand)
int ret;
/*
- * Gigadevice SPI NAND read ID need a dummy byte,
- * so the first byte in raw_id is dummy.
+ * For GD NANDs, There is an address byte needed to shift in before IDs
+ * are read out, so the first byte in raw_id is dummy.
*/
if (id[1] != SPINAND_MFR_GIGADEVICE)
return 0;
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 5671bca24a0..d3b007a731d 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -62,6 +62,9 @@ config SF_DEFAULT_MODE
The default mode may be provided by the platform
to handle the common case when only a single serial
flash is present on the system.
+ Not used for boot with device tree; the SPI driver reads
+ speed and mode from platdata values computed from
+ available node.
config SF_DEFAULT_SPEED
int "SPI Flash default speed in Hz"
@@ -71,6 +74,9 @@ config SF_DEFAULT_SPEED
The default speed may be provided by the platform
to handle the common case when only a single serial
flash is present on the system.
+ Not used for boot with device tree; the SPI driver reads
+ speed and mode from platdata values computed from
+ available node.
if SPI_FLASH
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 7f1378f4946..73297e1a0a5 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -166,7 +166,6 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
};
static const struct udevice_id spi_flash_std_ids[] = {
- { .compatible = "spi-flash" },
{ .compatible = "jedec,spi-nor" },
{ }
};
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index b7f07338779..c4e2f6a08fa 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -524,8 +524,11 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info)
*/
static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
{
- u8 buf[SPI_NOR_MAX_ADDR_WIDTH];
- int i;
+ struct spi_mem_op op =
+ SPI_MEM_OP(SPI_MEM_OP_CMD(nor->erase_opcode, 1),
+ SPI_MEM_OP_ADDR(nor->addr_width, addr, 1),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_NO_DATA);
if (nor->erase)
return nor->erase(nor, addr);
@@ -534,12 +537,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
* Default implementation, if driver doesn't have a specialized HW
* control
*/
- for (i = nor->addr_width - 1; i >= 0; i--) {
- buf[i] = addr & 0xff;
- addr >>= 8;
- }
-
- return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
+ return spi_mem_exec_op(nor->spi, &op);
}
/*
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 3215e2431dc..ec929760eee 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -106,6 +106,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+ {
+ INFO("gd25lq128", 0xc86018, 0, 64 * 1024, 256,
+ SECT_4K | SPI_NOR_DUAL_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
#endif
#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
/* ISSI */
@@ -142,6 +147,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("mx25l25655e", 0xc22619, 0, 64 * 1024, 512, 0) },
{ INFO("mx66l51235l", 0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66u51235f", 0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66u2g45g", 0xc2253c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66l1g45g", 0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
#endif
@@ -187,6 +193,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("s25fl116k", 0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("s25fl164k", 0x014017, 0, 64 * 1024, 128, SECT_4K) },
{ INFO("s25fl208k", 0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) },
+ { INFO("s25fl064l", 0x016017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("s25fl128l", 0x016018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
#endif
#ifdef CONFIG_SPI_FLASH_SST /* SST */
diff --git a/drivers/net/ag7xxx.c b/drivers/net/ag7xxx.c
index 8146c3170e1..7f1dee4b3e4 100644
--- a/drivers/net/ag7xxx.c
+++ b/drivers/net/ag7xxx.c
@@ -3,6 +3,7 @@
* Atheros AR71xx / AR9xxx GMAC driver
*
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
+ * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
*/
#include <common.h>
@@ -23,6 +24,8 @@ DECLARE_GLOBAL_DATA_PTR;
enum ag7xxx_model {
AG7XXX_MODEL_AG933X,
AG7XXX_MODEL_AG934X,
+ AG7XXX_MODEL_AG953X,
+ AG7XXX_MODEL_AG956X
};
/* MAC Configuration 1 */
@@ -99,8 +102,29 @@ enum ag7xxx_model {
/* Rx Status */
#define AG7XXX_ETH_DMA_RX_STATUS 0x194
+/* Custom register at 0x1805002C */
+#define AG7XXX_ETH_XMII 0x2C
+#define AG7XXX_ETH_XMII_TX_INVERT BIT(31)
+#define AG7XXX_ETH_XMII_RX_DELAY_LSB 28
+#define AG7XXX_ETH_XMII_RX_DELAY_MASK 0x30000000
+#define AG7XXX_ETH_XMII_RX_DELAY_SET(x) \
+ (((x) << AG7XXX_ETH_XMII_RX_DELAY_LSB) & AG7XXX_ETH_XMII_RX_DELAY_MASK)
+#define AG7XXX_ETH_XMII_TX_DELAY_LSB 26
+#define AG7XXX_ETH_XMII_TX_DELAY_MASK 0x0c000000
+#define AG7XXX_ETH_XMII_TX_DELAY_SET(x) \
+ (((x) << AG7XXX_ETH_XMII_TX_DELAY_LSB) & AG7XXX_ETH_XMII_TX_DELAY_MASK)
+#define AG7XXX_ETH_XMII_GIGE BIT(25)
+
/* Custom register at 0x18070000 */
#define AG7XXX_GMAC_ETH_CFG 0x00
+#define AG7XXX_ETH_CFG_RXDV_DELAY_LSB 16
+#define AG7XXX_ETH_CFG_RXDV_DELAY_MASK 0x00030000
+#define AG7XXX_ETH_CFG_RXDV_DELAY_SET(x) \
+ (((x) << AG7XXX_ETH_CFG_RXDV_DELAY_LSB) & AG7XXX_ETH_CFG_RXDV_DELAY_MASK)
+#define AG7XXX_ETH_CFG_RXD_DELAY_LSB 14
+#define AG7XXX_ETH_CFG_RXD_DELAY_MASK 0x0000c000
+#define AG7XXX_ETH_CFG_RXD_DELAY_SET(x) \
+ (((x) << AG7XXX_ETH_CFG_RXD_DELAY_LSB) & AG7XXX_ETH_CFG_RXD_DELAY_MASK)
#define AG7XXX_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8)
#define AG7XXX_ETH_CFG_SW_PHY_SWAP BIT(7)
#define AG7XXX_ETH_CFG_SW_ONLY_MODE BIT(6)
@@ -197,24 +221,33 @@ static int ag7xxx_switch_reg_read(struct mii_dev *bus, int reg, u32 *val)
u32 reg_addr;
u32 phy_temp;
u32 reg_temp;
+ u32 reg_temp_w = (reg & 0xfffffffc) >> 1;
u16 rv = 0;
int ret;
- if (priv->model == AG7XXX_MODEL_AG933X) {
+ if (priv->model == AG7XXX_MODEL_AG933X ||
+ priv->model == AG7XXX_MODEL_AG953X) {
phy_addr = 0x1f;
reg_addr = 0x10;
- } else if (priv->model == AG7XXX_MODEL_AG934X) {
+ } else if (priv->model == AG7XXX_MODEL_AG934X ||
+ priv->model == AG7XXX_MODEL_AG956X) {
phy_addr = 0x18;
reg_addr = 0x00;
} else
return -EINVAL;
- ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9);
+ if (priv->model == AG7XXX_MODEL_AG956X)
+ ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, (reg >> 9) & 0x1ff);
+ else
+ ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9);
if (ret)
return ret;
phy_temp = ((reg >> 6) & 0x7) | 0x10;
- reg_temp = (reg >> 1) & 0x1e;
+ if (priv->model == AG7XXX_MODEL_AG956X)
+ reg_temp = reg_temp_w & 0x1f;
+ else
+ reg_temp = (reg >> 1) & 0x1e;
*val = 0;
ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 0, &rv);
@@ -222,7 +255,13 @@ static int ag7xxx_switch_reg_read(struct mii_dev *bus, int reg, u32 *val)
return ret;
*val |= rv;
- ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 1, &rv);
+ if (priv->model == AG7XXX_MODEL_AG956X) {
+ phy_temp = (((reg_temp_w + 1) >> 5) & 0x7) | 0x10;
+ reg_temp = (reg_temp_w + 1) & 0x1f;
+ ret = ag7xxx_switch_read(bus, phy_temp, reg_temp, &rv);
+ } else {
+ ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 1, &rv);
+ }
if (ret < 0)
return ret;
*val |= (rv << 16);
@@ -237,23 +276,34 @@ static int ag7xxx_switch_reg_write(struct mii_dev *bus, int reg, u32 val)
u32 reg_addr;
u32 phy_temp;
u32 reg_temp;
+ u32 reg_temp_w = (reg & 0xfffffffc) >> 1;
int ret;
- if (priv->model == AG7XXX_MODEL_AG933X) {
+ if (priv->model == AG7XXX_MODEL_AG933X ||
+ priv->model == AG7XXX_MODEL_AG953X) {
phy_addr = 0x1f;
reg_addr = 0x10;
- } else if (priv->model == AG7XXX_MODEL_AG934X) {
+ } else if (priv->model == AG7XXX_MODEL_AG934X ||
+ priv->model == AG7XXX_MODEL_AG956X) {
phy_addr = 0x18;
reg_addr = 0x00;
} else
return -EINVAL;
- ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9);
+ if (priv->model == AG7XXX_MODEL_AG956X)
+ ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, (reg >> 9) & 0x1ff);
+ else
+ ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9);
if (ret)
return ret;
- phy_temp = ((reg >> 6) & 0x7) | 0x10;
- reg_temp = (reg >> 1) & 0x1e;
+ if (priv->model == AG7XXX_MODEL_AG956X) {
+ reg_temp = (reg_temp_w + 1) & 0x1f;
+ phy_temp = (((reg_temp_w + 1) >> 5) & 0x7) | 0x10;
+ } else {
+ phy_temp = ((reg >> 6) & 0x7) | 0x10;
+ reg_temp = (reg >> 1) & 0x1e;
+ }
/*
* The switch on AR933x has some special register behavior, which
@@ -272,10 +322,18 @@ static int ag7xxx_switch_reg_write(struct mii_dev *bus, int reg, u32 val)
if (ret < 0)
return ret;
} else {
- ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16);
+ if (priv->model == AG7XXX_MODEL_AG956X)
+ ret = ag7xxx_switch_write(bus, phy_temp, reg_temp, val >> 16);
+ else
+ ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16);
if (ret < 0)
return ret;
+ if (priv->model == AG7XXX_MODEL_AG956X) {
+ phy_temp = ((reg_temp_w >> 5) & 0x7) | 0x10;
+ reg_temp = reg_temp_w & 0x1f;
+ }
+
ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 0, val & 0xffff);
if (ret < 0)
return ret;
@@ -598,10 +656,19 @@ static int ag7xxx_mii_setup(struct udevice *dev)
return 0;
}
- if (priv->model == AG7XXX_MODEL_AG934X) {
- writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | 0x4,
+ if (priv->model == AG7XXX_MODEL_AG934X)
+ reg = 0x4;
+ else if (priv->model == AG7XXX_MODEL_AG953X)
+ reg = 0x2;
+ else if (priv->model == AG7XXX_MODEL_AG956X)
+ reg = 0x7;
+
+ if (priv->model == AG7XXX_MODEL_AG934X ||
+ priv->model == AG7XXX_MODEL_AG953X ||
+ priv->model == AG7XXX_MODEL_AG956X) {
+ writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | reg,
priv->regs + AG7XXX_ETH_MII_MGMT_CFG);
- writel(0x4, priv->regs + AG7XXX_ETH_MII_MGMT_CFG);
+ writel(reg, priv->regs + AG7XXX_ETH_MII_MGMT_CFG);
return 0;
}
@@ -698,14 +765,126 @@ static int ag933x_phy_setup_lan(struct udevice *dev)
return 0;
}
+static int ag953x_phy_setup_wan(struct udevice *dev)
+{
+ int ret;
+ u32 reg = 0;
+ struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
+
+ /* Set wan port connect to GE0 */
+ ret = ag7xxx_switch_reg_read(priv->bus, 0x8, &reg);
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x8, reg | BIT(28));
+ if (ret)
+ return ret;
+
+ /* Configure switch port 4 (GMAC0) */
+ ret = ag7xxx_switch_write(priv->bus, 4, MII_BMCR, 0x9000);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ag953x_phy_setup_lan(struct udevice *dev)
+{
+ struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
+ int i, ret;
+ u32 reg = 0;
+
+ /* Reset the switch */
+ ret = ag7xxx_switch_reg_read(priv->bus, 0, &reg);
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0, reg | BIT(31));
+ if (ret)
+ return ret;
+
+ do {
+ ret = ag7xxx_switch_reg_read(priv->bus, 0, &reg);
+ if (ret)
+ return ret;
+ } while (reg & BIT(31));
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x100, 0x4e);
+ if (ret)
+ return ret;
+
+ /* Set GMII mode */
+ ret = ag7xxx_switch_reg_read(priv->bus, 0x4, &reg);
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x4, reg | BIT(6));
+ if (ret)
+ return ret;
+
+ /* Configure switch ports 0...4 (GMAC1) */
+ for (i = 0; i < 5; i++) {
+ ret = ag7xxx_switch_write(priv->bus, i, MII_BMCR, 0x9000);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < 5; i++) {
+ ret = ag7xxx_switch_reg_write(priv->bus, (i + 2) * 0x100, BIT(9));
+ if (ret)
+ return ret;
+ }
+
+ /* QM Control */
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x38, 0xc000050e);
+ if (ret)
+ return ret;
+
+ /* Disable Atheros header */
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x104, 0x4004);
+ if (ret)
+ return ret;
+
+ /* Tag priority mapping */
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x70, 0xfa50);
+ if (ret)
+ return ret;
+
+ /* Enable ARP packets to the CPU */
+ ret = ag7xxx_switch_reg_read(priv->bus, 0x5c, &reg);
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x5c, reg | 0x100000);
+ if (ret)
+ return ret;
+
+ /* Enable broadcast packets to the CPU */
+ ret = ag7xxx_switch_reg_read(priv->bus, 0x2c, &reg);
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x2c, reg | BIT(25) | BIT(26));
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int ag933x_phy_setup_reset_set(struct udevice *dev, int port)
{
struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
int ret;
- ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_PAUSE_CAP |
- ADVERTISE_PAUSE_ASYM);
+ if (priv->model == AG7XXX_MODEL_AG953X ||
+ priv->model == AG7XXX_MODEL_AG956X) {
+ ret = ag7xxx_switch_write(priv->bus, port, MII_ADVERTISE,
+ ADVERTISE_ALL);
+ } else {
+ ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_ADVERTISE,
+ ADVERTISE_ALL | ADVERTISE_PAUSE_CAP |
+ ADVERTISE_PAUSE_ASYM);
+ }
if (ret)
return ret;
@@ -714,8 +893,18 @@ static int ag933x_phy_setup_reset_set(struct udevice *dev, int port)
ADVERTISE_1000FULL);
if (ret)
return ret;
+ } else if (priv->model == AG7XXX_MODEL_AG956X) {
+ ret = ag7xxx_switch_write(priv->bus, port, MII_CTRL1000,
+ ADVERTISE_1000FULL);
+ if (ret)
+ return ret;
}
+ if (priv->model == AG7XXX_MODEL_AG953X ||
+ priv->model == AG7XXX_MODEL_AG956X)
+ return ag7xxx_switch_write(priv->bus, port, MII_BMCR,
+ BMCR_ANENABLE | BMCR_RESET);
+
return ag7xxx_mdio_write(priv->bus, port, 0, MII_BMCR,
BMCR_ANENABLE | BMCR_RESET);
}
@@ -724,13 +913,24 @@ static int ag933x_phy_setup_reset_fin(struct udevice *dev, int port)
{
struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
int ret;
+ u16 reg;
- do {
- ret = ag7xxx_mdio_read(priv->bus, port, 0, MII_BMCR);
- if (ret < 0)
- return ret;
- mdelay(10);
- } while (ret & BMCR_RESET);
+ if (priv->model == AG7XXX_MODEL_AG953X ||
+ priv->model == AG7XXX_MODEL_AG956X) {
+ do {
+ ret = ag7xxx_switch_read(priv->bus, port, MII_BMCR, &reg);
+ if (ret < 0)
+ return ret;
+ mdelay(10);
+ } while (reg & BMCR_RESET);
+ } else {
+ do {
+ ret = ag7xxx_mdio_read(priv->bus, port, 0, MII_BMCR);
+ if (ret < 0)
+ return ret;
+ mdelay(10);
+ } while (ret & BMCR_RESET);
+ }
return 0;
}
@@ -739,10 +939,13 @@ static int ag933x_phy_setup_common(struct udevice *dev)
{
struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
int i, ret, phymax;
+ u16 reg;
if (priv->model == AG7XXX_MODEL_AG933X)
phymax = 4;
- else if (priv->model == AG7XXX_MODEL_AG934X)
+ else if (priv->model == AG7XXX_MODEL_AG934X ||
+ priv->model == AG7XXX_MODEL_AG953X ||
+ priv->model == AG7XXX_MODEL_AG956X)
phymax = 5;
else
return -EINVAL;
@@ -757,7 +960,10 @@ static int ag933x_phy_setup_common(struct udevice *dev)
return ret;
/* Read out link status */
- ret = ag7xxx_mdio_read(priv->bus, phymax, 0, MII_MIPSCR);
+ if (priv->model == AG7XXX_MODEL_AG953X)
+ ret = ag7xxx_switch_read(priv->bus, phymax, MII_MIPSCR, &reg);
+ else
+ ret = ag7xxx_mdio_read(priv->bus, phymax, 0, MII_MIPSCR);
if (ret < 0)
return ret;
@@ -779,7 +985,11 @@ static int ag933x_phy_setup_common(struct udevice *dev)
for (i = 0; i < phymax; i++) {
/* Read out link status */
- ret = ag7xxx_mdio_read(priv->bus, i, 0, MII_MIPSCR);
+ if (priv->model == AG7XXX_MODEL_AG953X ||
+ priv->model == AG7XXX_MODEL_AG956X)
+ ret = ag7xxx_switch_read(priv->bus, i, MII_MIPSCR, &reg);
+ else
+ ret = ag7xxx_mdio_read(priv->bus, i, 0, MII_MIPSCR);
if (ret < 0)
return ret;
}
@@ -841,6 +1051,63 @@ static int ag934x_phy_setup(struct udevice *dev)
return 0;
}
+static int ag956x_phy_setup(struct udevice *dev)
+{
+ struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
+ int i, ret;
+ u32 reg, ctrl;
+
+ ret = ag7xxx_switch_reg_read(priv->bus, 0x0, &reg);
+ if (ret)
+ return ret;
+ if ((reg & 0xffff) >= 0x1301)
+ ctrl = 0xc74164de;
+ else
+ ctrl = 0xc74164d0;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x4, BIT(7));
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0xe0, ctrl);
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x624, 0x7f7f7f7f);
+ if (ret)
+ return ret;
+
+ /*
+ * Values suggested by the switch team when s17 in sgmii
+ * configuration. 0x10(S17_PWS_REG) = 0x602613a0
+ */
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x10, 0x602613a0);
+ if (ret)
+ return ret;
+
+ ret = ag7xxx_switch_reg_write(priv->bus, 0x7c, 0x0000007e);
+ if (ret)
+ return ret;
+
+ /* AR8337/AR8334 v1.0 fixup */
+ ret = ag7xxx_switch_reg_read(priv->bus, 0, &reg);
+ if (ret)
+ return ret;
+ if ((reg & 0xffff) == 0x1301) {
+ for (i = 0; i < 5; i++) {
+ /* Turn on Gigabit clock */
+ ret = ag7xxx_switch_write(priv->bus, i, 0x1d, 0x3d);
+ if (ret)
+ return ret;
+ ret = ag7xxx_switch_write(priv->bus, i, 0x1e, 0x6820);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
static int ag7xxx_mac_probe(struct udevice *dev)
{
struct ar7xxx_eth_priv *priv = dev_get_priv(dev);
@@ -858,8 +1125,15 @@ static int ag7xxx_mac_probe(struct udevice *dev)
ret = ag933x_phy_setup_wan(dev);
else
ret = ag933x_phy_setup_lan(dev);
+ } else if (priv->model == AG7XXX_MODEL_AG953X) {
+ if (priv->interface == PHY_INTERFACE_MODE_RMII)
+ ret = ag953x_phy_setup_wan(dev);
+ else
+ ret = ag953x_phy_setup_lan(dev);
} else if (priv->model == AG7XXX_MODEL_AG934X) {
ret = ag934x_phy_setup(dev);
+ } else if (priv->model == AG7XXX_MODEL_AG956X) {
+ ret = ag956x_phy_setup(dev);
} else {
return -EINVAL;
}
@@ -997,6 +1271,8 @@ static int ag7xxx_eth_ofdata_to_platdata(struct udevice *dev)
static const struct udevice_id ag7xxx_eth_ids[] = {
{ .compatible = "qca,ag933x-mac", .data = AG7XXX_MODEL_AG933X },
{ .compatible = "qca,ag934x-mac", .data = AG7XXX_MODEL_AG934X },
+ { .compatible = "qca,ag953x-mac", .data = AG7XXX_MODEL_AG953X },
+ { .compatible = "qca,ag956x-mac", .data = AG7XXX_MODEL_AG956X },
{ }
};
diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig
index 88e5a97c4bf..6359d0b6101 100644
--- a/drivers/net/mscc_eswitch/Kconfig
+++ b/drivers/net/mscc_eswitch/Kconfig
@@ -15,3 +15,17 @@ config MSCC_LUTON_SWITCH
select PHYLIB
help
This driver supports the Luton network switch device.
+
+config MSCC_JR2_SWITCH
+ bool "Jaguar2 switch driver"
+ depends on DM_ETH && ARCH_MSCC
+ select PHYLIB
+ help
+ This driver supports the Jaguar2 network switch device.
+
+config MSCC_SERVALT_SWITCH
+ bool "Servalt switch driver"
+ depends on DM_ETH && ARCH_MSCC
+ select PHYLIB
+ help
+ This driver supports the Servalt network switch device.
diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
index 751a839a5f0..bffd8ec77b0 100644
--- a/drivers/net/mscc_eswitch/Makefile
+++ b/drivers/net/mscc_eswitch/Makefile
@@ -1,3 +1,5 @@
obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o
+obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o
+obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o
diff --git a/drivers/net/mscc_eswitch/jr2_switch.c b/drivers/net/mscc_eswitch/jr2_switch.c
new file mode 100644
index 00000000000..60d408f1c75
--- /dev/null
+++ b/drivers/net/mscc_eswitch/jr2_switch.c
@@ -0,0 +1,1075 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/of_access.h>
+#include <dm/of_addr.h>
+#include <fdt_support.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <miiphy.h>
+#include <net.h>
+#include <wait_bit.h>
+
+#include <dt-bindings/mscc/jr2_data.h>
+#include "mscc_xfer.h"
+
+#define GCB_MIIM_MII_STATUS 0x0
+#define GCB_MIIM_STAT_BUSY BIT(3)
+#define GCB_MIIM_MII_CMD 0x8
+#define GCB_MIIM_MII_CMD_SCAN BIT(0)
+#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
+#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
+#define GCB_MIIM_MII_CMD_SINGLE_SCAN BIT(3)
+#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
+#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
+#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
+#define GCB_MIIM_MII_CMD_VLD BIT(31)
+#define GCB_MIIM_DATA 0xC
+#define GCB_MIIM_DATA_ERROR (0x3 << 16)
+
+#define ANA_AC_RAM_CTRL_RAM_INIT 0x94358
+#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x94370
+
+#define ANA_CL_PORT_VLAN_CFG(x) (0x24018 + 0xc8 * (x))
+#define ANA_CL_PORT_VLAN_CFG_AWARE_ENA BIT(19)
+#define ANA_CL_PORT_VLAN_CFG_POP_CNT(x) ((x) << 17)
+
+#define ANA_L2_COMMON_FWD_CFG 0x8a2a8
+#define ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6)
+
+#define ASM_CFG_STAT_CFG 0x3508
+#define ASM_CFG_PORT(x) (0x36c4 + 0x4 * (x))
+#define ASM_CFG_PORT_NO_PREAMBLE_ENA BIT(8)
+#define ASM_CFG_PORT_INJ_FORMAT_CFG(x) ((x) << 1)
+#define ASM_RAM_CTRL_RAM_INIT 0x39b8
+
+#define DEV_DEV_CFG_DEV_RST_CTRL 0x0
+#define DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x) ((x) << 20)
+#define DEV_MAC_CFG_MAC_ENA 0x1c
+#define DEV_MAC_CFG_MAC_ENA_RX_ENA BIT(4)
+#define DEV_MAC_CFG_MAC_ENA_TX_ENA BIT(0)
+#define DEV_MAC_CFG_MAC_IFG 0x34
+#define DEV_MAC_CFG_MAC_IFG_TX_IFG(x) ((x) << 8)
+#define DEV_MAC_CFG_MAC_IFG_RX_IFG2(x) ((x) << 4)
+#define DEV_MAC_CFG_MAC_IFG_RX_IFG1(x) (x)
+#define DEV_PCS1G_CFG_PCS1G_CFG 0x40
+#define DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA BIT(0)
+#define DEV_PCS1G_CFG_PCS1G_MODE 0x44
+#define DEV_PCS1G_CFG_PCS1G_SD 0x48
+#define DEV_PCS1G_CFG_PCS1G_ANEG 0x4c
+#define DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16)
+
+#define DSM_RAM_CTRL_RAM_INIT 0x8
+
+#define HSIO_ANA_SERDES1G_DES_CFG 0xac
+#define HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x) ((x) << 1)
+#define HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x) ((x) << 5)
+#define HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x) ((x) << 8)
+#define HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x) ((x) << 13)
+#define HSIO_ANA_SERDES1G_IB_CFG 0xb0
+#define HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x) (x)
+#define HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x) ((x) << 6)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP BIT(9)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV BIT(11)
+#define HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM BIT(13)
+#define HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x) ((x) << 19)
+#define HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x) ((x) << 24)
+#define HSIO_ANA_SERDES1G_OB_CFG 0xb4
+#define HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x) (x)
+#define HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x) ((x) << 4)
+#define HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x) ((x) << 10)
+#define HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x) ((x) << 13)
+#define HSIO_ANA_SERDES1G_OB_CFG_SLP(x) ((x) << 17)
+#define HSIO_ANA_SERDES1G_SER_CFG 0xb8
+#define HSIO_ANA_SERDES1G_COMMON_CFG 0xbc
+#define HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE BIT(0)
+#define HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE BIT(18)
+#define HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST BIT(31)
+#define HSIO_ANA_SERDES1G_PLL_CFG 0xc0
+#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA BIT(7)
+#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 8)
+#define HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2 BIT(21)
+#define HSIO_DIG_SERDES1G_DFT_CFG0 0xc8
+#define HSIO_DIG_SERDES1G_TP_CFG 0xd4
+#define HSIO_DIG_SERDES1G_MISC_CFG 0xdc
+#define HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST BIT(0)
+#define HSIO_MCB_SERDES1G_CFG 0xe8
+#define HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT BIT(31)
+#define HSIO_MCB_SERDES1G_CFG_ADDR(x) (x)
+
+#define HSIO_ANA_SERDES6G_DES_CFG 0x11c
+#define HSIO_ANA_SERDES6G_DES_CFG_SWAP_ANA BIT(0)
+#define HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(x) ((x) << 1)
+#define HSIO_ANA_SERDES6G_DES_CFG_SWAP_HYST BIT(4)
+#define HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(x) ((x) << 5)
+#define HSIO_ANA_SERDES6G_DES_CFG_CPMD_SEL(x) ((x) << 8)
+#define HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(x) ((x) << 10)
+#define HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(x) ((x) << 13)
+#define HSIO_ANA_SERDES6G_IB_CFG 0x120
+#define HSIO_ANA_SERDES6G_IB_CFG_REG_ENA BIT(0)
+#define HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA BIT(1)
+#define HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA BIT(2)
+#define HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(x) ((x) << 3)
+#define HSIO_ANA_SERDES6G_IB_CFG_CONCUR BIT(4)
+#define HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA BIT(5)
+#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(x) ((x) << 7)
+#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(x) ((x) << 9)
+#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(x) ((x) << 11)
+#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(x) ((x) << 13)
+#define HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(x) ((x) << 15)
+#define HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(x) ((x) << 18)
+#define HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(x) ((x) << 20)
+#define HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(x) ((x) << 24)
+#define HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL BIT(28)
+#define HSIO_ANA_SERDES6G_IB_CFG_SOFSI(x) ((x) << 29)
+#define HSIO_ANA_SERDES6G_IB_CFG1 0x124
+#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET BIT(4)
+#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP BIT(5)
+#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID BIT(6)
+#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP BIT(7)
+#define HSIO_ANA_SERDES6G_IB_CFG1_SCALY(x) ((x) << 8)
+#define HSIO_ANA_SERDES6G_IB_CFG1_TSDET(x) ((x) << 12)
+#define HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(x) ((x) << 17)
+#define HSIO_ANA_SERDES6G_IB_CFG2 0x128
+#define HSIO_ANA_SERDES6G_IB_CFG2_UREG(x) (x)
+#define HSIO_ANA_SERDES6G_IB_CFG2_UMAX(x) ((x) << 3)
+#define HSIO_ANA_SERDES6G_IB_CFG2_TCALV(x) ((x) << 5)
+#define HSIO_ANA_SERDES6G_IB_CFG2_OCALS(x) ((x) << 10)
+#define HSIO_ANA_SERDES6G_IB_CFG2_OINFS(x) ((x) << 16)
+#define HSIO_ANA_SERDES6G_IB_CFG2_OINFI(x) ((x) << 22)
+#define HSIO_ANA_SERDES6G_IB_CFG2_TINFV(x) ((x) << 27)
+#define HSIO_ANA_SERDES6G_IB_CFG3 0x12c
+#define HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(x) (x)
+#define HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(x) ((x) << 6)
+#define HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(x) ((x) << 12)
+#define HSIO_ANA_SERDES6G_IB_CFG3_INI_HP(x) ((x) << 18)
+#define HSIO_ANA_SERDES6G_IB_CFG4 0x130
+#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_OFFSET(x) (x)
+#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_LP(x) ((x) << 6)
+#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_MID(x) ((x) << 12)
+#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_HP(x) ((x) << 18)
+#define HSIO_ANA_SERDES6G_IB_CFG5 0x134
+#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_OFFSET(x) (x)
+#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_LP(x) ((x) << 6)
+#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_MID(x) ((x) << 12)
+#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_HP(x) ((x) << 18)
+#define HSIO_ANA_SERDES6G_OB_CFG 0x138
+#define HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(x) (x)
+#define HSIO_ANA_SERDES6G_OB_CFG_SR(x) ((x) << 4)
+#define HSIO_ANA_SERDES6G_OB_CFG_SR_H BIT(8)
+#define HSIO_ANA_SERDES6G_OB_CFG_SEL_RCTRL BIT(9)
+#define HSIO_ANA_SERDES6G_OB_CFG_R_COR BIT(10)
+#define HSIO_ANA_SERDES6G_OB_CFG_POST1(x) ((x) << 11)
+#define HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_PDR BIT(16)
+#define HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_MUX BIT(17)
+#define HSIO_ANA_SERDES6G_OB_CFG_PREC(x) ((x) << 18)
+#define HSIO_ANA_SERDES6G_OB_CFG_POST0(x) ((x) << 23)
+#define HSIO_ANA_SERDES6G_OB_CFG_POL BIT(29)
+#define HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(x) ((x) << 30)
+#define HSIO_ANA_SERDES6G_OB_CFG_IDLE BIT(31)
+#define HSIO_ANA_SERDES6G_OB_CFG1 0x13c
+#define HSIO_ANA_SERDES6G_OB_CFG1_LEV(x) (x)
+#define HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(x) ((x) << 6)
+#define HSIO_ANA_SERDES6G_SER_CFG 0x140
+#define HSIO_ANA_SERDES6G_COMMON_CFG 0x144
+#define HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(x) (x)
+#define HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(x) (x << 2)
+#define HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE BIT(14)
+#define HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST BIT(16)
+#define HSIO_ANA_SERDES6G_PLL_CFG 0x148
+#define HSIO_ANA_SERDES6G_PLL_CFG_ROT_FRQ BIT(0)
+#define HSIO_ANA_SERDES6G_PLL_CFG_ROT_DIR BIT(1)
+#define HSIO_ANA_SERDES6G_PLL_CFG_RB_DATA_SEL BIT(2)
+#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_OOR_RECAL_ENA BIT(3)
+#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_FORCE_SET_ENA BIT(4)
+#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA BIT(5)
+#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 6)
+#define HSIO_ANA_SERDES6G_PLL_CFG_ENA_ROT BIT(14)
+#define HSIO_ANA_SERDES6G_PLL_CFG_DIV4 BIT(15)
+#define HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(x) ((x) << 16)
+#define HSIO_DIG_SERDES6G_MISC_CFG 0x108
+#define HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST BIT(0)
+#define HSIO_MCB_SERDES6G_CFG 0x168
+#define HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT BIT(31)
+#define HSIO_MCB_SERDES6G_CFG_ADDR(x) (x)
+#define HSIO_HW_CFGSTAT_HW_CFG 0x16c
+
+#define LRN_COMMON_ACCESS_CTRL 0x0
+#define LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT BIT(0)
+#define LRN_COMMON_MAC_ACCESS_CFG0 0x4
+#define LRN_COMMON_MAC_ACCESS_CFG1 0x8
+#define LRN_COMMON_MAC_ACCESS_CFG2 0xc
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x) (x)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x) ((x) << 12)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD BIT(15)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED BIT(16)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY BIT(23)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x) ((x) << 24)
+
+#define QFWD_SYSTEM_SWITCH_PORT_MODE(x) (0x4 * (x))
+#define QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA BIT(17)
+
+#define QS_XTR_GRP_CFG(x) (0x0 + 4 * (x))
+#define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4)
+
+#define QSYS_SYSTEM_RESET_CFG 0xf0
+#define QSYS_CALCFG_CAL_AUTO(x) (0x3d4 + 4 * (x))
+#define QSYS_CALCFG_CAL_CTRL 0x3e8
+#define QSYS_CALCFG_CAL_CTRL_CAL_MODE(x) ((x) << 11)
+#define QSYS_RAM_CTRL_RAM_INIT 0x3ec
+
+#define REW_RAM_CTRL_RAM_INIT 0x53528
+
+#define VOP_RAM_CTRL_RAM_INIT 0x43638
+
+#define XTR_VALID_BYTES(x) (4 - ((x) & 3))
+#define MAC_VID 0
+#define CPU_PORT 53
+#define IFH_LEN 7
+#define JR2_BUF_CELL_SZ 60
+#define ETH_ALEN 6
+#define PGID_BROADCAST 510
+#define PGID_UNICAST 511
+
+static const char * const regs_names[] = {
+ "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
+ "port8", "port9", "port10", "port11", "port12", "port13", "port14",
+ "port15", "port16", "port17", "port18", "port19", "port20", "port21",
+ "port22", "port23", "port24", "port25", "port26", "port27", "port28",
+ "port29", "port30", "port31", "port32", "port33", "port34", "port35",
+ "port36", "port37", "port38", "port39", "port40", "port41", "port42",
+ "port43", "port44", "port45", "port46", "port47",
+ "ana_ac", "ana_cl", "ana_l2", "asm", "hsio", "lrn",
+ "qfwd", "qs", "qsys", "rew",
+};
+
+#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
+#define MAX_PORT 48
+
+enum jr2_ctrl_regs {
+ ANA_AC = MAX_PORT,
+ ANA_CL,
+ ANA_L2,
+ ASM,
+ HSIO,
+ LRN,
+ QFWD,
+ QS,
+ QSYS,
+ REW,
+};
+
+#define JR2_MIIM_BUS_COUNT 3
+
+struct jr2_phy_port_t {
+ size_t phy_addr;
+ struct mii_dev *bus;
+ u8 serdes_index;
+ u8 phy_mode;
+};
+
+struct jr2_private {
+ void __iomem *regs[REGS_NAMES_COUNT];
+ struct mii_dev *bus[JR2_MIIM_BUS_COUNT];
+ struct jr2_phy_port_t ports[MAX_PORT];
+};
+
+struct jr2_miim_dev {
+ void __iomem *regs;
+ phys_addr_t miim_base;
+ unsigned long miim_size;
+ struct mii_dev *bus;
+};
+
+static const unsigned long jr2_regs_qs[] = {
+ [MSCC_QS_XTR_RD] = 0x8,
+ [MSCC_QS_XTR_FLUSH] = 0x18,
+ [MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
+ [MSCC_QS_INJ_WR] = 0x2c,
+ [MSCC_QS_INJ_CTRL] = 0x34,
+};
+
+static struct jr2_miim_dev miim[JR2_MIIM_BUS_COUNT];
+static int miim_count = -1;
+
+static int mscc_miim_wait_ready(struct jr2_miim_dev *miim)
+{
+ unsigned long deadline;
+ u32 val;
+
+ deadline = timer_get_us() + 250000;
+
+ do {
+ val = readl(miim->regs + GCB_MIIM_MII_STATUS);
+ } while (timer_get_us() <= deadline && (val & GCB_MIIM_STAT_BUSY));
+
+ if (val & GCB_MIIM_STAT_BUSY)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
+ u32 val;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
+ miim->regs + GCB_MIIM_MII_CMD);
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ val = readl(miim->regs + GCB_MIIM_DATA);
+ if (val & GCB_MIIM_DATA_ERROR) {
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = val & 0xFFFF;
+ out:
+ return ret;
+}
+
+static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 val)
+{
+ struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret < 0)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
+ GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
+
+ out:
+ return ret;
+}
+
+static struct mii_dev *jr2_mdiobus_init(phys_addr_t miim_base,
+ unsigned long miim_size)
+{
+ struct mii_dev *bus;
+
+ bus = mdio_alloc();
+ if (!bus)
+ return NULL;
+
+ ++miim_count;
+ sprintf(bus->name, "miim-bus%d", miim_count);
+
+ miim[miim_count].regs = ioremap(miim_base, miim_size);
+ miim[miim_count].miim_base = miim_base;
+ miim[miim_count].miim_size = miim_size;
+ bus->priv = &miim[miim_count];
+ bus->read = mscc_miim_read;
+ bus->write = mscc_miim_write;
+
+ if (mdio_register(bus))
+ return NULL;
+
+ miim[miim_count].bus = bus;
+ return bus;
+}
+
+static void jr2_cpu_capture_setup(struct jr2_private *priv)
+{
+ /* ASM: No preamble and IFH prefix on CPU injected frames */
+ writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
+ ASM_CFG_PORT_INJ_FORMAT_CFG(1),
+ priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
+
+ /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
+ writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
+
+ /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
+ writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
+
+ /* Enable CPU port for any frame transfer */
+ setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
+ QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
+
+ /* Send a copy to CPU when found as forwarding entry */
+ setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
+ ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
+}
+
+static void jr2_port_init(struct jr2_private *priv, int port)
+{
+ void __iomem *regs = priv->regs[port];
+
+ /* Enable PCS */
+ writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
+ regs + DEV_PCS1G_CFG_PCS1G_CFG);
+
+ /* Disable Signal Detect */
+ writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
+
+ /* Enable MAC RX and TX */
+ writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
+ DEV_MAC_CFG_MAC_ENA_TX_ENA,
+ regs + DEV_MAC_CFG_MAC_ENA);
+
+ /* Clear sgmii_mode_ena */
+ writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
+
+ /*
+ * Clear sw_resolve_ena(bit 0) and set adv_ability to
+ * something meaningful just in case
+ */
+ writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
+ regs + DEV_PCS1G_CFG_PCS1G_ANEG);
+
+ /* Set MAC IFG Gaps */
+ writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
+ DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
+ DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
+ regs + DEV_MAC_CFG_MAC_IFG);
+
+ /* Set link speed and release all resets */
+ writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
+ regs + DEV_DEV_CFG_DEV_RST_CTRL);
+
+ /* Make VLAN aware for CPU traffic */
+ writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
+ ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
+ MAC_VID,
+ priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
+
+ /* Enable CPU port for any frame transfer */
+ setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
+ QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
+}
+
+static void serdes6g_write(void __iomem *base, u32 addr)
+{
+ u32 data;
+
+ writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
+ HSIO_MCB_SERDES6G_CFG_ADDR(addr),
+ base + HSIO_MCB_SERDES6G_CFG);
+
+ do {
+ data = readl(base + HSIO_MCB_SERDES6G_CFG);
+ } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
+}
+
+static void serdes6g_setup(void __iomem *base, uint32_t addr,
+ phy_interface_t interface)
+{
+ u32 ib_if_mode = 0;
+ u32 ib_qrate = 0;
+ u32 ib_cal_ena = 0;
+ u32 ib1_tsdet = 0;
+ u32 ob_lev = 0;
+ u32 ob_ena_cas = 0;
+ u32 ob_ena1v_mode = 0;
+ u32 des_bw_ana = 0;
+ u32 pll_fsm_ctrl_data = 0;
+
+ switch (interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ ib_if_mode = 1;
+ ib_qrate = 1;
+ ib_cal_ena = 1;
+ ib1_tsdet = 3;
+ ob_lev = 48;
+ ob_ena_cas = 2;
+ ob_ena1v_mode = 1;
+ des_bw_ana = 3;
+ pll_fsm_ctrl_data = 60;
+ break;
+ case PHY_INTERFACE_MODE_QSGMII:
+ ib_if_mode = 3;
+ ib1_tsdet = 16;
+ ob_lev = 24;
+ des_bw_ana = 5;
+ pll_fsm_ctrl_data = 120;
+ break;
+ default:
+ pr_err("Interface not supported\n");
+ return;
+ }
+
+ if (interface == PHY_INTERFACE_MODE_QSGMII)
+ writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
+
+ writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3),
+ base + HSIO_ANA_SERDES6G_COMMON_CFG);
+ writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) |
+ HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
+ base + HSIO_ANA_SERDES6G_PLL_CFG);
+ writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
+ HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+ HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+ HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+ HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+ base + HSIO_ANA_SERDES6G_IB_CFG);
+ writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
+ HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
+ HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) |
+ HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
+ base + HSIO_ANA_SERDES6G_IB_CFG1);
+ writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
+ base + HSIO_DIG_SERDES6G_MISC_CFG);
+
+ serdes6g_write(base, addr);
+
+ writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
+ HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+ HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+ HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+ HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+ base + HSIO_ANA_SERDES6G_IB_CFG);
+ writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
+ HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
+ HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) |
+ HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
+ base + HSIO_ANA_SERDES6G_IB_CFG1);
+
+ writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG);
+ writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) |
+ HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) |
+ HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE |
+ HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST,
+ base + HSIO_ANA_SERDES6G_COMMON_CFG);
+ writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
+ base + HSIO_DIG_SERDES6G_MISC_CFG);
+
+ writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) |
+ HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
+ HSIO_ANA_SERDES6G_OB_CFG_SR_H |
+ HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
+ HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
+ writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) |
+ HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas),
+ base + HSIO_ANA_SERDES6G_OB_CFG1);
+
+ writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) |
+ HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) |
+ HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) |
+ HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6),
+ base + HSIO_ANA_SERDES6G_DES_CFG);
+ writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
+ HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
+ base + HSIO_ANA_SERDES6G_PLL_CFG);
+
+ serdes6g_write(base, addr);
+
+ /* set pll_fsm_ena = 1 */
+ writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA |
+ HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
+ HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
+ base + HSIO_ANA_SERDES6G_PLL_CFG);
+
+ serdes6g_write(base, addr);
+
+ /* wait 20ms for pll bringup */
+ mdelay(20);
+
+ /* start IB calibration by setting ib_cal_ena and clearing lane_rst */
+ writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
+ HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
+ HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+ HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+ HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+ HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+ base + HSIO_ANA_SERDES6G_IB_CFG);
+ writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG);
+
+ serdes6g_write(base, addr);
+
+ /* wait 60 for calibration */
+ mdelay(60);
+
+ /* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */
+ writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
+ HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
+ HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
+ HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
+ HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
+ HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
+ HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
+ base + HSIO_ANA_SERDES6G_IB_CFG);
+ writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
+ HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
+ HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
+ HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) |
+ HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
+ base + HSIO_ANA_SERDES6G_IB_CFG1);
+
+ serdes6g_write(base, addr);
+}
+
+static void serdes1g_write(void __iomem *base, u32 addr)
+{
+ u32 data;
+
+ writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
+ HSIO_MCB_SERDES1G_CFG_ADDR(addr),
+ base + HSIO_MCB_SERDES1G_CFG);
+
+ do {
+ data = readl(base + HSIO_MCB_SERDES1G_CFG);
+ } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
+}
+
+static void serdes1g_setup(void __iomem *base, uint32_t addr,
+ phy_interface_t interface)
+{
+ writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
+ writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG);
+ writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
+ writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
+ HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
+ HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
+ HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
+ HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
+ base + HSIO_ANA_SERDES1G_OB_CFG);
+ writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) |
+ HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) |
+ HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
+ HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV |
+ HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
+ HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) |
+ HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
+ base + HSIO_ANA_SERDES1G_IB_CFG);
+ writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
+ HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
+ HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
+ HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
+ base + HSIO_ANA_SERDES1G_DES_CFG);
+ writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
+ base + HSIO_DIG_SERDES1G_MISC_CFG);
+ writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
+ HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) |
+ HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
+ base + HSIO_ANA_SERDES1G_PLL_CFG);
+ writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
+ HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
+ base + HSIO_ANA_SERDES1G_COMMON_CFG);
+
+ serdes1g_write(base, addr);
+
+ setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
+ HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
+
+ serdes1g_write(base, addr);
+
+ clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
+ HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
+
+ serdes1g_write(base, addr);
+}
+
+static int ram_init(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+
+ if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
+ printf("Timeout in memory reset, reg = 0x%08x\n", val);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int jr2_switch_init(struct jr2_private *priv)
+{
+ /* Initialize memories */
+ ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
+ ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
+ ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
+ ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
+
+ /* Reset counters */
+ writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
+ writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
+
+ /* Enable switch-core and queue system */
+ writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
+
+ return 0;
+}
+
+static void jr2_switch_config(struct jr2_private *priv)
+{
+ writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0));
+ writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1));
+ writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2));
+ writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3));
+
+ writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
+ QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
+ priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
+}
+
+static int jr2_initialize(struct jr2_private *priv)
+{
+ int ret, i;
+
+ /* Initialize switch memories, enable core */
+ ret = jr2_switch_init(priv);
+ if (ret)
+ return ret;
+
+ jr2_switch_config(priv);
+
+ for (i = 0; i < MAX_PORT; i++)
+ jr2_port_init(priv, i);
+
+ jr2_cpu_capture_setup(priv);
+
+ return 0;
+}
+
+static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
+{
+ if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
+ LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
+ false, 2000, false))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int jr2_mac_table_add(struct jr2_private *priv,
+ const unsigned char mac[ETH_ALEN], int pgid)
+{
+ u32 macl = 0, mach = 0;
+
+ /*
+ * Set the MAC address to handle and the vlan associated in a format
+ * understood by the hardware.
+ */
+ mach |= MAC_VID << 16;
+ mach |= ((u32)mac[0]) << 8;
+ mach |= ((u32)mac[1]) << 0;
+ macl |= ((u32)mac[2]) << 24;
+ macl |= ((u32)mac[3]) << 16;
+ macl |= ((u32)mac[4]) << 8;
+ macl |= ((u32)mac[5]) << 0;
+
+ writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
+ writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
+
+ writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
+ priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
+
+ writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
+ priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
+
+ return jr2_vlant_wait_for_completion(priv);
+}
+
+static int jr2_write_hwaddr(struct udevice *dev)
+{
+ struct jr2_private *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
+}
+
+static void serdes_setup(struct jr2_private *priv)
+{
+ size_t mask;
+ int i = 0;
+
+ for (i = 0; i < MAX_PORT; ++i) {
+ if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
+ continue;
+
+ mask = BIT(priv->ports[i].serdes_index);
+ if (priv->ports[i].serdes_index < SERDES1G_MAX) {
+ serdes1g_setup(priv->regs[HSIO], mask,
+ priv->ports[i].phy_mode);
+ } else {
+ mask >>= SERDES6G(0);
+ serdes6g_setup(priv->regs[HSIO], mask,
+ priv->ports[i].phy_mode);
+ }
+ }
+}
+
+static int jr2_start(struct udevice *dev)
+{
+ struct jr2_private *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff };
+ int ret;
+
+ ret = jr2_initialize(priv);
+ if (ret)
+ return ret;
+
+ /* Set MAC address tables entries for CPU redirection */
+ ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
+ if (ret)
+ return ret;
+
+ ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
+ if (ret)
+ return ret;
+
+ serdes_setup(priv);
+
+ return 0;
+}
+
+static void jr2_stop(struct udevice *dev)
+{
+}
+
+static int jr2_send(struct udevice *dev, void *packet, int length)
+{
+ struct jr2_private *priv = dev_get_priv(dev);
+ u32 ifh[IFH_LEN];
+ u32 *buf = packet;
+
+ memset(ifh, '\0', IFH_LEN);
+
+ /* Set DST PORT_MASK */
+ ifh[0] = htonl(0);
+ ifh[1] = htonl(0x1FFFFF);
+ ifh[2] = htonl(~0);
+ /* Set DST_MODE to INJECT and UPDATE_FCS */
+ ifh[5] = htonl(0x4c0);
+
+ return mscc_send(priv->regs[QS], jr2_regs_qs,
+ ifh, IFH_LEN, buf, length);
+}
+
+static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct jr2_private *priv = dev_get_priv(dev);
+ u32 *rxbuf = (u32 *)net_rx_packets[0];
+ int byte_cnt = 0;
+
+ byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
+ false);
+
+ *packetp = net_rx_packets[0];
+
+ return byte_cnt;
+}
+
+static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
+{
+ int i = 0;
+
+ for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
+ if (miim[i].miim_base == base && miim[i].miim_size == size)
+ return miim[i].bus;
+
+ return NULL;
+}
+
+static void add_port_entry(struct jr2_private *priv, size_t index,
+ size_t phy_addr, struct mii_dev *bus,
+ u8 serdes_index, u8 phy_mode)
+{
+ priv->ports[index].phy_addr = phy_addr;
+ priv->ports[index].bus = bus;
+ priv->ports[index].serdes_index = serdes_index;
+ priv->ports[index].phy_mode = phy_mode;
+}
+
+static int jr2_probe(struct udevice *dev)
+{
+ struct jr2_private *priv = dev_get_priv(dev);
+ int i;
+ int ret;
+ struct resource res;
+ fdt32_t faddr;
+ phys_addr_t addr_base;
+ unsigned long addr_size;
+ ofnode eth_node, node, mdio_node;
+ size_t phy_addr;
+ struct mii_dev *bus;
+ struct ofnode_phandle_args phandle;
+ struct phy_device *phy;
+
+ if (!priv)
+ return -EINVAL;
+
+ /* Get registers and map them to the private structure */
+ for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
+ priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
+ if (!priv->regs[i]) {
+ debug
+ ("Error can't get regs base addresses for %s\n",
+ regs_names[i]);
+ return -ENOMEM;
+ }
+ }
+
+ /* Initialize miim buses */
+ memset(&miim, 0x0, sizeof(struct jr2_miim_dev) * JR2_MIIM_BUS_COUNT);
+
+ /* iterate all the ports and find out on which bus they are */
+ i = 0;
+ eth_node = dev_read_first_subnode(dev);
+ for (node = ofnode_first_subnode(eth_node);
+ ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ if (ofnode_read_resource(node, 0, &res))
+ return -ENOMEM;
+ i = res.start;
+
+ ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
+ 0, 0, &phandle);
+ if (ret)
+ continue;
+
+ /* Get phy address on mdio bus */
+ if (ofnode_read_resource(phandle.node, 0, &res))
+ return -ENOMEM;
+ phy_addr = res.start;
+
+ /* Get mdio node */
+ mdio_node = ofnode_get_parent(phandle.node);
+
+ if (ofnode_read_resource(mdio_node, 0, &res))
+ return -ENOMEM;
+ faddr = cpu_to_fdt32(res.start);
+
+ addr_base = ofnode_translate_address(mdio_node, &faddr);
+ addr_size = res.end - res.start;
+
+ /* If the bus is new then create a new bus */
+ if (!get_mdiobus(addr_base, addr_size))
+ priv->bus[miim_count] =
+ jr2_mdiobus_init(addr_base, addr_size);
+
+ /* Connect mdio bus with the port */
+ bus = get_mdiobus(addr_base, addr_size);
+
+ /* Get serdes info */
+ ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
+ 3, 0, &phandle);
+ if (ret)
+ return -ENOMEM;
+
+ add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
+ phandle.args[2]);
+ }
+
+ for (i = 0; i < MAX_PORT; i++) {
+ if (!priv->ports[i].bus)
+ continue;
+
+ phy = phy_connect(priv->ports[i].bus,
+ priv->ports[i].phy_addr, dev,
+ PHY_INTERFACE_MODE_NONE);
+ if (phy)
+ board_phy_config(phy);
+ }
+
+ return 0;
+}
+
+static int jr2_remove(struct udevice *dev)
+{
+ struct jr2_private *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
+ mdio_unregister(priv->bus[i]);
+ mdio_free(priv->bus[i]);
+ }
+
+ return 0;
+}
+
+static const struct eth_ops jr2_ops = {
+ .start = jr2_start,
+ .stop = jr2_stop,
+ .send = jr2_send,
+ .recv = jr2_recv,
+ .write_hwaddr = jr2_write_hwaddr,
+};
+
+static const struct udevice_id mscc_jr2_ids[] = {
+ {.compatible = "mscc,vsc7454-switch" },
+ { /* Sentinel */ }
+};
+
+U_BOOT_DRIVER(jr2) = {
+ .name = "jr2-switch",
+ .id = UCLASS_ETH,
+ .of_match = mscc_jr2_ids,
+ .probe = jr2_probe,
+ .remove = jr2_remove,
+ .ops = &jr2_ops,
+ .priv_auto_alloc_size = sizeof(struct jr2_private),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/mscc_eswitch/ocelot_switch.c b/drivers/net/mscc_eswitch/ocelot_switch.c
index bf08c35ba04..815c2da2646 100644
--- a/drivers/net/mscc_eswitch/ocelot_switch.c
+++ b/drivers/net/mscc_eswitch/ocelot_switch.c
@@ -142,18 +142,16 @@ static const unsigned long ocelot_regs_ana_table[] = {
static struct mscc_miim_dev miim[NUM_PHY];
-static int mscc_miim_reset(struct mii_dev *bus)
+static void mscc_phy_reset(void)
{
- struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-
- if (miim->phy_regs) {
- writel(0, miim->phy_regs + PHY_CFG);
- writel(PHY_CFG_RST | PHY_CFG_COMMON_RST
- | PHY_CFG_ENA, miim->phy_regs + PHY_CFG);
- mdelay(500);
+ writel(0, miim[INTERNAL].phy_regs + PHY_CFG);
+ writel(PHY_CFG_RST | PHY_CFG_COMMON_RST
+ | PHY_CFG_ENA, miim[INTERNAL].phy_regs + PHY_CFG);
+ if (wait_for_bit_le32(miim[INTERNAL].phy_regs + PHY_STAT,
+ PHY_STAT_SUPERVISOR_COMPLETE,
+ true, 2000, false)) {
+ pr_err("Timeout in phy reset\n");
}
-
- return 0;
}
/* For now only setup the internal mdio bus */
@@ -194,7 +192,6 @@ static struct mii_dev *ocelot_mdiobus_init(struct udevice *dev)
miim[INTERNAL].phy_regs = ioremap(phy_base[PHY], phy_size[PHY]);
miim[INTERNAL].regs = ioremap(phy_base[MIIM], phy_size[MIIM]);
bus->priv = &miim[INTERNAL];
- bus->reset = mscc_miim_reset;
bus->read = mscc_miim_read;
bus->write = mscc_miim_write;
@@ -210,13 +207,8 @@ __weak void mscc_switch_reset(void)
static void ocelot_stop(struct udevice *dev)
{
- struct ocelot_private *priv = dev_get_priv(dev);
- int i;
-
mscc_switch_reset();
- for (i = 0; i < NUM_PHY; i++)
- if (priv->bus[i])
- mscc_miim_reset(priv->bus[i]);
+ mscc_phy_reset();
}
static void ocelot_cpu_capture_setup(struct ocelot_private *priv)
@@ -473,6 +465,7 @@ static int ocelot_probe(struct udevice *dev)
}
priv->bus[INTERNAL] = ocelot_mdiobus_init(dev);
+ mscc_phy_reset();
for (i = 0; i < 4; i++) {
phy_connect(priv->bus[INTERNAL], i, dev,
diff --git a/drivers/net/mscc_eswitch/servalt_switch.c b/drivers/net/mscc_eswitch/servalt_switch.c
new file mode 100644
index 00000000000..995c62309d2
--- /dev/null
+++ b/drivers/net/mscc_eswitch/servalt_switch.c
@@ -0,0 +1,622 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Microsemi Corporation
+ */
+
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/of_access.h>
+#include <dm/of_addr.h>
+#include <fdt_support.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <miiphy.h>
+#include <net.h>
+#include <wait_bit.h>
+
+#include "mscc_xfer.h"
+
+#define GCB_MIIM_MII_STATUS 0x0
+#define GCB_MIIM_STAT_BUSY BIT(3)
+#define GCB_MIIM_MII_CMD 0x8
+#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
+#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
+#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
+#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
+#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
+#define GCB_MIIM_MII_CMD_VLD BIT(31)
+#define GCB_MIIM_DATA 0xC
+#define GCB_MIIM_DATA_ERROR (0x3 << 16)
+
+#define PHY_CFG 0x0
+#define PHY_CFG_ENA 0x3
+#define PHY_CFG_COMMON_RST BIT(2)
+#define PHY_CFG_RST (0x3 << 3)
+#define PHY_STAT 0x4
+#define PHY_STAT_SUPERVISOR_COMPLETE BIT(0)
+
+#define ANA_AC_RAM_CTRL_RAM_INIT 0x14fdc
+#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x15474
+
+#define ANA_CL_PORT_VLAN_CFG(x) (0xa018 + 0xc8 * (x))
+#define ANA_CL_PORT_VLAN_CFG_AWARE_ENA BIT(19)
+#define ANA_CL_PORT_VLAN_CFG_POP_CNT(x) ((x) << 17)
+
+#define ANA_L2_COMMON_FWD_CFG 0x18498
+#define ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6)
+
+#define ASM_CFG_STAT_CFG 0xb08
+#define ASM_CFG_PORT(x) (0xb74 + 0x4 * (x))
+#define ASM_CFG_PORT_NO_PREAMBLE_ENA BIT(8)
+#define ASM_CFG_PORT_INJ_FORMAT_CFG(x) ((x) << 1)
+#define ASM_RAM_CTRL_RAM_INIT 0xbfc
+
+#define DEV_DEV_CFG_DEV_RST_CTRL 0x0
+#define DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x) ((x) << 20)
+#define DEV_MAC_CFG_MAC_ENA 0x24
+#define DEV_MAC_CFG_MAC_ENA_RX_ENA BIT(4)
+#define DEV_MAC_CFG_MAC_ENA_TX_ENA BIT(0)
+#define DEV_MAC_CFG_MAC_IFG 0x3c
+#define DEV_MAC_CFG_MAC_IFG_TX_IFG(x) ((x) << 8)
+#define DEV_MAC_CFG_MAC_IFG_RX_IFG2(x) ((x) << 4)
+#define DEV_MAC_CFG_MAC_IFG_RX_IFG1(x) (x)
+#define DEV_PCS1G_CFG_PCS1G_CFG 0x48
+#define DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA BIT(0)
+#define DEV_PCS1G_CFG_PCS1G_MODE 0x4c
+#define DEV_PCS1G_CFG_PCS1G_SD 0x50
+#define DEV_PCS1G_CFG_PCS1G_ANEG 0x54
+#define DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16)
+
+#define LRN_COMMON_ACCESS_CTRL 0x0
+#define LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT BIT(0)
+#define LRN_COMMON_MAC_ACCESS_CFG0 0x4
+#define LRN_COMMON_MAC_ACCESS_CFG1 0x8
+#define LRN_COMMON_MAC_ACCESS_CFG2 0xc
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x) (x)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x) ((x) << 12)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD BIT(15)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED BIT(16)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY BIT(23)
+#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x) ((x) << 24)
+
+#define QFWD_SYSTEM_SWITCH_PORT_MODE(x) (0x4400 + 0x4 * (x))
+#define QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA BIT(17)
+
+#define QS_XTR_GRP_CFG(x) (4 * (x))
+#define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4)
+
+#define QSYS_SYSTEM_RESET_CFG 0x1048
+#define QSYS_CALCFG_CAL_AUTO 0x1134
+#define QSYS_CALCFG_CAL_CTRL 0x113c
+#define QSYS_CALCFG_CAL_CTRL_CAL_MODE(x) ((x) << 11)
+#define QSYS_RAM_CTRL_RAM_INIT 0x1140
+
+#define REW_RAM_CTRL_RAM_INIT 0xFFF4
+
+#define MAC_VID 0
+#define CPU_PORT 11
+#define IFH_LEN 7
+#define ETH_ALEN 6
+#define PGID_BROADCAST 50
+#define PGID_UNICAST 51
+
+static const char * const regs_names[] = {
+ "port0", "port1",
+ "ana_ac", "ana_cl", "ana_l2", "asm", "lrn", "qfwd", "qs", "qsys", "rew",
+};
+
+#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
+#define MAX_PORT 2
+
+enum servalt_ctrl_regs {
+ ANA_AC = MAX_PORT,
+ ANA_CL,
+ ANA_L2,
+ ASM,
+ LRN,
+ QFWD,
+ QS,
+ QSYS,
+ REW,
+};
+
+#define SERVALT_MIIM_BUS_COUNT 2
+
+struct servalt_phy_port_t {
+ size_t phy_addr;
+ struct mii_dev *bus;
+};
+
+struct servalt_private {
+ void __iomem *regs[REGS_NAMES_COUNT];
+ struct mii_dev *bus[SERVALT_MIIM_BUS_COUNT];
+ struct servalt_phy_port_t ports[MAX_PORT];
+};
+
+struct mscc_miim_dev {
+ void __iomem *regs;
+ phys_addr_t miim_base;
+ unsigned long miim_size;
+ struct mii_dev *bus;
+};
+
+static const unsigned long servalt_regs_qs[] = {
+ [MSCC_QS_XTR_RD] = 0x8,
+ [MSCC_QS_XTR_FLUSH] = 0x18,
+ [MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
+ [MSCC_QS_INJ_WR] = 0x2c,
+ [MSCC_QS_INJ_CTRL] = 0x34,
+};
+
+static struct mscc_miim_dev miim[SERVALT_MIIM_BUS_COUNT];
+static int miim_count = -1;
+
+static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
+{
+ return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
+ GCB_MIIM_STAT_BUSY, false, 250, false);
+}
+
+static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ u32 val;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
+ miim->regs + GCB_MIIM_MII_CMD);
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret)
+ goto out;
+
+ val = readl(miim->regs + GCB_MIIM_DATA);
+ if (val & GCB_MIIM_DATA_ERROR) {
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = val & 0xFFFF;
+out:
+ return ret;
+}
+
+static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 val)
+{
+ struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
+ int ret;
+
+ ret = mscc_miim_wait_ready(miim);
+ if (ret < 0)
+ goto out;
+
+ writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
+ GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
+ GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
+
+out:
+ return ret;
+}
+
+static struct mii_dev *servalt_mdiobus_init(phys_addr_t miim_base,
+ unsigned long miim_size)
+{
+ struct mii_dev *bus;
+
+ bus = mdio_alloc();
+ if (!bus)
+ return NULL;
+
+ ++miim_count;
+ sprintf(bus->name, "miim-bus%d", miim_count);
+
+ miim[miim_count].regs = ioremap(miim_base, miim_size);
+ miim[miim_count].miim_base = miim_base;
+ miim[miim_count].miim_size = miim_size;
+ bus->priv = &miim[miim_count];
+ bus->read = mscc_miim_read;
+ bus->write = mscc_miim_write;
+
+ if (mdio_register(bus))
+ return NULL;
+
+ miim[miim_count].bus = bus;
+ return bus;
+}
+
+static void mscc_phy_reset(void)
+{
+ writel(0, BASE_DEVCPU_GCB + GCB_PHY_CFG + PHY_CFG);
+ writel(PHY_CFG_RST | PHY_CFG_COMMON_RST
+ | PHY_CFG_ENA, BASE_DEVCPU_GCB + GCB_PHY_CFG + PHY_CFG);
+ if (wait_for_bit_le32((const void *)(BASE_DEVCPU_GCB + GCB_PHY_CFG) +
+ PHY_STAT, PHY_STAT_SUPERVISOR_COMPLETE,
+ true, 2000, false)) {
+ pr_err("Timeout in phy reset\n");
+ }
+}
+
+static void servalt_cpu_capture_setup(struct servalt_private *priv)
+{
+ /* ASM: No preamble and IFH prefix on CPU injected frames */
+ writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
+ ASM_CFG_PORT_INJ_FORMAT_CFG(1),
+ priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
+
+ /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
+ writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
+
+ /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
+ writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
+
+ /* Enable CPU port for any frame transfer */
+ setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
+ QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
+
+ /* Send a copy to CPU when found as forwarding entry */
+ setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
+ ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
+}
+
+static void servalt_port_init(struct servalt_private *priv, int port)
+{
+ void __iomem *regs = priv->regs[port];
+
+ /* Enable PCS */
+ writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
+ regs + DEV_PCS1G_CFG_PCS1G_CFG);
+
+ /* Disable Signal Detect */
+ writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
+
+ /* Enable MAC RX and TX */
+ writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
+ DEV_MAC_CFG_MAC_ENA_TX_ENA,
+ regs + DEV_MAC_CFG_MAC_ENA);
+
+ /* Clear sgmii_mode_ena */
+ writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
+
+ /*
+ * Clear sw_resolve_ena(bit 0) and set adv_ability to
+ * something meaningful just in case
+ */
+ writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
+ regs + DEV_PCS1G_CFG_PCS1G_ANEG);
+
+ /* Set MAC IFG Gaps */
+ writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
+ DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
+ DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
+ regs + DEV_MAC_CFG_MAC_IFG);
+
+ /* Set link speed and release all resets */
+ writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
+ regs + DEV_DEV_CFG_DEV_RST_CTRL);
+
+ /* Make VLAN aware for CPU traffic */
+ writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
+ ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
+ MAC_VID,
+ priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
+
+ /* Enable CPU port for any frame transfer */
+ setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
+ QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
+}
+
+static int ram_init(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+
+ if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
+ printf("Timeout in memory reset, reg = 0x%08x\n", val);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int servalt_switch_init(struct servalt_private *priv)
+{
+ /* Initialize memories */
+ ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
+ ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
+ ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
+ ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
+
+ /* Reset counters */
+ writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
+ writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
+
+ /* Enable switch-core and queue system */
+ writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
+
+ return 0;
+}
+
+static void servalt_switch_config(struct servalt_private *priv)
+{
+ writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO);
+
+ writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
+ QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
+ priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
+}
+
+static int servalt_initialize(struct servalt_private *priv)
+{
+ int ret, i;
+
+ /* Initialize switch memories, enable core */
+ ret = servalt_switch_init(priv);
+ if (ret)
+ return ret;
+
+ servalt_switch_config(priv);
+
+ for (i = 0; i < MAX_PORT; i++)
+ servalt_port_init(priv, i);
+
+ servalt_cpu_capture_setup(priv);
+
+ return 0;
+}
+
+static inline
+int servalt_vlant_wait_for_completion(struct servalt_private *priv)
+{
+ if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
+ LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
+ false, 2000, false))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int servalt_mac_table_add(struct servalt_private *priv,
+ const unsigned char mac[ETH_ALEN], int pgid)
+{
+ u32 macl = 0, mach = 0;
+
+ /*
+ * Set the MAC address to handle and the vlan associated in a format
+ * understood by the hardware.
+ */
+ mach |= MAC_VID << 16;
+ mach |= ((u32)mac[0]) << 8;
+ mach |= ((u32)mac[1]) << 0;
+ macl |= ((u32)mac[2]) << 24;
+ macl |= ((u32)mac[3]) << 16;
+ macl |= ((u32)mac[4]) << 8;
+ macl |= ((u32)mac[5]) << 0;
+
+ writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
+ writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
+
+ writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
+ LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
+ priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
+
+ writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
+ priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
+
+ return servalt_vlant_wait_for_completion(priv);
+}
+
+static int servalt_write_hwaddr(struct udevice *dev)
+{
+ struct servalt_private *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ return servalt_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
+}
+
+static int servalt_start(struct udevice *dev)
+{
+ struct servalt_private *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff };
+ int ret;
+
+ ret = servalt_initialize(priv);
+ if (ret)
+ return ret;
+
+ /* Set MAC address tables entries for CPU redirection */
+ ret = servalt_mac_table_add(priv, mac, PGID_BROADCAST);
+ if (ret)
+ return ret;
+
+ ret = servalt_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void servalt_stop(struct udevice *dev)
+{
+}
+
+static int servalt_send(struct udevice *dev, void *packet, int length)
+{
+ struct servalt_private *priv = dev_get_priv(dev);
+ u32 ifh[IFH_LEN];
+ u32 *buf = packet;
+
+ memset(ifh, '\0', IFH_LEN * 4);
+
+ /* Set DST PORT_MASK */
+ ifh[0] = htonl(0);
+ ifh[1] = htonl(0x1FFFFF);
+ ifh[2] = htonl(~0);
+ /* Set DST_MODE to INJECT and UPDATE_FCS */
+ ifh[5] = htonl(0x4c0);
+
+ return mscc_send(priv->regs[QS], servalt_regs_qs,
+ ifh, IFH_LEN, buf, length);
+}
+
+static int servalt_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct servalt_private *priv = dev_get_priv(dev);
+ u32 *rxbuf = (u32 *)net_rx_packets[0];
+ int byte_cnt = 0;
+
+ byte_cnt = mscc_recv(priv->regs[QS], servalt_regs_qs, rxbuf, IFH_LEN,
+ false);
+
+ *packetp = net_rx_packets[0];
+
+ return byte_cnt;
+}
+
+static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
+{
+ int i = 0;
+
+ for (i = 0; i < SERVALT_MIIM_BUS_COUNT; ++i)
+ if (miim[i].miim_base == base && miim[i].miim_size == size)
+ return miim[i].bus;
+
+ return NULL;
+}
+
+static void add_port_entry(struct servalt_private *priv, size_t index,
+ size_t phy_addr, struct mii_dev *bus)
+{
+ priv->ports[index].phy_addr = phy_addr;
+ priv->ports[index].bus = bus;
+}
+
+static int servalt_probe(struct udevice *dev)
+{
+ struct servalt_private *priv = dev_get_priv(dev);
+ int i;
+ struct resource res;
+ fdt32_t faddr;
+ phys_addr_t addr_base;
+ unsigned long addr_size;
+ ofnode eth_node, node, mdio_node;
+ size_t phy_addr;
+ struct mii_dev *bus;
+ struct ofnode_phandle_args phandle;
+
+ if (!priv)
+ return -EINVAL;
+
+ /* Get registers and map them to the private structure */
+ for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
+ priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
+ if (!priv->regs[i]) {
+ debug
+ ("Error can't get regs base addresses for %s\n",
+ regs_names[i]);
+ return -ENOMEM;
+ }
+ }
+
+ /* Initialize miim buses */
+ memset(&miim, 0x0, sizeof(struct mscc_miim_dev) *
+ SERVALT_MIIM_BUS_COUNT);
+
+ /* iterate all the ports and find out on which bus they are */
+ i = 0;
+ eth_node = dev_read_first_subnode(dev);
+ for (node = ofnode_first_subnode(eth_node);
+ ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ if (ofnode_read_resource(node, 0, &res))
+ return -ENOMEM;
+ i = res.start;
+
+ ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0,
+ &phandle);
+
+ /* Get phy address on mdio bus */
+ if (ofnode_read_resource(phandle.node, 0, &res))
+ return -ENOMEM;
+ phy_addr = res.start;
+
+ /* Get mdio node */
+ mdio_node = ofnode_get_parent(phandle.node);
+
+ if (ofnode_read_resource(mdio_node, 0, &res))
+ return -ENOMEM;
+ faddr = cpu_to_fdt32(res.start);
+
+ addr_base = ofnode_translate_address(mdio_node, &faddr);
+ addr_size = res.end - res.start;
+
+ /* If the bus is new then create a new bus */
+ if (!get_mdiobus(addr_base, addr_size))
+ priv->bus[miim_count] =
+ servalt_mdiobus_init(addr_base, addr_size);
+
+ /* Connect mdio bus with the port */
+ bus = get_mdiobus(addr_base, addr_size);
+ add_port_entry(priv, i, phy_addr, bus);
+ }
+
+ mscc_phy_reset();
+
+ for (i = 0; i < MAX_PORT; i++) {
+ if (!priv->ports[i].bus)
+ continue;
+
+ phy_connect(priv->ports[i].bus, priv->ports[i].phy_addr, dev,
+ PHY_INTERFACE_MODE_NONE);
+ }
+
+ return 0;
+}
+
+static int servalt_remove(struct udevice *dev)
+{
+ struct servalt_private *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < SERVALT_MIIM_BUS_COUNT; i++) {
+ mdio_unregister(priv->bus[i]);
+ mdio_free(priv->bus[i]);
+ }
+
+ return 0;
+}
+
+static const struct eth_ops servalt_ops = {
+ .start = servalt_start,
+ .stop = servalt_stop,
+ .send = servalt_send,
+ .recv = servalt_recv,
+ .write_hwaddr = servalt_write_hwaddr,
+};
+
+static const struct udevice_id mscc_servalt_ids[] = {
+ {.compatible = "mscc,vsc7437-switch" },
+ { /* Sentinel */ }
+};
+
+U_BOOT_DRIVER(servalt) = {
+ .name = "servalt-switch",
+ .id = UCLASS_ETH,
+ .of_match = mscc_servalt_ids,
+ .probe = servalt_probe,
+ .remove = servalt_remove,
+ .ops = &servalt_ops,
+ .priv_auto_alloc_size = sizeof(struct servalt_private),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 32bbf41dd1f..102fb91fffd 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -174,4 +174,12 @@ config KEYSTONE_USB_PHY
This PHY is found on some Keystone (K2) devices supporting USB.
+config MT76X8_USB_PHY
+ bool "MediaTek MT76x8 (7628/88) USB PHY support"
+ depends on PHY
+ help
+ Support the USB PHY in MT76x8 SoCs
+
+ This PHY is found on MT76x8 devices supporting USB.
+
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 099551d6930..b55917bce1a 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o
obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o
obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o
+obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o
diff --git a/drivers/phy/mt76x8-usb-phy.c b/drivers/phy/mt76x8-usb-phy.c
new file mode 100644
index 00000000000..268da8ef6c9
--- /dev/null
+++ b/drivers/phy/mt76x8-usb-phy.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Stefan Roese <sr@denx.de>
+ *
+ * Derived from linux/drivers/phy/ralink/phy-ralink-usb.c
+ * Copyright (C) 2017 John Crispin <john@phrozen.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <generic-phy.h>
+#include <regmap.h>
+#include <reset-uclass.h>
+#include <syscon.h>
+#include <asm/io.h>
+
+#define RT_SYSC_REG_SYSCFG1 0x014
+#define RT_SYSC_REG_CLKCFG1 0x030
+#define RT_SYSC_REG_USB_PHY_CFG 0x05c
+
+#define OFS_U2_PHY_AC0 0x800
+#define OFS_U2_PHY_AC1 0x804
+#define OFS_U2_PHY_AC2 0x808
+#define OFS_U2_PHY_ACR0 0x810
+#define OFS_U2_PHY_ACR1 0x814
+#define OFS_U2_PHY_ACR2 0x818
+#define OFS_U2_PHY_ACR3 0x81C
+#define OFS_U2_PHY_ACR4 0x820
+#define OFS_U2_PHY_AMON0 0x824
+#define OFS_U2_PHY_DCR0 0x860
+#define OFS_U2_PHY_DCR1 0x864
+#define OFS_U2_PHY_DTM0 0x868
+#define OFS_U2_PHY_DTM1 0x86C
+
+#define RT_RSTCTRL_UDEV BIT(25)
+#define RT_RSTCTRL_UHST BIT(22)
+#define RT_SYSCFG1_USB0_HOST_MODE BIT(10)
+
+#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25)
+#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22)
+#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20)
+#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18)
+
+#define USB_PHY_UTMI_8B60M BIT(1)
+#define UDEV_WAKEUP BIT(0)
+
+struct mt76x8_usb_phy {
+ u32 clk;
+ void __iomem *base;
+ struct regmap *sysctl;
+};
+
+static void u2_phy_w32(struct mt76x8_usb_phy *phy, u32 val, u32 reg)
+{
+ writel(val, phy->base + reg);
+}
+
+static u32 u2_phy_r32(struct mt76x8_usb_phy *phy, u32 reg)
+{
+ return readl(phy->base + reg);
+}
+
+static void mt76x8_usb_phy_init(struct mt76x8_usb_phy *phy)
+{
+ u2_phy_r32(phy, OFS_U2_PHY_AC2);
+ u2_phy_r32(phy, OFS_U2_PHY_ACR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+
+ u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0);
+ u2_phy_r32(phy, OFS_U2_PHY_DCR0);
+ u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0);
+ u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1);
+ u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3);
+ u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0);
+}
+
+static int mt76x8_usb_phy_power_on(struct phy *_phy)
+{
+ struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
+ u32 t;
+
+ /* enable the phy */
+ regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
+ phy->clk, phy->clk);
+
+ /* setup host mode */
+ regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1,
+ RT_SYSCFG1_USB0_HOST_MODE,
+ RT_SYSCFG1_USB0_HOST_MODE);
+
+ /*
+ * The SDK kernel had a delay of 100ms. however on device
+ * testing showed that 10ms is enough
+ */
+ mdelay(10);
+
+ if (phy->base)
+ mt76x8_usb_phy_init(phy);
+
+ /* print some status info */
+ regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t);
+ printf("remote usb device wakeup %s\n",
+ (t & UDEV_WAKEUP) ? "enabled" : "disabled");
+ if (t & USB_PHY_UTMI_8B60M)
+ printf("UTMI 8bit 60MHz\n");
+ else
+ printf("UTMI 16bit 30MHz\n");
+
+ return 0;
+}
+
+static int mt76x8_usb_phy_power_off(struct phy *_phy)
+{
+ struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev);
+
+ /* disable the phy */
+ regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1,
+ phy->clk, 0);
+
+ return 0;
+}
+
+static int mt76x8_usb_phy_probe(struct udevice *dev)
+{
+ struct mt76x8_usb_phy *phy = dev_get_priv(dev);
+
+ phy->sysctl = syscon_regmap_lookup_by_phandle(dev, "ralink,sysctl");
+ if (IS_ERR(phy->sysctl))
+ return PTR_ERR(phy->sysctl);
+
+ phy->base = dev_read_addr_ptr(dev);
+ if (!phy->base)
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct phy_ops mt76x8_usb_phy_ops = {
+ .power_on = mt76x8_usb_phy_power_on,
+ .power_off = mt76x8_usb_phy_power_off,
+};
+
+static const struct udevice_id mt76x8_usb_phy_ids[] = {
+ { .compatible = "mediatek,mt7628-usbphy" },
+ { }
+};
+
+U_BOOT_DRIVER(mt76x8_usb_phy) = {
+ .name = "mt76x8_usb_phy",
+ .id = UCLASS_PHY,
+ .of_match = mt76x8_usb_phy_ids,
+ .ops = &mt76x8_usb_phy_ops,
+ .probe = mt76x8_usb_phy_probe,
+ .priv_auto_alloc_size = sizeof(struct mt76x8_usb_phy),
+};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index be709f73d7d..a0ac167d145 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -209,6 +209,25 @@ config PINCTRL_STM32
the GPIO definitions and pin control functions for each available
multiplex function.
+config PINCTRL_STMFX
+ bool "STMicroelectronics STMFX I2C GPIO expander pinctrl driver"
+ depends on DM && PINCTRL_FULL
+ help
+ I2C driver for STMicroelectronics Multi-Function eXpander (STMFX)
+ GPIO expander.
+ Supports pin multiplexing control on stm32 SoCs.
+
+ The driver is controlled by a device tree node which contains both
+ the GPIO definitions and pin control functions for each available
+ multiplex function.
+
+config SPL_PINCTRL_STMFX
+ bool "STMicroelectronics STMFX I2C GPIO expander pinctrl driver in SPL"
+ depends on SPL_PINCTRL_FULL
+ help
+ This option is an SPL-variant of the SPL_PINCTRL_STMFX option.
+ See the help of PINCTRL_STMFX for details.
+
config ASPEED_AST2500_PINCTRL
bool "Aspeed AST2500 pin control driver"
depends on DM && PINCTRL_GENERIC && ASPEED_AST2500
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index e2c2b159d8c..4b080b74dcd 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -22,4 +22,5 @@ obj-$(CONFIG_ARCH_MVEBU) += mvebu/
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o
+obj-$(CONFIG_$(SPL_)PINCTRL_STMFX) += pinctrl-stmfx.o
obj-y += broadcom/
diff --git a/drivers/pinctrl/ath79/Makefile b/drivers/pinctrl/ath79/Makefile
index 1daa2123a14..c7d1e44882e 100644
--- a/drivers/pinctrl/ath79/Makefile
+++ b/drivers/pinctrl/ath79/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_PINCTRL_AR933X) += pinctrl_ar933x.o
-obj-$(CONFIG_PINCTRL_QCA953x) += pinctrl_qca953x.o
+obj-$(CONFIG_PINCTRL_QCA953X) += pinctrl_qca953x.o
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
new file mode 100644
index 00000000000..5431df9813a
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-stmfx.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * Driver for STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander
+ * based on Linux driver : pinctrl/pinctrl-stmfx.c
+ */
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+#include <asm/gpio.h>
+#include <dm/device.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <linux/bitfield.h>
+#include <power/regulator.h>
+
+/* STMFX pins = GPIO[15:0] + aGPIO[7:0] */
+#define STMFX_MAX_GPIO 16
+#define STMFX_MAX_AGPIO 8
+
+/* General */
+#define STMFX_REG_CHIP_ID 0x00 /* R */
+#define STMFX_REG_FW_VERSION_MSB 0x01 /* R */
+#define STMFX_REG_FW_VERSION_LSB 0x02 /* R */
+#define STMFX_REG_SYS_CTRL 0x40 /* RW */
+
+/* MFX boot time is around 10ms, so after reset, we have to wait this delay */
+#define STMFX_BOOT_TIME_MS 10
+
+/* GPIOs expander */
+/* GPIO_STATE1 0x10, GPIO_STATE2 0x11, GPIO_STATE3 0x12 */
+#define STMFX_REG_GPIO_STATE 0x10 /* R */
+/* GPIO_DIR1 0x60, GPIO_DIR2 0x61, GPIO_DIR3 0x63 */
+#define STMFX_REG_GPIO_DIR 0x60 /* RW */
+/* GPIO_TYPE1 0x64, GPIO_TYPE2 0x65, GPIO_TYPE3 0x66 */
+#define STMFX_REG_GPIO_TYPE 0x64 /* RW */
+/* GPIO_PUPD1 0x68, GPIO_PUPD2 0x69, GPIO_PUPD3 0x6A */
+#define STMFX_REG_GPIO_PUPD 0x68 /* RW */
+/* GPO_SET1 0x6C, GPO_SET2 0x6D, GPO_SET3 0x6E */
+#define STMFX_REG_GPO_SET 0x6C /* RW */
+/* GPO_CLR1 0x70, GPO_CLR2 0x71, GPO_CLR3 0x72 */
+#define STMFX_REG_GPO_CLR 0x70 /* RW */
+
+/* STMFX_REG_CHIP_ID bitfields */
+#define STMFX_REG_CHIP_ID_MASK GENMASK(7, 0)
+
+/* STMFX_REG_SYS_CTRL bitfields */
+#define STMFX_REG_SYS_CTRL_GPIO_EN BIT(0)
+#define STMFX_REG_SYS_CTRL_ALTGPIO_EN BIT(3)
+#define STMFX_REG_SYS_CTRL_SWRST BIT(7)
+
+#define NR_GPIO_REGS 3
+#define NR_GPIOS_PER_REG 8
+#define get_reg(offset) ((offset) / NR_GPIOS_PER_REG)
+#define get_shift(offset) ((offset) % NR_GPIOS_PER_REG)
+#define get_mask(offset) (BIT(get_shift(offset)))
+
+struct stmfx_pinctrl {
+ struct udevice *gpio;
+};
+
+static int stmfx_read(struct udevice *dev, uint offset)
+{
+ return dm_i2c_reg_read(dev_get_parent(dev), offset);
+}
+
+static int stmfx_write(struct udevice *dev, uint offset, unsigned int val)
+{
+ return dm_i2c_reg_write(dev_get_parent(dev), offset, val);
+}
+
+static int stmfx_gpio_get(struct udevice *dev, unsigned int offset)
+{
+ u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset);
+ u32 mask = get_mask(offset);
+ int ret;
+
+ ret = stmfx_read(dev, reg);
+
+ return ret < 0 ? ret : !!(ret & mask);
+}
+
+static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value)
+{
+ u32 reg = value ? STMFX_REG_GPO_SET : STMFX_REG_GPO_CLR;
+ u32 mask = get_mask(offset);
+
+ return stmfx_write(dev, reg + get_reg(offset), mask);
+}
+
+static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset)
+{
+ u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
+ u32 mask = get_mask(offset);
+ int ret;
+
+ ret = stmfx_read(dev, reg);
+
+ if (ret < 0)
+ return ret;
+ /* On stmfx, gpio pins direction is (0)input, (1)output. */
+
+ return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset)
+{
+ u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
+ u32 mask = get_mask(offset);
+ int ret;
+
+ ret = stmfx_read(dev, reg);
+ if (ret < 0)
+ return ret;
+
+ ret &= ~mask;
+
+ return stmfx_write(dev, reg, ret & ~mask);
+}
+
+static int stmfx_gpio_direction_output(struct udevice *dev,
+ unsigned int offset, int value)
+{
+ u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
+ u32 mask = get_mask(offset);
+ int ret;
+
+ ret = stmfx_gpio_set(dev, offset, value);
+ if (ret < 0)
+ return ret;
+
+ ret = stmfx_read(dev, reg);
+ if (ret < 0)
+ return ret;
+
+ return stmfx_write(dev, reg, ret | mask);
+}
+
+static int stmfx_gpio_probe(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct ofnode_phandle_args args;
+ u8 sys_ctrl;
+
+ uc_priv->bank_name = "stmfx";
+ uc_priv->gpio_count = STMFX_MAX_GPIO + STMFX_MAX_AGPIO;
+ if (!dev_read_phandle_with_args(dev, "gpio-ranges",
+ NULL, 3, 0, &args)) {
+ uc_priv->gpio_count = args.args[2];
+ }
+
+ /* enable GPIO function */
+ sys_ctrl = STMFX_REG_SYS_CTRL_GPIO_EN;
+ if (uc_priv->gpio_count > STMFX_MAX_GPIO)
+ sys_ctrl |= STMFX_REG_SYS_CTRL_ALTGPIO_EN;
+ stmfx_write(dev, STMFX_REG_SYS_CTRL, sys_ctrl);
+
+ return 0;
+}
+
+static const struct dm_gpio_ops stmfx_gpio_ops = {
+ .set_value = stmfx_gpio_set,
+ .get_value = stmfx_gpio_get,
+ .get_function = stmfx_gpio_get_function,
+ .direction_input = stmfx_gpio_direction_input,
+ .direction_output = stmfx_gpio_direction_output,
+};
+
+U_BOOT_DRIVER(stmfx_gpio) = {
+ .name = "stmfx-gpio",
+ .id = UCLASS_GPIO,
+ .probe = stmfx_gpio_probe,
+ .ops = &stmfx_gpio_ops,
+};
+
+#if CONFIG_IS_ENABLED(PINCONF)
+static const struct pinconf_param stmfx_pinctrl_conf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 0 },
+ { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 0 },
+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 0 },
+ { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
+ { "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
+ { "output-high", PIN_CONFIG_OUTPUT, 1 },
+ { "output-low", PIN_CONFIG_OUTPUT, 0 },
+};
+
+static int stmfx_pinctrl_set_pupd(struct udevice *dev,
+ unsigned int pin, u32 pupd)
+{
+ u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin);
+ u32 mask = get_mask(pin);
+ int ret;
+
+ ret = stmfx_read(dev, reg);
+ if (ret < 0)
+ return ret;
+ ret = (ret & ~mask) | (pupd ? mask : 0);
+
+ return stmfx_write(dev, reg, ret);
+}
+
+static int stmfx_pinctrl_set_type(struct udevice *dev,
+ unsigned int pin, u32 type)
+{
+ u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin);
+ u32 mask = get_mask(pin);
+ int ret;
+
+ ret = stmfx_read(dev, reg);
+ if (ret < 0)
+ return ret;
+ ret = (ret & ~mask) | (type ? mask : 0);
+
+ return stmfx_write(dev, reg, ret);
+}
+
+static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin,
+ unsigned int param, unsigned int arg)
+{
+ int ret, dir;
+ struct stmfx_pinctrl *plat = dev_get_platdata(dev);
+
+ dir = stmfx_gpio_get_function(plat->gpio, pin);
+
+ if (dir < 0)
+ return dir;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ ret = stmfx_pinctrl_set_pupd(dev, pin, 0);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ ret = stmfx_pinctrl_set_pupd(dev, pin, 1);
+ break;
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ if (dir == GPIOF_OUTPUT)
+ ret = stmfx_pinctrl_set_type(dev, pin, 1);
+ else
+ ret = stmfx_pinctrl_set_type(dev, pin, 0);
+ break;
+ case PIN_CONFIG_DRIVE_PUSH_PULL:
+ if (dir == GPIOF_OUTPUT)
+ ret = stmfx_pinctrl_set_type(dev, pin, 0);
+ else
+ ret = stmfx_pinctrl_set_type(dev, pin, 1);
+ break;
+ case PIN_CONFIG_OUTPUT:
+ ret = stmfx_gpio_direction_output(plat->gpio, pin, arg);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ return ret;
+}
+#endif
+
+static int stmfx_pinctrl_get_pins_count(struct udevice *dev)
+{
+ struct stmfx_pinctrl *plat = dev_get_platdata(dev);
+ struct gpio_dev_priv *uc_priv;
+
+ uc_priv = dev_get_uclass_priv(plat->gpio);
+
+ return uc_priv->gpio_count;
+}
+
+/*
+ * STMFX pins[15:0] are called "gpio[15:0]"
+ * and STMFX pins[23:16] are called "agpio[7:0]"
+ */
+#define MAX_PIN_NAME_LEN 7
+static char pin_name[MAX_PIN_NAME_LEN];
+static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ if (selector < STMFX_MAX_GPIO)
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+ else
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "agpio%u", selector - 16);
+ return pin_name;
+}
+
+static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev,
+ unsigned int selector,
+ char *buf, int size)
+{
+ struct stmfx_pinctrl *plat = dev_get_platdata(dev);
+ int func;
+
+ func = stmfx_gpio_get_function(plat->gpio, selector);
+ if (func < 0)
+ return func;
+
+ snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output");
+
+ return 0;
+}
+
+static int stmfx_pinctrl_bind(struct udevice *dev)
+{
+ struct stmfx_pinctrl *plat = dev_get_platdata(dev);
+
+ return device_bind_driver_to_node(dev->parent,
+ "stmfx-gpio", "stmfx-gpio",
+ dev_ofnode(dev), &plat->gpio);
+};
+
+static int stmfx_pinctrl_probe(struct udevice *dev)
+{
+ struct stmfx_pinctrl *plat = dev_get_platdata(dev);
+
+ return device_probe(plat->gpio);
+};
+
+const struct pinctrl_ops stmfx_pinctrl_ops = {
+ .get_pins_count = stmfx_pinctrl_get_pins_count,
+ .get_pin_name = stmfx_pinctrl_get_pin_name,
+ .set_state = pinctrl_generic_set_state,
+ .get_pin_muxing = stmfx_pinctrl_get_pin_muxing,
+#if CONFIG_IS_ENABLED(PINCONF)
+ .pinconf_set = stmfx_pinctrl_conf_set,
+ .pinconf_num_params = ARRAY_SIZE(stmfx_pinctrl_conf_params),
+ .pinconf_params = stmfx_pinctrl_conf_params,
+#endif
+};
+
+static const struct udevice_id stmfx_pinctrl_match[] = {
+ { .compatible = "st,stmfx-0300-pinctrl", },
+};
+
+U_BOOT_DRIVER(stmfx_pinctrl) = {
+ .name = "stmfx-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = of_match_ptr(stmfx_pinctrl_match),
+ .bind = stmfx_pinctrl_bind,
+ .probe = stmfx_pinctrl_probe,
+ .ops = &stmfx_pinctrl_ops,
+ .platdata_auto_alloc_size = sizeof(struct stmfx_pinctrl),
+};
+
+static int stmfx_chip_init(struct udevice *dev)
+{
+ u8 id;
+ u8 version[2];
+ int ret;
+ struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+ id = dm_i2c_reg_read(dev, STMFX_REG_CHIP_ID);
+ if (id < 0) {
+ dev_err(dev, "error reading chip id: %d\n", id);
+ return ret;
+ }
+ /*
+ * Check that ID is the complement of the I2C address:
+ * STMFX I2C address follows the 7-bit format (MSB), that's why
+ * client->addr is shifted.
+ *
+ * STMFX_I2C_ADDR| STMFX | Linux
+ * input pin | I2C device address | I2C device address
+ *---------------------------------------------------------
+ * 0 | b: 1000 010x h:0x84 | 0x42
+ * 1 | b: 1000 011x h:0x86 | 0x43
+ */
+ if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (chip->chip_addr << 1)) {
+ dev_err(dev, "unknown chip id: %#x\n", id);
+ return -EINVAL;
+ }
+
+ ret = dm_i2c_read(dev, STMFX_REG_FW_VERSION_MSB,
+ version, sizeof(version));
+ if (ret) {
+ dev_err(dev, "error reading fw version: %d\n", ret);
+ return ret;
+ }
+
+ dev_info(dev, "STMFX id: %#x, fw version: %x.%02x\n",
+ id, version[0], version[1]);
+
+ ret = dm_i2c_reg_read(dev, STMFX_REG_SYS_CTRL);
+
+ if (ret < 0)
+ return ret;
+
+ ret = dm_i2c_reg_write(dev, STMFX_REG_SYS_CTRL,
+ ret | STMFX_REG_SYS_CTRL_SWRST);
+ if (ret)
+ return ret;
+
+ mdelay(STMFX_BOOT_TIME_MS);
+
+ return ret;
+}
+
+static int stmfx_probe(struct udevice *dev)
+{
+ struct udevice *vdd;
+ int ret;
+
+ ret = device_get_supply_regulator(dev, "vdd-supply", &vdd);
+ if (ret && ret != -ENOENT) {
+ dev_err(dev, "vdd regulator error:%d\n", ret);
+ return ret;
+ }
+ if (!ret) {
+ ret = regulator_set_enable(vdd, true);
+ if (ret) {
+ dev_err(dev, "vdd enable failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return stmfx_chip_init(dev);
+}
+
+static const struct udevice_id stmfx_match[] = {
+ { .compatible = "st,stmfx-0300", },
+};
+
+U_BOOT_DRIVER(stmfx) = {
+ .name = "stmfx",
+ .id = UCLASS_I2C_GENERIC,
+ .of_match = of_match_ptr(stmfx_match),
+ .probe = stmfx_probe,
+ .bind = dm_scan_fdt_dev,
+};
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 0e3260afd1e..0e6c559d5ef 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -27,28 +27,6 @@ int pinctrl_decode_pin_config(const void *blob, int node)
return flags;
}
-/*
- * TODO: this function is temporary for v2019.01.
- * It should be renamed to pinctrl_decode_pin_config(),
- * the original pinctrl_decode_pin_config() function should
- * be removed and all callers of the original function should
- * be migrated to use the new one.
- */
-int pinctrl_decode_pin_config_dm(struct udevice *dev)
-{
- int pinconfig = 0;
-
- if (dev->uclass->uc_drv->id != UCLASS_PINCONFIG)
- return -EINVAL;
-
- if (dev_read_bool(dev, "bias-pull-up"))
- pinconfig |= 1 << PIN_CONFIG_BIAS_PULL_UP;
- else if (dev_read_bool(dev, "bias-pull-down"))
- pinconfig |= 1 << PIN_CONFIG_BIAS_PULL_DOWN;
-
- return pinconfig;
-}
-
#if CONFIG_IS_ENABLED(PINCTRL_FULL)
/**
* pinctrl_config_one() - apply pinctrl settings for a single node
@@ -149,6 +127,9 @@ static int pinconfig_post_bind(struct udevice *dev)
ofnode_get_property(node, "compatible", &ret);
if (ret >= 0)
continue;
+ /* If this node has "gpio-controller" property, skip */
+ if (ofnode_read_bool(node, "gpio-controller"))
+ continue;
if (ret != -FDT_ERR_NOTFOUND)
return ret;
@@ -201,11 +182,14 @@ static int pinctrl_select_state_simple(struct udevice *dev)
int ret;
/*
- * For simplicity, assume the first device of PINCTRL uclass
- * is the correct one. This is most likely OK as there is
- * usually only one pinctrl device on the system.
+ * For most system, there is only one pincontroller device. But in
+ * case of multiple pincontroller devices, probe the one with sequence
+ * number 0 (defined by alias) to avoid race condition.
*/
- ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev);
+ ret = uclass_get_device_by_seq(UCLASS_PINCTRL, 0, &pctldev);
+ if (ret)
+ /* if not found, get the first one */
+ ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev);
if (ret)
return ret;
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 8cf60ebcf3d..b0cd2603543 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -231,10 +231,10 @@ config DM_PMIC_TPS65910
DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO
pmic children.
-config PMIC_STPMU1
- bool "Enable support for STMicroelectronics STPMU1 PMIC"
+config PMIC_STPMIC1
+ bool "Enable support for STMicroelectronics STPMIC1 PMIC"
depends on DM_PMIC && DM_I2C
---help---
- The STPMU1 PMIC provides 4 BUCKs, 6 LDOs, 1 VREF and 2 power switches.
+ The STPMIC1 PMIC provides 4 BUCKs, 6 LDOs, 1 VREF and 2 power switches.
It is accessed via an I2C interface. The device is used with STM32MP1
SoCs. This driver implements register read/write operations.
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 637352ab2b7..ce250cb1555 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_DM_PMIC_TPS65910) += pmic_tps65910_dm.o
obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o
obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o
obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o
-obj-$(CONFIG_PMIC_STPMU1) += stpmu1.o
+obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o
obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o
diff --git a/drivers/power/pmic/stpmic1.c b/drivers/power/pmic/stpmic1.c
new file mode 100644
index 00000000000..65296c5fc3a
--- /dev/null
+++ b/drivers/power/pmic/stpmic1.c
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+#include <sysreset.h>
+#include <dm/device.h>
+#include <dm/lists.h>
+#include <power/pmic.h>
+#include <power/stpmic1.h>
+
+#define STPMIC1_NUM_OF_REGS 0x100
+
+#define STPMIC1_NVM_SIZE 8
+#define STPMIC1_NVM_POLL_TIMEOUT 100000
+#define STPMIC1_NVM_START_ADDRESS 0xf8
+
+enum pmic_nvm_op {
+ SHADOW_READ,
+ SHADOW_WRITE,
+ NVM_READ,
+ NVM_WRITE,
+};
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+static const struct pmic_child_info stpmic1_children_info[] = {
+ { .prefix = "ldo", .driver = "stpmic1_ldo" },
+ { .prefix = "buck", .driver = "stpmic1_buck" },
+ { .prefix = "vref_ddr", .driver = "stpmic1_vref_ddr" },
+ { .prefix = "pwr_sw", .driver = "stpmic1_pwr_sw" },
+ { .prefix = "boost", .driver = "stpmic1_boost" },
+ { },
+};
+#endif /* DM_REGULATOR */
+
+static int stpmic1_reg_count(struct udevice *dev)
+{
+ return STPMIC1_NUM_OF_REGS;
+}
+
+static int stpmic1_write(struct udevice *dev, uint reg, const uint8_t *buff,
+ int len)
+{
+ int ret;
+
+ ret = dm_i2c_write(dev, reg, buff, len);
+ if (ret)
+ dev_err(dev, "%s: failed to write register %#x :%d",
+ __func__, reg, ret);
+
+ return ret;
+}
+
+static int stpmic1_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+ int ret;
+
+ ret = dm_i2c_read(dev, reg, buff, len);
+ if (ret)
+ dev_err(dev, "%s: failed to read register %#x : %d",
+ __func__, reg, ret);
+
+ return ret;
+}
+
+static int stpmic1_bind(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ ofnode regulators_node;
+ int children;
+
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
+ dev_dbg(dev, "regulators subnode not found!");
+ return -ENXIO;
+ }
+ dev_dbg(dev, "found regulators subnode\n");
+
+ children = pmic_bind_children(dev, regulators_node,
+ stpmic1_children_info);
+ if (!children)
+ dev_dbg(dev, "no child found\n");
+#endif /* DM_REGULATOR */
+
+ if (CONFIG_IS_ENABLED(SYSRESET))
+ return device_bind_driver(dev, "stpmic1-sysreset",
+ "stpmic1-sysreset", NULL);
+
+ return 0;
+}
+
+static struct dm_pmic_ops stpmic1_ops = {
+ .reg_count = stpmic1_reg_count,
+ .read = stpmic1_read,
+ .write = stpmic1_write,
+};
+
+static const struct udevice_id stpmic1_ids[] = {
+ { .compatible = "st,stpmic1" },
+ { }
+};
+
+U_BOOT_DRIVER(pmic_stpmic1) = {
+ .name = "stpmic1_pmic",
+ .id = UCLASS_PMIC,
+ .of_match = stpmic1_ids,
+ .bind = stpmic1_bind,
+ .ops = &stpmic1_ops,
+};
+
+#ifndef CONFIG_SPL_BUILD
+static int stpmic1_nvm_rw(u8 addr, u8 *buf, int buf_len, enum pmic_nvm_op op)
+{
+ struct udevice *dev;
+ unsigned long timeout;
+ u8 cmd = STPMIC1_NVM_CMD_READ;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_PMIC,
+ DM_GET_DRIVER(pmic_stpmic1), &dev);
+ if (ret)
+ /* No PMIC on power discrete board */
+ return -EOPNOTSUPP;
+
+ if (addr < STPMIC1_NVM_START_ADDRESS)
+ return -EACCES;
+
+ if (op == SHADOW_READ)
+ return pmic_read(dev, addr, buf, buf_len);
+
+ if (op == SHADOW_WRITE)
+ return pmic_write(dev, addr, buf, buf_len);
+
+ if (op == NVM_WRITE) {
+ cmd = STPMIC1_NVM_CMD_PROGRAM;
+
+ ret = pmic_write(dev, addr, buf, buf_len);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = pmic_reg_read(dev, STPMIC1_NVM_CR);
+ if (ret < 0)
+ return ret;
+
+ ret = pmic_reg_write(dev, STPMIC1_NVM_CR, ret | cmd);
+ if (ret < 0)
+ return ret;
+
+ timeout = timer_get_us() + STPMIC1_NVM_POLL_TIMEOUT;
+ for (;;) {
+ ret = pmic_reg_read(dev, STPMIC1_NVM_SR);
+ if (ret < 0)
+ return ret;
+
+ if (!(ret & STPMIC1_NVM_BUSY))
+ break;
+
+ if (time_after(timer_get_us(), timeout))
+ break;
+ }
+
+ if (ret & STPMIC1_NVM_BUSY)
+ return -ETIMEDOUT;
+
+ if (op == NVM_READ) {
+ ret = pmic_read(dev, addr, buf, buf_len);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int stpmic1_shadow_read_byte(u8 addr, u8 *buf)
+{
+ return stpmic1_nvm_rw(addr, buf, 1, SHADOW_READ);
+}
+
+int stpmic1_shadow_write_byte(u8 addr, u8 *buf)
+{
+ return stpmic1_nvm_rw(addr, buf, 1, SHADOW_WRITE);
+}
+
+int stpmic1_nvm_read_byte(u8 addr, u8 *buf)
+{
+ return stpmic1_nvm_rw(addr, buf, 1, NVM_READ);
+}
+
+int stpmic1_nvm_write_byte(u8 addr, u8 *buf)
+{
+ return stpmic1_nvm_rw(addr, buf, 1, NVM_WRITE);
+}
+
+int stpmic1_nvm_read_all(u8 *buf, int buf_len)
+{
+ if (buf_len != STPMIC1_NVM_SIZE)
+ return -EINVAL;
+
+ return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
+ buf, buf_len, NVM_READ);
+}
+
+int stpmic1_nvm_write_all(u8 *buf, int buf_len)
+{
+ if (buf_len != STPMIC1_NVM_SIZE)
+ return -EINVAL;
+
+ return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
+ buf, buf_len, NVM_WRITE);
+}
+#endif /* CONFIG_SPL_BUILD */
+
+#ifdef CONFIG_SYSRESET
+static int stpmic1_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct udevice *pmic_dev;
+ int ret;
+
+ if (type != SYSRESET_POWER)
+ return -EPROTONOSUPPORT;
+
+ ret = uclass_get_device_by_driver(UCLASS_PMIC,
+ DM_GET_DRIVER(pmic_stpmic1),
+ &pmic_dev);
+
+ if (ret)
+ return -EOPNOTSUPP;
+
+ ret = pmic_reg_read(pmic_dev, STPMIC1_MAIN_CR);
+ if (ret < 0)
+ return ret;
+
+ ret = pmic_reg_write(pmic_dev, STPMIC1_MAIN_CR,
+ ret | STPMIC1_SWOFF | STPMIC1_RREQ_EN);
+ if (ret < 0)
+ return ret;
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops stpmic1_sysreset_ops = {
+ .request = stpmic1_sysreset_request,
+};
+
+U_BOOT_DRIVER(stpmic1_sysreset) = {
+ .name = "stpmic1-sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &stpmic1_sysreset_ops,
+};
+#endif
diff --git a/drivers/power/pmic/stpmu1.c b/drivers/power/pmic/stpmu1.c
deleted file mode 100644
index 47af0123328..00000000000
--- a/drivers/power/pmic/stpmu1.c
+++ /dev/null
@@ -1,95 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
-/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
- */
-
-#include <common.h>
-#include <dm.h>
-#include <errno.h>
-#include <i2c.h>
-#include <power/pmic.h>
-#include <power/stpmu1.h>
-
-#define STMPU1_NUM_OF_REGS 0x100
-
-#ifndef CONFIG_SPL_BUILD
-static const struct pmic_child_info stpmu1_children_info[] = {
- { .prefix = "ldo", .driver = "stpmu1_ldo" },
- { .prefix = "buck", .driver = "stpmu1_buck" },
- { .prefix = "vref_ddr", .driver = "stpmu1_vref_ddr" },
- { .prefix = "pwr_sw", .driver = "stpmu1_pwr_sw" },
- { .prefix = "boost", .driver = "stpmu1_boost" },
- { },
-};
-#endif /* CONFIG_SPL_BUILD */
-
-static int stpmu1_reg_count(struct udevice *dev)
-{
- return STMPU1_NUM_OF_REGS;
-}
-
-static int stpmu1_write(struct udevice *dev, uint reg, const uint8_t *buff,
- int len)
-{
- int ret;
-
- ret = dm_i2c_write(dev, reg, buff, len);
- if (ret)
- dev_err(dev, "%s: failed to write register %#x :%d",
- __func__, reg, ret);
-
- return ret;
-}
-
-static int stpmu1_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
-{
- int ret;
-
- ret = dm_i2c_read(dev, reg, buff, len);
- if (ret)
- dev_err(dev, "%s: failed to read register %#x : %d",
- __func__, reg, ret);
-
- return ret;
-}
-
-static int stpmu1_bind(struct udevice *dev)
-{
-#ifndef CONFIG_SPL_BUILD
- ofnode regulators_node;
- int children;
-
- regulators_node = dev_read_subnode(dev, "regulators");
- if (!ofnode_valid(regulators_node)) {
- dev_dbg(dev, "regulators subnode not found!\n");
- return -ENXIO;
- }
- dev_dbg(dev, "found regulators subnode\n");
-
- children = pmic_bind_children(dev, regulators_node,
- stpmu1_children_info);
- if (!children)
- dev_dbg(dev, "no child found\n");
-#endif /* CONFIG_SPL_BUILD */
-
- return 0;
-}
-
-static struct dm_pmic_ops stpmu1_ops = {
- .reg_count = stpmu1_reg_count,
- .read = stpmu1_read,
- .write = stpmu1_write,
-};
-
-static const struct udevice_id stpmu1_ids[] = {
- { .compatible = "st,stpmu1" },
- { }
-};
-
-U_BOOT_DRIVER(pmic_stpmu1) = {
- .name = "stpmu1_pmic",
- .id = UCLASS_PMIC,
- .of_match = stpmu1_ids,
- .bind = stpmu1_bind,
- .ops = &stpmu1_ops,
-};
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index 3ed0dd2264a..72dfc48981a 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -244,11 +244,17 @@ config DM_REGULATOR_TPS65910
regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements
the get/set api for value and enable.
-config DM_REGULATOR_STPMU1
- bool "Enable driver for STPMU1 regulators"
- depends on DM_REGULATOR && PMIC_STPMU1
+config DM_REGULATOR_STPMIC1
+ bool "Enable driver for STPMIC1 regulators"
+ depends on DM_REGULATOR && PMIC_STPMIC1
---help---
- Enable support for the regulator functions of the STPMU1 PMIC. The
+ Enable support for the regulator functions of the STPMIC1 PMIC. The
driver implements get/set api for the various BUCKS and LDOs supported
by the PMIC device. This driver is controlled by a device tree node
which includes voltage limits.
+
+config SPL_DM_REGULATOR_STPMIC1
+ bool "Enable driver for STPMIC1 regulators in SPL"
+ depends on SPL_DM_REGULATOR && PMIC_STPMIC1
+ help
+ Enable support for the regulator functions of the STPMIC1 PMIC in SPL.
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index f617ce723a9..8c1506c88ed 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -24,4 +24,4 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o
-obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMU1) += stpmu1.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o
diff --git a/drivers/power/regulator/stpmic1.c b/drivers/power/regulator/stpmic1.c
new file mode 100644
index 00000000000..50ef2a21d18
--- /dev/null
+++ b/drivers/power/regulator/stpmic1.c
@@ -0,0 +1,672 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Author: Christophe Kerello <christophe.kerello@st.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/stpmic1.h>
+
+struct stpmic1_range {
+ int min_uv;
+ int min_sel;
+ int max_sel;
+ int step;
+};
+
+struct stpmic1_output {
+ const struct stpmic1_range *ranges;
+ int nbranges;
+};
+
+#define STPMIC1_MODE(_id, _val, _name) { \
+ .id = _id, \
+ .register_value = _val, \
+ .name = _name, \
+}
+
+#define STPMIC1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \
+ .min_uv = _min_uv, \
+ .min_sel = _min_sel, \
+ .max_sel = _max_sel, \
+ .step = _step, \
+}
+
+#define STPMIC1_OUTPUT(_ranges, _nbranges) { \
+ .ranges = _ranges, \
+ .nbranges = _nbranges, \
+}
+
+static int stpmic1_output_find_uv(int sel,
+ const struct stpmic1_output *output)
+{
+ const struct stpmic1_range *range;
+ int i;
+
+ for (i = 0, range = output->ranges;
+ i < output->nbranges; i++, range++) {
+ if (sel >= range->min_sel && sel <= range->max_sel)
+ return range->min_uv +
+ (sel - range->min_sel) * range->step;
+ }
+
+ return -EINVAL;
+}
+
+static int stpmic1_output_find_sel(int uv,
+ const struct stpmic1_output *output)
+{
+ const struct stpmic1_range *range;
+ int i;
+
+ for (i = 0, range = output->ranges;
+ i < output->nbranges; i++, range++) {
+ if (uv == range->min_uv && !range->step)
+ return range->min_sel;
+
+ if (uv >= range->min_uv &&
+ uv <= range->min_uv +
+ (range->max_sel - range->min_sel) * range->step)
+ return range->min_sel +
+ (uv - range->min_uv) / range->step;
+ }
+
+ return -EINVAL;
+}
+
+/*
+ * BUCK regulators
+ */
+
+static const struct stpmic1_range buck1_ranges[] = {
+ STPMIC1_RANGE(725000, 0, 4, 0),
+ STPMIC1_RANGE(725000, 5, 36, 25000),
+ STPMIC1_RANGE(1500000, 37, 63, 0),
+};
+
+static const struct stpmic1_range buck2_ranges[] = {
+ STPMIC1_RANGE(1000000, 0, 17, 0),
+ STPMIC1_RANGE(1050000, 18, 19, 0),
+ STPMIC1_RANGE(1100000, 20, 21, 0),
+ STPMIC1_RANGE(1150000, 22, 23, 0),
+ STPMIC1_RANGE(1200000, 24, 25, 0),
+ STPMIC1_RANGE(1250000, 26, 27, 0),
+ STPMIC1_RANGE(1300000, 28, 29, 0),
+ STPMIC1_RANGE(1350000, 30, 31, 0),
+ STPMIC1_RANGE(1400000, 32, 33, 0),
+ STPMIC1_RANGE(1450000, 34, 35, 0),
+ STPMIC1_RANGE(1500000, 36, 63, 0),
+};
+
+static const struct stpmic1_range buck3_ranges[] = {
+ STPMIC1_RANGE(1000000, 0, 19, 0),
+ STPMIC1_RANGE(1100000, 20, 23, 0),
+ STPMIC1_RANGE(1200000, 24, 27, 0),
+ STPMIC1_RANGE(1300000, 28, 31, 0),
+ STPMIC1_RANGE(1400000, 32, 35, 0),
+ STPMIC1_RANGE(1500000, 36, 55, 100000),
+ STPMIC1_RANGE(3400000, 56, 63, 0),
+};
+
+static const struct stpmic1_range buck4_ranges[] = {
+ STPMIC1_RANGE(600000, 0, 27, 25000),
+ STPMIC1_RANGE(1300000, 28, 29, 0),
+ STPMIC1_RANGE(1350000, 30, 31, 0),
+ STPMIC1_RANGE(1400000, 32, 33, 0),
+ STPMIC1_RANGE(1450000, 34, 35, 0),
+ STPMIC1_RANGE(1500000, 36, 60, 100000),
+ STPMIC1_RANGE(3900000, 61, 63, 0),
+};
+
+/* BUCK: 1,2,3,4 - voltage ranges */
+static const struct stpmic1_output buck_voltage_range[] = {
+ STPMIC1_OUTPUT(buck1_ranges, ARRAY_SIZE(buck1_ranges)),
+ STPMIC1_OUTPUT(buck2_ranges, ARRAY_SIZE(buck2_ranges)),
+ STPMIC1_OUTPUT(buck3_ranges, ARRAY_SIZE(buck3_ranges)),
+ STPMIC1_OUTPUT(buck4_ranges, ARRAY_SIZE(buck4_ranges)),
+};
+
+/* BUCK modes */
+static const struct dm_regulator_mode buck_modes[] = {
+ STPMIC1_MODE(STPMIC1_PREG_MODE_HP, STPMIC1_PREG_MODE_HP, "HP"),
+ STPMIC1_MODE(STPMIC1_PREG_MODE_LP, STPMIC1_PREG_MODE_LP, "LP"),
+};
+
+static int stpmic1_buck_get_uv(struct udevice *dev, int buck)
+{
+ int sel;
+
+ sel = pmic_reg_read(dev, STPMIC1_BUCKX_MAIN_CR(buck));
+ if (sel < 0)
+ return sel;
+
+ sel &= STPMIC1_BUCK_VOUT_MASK;
+ sel >>= STPMIC1_BUCK_VOUT_SHIFT;
+
+ return stpmic1_output_find_uv(sel, &buck_voltage_range[buck]);
+}
+
+static int stpmic1_buck_get_value(struct udevice *dev)
+{
+ return stpmic1_buck_get_uv(dev->parent, dev->driver_data - 1);
+}
+
+static int stpmic1_buck_set_value(struct udevice *dev, int uv)
+{
+ int sel, buck = dev->driver_data - 1;
+
+ sel = stpmic1_output_find_sel(uv, &buck_voltage_range[buck]);
+ if (sel < 0)
+ return sel;
+
+ return pmic_clrsetbits(dev->parent,
+ STPMIC1_BUCKX_MAIN_CR(buck),
+ STPMIC1_BUCK_VOUT_MASK,
+ sel << STPMIC1_BUCK_VOUT_SHIFT);
+}
+
+static int stpmic1_buck_get_enable(struct udevice *dev)
+{
+ int ret;
+
+ ret = pmic_reg_read(dev->parent,
+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1));
+ if (ret < 0)
+ return false;
+
+ return ret & STPMIC1_BUCK_ENA ? true : false;
+}
+
+static int stpmic1_buck_set_enable(struct udevice *dev, bool enable)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS :
+ STPMIC1_DEFAULT_STOP_DELAY_MS;
+ int ret, uv;
+
+ /* if regulator is already in the wanted state, nothing to do */
+ if (stpmic1_buck_get_enable(dev) == enable)
+ return 0;
+
+ if (enable) {
+ uc_pdata = dev_get_uclass_platdata(dev);
+ uv = stpmic1_buck_get_value(dev);
+ if (uv < uc_pdata->min_uV || uv > uc_pdata->max_uV)
+ stpmic1_buck_set_value(dev, uc_pdata->min_uV);
+ }
+
+ ret = pmic_clrsetbits(dev->parent,
+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1),
+ STPMIC1_BUCK_ENA, enable ? STPMIC1_BUCK_ENA : 0);
+ mdelay(delay);
+
+ return ret;
+}
+
+static int stpmic1_buck_get_mode(struct udevice *dev)
+{
+ int ret;
+
+ ret = pmic_reg_read(dev->parent,
+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1));
+ if (ret < 0)
+ return ret;
+
+ return ret & STPMIC1_BUCK_PREG_MODE ? STPMIC1_PREG_MODE_LP :
+ STPMIC1_PREG_MODE_HP;
+}
+
+static int stpmic1_buck_set_mode(struct udevice *dev, int mode)
+{
+ return pmic_clrsetbits(dev->parent,
+ STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1),
+ STPMIC1_BUCK_PREG_MODE,
+ mode ? STPMIC1_BUCK_PREG_MODE : 0);
+}
+
+static int stpmic1_buck_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_BUCK)
+ return -EINVAL;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_BUCK;
+ uc_pdata->mode = (struct dm_regulator_mode *)buck_modes;
+ uc_pdata->mode_count = ARRAY_SIZE(buck_modes);
+
+ return 0;
+}
+
+static const struct dm_regulator_ops stpmic1_buck_ops = {
+ .get_value = stpmic1_buck_get_value,
+ .set_value = stpmic1_buck_set_value,
+ .get_enable = stpmic1_buck_get_enable,
+ .set_enable = stpmic1_buck_set_enable,
+ .get_mode = stpmic1_buck_get_mode,
+ .set_mode = stpmic1_buck_set_mode,
+};
+
+U_BOOT_DRIVER(stpmic1_buck) = {
+ .name = "stpmic1_buck",
+ .id = UCLASS_REGULATOR,
+ .ops = &stpmic1_buck_ops,
+ .probe = stpmic1_buck_probe,
+};
+
+/*
+ * LDO regulators
+ */
+
+static const struct stpmic1_range ldo12_ranges[] = {
+ STPMIC1_RANGE(1700000, 0, 7, 0),
+ STPMIC1_RANGE(1700000, 8, 24, 100000),
+ STPMIC1_RANGE(3300000, 25, 31, 0),
+};
+
+static const struct stpmic1_range ldo3_ranges[] = {
+ STPMIC1_RANGE(1700000, 0, 7, 0),
+ STPMIC1_RANGE(1700000, 8, 24, 100000),
+ STPMIC1_RANGE(3300000, 25, 30, 0),
+ /* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */
+};
+
+static const struct stpmic1_range ldo5_ranges[] = {
+ STPMIC1_RANGE(1700000, 0, 7, 0),
+ STPMIC1_RANGE(1700000, 8, 30, 100000),
+ STPMIC1_RANGE(3900000, 31, 31, 0),
+};
+
+static const struct stpmic1_range ldo6_ranges[] = {
+ STPMIC1_RANGE(900000, 0, 24, 100000),
+ STPMIC1_RANGE(3300000, 25, 31, 0),
+};
+
+/* LDO: 1,2,3,4,5,6 - voltage ranges */
+static const struct stpmic1_output ldo_voltage_range[] = {
+ STPMIC1_OUTPUT(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
+ STPMIC1_OUTPUT(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
+ STPMIC1_OUTPUT(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)),
+ STPMIC1_OUTPUT(NULL, 0),
+ STPMIC1_OUTPUT(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)),
+ STPMIC1_OUTPUT(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)),
+};
+
+/* LDO modes */
+static const struct dm_regulator_mode ldo_modes[] = {
+ STPMIC1_MODE(STPMIC1_LDO_MODE_NORMAL,
+ STPMIC1_LDO_MODE_NORMAL, "NORMAL"),
+ STPMIC1_MODE(STPMIC1_LDO_MODE_BYPASS,
+ STPMIC1_LDO_MODE_BYPASS, "BYPASS"),
+ STPMIC1_MODE(STPMIC1_LDO_MODE_SINK_SOURCE,
+ STPMIC1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"),
+};
+
+static int stpmic1_ldo_get_value(struct udevice *dev)
+{
+ int sel, ldo = dev->driver_data - 1;
+
+ sel = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo));
+ if (sel < 0)
+ return sel;
+
+ /* ldo4 => 3,3V */
+ if (ldo == STPMIC1_LDO4)
+ return STPMIC1_LDO4_UV;
+
+ sel &= STPMIC1_LDO12356_VOUT_MASK;
+ sel >>= STPMIC1_LDO12356_VOUT_SHIFT;
+
+ /* ldo3, sel = 31 => BUCK2/2 */
+ if (ldo == STPMIC1_LDO3 && sel == STPMIC1_LDO3_DDR_SEL)
+ return stpmic1_buck_get_uv(dev->parent, STPMIC1_BUCK2) / 2;
+
+ return stpmic1_output_find_uv(sel, &ldo_voltage_range[ldo]);
+}
+
+static int stpmic1_ldo_set_value(struct udevice *dev, int uv)
+{
+ int sel, ldo = dev->driver_data - 1;
+
+ /* ldo4 => not possible */
+ if (ldo == STPMIC1_LDO4)
+ return -EINVAL;
+
+ sel = stpmic1_output_find_sel(uv, &ldo_voltage_range[ldo]);
+ if (sel < 0)
+ return sel;
+
+ return pmic_clrsetbits(dev->parent,
+ STPMIC1_LDOX_MAIN_CR(ldo),
+ STPMIC1_LDO12356_VOUT_MASK,
+ sel << STPMIC1_LDO12356_VOUT_SHIFT);
+}
+
+static int stpmic1_ldo_get_enable(struct udevice *dev)
+{
+ int ret;
+
+ ret = pmic_reg_read(dev->parent,
+ STPMIC1_LDOX_MAIN_CR(dev->driver_data - 1));
+ if (ret < 0)
+ return false;
+
+ return ret & STPMIC1_LDO_ENA ? true : false;
+}
+
+static int stpmic1_ldo_set_enable(struct udevice *dev, bool enable)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS :
+ STPMIC1_DEFAULT_STOP_DELAY_MS;
+ int ret, uv;
+
+ /* if regulator is already in the wanted state, nothing to do */
+ if (stpmic1_ldo_get_enable(dev) == enable)
+ return 0;
+
+ if (enable) {
+ uc_pdata = dev_get_uclass_platdata(dev);
+ uv = stpmic1_ldo_get_value(dev);
+ if (uv < uc_pdata->min_uV || uv > uc_pdata->max_uV)
+ stpmic1_ldo_set_value(dev, uc_pdata->min_uV);
+ }
+
+ ret = pmic_clrsetbits(dev->parent,
+ STPMIC1_LDOX_MAIN_CR(dev->driver_data - 1),
+ STPMIC1_LDO_ENA, enable ? STPMIC1_LDO_ENA : 0);
+ mdelay(delay);
+
+ return ret;
+}
+
+static int stpmic1_ldo_get_mode(struct udevice *dev)
+{
+ int ret, ldo = dev->driver_data - 1;
+
+ if (ldo != STPMIC1_LDO3)
+ return -EINVAL;
+
+ ret = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo));
+ if (ret < 0)
+ return ret;
+
+ if (ret & STPMIC1_LDO3_MODE)
+ return STPMIC1_LDO_MODE_BYPASS;
+
+ ret &= STPMIC1_LDO12356_VOUT_MASK;
+ ret >>= STPMIC1_LDO12356_VOUT_SHIFT;
+
+ return ret == STPMIC1_LDO3_DDR_SEL ? STPMIC1_LDO_MODE_SINK_SOURCE :
+ STPMIC1_LDO_MODE_NORMAL;
+}
+
+static int stpmic1_ldo_set_mode(struct udevice *dev, int mode)
+{
+ int ret, ldo = dev->driver_data - 1;
+
+ if (ldo != STPMIC1_LDO3)
+ return -EINVAL;
+
+ ret = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo));
+ if (ret < 0)
+ return ret;
+
+ switch (mode) {
+ case STPMIC1_LDO_MODE_SINK_SOURCE:
+ ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+ ret |= STPMIC1_LDO3_DDR_SEL << STPMIC1_LDO12356_VOUT_SHIFT;
+ case STPMIC1_LDO_MODE_NORMAL:
+ ret &= ~STPMIC1_LDO3_MODE;
+ break;
+ case STPMIC1_LDO_MODE_BYPASS:
+ ret |= STPMIC1_LDO3_MODE;
+ break;
+ }
+
+ return pmic_reg_write(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo), ret);
+}
+
+static int stpmic1_ldo_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_LDO)
+ return -EINVAL;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_LDO;
+ if (dev->driver_data - 1 == STPMIC1_LDO3) {
+ uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes;
+ uc_pdata->mode_count = ARRAY_SIZE(ldo_modes);
+ } else {
+ uc_pdata->mode_count = 0;
+ }
+
+ return 0;
+}
+
+static const struct dm_regulator_ops stpmic1_ldo_ops = {
+ .get_value = stpmic1_ldo_get_value,
+ .set_value = stpmic1_ldo_set_value,
+ .get_enable = stpmic1_ldo_get_enable,
+ .set_enable = stpmic1_ldo_set_enable,
+ .get_mode = stpmic1_ldo_get_mode,
+ .set_mode = stpmic1_ldo_set_mode,
+};
+
+U_BOOT_DRIVER(stpmic1_ldo) = {
+ .name = "stpmic1_ldo",
+ .id = UCLASS_REGULATOR,
+ .ops = &stpmic1_ldo_ops,
+ .probe = stpmic1_ldo_probe,
+};
+
+/*
+ * VREF DDR regulator
+ */
+
+static int stpmic1_vref_ddr_get_value(struct udevice *dev)
+{
+ /* BUCK2/2 */
+ return stpmic1_buck_get_uv(dev->parent, STPMIC1_BUCK2) / 2;
+}
+
+static int stpmic1_vref_ddr_get_enable(struct udevice *dev)
+{
+ int ret;
+
+ ret = pmic_reg_read(dev->parent, STPMIC1_REFDDR_MAIN_CR);
+ if (ret < 0)
+ return false;
+
+ return ret & STPMIC1_VREF_ENA ? true : false;
+}
+
+static int stpmic1_vref_ddr_set_enable(struct udevice *dev, bool enable)
+{
+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS :
+ STPMIC1_DEFAULT_STOP_DELAY_MS;
+ int ret;
+
+ /* if regulator is already in the wanted state, nothing to do */
+ if (stpmic1_vref_ddr_get_enable(dev) == enable)
+ return 0;
+
+ ret = pmic_clrsetbits(dev->parent, STPMIC1_REFDDR_MAIN_CR,
+ STPMIC1_VREF_ENA, enable ? STPMIC1_VREF_ENA : 0);
+ mdelay(delay);
+
+ return ret;
+}
+
+static int stpmic1_vref_ddr_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_FIXED;
+ uc_pdata->mode_count = 0;
+
+ return 0;
+}
+
+static const struct dm_regulator_ops stpmic1_vref_ddr_ops = {
+ .get_value = stpmic1_vref_ddr_get_value,
+ .get_enable = stpmic1_vref_ddr_get_enable,
+ .set_enable = stpmic1_vref_ddr_set_enable,
+};
+
+U_BOOT_DRIVER(stpmic1_vref_ddr) = {
+ .name = "stpmic1_vref_ddr",
+ .id = UCLASS_REGULATOR,
+ .ops = &stpmic1_vref_ddr_ops,
+ .probe = stpmic1_vref_ddr_probe,
+};
+
+/*
+ * BOOST regulator
+ */
+
+static int stpmic1_boost_get_enable(struct udevice *dev)
+{
+ int ret;
+
+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR);
+ if (ret < 0)
+ return false;
+
+ return ret & STPMIC1_BST_ON ? true : false;
+}
+
+static int stpmic1_boost_set_enable(struct udevice *dev, bool enable)
+{
+ int ret;
+
+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR);
+ if (ret < 0)
+ return ret;
+
+ if (!enable && ret & STPMIC1_PWR_SW_ON)
+ return -EINVAL;
+
+ /* if regulator is already in the wanted state, nothing to do */
+ if (!!(ret & STPMIC1_BST_ON) == enable)
+ return 0;
+
+ ret = pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR,
+ STPMIC1_BST_ON,
+ enable ? STPMIC1_BST_ON : 0);
+ if (enable)
+ mdelay(STPMIC1_USB_BOOST_START_UP_DELAY_MS);
+
+ return ret;
+}
+
+static int stpmic1_boost_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_FIXED;
+ uc_pdata->mode_count = 0;
+
+ return 0;
+}
+
+static const struct dm_regulator_ops stpmic1_boost_ops = {
+ .get_enable = stpmic1_boost_get_enable,
+ .set_enable = stpmic1_boost_set_enable,
+};
+
+U_BOOT_DRIVER(stpmic1_boost) = {
+ .name = "stpmic1_boost",
+ .id = UCLASS_REGULATOR,
+ .ops = &stpmic1_boost_ops,
+ .probe = stpmic1_boost_probe,
+};
+
+/*
+ * USB power switch
+ */
+
+static int stpmic1_pwr_sw_get_enable(struct udevice *dev)
+{
+ uint mask = 1 << dev->driver_data;
+ int ret;
+
+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR);
+ if (ret < 0)
+ return false;
+
+ return ret & mask ? true : false;
+}
+
+static int stpmic1_pwr_sw_set_enable(struct udevice *dev, bool enable)
+{
+ uint mask = 1 << dev->driver_data;
+ int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS :
+ STPMIC1_DEFAULT_STOP_DELAY_MS;
+ int ret;
+
+ ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR);
+ if (ret < 0)
+ return ret;
+
+ /* if regulator is already in the wanted state, nothing to do */
+ if (!!(ret & mask) == enable)
+ return 0;
+
+ /* Boost management */
+ if (enable && !(ret & STPMIC1_BST_ON)) {
+ pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR,
+ STPMIC1_BST_ON, STPMIC1_BST_ON);
+ mdelay(STPMIC1_USB_BOOST_START_UP_DELAY_MS);
+ } else if (!enable && ret & STPMIC1_BST_ON &&
+ (ret & STPMIC1_PWR_SW_ON) != STPMIC1_PWR_SW_ON) {
+ pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR,
+ STPMIC1_BST_ON, 0);
+ }
+
+ ret = pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR,
+ mask, enable ? mask : 0);
+ mdelay(delay);
+
+ return ret;
+}
+
+static int stpmic1_pwr_sw_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_PWR_SW)
+ return -EINVAL;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_FIXED;
+ uc_pdata->mode_count = 0;
+
+ return 0;
+}
+
+static const struct dm_regulator_ops stpmic1_pwr_sw_ops = {
+ .get_enable = stpmic1_pwr_sw_get_enable,
+ .set_enable = stpmic1_pwr_sw_set_enable,
+};
+
+U_BOOT_DRIVER(stpmic1_pwr_sw) = {
+ .name = "stpmic1_pwr_sw",
+ .id = UCLASS_REGULATOR,
+ .ops = &stpmic1_pwr_sw_ops,
+ .probe = stpmic1_pwr_sw_probe,
+};
diff --git a/drivers/power/regulator/stpmu1.c b/drivers/power/regulator/stpmu1.c
deleted file mode 100644
index 6eb2420b6bc..00000000000
--- a/drivers/power/regulator/stpmu1.c
+++ /dev/null
@@ -1,671 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
-/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
- * Author: Christophe Kerello <christophe.kerello@st.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <errno.h>
-#include <power/pmic.h>
-#include <power/regulator.h>
-#include <power/stpmu1.h>
-
-struct stpmu1_range {
- int min_uv;
- int min_sel;
- int max_sel;
- int step;
-};
-
-struct stpmu1_output_range {
- const struct stpmu1_range *ranges;
- int nbranges;
-};
-
-#define STPMU1_MODE(_id, _val, _name) { \
- .id = _id, \
- .register_value = _val, \
- .name = _name, \
-}
-
-#define STPMU1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \
- .min_uv = _min_uv, \
- .min_sel = _min_sel, \
- .max_sel = _max_sel, \
- .step = _step, \
-}
-
-#define STPMU1_OUTPUT_RANGE(_ranges, _nbranges) { \
- .ranges = _ranges, \
- .nbranges = _nbranges, \
-}
-
-static int stpmu1_output_find_uv(int sel,
- const struct stpmu1_output_range *output_range)
-{
- const struct stpmu1_range *range;
- int i;
-
- for (i = 0, range = output_range->ranges;
- i < output_range->nbranges; i++, range++) {
- if (sel >= range->min_sel && sel <= range->max_sel)
- return range->min_uv +
- (sel - range->min_sel) * range->step;
- }
-
- return -EINVAL;
-}
-
-static int stpmu1_output_find_sel(int uv,
- const struct stpmu1_output_range *output_range)
-{
- const struct stpmu1_range *range;
- int i;
-
- for (i = 0, range = output_range->ranges;
- i < output_range->nbranges; i++, range++) {
- if (uv == range->min_uv && !range->step)
- return range->min_sel;
-
- if (uv >= range->min_uv &&
- uv <= range->min_uv +
- (range->max_sel - range->min_sel) * range->step)
- return range->min_sel +
- (uv - range->min_uv) / range->step;
- }
-
- return -EINVAL;
-}
-
-/*
- * BUCK regulators
- */
-
-static const struct stpmu1_range buck1_ranges[] = {
- STPMU1_RANGE(600000, 0, 30, 25000),
- STPMU1_RANGE(1350000, 31, 63, 0),
-};
-
-static const struct stpmu1_range buck2_ranges[] = {
- STPMU1_RANGE(1000000, 0, 17, 0),
- STPMU1_RANGE(1050000, 18, 19, 0),
- STPMU1_RANGE(1100000, 20, 21, 0),
- STPMU1_RANGE(1150000, 22, 23, 0),
- STPMU1_RANGE(1200000, 24, 25, 0),
- STPMU1_RANGE(1250000, 26, 27, 0),
- STPMU1_RANGE(1300000, 28, 29, 0),
- STPMU1_RANGE(1350000, 30, 31, 0),
- STPMU1_RANGE(1400000, 32, 33, 0),
- STPMU1_RANGE(1450000, 34, 35, 0),
- STPMU1_RANGE(1500000, 36, 63, 0),
-};
-
-static const struct stpmu1_range buck3_ranges[] = {
- STPMU1_RANGE(1000000, 0, 19, 0),
- STPMU1_RANGE(1100000, 20, 23, 0),
- STPMU1_RANGE(1200000, 24, 27, 0),
- STPMU1_RANGE(1300000, 28, 31, 0),
- STPMU1_RANGE(1400000, 32, 35, 0),
- STPMU1_RANGE(1500000, 36, 55, 100000),
- STPMU1_RANGE(3400000, 56, 63, 0),
-};
-
-static const struct stpmu1_range buck4_ranges[] = {
- STPMU1_RANGE(600000, 0, 27, 25000),
- STPMU1_RANGE(1300000, 28, 29, 0),
- STPMU1_RANGE(1350000, 30, 31, 0),
- STPMU1_RANGE(1400000, 32, 33, 0),
- STPMU1_RANGE(1450000, 34, 35, 0),
- STPMU1_RANGE(1500000, 36, 60, 100000),
- STPMU1_RANGE(3900000, 61, 63, 0),
-};
-
-/* BUCK: 1,2,3,4 - voltage ranges */
-static const struct stpmu1_output_range buck_voltage_range[] = {
- STPMU1_OUTPUT_RANGE(buck1_ranges, ARRAY_SIZE(buck1_ranges)),
- STPMU1_OUTPUT_RANGE(buck2_ranges, ARRAY_SIZE(buck2_ranges)),
- STPMU1_OUTPUT_RANGE(buck3_ranges, ARRAY_SIZE(buck3_ranges)),
- STPMU1_OUTPUT_RANGE(buck4_ranges, ARRAY_SIZE(buck4_ranges)),
-};
-
-/* BUCK modes */
-static const struct dm_regulator_mode buck_modes[] = {
- STPMU1_MODE(STPMU1_BUCK_MODE_HP, STPMU1_BUCK_MODE_HP, "HP"),
- STPMU1_MODE(STPMU1_BUCK_MODE_LP, STPMU1_BUCK_MODE_LP, "LP"),
-};
-
-static int stpmu1_buck_get_uv(struct udevice *dev, int buck)
-{
- int sel;
-
- sel = pmic_reg_read(dev, STPMU1_BUCKX_CTRL_REG(buck));
- if (sel < 0)
- return sel;
-
- sel &= STPMU1_BUCK_OUTPUT_MASK;
- sel >>= STPMU1_BUCK_OUTPUT_SHIFT;
-
- return stpmu1_output_find_uv(sel, &buck_voltage_range[buck]);
-}
-
-static int stpmu1_buck_get_value(struct udevice *dev)
-{
- return stpmu1_buck_get_uv(dev->parent, dev->driver_data - 1);
-}
-
-static int stpmu1_buck_set_value(struct udevice *dev, int uv)
-{
- int sel, buck = dev->driver_data - 1;
-
- sel = stpmu1_output_find_sel(uv, &buck_voltage_range[buck]);
- if (sel < 0)
- return sel;
-
- return pmic_clrsetbits(dev->parent,
- STPMU1_BUCKX_CTRL_REG(buck),
- STPMU1_BUCK_OUTPUT_MASK,
- sel << STPMU1_BUCK_OUTPUT_SHIFT);
-}
-
-static int stpmu1_buck_get_enable(struct udevice *dev)
-{
- int ret;
-
- ret = pmic_reg_read(dev->parent,
- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1));
- if (ret < 0)
- return false;
-
- return ret & STPMU1_BUCK_EN ? true : false;
-}
-
-static int stpmu1_buck_set_enable(struct udevice *dev, bool enable)
-{
- struct dm_regulator_uclass_platdata *uc_pdata;
- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS :
- STPMU1_DEFAULT_STOP_DELAY_MS;
- int ret, uv;
-
- /* if regulator is already in the wanted state, nothing to do */
- if (stpmu1_buck_get_enable(dev) == enable)
- return 0;
-
- if (enable) {
- uc_pdata = dev_get_uclass_platdata(dev);
- uv = stpmu1_buck_get_value(dev);
- if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV))
- stpmu1_buck_set_value(dev, uc_pdata->min_uV);
- }
-
- ret = pmic_clrsetbits(dev->parent,
- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1),
- STPMU1_BUCK_EN, enable ? STPMU1_BUCK_EN : 0);
- mdelay(delay);
-
- return ret;
-}
-
-static int stpmu1_buck_get_mode(struct udevice *dev)
-{
- int ret;
-
- ret = pmic_reg_read(dev->parent,
- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1));
- if (ret < 0)
- return ret;
-
- return ret & STPMU1_BUCK_MODE ? STPMU1_BUCK_MODE_LP :
- STPMU1_BUCK_MODE_HP;
-}
-
-static int stpmu1_buck_set_mode(struct udevice *dev, int mode)
-{
- return pmic_clrsetbits(dev->parent,
- STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1),
- STPMU1_BUCK_MODE,
- mode ? STPMU1_BUCK_MODE : 0);
-}
-
-static int stpmu1_buck_probe(struct udevice *dev)
-{
- struct dm_regulator_uclass_platdata *uc_pdata;
-
- if (!dev->driver_data || dev->driver_data > STPMU1_MAX_BUCK)
- return -EINVAL;
-
- uc_pdata = dev_get_uclass_platdata(dev);
-
- uc_pdata->type = REGULATOR_TYPE_BUCK;
- uc_pdata->mode = (struct dm_regulator_mode *)buck_modes;
- uc_pdata->mode_count = ARRAY_SIZE(buck_modes);
-
- return 0;
-}
-
-static const struct dm_regulator_ops stpmu1_buck_ops = {
- .get_value = stpmu1_buck_get_value,
- .set_value = stpmu1_buck_set_value,
- .get_enable = stpmu1_buck_get_enable,
- .set_enable = stpmu1_buck_set_enable,
- .get_mode = stpmu1_buck_get_mode,
- .set_mode = stpmu1_buck_set_mode,
-};
-
-U_BOOT_DRIVER(stpmu1_buck) = {
- .name = "stpmu1_buck",
- .id = UCLASS_REGULATOR,
- .ops = &stpmu1_buck_ops,
- .probe = stpmu1_buck_probe,
-};
-
-/*
- * LDO regulators
- */
-
-static const struct stpmu1_range ldo12_ranges[] = {
- STPMU1_RANGE(1700000, 0, 7, 0),
- STPMU1_RANGE(1700000, 8, 24, 100000),
- STPMU1_RANGE(3300000, 25, 31, 0),
-};
-
-static const struct stpmu1_range ldo3_ranges[] = {
- STPMU1_RANGE(1700000, 0, 7, 0),
- STPMU1_RANGE(1700000, 8, 24, 100000),
- STPMU1_RANGE(3300000, 25, 30, 0),
- /* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */
-};
-
-static const struct stpmu1_range ldo5_ranges[] = {
- STPMU1_RANGE(1700000, 0, 7, 0),
- STPMU1_RANGE(1700000, 8, 30, 100000),
- STPMU1_RANGE(3900000, 31, 31, 0),
-};
-
-static const struct stpmu1_range ldo6_ranges[] = {
- STPMU1_RANGE(900000, 0, 24, 100000),
- STPMU1_RANGE(3300000, 25, 31, 0),
-};
-
-/* LDO: 1,2,3,4,5,6 - voltage ranges */
-static const struct stpmu1_output_range ldo_voltage_range[] = {
- STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
- STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)),
- STPMU1_OUTPUT_RANGE(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)),
- STPMU1_OUTPUT_RANGE(NULL, 0),
- STPMU1_OUTPUT_RANGE(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)),
- STPMU1_OUTPUT_RANGE(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)),
-};
-
-/* LDO modes */
-static const struct dm_regulator_mode ldo_modes[] = {
- STPMU1_MODE(STPMU1_LDO_MODE_NORMAL,
- STPMU1_LDO_MODE_NORMAL, "NORMAL"),
- STPMU1_MODE(STPMU1_LDO_MODE_BYPASS,
- STPMU1_LDO_MODE_BYPASS, "BYPASS"),
- STPMU1_MODE(STPMU1_LDO_MODE_SINK_SOURCE,
- STPMU1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"),
-};
-
-static int stpmu1_ldo_get_value(struct udevice *dev)
-{
- int sel, ldo = dev->driver_data - 1;
-
- sel = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
- if (sel < 0)
- return sel;
-
- /* ldo4 => 3,3V */
- if (ldo == STPMU1_LDO4)
- return STPMU1_LDO4_UV;
-
- sel &= STPMU1_LDO12356_OUTPUT_MASK;
- sel >>= STPMU1_LDO12356_OUTPUT_SHIFT;
-
- /* ldo3, sel = 31 => BUCK2/2 */
- if (ldo == STPMU1_LDO3 && sel == STPMU1_LDO3_DDR_SEL)
- return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2;
-
- return stpmu1_output_find_uv(sel, &ldo_voltage_range[ldo]);
-}
-
-static int stpmu1_ldo_set_value(struct udevice *dev, int uv)
-{
- int sel, ldo = dev->driver_data - 1;
-
- /* ldo4 => not possible */
- if (ldo == STPMU1_LDO4)
- return -EINVAL;
-
- sel = stpmu1_output_find_sel(uv, &ldo_voltage_range[ldo]);
- if (sel < 0)
- return sel;
-
- return pmic_clrsetbits(dev->parent,
- STPMU1_LDOX_CTRL_REG(ldo),
- STPMU1_LDO12356_OUTPUT_MASK,
- sel << STPMU1_LDO12356_OUTPUT_SHIFT);
-}
-
-static int stpmu1_ldo_get_enable(struct udevice *dev)
-{
- int ret;
-
- ret = pmic_reg_read(dev->parent,
- STPMU1_LDOX_CTRL_REG(dev->driver_data - 1));
- if (ret < 0)
- return false;
-
- return ret & STPMU1_LDO_EN ? true : false;
-}
-
-static int stpmu1_ldo_set_enable(struct udevice *dev, bool enable)
-{
- struct dm_regulator_uclass_platdata *uc_pdata;
- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS :
- STPMU1_DEFAULT_STOP_DELAY_MS;
- int ret, uv;
-
- /* if regulator is already in the wanted state, nothing to do */
- if (stpmu1_ldo_get_enable(dev) == enable)
- return 0;
-
- if (enable) {
- uc_pdata = dev_get_uclass_platdata(dev);
- uv = stpmu1_ldo_get_value(dev);
- if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV))
- stpmu1_ldo_set_value(dev, uc_pdata->min_uV);
- }
-
- ret = pmic_clrsetbits(dev->parent,
- STPMU1_LDOX_CTRL_REG(dev->driver_data - 1),
- STPMU1_LDO_EN, enable ? STPMU1_LDO_EN : 0);
- mdelay(delay);
-
- return ret;
-}
-
-static int stpmu1_ldo_get_mode(struct udevice *dev)
-{
- int ret, ldo = dev->driver_data - 1;
-
- if (ldo != STPMU1_LDO3)
- return -EINVAL;
-
- ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
- if (ret < 0)
- return ret;
-
- if (ret & STPMU1_LDO3_MODE)
- return STPMU1_LDO_MODE_BYPASS;
-
- ret &= STPMU1_LDO12356_OUTPUT_MASK;
- ret >>= STPMU1_LDO12356_OUTPUT_SHIFT;
-
- return ret == STPMU1_LDO3_DDR_SEL ? STPMU1_LDO_MODE_SINK_SOURCE :
- STPMU1_LDO_MODE_NORMAL;
-}
-
-static int stpmu1_ldo_set_mode(struct udevice *dev, int mode)
-{
- int ret, ldo = dev->driver_data - 1;
-
- if (ldo != STPMU1_LDO3)
- return -EINVAL;
-
- ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo));
- if (ret < 0)
- return ret;
-
- switch (mode) {
- case STPMU1_LDO_MODE_SINK_SOURCE:
- ret &= ~STPMU1_LDO12356_OUTPUT_MASK;
- ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
- case STPMU1_LDO_MODE_NORMAL:
- ret &= ~STPMU1_LDO3_MODE;
- break;
- case STPMU1_LDO_MODE_BYPASS:
- ret |= STPMU1_LDO3_MODE;
- break;
- }
-
- return pmic_reg_write(dev->parent, STPMU1_LDOX_CTRL_REG(ldo), ret);
-}
-
-static int stpmu1_ldo_probe(struct udevice *dev)
-{
- struct dm_regulator_uclass_platdata *uc_pdata;
-
- if (!dev->driver_data || dev->driver_data > STPMU1_MAX_LDO)
- return -EINVAL;
-
- uc_pdata = dev_get_uclass_platdata(dev);
-
- uc_pdata->type = REGULATOR_TYPE_LDO;
- if (dev->driver_data - 1 == STPMU1_LDO3) {
- uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes;
- uc_pdata->mode_count = ARRAY_SIZE(ldo_modes);
- } else {
- uc_pdata->mode_count = 0;
- }
-
- return 0;
-}
-
-static const struct dm_regulator_ops stpmu1_ldo_ops = {
- .get_value = stpmu1_ldo_get_value,
- .set_value = stpmu1_ldo_set_value,
- .get_enable = stpmu1_ldo_get_enable,
- .set_enable = stpmu1_ldo_set_enable,
- .get_mode = stpmu1_ldo_get_mode,
- .set_mode = stpmu1_ldo_set_mode,
-};
-
-U_BOOT_DRIVER(stpmu1_ldo) = {
- .name = "stpmu1_ldo",
- .id = UCLASS_REGULATOR,
- .ops = &stpmu1_ldo_ops,
- .probe = stpmu1_ldo_probe,
-};
-
-/*
- * VREF DDR regulator
- */
-
-static int stpmu1_vref_ddr_get_value(struct udevice *dev)
-{
- /* BUCK2/2 */
- return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2;
-}
-
-static int stpmu1_vref_ddr_get_enable(struct udevice *dev)
-{
- int ret;
-
- ret = pmic_reg_read(dev->parent, STPMU1_VREF_CTRL_REG);
- if (ret < 0)
- return false;
-
- return ret & STPMU1_VREF_EN ? true : false;
-}
-
-static int stpmu1_vref_ddr_set_enable(struct udevice *dev, bool enable)
-{
- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS :
- STPMU1_DEFAULT_STOP_DELAY_MS;
- int ret;
-
- /* if regulator is already in the wanted state, nothing to do */
- if (stpmu1_vref_ddr_get_enable(dev) == enable)
- return 0;
-
- ret = pmic_clrsetbits(dev->parent, STPMU1_VREF_CTRL_REG,
- STPMU1_VREF_EN, enable ? STPMU1_VREF_EN : 0);
- mdelay(delay);
-
- return ret;
-}
-
-static int stpmu1_vref_ddr_probe(struct udevice *dev)
-{
- struct dm_regulator_uclass_platdata *uc_pdata;
-
- uc_pdata = dev_get_uclass_platdata(dev);
-
- uc_pdata->type = REGULATOR_TYPE_FIXED;
- uc_pdata->mode_count = 0;
-
- return 0;
-}
-
-static const struct dm_regulator_ops stpmu1_vref_ddr_ops = {
- .get_value = stpmu1_vref_ddr_get_value,
- .get_enable = stpmu1_vref_ddr_get_enable,
- .set_enable = stpmu1_vref_ddr_set_enable,
-};
-
-U_BOOT_DRIVER(stpmu1_vref_ddr) = {
- .name = "stpmu1_vref_ddr",
- .id = UCLASS_REGULATOR,
- .ops = &stpmu1_vref_ddr_ops,
- .probe = stpmu1_vref_ddr_probe,
-};
-
-/*
- * BOOST regulator
- */
-
-static int stpmu1_boost_get_enable(struct udevice *dev)
-{
- int ret;
-
- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
- if (ret < 0)
- return false;
-
- return ret & STPMU1_USB_BOOST_EN ? true : false;
-}
-
-static int stpmu1_boost_set_enable(struct udevice *dev, bool enable)
-{
- int ret;
-
- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
- if (ret < 0)
- return ret;
-
- if (!enable && ret & STPMU1_USB_PWR_SW_EN)
- return -EINVAL;
-
- /* if regulator is already in the wanted state, nothing to do */
- if (!!(ret & STPMU1_USB_BOOST_EN) == enable)
- return 0;
-
- ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
- STPMU1_USB_BOOST_EN,
- enable ? STPMU1_USB_BOOST_EN : 0);
- if (enable)
- mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS);
-
- return ret;
-}
-
-static int stpmu1_boost_probe(struct udevice *dev)
-{
- struct dm_regulator_uclass_platdata *uc_pdata;
-
- uc_pdata = dev_get_uclass_platdata(dev);
-
- uc_pdata->type = REGULATOR_TYPE_FIXED;
- uc_pdata->mode_count = 0;
-
- return 0;
-}
-
-static const struct dm_regulator_ops stpmu1_boost_ops = {
- .get_enable = stpmu1_boost_get_enable,
- .set_enable = stpmu1_boost_set_enable,
-};
-
-U_BOOT_DRIVER(stpmu1_boost) = {
- .name = "stpmu1_boost",
- .id = UCLASS_REGULATOR,
- .ops = &stpmu1_boost_ops,
- .probe = stpmu1_boost_probe,
-};
-
-/*
- * USB power switch
- */
-
-static int stpmu1_pwr_sw_get_enable(struct udevice *dev)
-{
- uint mask = 1 << dev->driver_data;
- int ret;
-
- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
- if (ret < 0)
- return false;
-
- return ret & mask ? true : false;
-}
-
-static int stpmu1_pwr_sw_set_enable(struct udevice *dev, bool enable)
-{
- uint mask = 1 << dev->driver_data;
- int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS :
- STPMU1_DEFAULT_STOP_DELAY_MS;
- int ret;
-
- ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG);
- if (ret < 0)
- return ret;
-
- /* if regulator is already in the wanted state, nothing to do */
- if (!!(ret & mask) == enable)
- return 0;
-
- /* Boost management */
- if (enable && !(ret & STPMU1_USB_BOOST_EN)) {
- pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
- STPMU1_USB_BOOST_EN, STPMU1_USB_BOOST_EN);
- mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS);
- } else if (!enable && ret & STPMU1_USB_BOOST_EN &&
- (ret & STPMU1_USB_PWR_SW_EN) != STPMU1_USB_PWR_SW_EN) {
- pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
- STPMU1_USB_BOOST_EN, 0);
- }
-
- ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG,
- mask, enable ? mask : 0);
- mdelay(delay);
-
- return ret;
-}
-
-static int stpmu1_pwr_sw_probe(struct udevice *dev)
-{
- struct dm_regulator_uclass_platdata *uc_pdata;
-
- if (!dev->driver_data || dev->driver_data > STPMU1_MAX_PWR_SW)
- return -EINVAL;
-
- uc_pdata = dev_get_uclass_platdata(dev);
-
- uc_pdata->type = REGULATOR_TYPE_FIXED;
- uc_pdata->mode_count = 0;
-
- return 0;
-}
-
-static const struct dm_regulator_ops stpmu1_pwr_sw_ops = {
- .get_enable = stpmu1_pwr_sw_get_enable,
- .set_enable = stpmu1_pwr_sw_set_enable,
-};
-
-U_BOOT_DRIVER(stpmu1_pwr_sw) = {
- .name = "stpmu1_pwr_sw",
- .id = UCLASS_REGULATOR,
- .ops = &stpmu1_pwr_sw_ops,
- .probe = stpmu1_pwr_sw_probe,
-};
diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c
index bd497a3021d..e45a3b2658a 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ram.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ram.c
@@ -157,7 +157,8 @@ static int stm32mp1_ddr_probe(struct udevice *dev)
priv->info.base = STM32_DDR_BASE;
-#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+#if !defined(CONFIG_STM32MP1_TRUSTED) && \
+ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
priv->info.size = 0;
return stm32mp1_ddr_setup(dev);
#else
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 098372e0932..a700f240adf 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -222,8 +222,7 @@ config SPI_SUNXI
config STM32_QSPI
bool "STM32F7 QSPI driver"
- depends on STM32F7
- imply SPI_FLASH_BAR
+ depends on STM32F7 || ARCH_STM32MP
help
Enable the STM32F7 Quad-SPI (QSPI) driver. This driver can be
used to access the SPI NOR flash chips on platforms embedding
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 11fce9c4fe5..efdb178450e 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -256,7 +256,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
break;
case CQSPI_INDIRECT_WRITE:
err = cadence_qspi_apb_indirect_write_setup
- (plat, priv->cmd_len, cmd_buf);
+ (plat, priv->cmd_len, dm_plat->mode, cmd_buf);
if (!err) {
err = cadence_qspi_apb_indirect_write_execute
(plat, data_bytes, dout);
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 055900def00..b4914071308 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -60,7 +60,7 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
unsigned int rxlen, u8 *rxbuf);
int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf);
+ unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf);
int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat,
unsigned int txlen, const u8 *txbuf);
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index a8af3520303..55a7501913a 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -77,6 +77,7 @@
#define CQSPI_REG_WR_INSTR 0x08
#define CQSPI_REG_WR_INSTR_OPCODE_LSB 0
+#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16
#define CQSPI_REG_DELAY 0x0C
#define CQSPI_REG_DELAY_TSLCH_LSB 0
@@ -686,7 +687,7 @@ failrd:
/* Opcode + Address (3/4 bytes) */
int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
- unsigned int cmdlen, const u8 *cmdbuf)
+ unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf)
{
unsigned int reg;
unsigned int addr_bytes = cmdlen > 4 ? 4 : 3;
@@ -702,6 +703,10 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
/* Configure the opcode */
reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+
+ if (tx_width & SPI_TX_QUAD)
+ reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB;
+
writel(reg, plat->regbase + CQSPI_REG_WR_INSTR);
/* Setup write address. */
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index 764c94215e7..a68a51945e4 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -273,7 +273,18 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
if (len > 1) {
int tmp_len = len - 1;
while (tmp_len--) {
- if (dout != NULL) {
+ if ((dout != NULL) && (din != NULL)) {
+ if (priv->charbit == 16) {
+ dspi_tx(priv, ctrl, *spi_wr16++);
+ *spi_rd16++ = dspi_rx(priv);
+ }
+ else {
+ dspi_tx(priv, ctrl, *spi_wr++);
+ *spi_rd++ = dspi_rx(priv);
+ }
+ }
+
+ else if (dout != NULL) {
if (priv->charbit == 16)
dspi_tx(priv, ctrl, *spi_wr16++);
else
@@ -281,7 +292,7 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
dspi_rx(priv);
}
- if (din != NULL) {
+ else if (din != NULL) {
dspi_tx(priv, ctrl, DSPI_IDLE_VAL);
if (priv->charbit == 16)
*spi_rd16++ = dspi_rx(priv);
@@ -297,7 +308,18 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
ctrl &= ~DSPI_TFR_CONT;
if (len) {
- if (dout != NULL) {
+ if ((dout != NULL) && (din != NULL)) {
+ if (priv->charbit == 16) {
+ dspi_tx(priv, ctrl, *spi_wr16++);
+ *spi_rd16++ = dspi_rx(priv);
+ }
+ else {
+ dspi_tx(priv, ctrl, *spi_wr++);
+ *spi_rd++ = dspi_rx(priv);
+ }
+ }
+
+ else if (dout != NULL) {
if (priv->charbit == 16)
dspi_tx(priv, ctrl, *spi_wr16);
else
@@ -305,7 +327,7 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
dspi_rx(priv);
}
- if (din != NULL) {
+ else if (din != NULL) {
dspi_tx(priv, ctrl, DSPI_IDLE_VAL);
if (priv->charbit == 16)
*spi_rd16 = dspi_rx(priv);
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 1bb0987edb7..b86eee75bcb 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -214,7 +214,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
if (ret < 0)
return ret;
- if (ops->mem_ops) {
+ if (ops->mem_ops && ops->mem_ops->exec_op) {
#ifndef __UBOOT__
/*
* Flush the message queue before executing our SPI memory
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 2bc289a74cc..88cb2a12622 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -328,7 +328,9 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
}
plat = dev_get_parent_platdata(dev);
- if (!speed) {
+
+ /* get speed and mode from platdata when available */
+ if (plat->max_hz) {
speed = plat->max_hz;
mode = plat->mode;
}
diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c
index 8b60d7c3b22..bb1067ff4a9 100644
--- a/drivers/spi/stm32_qspi.c
+++ b/drivers/spi/stm32_qspi.c
@@ -9,15 +9,11 @@
#include <common.h>
#include <clk.h>
-#include <dm.h>
-#include <errno.h>
-#include <malloc.h>
#include <reset.h>
-#include <spi.h>
-#include <spi_flash.h>
-#include <asm/io.h>
-#include <asm/arch/stm32.h>
+#include <spi-mem.h>
+#include <linux/iopoll.h>
#include <linux/ioport.h>
+#include <linux/sizes.h>
struct stm32_qspi_regs {
u32 cr; /* 0x00 */
@@ -45,8 +41,7 @@ struct stm32_qspi_regs {
#define STM32_QSPI_CR_SSHIFT BIT(4)
#define STM32_QSPI_CR_DFM BIT(6)
#define STM32_QSPI_CR_FSEL BIT(7)
-#define STM32_QSPI_CR_FTHRES_MASK GENMASK(4, 0)
-#define STM32_QSPI_CR_FTHRES_SHIFT (8)
+#define STM32_QSPI_CR_FTHRES_SHIFT 8
#define STM32_QSPI_CR_TEIE BIT(16)
#define STM32_QSPI_CR_TCIE BIT(17)
#define STM32_QSPI_CR_FTIE BIT(18)
@@ -55,16 +50,16 @@ struct stm32_qspi_regs {
#define STM32_QSPI_CR_APMS BIT(22)
#define STM32_QSPI_CR_PMM BIT(23)
#define STM32_QSPI_CR_PRESCALER_MASK GENMASK(7, 0)
-#define STM32_QSPI_CR_PRESCALER_SHIFT (24)
+#define STM32_QSPI_CR_PRESCALER_SHIFT 24
/*
* QUADSPI device configuration register
*/
#define STM32_QSPI_DCR_CKMODE BIT(0)
#define STM32_QSPI_DCR_CSHT_MASK GENMASK(2, 0)
-#define STM32_QSPI_DCR_CSHT_SHIFT (8)
+#define STM32_QSPI_DCR_CSHT_SHIFT 8
#define STM32_QSPI_DCR_FSIZE_MASK GENMASK(4, 0)
-#define STM32_QSPI_DCR_FSIZE_SHIFT (16)
+#define STM32_QSPI_DCR_FSIZE_SHIFT 16
/*
* QUADSPI status register
@@ -75,8 +70,6 @@ struct stm32_qspi_regs {
#define STM32_QSPI_SR_SMF BIT(3)
#define STM32_QSPI_SR_TOF BIT(4)
#define STM32_QSPI_SR_BUSY BIT(5)
-#define STM32_QSPI_SR_FLEVEL_MASK GENMASK(5, 0)
-#define STM32_QSPI_SR_FLEVEL_SHIFT (8)
/*
* QUADSPI flag clear register
@@ -92,388 +85,276 @@ struct stm32_qspi_regs {
#define STM32_QSPI_CCR_DDRM BIT(31)
#define STM32_QSPI_CCR_DHHC BIT(30)
#define STM32_QSPI_CCR_SIOO BIT(28)
-#define STM32_QSPI_CCR_FMODE_SHIFT (26)
-#define STM32_QSPI_CCR_DMODE_SHIFT (24)
-#define STM32_QSPI_CCR_DCYC_SHIFT (18)
-#define STM32_QSPI_CCR_DCYC_MASK GENMASK(4, 0)
-#define STM32_QSPI_CCR_ABSIZE_SHIFT (16)
-#define STM32_QSPI_CCR_ABMODE_SHIFT (14)
-#define STM32_QSPI_CCR_ADSIZE_SHIFT (12)
-#define STM32_QSPI_CCR_ADMODE_SHIFT (10)
-#define STM32_QSPI_CCR_IMODE_SHIFT (8)
-#define STM32_QSPI_CCR_INSTRUCTION_MASK GENMASK(7, 0)
-
-enum STM32_QSPI_CCR_IMODE {
- STM32_QSPI_CCR_IMODE_NONE = 0,
- STM32_QSPI_CCR_IMODE_ONE_LINE = 1,
- STM32_QSPI_CCR_IMODE_TWO_LINE = 2,
- STM32_QSPI_CCR_IMODE_FOUR_LINE = 3,
-};
-
-enum STM32_QSPI_CCR_ADMODE {
- STM32_QSPI_CCR_ADMODE_NONE = 0,
- STM32_QSPI_CCR_ADMODE_ONE_LINE = 1,
- STM32_QSPI_CCR_ADMODE_TWO_LINE = 2,
- STM32_QSPI_CCR_ADMODE_FOUR_LINE = 3,
-};
-
-enum STM32_QSPI_CCR_ADSIZE {
- STM32_QSPI_CCR_ADSIZE_8BIT = 0,
- STM32_QSPI_CCR_ADSIZE_16BIT = 1,
- STM32_QSPI_CCR_ADSIZE_24BIT = 2,
- STM32_QSPI_CCR_ADSIZE_32BIT = 3,
-};
-
-enum STM32_QSPI_CCR_ABMODE {
- STM32_QSPI_CCR_ABMODE_NONE = 0,
- STM32_QSPI_CCR_ABMODE_ONE_LINE = 1,
- STM32_QSPI_CCR_ABMODE_TWO_LINE = 2,
- STM32_QSPI_CCR_ABMODE_FOUR_LINE = 3,
-};
-
-enum STM32_QSPI_CCR_ABSIZE {
- STM32_QSPI_CCR_ABSIZE_8BIT = 0,
- STM32_QSPI_CCR_ABSIZE_16BIT = 1,
- STM32_QSPI_CCR_ABSIZE_24BIT = 2,
- STM32_QSPI_CCR_ABSIZE_32BIT = 3,
-};
-
-enum STM32_QSPI_CCR_DMODE {
- STM32_QSPI_CCR_DMODE_NONE = 0,
- STM32_QSPI_CCR_DMODE_ONE_LINE = 1,
- STM32_QSPI_CCR_DMODE_TWO_LINE = 2,
- STM32_QSPI_CCR_DMODE_FOUR_LINE = 3,
-};
-
-enum STM32_QSPI_CCR_FMODE {
- STM32_QSPI_CCR_IND_WRITE = 0,
- STM32_QSPI_CCR_IND_READ = 1,
- STM32_QSPI_CCR_AUTO_POLL = 2,
- STM32_QSPI_CCR_MEM_MAP = 3,
-};
-
-/* default SCK frequency, unit: HZ */
-#define STM32_QSPI_DEFAULT_SCK_FREQ 108000000
-
-#define STM32_MAX_NORCHIP 2
-
-struct stm32_qspi_platdata {
- u32 base;
- u32 memory_map;
- u32 max_hz;
+#define STM32_QSPI_CCR_FMODE_SHIFT 26
+#define STM32_QSPI_CCR_DMODE_SHIFT 24
+#define STM32_QSPI_CCR_DCYC_SHIFT 18
+#define STM32_QSPI_CCR_ABSIZE_SHIFT 16
+#define STM32_QSPI_CCR_ABMODE_SHIFT 14
+#define STM32_QSPI_CCR_ADSIZE_SHIFT 12
+#define STM32_QSPI_CCR_ADMODE_SHIFT 10
+#define STM32_QSPI_CCR_IMODE_SHIFT 8
+
+#define STM32_QSPI_CCR_IND_WRITE 0
+#define STM32_QSPI_CCR_IND_READ 1
+#define STM32_QSPI_CCR_MEM_MAP 3
+
+#define STM32_QSPI_MAX_MMAP_SZ SZ_256M
+#define STM32_QSPI_MAX_CHIP 2
+
+#define STM32_QSPI_FIFO_TIMEOUT_US 30000
+#define STM32_QSPI_CMD_TIMEOUT_US 1000000
+#define STM32_BUSY_TIMEOUT_US 100000
+#define STM32_ABT_TIMEOUT_US 100000
+
+struct stm32_qspi_flash {
+ u32 cr;
+ u32 dcr;
+ bool initialized;
};
struct stm32_qspi_priv {
struct stm32_qspi_regs *regs;
+ struct stm32_qspi_flash flash[STM32_QSPI_MAX_CHIP];
+ void __iomem *mm_base;
+ resource_size_t mm_size;
ulong clock_rate;
- u32 max_hz;
- u32 mode;
-
- u32 command;
- u32 address;
- u32 dummycycles;
-#define CMD_HAS_ADR BIT(24)
-#define CMD_HAS_DUMMY BIT(25)
-#define CMD_HAS_DATA BIT(26)
+ int cs_used;
};
-static void _stm32_qspi_disable(struct stm32_qspi_priv *priv)
+static int _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv)
{
- clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
-}
+ u32 sr;
+ int ret;
-static void _stm32_qspi_enable(struct stm32_qspi_priv *priv)
-{
- setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
-}
+ ret = readl_poll_timeout(&priv->regs->sr, sr,
+ !(sr & STM32_QSPI_SR_BUSY),
+ STM32_BUSY_TIMEOUT_US);
+ if (ret)
+ pr_err("busy timeout (stat:%#x)\n", sr);
-static void _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv)
-{
- while (readl(&priv->regs->sr) & STM32_QSPI_SR_BUSY)
- ;
+ return ret;
}
-static void _stm32_qspi_wait_for_complete(struct stm32_qspi_priv *priv)
+static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv,
+ const struct spi_mem_op *op)
{
- while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_TCF))
- ;
-}
+ u32 sr;
+ int ret;
-static void _stm32_qspi_wait_for_ftf(struct stm32_qspi_priv *priv)
-{
- while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_FTF))
- ;
-}
+ if (!op->data.nbytes)
+ return _stm32_qspi_wait_for_not_busy(priv);
-static void _stm32_qspi_set_flash_size(struct stm32_qspi_priv *priv, u32 size)
-{
- u32 fsize = fls(size) - 1;
+ ret = readl_poll_timeout(&priv->regs->sr, sr,
+ sr & STM32_QSPI_SR_TCF,
+ STM32_QSPI_CMD_TIMEOUT_US);
+ if (ret) {
+ pr_err("cmd timeout (stat:%#x)\n", sr);
+ } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) {
+ pr_err("transfer error (stat:%#x)\n", sr);
+ ret = -EIO;
+ }
- clrsetbits_le32(&priv->regs->dcr,
- STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT,
- fsize << STM32_QSPI_DCR_FSIZE_SHIFT);
+ /* clear flags */
+ writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr);
+
+ return ret;
}
-static void _stm32_qspi_set_cs(struct stm32_qspi_priv *priv, unsigned int cs)
+static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr)
{
- clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL,
- cs ? STM32_QSPI_CR_FSEL : 0);
+ *val = readb(addr);
}
-static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv, u8 fmode)
+static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr)
{
- unsigned int ccr_reg = 0;
- u8 imode, admode, dmode;
- u32 mode = priv->mode;
- u32 cmd = (priv->command & STM32_QSPI_CCR_INSTRUCTION_MASK);
-
- imode = STM32_QSPI_CCR_IMODE_ONE_LINE;
- admode = STM32_QSPI_CCR_ADMODE_ONE_LINE;
- dmode = STM32_QSPI_CCR_DMODE_ONE_LINE;
-
- if ((priv->command & CMD_HAS_ADR) && (priv->command & CMD_HAS_DATA)) {
- if (fmode == STM32_QSPI_CCR_IND_WRITE) {
- if (mode & SPI_TX_QUAD)
- dmode = STM32_QSPI_CCR_DMODE_FOUR_LINE;
- else if (mode & SPI_TX_DUAL)
- dmode = STM32_QSPI_CCR_DMODE_TWO_LINE;
- } else if ((fmode == STM32_QSPI_CCR_MEM_MAP) ||
- (fmode == STM32_QSPI_CCR_IND_READ)) {
- if (mode & SPI_RX_QUAD)
- dmode = STM32_QSPI_CCR_DMODE_FOUR_LINE;
- else if (mode & SPI_RX_DUAL)
- dmode = STM32_QSPI_CCR_DMODE_TWO_LINE;
- }
- }
-
- if (priv->command & CMD_HAS_DATA)
- ccr_reg |= (dmode << STM32_QSPI_CCR_DMODE_SHIFT);
-
- if (priv->command & CMD_HAS_DUMMY)
- ccr_reg |= ((priv->dummycycles & STM32_QSPI_CCR_DCYC_MASK)
- << STM32_QSPI_CCR_DCYC_SHIFT);
-
- if (priv->command & CMD_HAS_ADR) {
- ccr_reg |= (STM32_QSPI_CCR_ADSIZE_24BIT
- << STM32_QSPI_CCR_ADSIZE_SHIFT);
- ccr_reg |= (admode << STM32_QSPI_CCR_ADMODE_SHIFT);
- }
-
- ccr_reg |= (fmode << STM32_QSPI_CCR_FMODE_SHIFT);
- ccr_reg |= (imode << STM32_QSPI_CCR_IMODE_SHIFT);
- ccr_reg |= cmd;
-
- return ccr_reg;
+ writeb(*val, addr);
}
-static void _stm32_qspi_enable_mmap(struct stm32_qspi_priv *priv,
- struct spi_flash *flash)
+static int _stm32_qspi_poll(struct stm32_qspi_priv *priv,
+ const struct spi_mem_op *op)
{
- unsigned int ccr_reg;
+ void (*fifo)(u8 *val, void __iomem *addr);
+ u32 len = op->data.nbytes, sr;
+ u8 *buf;
+ int ret;
- priv->command = flash->read_opcode | CMD_HAS_ADR | CMD_HAS_DATA
- | CMD_HAS_DUMMY;
- priv->dummycycles = flash->read_dummy;
+ if (op->data.dir == SPI_MEM_DATA_IN) {
+ fifo = _stm32_qspi_read_fifo;
+ buf = op->data.buf.in;
- ccr_reg = _stm32_qspi_gen_ccr(priv, STM32_QSPI_CCR_MEM_MAP);
+ } else {
+ fifo = _stm32_qspi_write_fifo;
+ buf = (u8 *)op->data.buf.out;
+ }
- _stm32_qspi_wait_for_not_busy(priv);
+ while (len--) {
+ ret = readl_poll_timeout(&priv->regs->sr, sr,
+ sr & STM32_QSPI_SR_FTF,
+ STM32_QSPI_FIFO_TIMEOUT_US);
+ if (ret) {
+ pr_err("fifo timeout (len:%d stat:%#x)\n", len, sr);
+ return ret;
+ }
- writel(ccr_reg, &priv->regs->ccr);
+ fifo(buf++, &priv->regs->dr);
+ }
- priv->dummycycles = 0;
+ return 0;
}
-static void _stm32_qspi_disable_mmap(struct stm32_qspi_priv *priv)
+static int stm32_qspi_mm(struct stm32_qspi_priv *priv,
+ const struct spi_mem_op *op)
{
- setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT);
-}
+ memcpy_fromio(op->data.buf.in, priv->mm_base + op->addr.val,
+ op->data.nbytes);
-static void _stm32_qspi_set_xfer_length(struct stm32_qspi_priv *priv,
- u32 length)
-{
- writel(length - 1, &priv->regs->dlr);
+ return 0;
}
-static void _stm32_qspi_start_xfer(struct stm32_qspi_priv *priv, u32 cr_reg)
+static int _stm32_qspi_tx(struct stm32_qspi_priv *priv,
+ const struct spi_mem_op *op,
+ u8 mode)
{
- writel(cr_reg, &priv->regs->ccr);
+ if (!op->data.nbytes)
+ return 0;
+
+ if (mode == STM32_QSPI_CCR_MEM_MAP)
+ return stm32_qspi_mm(priv, op);
- if (priv->command & CMD_HAS_ADR)
- writel(priv->address, &priv->regs->ar);
+ return _stm32_qspi_poll(priv, op);
}
-static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,
- struct spi_flash *flash, unsigned int bitlen,
- const u8 *dout, u8 *din, unsigned long flags)
+static int _stm32_qspi_get_mode(u8 buswidth)
{
- unsigned int words = bitlen / 8;
- u32 ccr_reg;
- int i;
+ if (buswidth == 4)
+ return 3;
- if (flags & SPI_XFER_MMAP) {
- _stm32_qspi_enable_mmap(priv, flash);
- return 0;
- } else if (flags & SPI_XFER_MMAP_END) {
- _stm32_qspi_disable_mmap(priv);
- return 0;
- }
-
- if (bitlen == 0)
- return -1;
+ return buswidth;
+}
- if (bitlen % 8) {
- debug("spi_xfer: Non byte aligned SPI transfer\n");
- return -1;
- }
+static int stm32_qspi_exec_op(struct spi_slave *slave,
+ const struct spi_mem_op *op)
+{
+ struct stm32_qspi_priv *priv = dev_get_priv(slave->dev->parent);
+ u32 cr, ccr, addr_max;
+ u8 mode = STM32_QSPI_CCR_IND_WRITE;
+ int timeout, ret;
+
+ debug("%s: cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
+ __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
+ op->dummy.buswidth, op->data.buswidth,
+ op->addr.val, op->data.nbytes);
+
+ ret = _stm32_qspi_wait_for_not_busy(priv);
+ if (ret)
+ return ret;
- if (dout && din) {
- debug("spi_xfer: QSPI cannot have data in and data out set\n");
- return -1;
- }
+ addr_max = op->addr.val + op->data.nbytes + 1;
- if (!dout && (flags & SPI_XFER_BEGIN)) {
- debug("spi_xfer: QSPI transfer must begin with command\n");
- return -1;
+ if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes) {
+ if (addr_max < priv->mm_size && op->addr.buswidth)
+ mode = STM32_QSPI_CCR_MEM_MAP;
+ else
+ mode = STM32_QSPI_CCR_IND_READ;
}
- if (dout) {
- if (flags & SPI_XFER_BEGIN) {
- /* data is command */
- priv->command = dout[0] | CMD_HAS_DATA;
- if (words >= 4) {
- /* address is here too */
- priv->address = (dout[1] << 16) |
- (dout[2] << 8) | dout[3];
- priv->command |= CMD_HAS_ADR;
- }
-
- if (words > 4) {
- /* rest is dummy bytes */
- priv->dummycycles = (words - 4) * 8;
- priv->command |= CMD_HAS_DUMMY;
- }
-
- if (flags & SPI_XFER_END) {
- /* command without data */
- priv->command &= ~(CMD_HAS_DATA);
- }
- }
-
- if (flags & SPI_XFER_END) {
- ccr_reg = _stm32_qspi_gen_ccr(priv,
- STM32_QSPI_CCR_IND_WRITE);
-
- _stm32_qspi_wait_for_not_busy(priv);
-
- if (priv->command & CMD_HAS_DATA)
- _stm32_qspi_set_xfer_length(priv, words);
-
- _stm32_qspi_start_xfer(priv, ccr_reg);
-
- debug("%s: write: ccr:0x%08x adr:0x%08x\n",
- __func__, priv->regs->ccr, priv->regs->ar);
-
- if (priv->command & CMD_HAS_DATA) {
- _stm32_qspi_wait_for_ftf(priv);
-
- debug("%s: words:%d data:", __func__, words);
+ if (op->data.nbytes)
+ writel(op->data.nbytes - 1, &priv->regs->dlr);
- i = 0;
- while (words > i) {
- writeb(dout[i], &priv->regs->dr);
- debug("%02x ", dout[i]);
- i++;
- }
- debug("\n");
+ ccr = (mode << STM32_QSPI_CCR_FMODE_SHIFT);
+ ccr |= op->cmd.opcode;
+ ccr |= (_stm32_qspi_get_mode(op->cmd.buswidth)
+ << STM32_QSPI_CCR_IMODE_SHIFT);
- _stm32_qspi_wait_for_complete(priv);
- } else {
- _stm32_qspi_wait_for_not_busy(priv);
- }
- }
- } else if (din) {
- ccr_reg = _stm32_qspi_gen_ccr(priv, STM32_QSPI_CCR_IND_READ);
+ if (op->addr.nbytes) {
+ ccr |= ((op->addr.nbytes - 1) << STM32_QSPI_CCR_ADSIZE_SHIFT);
+ ccr |= (_stm32_qspi_get_mode(op->addr.buswidth)
+ << STM32_QSPI_CCR_ADMODE_SHIFT);
+ }
- _stm32_qspi_wait_for_not_busy(priv);
+ if (op->dummy.buswidth && op->dummy.nbytes)
+ ccr |= (op->dummy.nbytes * 8 / op->dummy.buswidth
+ << STM32_QSPI_CCR_DCYC_SHIFT);
- _stm32_qspi_set_xfer_length(priv, words);
+ if (op->data.nbytes)
+ ccr |= (_stm32_qspi_get_mode(op->data.buswidth)
+ << STM32_QSPI_CCR_DMODE_SHIFT);
- _stm32_qspi_start_xfer(priv, ccr_reg);
+ writel(ccr, &priv->regs->ccr);
- debug("%s: read: ccr:0x%08x adr:0x%08x len:%d\n", __func__,
- priv->regs->ccr, priv->regs->ar, priv->regs->dlr);
+ if (op->addr.nbytes && mode != STM32_QSPI_CCR_MEM_MAP)
+ writel(op->addr.val, &priv->regs->ar);
- debug("%s: data:", __func__);
+ ret = _stm32_qspi_tx(priv, op, mode);
+ /*
+ * Abort in:
+ * -error case
+ * -read memory map: prefetching must be stopped if we read the last
+ * byte of device (device size - fifo size). like device size is not
+ * knows, the prefetching is always stop.
+ */
+ if (ret || mode == STM32_QSPI_CCR_MEM_MAP)
+ goto abort;
- i = 0;
- while (words > i) {
- din[i] = readb(&priv->regs->dr);
- debug("%02x ", din[i]);
- i++;
- }
- debug("\n");
- }
+ /* Wait end of tx in indirect mode */
+ ret = _stm32_qspi_wait_cmd(priv, op);
+ if (ret)
+ goto abort;
return 0;
-}
-
-static int stm32_qspi_ofdata_to_platdata(struct udevice *bus)
-{
- struct resource res_regs, res_mem;
- struct stm32_qspi_platdata *plat = bus->platdata;
- int ret;
- ret = dev_read_resource_byname(bus, "qspi", &res_regs);
- if (ret) {
- debug("Error: can't get regs base addresses(ret = %d)!\n", ret);
- return -ENOMEM;
- }
- ret = dev_read_resource_byname(bus, "qspi_mm", &res_mem);
- if (ret) {
- debug("Error: can't get mmap base address(ret = %d)!\n", ret);
- return -ENOMEM;
- }
+abort:
+ setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT);
- plat->max_hz = dev_read_u32_default(bus, "spi-max-frequency",
- STM32_QSPI_DEFAULT_SCK_FREQ);
+ /* Wait clear of abort bit by hw */
+ timeout = readl_poll_timeout(&priv->regs->cr, cr,
+ !(cr & STM32_QSPI_CR_ABORT),
+ STM32_ABT_TIMEOUT_US);
- plat->base = res_regs.start;
- plat->memory_map = res_mem.start;
+ writel(STM32_QSPI_FCR_CTCF, &priv->regs->fcr);
- debug("%s: regs=<0x%x> mapped=<0x%x>, max-frequency=%d\n",
- __func__,
- plat->base,
- plat->memory_map,
- plat->max_hz
- );
+ if (ret || timeout)
+ pr_err("%s ret:%d abort timeout:%d\n", __func__, ret, timeout);
- return 0;
+ return ret;
}
static int stm32_qspi_probe(struct udevice *bus)
{
- struct stm32_qspi_platdata *plat = dev_get_platdata(bus);
struct stm32_qspi_priv *priv = dev_get_priv(bus);
- struct dm_spi_bus *dm_spi_bus;
+ struct resource res;
struct clk clk;
struct reset_ctl reset_ctl;
int ret;
- dm_spi_bus = bus->uclass_priv;
+ ret = dev_read_resource_byname(bus, "qspi", &res);
+ if (ret) {
+ dev_err(bus, "can't get regs base addresses(ret = %d)!\n", ret);
+ return ret;
+ }
- dm_spi_bus->max_hz = plat->max_hz;
+ priv->regs = (struct stm32_qspi_regs *)res.start;
- priv->regs = (struct stm32_qspi_regs *)(uintptr_t)plat->base;
+ ret = dev_read_resource_byname(bus, "qspi_mm", &res);
+ if (ret) {
+ dev_err(bus, "can't get mmap base address(ret = %d)!\n", ret);
+ return ret;
+ }
- priv->max_hz = plat->max_hz;
+ priv->mm_base = (void __iomem *)res.start;
+
+ priv->mm_size = resource_size(&res);
+ if (priv->mm_size > STM32_QSPI_MAX_MMAP_SZ)
+ return -EINVAL;
+
+ debug("%s: regs=<0x%p> mapped=<0x%p> mapped_size=<0x%lx>\n",
+ __func__, priv->regs, priv->mm_base, priv->mm_size);
ret = clk_get_by_index(bus, 0, &clk);
if (ret < 0)
return ret;
ret = clk_enable(&clk);
-
if (ret) {
dev_err(bus, "failed to enable clock\n");
return ret;
@@ -499,78 +380,68 @@ static int stm32_qspi_probe(struct udevice *bus)
reset_deassert(&reset_ctl);
}
+ priv->cs_used = -1;
+
setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT);
- return 0;
-}
+ /* Set dcr fsize to max address */
+ setbits_le32(&priv->regs->dcr,
+ STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT);
-static int stm32_qspi_remove(struct udevice *bus)
-{
return 0;
}
static int stm32_qspi_claim_bus(struct udevice *dev)
{
- struct stm32_qspi_priv *priv;
- struct udevice *bus;
- struct spi_flash *flash;
- struct dm_spi_slave_platdata *slave_plat;
+ struct stm32_qspi_priv *priv = dev_get_priv(dev->parent);
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
- bus = dev->parent;
- priv = dev_get_priv(bus);
- flash = dev_get_uclass_priv(dev);
- slave_plat = dev_get_parent_platdata(dev);
-
- if (slave_plat->cs >= STM32_MAX_NORCHIP)
+ if (slave_plat->cs >= STM32_QSPI_MAX_CHIP)
return -ENODEV;
- _stm32_qspi_set_cs(priv, slave_plat->cs);
-
- _stm32_qspi_set_flash_size(priv, flash->size);
+ if (priv->cs_used != slave_plat->cs) {
+ struct stm32_qspi_flash *flash = &priv->flash[slave_plat->cs];
- _stm32_qspi_enable(priv);
+ priv->cs_used = slave_plat->cs;
- return 0;
-}
+ if (flash->initialized) {
+ /* Set the configuration: speed + cs */
+ writel(flash->cr, &priv->regs->cr);
+ writel(flash->dcr, &priv->regs->dcr);
+ } else {
+ /* Set chip select */
+ clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL,
+ priv->cs_used ? STM32_QSPI_CR_FSEL : 0);
-static int stm32_qspi_release_bus(struct udevice *dev)
-{
- struct stm32_qspi_priv *priv;
- struct udevice *bus;
+ /* Save the configuration: speed + cs */
+ flash->cr = readl(&priv->regs->cr);
+ flash->dcr = readl(&priv->regs->dcr);
- bus = dev->parent;
- priv = dev_get_priv(bus);
+ flash->initialized = true;
+ }
+ }
- _stm32_qspi_disable(priv);
+ setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
return 0;
}
-static int stm32_qspi_xfer(struct udevice *dev, unsigned int bitlen,
- const void *dout, void *din, unsigned long flags)
+static int stm32_qspi_release_bus(struct udevice *dev)
{
- struct stm32_qspi_priv *priv;
- struct udevice *bus;
- struct spi_flash *flash;
+ struct stm32_qspi_priv *priv = dev_get_priv(dev->parent);
- bus = dev->parent;
- priv = dev_get_priv(bus);
- flash = dev_get_uclass_priv(dev);
+ clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN);
- return _stm32_qspi_xfer(priv, flash, bitlen, (const u8 *)dout,
- (u8 *)din, flags);
+ return 0;
}
static int stm32_qspi_set_speed(struct udevice *bus, uint speed)
{
- struct stm32_qspi_platdata *plat = bus->platdata;
struct stm32_qspi_priv *priv = dev_get_priv(bus);
u32 qspi_clk = priv->clock_rate;
u32 prescaler = 255;
u32 csht;
-
- if (speed > plat->max_hz)
- speed = plat->max_hz;
+ int ret;
if (speed > 0) {
prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1;
@@ -583,7 +454,9 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed)
csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000);
csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK;
- _stm32_qspi_wait_for_not_busy(priv);
+ ret = _stm32_qspi_wait_for_not_busy(priv);
+ if (ret)
+ return ret;
clrsetbits_le32(&priv->regs->cr,
STM32_QSPI_CR_PRESCALER_MASK <<
@@ -603,8 +476,11 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed)
static int stm32_qspi_set_mode(struct udevice *bus, uint mode)
{
struct stm32_qspi_priv *priv = dev_get_priv(bus);
+ int ret;
- _stm32_qspi_wait_for_not_busy(priv);
+ ret = _stm32_qspi_wait_for_not_busy(priv);
+ if (ret)
+ return ret;
if ((mode & SPI_CPHA) && (mode & SPI_CPOL))
setbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE);
@@ -616,20 +492,6 @@ static int stm32_qspi_set_mode(struct udevice *bus, uint mode)
if (mode & SPI_CS_HIGH)
return -ENODEV;
- if (mode & SPI_RX_QUAD)
- priv->mode |= SPI_RX_QUAD;
- else if (mode & SPI_RX_DUAL)
- priv->mode |= SPI_RX_DUAL;
- else
- priv->mode &= ~(SPI_RX_QUAD | SPI_RX_DUAL);
-
- if (mode & SPI_TX_QUAD)
- priv->mode |= SPI_TX_QUAD;
- else if (mode & SPI_TX_DUAL)
- priv->mode |= SPI_TX_DUAL;
- else
- priv->mode &= ~(SPI_TX_QUAD | SPI_TX_DUAL);
-
debug("%s: regs=%p, mode=%d rx: ", __func__, priv->regs, mode);
if (mode & SPI_RX_QUAD)
@@ -649,12 +511,16 @@ static int stm32_qspi_set_mode(struct udevice *bus, uint mode)
return 0;
}
+static const struct spi_controller_mem_ops stm32_qspi_mem_ops = {
+ .exec_op = stm32_qspi_exec_op,
+};
+
static const struct dm_spi_ops stm32_qspi_ops = {
.claim_bus = stm32_qspi_claim_bus,
.release_bus = stm32_qspi_release_bus,
- .xfer = stm32_qspi_xfer,
.set_speed = stm32_qspi_set_speed,
.set_mode = stm32_qspi_set_mode,
+ .mem_ops = &stm32_qspi_mem_ops,
};
static const struct udevice_id stm32_qspi_ids[] = {
@@ -664,13 +530,10 @@ static const struct udevice_id stm32_qspi_ids[] = {
};
U_BOOT_DRIVER(stm32_qspi) = {
- .name = "stm32_qspi",
- .id = UCLASS_SPI,
+ .name = "stm32_qspi",
+ .id = UCLASS_SPI,
.of_match = stm32_qspi_ids,
- .ops = &stm32_qspi_ops,
- .ofdata_to_platdata = stm32_qspi_ofdata_to_platdata,
- .platdata_auto_alloc_size = sizeof(struct stm32_qspi_platdata),
+ .ops = &stm32_qspi_ops,
.priv_auto_alloc_size = sizeof(struct stm32_qspi_priv),
- .probe = stm32_qspi_probe,
- .remove = stm32_qspi_remove,
+ .probe = stm32_qspi_probe,
};
diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c
index 34506402ac3..3fb39b9952e 100644
--- a/drivers/sysreset/sysreset_syscon.c
+++ b/drivers/sysreset/sysreset_syscon.c
@@ -36,20 +36,9 @@ static struct sysreset_ops syscon_reboot_ops = {
int syscon_reboot_probe(struct udevice *dev)
{
struct syscon_reboot_priv *priv = dev_get_priv(dev);
- int err;
- u32 phandle;
- ofnode node;
- err = ofnode_read_u32(dev_ofnode(dev), "regmap", &phandle);
- if (err)
- return err;
-
- node = ofnode_get_by_phandle(phandle);
- if (!ofnode_valid(node))
- return -EINVAL;
-
- priv->regmap = syscon_node_to_regmap(node);
- if (!priv->regmap) {
+ priv->regmap = syscon_regmap_lookup_by_phandle(dev, "regmap");
+ if (IS_ERR(priv->regmap)) {
pr_err("unable to find regmap\n");
return -ENODEV;
}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2eac4b63813..43412873c98 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -120,7 +120,7 @@ config CONSOLE_TRUETYPE_SIZE
config SYS_WHITE_ON_BLACK
bool "Display console as white on a black background"
- default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || TEGRA || X86
+ default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || TEGRA || X86 || ARCH_SUNXI
help
Normally the display is black on a white background, Enable this
option to invert this, i.e. white on a black background. This can be
diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index 2cfa510d5f7..7f01ee94242 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -84,7 +84,8 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
return -EAGAIN;
for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
- uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
+ unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
+ uchar bits = video_fontdata[idx];
switch (vid_priv->bpix) {
#ifdef CONFIG_VIDEO_BPP8
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index f076570335b..71a5c5efba3 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -90,7 +90,7 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
int i, col;
int mask = 0x80;
void *line;
- uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
+ uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
vid_priv->line_length - (y + 1) * pbytes;
@@ -222,7 +222,8 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
- uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
+ unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
+ uchar bits = video_fontdata[idx];
switch (vid_priv->bpix) {
#ifdef CONFIG_VIDEO_BPP8
@@ -348,7 +349,7 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
void *line = vid_priv->fb +
(vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
vid_priv->line_length + y * pbytes;
- uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
+ uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c
index bd733f5f1ca..a587977c225 100644
--- a/drivers/video/pwm_backlight.c
+++ b/drivers/video/pwm_backlight.c
@@ -39,6 +39,12 @@ struct pwm_backlight_priv {
struct udevice *pwm;
uint channel;
uint period_ns;
+ /*
+ * the polarity of one PWM
+ * 0: normal polarity
+ * 1: inverted polarity
+ */
+ bool polarity;
u32 *levels;
int num_levels;
uint default_level;
@@ -57,7 +63,10 @@ static int set_pwm(struct pwm_backlight_priv *priv)
(priv->max_level - priv->min_level + 1);
ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns,
duty_cycle);
+ if (ret)
+ return log_ret(ret);
+ ret = pwm_set_invert(priv->pwm, priv->channel, priv->polarity);
return log_ret(ret);
}
@@ -202,6 +211,8 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev)
return log_msg_ret("Not enough arguments to pwm\n", -EINVAL);
priv->channel = args.args[0];
priv->period_ns = args.args[1];
+ if (args.args_count > 2)
+ priv->polarity = args.args[2];
index = dev_read_u32_default(dev, "default-brightness-level", 255);
cell = dev_read_prop(dev, "brightness-levels", &len);
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 2ca19d40491..c31303b56ed 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -259,6 +259,43 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
priv->escape = 0;
switch (ch) {
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F': {
+ int row, col, num;
+ char *s = priv->escape_buf;
+
+ /*
+ * Cursor up/down: [%dA, [%dB, [%dE, [%dF
+ * Cursor left/right: [%dD, [%dC
+ */
+ s++; /* [ */
+ s = parsenum(s, &num);
+ if (num == 0) /* No digit in sequence ... */
+ num = 1; /* ... means "move by 1". */
+
+ get_cursor_position(priv, &row, &col);
+ if (ch == 'A' || ch == 'F')
+ row -= num;
+ if (ch == 'C')
+ col += num;
+ if (ch == 'D')
+ col -= num;
+ if (ch == 'B' || ch == 'E')
+ row += num;
+ if (ch == 'E' || ch == 'F')
+ col = 0;
+ if (col < 0)
+ col = 0;
+ if (row < 0)
+ row = 0;
+ /* Right and bottom overflows are handled in the callee. */
+ set_cursor_position(priv, row, col);
+ break;
+ }
case 'H':
case 'f': {
int row, col;
@@ -309,6 +346,25 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
}
break;
}
+ case 'K': {
+ struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ int mode;
+
+ /*
+ * Clear (parts of) current line
+ * [0K - clear line to end
+ * [2K - clear entire line
+ */
+ parsenum(priv->escape_buf + 1, &mode);
+
+ if (mode == 2) {
+ int row, col;
+
+ get_cursor_position(priv, &row, &col);
+ vidconsole_set_row(dev, row, vid_priv->colour_bg);
+ }
+ break;
+ }
case 'm': {
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
char *s = priv->escape_buf;
@@ -360,6 +416,13 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
vid_priv->colour_fg = vid_console_color(
vid_priv, vid_priv->fg_col_idx);
break;
+ case 7:
+ /* reverse video */
+ vid_priv->colour_fg = vid_console_color(
+ vid_priv, vid_priv->bg_col_idx);
+ vid_priv->colour_bg = vid_console_color(
+ vid_priv, vid_priv->fg_col_idx);
+ break;
case 30 ... 37:
/* foreground color */
vid_priv->fg_col_idx &= ~7;
@@ -368,9 +431,11 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
vid_priv, vid_priv->fg_col_idx);
break;
case 40 ... 47:
- /* background color */
+ /* background color, also mask the bold bit */
+ vid_priv->bg_col_idx &= ~0xf;
+ vid_priv->bg_col_idx |= val - 40;
vid_priv->colour_bg = vid_console_color(
- vid_priv, val - 40);
+ vid_priv, vid_priv->bg_col_idx);
break;
default:
/* ignore unsupported SGR parameter */
@@ -392,6 +457,32 @@ error:
priv->escape = 0;
}
+/* Put that actual character on the screen (using the CP437 code page). */
+static int vidconsole_output_glyph(struct udevice *dev, char ch)
+{
+ struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+ int ret;
+
+ /*
+ * Failure of this function normally indicates an unsupported
+ * colour depth. Check this and return an error to help with
+ * diagnosis.
+ */
+ ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch);
+ if (ret == -EAGAIN) {
+ vidconsole_newline(dev);
+ ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch);
+ }
+ if (ret < 0)
+ return ret;
+ priv->xcur_frac += ret;
+ priv->last_ch = ch;
+ if (priv->xcur_frac >= priv->xsize_frac)
+ vidconsole_newline(dev);
+
+ return 0;
+}
+
int vidconsole_put_char(struct udevice *dev, char ch)
{
struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
@@ -429,23 +520,9 @@ int vidconsole_put_char(struct udevice *dev, char ch)
priv->last_ch = 0;
break;
default:
- /*
- * Failure of this function normally indicates an unsupported
- * colour depth. Check this and return an error to help with
- * diagnosis.
- */
- ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch);
- if (ret == -EAGAIN) {
- vidconsole_newline(dev);
- ret = vidconsole_putc_xy(dev, priv->xcur_frac,
- priv->ycur, ch);
- }
+ ret = vidconsole_output_glyph(dev, ch);
if (ret < 0)
return ret;
- priv->xcur_frac += ret;
- priv->last_ch = ch;
- if (priv->xcur_frac >= priv->xsize_frac)
- vidconsole_newline(dev);
break;
}
diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index f307cf243bd..14aac88d6d2 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -136,6 +136,7 @@ void video_set_default_colors(struct udevice *dev, bool invert)
back = temp;
}
priv->fg_col_idx = fore;
+ priv->bg_col_idx = back;
priv->colour_fg = vid_console_color(priv, fore);
priv->colour_bg = vid_console_color(priv, back);
}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 34e78beb2a6..9d7f503b698 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -97,6 +97,7 @@ config WDT_BCM6345
config WDT_ORION
bool "Orion watchdog timer support"
depends on WDT
+ select CLK
help
Select this to enable Orion watchdog timer, which can be found on some
Marvell Armada chips.
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index a0df02d1038..885821d562e 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -14,7 +14,9 @@
#include <common.h>
#include <dm.h>
+#include <clk.h>
#include <wdt.h>
+#include <linux/kernel.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
@@ -27,6 +29,8 @@ struct orion_wdt_priv {
void __iomem *rstout;
void __iomem *rstout_mask;
u32 timeout;
+ unsigned long clk_rate;
+ struct clk clk;
};
#define RSTOUT_ENABLE_BIT BIT(8)
@@ -44,17 +48,18 @@ static int orion_wdt_reset(struct udevice *dev)
struct orion_wdt_priv *priv = dev_get_priv(dev);
/* Reload watchdog duration */
- writel(priv->timeout, priv->reg + priv->wdt_counter_offset);
+ writel(priv->clk_rate * priv->timeout,
+ priv->reg + priv->wdt_counter_offset);
return 0;
}
-static int orion_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+static int orion_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
struct orion_wdt_priv *priv = dev_get_priv(dev);
u32 reg;
- priv->timeout = (u32) timeout;
+ priv->timeout = DIV_ROUND_UP(timeout_ms, 1000);
/* Enable the fixed watchdog clock input */
reg = readl(priv->reg + TIMER_CTRL);
@@ -62,7 +67,8 @@ static int orion_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
writel(reg, priv->reg + TIMER_CTRL);
/* Set watchdog duration */
- writel(priv->timeout, priv->reg + priv->wdt_counter_offset);
+ writel(priv->clk_rate * priv->timeout,
+ priv->reg + priv->wdt_counter_offset);
/* Clear the watchdog expiration bit */
reg = readl(priv->reg + TIMER_A370_STATUS);
@@ -114,9 +120,7 @@ static inline bool save_reg_from_ofdata(struct udevice *dev, int index,
fdt_addr_t addr;
fdt_size_t off;
- addr = fdtdec_get_addr_size_auto_noparent(
- gd->fdt_blob, dev_of_offset(dev), "reg", index, &off, true);
-
+ addr = devfdt_get_addr_size_index(dev, index, &off);
if (addr == FDT_ADDR_T_NONE)
return false;
@@ -149,9 +153,18 @@ err:
static int orion_wdt_probe(struct udevice *dev)
{
+ struct orion_wdt_priv *priv = dev_get_priv(dev);
+ int ret;
+
debug("%s: Probing wdt%u\n", __func__, dev->seq);
orion_wdt_stop(dev);
+ ret = clk_get_by_name(dev, "fixed", &priv->clk);
+ if (!ret)
+ priv->clk_rate = clk_get_rate(&priv->clk);
+ else
+ priv->clk_rate = 25000000;
+
return 0;
}
diff --git a/dts/Kconfig b/dts/Kconfig
index a5f30c8fd03..c9ab66cccc8 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -291,10 +291,10 @@ config SPL_MULTI_DTB_FIT_USER_DEF_ADDR
config OF_SPL_REMOVE_PROPS
string "List of device tree properties to drop for SPL"
depends on SPL_OF_CONTROL
- default "interrupt-parent" if SPL_PINCTRL && SPL_CLK
- default "clocks clock-names interrupt-parent" if SPL_PINCTRL
- default "pinctrl-0 pinctrl-names interrupt-parent" if SPL_CLK
- default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent"
+ default "interrupt-parent interrupts" if SPL_PINCTRL && SPL_CLK
+ default "clocks clock-names interrupt-parent interrupts" if SPL_PINCTRL
+ default "pinctrl-0 pinctrl-names interrupt-parent interrupts" if SPL_CLK
+ default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupts"
help
Since SPL normally runs in a reduced memory space, the device tree
is cut down to only what is needed to load and start U-Boot. Only
diff --git a/include/configs/ap152.h b/include/configs/ap152.h
new file mode 100644
index 00000000000..c948a440541
--- /dev/null
+++ b/include/configs/ap152.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com>
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_MHZ 375
+#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000)
+
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MALLOC_LEN 0x40000
+#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
+
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+#define CONFIG_SYS_LOAD_ADDR 0x81000000
+
+#define CONFIG_SYS_INIT_RAM_ADDR 0xbd000000
+#define CONFIG_SYS_INIT_RAM_SIZE 0x2000
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1)
+
+/*
+ * Serial Port
+ */
+#define CONFIG_SYS_NS16550_CLK 25000000
+#define CONFIG_SYS_BAUDRATE_TABLE \
+ {9600, 19200, 38400, 57600, 115200}
+
+#define CONFIG_BOOTCOMMAND "sf probe;" \
+ "mtdparts default;" \
+ "bootm 0x9f060000"
+
+#define CONFIG_ENV_SPI_MAX_HZ 25000000
+#define CONFIG_ENV_OFFSET 0x40000
+#define CONFIG_ENV_SECT_SIZE 0x10000
+#define CONFIG_ENV_SIZE 0x10000
+
+/* Miscellaneous configurable options */
+
+/*
+ * Diagnostics
+ */
+#define CONFIG_SYS_MEMTEST_START 0x80100000
+#define CONFIG_SYS_MEMTEST_END 0x83f00000
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h
index c51cf284502..9f8d3cc9e5e 100644
--- a/include/configs/clearfog.h
+++ b/include/configs/clearfog.h
@@ -21,8 +21,6 @@
* Commands configuration
*/
-/* SPI NOR flash default params, used by sf commands */
-
/*
* SDIO/MMC Card Configuration
*/
diff --git a/include/configs/db-88f6720.h b/include/configs/db-88f6720.h
index 55968c2749e..63194d58a29 100644
--- a/include/configs/db-88f6720.h
+++ b/include/configs/db-88f6720.h
@@ -32,8 +32,6 @@
#define CONFIG_EHCI_IS_TDI
#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
-/* SPI NOR flash default params, used by sf commands */
-
/* Environment in SPI NOR flash */
#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
diff --git a/include/configs/db-88f6820-amc.h b/include/configs/db-88f6820-amc.h
index f1bdc2d3e74..2fdc8450292 100644
--- a/include/configs/db-88f6820-amc.h
+++ b/include/configs/db-88f6820-amc.h
@@ -16,8 +16,6 @@
* Commands configuration
*/
-/* SPI NOR flash default params, used by sf commands */
-
/* USB/EHCI configuration */
#define CONFIG_EHCI_IS_TDI
diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h
index d378052a8f7..ec2405bbb45 100644
--- a/include/configs/db-88f6820-gp.h
+++ b/include/configs/db-88f6820-gp.h
@@ -24,12 +24,6 @@
#define CONFIG_SYS_I2C_SPEED 100000
/*
- * SPI Flash configuration for the environemnt access
- */
-
-/* SPI NOR flash default params, used by sf commands */
-
-/*
* SDIO/MMC Card Configuration
*/
#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE
diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h
index b78dbcb6b94..1f9d24b19b9 100644
--- a/include/configs/db-mv784mp-gp.h
+++ b/include/configs/db-mv784mp-gp.h
@@ -29,8 +29,6 @@
#define CONFIG_EHCI_IS_TDI
#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
-/* SPI NOR flash default params, used by sf commands */
-
/* Environment in SPI NOR flash */
#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
diff --git a/include/configs/db-xc3-24g4xg.h b/include/configs/db-xc3-24g4xg.h
new file mode 100644
index 00000000000..0f75ad71859
--- /dev/null
+++ b/include/configs/db-xc3-24g4xg.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ */
+
+#ifndef _CONFIG_DB_XC3_24G4G_H
+#define _CONFIG_DB_XC3_24G4G_H
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+
+#define CONFIG_SYS_KWD_CONFIG $(CONFIG_BOARDDIR)/kwbimage.cfg
+#define CONFIG_SYS_TCLK 200000000 /* 200MHz */
+
+/* USB/EHCI configuration */
+#define CONFIG_EHCI_IS_TDI
+
+/* Environment in SPI NOR flash */
+#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */
+#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
+#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */
+
+/* NAND */
+#define CONFIG_SYS_NAND_USE_FLASH_BBT
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* Keep device tree and initrd in lower memory so the kernel can access them */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "fdt_high=0x10000000\0" \
+ "initrd_high=0x10000000\0"
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#include "mv-common.h"
+#undef CONFIG_SYS_MAXARGS
+#define CONFIG_SYS_MAXARGS 96
+
+#endif /* _CONFIG_DB_XC3_24G4G_H */
diff --git a/include/configs/ds414.h b/include/configs/ds414.h
index 275a2b47880..192c055c5cc 100644
--- a/include/configs/ds414.h
+++ b/include/configs/ds414.h
@@ -28,8 +28,6 @@
#define CONFIG_SYS_I2C_SLAVE 0x0
#define CONFIG_SYS_I2C_SPEED 100000
-/* SPI NOR flash default params, used by sf commands */
-
/* Environment in SPI NOR flash */
#define CONFIG_ENV_OFFSET 0x7E0000 /* RedBoot config partition in DTS */
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
diff --git a/include/configs/helios4.h b/include/configs/helios4.h
index df4d8bcb3bb..b2badab15ea 100644
--- a/include/configs/helios4.h
+++ b/include/configs/helios4.h
@@ -23,8 +23,6 @@
* Commands configuration
*/
-/* SPI NOR flash default params, used by sf commands */
-
/*
* SDIO/MMC Card Configuration
*/
diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h
index 72e62658d0c..55c4e633254 100644
--- a/include/configs/lsxl.h
+++ b/include/configs/lsxl.h
@@ -76,9 +76,9 @@
"kernel_addr=0x00800000\0" \
"ramdisk_addr=0x01000000\0" \
"fdt_addr=0x00ff0000\0" \
- "bootcmd_legacy=ide reset " \
- "&& load ide ${hdpart} ${kernel_addr} /uImage.buffalo " \
- "&& load ide ${hdpart} ${ramdisk_addr} /initrd.buffalo "\
+ "bootcmd_legacy=sata init " \
+ "&& load sata ${hdpart} ${kernel_addr} /uImage.buffalo "\
+ "&& load sata ${hdpart} ${ramdisk_addr} /initrd.buffalo "\
"&& bootm ${kernel_addr} ${ramdisk_addr}\0" \
"bootcmd_net=bootp ${kernel_addr} vmlinuz " \
"&& tftpboot ${ramdisk_addr} initrd.img " \
@@ -86,11 +86,11 @@
"&& tftpboot ${fdt_addr} " CONFIG_FDTFILE " " \
"&& bootz ${kernel_addr} " \
"${ramdisk_addr}:${ramdisk_len} ${fdt_addr}\0" \
- "bootcmd_hdd=ide reset " \
- "&& load ide ${hdpart} ${kernel_addr} /vmlinuz " \
- "&& load ide ${hdpart} ${ramdisk_addr} /initrd.img " \
+ "bootcmd_hdd=sata init " \
+ "&& load sata ${hdpart} ${kernel_addr} /vmlinuz " \
+ "&& load sata ${hdpart} ${ramdisk_addr} /initrd.img " \
"&& setenv ramdisk_len ${filesize} " \
- "&& load ide ${hdpart} ${fdt_addr} /dtb " \
+ "&& load sata ${hdpart} ${fdt_addr} /dtb " \
"&& bootz ${kernel_addr} " \
"${ramdisk_addr}:${ramdisk_len} ${fdt_addr}\0" \
"bootcmd_usb=usb start " \
@@ -131,13 +131,10 @@
#undef CONFIG_RESET_PHY_R
#endif /* CONFIG_CMD_NET */
-#ifdef CONFIG_IDE
-#undef CONFIG_SYS_IDE_MAXBUS
-#define CONFIG_SYS_IDE_MAXBUS 1
-#undef CONFIG_SYS_IDE_MAXDEVICE
-#define CONFIG_SYS_IDE_MAXDEVICE 1
-#define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET
+#ifdef CONFIG_SATA
+#define CONFIG_SYS_SATA_MAX_DEVICE 1
#define CONFIG_SYS_64BIT_LBA
+#define CONFIG_LBA48
#endif
#endif /* _CONFIG_LSXL_H */
diff --git a/include/configs/mvebu_armada-8k.h b/include/configs/mvebu_armada-8k.h
index f4972b64dcb..b28f3b94085 100644
--- a/include/configs/mvebu_armada-8k.h
+++ b/include/configs/mvebu_armada-8k.h
@@ -49,10 +49,6 @@
/* End of 16M scrubbed by training in bootrom */
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0xFF0000)
-/*
- * SPI Flash configuration
- */
-
#define CONFIG_ENV_OFFSET 0x180000 /* as Marvell U-Boot version */
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
#define CONFIG_ENV_SECT_SIZE (64 << 10) /* 64KiB sectors */
diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index 701298cab88..737dfd6a5c2 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -10,17 +10,17 @@
#include <linux/sizes.h>
#include <asm/arch/stm32.h>
-#define CONFIG_PREBOOT
-
/*
* Number of clock ticks in 1 sec
*/
#define CONFIG_SYS_HZ 1000
+#ifndef CONFIG_STM32MP1_TRUSTED
/* PSCI support */
#define CONFIG_ARMV7_PSCI_1_0
#define CONFIG_ARMV7_SECURE_BASE STM32_SYSRAM_BASE
#define CONFIG_ARMV7_SECURE_MAX_SIZE STM32_SYSRAM_SIZE
+#endif
/*
* malloc() pool size
@@ -53,6 +53,9 @@
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
+/* Extend size of kernel image for uncompression */
+#define CONFIG_SYS_BOOTM_LEN SZ_32M
+
/* SPL support */
#ifdef CONFIG_SPL
/* BOOTROM load address */
@@ -69,36 +72,65 @@
STM32_SYSRAM_SIZE)
#endif /* #ifdef CONFIG_SPL */
+#define CONFIG_SYS_MEMTEST_START STM32_DDR_BASE
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + SZ_64M)
+#define CONFIG_SYS_MEMTEST_SCRATCH (CONFIG_SYS_MEMTEST_END + 4)
+
/*MMC SD*/
#define CONFIG_SYS_MMC_MAX_DEVICE 3
#define CONFIG_SUPPORT_EMMC_BOOT
-#if !defined(CONFIG_SPL) || !defined(CONFIG_SPL_BUILD)
+/*****************************************************************************/
+#ifdef CONFIG_DISTRO_DEFAULTS
+/*****************************************************************************/
+
+#if !defined(CONFIG_SPL_BUILD)
#define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 1) \
func(MMC, mmc, 0) \
func(MMC, mmc, 2)
+/*
+ * bootcmd for stm32mp1:
+ * for serial/usb: execute the stm32prog command
+ * for mmc boot (eMMC, SD card), boot only on the same device
+ * for nand boot, boot with on ubifs partition on nand
+ * for nor boot, use the default order
+ */
+#define CONFIG_PREBOOT
-#include <config_distro_bootcmd.h>
+#define STM32MP_BOOTCMD "bootcmd_stm32mp=" \
+ "echo \"Boot over ${boot_device}${boot_instance}!\";" \
+ "if test ${boot_device} = serial || test ${boot_device} = usb;" \
+ "then stm32prog ${boot_device} ${boot_instance}; " \
+ "else " \
+ "if test ${boot_device} = mmc;" \
+ "then env set boot_targets \"mmc${boot_instance}\"; fi;" \
+ "if test ${boot_device} = nand;" \
+ "then env set boot_targets ubifs0; fi;" \
+ "run distro_bootcmd;" \
+ "fi;\0"
-#define STM32MP_PREBOOT \
- "echo \"Boot over ${boot_device}${boot_instance}!\"; " \
- "if test \"${boot_device}\" = \"mmc\"; then " \
- "env set boot_targets \"mmc${boot_instance}\"; "\
- "fi;"
+#include <config_distro_bootcmd.h>
+/*
+ * memory layout for 32M uncompressed/compressed kernel,
+ * 1M fdt, 1M script, 1M pxe and 1M for splashimage
+ * and the ramdisk at the end.
+ */
#define CONFIG_EXTRA_ENV_SETTINGS \
- "scriptaddr=0xC0000000\0" \
- "pxefile_addr_r=0xC0000000\0" \
- "kernel_addr_r=0xC1000000\0" \
- "fdt_addr_r=0xC4000000\0" \
- "ramdisk_addr_r=0xC4100000\0" \
+ "kernel_addr_r=0xc2000000\0" \
+ "fdt_addr_r=0xc4000000\0" \
+ "scriptaddr=0xc4100000\0" \
+ "pxefile_addr_r=0xc4200000\0" \
+ "splashimage=0xc4300000\0" \
+ "ramdisk_addr_r=0xc4400000\0" \
"fdt_high=0xffffffff\0" \
"initrd_high=0xffffffff\0" \
- "preboot=" STM32MP_PREBOOT "\0" \
+ STM32MP_BOOTCMD \
BOOTENV
#endif /* ifndef CONFIG_SPL_BUILD */
+#endif /* ifdef CONFIG_DISTRO_DEFAULTS*/
#endif /* __CONFIG_H */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index b01d1c3c843..ee18260be69 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -449,7 +449,6 @@ extern int soft_i2c_gpio_scl;
"stdout=serial,vga\0" \
"stderr=serial,vga\0"
#elif CONFIG_DM_VIDEO
-#define CONFIG_SYS_WHITE_ON_BLACK
#define CONSOLE_STDOUT_SETTINGS \
"stdout=serial,vidconsole\0" \
"stderr=serial,vidconsole\0"
diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h
index 59b2546f0b4..cd92835112d 100644
--- a/include/configs/theadorable.h
+++ b/include/configs/theadorable.h
@@ -39,8 +39,6 @@
#define CONFIG_EHCI_IS_TDI
#define CONFIG_USB_MAX_CONTROLLER_COUNT 3
-/* SPI NOR flash default params, used by sf commands */
-
/* Environment in SPI NOR flash */
#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
diff --git a/include/configs/turris_mox.h b/include/configs/turris_mox.h
index 5d5394e3e53..0de40eddcb5 100644
--- a/include/configs/turris_mox.h
+++ b/include/configs/turris_mox.h
@@ -63,10 +63,6 @@
#define CONFIG_I2C_MV
#define CONFIG_SYS_I2C_SLAVE 0x0
-/*
- * SPI Flash configuration
- */
-
/* Environment in SPI NOR flash */
#define CONFIG_ENV_OFFSET 0x180000 /* as Marvell U-Boot version */
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h
index 038f6398eb6..c7805cf36bf 100644
--- a/include/configs/turris_omnia.h
+++ b/include/configs/turris_omnia.h
@@ -34,9 +34,6 @@
# define CONFIG_WATCHDOG
#endif
-/* SPI NOR flash default params, used by sf commands */
-#define CONFIG_SPI_FLASH_SPANSION
-
/*
* SDIO/MMC Card Configuration
*/
diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h
index 2840c7b815b..8c68372026e 100644
--- a/include/configs/vcoreiii.h
+++ b/include/configs/vcoreiii.h
@@ -10,7 +10,7 @@
/* Onboard devices */
-#define CONFIG_SYS_MALLOC_LEN 0x100000
+#define CONFIG_SYS_MALLOC_LEN 0x1F0000
#define CONFIG_SYS_LOAD_ADDR 0x00100000
#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
@@ -27,7 +27,7 @@
#if defined(CONFIG_ENV_IS_IN_SPI_FLASH) && !defined(CONFIG_ENV_OFFSET)
#define CONFIG_ENV_OFFSET (1024 * 1024)
-#define CONFIG_ENV_SIZE (256 * 1024)
+#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_SECT_SIZE (256 * 1024)
#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h
index ff2b82e7c25..63a7d55b888 100644
--- a/include/dm/pinctrl.h
+++ b/include/dm/pinctrl.h
@@ -355,18 +355,6 @@ int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph);
int pinctrl_decode_pin_config(const void *blob, int node);
/**
- * pinctrl_decode_pin_config_dm() - decode pin configuration flags
- *
- * This decodes some of the PIN_CONFIG values into flags, with each value
- * being (1 << pin_cfg). This does not support things with values like the
- * slew rate.
- *
- * @pinconfig: Pinconfig udevice
- * @return decoded flag value, or -ve on error
- */
-int pinctrl_decode_pin_config_dm(struct udevice *dev);
-
-/**
* pinctrl_get_gpio_mux() - get the mux value for a particular GPIO
*
* This allows the raw mux value for a GPIO to be obtained. It is
diff --git a/include/dm/util.h b/include/dm/util.h
index 9ff6531d1b2..60d3b93decd 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -40,32 +40,6 @@ static inline void dm_dump_devres(void)
#endif
/**
- * Check if a dt node should be or was bound before relocation.
- *
- * Devicetree nodes can be marked as needed to be bound
- * in the loader stages via special devicetree properties.
- *
- * Before relocation this function can be used to check if nodes
- * are required in either SPL or TPL stages.
- *
- * After relocation and jumping into the real U-Boot binary
- * it is possible to determine if a node was bound in one of
- * SPL/TPL stages.
- *
- * There are 3 settings currently in use
- * -
- * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
- * Existing platforms only use it to indicate nodes needed in
- * SPL. Should probably be replaced by u-boot,dm-spl for
- * existing platforms.
- * @blob: devicetree
- * @offset: node offset
- *
- * Returns true if node is needed in SPL/TL, false otherwise.
- */
-bool dm_fdt_pre_reloc(const void *blob, int offset);
-
-/**
* Check if an of node should be or was bound before relocation.
*
* Devicetree nodes can be marked as needed to be bound
diff --git a/include/dt-bindings/mfd/st,stpmic1.h b/include/dt-bindings/mfd/st,stpmic1.h
new file mode 100644
index 00000000000..b2d6c83462a
--- /dev/null
+++ b/include/dt-bindings/mfd/st,stpmic1.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Philippe Peurichard <philippe.peurichard@st.com>,
+ * Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+ */
+
+#ifndef __DT_BINDINGS_STPMIC1_H__
+#define __DT_BINDINGS_STPMIC1_H__
+
+/* IRQ definitions */
+#define IT_PONKEY_F 0
+#define IT_PONKEY_R 1
+#define IT_WAKEUP_F 2
+#define IT_WAKEUP_R 3
+#define IT_VBUS_OTG_F 4
+#define IT_VBUS_OTG_R 5
+#define IT_SWOUT_F 6
+#define IT_SWOUT_R 7
+
+#define IT_CURLIM_BUCK1 8
+#define IT_CURLIM_BUCK2 9
+#define IT_CURLIM_BUCK3 10
+#define IT_CURLIM_BUCK4 11
+#define IT_OCP_OTG 12
+#define IT_OCP_SWOUT 13
+#define IT_OCP_BOOST 14
+#define IT_OVP_BOOST 15
+
+#define IT_CURLIM_LDO1 16
+#define IT_CURLIM_LDO2 17
+#define IT_CURLIM_LDO3 18
+#define IT_CURLIM_LDO4 19
+#define IT_CURLIM_LDO5 20
+#define IT_CURLIM_LDO6 21
+#define IT_SHORT_SWOTG 22
+#define IT_SHORT_SWOUT 23
+
+#define IT_TWARN_F 24
+#define IT_TWARN_R 25
+#define IT_VINLOW_F 26
+#define IT_VINLOW_R 27
+#define IT_SWIN_F 30
+#define IT_SWIN_R 31
+
+#endif /* __DT_BINDINGS_STPMIC1_H__ */
diff --git a/include/dt-bindings/mfd/st,stpmu1.h b/include/dt-bindings/mfd/st,stpmu1.h
deleted file mode 100644
index 81982ebe2c2..00000000000
--- a/include/dt-bindings/mfd/st,stpmu1.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is part of stpmu1 pmic driver
- *
- * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
- * Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
- *
- * License type: GPLv2
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __DT_BINDINGS_STPMU1_H__
-#define __DT_BINDINGS_STPMU1_H__
-
-/* IRQ definitions */
-#define IT_PONKEY_F 0
-#define IT_PONKEY_R 1
-#define IT_WAKEUP_F 2
-#define IT_WAKEUP_R 3
-#define IT_VBUS_OTG_F 4
-#define IT_VBUS_OTG_R 5
-#define IT_SWOUT_F 6
-#define IT_SWOUT_R 7
-
-#define IT_CURLIM_BUCK1 8
-#define IT_CURLIM_BUCK2 9
-#define IT_CURLIM_BUCK3 10
-#define IT_CURLIM_BUCK4 11
-#define IT_OCP_OTG 12
-#define IT_OCP_SWOUT 13
-#define IT_OCP_BOOST 14
-#define IT_OVP_BOOST 15
-
-#define IT_CURLIM_LDO1 16
-#define IT_CURLIM_LDO2 17
-#define IT_CURLIM_LDO3 18
-#define IT_CURLIM_LDO4 19
-#define IT_CURLIM_LDO5 20
-#define IT_CURLIM_LDO6 21
-#define IT_SHORT_SWOTG 22
-#define IT_SHORT_SWOUT 23
-
-#define IT_TWARN_F 24
-#define IT_TWARN_R 25
-#define IT_VINLOW_F 26
-#define IT_VINLOW_R 27
-#define IT_SWIN_F 30
-#define IT_SWIN_R 31
-
-#endif /* __DT_BINDINGS_STPMU1_H__ */
diff --git a/include/dt-bindings/mscc/jr2_data.h b/include/dt-bindings/mscc/jr2_data.h
new file mode 100644
index 00000000000..2f06fc5c5de
--- /dev/null
+++ b/include/dt-bindings/mscc/jr2_data.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _JR2_DATA_H_
+#define _JR2_DATA_H_
+
+#define SERDES1G(x) (x)
+#define SERDES1G_MAX SERDES1G(10)
+#define SERDES6G(x) (SERDES1G_MAX + 1 + (x))
+#define SERDES6G_MAX SERDES6G(17)
+#define SERDES_MAX (SERDES6G_MAX + 1)
+
+/* similar with phy_interface_t */
+#define PHY_MODE_SGMII 2
+#define PHY_MODE_QSGMII 4
+
+#endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index ad00f79f203..266c58271f0 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -23,15 +23,44 @@
*/
typedef phys_addr_t fdt_addr_t;
typedef phys_size_t fdt_size_t;
+
+static inline fdt32_t fdt_addr_unpack(fdt_addr_t addr, fdt32_t *upper)
+{
+ if (upper)
+#ifdef CONFIG_PHYS_64BIT
+ *upper = addr >> 32;
+#else
+ *upper = 0;
+#endif
+
+ return addr;
+}
+
+static inline fdt32_t fdt_size_unpack(fdt_size_t size, fdt32_t *upper)
+{
+ if (upper)
+#ifdef CONFIG_PHYS_64BIT
+ *upper = size >> 32;
+#else
+ *upper = 0;
+#endif
+
+ return size;
+}
+
#ifdef CONFIG_PHYS_64BIT
#define FDT_ADDR_T_NONE (-1U)
#define fdt_addr_to_cpu(reg) be64_to_cpu(reg)
#define fdt_size_to_cpu(reg) be64_to_cpu(reg)
+#define cpu_to_fdt_addr(reg) cpu_to_be64(reg)
+#define cpu_to_fdt_size(reg) cpu_to_be64(reg)
typedef fdt64_t fdt_val_t;
#else
#define FDT_ADDR_T_NONE (-1U)
#define fdt_addr_to_cpu(reg) be32_to_cpu(reg)
#define fdt_size_to_cpu(reg) be32_to_cpu(reg)
+#define cpu_to_fdt_addr(reg) cpu_to_be32(reg)
+#define cpu_to_fdt_size(reg) cpu_to_be32(reg)
typedef fdt32_t fdt_val_t;
#endif
@@ -992,6 +1021,146 @@ int fdtdec_setup_memory_banksize_fdt(const void *blob);
int fdtdec_setup_memory_banksize(void);
/**
+ * fdtdec_set_phandle() - sets the phandle of a given node
+ *
+ * @param blob FDT blob
+ * @param node offset in the FDT blob of the node whose phandle is to
+ * be set
+ * @param phandle phandle to set for the given node
+ * @return 0 on success or a negative error code on failure
+ */
+int fdtdec_set_phandle(void *blob, int node, uint32_t phandle);
+
+/**
+ * fdtdec_add_reserved_memory() - add or find a reserved-memory node
+ *
+ * If a reserved-memory node already exists for the given carveout, a phandle
+ * for that node will be returned. Otherwise a new node will be created and a
+ * phandle corresponding to it will be returned.
+ *
+ * See Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+ * for details on how to use reserved memory regions.
+ *
+ * As an example, consider the following code snippet:
+ *
+ * struct fdt_memory fb = {
+ * .start = 0x92cb3000,
+ * .end = 0x934b2fff,
+ * };
+ * uint32_t phandle;
+ *
+ * fdtdec_add_reserved_memory(fdt, "framebuffer", &fb, &phandle);
+ *
+ * This results in the following subnode being added to the top-level
+ * /reserved-memory node:
+ *
+ * reserved-memory {
+ * #address-cells = <0x00000002>;
+ * #size-cells = <0x00000002>;
+ * ranges;
+ *
+ * framebuffer@92cb3000 {
+ * reg = <0x00000000 0x92cb3000 0x00000000 0x00800000>;
+ * phandle = <0x0000004d>;
+ * };
+ * };
+ *
+ * If the top-level /reserved-memory node does not exist, it will be created.
+ * The phandle returned from the function call can be used to reference this
+ * reserved memory region from other nodes.
+ *
+ * See fdtdec_set_carveout() for a more elaborate example.
+ *
+ * @param blob FDT blob
+ * @param basename base name of the node to create
+ * @param carveout information about the carveout region
+ * @param phandlep return location for the phandle of the carveout region
+ * @return 0 on success or a negative error code on failure
+ */
+int fdtdec_add_reserved_memory(void *blob, const char *basename,
+ const struct fdt_memory *carveout,
+ uint32_t *phandlep);
+
+/**
+ * fdtdec_get_carveout() - reads a carveout from an FDT
+ *
+ * Reads information about a carveout region from an FDT. The carveout is a
+ * referenced by its phandle that is read from a given property in a given
+ * node.
+ *
+ * @param blob FDT blob
+ * @param node name of a node
+ * @param name name of the property in the given node that contains
+ * the phandle for the carveout
+ * @param index index of the phandle for which to read the carveout
+ * @param carveout return location for the carveout information
+ * @return 0 on success or a negative error code on failure
+ */
+int fdtdec_get_carveout(const void *blob, const char *node, const char *name,
+ unsigned int index, struct fdt_memory *carveout);
+
+/**
+ * fdtdec_set_carveout() - sets a carveout region for a given node
+ *
+ * Sets a carveout region for a given node. If a reserved-memory node already
+ * exists for the carveout, the phandle for that node will be reused. If no
+ * such node exists, a new one will be created and a phandle to it stored in
+ * a specified property of the given node.
+ *
+ * As an example, consider the following code snippet:
+ *
+ * const char *node = "/host1x@50000000/dc@54240000";
+ * struct fdt_memory fb = {
+ * .start = 0x92cb3000,
+ * .end = 0x934b2fff,
+ * };
+ *
+ * fdtdec_set_carveout(fdt, node, "memory-region", 0, "framebuffer", &fb);
+ *
+ * dc@54200000 is a display controller and was set up by the bootloader to
+ * scan out the framebuffer specified by "fb". This would cause the following
+ * reserved memory region to be added:
+ *
+ * reserved-memory {
+ * #address-cells = <0x00000002>;
+ * #size-cells = <0x00000002>;
+ * ranges;
+ *
+ * framebuffer@92cb3000 {
+ * reg = <0x00000000 0x92cb3000 0x00000000 0x00800000>;
+ * phandle = <0x0000004d>;
+ * };
+ * };
+ *
+ * A "memory-region" property will also be added to the node referenced by the
+ * offset parameter.
+ *
+ * host1x@50000000 {
+ * ...
+ *
+ * dc@54240000 {
+ * ...
+ * memory-region = <0x0000004d>;
+ * ...
+ * };
+ *
+ * ...
+ * };
+ *
+ * @param blob FDT blob
+ * @param node name of the node to add the carveout to
+ * @param prop_name name of the property in which to store the phandle of
+ * the carveout
+ * @param index index of the phandle to store
+ * @param name base name of the reserved-memory node to create
+ * @param carveout information about the carveout to add
+ * @return 0 on success or a negative error code on failure
+ */
+int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name,
+ unsigned int index, const char *name,
+ const struct fdt_memory *carveout);
+
+/**
* Set up the device tree ready for use
*/
int fdtdec_setup(void);
diff --git a/include/i2c.h b/include/i2c.h
index ccffc195527..a5c760c711e 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -68,9 +68,11 @@ struct dm_i2c_chip {
* I2C bus udevice.
*
* @speed_hz: Bus speed in hertz (typically 100000)
+ * @max_transaction_bytes: Maximal size of single I2C transfer
*/
struct dm_i2c_bus {
int speed_hz;
+ int max_transaction_bytes;
};
/*
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index cd1f557a2f3..e3549f0a461 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -392,7 +392,7 @@ static inline void mtd_set_ooblayout(struct mtd_info *mtd,
mtd->ooblayout = ooblayout;
}
-static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
+static inline u32 mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
{
return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
}
diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h
new file mode 100644
index 00000000000..0e6721d852a
--- /dev/null
+++ b/include/power/stpmic1.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef __PMIC_STPMIC1_H_
+#define __PMIC_STPMIC1_H_
+
+#define STPMIC1_MAIN_CR 0x10
+#define STPMIC1_BUCKS_MRST_CR 0x18
+#define STPMIC1_LDOS_MRST_CR 0x1a
+#define STPMIC1_BUCKX_MAIN_CR(buck) (0x20 + (buck))
+#define STPMIC1_REFDDR_MAIN_CR 0x24
+#define STPMIC1_LDOX_MAIN_CR(ldo) (0x25 + (ldo))
+#define STPMIC1_BST_SW_CR 0x40
+#define STPMIC1_NVM_SR 0xb8
+#define STPMIC1_NVM_CR 0xb9
+
+/* Main PMIC Control Register (MAIN_CR) */
+#define STPMIC1_SWOFF BIT(0)
+#define STPMIC1_RREQ_EN BIT(1)
+
+/* BUCKS_MRST_CR */
+#define STPMIC1_MRST_BUCK(buck) BIT(buck)
+#define STPMIC1_MRST_BUCK_ALL GENMASK(3, 0)
+
+/* LDOS_MRST_CR */
+#define STPMIC1_MRST_LDO(ldo) BIT(ldo)
+#define STPMIC1_MRST_LDO_ALL GENMASK(6, 0)
+
+/* BUCKx_MAIN_CR (x=1...4) */
+#define STPMIC1_BUCK_ENA BIT(0)
+#define STPMIC1_BUCK_PREG_MODE BIT(1)
+#define STPMIC1_BUCK_VOUT_MASK GENMASK(7, 2)
+#define STPMIC1_BUCK_VOUT_SHIFT 2
+#define STPMIC1_BUCK_VOUT(sel) (sel << STPMIC1_BUCK_VOUT_SHIFT)
+
+#define STPMIC1_BUCK2_1200000V STPMIC1_BUCK_VOUT(24)
+#define STPMIC1_BUCK2_1350000V STPMIC1_BUCK_VOUT(30)
+
+#define STPMIC1_BUCK3_1800000V STPMIC1_BUCK_VOUT(39)
+
+/* REFDDR_MAIN_CR */
+#define STPMIC1_VREF_ENA BIT(0)
+
+/* LDOX_MAIN_CR */
+#define STPMIC1_LDO_ENA BIT(0)
+#define STPMIC1_LDO12356_VOUT_MASK GENMASK(6, 2)
+#define STPMIC1_LDO12356_VOUT_SHIFT 2
+#define STPMIC1_LDO_VOUT(sel) (sel << STPMIC1_LDO12356_VOUT_SHIFT)
+
+#define STPMIC1_LDO3_MODE BIT(7)
+#define STPMIC1_LDO3_DDR_SEL 31
+#define STPMIC1_LDO3_1800000 STPMIC1_LDO_VOUT(9)
+
+#define STPMIC1_LDO4_UV 3300000
+
+/* BST_SW_CR */
+#define STPMIC1_BST_ON BIT(0)
+#define STPMIC1_VBUSOTG_ON BIT(1)
+#define STPMIC1_SWOUT_ON BIT(2)
+#define STPMIC1_PWR_SW_ON (STPMIC1_VBUSOTG_ON | STPMIC1_SWOUT_ON)
+
+/* NVM_SR */
+#define STPMIC1_NVM_BUSY BIT(0)
+
+/* NVM_CR */
+#define STPMIC1_NVM_CMD_PROGRAM 1
+#define STPMIC1_NVM_CMD_READ 2
+
+/* Timeout */
+#define STPMIC1_DEFAULT_START_UP_DELAY_MS 1
+#define STPMIC1_DEFAULT_STOP_DELAY_MS 5
+#define STPMIC1_USB_BOOST_START_UP_DELAY_MS 10
+
+enum {
+ STPMIC1_BUCK1,
+ STPMIC1_BUCK2,
+ STPMIC1_BUCK3,
+ STPMIC1_BUCK4,
+ STPMIC1_MAX_BUCK,
+};
+
+enum {
+ STPMIC1_PREG_MODE_HP,
+ STPMIC1_PREG_MODE_LP,
+};
+
+enum {
+ STPMIC1_LDO1,
+ STPMIC1_LDO2,
+ STPMIC1_LDO3,
+ STPMIC1_LDO4,
+ STPMIC1_LDO5,
+ STPMIC1_LDO6,
+ STPMIC1_MAX_LDO,
+};
+
+enum {
+ STPMIC1_LDO_MODE_NORMAL,
+ STPMIC1_LDO_MODE_BYPASS,
+ STPMIC1_LDO_MODE_SINK_SOURCE,
+};
+
+enum {
+ STPMIC1_PWR_SW1,
+ STPMIC1_PWR_SW2,
+ STPMIC1_MAX_PWR_SW,
+};
+
+int stpmic1_shadow_read_byte(u8 addr, u8 *buf);
+int stpmic1_shadow_write_byte(u8 addr, u8 *buf);
+int stpmic1_nvm_read_byte(u8 addr, u8 *buf);
+int stpmic1_nvm_write_byte(u8 addr, u8 *buf);
+int stpmic1_nvm_read_all(u8 *buf, int buf_len);
+int stpmic1_nvm_write_all(u8 *buf, int buf_len);
+#endif
diff --git a/include/power/stpmu1.h b/include/power/stpmu1.h
deleted file mode 100644
index 5906fbf832b..00000000000
--- a/include/power/stpmu1.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
-/*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
- */
-
-#ifndef __PMIC_STPMU1_H_
-#define __PMIC_STPMU1_H_
-
-#define STPMU1_MASK_RESET_BUCK 0x18
-#define STPMU1_BUCKX_CTRL_REG(buck) (0x20 + (buck))
-#define STPMU1_VREF_CTRL_REG 0x24
-#define STPMU1_LDOX_CTRL_REG(ldo) (0x25 + (ldo))
-#define STPMU1_USB_CTRL_REG 0x40
-#define STPMU1_NVM_USER_STATUS_REG 0xb8
-#define STPMU1_NVM_USER_CONTROL_REG 0xb9
-
-#define STPMU1_MASK_RESET_BUCK3 BIT(2)
-
-#define STPMU1_BUCK_EN BIT(0)
-#define STPMU1_BUCK_MODE BIT(1)
-#define STPMU1_BUCK_OUTPUT_MASK GENMASK(7, 2)
-#define STPMU1_BUCK_OUTPUT_SHIFT 2
-#define STPMU1_BUCK2_1200000V (24 << STPMU1_BUCK_OUTPUT_SHIFT)
-#define STPMU1_BUCK2_1350000V (30 << STPMU1_BUCK_OUTPUT_SHIFT)
-#define STPMU1_BUCK3_1800000V (39 << STPMU1_BUCK_OUTPUT_SHIFT)
-
-#define STPMU1_VREF_EN BIT(0)
-
-#define STPMU1_LDO_EN BIT(0)
-#define STPMU1_LDO12356_OUTPUT_MASK GENMASK(6, 2)
-#define STPMU1_LDO12356_OUTPUT_SHIFT 2
-#define STPMU1_LDO3_MODE BIT(7)
-#define STPMU1_LDO3_DDR_SEL 31
-#define STPMU1_LDO3_1800000 (9 << STPMU1_LDO12356_OUTPUT_SHIFT)
-#define STPMU1_LDO4_UV 3300000
-
-#define STPMU1_USB_BOOST_EN BIT(0)
-#define STPMU1_USB_PWR_SW_EN GENMASK(2, 1)
-
-#define STPMU1_NVM_USER_CONTROL_PROGRAM BIT(0)
-#define STPMU1_NVM_USER_CONTROL_READ BIT(1)
-
-#define STPMU1_NVM_USER_STATUS_BUSY BIT(0)
-#define STPMU1_NVM_USER_STATUS_ERROR BIT(1)
-
-#define STPMU1_DEFAULT_START_UP_DELAY_MS 1
-#define STPMU1_DEFAULT_STOP_DELAY_MS 5
-#define STPMU1_USB_BOOST_START_UP_DELAY_MS 10
-
-enum {
- STPMU1_BUCK1,
- STPMU1_BUCK2,
- STPMU1_BUCK3,
- STPMU1_BUCK4,
- STPMU1_MAX_BUCK,
-};
-
-enum {
- STPMU1_BUCK_MODE_HP,
- STPMU1_BUCK_MODE_LP,
-};
-
-enum {
- STPMU1_LDO1,
- STPMU1_LDO2,
- STPMU1_LDO3,
- STPMU1_LDO4,
- STPMU1_LDO5,
- STPMU1_LDO6,
- STPMU1_MAX_LDO,
-};
-
-enum {
- STPMU1_LDO_MODE_NORMAL,
- STPMU1_LDO_MODE_BYPASS,
- STPMU1_LDO_MODE_SINK_SOURCE,
-};
-
-enum {
- STPMU1_PWR_SW1,
- STPMU1_PWR_SW2,
- STPMU1_MAX_PWR_SW,
-};
-
-#endif
diff --git a/include/spi.h b/include/spi.h
index 92427e5f329..378594163b8 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -496,14 +496,15 @@ int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
* device and slave device.
*
* If no such slave exists, and drv_name is not NULL, then a new slave device
- * is automatically bound on this chip select.
+ * is automatically bound on this chip select with requested speed and mode.
*
- * Ths new slave device is probed ready for use with the given speed and mode.
+ * Ths new slave device is probed ready for use with the speed and mode
+ * from platdata when available or the requested values.
*
* @busnum: SPI bus number
* @cs: Chip select to look for
- * @speed: SPI speed to use for this slave
- * @mode: SPI mode to use for this slave
+ * @speed: SPI speed to use for this slave when not available in platdata
+ * @mode: SPI mode to use for this slave when not available in platdata
* @drv_name: Name of driver to attach to this chip select
* @dev_name: Name of the new device thus created
* @busp: Returns bus device
diff --git a/include/video.h b/include/video.h
index 1d57b48b173..485071d0723 100644
--- a/include/video.h
+++ b/include/video.h
@@ -70,6 +70,7 @@ enum video_log2_bpp {
* the LCD is updated
* @cmap: Colour map for 8-bit-per-pixel displays
* @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color)
+ * @bg_col_idx: Background color code (bit 3 = bold, bit 0-2 = color)
*/
struct video_priv {
/* Things set up by the driver: */
@@ -92,6 +93,7 @@ struct video_priv {
bool flush_dcache;
ushort *cmap;
u8 fg_col_idx;
+ u8 bg_col_idx;
};
/* Placeholder - there are no video operations at present */
diff --git a/lib/Kconfig b/lib/Kconfig
index 8fe5d85a050..2120216593e 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -436,4 +436,8 @@ source lib/efi/Kconfig
source lib/efi_loader/Kconfig
source lib/optee/Kconfig
+config TEST_FDTDEC
+ bool "enable fdtdec test"
+ depends on OF_LIBFDT
+
endmenu
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index a51dc5e9867..9c9c3023473 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -45,7 +45,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"),
COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"),
- COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
+ COMPAT(GENERIC_SPI_FLASH, "jedec,spi-nor"),
COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
COMPAT(INTEL_MICROCODE, "intel,microcode"),
COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
@@ -1261,6 +1261,231 @@ __weak void *board_fdt_blob_setup(void)
}
#endif
+int fdtdec_set_phandle(void *blob, int node, uint32_t phandle)
+{
+ fdt32_t value = cpu_to_fdt32(phandle);
+
+ return fdt_setprop(blob, node, "phandle", &value, sizeof(value));
+}
+
+static int fdtdec_init_reserved_memory(void *blob)
+{
+ int na, ns, node, err;
+ fdt32_t value;
+
+ /* inherit #address-cells and #size-cells from the root node */
+ na = fdt_address_cells(blob, 0);
+ ns = fdt_size_cells(blob, 0);
+
+ node = fdt_add_subnode(blob, 0, "reserved-memory");
+ if (node < 0)
+ return node;
+
+ err = fdt_setprop(blob, node, "ranges", NULL, 0);
+ if (err < 0)
+ return err;
+
+ value = cpu_to_fdt32(ns);
+
+ err = fdt_setprop(blob, node, "#size-cells", &value, sizeof(value));
+ if (err < 0)
+ return err;
+
+ value = cpu_to_fdt32(na);
+
+ err = fdt_setprop(blob, node, "#address-cells", &value, sizeof(value));
+ if (err < 0)
+ return err;
+
+ return node;
+}
+
+int fdtdec_add_reserved_memory(void *blob, const char *basename,
+ const struct fdt_memory *carveout,
+ uint32_t *phandlep)
+{
+ fdt32_t cells[4] = {}, *ptr = cells;
+ uint32_t upper, lower, phandle;
+ int parent, node, na, ns, err;
+ char name[64];
+
+ /* create an empty /reserved-memory node if one doesn't exist */
+ parent = fdt_path_offset(blob, "/reserved-memory");
+ if (parent < 0) {
+ parent = fdtdec_init_reserved_memory(blob);
+ if (parent < 0)
+ return parent;
+ }
+
+ /* only 1 or 2 #address-cells and #size-cells are supported */
+ na = fdt_address_cells(blob, parent);
+ if (na < 1 || na > 2)
+ return -FDT_ERR_BADNCELLS;
+
+ ns = fdt_size_cells(blob, parent);
+ if (ns < 1 || ns > 2)
+ return -FDT_ERR_BADNCELLS;
+
+ /* find a matching node and return the phandle to that */
+ fdt_for_each_subnode(node, blob, parent) {
+ const char *name = fdt_get_name(blob, node, NULL);
+ phys_addr_t addr, size;
+
+ addr = fdtdec_get_addr_size(blob, node, "reg", &size);
+ if (addr == FDT_ADDR_T_NONE) {
+ debug("failed to read address/size for %s\n", name);
+ continue;
+ }
+
+ if (addr == carveout->start && (addr + size) == carveout->end) {
+ *phandlep = fdt_get_phandle(blob, node);
+ return 0;
+ }
+ }
+
+ /*
+ * Unpack the start address and generate the name of the new node
+ * base on the basename and the unit-address.
+ */
+ lower = fdt_addr_unpack(carveout->start, &upper);
+
+ if (na > 1 && upper > 0)
+ snprintf(name, sizeof(name), "%s@%x,%x", basename, upper,
+ lower);
+ else {
+ if (upper > 0) {
+ debug("address %08x:%08x exceeds addressable space\n",
+ upper, lower);
+ return -FDT_ERR_BADVALUE;
+ }
+
+ snprintf(name, sizeof(name), "%s@%x", basename, lower);
+ }
+
+ node = fdt_add_subnode(blob, parent, name);
+ if (node < 0)
+ return node;
+
+ err = fdt_generate_phandle(blob, &phandle);
+ if (err < 0)
+ return err;
+
+ err = fdtdec_set_phandle(blob, node, phandle);
+ if (err < 0)
+ return err;
+
+ /* store one or two address cells */
+ if (na > 1)
+ *ptr++ = cpu_to_fdt32(upper);
+
+ *ptr++ = cpu_to_fdt32(lower);
+
+ /* store one or two size cells */
+ lower = fdt_size_unpack(carveout->end - carveout->start + 1, &upper);
+
+ if (ns > 1)
+ *ptr++ = cpu_to_fdt32(upper);
+
+ *ptr++ = cpu_to_fdt32(lower);
+
+ err = fdt_setprop(blob, node, "reg", cells, (na + ns) * sizeof(*cells));
+ if (err < 0)
+ return err;
+
+ /* return the phandle for the new node for the caller to use */
+ if (phandlep)
+ *phandlep = phandle;
+
+ return 0;
+}
+
+int fdtdec_get_carveout(const void *blob, const char *node, const char *name,
+ unsigned int index, struct fdt_memory *carveout)
+{
+ const fdt32_t *prop;
+ uint32_t phandle;
+ int offset, len;
+ fdt_size_t size;
+
+ offset = fdt_path_offset(blob, node);
+ if (offset < 0)
+ return offset;
+
+ prop = fdt_getprop(blob, offset, name, &len);
+ if (!prop) {
+ debug("failed to get %s for %s\n", name, node);
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ if ((len % sizeof(phandle)) != 0) {
+ debug("invalid phandle property\n");
+ return -FDT_ERR_BADPHANDLE;
+ }
+
+ if (len < (sizeof(phandle) * (index + 1))) {
+ debug("invalid phandle index\n");
+ return -FDT_ERR_BADPHANDLE;
+ }
+
+ phandle = fdt32_to_cpu(prop[index]);
+
+ offset = fdt_node_offset_by_phandle(blob, phandle);
+ if (offset < 0) {
+ debug("failed to find node for phandle %u\n", phandle);
+ return offset;
+ }
+
+ carveout->start = fdtdec_get_addr_size_auto_noparent(blob, offset,
+ "reg", 0, &size,
+ true);
+ if (carveout->start == FDT_ADDR_T_NONE) {
+ debug("failed to read address/size from \"reg\" property\n");
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ carveout->end = carveout->start + size - 1;
+
+ return 0;
+}
+
+int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name,
+ unsigned int index, const char *name,
+ const struct fdt_memory *carveout)
+{
+ uint32_t phandle;
+ int err, offset;
+ fdt32_t value;
+
+ /* XXX implement support for multiple phandles */
+ if (index > 0) {
+ debug("invalid index %u\n", index);
+ return -FDT_ERR_BADOFFSET;
+ }
+
+ err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle);
+ if (err < 0) {
+ debug("failed to add reserved memory: %d\n", err);
+ return err;
+ }
+
+ offset = fdt_path_offset(blob, node);
+ if (offset < 0) {
+ debug("failed to find offset for node %s: %d\n", node, offset);
+ return offset;
+ }
+
+ value = cpu_to_fdt32(phandle);
+
+ err = fdt_setprop(blob, offset, prop_name, &value, sizeof(value));
+ if (err < 0) {
+ debug("failed to set %s property for node %s: %d\n", prop_name,
+ node, err);
+ return err;
+ }
+
+ return 0;
+}
+
int fdtdec_setup(void)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
diff --git a/lib/fdtdec_test.c b/lib/fdtdec_test.c
index a82e27de942..f6defe16c5a 100644
--- a/lib/fdtdec_test.c
+++ b/lib/fdtdec_test.c
@@ -15,48 +15,28 @@
/* The size of our test fdt blob */
#define FDT_SIZE (16 * 1024)
-/**
- * Check if an operation failed, and if so, print an error
- *
- * @param oper_name Name of operation
- * @param err Error code to check
- *
- * @return 0 if ok, -1 if there was an error
- */
-static int fdt_checkerr(const char *oper_name, int err)
-{
- if (err) {
- printf("%s: %s: %s\n", __func__, oper_name, fdt_strerror(err));
- return -1;
- }
+#define CHECK(op) ({ \
+ int err = op; \
+ if (err < 0) { \
+ printf("%s: %s: %s\n", __func__, #op, \
+ fdt_strerror(err)); \
+ return err; \
+ } \
+ \
+ err; \
+ })
- return 0;
-}
+#define CHECKVAL(op, expected) ({ \
+ int err = op; \
+ if (err != expected) { \
+ printf("%s: %s: expected %d, but returned %d\n",\
+ __func__, #op, expected, err); \
+ return err; \
+ } \
+ \
+ err; \
+ })
-/**
- * Check the result of an operation and if incorrect, print an error
- *
- * @param oper_name Name of operation
- * @param expected Expected value
- * @param value Actual value
- *
- * @return 0 if ok, -1 if there was an error
- */
-static int checkval(const char *oper_name, int expected, int value)
-{
- if (expected != value) {
- printf("%s: %s: expected %d, but returned %d\n", __func__,
- oper_name, expected, value);
- return -1;
- }
-
- return 0;
-}
-
-#define CHECK(op) if (fdt_checkerr(#op, op)) return -1
-#define CHECKVAL(op, expected) \
- if (checkval(#op, expected, op)) \
- return -1
#define CHECKOK(op) CHECKVAL(op, 0)
/* maximum number of nodes / aliases to generate */
@@ -79,7 +59,9 @@ static int make_fdt(void *fdt, int size, const char *aliases,
{
char name[20], value[20];
const char *s;
+#if defined(DEBUG) && defined(CONFIG_SANDBOX)
int fd;
+#endif
CHECK(fdt_create(fdt, size));
CHECK(fdt_finish_reservemap(fdt));
@@ -136,7 +118,7 @@ static int run_test(const char *aliases, const char *nodes, const char *expect)
CHECKVAL(make_fdt(blob, FDT_SIZE, aliases, nodes), 0);
CHECKVAL(fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_UNKNOWN,
- list, ARRAY_SIZE(list)), strlen(expect));
+ list, ARRAY_SIZE(list)), (int)strlen(expect));
/* Check we got the right ones */
for (i = 0, s = expect; *s; s++, i++) {
@@ -159,6 +141,156 @@ static int run_test(const char *aliases, const char *nodes, const char *expect)
return 0;
}
+static int make_fdt_carveout_device(void *fdt, uint32_t na, uint32_t ns)
+{
+ const char *basename = "/display";
+ struct fdt_memory carveout = {
+#ifdef CONFIG_PHYS_64BIT
+ .start = 0x180000000,
+ .end = 0x18fffffff,
+#else
+ .start = 0x80000000,
+ .end = 0x8fffffff,
+#endif
+ };
+ fdt32_t cells[4], *ptr = cells;
+ uint32_t upper, lower;
+ char name[32];
+ int offset;
+
+ /* store one or two address cells */
+ lower = fdt_addr_unpack(carveout.start, &upper);
+
+ if (na > 1 && upper > 0)
+ snprintf(name, sizeof(name), "%s@%x,%x", basename, upper,
+ lower);
+ else
+ snprintf(name, sizeof(name), "%s@%x", basename, lower);
+
+ if (na > 1)
+ *ptr++ = cpu_to_fdt32(upper);
+
+ *ptr++ = cpu_to_fdt32(lower);
+
+ /* store one or two size cells */
+ lower = fdt_size_unpack(carveout.end - carveout.start + 1, &upper);
+
+ if (ns > 1)
+ *ptr++ = cpu_to_fdt32(upper);
+
+ *ptr++ = cpu_to_fdt32(lower);
+
+ offset = CHECK(fdt_add_subnode(fdt, 0, name + 1));
+ CHECK(fdt_setprop(fdt, offset, "reg", cells, (na + ns) * sizeof(*cells)));
+
+ return fdtdec_set_carveout(fdt, name, "memory-region", 0,
+ "framebuffer", &carveout);
+}
+
+static int check_fdt_carveout(void *fdt, uint32_t address_cells,
+ uint32_t size_cells)
+{
+#ifdef CONFIG_PHYS_64BIT
+ const char *name = "/display@1,80000000";
+ const struct fdt_memory expected = {
+ .start = 0x180000000,
+ .end = 0x18fffffff,
+ };
+#else
+ const char *name = "/display@80000000";
+ const struct fdt_memory expected = {
+ .start = 0x80000000,
+ .end = 0x8fffffff,
+ };
+#endif
+ struct fdt_memory carveout;
+
+ printf("carveout: %pap-%pap na=%u ns=%u: ", &expected.start,
+ &expected.end, address_cells, size_cells);
+
+ CHECK(fdtdec_get_carveout(fdt, name, "memory-region", 0, &carveout));
+
+ if ((carveout.start != expected.start) ||
+ (carveout.end != expected.end)) {
+ printf("carveout: %pap-%pap, expected %pap-%pap\n",
+ &carveout.start, &carveout.end,
+ &expected.start, &expected.end);
+ return 1;
+ }
+
+ printf("pass\n");
+ return 0;
+}
+
+static int make_fdt_carveout(void *fdt, int size, uint32_t address_cells,
+ uint32_t size_cells)
+{
+ fdt32_t na = cpu_to_fdt32(address_cells);
+ fdt32_t ns = cpu_to_fdt32(size_cells);
+#if defined(DEBUG) && defined(CONFIG_SANDBOX)
+ char filename[512];
+ int fd;
+#endif
+ int err;
+
+ CHECK(fdt_create(fdt, size));
+ CHECK(fdt_finish_reservemap(fdt));
+ CHECK(fdt_begin_node(fdt, ""));
+ CHECK(fdt_property(fdt, "#address-cells", &na, sizeof(na)));
+ CHECK(fdt_property(fdt, "#size-cells", &ns, sizeof(ns)));
+ CHECK(fdt_end_node(fdt));
+ CHECK(fdt_finish(fdt));
+ CHECK(fdt_pack(fdt));
+
+ CHECK(fdt_open_into(fdt, fdt, FDT_SIZE));
+
+ err = make_fdt_carveout_device(fdt, address_cells, size_cells);
+
+#if defined(DEBUG) && defined(CONFIG_SANDBOX)
+ snprintf(filename, sizeof(filename), "/tmp/fdtdec-carveout-%u-%u.dtb",
+ address_cells, size_cells);
+
+ fd = os_open(filename, OS_O_CREAT | OS_O_WRONLY);
+ if (fd < 0) {
+ printf("could not open .dtb file to write\n");
+ goto out;
+ }
+
+ os_write(fd, fdt, size);
+ os_close(fd);
+
+out:
+#endif
+ return err;
+}
+
+static int check_carveout(void)
+{
+ void *fdt;
+
+ fdt = malloc(FDT_SIZE);
+ if (!fdt) {
+ printf("%s: out of memory\n", __func__);
+ return 1;
+ }
+
+#ifndef CONFIG_PHYS_64BIT
+ CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 1), 0);
+ CHECKOK(check_fdt_carveout(fdt, 1, 1));
+ CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 2), 0);
+ CHECKOK(check_fdt_carveout(fdt, 1, 2));
+#else
+ CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 1), -FDT_ERR_BADVALUE);
+ CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 2), -FDT_ERR_BADVALUE);
+#endif
+ CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 1), 0);
+ CHECKOK(check_fdt_carveout(fdt, 2, 1));
+ CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 2), 0);
+ CHECKOK(check_fdt_carveout(fdt, 2, 2));
+
+ return 0;
+}
+
static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
@@ -200,6 +332,8 @@ static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc,
CHECKOK(run_test("2a 1a 0a", "a", " a"));
CHECKOK(run_test("0a 1a 2a", "a", "a"));
+ CHECKOK(check_carveout());
+
printf("Test passed\n");
return 0;
}
diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c
index b6ca4e0b0c3..693de9aa5ad 100644
--- a/lib/libfdt/fdt_ro.c
+++ b/lib/libfdt/fdt_ro.c
@@ -73,6 +73,37 @@ uint32_t fdt_get_max_phandle(const void *fdt)
return 0;
}
+int fdt_generate_phandle(const void *fdt, uint32_t *phandle)
+{
+ uint32_t max = 0;
+ int offset = -1;
+
+ while (true) {
+ uint32_t value;
+
+ offset = fdt_next_node(fdt, offset, NULL);
+ if (offset < 0) {
+ if (offset == -FDT_ERR_NOTFOUND)
+ break;
+
+ return offset;
+ }
+
+ value = fdt_get_phandle(fdt, offset);
+
+ if (value > max)
+ max = value;
+ }
+
+ if (max == FDT_MAX_PHANDLE)
+ return -FDT_ERR_NOPHANDLES;
+
+ if (phandle)
+ *phandle = max + 1;
+
+ return 0;
+}
+
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
{
FDT_CHECK_HEADER(fdt);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 1b6c154d8d7..2403825dc98 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -457,7 +457,6 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
return device_path_string(buf, end, ptr, field_width,
precision, flags);
#endif
-#ifdef CONFIG_CMD_NET
case 'a':
flags |= SPECIAL | ZEROPAD;
@@ -469,6 +468,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
break;
}
break;
+#ifdef CONFIG_CMD_NET
case 'm':
flags |= SPECIAL;
/* Fallthrough */
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 70de9bb13a6..de67677f61a 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -525,4 +525,5 @@ quiet_cmd_fdtgrep = FDTGREP $@
cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \
-n /chosen -n /config -O dtb | \
$(objtree)/tools/fdtgrep -r -O dtb - -o $@ \
+ -P u-boot,dm-pre-reloc -P u-boot,dm-spl -P u-boot,dm-tpl \
$(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS)))
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index dfb3236da38..dc499884e4d 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -115,6 +115,37 @@ uint32_t fdt_get_max_phandle(const void *fdt)
return 0;
}
+int fdt_generate_phandle(const void *fdt, uint32_t *phandle)
+{
+ uint32_t max = 0;
+ int offset = -1;
+
+ while (true) {
+ uint32_t value;
+
+ offset = fdt_next_node(fdt, offset, NULL);
+ if (offset < 0) {
+ if (offset == -FDT_ERR_NOTFOUND)
+ break;
+
+ return offset;
+ }
+
+ value = fdt_get_phandle(fdt, offset);
+
+ if (value > max)
+ max = value;
+ }
+
+ if (max == FDT_MAX_PHANDLE)
+ return -FDT_ERR_NOPHANDLES;
+
+ if (phandle)
+ *phandle = max + 1;
+
+ return 0;
+}
+
int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
{
FDT_CHECK_HEADER(fdt);
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index fd73688f9e9..cf86ddba881 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -139,6 +139,10 @@
#define FDT_ERR_MAX 17
+/* constants */
+#define FDT_MAX_PHANDLE 0xfffffffe
+ /* Valid values for phandles range from 1 to 2^32-2. */
+
/**********************************************************************/
/* Low-level functions (you probably don't need these) */
/**********************************************************************/
@@ -314,6 +318,21 @@ const char *fdt_string(const void *fdt, int stroffset);
uint32_t fdt_get_max_phandle(const void *fdt);
/**
+ * fdt_generate_phandle - return a new, unused phandle for a device tree blob
+ * @fdt: pointer to the device tree blob
+ * @phandle: return location for the new phandle
+ *
+ * Walks the device tree blob and looks for the highest phandle value. On
+ * success, the new, unused phandle value (one higher than the previously
+ * highest phandle value in the device tree blob) will be returned in the
+ * @phandle parameter.
+ *
+ * Returns:
+ * 0 on success or a negative error-code on failure
+ */
+int fdt_generate_phandle(const void *fdt, uint32_t *phandle);
+
+/**
* fdt_num_mem_rsv - retrieve the number of memory reserve map entries
* @fdt: pointer to the device tree blob
*
diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
index bd247462877..3ff9e286307 100644
--- a/scripts/dtc/libfdt/libfdt_env.h
+++ b/scripts/dtc/libfdt/libfdt_env.h
@@ -52,6 +52,7 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/test/dm/syscon.c b/test/dm/syscon.c
index a294dda02e7..0ff9da7ec63 100644
--- a/test/dm/syscon.c
+++ b/test/dm/syscon.c
@@ -67,6 +67,13 @@ static int dm_test_syscon_by_phandle(struct unit_test_state *uts)
ut_assert(!IS_ERR(map));
ut_asserteq(4, map->range_count);
+ ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev,
+ "third-syscon"));
+ map = syscon_regmap_lookup_by_phandle(dev, "third-syscon");
+ ut_assert(map);
+ ut_assert(!IS_ERR(map));
+ ut_asserteq(4, map->range_count);
+
ut_assert(IS_ERR(syscon_regmap_lookup_by_phandle(dev, "not-present")));
return 0;
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index a88a3830c0c..dffaf9043a0 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -1273,6 +1273,13 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
e = image_find_option(IMAGE_CFG_DEBUG);
if (e)
main_hdr->flags = e->debug ? 0x1 : 0;
+ e = image_find_option(IMAGE_CFG_BINARY);
+ if (e) {
+ char *s = strrchr(e->binary.file, '/');
+
+ if (strcmp(s, "/binary.0") == 0)
+ main_hdr->destaddr = cpu_to_le32(params->addr);
+ }
#if defined(CONFIG_KWB_SECURE)
if (image_get_csk_index() >= 0) {
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 2899adff810..d1e1a6743d1 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -403,14 +403,21 @@ int main(int argc, char **argv)
exit (EXIT_FAILURE);
}
- /*
- * scan through mkimage registry for all supported image types
- * and verify the input image file header for match
- * Print the image information for matched image type
- * Returns the error code if not matched
- */
- retval = imagetool_verify_print_header_by_type(ptr, &sbuf,
- tparams, &params);
+ if (params.fflag) {
+ /*
+ * Verifies the header format based on the expected header for image
+ * type in tparams
+ */
+ retval = imagetool_verify_print_header_by_type(ptr, &sbuf,
+ tparams, &params);
+ } else {
+ /**
+ * When listing the image, we are not given the image type. Simply check all
+ * image types to find one that matches our header
+ */
+ retval = imagetool_verify_print_header(ptr, &sbuf,
+ tparams, &params);
+ }
(void) munmap((void *)ptr, sbuf.st_size);
(void) close (ifd);