summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/adc/Kconfig2
-rw-r--r--drivers/ata/dwc_ahci.c2
-rw-r--r--drivers/ata/fsl_sata.c2
-rw-r--r--drivers/ata/mtk_ahci.c12
-rw-r--r--drivers/ata/sata_bootdev.c4
-rw-r--r--drivers/ata/sata_mv.c2
-rw-r--r--drivers/block/Kconfig8
-rw-r--r--drivers/block/Makefile2
-rw-r--r--drivers/block/host-uclass.c15
-rw-r--r--drivers/block/ide.c4
-rw-r--r--drivers/block/rkmtd.c2
-rw-r--r--drivers/block/sandbox-bootdev.c73
-rw-r--r--drivers/bootcount/Kconfig4
-rw-r--r--drivers/bootcount/bootcount_ram.c4
-rw-r--r--drivers/cache/Kconfig2
-rw-r--r--drivers/clk/Kconfig11
-rw-r--r--drivers/clk/Makefile3
-rw-r--r--drivers/clk/airoha/clk-airoha.c6
-rw-r--r--drivers/clk/altera/clk-mem-n5x.c9
-rw-r--r--drivers/clk/altera/clk-n5x.c8
-rw-r--r--drivers/clk/aspeed/Makefile1
-rw-r--r--drivers/clk/aspeed/clk_ast2500.c8
-rw-r--r--drivers/clk/aspeed/clk_ast2600.c8
-rw-r--r--drivers/clk/aspeed/clk_ast2700.c952
-rw-r--r--drivers/clk/at91/sam9x60.c2
-rw-r--r--drivers/clk/at91/sam9x7.c2
-rw-r--r--drivers/clk/at91/sama7d65.c6
-rw-r--r--drivers/clk/at91/sama7g5.c6
-rw-r--r--drivers/clk/at91/sckc.c5
-rw-r--r--drivers/clk/clk-divider.c16
-rw-r--r--drivers/clk/clk-hsdk-cgu.c4
-rw-r--r--drivers/clk/clk-stub.c6
-rw-r--r--drivers/clk/imx/Makefile2
-rw-r--r--drivers/clk/imx/clk-frac-pll.c199
-rw-r--r--drivers/clk/imx/clk-imx6q.c255
-rw-r--r--drivers/clk/imx/clk-imx8mq.c55
-rw-r--r--drivers/clk/imx/clk.h3
-rw-r--r--drivers/clk/owl/Kconfig8
-rw-r--r--drivers/clk/qcom/Kconfig8
-rw-r--r--drivers/clk/qcom/Makefile1
-rw-r--r--drivers/clk/qcom/clock-milos.c73
-rw-r--r--drivers/clk/qcom/clock-qcm2290.c2
-rw-r--r--drivers/clk/qcom/clock-qcs615.c63
-rw-r--r--drivers/clk/qcom/clock-sa8775p.c63
-rw-r--r--drivers/clk/qcom/clock-sc7280.c52
-rw-r--r--drivers/clk/qcom/clock-sm6125.c260
-rw-r--r--drivers/clk/renesas/Kconfig8
-rw-r--r--drivers/clk/renesas/rcar-cpg-lib.c4
-rw-r--r--drivers/clk/rockchip/clk_rk3528.c2
-rw-r--r--drivers/clk/rockchip/clk_rk3576.c54
-rw-r--r--drivers/clk/sophgo/clk-cv1800b.c5
-rw-r--r--drivers/clk/spacemit/Kconfig23
-rw-r--r--drivers/clk/spacemit/Makefile7
-rw-r--r--drivers/clk/spacemit/clk-k1.c1878
-rw-r--r--drivers/clk/spacemit/clk_common.h79
-rw-r--r--drivers/clk/spacemit/clk_ddn.c93
-rw-r--r--drivers/clk/spacemit/clk_ddn.h53
-rw-r--r--drivers/clk/spacemit/clk_mix.c403
-rw-r--r--drivers/clk/spacemit/clk_mix.h224
-rw-r--r--drivers/clk/spacemit/clk_pll.c157
-rw-r--r--drivers/clk/spacemit/clk_pll.h81
-rw-r--r--drivers/clk/sunxi/clk_sunxi.c2
-rw-r--r--drivers/clk/ti/clk-ctrl.c77
-rw-r--r--drivers/core/Kconfig10
-rw-r--r--drivers/core/Makefile2
-rw-r--r--drivers/core/acpi.c7
-rw-r--r--drivers/core/device.c2
-rw-r--r--drivers/core/of_access.c2
-rw-r--r--drivers/core/ofnode.c7
-rw-r--r--drivers/core/read.c34
-rw-r--r--drivers/core/root.c5
-rw-r--r--drivers/core/tag.c4
-rw-r--r--drivers/cpu/armv8_cpu.c2
-rw-r--r--drivers/cpu/bcm283x_cpu.c2
-rw-r--r--drivers/cpu/imx8_cpu.c32
-rw-r--r--drivers/crypto/aspeed/Kconfig8
-rw-r--r--drivers/crypto/aspeed/aspeed_acry.c4
-rw-r--r--drivers/crypto/aspeed/aspeed_hace.c2
-rw-r--r--drivers/crypto/aspeed/cptra_ecdsa.c2
-rw-r--r--drivers/crypto/aspeed/cptra_sha.c2
-rw-r--r--drivers/crypto/fsl/Kconfig11
-rw-r--r--drivers/crypto/tegra/tegra_aes.c2
-rw-r--r--drivers/ddr/altera/sdram_agilex.c4
-rw-r--r--drivers/ddr/altera/sdram_agilex5.c18
-rw-r--r--drivers/ddr/altera/sdram_agilex7m.c4
-rw-r--r--drivers/ddr/altera/sdram_arria10.c12
-rw-r--r--drivers/ddr/altera/sdram_n5x.c4
-rw-r--r--drivers/ddr/altera/sdram_s10.c4
-rw-r--r--drivers/ddr/altera/sdram_soc64.c28
-rw-r--r--drivers/ddr/fsl/Kconfig4
-rw-r--r--drivers/ddr/fsl/main.c2
-rw-r--r--drivers/ddr/fsl/mpc85xx_ddr_gen1.c2
-rw-r--r--drivers/ddr/fsl/mpc85xx_ddr_gen2.c2
-rw-r--r--drivers/ddr/fsl/mpc85xx_ddr_gen3.c2
-rw-r--r--drivers/ddr/imx/imx9/Kconfig7
-rw-r--r--drivers/dma/ti/Kconfig16
-rw-r--r--drivers/fastboot/fb_mmc.c6
-rw-r--r--drivers/firmware/Kconfig2
-rw-r--r--drivers/firmware/firmware-zynqmp.c143
-rw-r--r--drivers/firmware/psci.c4
-rw-r--r--drivers/fpga/altera.c6
-rw-r--r--drivers/fpga/spartan2.c12
-rw-r--r--drivers/fpga/spartan3.c12
-rw-r--r--drivers/fpga/xilinx.c12
-rw-r--r--drivers/gpio/Kconfig61
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-aspeed-g7.c2
-rw-r--r--drivers/gpio/gpio-aspeed-sgpio.c6
-rw-r--r--drivers/gpio/gpio-aspeed.c2
-rw-r--r--drivers/gpio/gpio-fxl6408.c2
-rw-r--r--drivers/gpio/gpio-uclass.c13
-rw-r--r--drivers/gpio/imx_rgpio2p.c4
-rw-r--r--drivers/gpio/mpc8xxx_gpio.c54
-rw-r--r--drivers/gpio/nx_gpio.c7
-rw-r--r--drivers/gpio/pca953x_gpio.c2
-rw-r--r--drivers/gpio/qcom_pmic_gpio.c3
-rw-r--r--drivers/gpio/qcom_spmi_gpio.c3
-rw-r--r--drivers/gpio/sandbox.c4
-rw-r--r--drivers/gpio/spacemit_gpio.c253
-rw-r--r--drivers/i2c/Kconfig155
-rw-r--r--drivers/i2c/Makefile1
-rw-r--r--drivers/i2c/designware_i2c.c44
-rw-r--r--drivers/i2c/designware_i2c_pci.c2
-rw-r--r--drivers/i2c/imx_lpi2c.c4
-rw-r--r--drivers/i2c/k1_i2c.c523
-rw-r--r--drivers/i2c/k1_i2c.h69
-rw-r--r--drivers/i2c/muxes/Kconfig6
-rw-r--r--drivers/i2c/nx_i2c.c9
-rw-r--r--drivers/i3c/Kconfig2
-rw-r--r--drivers/i3c/master/Kconfig2
-rw-r--r--drivers/led/Kconfig2
-rw-r--r--drivers/led/led_sw_blink.c2
-rw-r--r--drivers/mailbox/Kconfig2
-rw-r--r--drivers/mailbox/apple-mbox.c2
-rw-r--r--drivers/mailbox/imx-mailbox.c2
-rw-r--r--drivers/mailbox/k3-sec-proxy.c2
-rw-r--r--drivers/mailbox/mpfs-mbox.c106
-rw-r--r--drivers/mailbox/renesas-mfis.c2
-rw-r--r--drivers/mailbox/sandbox-mbox.c2
-rw-r--r--drivers/mailbox/stm32-ipcc.c2
-rw-r--r--drivers/memory/Kconfig18
-rw-r--r--drivers/mfd/Kconfig6
-rw-r--r--drivers/misc/Kconfig11
-rw-r--r--drivers/misc/cros_ec.c11
-rw-r--r--drivers/misc/cros_ec_sandbox.c4
-rw-r--r--drivers/misc/i2c_eeprom_emul.c2
-rw-r--r--drivers/misc/imx_ele/ele_api.c32
-rw-r--r--drivers/misc/imx_ele/ele_mu.c2
-rw-r--r--drivers/misc/k3_avs.c4
-rw-r--r--drivers/misc/qfw.c2
-rw-r--r--drivers/misc/qfw_acpi.c1
-rw-r--r--drivers/mmc/Kconfig15
-rw-r--r--drivers/mmc/cv1800b_sdhci.c5
-rw-r--r--drivers/mmc/dw_mmc.c6
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c14
-rw-r--r--drivers/mmc/mmc.c7
-rw-r--r--drivers/mmc/mmc_bootdev.c2
-rw-r--r--drivers/mmc/msm_sdhci.c7
-rw-r--r--drivers/mmc/mvebu_mmc.c4
-rw-r--r--drivers/mmc/octeontx_hsmmc.c74
-rw-r--r--drivers/mmc/octeontx_hsmmc.h1
-rw-r--r--drivers/mmc/pci_mmc.c4
-rw-r--r--drivers/mmc/sdhci-cadence.c108
-rw-r--r--drivers/mmc/sdhci-cadence.h5
-rw-r--r--drivers/mmc/sdhci-cadence6.c45
-rw-r--r--drivers/mmc/sdhci.c4
-rw-r--r--drivers/mmc/xenon_sdhci.c5
-rw-r--r--drivers/mtd/Kconfig20
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/raw/Kconfig34
-rw-r--r--drivers/mtd/nand/raw/pxa3xx_nand.c11
-rw-r--r--drivers/mtd/nand/raw/rockchip_nfc.c18
-rw-r--r--drivers/mtd/nand/raw/sunxi_nand.h5
-rw-r--r--drivers/mtd/spi/Kconfig58
-rw-r--r--drivers/mtd/spi/Makefile5
-rw-r--r--drivers/mtd/spi/sf_bootdev.c2
-rw-r--r--drivers/mtd/spi/sf_probe.c8
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c4
-rw-r--r--drivers/mtd/ubi/Kconfig4
-rw-r--r--drivers/mux/Kconfig12
-rw-r--r--drivers/net/Kconfig87
-rw-r--r--drivers/net/Makefile11
-rw-r--r--drivers/net/airoha_eth.c78
-rw-r--r--drivers/net/calxedaxgmac.c2
-rw-r--r--drivers/net/dc2114x.c2
-rw-r--r--drivers/net/dwc_eth_qos.c6
-rw-r--r--drivers/net/dwc_eth_qos.h2
-rw-r--r--drivers/net/dwc_eth_qos_mtk.c442
-rw-r--r--drivers/net/ethoc.c2
-rw-r--r--drivers/net/fsl_enetc.c46
-rw-r--r--drivers/net/fsl_enetc_netc_blk_ctrl.c72
-rw-r--r--drivers/net/hifemac.c3
-rw-r--r--drivers/net/mcfmii.c2
-rw-r--r--drivers/net/mtk_eth/Kconfig1
-rw-r--r--drivers/net/mvgbe.c4
-rw-r--r--drivers/net/mvpp2.c60
-rw-r--r--drivers/net/phy/Kconfig22
-rw-r--r--drivers/net/phy/airoha/Kconfig13
-rw-r--r--drivers/net/phy/airoha/Makefile2
-rw-r--r--drivers/net/phy/airoha/air_an8801.c594
-rw-r--r--drivers/net/phy/airoha/air_en8811.c303
-rw-r--r--drivers/net/phy/airoha/air_phy_lib.c216
-rw-r--r--drivers/net/phy/airoha/air_phy_lib.h39
-rw-r--r--drivers/net/phy/nxp-c45-tja11xx.c2
-rw-r--r--drivers/net/qe/dm_qe_uec.c2
-rw-r--r--drivers/net/rtl8169.c18
-rw-r--r--drivers/net/ti/Kconfig4
-rw-r--r--drivers/net/ti/icssg_prueth.c5
-rw-r--r--drivers/net/tsec.c17
-rw-r--r--drivers/nvme/nvme.c50
-rw-r--r--drivers/pci/Kconfig16
-rw-r--r--drivers/pci/pci-rcar-gen2.c7
-rw-r--r--drivers/pci/pci-rcar-gen3.c5
-rw-r--r--drivers/pci/pci-uclass.c8
-rw-r--r--drivers/pci/pci_mpc85xx.c11
-rw-r--r--drivers/pci/pcie_brcmstb.c387
-rw-r--r--drivers/pci/pcie_dw_mvebu.c5
-rw-r--r--drivers/pci/pcie_dw_qcom.c2
-rw-r--r--drivers/pci/pcie_imx.c4
-rw-r--r--drivers/pci/pcie_layerscape.h3
-rw-r--r--drivers/pci/pcie_layerscape_ep.c24
-rw-r--r--drivers/pci_endpoint/Kconfig8
-rw-r--r--drivers/phy/Kconfig32
-rw-r--r--drivers/phy/cadence/Kconfig4
-rw-r--r--drivers/phy/cadence/phy-cadence-sierra.c4
-rw-r--r--drivers/phy/cadence/phy-cadence-torrent.c8
-rw-r--r--drivers/phy/marvell/comphy_core.c4
-rw-r--r--drivers/phy/qcom/Kconfig18
-rw-r--r--drivers/phy/qcom/phy-qcom-qmp-ufs.c2
-rw-r--r--drivers/phy/renesas/Kconfig6
-rw-r--r--drivers/phy/rockchip/Kconfig2
-rw-r--r--drivers/phy/ti-pipe3-phy.c23
-rw-r--r--drivers/phy/ti/Kconfig2
-rw-r--r--drivers/pinctrl/Kconfig22
-rw-r--r--drivers/pinctrl/Makefile62
-rw-r--r--drivers/pinctrl/airoha/Kconfig26
-rw-r--r--drivers/pinctrl/airoha/Makefile7
-rw-r--r--drivers/pinctrl/airoha/airoha-common.h144
-rw-r--r--drivers/pinctrl/airoha/pinctrl-airoha.c958
-rw-r--r--drivers/pinctrl/airoha/pinctrl-an7581.c1484
-rw-r--r--drivers/pinctrl/airoha/pinctrl-an7583.c1492
-rw-r--r--drivers/pinctrl/airoha/pinctrl-en7523.c1118
-rw-r--r--drivers/pinctrl/aspeed/Makefile2
-rw-r--r--drivers/pinctrl/aspeed/pinctrl_ast2700_soc0.c623
-rw-r--r--drivers/pinctrl/aspeed/pinctrl_ast2700_soc1.c1642
-rw-r--r--drivers/pinctrl/broadcom/Kconfig8
-rw-r--r--drivers/pinctrl/mediatek/Kconfig2
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common.c10
-rw-r--r--drivers/pinctrl/mscc/Kconfig20
-rw-r--r--drivers/pinctrl/mvebu/Kconfig12
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-38x.c2
-rw-r--r--drivers/pinctrl/nexell/pinctrl-nexell.c2
-rw-r--r--drivers/pinctrl/pinctrl-at91.c2
-rw-r--r--drivers/pinctrl/qcom/Kconfig18
-rw-r--r--drivers/pinctrl/qcom/Makefile1
-rw-r--r--drivers/pinctrl/qcom/pinctrl-sm6125.c147
-rw-r--r--drivers/pinctrl/spacemit/Kconfig9
-rw-r--r--drivers/pinctrl/spacemit/Makefile2
-rw-r--r--drivers/pinctrl/spacemit/pinctrl-k1.c550
-rw-r--r--drivers/power/Kconfig364
-rw-r--r--drivers/power/domain/Kconfig8
-rw-r--r--drivers/power/domain/apple-pmgr.c4
-rw-r--r--drivers/power/domain/bcm6328-power-domain.c2
-rw-r--r--drivers/power/domain/imx8-power-domain-legacy.c2
-rw-r--r--drivers/power/domain/imx8-power-domain.c2
-rw-r--r--drivers/power/domain/imx8m-power-domain.c6
-rw-r--r--drivers/power/domain/imx8mp-mediamix.c2
-rw-r--r--drivers/power/domain/meson-ee-pwrc.c15
-rw-r--r--drivers/power/domain/meson-gx-pwrc-vpu.c15
-rw-r--r--drivers/power/domain/meson-secure-pwrc.c2
-rw-r--r--drivers/power/domain/mtk-power-domain.c2
-rw-r--r--drivers/power/domain/renesas-r8a78000-power-domain.c4
-rw-r--r--drivers/power/domain/sandbox-power-domain.c2
-rw-r--r--drivers/power/domain/scmi-power-domain.c10
-rw-r--r--drivers/power/domain/tegra186-power-domain.c2
-rw-r--r--drivers/power/domain/zynqmp-power-domain.c2
-rw-r--r--drivers/power/pmic/Kconfig384
-rw-r--r--drivers/power/pmic/Makefile1
-rw-r--r--drivers/power/pmic/i2c_pmic_emul.c2
-rw-r--r--drivers/power/pmic/pca9450.c2
-rw-r--r--drivers/power/pmic/pmic_qcom.c2
-rw-r--r--drivers/power/pmic/pmic_spacemit_p1.c94
-rw-r--r--drivers/power/regulator/Kconfig482
-rw-r--r--drivers/power/regulator/Makefile5
-rw-r--r--drivers/power/regulator/anatop_regulator.c3
-rw-r--r--drivers/power/regulator/mpq8785.c494
-rw-r--r--drivers/power/regulator/pfuze100.c2
-rw-r--r--drivers/power/regulator/pmbus_generic.c90
-rw-r--r--drivers/power/regulator/pmbus_helper.c315
-rw-r--r--drivers/power/regulator/pmbus_helper.h90
-rw-r--r--drivers/power/regulator/qcom-rpmh-regulator.c113
-rw-r--r--drivers/power/regulator/regulator-uclass.c27
-rw-r--r--drivers/power/regulator/regulator_common.c6
-rw-r--r--drivers/power/regulator/sandbox.c11
-rw-r--r--drivers/power/regulator/sandbox_pmbus.c171
-rw-r--r--drivers/power/regulator/scmi_regulator.c2
-rw-r--r--drivers/power/regulator/spacemit_p1_regulator.c464
-rw-r--r--drivers/power/regulator/tps6287x_regulator.c2
-rw-r--r--drivers/ram/aspeed/Kconfig16
-rw-r--r--drivers/ram/aspeed/Makefile1
-rw-r--r--drivers/ram/aspeed/sdram_ast2600.c15
-rw-r--r--drivers/ram/aspeed/sdram_ast2700.c19
-rw-r--r--drivers/ram/octeon/Kconfig6
-rw-r--r--drivers/ram/renesas/Kconfig6
-rw-r--r--drivers/ram/renesas/Makefile2
-rw-r--r--drivers/ram/renesas/dbsc5/Makefile4
-rw-r--r--drivers/ram/renesas/dbsc5/ecc.c168
-rw-r--r--drivers/ram/renesas/dbsc5/qos.c2
-rw-r--r--drivers/ram/renesas/dbsc5/r8a779g0-dbsc5.c (renamed from drivers/ram/renesas/dbsc5/dbsc5.c)2
-rw-r--r--drivers/ram/renesas/dbsc5/r8a779g0-dbsc5.h (renamed from drivers/ram/renesas/dbsc5/dbsc5.h)6
-rw-r--r--drivers/ram/renesas/dbsc5/r8a779g0-dram.c (renamed from drivers/ram/renesas/dbsc5/dram.c)4
-rw-r--r--drivers/ram/renesas/dbsc5/r8a78000-dbsc5.c76
-rw-r--r--drivers/ram/renesas/dbsc5/r8a78000-dbsc5.h17
-rw-r--r--drivers/ram/renesas/dbsc5/r8a78000-dram.c2795
-rw-r--r--drivers/ram/renesas/dbsc5/r8a78000-dram.h7385
-rw-r--r--drivers/ram/renesas/dbsc5/rtvram.c44
-rw-r--r--drivers/ram/stm32mp1/Kconfig36
-rw-r--r--drivers/reboot-mode/Kconfig18
-rw-r--r--drivers/remoteproc/ipu_rproc.c7
-rw-r--r--drivers/remoteproc/pru_rproc.c15
-rw-r--r--drivers/remoteproc/ti_k3_r5f_rproc.c2
-rw-r--r--drivers/reset/Kconfig41
-rw-r--r--drivers/reset/Makefile7
-rw-r--r--drivers/reset/reset-ast2500.c6
-rw-r--r--drivers/reset/reset-ast2600.c6
-rw-r--r--drivers/reset/reset-ast2700.c82
-rw-r--r--drivers/reset/reset-at91.c2
-rw-r--r--drivers/reset/reset-bcm6345.c2
-rw-r--r--drivers/reset/reset-brcmstb-rescal.c103
-rw-r--r--drivers/reset/reset-brcmstb.c97
-rw-r--r--drivers/reset/reset-dra7.c2
-rw-r--r--drivers/reset/reset-mediatek.c2
-rw-r--r--drivers/reset/reset-meson.c2
-rw-r--r--drivers/reset/reset-npcm.c2
-rw-r--r--drivers/reset/reset-raspberrypi.c2
-rw-r--r--drivers/reset/reset-spacemit-k1.c548
-rw-r--r--drivers/reset/reset-sunxi.c2
-rw-r--r--drivers/reset/reset-uclass.c34
-rw-r--r--drivers/reset/reset-zynqmp.c11
-rw-r--r--drivers/reset/sandbox-reset-test.c14
-rw-r--r--drivers/reset/sandbox-reset.c60
-rw-r--r--drivers/reset/spacemit/Makefile5
-rw-r--r--drivers/reset/spacemit/reset-spacemit-k1.c289
-rw-r--r--drivers/reset/sti-reset.c2
-rw-r--r--drivers/reset/tegra-car-reset.c2
-rw-r--r--drivers/reset/tegra186-reset.c2
-rw-r--r--drivers/rng/iproc_rng200.c2
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/ds1307.c6
-rw-r--r--drivers/rtc/goldfish_rtc.c16
-rw-r--r--drivers/rtc/i2c_rtc_emul.c2
-rw-r--r--drivers/rtc/m41t62.c4
-rw-r--r--drivers/rtc/mcfrtc.c2
-rw-r--r--drivers/rtc/pcf85063.c134
-rw-r--r--drivers/rtc/sandbox_rtc.c2
-rw-r--r--drivers/scsi/sandbox_scsi.c2
-rw-r--r--drivers/scsi/scsi_bootdev.c4
-rw-r--r--drivers/serial/Kconfig18
-rw-r--r--drivers/serial/serial_cortina.c8
-rw-r--r--drivers/serial/serial_goldfish.c6
-rw-r--r--drivers/serial/serial_lpuart.c25
-rw-r--r--drivers/serial/serial_msm_geni.c4
-rw-r--r--drivers/serial/serial_sh.c2
-rw-r--r--drivers/smem/Kconfig30
-rw-r--r--drivers/soc/soc_xilinx_zynqmp.c4
-rw-r--r--drivers/soc/ti/Kconfig4
-rw-r--r--drivers/sound/da7219.c2
-rw-r--r--drivers/sound/max98357a.c2
-rw-r--r--drivers/spi/Kconfig30
-rw-r--r--drivers/spi/apple_spi.c2
-rw-r--r--drivers/spi/cadence_qspi.c16
-rw-r--r--drivers/spi/designware_spi.c12
-rw-r--r--drivers/spi/fsl_qspi.c9
-rw-r--r--drivers/spi/spi-aspeed-smc.c219
-rw-r--r--drivers/spmi/Kconfig8
-rw-r--r--drivers/sysinfo/Kconfig8
-rw-r--r--drivers/sysinfo/Makefile1
-rw-r--r--drivers/sysinfo/sysinfo-uclass.c12
-rw-r--r--drivers/sysinfo/tq_eeprom.c203
-rw-r--r--drivers/sysreset/Kconfig15
-rw-r--r--drivers/sysreset/Makefile1
-rw-r--r--drivers/sysreset/sysreset-uclass.c37
-rw-r--r--drivers/sysreset/sysreset_qcom-psci.c45
-rw-r--r--drivers/sysreset/sysreset_qemu_virt_ctrl.c4
-rw-r--r--drivers/thermal/Kconfig48
-rw-r--r--drivers/thermal/Makefile2
-rw-r--r--drivers/thermal/imx_tmu.c125
-rw-r--r--drivers/thermal/jc42.c93
-rw-r--r--drivers/thermal/pmbus_thermal.c33
-rw-r--r--drivers/thermal/ti-bandgap.c2
-rw-r--r--drivers/timer/goldfish_timer.c10
-rw-r--r--drivers/timer/orion-timer.c3
-rw-r--r--drivers/timer/sp804_timer.c2
-rw-r--r--drivers/tpm/cr50_i2c.c2
-rw-r--r--drivers/ufs/Kconfig6
-rw-r--r--drivers/ufs/ufs-amd-versal2.c1
-rw-r--r--drivers/ufs/ufs-qcom.c54
-rw-r--r--drivers/usb/Kconfig16
-rw-r--r--drivers/usb/cdns3/Kconfig6
-rw-r--r--drivers/usb/dwc3/dwc3-am62.c2
-rw-r--r--drivers/usb/dwc3/dwc3-generic-sti.c2
-rw-r--r--drivers/usb/dwc3/dwc3-generic.c10
-rw-r--r--drivers/usb/eth/Kconfig16
-rw-r--r--drivers/usb/gadget/Kconfig22
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c2
-rw-r--r--drivers/usb/gadget/f_mass_storage.c11
-rw-r--r--drivers/usb/gadget/f_sdp.c16
-rw-r--r--drivers/usb/host/Kconfig44
-rw-r--r--drivers/usb/host/ehci-marvell.c4
-rw-r--r--drivers/usb/host/ohci-hcd.c2
-rw-r--r--drivers/usb/host/usb-uclass.c2
-rw-r--r--drivers/usb/host/xhci-mvebu.c1
-rw-r--r--drivers/usb/musb-new/Kconfig16
-rw-r--r--drivers/usb/musb-new/omap2430.c2
-rw-r--r--drivers/usb/tcpm/Kconfig4
-rw-r--r--drivers/usb/tcpm/tcpm.c2
-rw-r--r--drivers/video/Kconfig210
-rw-r--r--drivers/video/bridge/Kconfig4
-rw-r--r--drivers/video/bridge/anx6345.c2
-rw-r--r--drivers/video/bridge/ps862x.c2
-rw-r--r--drivers/video/bridge/ptn3460.c2
-rw-r--r--drivers/video/console_normal.c2
-rw-r--r--drivers/video/console_rotate.c6
-rw-r--r--drivers/video/console_truetype.c2
-rw-r--r--drivers/video/dw_mipi_dsi.c2
-rw-r--r--drivers/video/imx/Kconfig2
-rw-r--r--drivers/video/imx/ipu.h1
-rw-r--r--drivers/video/imx/ipu_common.c13
-rw-r--r--drivers/video/imx/ldb.c2
-rw-r--r--drivers/video/meson/meson_vpu.c8
-rw-r--r--drivers/video/rockchip/Kconfig4
-rw-r--r--drivers/video/simplefb.c17
-rw-r--r--drivers/video/stm32/stm32_dsi.c2
-rw-r--r--drivers/video/sunxi/sunxi_de2.c2
-rw-r--r--drivers/video/sunxi/sunxi_display.c2
-rw-r--r--drivers/video/tda19988.c2
-rw-r--r--drivers/video/tegra/Kconfig42
-rw-r--r--drivers/video/tegra/dsi.c2
-rw-r--r--drivers/video/ti/Kconfig2
-rw-r--r--drivers/video/tidss/Kconfig4
-rw-r--r--drivers/video/zynqmp/Kconfig6
-rw-r--r--drivers/virtio/virtio-uclass.c4
-rw-r--r--drivers/virtio/virtio_blk.c11
-rw-r--r--drivers/virtio/virtio_mmio.c27
-rw-r--r--drivers/watchdog/Kconfig9
-rw-r--r--drivers/watchdog/designware_wdt.c2
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c2
-rw-r--r--drivers/watchdog/octeontx_wdt.c3
-rw-r--r--drivers/watchdog/orion_wdt.c101
-rw-r--r--drivers/watchdog/renesas_wwdt.c2
-rw-r--r--drivers/watchdog/rti_wdt.c4
-rw-r--r--drivers/watchdog/sbsa_gwdt.c10
-rw-r--r--drivers/watchdog/starfive_wdt.c4
-rw-r--r--drivers/watchdog/ulp_wdog.c79
454 files changed, 32655 insertions, 3420 deletions
diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig
index 2b45f9e5eba..d5ef0795401 100644
--- a/drivers/adc/Kconfig
+++ b/drivers/adc/Kconfig
@@ -5,7 +5,7 @@ config ADC
This enables ADC API for drivers, which allows driving ADC features
by single and multi-channel methods for:
- start/stop/get data for conversion of a single-channel selected by
- a number or multi-channels selected by a bitmask
+ a number or multi-channels selected by a bitmask
- get data mask (ADC resolution)
ADC reference Voltage supply options:
- methods for get Vdd/Vss reference Voltage values with polarity
diff --git a/drivers/ata/dwc_ahci.c b/drivers/ata/dwc_ahci.c
index b480cde4465..0431d370716 100644
--- a/drivers/ata/dwc_ahci.c
+++ b/drivers/ata/dwc_ahci.c
@@ -39,7 +39,7 @@ static int dwc_ahci_of_to_plat(struct udevice *dev)
priv->base = map_physmem(dev_read_addr(dev), sizeof(void *),
MAP_NOCACHE);
- addr = devfdt_get_addr_index(dev, 1);
+ addr = dev_read_addr_index(dev, 1);
if (addr != FDT_ADDR_T_NONE) {
priv->wrapper_base = map_physmem(addr, sizeof(void *),
MAP_NOCACHE);
diff --git a/drivers/ata/fsl_sata.c b/drivers/ata/fsl_sata.c
index 4990148388b..a29735f7609 100644
--- a/drivers/ata/fsl_sata.c
+++ b/drivers/ata/fsl_sata.c
@@ -960,7 +960,7 @@ static int sata_fsl_scan(struct udevice *dev)
return 0;
}
-struct ahci_ops sata_fsl_ahci_ops = {
+static const struct ahci_ops sata_fsl_ahci_ops = {
.scan = sata_fsl_scan,
};
diff --git a/drivers/ata/mtk_ahci.c b/drivers/ata/mtk_ahci.c
index 53aabee0a5e..1d4245ee635 100644
--- a/drivers/ata/mtk_ahci.c
+++ b/drivers/ata/mtk_ahci.c
@@ -45,7 +45,9 @@ static int mtk_ahci_of_to_plat(struct udevice *dev)
{
struct mtk_ahci_priv *priv = dev_get_priv(dev);
- priv->base = devfdt_remap_addr_index(dev, 0);
+ priv->base = dev_remap_addr_index(dev, 0);
+ if (!priv->base)
+ return -EINVAL;
return 0;
}
@@ -54,11 +56,9 @@ static int mtk_ahci_parse_property(struct ahci_uc_priv *hpriv,
struct udevice *dev)
{
struct mtk_ahci_priv *plat = dev_get_priv(dev);
- const void *fdt = gd->fdt_blob;
/* enable SATA function if needed */
- if (fdt_get_property(fdt, dev_of_offset(dev),
- "mediatek,phy-mode", NULL)) {
+ if (dev_read_prop(dev, "mediatek,phy-mode", NULL)) {
plat->mode = syscon_regmap_lookup_by_phandle(dev,
"mediatek,phy-mode");
if (IS_ERR(plat->mode)) {
@@ -69,8 +69,8 @@ static int mtk_ahci_parse_property(struct ahci_uc_priv *hpriv,
SYS_CFG_SATA_MSK, SYS_CFG_SATA_EN);
}
- ofnode_read_u32(dev_ofnode(dev), "ports-implemented",
- &hpriv->port_map);
+ dev_read_u32(dev, "ports-implemented", &hpriv->port_map);
+
return 0;
}
diff --git a/drivers/ata/sata_bootdev.c b/drivers/ata/sata_bootdev.c
index a5ca6f6fd5b..7d5ef3c94bf 100644
--- a/drivers/ata/sata_bootdev.c
+++ b/drivers/ata/sata_bootdev.c
@@ -37,9 +37,6 @@ static int sata_bootdev_hunt(struct bootdev_hunter *info, bool show)
return 0;
}
-struct bootdev_ops sata_bootdev_ops = {
-};
-
static const struct udevice_id sata_bootdev_ids[] = {
{ .compatible = "u-boot,bootdev-sata" },
{ }
@@ -48,7 +45,6 @@ static const struct udevice_id sata_bootdev_ids[] = {
U_BOOT_DRIVER(sata_bootdev) = {
.name = "sata_bootdev",
.id = UCLASS_BOOTDEV,
- .ops = &sata_bootdev_ops,
.bind = sata_bootdev_bind,
.of_match = sata_bootdev_ids,
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index b8c73b4a9dd..3fb1a245698 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1122,7 +1122,7 @@ static const struct udevice_id sata_mv_ids[] = {
{ }
};
-struct ahci_ops sata_mv_ahci_ops = {
+static const struct ahci_ops sata_mv_ahci_ops = {
.scan = sata_mv_scan,
};
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index adf338ab00c..d44cf4bcb6b 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -68,10 +68,10 @@ config BLKMAP
bool "Composable virtual block devices (blkmap)"
depends on BLK
help
- Create virtual block devices that are backed by various sources,
- e.g. RAM, or parts of an existing block device. Though much more
- rudimentary, it borrows a lot of ideas from Linux's device mapper
- subsystem.
+ Create virtual block devices that are backed by various sources,
+ e.g. RAM, or parts of an existing block device. Though much more
+ rudimentary, it borrows a lot of ideas from Linux's device mapper
+ subsystem.
Example use-cases:
- Treat a region of RAM as a block device, i.e. a RAM disk. This let's
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index f5a9d8637a3..c827fa81a2d 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -13,7 +13,7 @@ ifndef CONFIG_XPL_BUILD
obj-$(CONFIG_IDE) += ide.o
obj-$(CONFIG_RKMTD) += rkmtd.o
endif
-obj-$(CONFIG_SANDBOX) += sandbox.o host-uclass.o host_dev.o
+obj-$(CONFIG_SANDBOX) += sandbox.o sandbox-bootdev.o host-uclass.o host_dev.o
obj-$(CONFIG_$(PHASE_)BLOCK_CACHE) += blkcache.o
obj-$(CONFIG_$(PHASE_)BLKMAP) += blkmap.o
obj-$(CONFIG_$(PHASE_)BLKMAP) += blkmap_helper.o
diff --git a/drivers/block/host-uclass.c b/drivers/block/host-uclass.c
index cf42bd1e07a..95b0b0b2ffe 100644
--- a/drivers/block/host-uclass.c
+++ b/drivers/block/host-uclass.c
@@ -150,6 +150,21 @@ struct udevice *host_find_by_label(const char *label)
return NULL;
}
+int host_set_flags_by_label(const char *label, unsigned int flags)
+{
+ struct udevice *dev;
+ struct host_sb_plat *plat;
+
+ dev = host_find_by_label(label);
+ if (!dev)
+ return -ENODEV;
+
+ plat = dev_get_plat(dev);
+ plat->flags = flags;
+
+ return 0;
+}
+
struct udevice *host_get_cur_dev(void)
{
struct uclass *uc = uclass_find(UCLASS_HOST);
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index cab5e1bc92b..c1a46dd2a94 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -969,9 +969,6 @@ static int ide_bootdev_hunt(struct bootdev_hunter *info, bool show)
return 0;
}
-struct bootdev_ops ide_bootdev_ops = {
-};
-
static const struct udevice_id ide_bootdev_ids[] = {
{ .compatible = "u-boot,bootdev-ide" },
{ }
@@ -980,7 +977,6 @@ static const struct udevice_id ide_bootdev_ids[] = {
U_BOOT_DRIVER(ide_bootdev) = {
.name = "ide_bootdev",
.id = UCLASS_BOOTDEV,
- .ops = &ide_bootdev_ops,
.bind = ide_bootdev_bind,
.of_match = ide_bootdev_ids,
};
diff --git a/drivers/block/rkmtd.c b/drivers/block/rkmtd.c
index f84cacd7ead..9334ab24a61 100644
--- a/drivers/block/rkmtd.c
+++ b/drivers/block/rkmtd.c
@@ -935,7 +935,7 @@ int rkmtd_detach_mtd(struct udevice *dev)
return 0;
}
-struct rkmtd_ops rkmtd_ops = {
+static const struct rkmtd_ops rkmtd_ops = {
.attach_mtd = rkmtd_attach_mtd,
.detach_mtd = rkmtd_detach_mtd,
};
diff --git a/drivers/block/sandbox-bootdev.c b/drivers/block/sandbox-bootdev.c
new file mode 100644
index 00000000000..15af0c17d1f
--- /dev/null
+++ b/drivers/block/sandbox-bootdev.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#define LOG_CATEGORY UCLASS_HOST
+
+#include <bootdev.h>
+#include <dm.h>
+#include <log.h>
+#include <sandbox_host.h>
+
+static int sandbox_bootdev_bind(struct udevice *dev)
+{
+ struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+
+ ucp->prio = BOOTDEVP_4_SCAN_FAST;
+
+ return 0;
+}
+
+/**
+ * sandbox_bootdev_hunt() - Hunt host bootdev.
+ *
+ * Note, this hunter exists for bootdev testing to simulate a failure
+ * mode. Do not use as an example of a real hunter.
+ *
+ * @info: Hunter details.
+ * @show: Enable extra printouts.
+ *
+ * Returns: 0 if OK, -ve on error (expected by the test)
+ */
+static int sandbox_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ uclass_id_foreach_dev(UCLASS_HOST, dev, uc) {
+ struct host_sb_plat *plat = dev_get_plat(dev);
+
+ log_debug("hunting %s\n", plat->label);
+
+ if (plat->flags & HOST_FLAG_BROKEN) {
+ ret = -ETIME;
+ log_debug("cannot hunt sandbox device '%s': %d\n",
+ plat->label, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct bootdev_ops sandbox_bootdev_ops = {
+};
+
+static const struct udevice_id sandbox_bootdev_ids[] = {
+ { .compatible = "u-boot,bootdev-sandbox" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_bootdev) = {
+ .name = "sandbox_bootdev",
+ .id = UCLASS_BOOTDEV,
+ .ops = &sandbox_bootdev_ops,
+ .bind = sandbox_bootdev_bind,
+ .of_match = sandbox_bootdev_ids,
+};
+
+BOOTDEV_HUNTER(sandbox_bootdev_hunter) = {
+ .prio = BOOTDEVP_4_SCAN_FAST,
+ .uclass = UCLASS_HOST,
+ .hunt = sandbox_bootdev_hunt,
+ .drv = DM_DRIVER_REF(sandbox_bootdev),
+};
diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig
index 4c0c8d89bb4..af6bd2f1a7d 100644
--- a/drivers/bootcount/Kconfig
+++ b/drivers/bootcount/Kconfig
@@ -68,7 +68,7 @@ config BOOTCOUNT_ENV
saveenv on all reboots, the environment variable
"upgrade_available" is used. If "upgrade_available" is
0, "bootcount" is always 0. If "upgrade_available" is 1,
- "bootcount" is incremented in the environment.
+ "bootcount" is incremented in the environment.
So the Userspace Application must set the "upgrade_available"
and "bootcount" variables to 0, if the system booted successfully.
@@ -83,7 +83,7 @@ config BOOTCOUNT_AT91
depends on AT91SAM9XE
config DM_BOOTCOUNT
- bool "Boot counter in a device-model device"
+ bool "Boot counter in a device-model device"
help
Enables reading/writing the bootcount in a device-model based
backing store. If an entry in /chosen/u-boot,bootcount-device
diff --git a/drivers/bootcount/bootcount_ram.c b/drivers/bootcount/bootcount_ram.c
index 33e157b865a..f726d9ab016 100644
--- a/drivers/bootcount/bootcount_ram.c
+++ b/drivers/bootcount/bootcount_ram.c
@@ -27,7 +27,7 @@ void bootcount_store(ulong a)
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
- size += gd->bd->bi_dram[i].size;
+ size += gd->dram[i].size;
save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
writel(a, save_addr);
writel(CONFIG_SYS_BOOTCOUNT_MAGIC, &save_addr[1]);
@@ -50,7 +50,7 @@ ulong bootcount_load(void)
int i, tmp;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
- size += gd->bd->bi_dram[i].size;
+ size += gd->dram[i].size;
save_addr = (ulong *)(size - BOOTCOUNT_ADDR);
counter = readl(&save_addr[0]);
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
index 3bf5c7f5dbf..5ebc8842acd 100644
--- a/drivers/cache/Kconfig
+++ b/drivers/cache/Kconfig
@@ -14,7 +14,7 @@ config CACHE
configuring settings that be found from a device tree file.
config L2X0_CACHE
- tristate "PL310 cache driver"
+ bool "PL310 cache driver"
select CACHE
depends on ARM
help
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c2da7b3938b..145e4cfa2de 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -134,8 +134,8 @@ config CLK_CDCE9XX
bool "Enable CDCD9XX clock driver"
depends on CLK && ARCH_OMAP2PLUS
help
- Enable the clock synthesizer driver for CDCE913/925/937/949
- series of chips.
+ Enable the clock synthesizer driver for CDCE913/925/937/949
+ series of chips.
config CLK_ICS8N3QV01
bool "Enable ICS8N3QV01 VCXO driver"
@@ -216,7 +216,7 @@ config CLK_HSDK
Synopsys ARC HSDK-4xD boards
config CLK_VERSACLOCK
- tristate "Enable VersaClock 5/6 devices"
+ bool "Enable VersaClock 5/6 devices"
depends on CLK
depends on CLK_CCF
depends on OF_CONTROL
@@ -277,11 +277,12 @@ source "drivers/clk/mvebu/Kconfig"
source "drivers/clk/owl/Kconfig"
source "drivers/clk/qcom/Kconfig"
source "drivers/clk/renesas/Kconfig"
-source "drivers/clk/sophgo/Kconfig"
-source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/sifive/Kconfig"
+source "drivers/clk/sophgo/Kconfig"
+source "drivers/clk/spacemit/Kconfig"
source "drivers/clk/starfive/Kconfig"
source "drivers/clk/stm32/Kconfig"
+source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/thead/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5f0c0d8a5c2..2bfa789e48a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_$(PHASE_)CLK_STUB) += clk-stub.o
obj-y += adi/
obj-y += airoha/
obj-y += analogbits/
-obj-y += imx/
+obj-$(CONFIG_MACH_IMX) += imx/
obj-$(CONFIG_CLK_JH7110) += starfive/
obj-y += tegra/
obj-y += ti/
@@ -48,6 +48,7 @@ obj-$(CONFIG_CLK_RENESAS) += renesas/
obj-$(CONFIG_$(PHASE_)CLK_SCMI) += clk_scmi.o
obj-$(CONFIG_CLK_SIFIVE) += sifive/
obj-$(CONFIG_CLK_SOPHGO) += sophgo/
+obj-$(CONFIG_CLK_SPACEMIT) += spacemit/
obj-$(CONFIG_CLK_SUNXI) += sunxi/
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o
diff --git a/drivers/clk/airoha/clk-airoha.c b/drivers/clk/airoha/clk-airoha.c
index 49dbca82135..89a8b4cb1cf 100644
--- a/drivers/clk/airoha/clk-airoha.c
+++ b/drivers/clk/airoha/clk-airoha.c
@@ -327,7 +327,7 @@ static int airoha_clk_enable(struct clk *clk)
struct airoha_clk_soc_data *data = priv->data;
int id = clk->id;
- if (id > data->num_clocks)
+ if (id >= data->num_clocks)
return -EINVAL;
return 0;
@@ -349,7 +349,7 @@ static ulong airoha_clk_get_rate(struct clk *clk)
ulong rate;
int ret;
- if (id > data->num_clocks) {
+ if (id >= data->num_clocks) {
dev_err(clk->dev, "Invalid clk ID %d\n", id);
return 0;
}
@@ -412,7 +412,7 @@ static ulong airoha_clk_set_rate(struct clk *clk, ulong rate)
int div;
int ret;
- if (id > data->num_clocks) {
+ if (id >= data->num_clocks) {
dev_err(clk->dev, "Invalid clk ID %d\n", id);
return 0;
}
diff --git a/drivers/clk/altera/clk-mem-n5x.c b/drivers/clk/altera/clk-mem-n5x.c
index ac59571a853..149e3016dd3 100644
--- a/drivers/clk/altera/clk-mem-n5x.c
+++ b/drivers/clk/altera/clk-mem-n5x.c
@@ -103,12 +103,13 @@ static int socfpga_mem_clk_enable(struct clk *clk)
static int socfpga_mem_clk_of_to_plat(struct udevice *dev)
{
struct socfpga_mem_clk_plat *plat = dev_get_plat(dev);
- fdt_addr_t addr;
+ void __iomem *addr;
- addr = devfdt_get_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_read_addr_ptr(dev);
+ if (!addr)
return -EINVAL;
- plat->regs = (void __iomem *)addr;
+
+ plat->regs = addr;
return 0;
}
diff --git a/drivers/clk/altera/clk-n5x.c b/drivers/clk/altera/clk-n5x.c
index 185c9028a78..0a3bae38589 100644
--- a/drivers/clk/altera/clk-n5x.c
+++ b/drivers/clk/altera/clk-n5x.c
@@ -454,12 +454,12 @@ static int socfpga_clk_probe(struct udevice *dev)
static int socfpga_clk_of_to_plat(struct udevice *dev)
{
struct socfpga_clk_plat *plat = dev_get_plat(dev);
- fdt_addr_t addr;
+ void __iomem *addr;
- addr = devfdt_get_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_read_addr_ptr(dev);
+ if (!addr)
return -EINVAL;
- plat->regs = (void __iomem *)addr;
+ plat->regs = addr;
return 0;
}
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
index 84776e5265e..285180b67cf 100644
--- a/drivers/clk/aspeed/Makefile
+++ b/drivers/clk/aspeed/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
obj-$(CONFIG_ASPEED_AST2600) += clk_ast2600.o
+obj-$(CONFIG_ASPEED_AST2700) += clk_ast2700.o
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index a330dcda4dc..94c7f662319 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -534,7 +534,7 @@ static int ast2500_clk_enable(struct clk *clk)
return 0;
}
-struct clk_ops ast2500_clk_ops = {
+static const struct clk_ops ast2500_clk_ops = {
.get_rate = ast2500_clk_get_rate,
.set_rate = ast2500_clk_set_rate,
.enable = ast2500_clk_enable,
@@ -544,9 +544,9 @@ static int ast2500_clk_of_to_plat(struct udevice *dev)
{
struct ast2500_clk_priv *priv = dev_get_priv(dev);
- priv->scu = devfdt_get_addr_ptr(dev);
- if (IS_ERR(priv->scu))
- return PTR_ERR(priv->scu);
+ priv->scu = dev_read_addr_ptr(dev);
+ if (!priv->scu)
+ return -EINVAL;
return 0;
}
diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c
index 535010b7941..74209e947ed 100644
--- a/drivers/clk/aspeed/clk_ast2600.c
+++ b/drivers/clk/aspeed/clk_ast2600.c
@@ -1161,7 +1161,7 @@ static void ast2600_clk_dump(struct udevice *dev)
}
#endif
-struct clk_ops ast2600_clk_ops = {
+static const struct clk_ops ast2600_clk_ops = {
.get_rate = ast2600_clk_get_rate,
.set_rate = ast2600_clk_set_rate,
.enable = ast2600_clk_enable,
@@ -1174,9 +1174,9 @@ static int ast2600_clk_probe(struct udevice *dev)
{
struct ast2600_clk_priv *priv = dev_get_priv(dev);
- priv->scu = devfdt_get_addr_ptr(dev);
- if (IS_ERR(priv->scu))
- return PTR_ERR(priv->scu);
+ priv->scu = dev_read_addr_ptr(dev);
+ if (!priv->scu)
+ return -EINVAL;
ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig);
ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig);
diff --git a/drivers/clk/aspeed/clk_ast2700.c b/drivers/clk/aspeed/clk_ast2700.c
new file mode 100644
index 00000000000..ca76abef48f
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2700.c
@@ -0,0 +1,952 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <asm/io.h>
+#include <asm/arch/scu_ast2700.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <syscon.h>
+#include <linux/bitfield.h>
+
+#include <dt-bindings/clock/aspeed,ast2700-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * RGMII clock source tree
+ * HPLL -->|\
+ * | |---->| divider |---->RGMII 125M for MAC#0 & MAC#1
+ * APLL -->|/
+ */
+#define RGMII_DEFAULT_CLK_SRC SCU1_CLK_HPLL
+
+struct mac_delay_config {
+ u32 tx_delay_1000;
+ u32 rx_delay_1000;
+ u32 tx_delay_100;
+ u32 rx_delay_100;
+ u32 tx_delay_10;
+ u32 rx_delay_10;
+};
+
+typedef int (*ast2700_clk_init_fn)(struct udevice *dev);
+
+struct ast2700_clk_priv {
+ void __iomem *reg;
+ ast2700_clk_init_fn init;
+};
+
+static u32 ast2700_soc1_get_pll_rate(struct ast2700_scu1 *scu, int pll_idx)
+{
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+
+ switch (pll_idx) {
+ case SCU1_CLK_HPLL:
+ pll_reg.w = readl(&scu->hpll);
+ break;
+ case SCU1_CLK_APLL:
+ pll_reg.w = readl(&scu->apll);
+ break;
+ case SCU1_CLK_DPLL:
+ pll_reg.w = readl(&scu->dpll);
+ break;
+ }
+
+ if (!pll_reg.b.bypass) {
+ mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1);
+ div = (pll_reg.b.p + 1);
+ }
+
+ return ((CLKIN_25M * mul) / div);
+}
+
+#define SCU_CLKSEL2_HCLK_DIV_MASK GENMASK(22, 20)
+#define SCU_CLKSEL2_HCLK_DIV_SHIFT 20
+
+static u32 ast2700_soc1_get_hclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 clk_sel2 = readl(&scu->clk_sel2);
+ u32 hclk_div = (clk_sel2 & SCU_CLKSEL2_HCLK_DIV_MASK) >>
+ SCU_CLKSEL2_HCLK_DIV_SHIFT;
+
+ if (!hclk_div)
+ hclk_div = 2;
+ else
+ hclk_div++;
+
+ return (rate / hclk_div);
+}
+
+#define SCU1_CLKSEL1_PCLK_DIV_MASK GENMASK(20, 18)
+#define SCU1_CLKSEL1_PCLK_DIV_SHIFT 18
+
+static u32 ast2700_soc1_get_pclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+
+ u32 clk_sel1 = readl(&scu->clk_sel1);
+ u32 pclk_div = (clk_sel1 & SCU1_CLKSEL1_PCLK_DIV_MASK) >>
+ SCU1_CLKSEL1_PCLK_DIV_SHIFT;
+
+ return (rate / ((pclk_div + 1) * 2));
+}
+
+#define SCU_UART_CLKGEN_N_MASK GENMASK(17, 8)
+#define SCU_UART_CLKGEN_N_SHIFT 8
+#define SCU_UART_CLKGEN_R_MASK GENMASK(7, 0)
+#define SCU_UART_CLKGEN_R_SHIFT 0
+
+static u32 ast2700_soc1_get_uart_uxclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 uxclk_sel = readl(&scu->clk_sel2) & GENMASK(1, 0);
+ u32 uxclk_ctrl = readl(&scu->uxclk_ctrl);
+ u32 rate;
+
+ switch (uxclk_sel) {
+ case 0:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ break;
+ }
+
+ u32 n = (uxclk_ctrl & SCU_UART_CLKGEN_N_MASK) >>
+ SCU_UART_CLKGEN_N_SHIFT;
+ u32 r = (uxclk_ctrl & SCU_UART_CLKGEN_R_MASK) >>
+ SCU_UART_CLKGEN_R_SHIFT;
+
+ return ((rate * r) / (n * 2));
+}
+
+#define SCU_HUART_CLKGEN_N_MASK GENMASK(17, 8)
+#define SCU_HUART_CLKGEN_N_SHIFT 8
+#define SCU_HUART_CLKGEN_R_MASK GENMASK(7, 0)
+#define SCU_HUART_CLKGEN_R_SHIFT 0
+
+static u32 ast2700_soc1_get_uart_huxclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 huxclk_sel = (readl(&scu->clk_sel2) & GENMASK(4, 3)) >> 3;
+ u32 huxclk_ctrl = readl(&scu->huxclk_ctrl);
+ u32 n = (huxclk_ctrl & SCU_HUART_CLKGEN_N_MASK) >>
+ SCU_HUART_CLKGEN_N_SHIFT;
+ u32 r = (huxclk_ctrl & SCU_HUART_CLKGEN_R_MASK) >>
+ SCU_HUART_CLKGEN_R_SHIFT;
+ u32 rate;
+
+ switch (huxclk_sel) {
+ case 0:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ break;
+ }
+
+ return ((rate * r) / (n * 2));
+}
+
+#define SCU_CLKSRC1_SDIO_DIV_MASK GENMASK(16, 14)
+#define SCU_CLKSRC1_SDIO_DIV_SHIFT 14
+#define SCU_CLKSRC1_SDIO_SEL BIT(13)
+const int ast2700_sd_div_tbl[] = {
+ 2, 2, 3, 4, 5, 6, 7, 8
+};
+
+static u32 ast2700_soc1_get_sdio_clk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = 0;
+ u32 clk_sel1 = readl(&scu->clk_sel1);
+ u32 div = (clk_sel1 & SCU_CLKSRC1_SDIO_DIV_MASK) >>
+ SCU_CLKSRC1_SDIO_DIV_SHIFT;
+
+ if (clk_sel1 & SCU_CLKSRC1_SDIO_SEL)
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ else
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+
+ if (!div)
+ div = 1;
+
+ div++;
+
+ return (rate / div);
+}
+
+static void ast2700_init_sdclk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (src_clk / ast2700_sd_div_tbl[i] <= 125000000)
+ break;
+ }
+
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~(SCU_CLKSRC1_SDIO_DIV_MASK | SCU_CLKSRC1_SDIO_SEL);
+ reg_280 |= i << SCU_CLKSRC1_SDIO_DIV_SHIFT;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static u32
+ast2700_soc1_get_uart_clk_rate(struct ast2700_scu1 *scu, int uart_idx)
+{
+ u32 rate = 0;
+
+ if (readl(&scu->clk_sel1) & BIT(uart_idx))
+ rate = ast2700_soc1_get_uart_huxclk_rate(scu);
+ else
+ rate = ast2700_soc1_get_uart_uxclk_rate(scu);
+
+ return rate;
+}
+
+static ulong ast2700_soc1_clk_get_rate(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case SCU1_CLK_HPLL:
+ case SCU1_CLK_APLL:
+ case SCU1_CLK_DPLL:
+ rate = ast2700_soc1_get_pll_rate(scu, clk->id);
+ break;
+ case SCU1_CLK_AHB:
+ rate = ast2700_soc1_get_hclk_rate(scu);
+ break;
+ case SCU1_CLK_APB:
+ rate = ast2700_soc1_get_pclk_rate(scu);
+ break;
+ case SCU1_CLK_GATE_UART0CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 0);
+ break;
+ case SCU1_CLK_GATE_UART1CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 1);
+ break;
+ case SCU1_CLK_GATE_UART2CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 2);
+ break;
+ case SCU1_CLK_GATE_UART3CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 3);
+ break;
+ case SCU1_CLK_GATE_UART5CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 5);
+ break;
+ case SCU1_CLK_GATE_UART6CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 6);
+ break;
+ case SCU1_CLK_GATE_UART7CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 7);
+ break;
+ case SCU1_CLK_GATE_UART8CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 8);
+ break;
+ case SCU1_CLK_GATE_UART9CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 9);
+ break;
+ case SCU1_CLK_GATE_UART10CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 10);
+ break;
+ case SCU1_CLK_GATE_UART11CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 11);
+ break;
+ case SCU1_CLK_GATE_UART12CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 12);
+ break;
+ case SCU1_CLK_GATE_SDCLK:
+ rate = ast2700_soc1_get_sdio_clk_rate(scu);
+ break;
+ case SCU1_CLK_UXCLK:
+ rate = ast2700_soc1_get_uart_uxclk_rate(scu);
+ break;
+ case SCU1_CLK_HUXCLK:
+ rate = ast2700_soc1_get_uart_huxclk_rate(scu);
+ break;
+ default:
+ debug("%s: unknown clk %ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static int ast2700_soc1_clk_enable(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+ u32 clkgate_bit;
+
+ if (clk->id >= 32)
+ clkgate_bit = BIT(clk->id - 32);
+ else
+ clkgate_bit = BIT(clk->id);
+
+ writel(clkgate_bit, &scu->clkgate_clr1);
+
+ return 0;
+}
+
+static const struct clk_ops ast2700_soc1_clk_ops = {
+ .get_rate = ast2700_soc1_clk_get_rate,
+ .enable = ast2700_soc1_clk_enable,
+};
+
+#define SCU_HW_REVISION_ID GENMASK(23, 16)
+#define SCU_CPUCLK_MASK GENMASK(4, 2)
+#define SCU_CPUCLK_SHIFT 2
+static u32 ast2700_soc0_get_hpll_rate(struct ast2700_scu0 *scu)
+{
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+ u32 rate;
+
+ pll_reg.w = readl(&scu->hpll);
+
+ if ((chip_id1 & SCU_HW_REVISION_ID) && (hwstrap1 & BIT(3))) {
+ switch ((hwstrap1 & GENMASK(4, 2)) >> 2) {
+ case 2:
+ rate = 1800000000;
+ break;
+ case 3:
+ rate = 1700000000;
+ break;
+ case 6:
+ rate = 1200000000;
+ break;
+ case 7:
+ rate = 800000000;
+ break;
+ default:
+ rate = 1600000000;
+ }
+ } else if (hwstrap1 & GENMASK(3, 2)) {
+ switch ((hwstrap1 & GENMASK(3, 2)) >> 2) {
+ case 1U:
+ rate = 1900000000;
+ break;
+ case 2U:
+ rate = 1800000000;
+ break;
+ case 3U:
+ rate = 1700000000;
+ break;
+ default:
+ rate = 1600000000;
+ break;
+ }
+ } else {
+ if (pll_reg.b.bypass == 0U) {
+ /* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+ div = (pll_reg.b.p + 1);
+ }
+ rate = ((CLKIN_25M * mul) / div);
+ }
+
+ return rate;
+}
+
+static u32 ast2700_soc0_get_pll_rate(struct ast2700_scu0 *scu, int pll_idx)
+{
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+ u32 rate;
+
+ switch (pll_idx) {
+ case SCU0_CLK_DPLL:
+ pll_reg.w = readl(&scu->dpll);
+ break;
+ case SCU0_CLK_MPLL:
+ pll_reg.w = readl(&scu->mpll);
+ break;
+ default:
+ pr_err("%s: invalid PSP clock source (%d)\n", __func__, pll_idx);
+ return 0;
+ }
+
+ if (pll_reg.b.bypass == 0U) {
+ if (pll_idx == SCU0_CLK_MPLL) {
+ /* F = 25Mhz * [M / (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m) / ((pll_reg.b.n + 1));
+ div = (pll_reg.b.p + 1);
+ } else {
+ /* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+ div = (pll_reg.b.p + 1);
+ }
+ }
+
+ rate = ((CLKIN_25M * mul) / div);
+
+ return rate;
+}
+
+/*
+ * AST2700A1
+ * SCU010[4:2]:
+ * 000: CPUCLK=MPLL=1.6GHz (MPLL default setting with SCU310, SCU314)
+ * 001: CPUCLK=HPLL=2.0GHz (HPLL default setting with SCU300, SCU304)
+ * 010: CPUCLK=HPLL=1.8GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 011: CPUCLK=HPLL=1.7GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 100: CPUCLK=MPLL/2=800MHz (MPLL default setting with SCU310, SCU314)
+ * 101: CPUCLK=HPLL/2=1.0GHz (HPLL default setting with SCU300, SCU304)
+ * 110: CPUCLK=HPLL=1.2GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 111: CPUCLK=HPLL=800MHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ */
+
+static u32 ast2700_soc0_get_pspclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ u32 rate;
+ int cpuclk_set;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ cpuclk_set = (hwstrap1 & SCU_CPUCLK_MASK) >> SCU_CPUCLK_SHIFT;
+ switch (cpuclk_set) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 6:
+ case 7:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 4:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 2;
+ break;
+ case 5:
+ rate = ast2700_soc0_get_hpll_rate(scu) / 2;
+ break;
+ default:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ }
+ } else {
+ if (hwstrap1 & BIT(4))
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ else
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ }
+ return rate;
+}
+
+static u32 ast2700_soc0_get_axi0clk_rate(struct ast2700_scu0 *scu)
+{
+ return ast2700_soc0_get_pspclk_rate(scu) / 2;
+}
+
+#define SCU_AHB_DIV_MASK GENMASK(6, 5)
+#define SCU_AHB_DIV_SHIFT 5
+static u32 hclk_ast2700a1_div_table[] = {
+ 6, 5, 4, 7,
+};
+
+static u32 ast2700_soc0_get_hclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 src_clk;
+ int div;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ if (hwstrap1 & BIT(7))
+ src_clk = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ else
+ src_clk = ast2700_soc0_get_hpll_rate(scu);
+
+ div = (hwstrap1 & SCU_AHB_DIV_MASK) >> SCU_AHB_DIV_SHIFT;
+ div = hclk_ast2700a1_div_table[div];
+ } else {
+ if (hwstrap1 & BIT(7))
+ src_clk = ast2700_soc0_get_hpll_rate(scu);
+ else
+ src_clk = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+
+ div = (hwstrap1 & SCU_AHB_DIV_MASK) >> SCU_AHB_DIV_SHIFT;
+
+ if (!div)
+ div = 4;
+ else
+ div = (div + 1) * 2;
+ }
+ return (src_clk / div);
+}
+
+static u32 ast2700_soc0_get_axi1clk_rate(struct ast2700_scu0 *scu)
+{
+ if (readl(&scu->chip_id1) & SCU_HW_REVISION_ID)
+ return ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+ else
+ return ast2700_soc0_get_hclk_rate(scu);
+}
+
+#define SCU0_CLKSEL1_PCLK_DIV_MASK GENMASK(25, 23)
+#define SCU0_CLKSEL1_PCLK_DIV_SHIFT 23
+
+static u32 ast2700_soc0_get_pclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 rate = ast2700_soc0_get_axi0clk_rate(scu);
+ u32 clksel1 = readl(&scu->clk_sel1);
+ int div;
+
+ div = (clksel1 & SCU0_CLKSEL1_PCLK_DIV_MASK) >>
+ SCU0_CLKSEL1_PCLK_DIV_SHIFT;
+
+ return (rate / ((div + 1) * 2));
+}
+
+#define SCU_CLKSEL1_MPHYCLK_SEL_MASK GENMASK(19, 18)
+#define SCU_CLKSEL1_MPHYCLK_SEL_SHIFT 18
+#define SCU_CLKSEL1_MPHYCLK_DIV_MASK GENMASK(7, 0)
+static u32 ast2700_soc0_get_mphyclk_rate(struct ast2700_scu0 *scu)
+{
+ int div = readl(&scu->mphyclk_para) & SCU_CLKSEL1_MPHYCLK_DIV_MASK;
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 clk_sel2;
+ int clk_sel;
+ u32 rate = 0;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ clk_sel2 = readl(&scu->clk_sel2);
+ clk_sel = (clk_sel2 & SCU_CLKSEL1_MPHYCLK_SEL_MASK)
+ >> SCU_CLKSEL1_MPHYCLK_SEL_SHIFT;
+ switch (clk_sel) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 2:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_DPLL);
+ break;
+ case 3:
+ rate = 26000000;
+ break;
+ }
+ } else {
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ }
+
+ return (rate / (div + 1));
+}
+
+static void ast2700_mphy_clk_init(struct ast2700_scu0 *scu)
+{
+ u32 clksrc1, rate = 0;
+ int i;
+
+ /* set mphy clk */
+ if (readl(&scu->chip_id1) & SCU_HW_REVISION_ID) {
+ clksrc1 = (readl(&scu->clk_sel2) & SCU_CLKSEL1_MPHYCLK_SEL_MASK)
+ >> SCU_CLKSEL1_MPHYCLK_SEL_SHIFT;
+ switch (clksrc1) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 2:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_DPLL);
+ break;
+ case 3:
+ rate = 26000000;
+ break;
+ }
+ } else {
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ }
+
+ for (i = 1; i < 256; i++) {
+ if ((rate / i) <= 26000000)
+ break;
+ }
+
+ /* register defined the value plus 1 is divider*/
+ i--;
+ writel(i, &scu->mphyclk_para);
+}
+
+#define SCU_CLKSRC1_EMMC_DIV_MASK GENMASK(14, 12)
+#define SCU_CLKSRC1_EMMC_DIV_SHIFT 12
+#define SCU_CLKSRC1_EMMC_SEL BIT(11)
+static u32 ast2700_soc0_get_emmcclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 clksel1 = readl(&scu->clk_sel1);
+ u32 rate;
+ int div;
+
+ div = (clksel1 & SCU_CLKSRC1_EMMC_DIV_MASK) >> SCU_CLKSRC1_EMMC_DIV_SHIFT;
+
+ if (clksel1 & SCU_CLKSRC1_EMMC_SEL)
+ rate = ast2700_soc0_get_hpll_rate(scu) / 4;
+ else
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+
+ return (rate / ((div + 1) * 2));
+}
+
+static void ast2700_emmc_init(struct ast2700_scu0 *scu)
+{
+ u32 clksrc1, rate, div;
+ int i;
+
+ /* set clk/cmd driving */
+ writel(2, &scu->gpio18d0_ioctrl); /* clk driving */
+ writel(1, &scu->gpio18d1_ioctrl); /* cmd driving */
+ writel(1, &scu->gpio18d2_ioctrl); /* data0 driving */
+ writel(1, &scu->gpio18d3_ioctrl); /* data1 driving */
+ writel(1, &scu->gpio18d4_ioctrl); /* data2 driving */
+ writel(1, &scu->gpio18d5_ioctrl); /* data2 driving */
+
+ /* emmc clk: set clk src mpll/4:400Mhz */
+ clksrc1 = readl(&scu->clk_sel1);
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+ for (i = 0; i < 8; i++) {
+ div = (i + 1) * 2;
+ if ((rate / div) <= 200000000)
+ break;
+ }
+
+ clksrc1 &= ~(SCU_CLKSRC1_EMMC_DIV_MASK | SCU_CLKSRC1_EMMC_SEL);
+ clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT);
+ writel(clksrc1, &scu->clk_sel1);
+}
+
+static void ast2700_vga_clk_init(struct ast2700_scu0 *scu)
+{
+ if ((readl(&scu->chip_id1) & SCU_HW_REVISION_ID) == 0)
+ return;
+
+ // Use d0clk/d1clk which generated from hpll for vga0/1 after A0
+ // Use CRT1clk as soc display source
+ setbits_le32(&scu->clk_sel3, BIT(14) | BIT(13) | BIT(12));
+}
+
+static u32 ast2700_soc0_get_uartclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 clksel2 = readl(&scu->clk_sel2);
+ u32 div = 1;
+ u32 rate;
+
+ if (clksel2 & BIT(15))
+ rate = 192000000;
+ else
+ rate = 24000000;
+
+ if (clksel2 & BIT(30))
+ div = 13;
+ return (rate / div);
+}
+
+static ulong ast2700_soc0_clk_get_rate(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case SCU0_CLK_PSP:
+ rate = ast2700_soc0_get_pspclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_HPLL:
+ rate = ast2700_soc0_get_hpll_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_DPLL:
+ case SCU0_CLK_MPLL:
+ rate = ast2700_soc0_get_pll_rate((struct ast2700_scu0 *)priv->reg, clk->id);
+ break;
+ case SCU0_CLK_AXI0:
+ rate = ast2700_soc0_get_axi0clk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_AXI1:
+ rate = ast2700_soc0_get_axi1clk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_AHB:
+ rate = ast2700_soc0_get_hclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_APB:
+ rate = ast2700_soc0_get_pclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_GATE_EMMCCLK:
+ rate = ast2700_soc0_get_emmcclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_GATE_UART4CLK:
+ rate = ast2700_soc0_get_uartclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_MPHY:
+ rate = ast2700_soc0_get_mphyclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ default:
+ debug("%s: unknown clk %ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static int ast2700_soc0_clk_enable(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu0 *scu = (struct ast2700_scu0 *)priv->reg;
+ u32 clkgate_bit = BIT(clk->id);
+
+ writel(clkgate_bit, &scu->clkgate_clr);
+
+ return 0;
+}
+
+static const struct clk_ops ast2700_soc0_clk_ops = {
+ .get_rate = ast2700_soc0_clk_get_rate,
+ .enable = ast2700_soc0_clk_enable,
+};
+
+static void ast2700_init_mac_clk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ u8 div_idx;
+
+ /* The MAC source clock selects HPLL only, and the default clock
+ * setting is 200 Mhz.
+ * Calculate the corresponding divider:
+ * 1: div 2
+ * 2: div 3
+ * ...
+ * 7: div 8
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++)
+ if (DIV_ROUND_UP(src_clk, div_idx + 1) == 200000000)
+ break;
+
+ if (div_idx == 8) {
+ pr_err("MAC clock cannot divide to 200 MHz\n");
+ return;
+ }
+
+ /* set HPLL clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(31, 29);
+ reg_280 |= div_idx << 29;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static void ast2700_init_rgmii_clk(struct ast2700_scu1 *scu)
+{
+ u32 reg_284 = readl(&scu->clk_sel2);
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, RGMII_DEFAULT_CLK_SRC);
+
+ if (RGMII_DEFAULT_CLK_SRC == SCU1_CLK_HPLL) {
+ u32 reg_280;
+ u8 div_idx;
+
+ /* Calculate the corresponding divider:
+ * 1: div 4
+ * 2: div 6
+ * ...
+ * 7: div 16
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++) {
+ u8 div = 4 + 2 * (div_idx - 1);
+
+ if (DIV_ROUND_UP(src_clk, div) == 125000000)
+ break;
+ }
+ if (div_idx == 8) {
+ pr_err("RGMII using HPLL cannot divide to 125 MHz\n");
+ return;
+ }
+
+ /* set HPLL clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(27, 25);
+ reg_280 |= div_idx << 25;
+ writel(reg_280, &scu->clk_sel1);
+
+ /* select HPLL clock source */
+ reg_284 &= ~BIT(18);
+ } else {
+ /* APLL clock divider is fixed to 8 */
+ if (DIV_ROUND_UP(src_clk, 8) != 125000000) {
+ pr_err("RGMII using APLL cannot divide to 125 MHz\n");
+ return;
+ }
+
+ /* select APLL clock source */
+ reg_284 |= BIT(18);
+ }
+
+ writel(reg_284, &scu->clk_sel2);
+}
+
+static void ast2700_init_rmii_clk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ u8 div_idx;
+
+ /* The RMII source clock selects HPLL only.
+ * Calculate the corresponding divider:
+ * 1: div 8
+ * 2: div 12
+ * ...
+ * 7: div 32
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++) {
+ u8 div = 8 + 4 * (div_idx - 1);
+
+ if (DIV_ROUND_UP(src_clk, div) == 50000000)
+ break;
+ }
+ if (div_idx == 8) {
+ pr_err("RMII using HPLL cannot divide to 50 MHz\n");
+ return;
+ }
+
+ /* set RMII clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(23, 21);
+ reg_280 |= div_idx << 21;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static void ast2700_init_spi(struct ast2700_scu1 *scu)
+{
+ writel(readl(&scu->io_driving8) | 0x0000aaaa, &scu->io_driving8); /* fwspi driving */
+ writel(readl(&scu->io_driving3) | 0x00000aaa, &scu->io_driving3); /* spi0 driving */
+ writel(readl(&scu->io_driving3) | 0x0aaa0000, &scu->io_driving3); /* spi1 driving */
+ writel(readl(&scu->io_driving4) | 0x00002aaa, &scu->io_driving4); /* spi2 driving */
+}
+
+#define SCU1_CLK_I3C_DIV_MASK GENMASK(25, 23)
+#define SCU1_CLK_I3C_DIV(n) ((n) - 1)
+static void ast2700_init_i3c_clk(struct ast2700_scu1 *scu)
+{
+ u32 reg_284;
+
+ /* I3C 250MHz = HPLL/4 */
+ reg_284 = readl(&scu->clk_sel2);
+ reg_284 &= ~SCU1_CLK_I3C_DIV_MASK;
+ reg_284 |= FIELD_PREP(SCU1_CLK_I3C_DIV_MASK, SCU1_CLK_I3C_DIV(4));
+ writel(reg_284, &scu->clk_sel2);
+}
+
+static int ast2700_clk1_init(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+
+ ast2700_init_spi(scu);
+ ast2700_init_mac_clk(scu);
+ ast2700_init_rgmii_clk(scu);
+ ast2700_init_rmii_clk(scu);
+ ast2700_init_sdclk(scu);
+ ast2700_init_i3c_clk(scu);
+
+ return 0;
+}
+
+static int ast2700_clk0_init(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+ struct ast2700_scu0 *scu = (struct ast2700_scu0 *)priv->reg;
+
+ ast2700_emmc_init(scu);
+ ast2700_mphy_clk_init(scu);
+ ast2700_vga_clk_init(scu);
+
+ return 0;
+}
+
+static int ast2700_clk_probe(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+
+ priv->init = (ast2700_clk_init_fn)dev_get_driver_data(dev);
+ priv->reg = (void __iomem *)dev_read_addr_ptr(dev);
+
+ if (priv->init)
+ return priv->init(dev);
+
+ return 0;
+}
+
+static int ast2700_clk_bind(struct udevice *dev)
+{
+ struct udevice *sysreset_dev, *rst_dev;
+ int ret;
+
+ /* The system reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &sysreset_dev);
+ if (ret)
+ debug("Warning: No sysreset driver: ret = %d\n", ret);
+
+ /* Bind the per-SCU reset controller to the same ofnode so that
+ * <&syscon0/1 RESET_X> phandle references resolve to a UCLASS_RESET
+ * device. This pairs with the airoha-style binding pattern.
+ */
+ if (CONFIG_IS_ENABLED(RESET_AST2700)) {
+ ret = device_bind_driver_to_node(dev, "ast2700_reset", "reset",
+ dev_ofnode(dev), &rst_dev);
+ if (ret)
+ debug("Warning: failed to bind reset controller: ret = %d\n", ret);
+ }
+
+ return 0;
+}
+
+static const struct udevice_id ast2700_soc1_clk_ids[] = {
+ { .compatible = "aspeed,ast2700-scu1", .data = (ulong)&ast2700_clk1_init },
+ { },
+};
+
+U_BOOT_DRIVER(aspeed_ast2700_soc1_clk) = {
+ .name = "aspeed_ast2700_scu1",
+ .id = UCLASS_CLK,
+ .of_match = ast2700_soc1_clk_ids,
+ .priv_auto = sizeof(struct ast2700_clk_priv),
+ .ops = &ast2700_soc1_clk_ops,
+ .probe = ast2700_clk_probe,
+ .bind = ast2700_clk_bind,
+};
+
+static const struct udevice_id ast2700_soc0_clk_ids[] = {
+ { .compatible = "aspeed,ast2700-scu0", .data = (ulong)&ast2700_clk0_init },
+ { },
+};
+
+U_BOOT_DRIVER(aspeed_ast2700_soc0_clk) = {
+ .name = "aspeed_ast2700_scu0",
+ .id = UCLASS_CLK,
+ .of_match = ast2700_soc0_clk_ids,
+ .priv_auto = sizeof(struct ast2700_clk_priv),
+ .ops = &ast2700_soc0_clk_ops,
+ .probe = ast2700_clk_probe,
+ .bind = ast2700_clk_bind,
+};
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index 2251e2846fa..0d0e39db57e 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -426,7 +426,7 @@ static const struct pmc_clk_setup sam9x60_clk_setup[] = {
static int sam9x60_clk_probe(struct udevice *dev)
{
- void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[64], *muxallocs[64];
const char *p[10];
unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
diff --git a/drivers/clk/at91/sam9x7.c b/drivers/clk/at91/sam9x7.c
index 9ea253e6ff8..93f899b6617 100644
--- a/drivers/clk/at91/sam9x7.c
+++ b/drivers/clk/at91/sam9x7.c
@@ -817,7 +817,7 @@ static const struct {
static int sam9x7_clk_probe(struct udevice *dev)
{
- void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[64], *muxallocs[64];
const char *p[10];
unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
diff --git a/drivers/clk/at91/sama7d65.c b/drivers/clk/at91/sama7d65.c
index 9f0b394543b..0c17a8cf67b 100644
--- a/drivers/clk/at91/sama7d65.c
+++ b/drivers/clk/at91/sama7d65.c
@@ -1176,7 +1176,7 @@ static const struct pmc_clk_setup sama7d65_clk_setup[] = {
static int sama7d65_clk_probe(struct udevice *dev)
{
- void __iomem *base = (void *)devfdt_get_addr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[SAMA7D65_MAX_MUX_ALLOCS];
unsigned int *muxallocs[SAMA7D65_MAX_MUX_ALLOCS];
const char *p[12];
@@ -1185,8 +1185,8 @@ static int sama7d65_clk_probe(struct udevice *dev)
bool main_osc_bypass;
int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
- if (IS_ERR(base))
- return PTR_ERR(base);
+ if (!base)
+ return -EINVAL;
memset(muxallocs, 0, ARRAY_SIZE(muxallocs));
memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs));
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index f24d251857f..c436038aed2 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -1109,7 +1109,7 @@ static const struct pmc_clk_setup sama7g5_clk_setup[] = {
static int sama7g5_clk_probe(struct udevice *dev)
{
- void __iomem *base = devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
unsigned int *clkmuxallocs[SAMA7G5_MAX_MUX_ALLOCS];
unsigned int *muxallocs[SAMA7G5_MAX_MUX_ALLOCS];
const char *p[10];
@@ -1118,8 +1118,8 @@ static int sama7g5_clk_probe(struct udevice *dev)
bool main_osc_bypass;
int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
- if (IS_ERR(base))
- return PTR_ERR(base);
+ if (!base)
+ return -EINVAL;
memset(muxallocs, 0, sizeof(muxallocs));
memset(clkmuxallocs, 0, sizeof(clkmuxallocs));
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index dcaffd360fd..410bc088248 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -124,12 +124,15 @@ U_BOOT_DRIVER(at91_sam9x60_td_slck) = {
static int at91_sam9x60_sckc_probe(struct udevice *dev)
{
struct sam9x60_sckc *sckc = dev_get_priv(dev);
- void __iomem *base = devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
const char *slow_rc_osc, *slow_osc;
const char *parents[2];
struct clk *clk, c;
int ret;
+ if (!base)
+ return -EINVAL;
+
ret = clk_get_by_index(dev, 0, &c);
if (ret)
return ret;
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index e692b9c2167..d30786a9e6c 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -228,20 +228,30 @@ static struct clk *_register_divider(struct udevice *dev, const char *name,
return clk;
}
-struct clk *clk_register_divider(struct udevice *dev, const char *name,
+struct clk *clk_register_divider_table(struct udevice *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 shift, u8 width,
- u8 clk_divider_flags)
+ u8 clk_divider_flags, const struct clk_div_table *table)
{
struct clk *clk;
clk = _register_divider(dev, name, parent_name, flags, reg, shift,
- width, clk_divider_flags, NULL);
+ width, clk_divider_flags, table);
if (IS_ERR(clk))
return ERR_CAST(clk);
return clk;
}
+struct clk *clk_register_divider(struct udevice *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 shift, u8 width,
+ u8 clk_divider_flags)
+{
+ return clk_register_divider_table(dev, name, parent_name, flags, reg,
+ shift, width, clk_divider_flags,
+ NULL);
+}
+
U_BOOT_DRIVER(ccf_clk_divider) = {
.name = UBOOT_DM_CLK_CCF_DIVIDER,
.id = UCLASS_CLK,
diff --git a/drivers/clk/clk-hsdk-cgu.c b/drivers/clk/clk-hsdk-cgu.c
index 53655059279..dbc926a4391 100644
--- a/drivers/clk/clk-hsdk-cgu.c
+++ b/drivers/clk/clk-hsdk-cgu.c
@@ -753,11 +753,11 @@ static int hsdk_cgu_clk_probe(struct udevice *dev)
else
hsdk_clk->map = hsdk_4xd_clk_map;
- hsdk_clk->cgu_regs = devfdt_get_addr_index_ptr(dev, 0);
+ hsdk_clk->cgu_regs = dev_read_addr_index_ptr(dev, 0);
if (!hsdk_clk->cgu_regs)
return -EINVAL;
- hsdk_clk->creg_regs = devfdt_get_addr_index_ptr(dev, 1);
+ hsdk_clk->creg_regs = dev_read_addr_index_ptr(dev, 1);
if (!hsdk_clk->creg_regs)
return -EINVAL;
diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c
index 117266ac778..4a6c71016da 100644
--- a/drivers/clk/clk-stub.c
+++ b/drivers/clk/clk-stub.c
@@ -49,11 +49,13 @@ static struct clk_ops stub_clk_ops = {
};
static const struct udevice_id stub_clk_ids[] = {
+ { .compatible = "qcom,qcs615-rpmh-clk" },
{ .compatible = "qcom,rpmcc" },
- { .compatible = "qcom,sdm670-rpmh-clk" },
- { .compatible = "qcom,sdm845-rpmh-clk" },
+ { .compatible = "qcom,sa8775p-rpmh-clk" },
{ .compatible = "qcom,sc7180-rpmh-clk" },
{ .compatible = "qcom,sc7280-rpmh-clk" },
+ { .compatible = "qcom,sdm670-rpmh-clk" },
+ { .compatible = "qcom,sdm845-rpmh-clk" },
{ .compatible = "qcom,sm6350-rpmh-clk" },
{ .compatible = "qcom,sm8150-rpmh-clk" },
{ .compatible = "qcom,sm8250-rpmh-clk" },
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index f2fd6ff8ca0..a825ed9988f 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -17,7 +17,7 @@ obj-$(CONFIG_$(PHASE_)CLK_IMX8MN) += clk-imx8mn.o clk-pll14xx.o \
clk-composite-8m.o
obj-$(CONFIG_$(PHASE_)CLK_IMX8MP) += clk-imx8mp.o clk-pll14xx.o \
clk-composite-8m.o
-obj-$(CONFIG_$(PHASE_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
+obj-$(CONFIG_$(PHASE_)CLK_IMX8MQ) += clk-imx8mq.o clk-frac-pll.o \
clk-composite-8m.o
obj-$(CONFIG_$(PHASE_)CLK_IMX93) += clk-imx93.o clk-fracn-gppll.o \
clk-gate-93.o clk-composite-93.o
diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c
new file mode 100644
index 00000000000..057389d3069
--- /dev/null
+++ b/drivers/clk/imx/clk-frac-pll.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2026 NXP
+ *
+ */
+
+#include <asm/io.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <clk.h>
+#include <div64.h>
+#include <linux/printk.h>
+#include <linux/bitfield.h>
+
+#include "clk.h"
+
+#define PLL_CFG0 0x0
+#define PLL_CFG1 0x4
+
+#define PLL_LOCK_STATUS BIT(31)
+#define PLL_PD_MASK BIT(19)
+#define PLL_BYPASS_MASK BIT(14)
+#define PLL_NEWDIV_VAL BIT(12)
+#define PLL_NEWDIV_ACK BIT(11)
+#define PLL_FRAC_DIV_MASK GENMASK(30, 7)
+#define PLL_INT_DIV_MASK GENMASK(6, 0)
+#define PLL_OUTPUT_DIV_MASK GENMASK(4, 0)
+#define PLL_FRAC_DENOM 0x1000000
+
+#define PLL_FRAC_LOCK_TIMEOUT 10000
+#define PLL_FRAC_ACK_TIMEOUT 500000
+
+struct clk_frac_pll {
+ struct clk clk;
+ void __iomem *base;
+};
+
+#define to_clk_frac_pll(_clk) container_of(_clk, struct clk_frac_pll, clk)
+
+static int clk_wait_lock(struct clk_frac_pll *pll)
+{
+ u32 val;
+
+ return readl_poll_timeout(pll->base, val, val & PLL_LOCK_STATUS,
+ PLL_FRAC_LOCK_TIMEOUT);
+}
+
+static int clk_wait_ack(struct clk_frac_pll *pll)
+{
+ u32 val;
+
+ /* return directly if the pll is in powerdown or in bypass */
+ if (readl_relaxed(pll->base) & (PLL_PD_MASK | PLL_BYPASS_MASK))
+ return 0;
+
+ /* Wait for the pll's divfi and divff to be reloaded */
+ return readl_poll_timeout(pll->base, val, val & PLL_NEWDIV_ACK,
+ PLL_FRAC_ACK_TIMEOUT);
+}
+
+static int clk_pll_prepare(struct clk *clk)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val &= ~PLL_PD_MASK;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ return clk_wait_lock(pll);
+}
+
+static int clk_pll_unprepare(struct clk *clk)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+ u32 val;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val |= PLL_PD_MASK;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ return 0;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk *clk)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+ u32 val, divff, divfi, divq;
+ ulong parent_rate = clk_get_parent_rate(clk);
+ u64 temp64 = parent_rate;
+ u64 rate;
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ divq = (FIELD_GET(PLL_OUTPUT_DIV_MASK, val) + 1) * 2;
+ val = readl_relaxed(pll->base + PLL_CFG1);
+ divff = FIELD_GET(PLL_FRAC_DIV_MASK, val);
+ divfi = FIELD_GET(PLL_INT_DIV_MASK, val);
+
+ temp64 *= 8;
+ temp64 *= divff;
+ do_div(temp64, PLL_FRAC_DENOM);
+ do_div(temp64, divq);
+
+ rate = parent_rate * 8 * (divfi + 1);
+ do_div(rate, divq);
+ rate += temp64;
+
+ return rate;
+}
+
+static ulong clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk_frac_pll *pll = to_clk_frac_pll(clk);
+ ulong parent_rate = clk_get_parent_rate(clk);
+ u32 val, divfi, divff;
+ u64 temp64;
+ int ret;
+
+ parent_rate *= 8;
+ rate *= 2;
+ divfi = rate / parent_rate;
+ temp64 = parent_rate * divfi;
+ temp64 = rate - temp64;
+ temp64 *= PLL_FRAC_DENOM;
+ do_div(temp64, parent_rate);
+ divff = temp64;
+
+ val = readl_relaxed(pll->base + PLL_CFG1);
+ val &= ~(PLL_FRAC_DIV_MASK | PLL_INT_DIV_MASK);
+ val |= (divff << 7) | (divfi - 1);
+ writel_relaxed(val, pll->base + PLL_CFG1);
+
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val &= ~0x1f;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ /* Set the NEV_DIV_VAL to reload the DIVFI and DIVFF */
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val |= PLL_NEWDIV_VAL;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ ret = clk_wait_ack(pll);
+
+ /* clear the NEV_DIV_VAL */
+ val = readl_relaxed(pll->base + PLL_CFG0);
+ val &= ~PLL_NEWDIV_VAL;
+ writel_relaxed(val, pll->base + PLL_CFG0);
+
+ if (ret)
+ return ret;
+
+ return clk_pll_recalc_rate(clk);
+}
+
+static const struct clk_ops clk_frac_pll_ops = {
+ .enable = clk_pll_prepare,
+ .disable = clk_pll_unprepare,
+ .set_rate = clk_pll_set_rate,
+ .get_rate = clk_pll_recalc_rate,
+};
+
+struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
+ void __iomem *base)
+{
+ struct clk_frac_pll *pll;
+ struct clk *clk;
+ int ret;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+ clk = &pll->clk;
+
+ ret = clk_register(clk, "imx_clk_frac_pll", name, parent_name);
+ if (ret) {
+ pr_err("%s: failed to register pll %s %d\n",
+ __func__, name, ret);
+ kfree(pll);
+ return ERR_PTR(ret);
+ }
+
+ return clk;
+}
+
+U_BOOT_DRIVER(clk_frac_pll) = {
+ .name = "imx_clk_frac_pll",
+ .id = UCLASS_CLK,
+ .ops = &clk_frac_pll_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index f57ac79f8ca..846b8011f5c 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -9,6 +9,7 @@
#include <log.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
+#include <dm/of_access.h>
#include <dt-bindings/clock/imx6qdl-clock.h>
#include "clk.h"
@@ -46,6 +47,33 @@ static struct clk_ops imx6q_clk_ops = {
.disable = ccf_clk_disable,
};
+static const char *const pll_bypass_src_sels[] = {
+ "osc",
+ "lvds1_in",
+ "lvds2_in",
+ "dummy",
+};
+
+static const char *const pll2_bypass_sels[] = {
+ "pll2",
+ "pll2_bypass_src",
+};
+
+static const char *const pll3_bypass_sels[] = {
+ "pll3",
+ "pll3_bypass_src",
+};
+
+static const char *const pll5_bypass_sels[] = {
+ "pll5",
+ "pll5_bypass_src",
+};
+
+static const char *const pll6_bypass_sels[] = {
+ "pll6",
+ "pll6_bypass_src",
+};
+
static const char *const usdhc_sels[] = {
"pll2_pfd2_396m",
"pll2_pfd0_352m",
@@ -72,6 +100,23 @@ static const char *const ecspi_sels[] = {
"pll3_60m",
"osc",
};
+
+static const struct clk_div_table post_div_table[] = {
+ { .val = 2, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 0, .div = 4, },
+ { /* sentinel */ }
+};
+
+static const struct clk_div_table video_div_table[] = {
+ { .val = 0, .div = 1, },
+ { .val = 1, .div = 2, },
+ { .val = 2, .div = 1, },
+ { .val = 3, .div = 4, },
+ { /* sentinel */ }
+};
+
+#if CONFIG_IS_ENABLED(VIDEO)
static const char *const ipu_sels[] = {
"mmdc_ch0_axi",
"pll2_pfd2_396m",
@@ -113,6 +158,122 @@ static const char *ipu2_di1_sels_2[] = {
static unsigned int share_count_mipi_core_cfg;
+static void of_assigned_ldb_sels(struct udevice *dev, int *ldb_di0_sel,
+ int *ldb_di1_sel)
+{
+ struct ofnode_phandle_args clk_args, parent_args;
+ ofnode node = dev_ofnode(dev);
+ int count, err;
+
+ count = dev_count_phandle_with_args(dev, "assigned-clocks",
+ "#clock-cells", 0);
+ if (count <= 0) {
+ if (count == 0)
+ debug("%s: no assigned_clocks found\n", dev->name);
+ else
+ pr_err("%s: failed to get phandle count (%d)\n",
+ dev->name, count);
+ return;
+ }
+
+ for (int i = 0; i < count; i++) {
+ err = dev_read_phandle_with_args(dev, "assigned-clocks",
+ "#clock-cells", 0, i,
+ &clk_args);
+ if (err == -ENOENT)
+ /* Skip empty handles */
+ continue;
+ else if (err < 0)
+ return;
+
+ if (!ofnode_equal(clk_args.node, node) ||
+ clk_args.args[0] >= IMX6QDL_CLK_END) {
+ pr_err("%s: clock %d not in ccm\n", dev->name, i);
+ return;
+ }
+
+ err = dev_read_phandle_with_args(dev, "assigned-clock-parents",
+ "#clock-cells", 0, i,
+ &parent_args);
+ if (err < 0)
+ return;
+
+ if (!ofnode_equal(parent_args.node, node) ||
+ parent_args.args[0] >= IMX6QDL_CLK_END) {
+ pr_err("%s: parent clock %d not in ccm\n", dev->name,
+ i);
+ return;
+ }
+
+ if (clk_args.args[0] == IMX6QDL_CLK_LDB_DI0_SEL)
+ *ldb_di0_sel = parent_args.args[0];
+ else if (clk_args.args[0] == IMX6QDL_CLK_LDB_DI1_SEL)
+ *ldb_di1_sel = parent_args.args[0];
+ }
+}
+
+static void imx6q_init_ldb_clks(struct udevice *dev)
+{
+ int ldb_di_sel[] = { IMX6QDL_CLK_END, IMX6QDL_CLK_END };
+ enum ldb_di_clock ldb_di_clk[] = { MXC_MMDC_CH1_CLK, MXC_MMDC_CH1_CLK };
+
+ of_assigned_ldb_sels(dev, &ldb_di_sel[0], &ldb_di_sel[1]);
+ for (int i = 0; i < 2; i++) {
+ switch (ldb_di_sel[i]) {
+ case IMX6QDL_CLK_PLL5_VIDEO_DIV:
+ ldb_di_clk[i] = MXC_PLL5_CLK;
+ break;
+ case IMX6QDL_CLK_PLL2_PFD0_352M:
+ ldb_di_clk[i] = MXC_PLL2_PFD0_CLK;
+ break;
+ case IMX6QDL_CLK_PLL2_PFD2_396M: {
+ struct clk *clk, *parent;
+
+ int err = clk_get_by_id(IMX6QDL_CLK_PERIPH_PRE, &clk);
+
+ if (err) {
+ pr_err("%s: failed to get periph_pre clock "
+ "(%d)\n",
+ dev->name, err);
+ return;
+ }
+
+ err = clk_get_by_id(IMX6QDL_CLK_PLL2_PFD2_396M,
+ &parent);
+ if (err) {
+ pr_err("%s: failed to get pll2_pfd2_396m clock"
+ " (%d)\n",
+ dev->name, err);
+ return;
+ }
+
+ if (parent == clk) {
+ pr_err("%s: ldb_di%d_sel: couldn't disable "
+ "pll2_pfd2_396m clock\n",
+ dev->name, i);
+ return;
+ }
+
+ ldb_di_clk[i] = MXC_PLL2_PFD2_CLK;
+ break;
+ }
+ case IMX6QDL_CLK_MMDC_CH1_AXI:
+ case IMX6QDL_CLK_END:
+ /* use the default clock */
+ break;
+ case IMX6QDL_CLK_PLL3_USB_OTG:
+ ldb_di_clk[i] = MXC_PLL3_SW_CLK;
+ break;
+ default:
+ pr_err("%s: invalid LDB clock parent\n", dev->name);
+ return;
+ }
+ }
+
+ select_ldb_di_clock_source(ldb_di_clk[0], ldb_di_clk[1]);
+}
+#endif /* CONFIG_IS_ENABLED(VIDEO) */
+
static int imx6q_clk_probe(struct udevice *dev)
{
void *base;
@@ -120,26 +281,70 @@ static int imx6q_clk_probe(struct udevice *dev)
/* Anatop clocks */
base = (void *)ANATOP_BASE_ADDR;
- clk_dm(IMX6QDL_CLK_PLL2,
- imx_clk_pllv3(dev, IMX_PLLV3_GENERIC, "pll2_bus", "osc",
- base + 0x30, 0x1));
+ clk_dm(IMX6QDL_PLL2_BYPASS_SRC,
+ imx_clk_mux(dev, "pll2_bypass_src", base + 0x30, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+ clk_dm(IMX6QDL_PLL3_BYPASS_SRC,
+ imx_clk_mux(dev, "pll3_bypass_src", base + 0x10, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+ clk_dm(IMX6QDL_PLL5_BYPASS_SRC,
+ imx_clk_mux(dev, "pll5_bypass_src", base + 0xa0, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+ clk_dm(IMX6QDL_PLL6_BYPASS_SRC,
+ imx_clk_mux(dev, "pll6_bypass_src", base + 0xe0, 14, 2,
+ pll_bypass_src_sels,
+ ARRAY_SIZE(pll_bypass_src_sels)));
+
+ clk_dm(IMX6QDL_CLK_PLL2, imx_clk_pllv3(dev, IMX_PLLV3_GENERIC, "pll2",
+ "osc", base + 0x30, 0x1));
+ clk_dm(IMX6QDL_CLK_PLL3, imx_clk_pllv3(dev, IMX_PLLV3_USB, "pll3",
+ "osc", base + 0x10, 0x3));
+ clk_dm(IMX6QDL_CLK_PLL5, imx_clk_pllv3(dev, IMX_PLLV3_AV, "pll5", "osc",
+ base + 0xa0, 0x7f));
+ clk_dm(IMX6QDL_CLK_PLL6, imx_clk_pllv3(dev, IMX_PLLV3_ENET, "pll6",
+ "osc", base + 0xe0, 0x3));
+
+ clk_dm(IMX6QDL_PLL2_BYPASS,
+ imx_clk_mux_flags(dev, "pll2_bypass", base + 0x30, 16, 1,
+ pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_PLL3_BYPASS,
+ imx_clk_mux_flags(dev, "pll3_bypass", base + 0x10, 16, 1,
+ pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_PLL5_BYPASS,
+ imx_clk_mux_flags(dev, "pll5_bypass", base + 0xa0, 16, 1,
+ pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels),
+ CLK_SET_RATE_PARENT));
+ clk_dm(IMX6QDL_PLL6_BYPASS,
+ imx_clk_mux_flags(dev, "pll6_bypass", base + 0xe0, 16, 1,
+ pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels),
+ CLK_SET_RATE_PARENT));
+
+ SET_CLK_PARENT(IMX6QDL_PLL2_BYPASS, IMX6QDL_CLK_PLL2);
+ SET_CLK_PARENT(IMX6QDL_PLL3_BYPASS, IMX6QDL_CLK_PLL3);
+ SET_CLK_PARENT(IMX6QDL_PLL5_BYPASS, IMX6QDL_CLK_PLL5);
+ SET_CLK_PARENT(IMX6QDL_PLL6_BYPASS, IMX6QDL_CLK_PLL6);
+
+ clk_dm(IMX6QDL_CLK_PLL2_BUS,
+ imx_clk_gate(dev, "pll2_bus", "pll2_bypass", base + 0x30, 13));
clk_dm(IMX6QDL_CLK_PLL3_USB_OTG,
- imx_clk_pllv3(dev, IMX_PLLV3_USB, "pll3_usb_otg", "osc",
- base + 0x10, 0x3));
+ imx_clk_gate(dev, "pll3_usb_otg", "pll3_bypass", base + 0x10,
+ 13));
+ clk_dm(IMX6QDL_CLK_PLL5_VIDEO,
+ imx_clk_gate(dev, "pll5_video", "pll5_bypass", base + 0xa0, 13));
+ clk_dm(IMX6QDL_CLK_PLL6_ENET,
+ imx_clk_gate(dev, "pll6_enet", "pll6_bypass", base + 0xe0, 13));
+
clk_dm(IMX6QDL_CLK_PLL3_60M,
imx_clk_fixed_factor(dev, "pll3_60m", "pll3_usb_otg", 1, 8));
clk_dm(IMX6QDL_CLK_PLL3_80M,
imx_clk_fixed_factor(dev, "pll3_80m", "pll3_usb_otg", 1, 6));
clk_dm(IMX6QDL_CLK_PLL3_120M,
imx_clk_fixed_factor(dev, "pll3_120m", "pll3_usb_otg", 1, 4));
- clk_dm(IMX6QDL_CLK_PLL5, imx_clk_pllv3(dev, IMX_PLLV3_AV, "pll5", "osc",
- base + 0xa0, 0x7f));
- clk_dm(IMX6QDL_CLK_PLL5_VIDEO,
- imx_clk_gate(dev, "pll5_video", "pll5", base + 0xa0, 13));
- clk_dm(IMX6QDL_CLK_PLL6, imx_clk_pllv3(dev, IMX_PLLV3_ENET, "pll6",
- "osc", base + 0xe0, 0x3));
- clk_dm(IMX6QDL_CLK_PLL6_ENET,
- imx_clk_gate(dev, "pll6_enet", "pll6", base + 0xe0, 13));
clk_dm(IMX6QDL_CLK_PLL2_PFD0_352M,
imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0));
@@ -151,10 +356,14 @@ static int imx6q_clk_probe(struct udevice *dev)
clk_dm(IMX6QDL_CLK_PLL2_198M,
imx_clk_fixed_factor(dev, "pll2_198m", "pll2_pfd2_396m", 1, 2));
clk_dm(IMX6QDL_CLK_PLL5_POST_DIV,
- imx_clk_fixed_factor(dev, "pll5_post_div", "pll5_video", 1, 1));
+ clk_register_divider_table(dev, "pll5_post_div", "pll5_video",
+ CLK_SET_RATE_PARENT, base + 0xa0, 19,
+ 2, 0, post_div_table));
clk_dm(IMX6QDL_CLK_PLL5_VIDEO_DIV,
- imx_clk_fixed_factor(dev, "pll5_video_div", "pll5_post_div", 1,
- 1));
+ clk_register_divider_table(dev, "pll5_video_div",
+ "pll5_post_div", CLK_SET_RATE_PARENT,
+ base + 0x170, 30, 2, 0,
+ video_div_table));
clk_dm(IMX6QDL_CLK_VIDEO_27M,
imx_clk_fixed_factor(dev, "video_27m", "pll3_pfd1_540m", 1,
20));
@@ -263,6 +472,7 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_gate2(dev, "mmdc_ch1_axi", "mmdc_ch1_axi_podf",
base + 0x74, 22));
+#if CONFIG_IS_ENABLED(VIDEO)
clk_dm(IMX6QDL_CLK_IPU1_SEL,
imx_clk_mux(dev, "ipu1_sel", base + 0x3c, 9, 2, ipu_sels,
ARRAY_SIZE(ipu_sels)));
@@ -279,9 +489,12 @@ static int imx6q_clk_probe(struct udevice *dev)
ldb_di_sels, ARRAY_SIZE(ldb_di_sels)));
} else {
/*
- * Need to set these as read-only due to a hardware bug.
- * Keeping default mux values. Fixed on the i.MX6 QuadPlus
- */
+ * Need to set these as read-only due to a hardware bug.
+ * Keeping default mux values. Fixed on the i.MX6 QuadPlus
+ * Need to set the clocks now and make them read-only due to a
+ * hardware bug. Fixed on the i.MX6 QuadPlus
+ */
+ imx6q_init_ldb_clks(dev);
clk_dm(IMX6QDL_CLK_LDB_DI0_SEL,
imx_clk_mux_flags(dev, "ldb_di0_sel", base + 0x2c, 9, 3,
ldb_di_sels, ARRAY_SIZE(ldb_di_sels),
@@ -413,6 +626,7 @@ static int imx6q_clk_probe(struct udevice *dev)
ARRAY_SIZE(ipu2_di1_sels),
CLK_SET_RATE_PARENT));
}
+#endif /* CONFIG_IS_ENABLED(VIDEO) */
clk_dm(IMX6QDL_CLK_ECSPI1,
imx_clk_gate2(dev, "ecspi1", "ecspi_root", base + 0x6c, 0));
@@ -453,6 +667,8 @@ static int imx6q_clk_probe(struct udevice *dev)
imx_clk_gate2(dev, "enet", "ipg", base + 0x6c, 10));
clk_dm(IMX6QDL_CLK_ENET_REF,
imx_clk_fixed_factor(dev, "enet_ref", "pll6_enet", 1, 1));
+
+#if CONFIG_IS_ENABLED(VIDEO)
clk_dm(IMX6QDL_CLK_MIPI_CORE_CFG,
imx_clk_gate2_shared(dev, "mipi_core_cfg", "video_27m",
base + 0x74, 16,
@@ -480,6 +696,7 @@ static int imx6q_clk_probe(struct udevice *dev)
SET_CLK_PARENT(IMX6QDL_CLK_IPU1_SEL,
IMX6QDL_CLK_PLL3_PFD1_540M);
}
+#endif /* CONFIG_IS_ENABLED(VIDEO) */
return 0;
}
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index fe6cba19758..78156003ad9 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright 2019 NXP
+ * Copyright 2019, 2026 NXP
* Copyright 2022 Purism
* Peng Fan <[email protected]>
*/
@@ -155,39 +155,52 @@ static int imx8mq_clk_probe(struct udevice *dev)
imx_clk_mux(dev, "dram_pll_ref_sel", base + 0x60, 0, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_ARM_PLL_REF_SEL,
- imx_clk_mux(dev, "arm_pll_ref_sel", base + 0x28, 0, 2,
+ imx_clk_mux(dev, "arm_pll_ref_sel", base + 0x28, 16, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_GPU_PLL_REF_SEL,
- imx_clk_mux(dev, "gpu_pll_ref_sel", base + 0x18, 0, 2,
+ imx_clk_mux(dev, "gpu_pll_ref_sel", base + 0x18, 16, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_VPU_PLL_REF_SEL,
- imx_clk_mux(dev, "vpu_pll_ref_sel", base + 0x20, 0, 2,
+ imx_clk_mux(dev, "vpu_pll_ref_sel", base + 0x20, 16, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_SYS3_PLL1_REF_SEL,
imx_clk_mux(dev, "sys3_pll_ref_sel", base + 0x48, 0, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_AUDIO_PLL1_REF_SEL,
- imx_clk_mux(dev, "audio_pll1_ref_sel", base + 0x0, 0, 2,
+ imx_clk_mux(dev, "audio_pll1_ref_sel", base + 0x0, 16, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_AUDIO_PLL2_REF_SEL,
- imx_clk_mux(dev, "audio_pll2_ref_sel", base + 0x8, 0, 2,
+ imx_clk_mux(dev, "audio_pll2_ref_sel", base + 0x8, 16, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_VIDEO_PLL1_REF_SEL,
- imx_clk_mux(dev, "video_pll1_ref_sel", base + 0x10, 0, 2,
+ imx_clk_mux(dev, "video_pll1_ref_sel", base + 0x10, 16, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
clk_dm(IMX8MQ_VIDEO2_PLL1_REF_SEL,
imx_clk_mux(dev, "video_pll2_ref_sel", base + 0x54, 0, 2,
pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+ clk_dm(IMX8MQ_ARM_PLL_REF_DIV,
+ imx_clk_divider(dev, "arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6));
+ clk_dm(IMX8MQ_GPU_PLL_REF_DIV,
+ imx_clk_divider(dev, "gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6));
+ clk_dm(IMX8MQ_VPU_PLL_REF_DIV,
+ imx_clk_divider(dev, "vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6));
+ clk_dm(IMX8MQ_AUDIO_PLL1_REF_DIV,
+ imx_clk_divider(dev, "audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6));
+ clk_dm(IMX8MQ_AUDIO_PLL2_REF_DIV,
+ imx_clk_divider(dev, "audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6));
+ clk_dm(IMX8MQ_VIDEO_PLL1_REF_DIV,
+ imx_clk_divider(dev, "video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6));
+
clk_dm(IMX8MQ_ARM_PLL,
- imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel",
- base + 0x28, &imx_1416x_pll));
+ imx_clk_frac_pll("arm_pll", "arm_pll_ref_div",
+ base + 0x28));
clk_dm(IMX8MQ_GPU_PLL,
- imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel",
- base + 0x18, &imx_1416x_pll));
+ imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div",
+ base + 0x18));
clk_dm(IMX8MQ_VPU_PLL,
- imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel",
- base + 0x20, &imx_1416x_pll));
+ imx_clk_frac_pll("vpu_pll", "vpu_pll_ref_div",
+ base + 0x20));
clk_dm(IMX8MQ_SYS1_PLL1,
clk_register_fixed_rate(NULL, "sys1_pll", 800000000));
@@ -196,14 +209,14 @@ static int imx8mq_clk_probe(struct udevice *dev)
clk_dm(IMX8MQ_SYS2_PLL1,
clk_register_fixed_rate(NULL, "sys3_pll", 1000000000));
clk_dm(IMX8MQ_AUDIO_PLL1,
- imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel",
- base + 0x0, &imx_1443x_pll));
+ imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div",
+ base + 0x0));
clk_dm(IMX8MQ_AUDIO_PLL2,
- imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel",
- base + 0x8, &imx_1443x_pll));
+ imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div",
+ base + 0x8));
clk_dm(IMX8MQ_VIDEO_PLL1,
- imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel",
- base + 0x10, &imx_1443x_pll));
+ imx_clk_frac_pll("video_pll1", "video_pll1_ref_div",
+ base + 0x10));
/* PLL bypass out */
clk_dm(IMX8MQ_ARM_PLL_BYPASS,
@@ -356,8 +369,8 @@ static int imx8mq_clk_probe(struct udevice *dev)
clk_dm(IMX8MQ_CLK_A53_DIV,
imx_clk_divider2(dev, "arm_a53_div", "arm_a53_cg",
base + 0x8000, 0, 3));
- clk_dm(IMX8MQ_CLK_A53_CORE,
- imx_clk_mux2(dev, "arm_a53_src", base + 0x9880, 24, 1,
+ clk_dm(IMX8MQ_CLK_ARM,
+ imx_clk_mux2(dev, "arm_a53_core", base + 0x9880, 24, 1,
imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)));
clk_dm(IMX8MQ_CLK_AHB,
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index b53f35df84f..6aef72c0212 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -78,6 +78,9 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
void __iomem *base,
const struct imx_pll14xx_clk *pll_clk);
+struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
+ void __iomem *base);
+
struct clk *clk_register_gate2(struct udevice *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx, u8 cgr_val,
diff --git a/drivers/clk/owl/Kconfig b/drivers/clk/owl/Kconfig
index c6afef90034..5f3b8fe8ab4 100644
--- a/drivers/clk/owl/Kconfig
+++ b/drivers/clk/owl/Kconfig
@@ -1,8 +1,8 @@
config CLK_OWL
- bool "Actions Semi OWL clock drivers"
- depends on CLK && ARCH_OWL
- help
- Enable support for clock managemet unit present in Actions Semi
+ bool "Actions Semi OWL clock drivers"
+ depends on CLK && ARCH_OWL
+ help
+ Enable support for clock managemet unit present in Actions Semi
Owl series S900/S700 SoCs.
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 0a2ce55aaa2..9ad233c83ac 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -111,6 +111,14 @@ config CLK_QCOM_SM6115
on the Snapdragon SM6115 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
+config CLK_QCOM_SM6125
+ bool "Qualcomm SM6125 GCC"
+ select CLK_QCOM
+ help
+ Say Y here to enable support for the Global Clock Controller
+ on the Snapdragon SM6125 SoC. This driver supports the clocks
+ and resets exposed by the GCC hardware block.
+
config CLK_QCOM_SM6350
bool "Qualcomm SM6350 GCC"
select CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index b96d61b603e..c0d95a6300e 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_CLK_QCOM_QCS615) += clock-qcs615.o
obj-$(CONFIG_CLK_QCOM_SA8775P) += clock-sa8775p.o
obj-$(CONFIG_CLK_QCOM_SC7280) += clock-sc7280.o
obj-$(CONFIG_CLK_QCOM_SM6115) += clock-sm6115.o
+obj-$(CONFIG_CLK_QCOM_SM6125) += clock-sm6125.o
obj-$(CONFIG_CLK_QCOM_SM6350) += clock-sm6350.o
obj-$(CONFIG_CLK_QCOM_SM7150) += clock-sm7150.o
obj-$(CONFIG_CLK_QCOM_SM8150) += clock-sm8150.o
diff --git a/drivers/clk/qcom/clock-milos.c b/drivers/clk/qcom/clock-milos.c
index afe59108559..54103adc114 100644
--- a/drivers/clk/qcom/clock-milos.c
+++ b/drivers/clk/qcom/clock-milos.c
@@ -15,6 +15,7 @@
#include <linux/bitops.h>
#include <dt-bindings/clock/qcom,milos-gcc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/clock/qcom,sm8650-tcsr.h>
#include "clock-qcom.h"
@@ -98,6 +99,13 @@ static const struct gate_clk milos_clks[] = {
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x39028, BIT(0)),
GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x39024, BIT(0)),
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x3908c, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77018, BIT(0)),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770e4, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77024, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77068, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77028, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7702c, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770cc, BIT(0)),
};
static int milos_enable(struct clk *clk)
@@ -194,3 +202,68 @@ U_BOOT_DRIVER(milos_rpmh_clk) = {
.ops = &milos_rpmh_clk_ops,
.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
};
+
+/* TCSRCC */
+
+static const struct gate_clk milos_tcsr_clks[] = {
+ GATE_CLK(TCSR_PCIE_0_CLKREF_EN, 0x31100, BIT(0)),
+ GATE_CLK(TCSR_PCIE_1_CLKREF_EN, 0x31114, BIT(0)),
+ GATE_CLK(TCSR_UFS_CLKREF_EN, 0x31118, BIT(0)),
+ GATE_CLK(TCSR_UFS_PAD_CLKREF_EN, 0x31104, BIT(0)),
+};
+
+static struct msm_clk_data milos_tcsrcc_data = {
+ .clks = milos_tcsr_clks,
+ .num_clks = ARRAY_SIZE(milos_tcsr_clks),
+};
+
+static int tcsrcc_milos_clk_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ qcom_gate_clk_en(priv, clk->id);
+
+ return 0;
+}
+
+static ulong tcsrcc_milos_clk_get_rate(struct clk *clk)
+{
+ return TCXO_RATE;
+}
+
+static int tcsrcc_milos_clk_probe(struct udevice *dev)
+{
+ struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev);
+ struct msm_clk_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr(dev);
+ if (priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->data = data;
+
+ return 0;
+}
+
+static struct clk_ops tcsrcc_milos_clk_ops = {
+ .enable = tcsrcc_milos_clk_enable,
+ .get_rate = tcsrcc_milos_clk_get_rate,
+};
+
+static const struct udevice_id tcsrcc_milos_of_match[] = {
+ {
+ .compatible = "qcom,milos-tcsr",
+ .data = (ulong)&milos_tcsrcc_data,
+ },
+ { }
+};
+
+U_BOOT_DRIVER(tcsrcc_milos) = {
+ .name = "tcsrcc_milos",
+ .id = UCLASS_CLK,
+ .of_match = tcsrcc_milos_of_match,
+ .ops = &tcsrcc_milos_clk_ops,
+ .priv_auto = sizeof(struct msm_clk_priv),
+ .probe = tcsrcc_milos_clk_probe,
+ .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
+};
diff --git a/drivers/clk/qcom/clock-qcm2290.c b/drivers/clk/qcom/clock-qcm2290.c
index 5a599085b50..c38ff1a1e4a 100644
--- a/drivers/clk/qcom/clock-qcm2290.c
+++ b/drivers/clk/qcom/clock-qcm2290.c
@@ -73,7 +73,7 @@ static const struct pll_vote_clk gpll6_clk = {
.status = 0x6000,
.status_bit = BIT(31),
.ena_vote = 0x79000,
- .vote_bit = BIT(7),
+ .vote_bit = BIT(6),
};
static const struct gate_clk qcm2290_clks[] = {
diff --git a/drivers/clk/qcom/clock-qcs615.c b/drivers/clk/qcom/clock-qcs615.c
index 2087fc38f63..7b3fe49de9c 100644
--- a/drivers/clk/qcom/clock-qcs615.c
+++ b/drivers/clk/qcom/clock-qcs615.c
@@ -19,6 +19,11 @@
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf01c
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf060
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77020
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x77048
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77060
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x7707c
+
#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
@@ -33,9 +38,37 @@
#define GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT BIT(26)
#define GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT BIT(27)
+/* UFS PHY AXI clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
+ F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
+ F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
+ F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
+ { }
+};
+
+/* UFS PHY ICE CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS PHY UNIPRO CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0, 8, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ { }
+};
+
static ulong qcs615_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__,
@@ -52,6 +85,24 @@ static ulong qcs615_set_rate(struct clk *clk, ulong rate)
5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
return rate;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return 19200000;
default:
return 0;
}
@@ -81,7 +132,17 @@ static const struct gate_clk qcs615_clks[] = {
GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT),
GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT),
GATE_CLK(GCC_DISP_HF_AXI_CLK, 0xb038, BIT(0)),
- GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0))
+ GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0)),
+ /* UFS clocks */
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770c0, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77014, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77040, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77044, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x77078, BIT(0)),
+ GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, BIT(0)),
};
static int qcs615_enable(struct clk *clk)
diff --git a/drivers/clk/qcom/clock-sa8775p.c b/drivers/clk/qcom/clock-sa8775p.c
index 4957abf6f58..7eec4aeae48 100644
--- a/drivers/clk/qcom/clock-sa8775p.c
+++ b/drivers/clk/qcom/clock-sa8775p.c
@@ -19,6 +19,11 @@
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0x1b028
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0x1b06c
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x8302c
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x83074
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x830a8
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x8308c
+
#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
@@ -44,9 +49,35 @@
#define GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT BIT(25)
+/* UFS AXI clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS ICE CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS UNIPRO CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__,
@@ -63,6 +94,24 @@ static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
return rate;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return 19200000;
default:
return 0;
}
@@ -106,6 +155,20 @@ static const struct gate_clk sa8775p_clks[] = {
/* QUP Wrapper 3 clocks */
GATE_CLK(GCC_QUPV3_WRAP3_S0_CLK, 0x4b000, GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT),
+
+ /* UFS PHY clocks */
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x83018, 1),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x830d4, 1),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x83020, 1),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x83064, 1),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x83024, 1),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x83028, 1),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x830c0, 1),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x830a4, 1),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x8306c, 1),
+
+ /* EDP reference clock (used by UFS PHY) */
+ GATE_CLK(GCC_EDP_REF_CLKREF_EN, 0x97448, 1),
};
static int sa8775p_enable(struct clk *clk)
diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c
index 01c8587ac39..91e3fcc27cb 100644
--- a/drivers/clk/qcom/clock-sc7280.c
+++ b/drivers/clk/qcom/clock-sc7280.c
@@ -23,6 +23,10 @@
#define PCIE_1_AUX_CLK_CMD_RCGR 0x8d058
#define PCIE1_PHY_RCHNG_CMD_RCGR 0x8d03c
#define PCIE_1_PIPE_CLK_PHY_MUX 0x8d054
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77024
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x7706c
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x770a0
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77084
static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
@@ -54,6 +58,33 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = {
{ }
};
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
static ulong sc7280_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
@@ -103,6 +134,26 @@ static ulong sc7280_set_rate(struct clk *clk, ulong rate)
case GCC_PCIE1_PHY_RCHNG_CLK:
clk_rcg_set_rate(priv->base, PCIE1_PHY_RCHNG_CMD_RCGR, 5, CFG_CLK_SRC_GPLL0_EVEN);
return 100000000;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_phy_aux_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
default:
return rate;
}
@@ -148,6 +199,7 @@ static const struct gate_clk sc7280_clks[] = {
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77064, BIT(0)),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
diff --git a/drivers/clk/qcom/clock-sm6125.c b/drivers/clk/qcom/clock-sm6125.c
new file mode 100644
index 00000000000..1fd72d55e88
--- /dev/null
+++ b/drivers/clk/qcom/clock-sm6125.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm sm6125
+ *
+ * (C) Copyright 2026 Biswapriyo Nath <[email protected]>
+ *
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/bug.h>
+#include <dt-bindings/clock/qcom,gcc-sm6125.h>
+
+#include "clock-qcom.h"
+
+#define GCC_BASE 0x01400000
+
+#define QUPV3_WRAP0_S4_CMD_RCGR 0x1f608
+#define SDCC1_APPS_CLK_CMD_RCGR 0x38028
+#define SDCC2_APPS_CLK_CMD_RCGR 0x1e00c
+
+#define GCC_GPLL0_MODE 0x0
+#define GCC_GPLL3_MODE 0x3000
+#define GCC_GPLL4_MODE 0x4000
+#define GCC_GPLL5_MODE 0x5000
+#define GCC_GPLL6_MODE 0x6000
+#define GCC_GPLL7_MODE 0x7000
+#define GCC_GPLL8_MODE 0x8000
+#define GCC_GPLL9_MODE 0x9000
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+ F(7372800, CFG_CLK_SRC_GPLL0_AUX2, 1, 384, 15625),
+ F(14745600, CFG_CLK_SRC_GPLL0_AUX2, 1, 768, 15625),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(29491200, CFG_CLK_SRC_GPLL0_AUX2, 1, 1536, 15625),
+ F(32000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 75),
+ F(48000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 25),
+ F(64000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 16, 75),
+ F(75000000, CFG_CLK_SRC_GPLL0_AUX2, 4, 0, 0),
+ F(80000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 15),
+ F(96000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 25),
+ F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
+ F(102400000, CFG_CLK_SRC_GPLL0_AUX2, 1, 128, 375),
+ F(112000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 28, 75),
+ F(117964800, CFG_CLK_SRC_GPLL0_AUX2, 1, 6144, 15625),
+ F(120000000, CFG_CLK_SRC_GPLL0_AUX2, 2.5, 0, 0),
+ F(128000000, CFG_CLK_SRC_GPLL6, 3, 0, 0),
+ {}
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+ F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(25000000, CFG_CLK_SRC_GPLL0_AUX2, 12, 0, 0),
+ F(50000000, CFG_CLK_SRC_GPLL0_AUX2, 6, 0, 0),
+ F(100000000, CFG_CLK_SRC_GPLL0_AUX2, 3, 0, 0),
+ {}
+};
+
+static const struct pll_vote_clk gpll0_clk = {
+ .status = 0,
+ .status_bit = BIT(31),
+ .ena_vote = 0x79000,
+ .vote_bit = BIT(0),
+};
+
+static const struct gate_clk sm6125_clks[] = {
+ GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x1a084, BIT(0)),
+ GATE_CLK(GCC_QUPV3_WRAP0_CORE_2X_CLK, 0x7900c, BIT(9)),
+ GATE_CLK(GCC_QUPV3_WRAP0_CORE_CLK, 0x7900c, BIT(8)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x7900c, BIT(10)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x7900c, BIT(11)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x7900c, BIT(12)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x7900c, BIT(13)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x7900c, BIT(14)),
+ GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x7900c, BIT(15)),
+ GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x7900c, BIT(6)),
+ GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x7900c, BIT(7)),
+ GATE_CLK(GCC_SDCC1_AHB_CLK, 0x38008, BIT(0)),
+ GATE_CLK(GCC_SDCC1_APPS_CLK, 0x38004, BIT(0)),
+ GATE_CLK(GCC_SDCC1_ICE_CORE_CLK, 0x3800c, BIT(0)),
+ GATE_CLK(GCC_SDCC2_AHB_CLK, 0x1e008, BIT(0)),
+ GATE_CLK(GCC_SDCC2_APPS_CLK, 0x1e004, BIT(0)),
+ GATE_CLK(GCC_SYS_NOC_CPUSS_AHB_CLK, 0x79004, BIT(0)),
+ GATE_CLK(GCC_SYS_NOC_UFS_PHY_AXI_CLK, 0x45098, BIT(0)),
+ GATE_CLK(GCC_SYS_NOC_USB3_PRIM_AXI_CLK, 0x1a080, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x45014, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x45010, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x45044, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x45078, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x4501c, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x45018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x45040, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x1a010, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x1a018, BIT(0)),
+ GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x1a014, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x80278, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x1a054, BIT(0)),
+ GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x1a058, BIT(0)),
+ GATE_CLK(GCC_AHB2PHY_USB_CLK, 0x1d008, BIT(0)),
+ GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, BIT(0)),
+};
+
+static ulong sm6125_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
+
+ debug("%s: clk %s rate %lu\n", __func__, sm6125_clks[clk->id].name,
+ rate);
+
+ switch (clk->id) {
+ case GCC_QUPV3_WRAP0_S4_CLK:
+ freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, QUPV3_WRAP0_S4_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src,
+ 16);
+ return 0;
+ case GCC_SDCC2_APPS_CLK:
+ clk_enable_gpll0(priv->base, &gpll0_clk);
+ freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
+ WARN(freq->src != CFG_CLK_SRC_GPLL0,
+ "SDCC2_APPS_CLK_SRC not set to GPLL0, requested rate %lu\n",
+ rate);
+ clk_rcg_set_rate_mnd(priv->base, SDCC2_APPS_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src,
+ 8);
+ return freq->freq;
+ case GCC_SDCC1_APPS_CLK:
+ /* The firmware turns this on for us and always sets it to this rate */
+ return 384000000;
+ default:
+ return rate;
+ }
+}
+
+static int sm6125_enable(struct clk *clk)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (priv->data->num_clks < clk->id) {
+ debug("%s: unknown clk id %lu\n", __func__, clk->id);
+ return 0;
+ }
+
+ debug("%s: clk %s\n", __func__, sm6125_clks[clk->id].name);
+
+ switch (clk->id) {
+ case GCC_USB30_PRIM_MASTER_CLK:
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
+ qcom_gate_clk_en(priv, GCC_USB3_PRIM_CLKREF_CLK);
+ break;
+ }
+
+ return qcom_gate_clk_en(priv, clk->id);
+}
+
+static const struct qcom_reset_map sm6125_gcc_resets[] = {
+ [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 },
+ [GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 },
+ [GCC_UFS_PHY_BCR] = { 0x45000 },
+ [GCC_USB30_PRIM_BCR] = { 0x1a000 },
+ [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 },
+ [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 },
+ [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 },
+ [GCC_CAMSS_MICRO_BCR] = { 0x560ac },
+};
+
+static const struct qcom_power_map sm6125_gdscs[] = {
+ [USB30_PRIM_GDSC] = { 0x1a004 },
+ [UFS_PHY_GDSC] = { 0x45004 },
+ [CAMSS_VFE0_GDSC] = { 0x54004 },
+ [CAMSS_VFE1_GDSC] = { 0x5403c },
+ [CAMSS_TOP_GDSC] = { 0x5607c },
+ [CAM_CPP_GDSC] = { 0x560bc },
+ [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = { 0x7d060 },
+ [HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC] = { 0x80074 },
+ [HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC] = { 0x80084 },
+ [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = { 0x80094 },
+};
+
+static const phys_addr_t sm6125_gpll_addrs[] = {
+ GCC_BASE + GCC_GPLL0_MODE, GCC_BASE + GCC_GPLL3_MODE,
+ GCC_BASE + GCC_GPLL4_MODE, GCC_BASE + GCC_GPLL5_MODE,
+ GCC_BASE + GCC_GPLL6_MODE, GCC_BASE + GCC_GPLL7_MODE,
+ GCC_BASE + GCC_GPLL8_MODE, GCC_BASE + GCC_GPLL9_MODE,
+};
+
+static const phys_addr_t sm6125_rcg_addrs[] = {
+ 0x0141a01c, // GCC_USB30_PRIM_MASTER_CMD_RCGR
+ 0x0141a034, // GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR
+ 0x0141a060, // GCC_USB3_PRIM_PHY_AUX_CMD_RCGR
+ 0x01438028, // GCC_SDCC1_APPS_CMD_RCGR
+ 0x0141e00c, // GCC_SDCC2_APPS_CMD_RCGR
+ 0x0141f148, // GCC_QUPV3_WRAP0_S0_CMD_RCGR
+ 0x0141f278, // GCC_QUPV3_WRAP0_S1_CMD_RCGR
+ 0x0141f3a8, // GCC_QUPV3_WRAP0_S2_CMD_RCGR
+ 0x0141f4d8, // GCC_QUPV3_WRAP0_S3_CMD_RCGR
+ 0x0141f608, // GCC_QUPV3_WRAP0_S4_CMD_RCGR
+ 0x0141f738, // GCC_QUPV3_WRAP0_S5_CMD_RCGR
+ 0x01445020, // GCC_UFS_PHY_AXI_CMD_RCGR
+ 0x01445048, // GCC_UFS_PHY_ICE_CORE_CMD_RCGR
+ 0x01445060, // GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR
+ 0x0144507c, // GCC_UFS_PHY_PHY_AUX_CMD_RCGR
+};
+
+static const char *const sm6125_rcg_names[] = {
+ "GCC_USB30_PRIM_MASTER_CMD_RCGR",
+ "GCC_USB30_PRIM_MOCK_UTMI_CMD_RCGR",
+ "GCC_USB3_PRIM_PHY_AUX_CMD_RCGR",
+ "GCC_SDCC1_APPS_CMD_RCGR",
+ "GCC_SDCC2_APPS_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S0_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S1_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S2_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S3_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S4_CMD_RCGR",
+ "GCC_QUPV3_WRAP0_S5_CMD_RCGR",
+ "GCC_UFS_PHY_AXI_CMD_RCGR",
+ "GCC_UFS_PHY_ICE_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_UNIPRO_CORE_CMD_RCGR",
+ "GCC_UFS_PHY_PHY_AUX_CMD_RCGR",
+};
+
+static struct msm_clk_data sm6125_gcc_data = {
+ .resets = sm6125_gcc_resets,
+ .num_resets = ARRAY_SIZE(sm6125_gcc_resets),
+ .clks = sm6125_clks,
+ .num_clks = ARRAY_SIZE(sm6125_clks),
+ .power_domains = sm6125_gdscs,
+ .num_power_domains = ARRAY_SIZE(sm6125_gdscs),
+
+ .enable = sm6125_enable,
+ .set_rate = sm6125_set_rate,
+
+ .dbg_pll_addrs = sm6125_gpll_addrs,
+ .num_plls = ARRAY_SIZE(sm6125_gpll_addrs),
+ .dbg_rcg_addrs = sm6125_rcg_addrs,
+ .num_rcgs = ARRAY_SIZE(sm6125_rcg_addrs),
+ .dbg_rcg_names = sm6125_rcg_names,
+};
+
+static const struct udevice_id gcc_sm6125_of_match[] = {
+ {
+ .compatible = "qcom,gcc-sm6125",
+ .data = (ulong)&sm6125_gcc_data,
+ },
+ {}
+};
+
+U_BOOT_DRIVER(gcc_sm6125) = {
+ .name = "gcc_sm6125",
+ .id = UCLASS_NOP,
+ .of_match = gcc_sm6125_of_match,
+ .bind = qcom_cc_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 72f99e9fa1b..1893b6c4181 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -61,11 +61,11 @@ config CLK_RCAR_GEN3
Enable this to support the clocks on Renesas R-Car Gen3 and Gen4 SoCs.
config CLK_R8A774A1
- bool "Renesas R8A774A1 clock driver"
+ bool "Renesas R8A774A1 clock driver"
def_bool y if R8A774A1
- depends on CLK_RCAR_GEN3
- help
- Enable this to support the clocks on Renesas R8A774A1 SoC.
+ depends on CLK_RCAR_GEN3
+ help
+ Enable this to support the clocks on Renesas R8A774A1 SoC.
config CLK_R8A774B1
bool "Renesas R8A774B1 clock driver"
diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c
index 60ab2cb379e..8e992d2c2da 100644
--- a/drivers/clk/renesas/rcar-cpg-lib.c
+++ b/drivers/clk/renesas/rcar-cpg-lib.c
@@ -30,10 +30,6 @@
#define SDnSRCFC_SHIFT 2
#define STPnHCK_TABLE (CPG_SDCKCR_STPnHCK >> SDnSRCFC_SHIFT)
-/* Non-constant mask variant of FIELD_GET/FIELD_PREP */
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
-
static const struct clk_div_table cpg_sdh_div_table[] = {
{ 0, 1 }, { 1, 2 }, { STPnHCK_TABLE | 2, 4 }, { STPnHCK_TABLE | 3, 8 },
{ STPnHCK_TABLE | 4, 16 }, { 0, 0 },
diff --git a/drivers/clk/rockchip/clk_rk3528.c b/drivers/clk/rockchip/clk_rk3528.c
index bcdc0f930d2..cf8c3a62349 100644
--- a/drivers/clk/rockchip/clk_rk3528.c
+++ b/drivers/clk/rockchip/clk_rk3528.c
@@ -1335,6 +1335,7 @@ static ulong rk3528_clk_get_rate(struct clk *clk)
DPLL);
break;
+ case CLK_REF_USB3OTG:
case TCLK_EMMC:
case TCLK_WDT_NS:
rate = OSC_HZ;
@@ -1455,6 +1456,7 @@ static ulong rk3528_clk_set_rate(struct clk *clk, ulong rate)
priv->ppll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL],
priv->cru, PPLL);
break;
+ case CLK_REF_USB3OTG:
case TCLK_EMMC:
case TCLK_WDT_NS:
return (rate == OSC_HZ) ? 0 : -EINVAL;
diff --git a/drivers/clk/rockchip/clk_rk3576.c b/drivers/clk/rockchip/clk_rk3576.c
index 1026af27ca1..db8ce25852f 100644
--- a/drivers/clk/rockchip/clk_rk3576.c
+++ b/drivers/clk/rockchip/clk_rk3576.c
@@ -1549,6 +1549,24 @@ static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
con = readl(&cru->clksel_con[31]);
div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT;
return DIV_TO_RATE(priv->cpll_hz, div);
+ case REFCLKO25M_GMAC0_OUT:
+ con = readl(&cru->clksel_con[36]);
+ div = (con & CLK_REFCLKO25M_GMAC0_DIV_MASK) >> CLK_REFCLKO25M_GMAC0_DIV_SHIFT;
+ src = (con & CLK_REFCLKO25M_GMAC0_SEL_MASK) >> CLK_REFCLKO25M_GMAC0_SEL_SHIFT;
+ if (src == CLK_REFCLKO25M_GMAC0_SEL_CPLL)
+ p_rate = priv->cpll_hz;
+ else
+ p_rate = priv->gpll_hz;
+ return DIV_TO_RATE(p_rate, div);
+ case REFCLKO25M_GMAC1_OUT:
+ con = readl(&cru->clksel_con[36]);
+ div = (con & CLK_REFCLKO25M_GMAC1_DIV_MASK) >> CLK_REFCLKO25M_GMAC1_DIV_SHIFT;
+ src = (con & CLK_REFCLKO25M_GMAC1_SEL_MASK) >> CLK_REFCLKO25M_GMAC1_SEL_SHIFT;
+ if (src == CLK_REFCLKO25M_GMAC1_SEL_CPLL)
+ p_rate = priv->cpll_hz;
+ else
+ p_rate = priv->gpll_hz;
+ return DIV_TO_RATE(p_rate, div);
default:
return -ENOENT;
}
@@ -1608,6 +1626,34 @@ static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv,
CLK_GMAC1_125M_DIV_MASK,
(div - 1) << CLK_GMAC1_125M_DIV_SHIFT);
break;
+ case REFCLKO25M_GMAC0_OUT:
+ if (!(priv->gpll_hz % rate)) {
+ src = CLK_REFCLKO25M_GMAC0_SEL_GPLL;
+ div = priv->gpll_hz / rate;
+ } else {
+ src = CLK_REFCLKO25M_GMAC0_SEL_CPLL;
+ div = priv->cpll_hz / rate;
+ }
+ rk_clrsetreg(&cru->clksel_con[36],
+ CLK_REFCLKO25M_GMAC0_SEL_MASK |
+ CLK_REFCLKO25M_GMAC0_DIV_MASK,
+ src << CLK_REFCLKO25M_GMAC0_SEL_SHIFT |
+ (div - 1) << CLK_REFCLKO25M_GMAC0_DIV_SHIFT);
+ break;
+ case REFCLKO25M_GMAC1_OUT:
+ if (!(priv->gpll_hz % rate)) {
+ src = CLK_REFCLKO25M_GMAC1_SEL_GPLL;
+ div = priv->gpll_hz / rate;
+ } else {
+ src = CLK_REFCLKO25M_GMAC1_SEL_CPLL;
+ div = priv->cpll_hz / rate;
+ }
+ rk_clrsetreg(&cru->clksel_con[36],
+ CLK_REFCLKO25M_GMAC1_SEL_MASK |
+ CLK_REFCLKO25M_GMAC1_DIV_MASK,
+ src << CLK_REFCLKO25M_GMAC1_SEL_SHIFT |
+ (div - 1) << CLK_REFCLKO25M_GMAC1_DIV_SHIFT);
+ break;
default:
return -ENOENT;
}
@@ -1987,6 +2033,8 @@ static ulong rk3576_clk_get_rate(struct clk *clk)
case HCLK_SDIO:
rate = rk3576_mmc_get_clk(priv, clk->id);
break;
+ case CLK_REF_USB3OTG0:
+ case CLK_REF_USB3OTG1:
case TCLK_EMMC:
case TCLK_WDT0:
rate = OSC_HZ;
@@ -2014,6 +2062,8 @@ static ulong rk3576_clk_get_rate(struct clk *clk)
case CLK_GMAC1_PTP_REF:
case CLK_GMAC0_125M_SRC:
case CLK_GMAC1_125M_SRC:
+ case REFCLKO25M_GMAC0_OUT:
+ case REFCLKO25M_GMAC1_OUT:
rate = rk3576_gmac_get_clk(priv, clk->id);
break;
case CLK_UART_FRAC_0:
@@ -2151,6 +2201,8 @@ static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate)
case HCLK_SDIO:
ret = rk3576_mmc_set_clk(priv, clk->id, rate);
break;
+ case CLK_REF_USB3OTG0:
+ case CLK_REF_USB3OTG1:
case TCLK_EMMC:
case TCLK_WDT0:
ret = OSC_HZ;
@@ -2193,6 +2245,8 @@ static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate)
case CLK_GMAC1_PTP_REF:
case CLK_GMAC0_125M_SRC:
case CLK_GMAC1_125M_SRC:
+ case REFCLKO25M_GMAC0_OUT:
+ case REFCLKO25M_GMAC1_OUT:
ret = rk3576_gmac_set_clk(priv, clk->id, rate);
break;
case CLK_UART_FRAC_0:
diff --git a/drivers/clk/sophgo/clk-cv1800b.c b/drivers/clk/sophgo/clk-cv1800b.c
index d946ea57a46..248a69321fc 100644
--- a/drivers/clk/sophgo/clk-cv1800b.c
+++ b/drivers/clk/sophgo/clk-cv1800b.c
@@ -500,9 +500,12 @@ static int cv1800b_register_clk(struct udevice *dev)
{
struct clk osc;
ulong osc_rate;
- void *base = devfdt_get_addr_ptr(dev);
+ void __iomem *base = dev_read_addr_ptr(dev);
int i, ret;
+ if (!base)
+ return -EINVAL;
+
ret = clk_get_by_index(dev, 0, &osc);
if (ret) {
pr_err("Failed to get clock\n");
diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig
new file mode 100644
index 00000000000..25a3c1e4a45
--- /dev/null
+++ b/drivers/clk/spacemit/Kconfig
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2025, Junhui Liu <[email protected]>
+
+config CLK_SPACEMIT
+ bool "Clock support for SpacemiT SoCs"
+ depends on CLK || COMPILE_TEST
+ select REGMAP
+ select LIB_RATIONAL
+ help
+ This enables support clock driver for Spacemit SoC
+ family.
+
+if CLK_SPACEMIT
+
+config CLK_SPACEMIT_K1
+ bool "SpacemiT K1 clock support"
+ select CLK_CCF
+ help
+ This enables support clock driver for Spacemit K1 SoC.
+ It's based on Common Clock Framework.
+
+endif
diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile
new file mode 100644
index 00000000000..824e94d1f74
--- /dev/null
+++ b/drivers/clk/spacemit/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2025 Junhui Liu <[email protected]>
+
+obj-$(CONFIG_CLK_SPACEMIT) += clk_ddn.o clk_mix.o clk_pll.o
+
+obj-$(CONFIG_CLK_SPACEMIT_K1) += clk-k1.o
diff --git a/drivers/clk/spacemit/clk-k1.c b/drivers/clk/spacemit/clk-k1.c
new file mode 100644
index 00000000000..07adc126ee3
--- /dev/null
+++ b/drivers/clk/spacemit/clk-k1.c
@@ -0,0 +1,1878 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/lists.h>
+#include <regmap.h>
+#include <linux/clk-provider.h>
+#include <soc/spacemit/k1-reset.h>
+#include <soc/spacemit/k1-syscon.h>
+
+#include "clk_common.h"
+#include "clk_ddn.h"
+#include "clk_mix.h"
+#include "clk_pll.h"
+
+#include <dt-bindings/clock/spacemit,k1-syscon.h>
+
+#define K1_PLL_ID 100
+#define K1_MPMU_ID 200
+#define K1_APBC_ID 300
+#define K1_APMU_ID 400
+
+struct spacemit_ccu_data {
+ struct clk **clks;
+ size_t num;
+ unsigned long offset;
+};
+
+/* APBS clocks start, APBS region contains and only contains all PLL clocks */
+
+/*
+ * PLL{1,2} must run at fixed frequencies to provide clocks in correct rates for
+ * peripherals.
+ */
+static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = {
+ CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+CCU_PLL_DEFINE(CLK_PLL1, pll1, pll1, "clock-24m", pll1_rate_tbl,
+ APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU_POSR, POSR_PLL1_LOCK,
+ CLK_SET_RATE_GATE);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D4, pll1_d4, pll1_d4, "pll1", APBS_PLL1_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D6, pll1_d6, pll1_d6, "pll1", APBS_PLL1_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_FLAGS_DEFINE(CLK_PLL1_D8, pll1_d8, pll1_d8, "pll1",
+ APBS_PLL1_SWCR2, BIT(7), 8, 1, CLK_IS_CRITICAL);
+#else
+static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = {
+ CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),
+};
+
+static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = {
+ CCU_PLL_RATE(1600000000UL, 0x0050cd61, 0x43eaaaab),
+ CCU_PLL_RATE(1800000000UL, 0x0050cd61, 0x4b000000),
+ CCU_PLL_RATE(2000000000UL, 0x0050dd62, 0x2aeaaaab),
+ CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),
+ CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),
+ CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab),
+};
+
+CCU_PLL_DEFINE(CLK_PLL1, pll1, pll1, "clock-24m", pll1_rate_tbl,
+ APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU_POSR, POSR_PLL1_LOCK,
+ CLK_SET_RATE_GATE);
+CCU_PLL_DEFINE(CLK_PLL2, pll2, pll2, "clock-24m", pll2_rate_tbl,
+ APBS_PLL2_SWCR1, APBS_PLL2_SWCR3, MPMU_POSR, POSR_PLL2_LOCK,
+ CLK_SET_RATE_GATE);
+CCU_PLL_DEFINE(CLK_PLL3, pll3, pll3, "clock-24m", pll3_rate_tbl,
+ APBS_PLL3_SWCR1, APBS_PLL3_SWCR3, MPMU_POSR, POSR_PLL3_LOCK,
+ CLK_SET_RATE_GATE);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D2, pll1_d2, pll1_d2, "pll1", APBS_PLL1_SWCR2,
+ BIT(1), 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D3, pll1_d3, pll1_d3, "pll1", APBS_PLL1_SWCR2,
+ BIT(2), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D4, pll1_d4, pll1_d4, "pll1", APBS_PLL1_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D5, pll1_d5, pll1_d5, "pll1", APBS_PLL1_SWCR2,
+ BIT(4), 5, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D6, pll1_d6, pll1_d6, "pll1", APBS_PLL1_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D7, pll1_d7, pll1_d7, "pll1", APBS_PLL1_SWCR2,
+ BIT(6), 7, 1);
+CCU_FACTOR_GATE_FLAGS_DEFINE(CLK_PLL1_D8, pll1_d8, pll1_d8, "pll1",
+ APBS_PLL1_SWCR2, BIT(7), 8, 1, CLK_IS_CRITICAL);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D11, pll1_d11_223p4, pll1_d11_223p4, "pll1",
+ APBS_PLL1_SWCR2, BIT(15), 11, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D13, pll1_d13_189, pll1_d13_189, "pll1",
+ APBS_PLL1_SWCR2, BIT(16), 13, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D23, pll1_d23_106p8, pll1_d23_106p8, "pll1",
+ APBS_PLL1_SWCR2, BIT(20), 23, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D64, pll1_d64_38p4, pll1_d64_38p4, "pll1",
+ APBS_PLL1_SWCR2, BIT(0), 64, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D10_AUD, pll1_aud_245p7, pll1_aud_245p7, "pll1",
+ APBS_PLL1_SWCR2, BIT(10), 10, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D100_AUD, pll1_aud_24p5, pll1_aud_24p5, "pll1",
+ APBS_PLL1_SWCR2, BIT(11), 100, 1);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D1, pll2_d1, pll2_d1, "pll2", APBS_PLL2_SWCR2,
+ BIT(0), 1, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D2, pll2_d2, pll2_d2, "pll2", APBS_PLL2_SWCR2,
+ BIT(1), 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D3, pll2_d3, pll2_d3, "pll2", APBS_PLL2_SWCR2,
+ BIT(2), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D4, pll2_d4, pll2_d4, "pll2", APBS_PLL2_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D5, pll2_d5, pll2_d5, "pll2", APBS_PLL2_SWCR2,
+ BIT(4), 5, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D6, pll2_d6, pll2_d6, "pll2", APBS_PLL2_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D7, pll2_d7, pll2_d7, "pll2", APBS_PLL2_SWCR2,
+ BIT(6), 7, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D8, pll2_d8, pll2_d8, "pll2", APBS_PLL2_SWCR2,
+ BIT(7), 8, 1);
+
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D1, pll3_d1, pll3_d1, "pll3", APBS_PLL3_SWCR2,
+ BIT(0), 1, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D2, pll3_d2, pll3_d2, "pll3", APBS_PLL3_SWCR2,
+ BIT(1), 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D3, pll3_d3, pll3_d3, "pll3", APBS_PLL3_SWCR2,
+ BIT(2), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D4, pll3_d4, pll3_d4, "pll3", APBS_PLL3_SWCR2,
+ BIT(3), 4, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D5, pll3_d5, pll3_d5, "pll3", APBS_PLL3_SWCR2,
+ BIT(4), 5, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D6, pll3_d6, pll3_d6, "pll3", APBS_PLL3_SWCR2,
+ BIT(5), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D7, pll3_d7, pll3_d7, "pll3", APBS_PLL3_SWCR2,
+ BIT(6), 7, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D8, pll3_d8, pll3_d8, "pll3", APBS_PLL3_SWCR2,
+ BIT(7), 8, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL3_20, pll3_20, pll3_20, "pll3_d8", 20, 1);
+CCU_FACTOR_DEFINE(CLK_PLL3_40, pll3_40, pll3_40, "pll3_d8", 10, 1);
+CCU_FACTOR_DEFINE(CLK_PLL3_80, pll3_80, pll3_80, "pll3_d8", 5, 1);
+#endif
+/* APBS clocks end */
+
+/* MPMU clocks start */
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+CCU_GATE_DEFINE(CLK_PLL1_614, pll1_d4_614p4, pll1_d4_614p4, "pll1_d4",
+ MPMU_ACGR, BIT(15), 0);
+CCU_GATE_DEFINE(CLK_PLL1_409P6, pll1_d6_409p6, pll1_d6_409p6, "pll1_d6",
+ MPMU_ACGR, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, "pll1_d8",
+ MPMU_ACGR, BIT(13), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_31P5, pll1_d78_31p5, pll1_d78_31p5,
+ "pll1_d4", MPMU_ACGR, BIT(6), 39, 2);
+CCU_DDN_DEFINE(CLK_SLOW_UART2, slow_uart2_48, slow_uart2_48,
+ "pll1_d4_614p4", MPMU_SUCCR_1,
+ CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);
+#else
+CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, "pll1_d8",
+ MPMU_ACGR, BIT(13), 0);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_76P8, pll1_d32_76p8, pll1_d32_76p8, "pll1_d8_307p2",
+ 4, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_61P44, pll1_d40_61p44, pll1_d40_61p44,
+ "pll1_d8_307p2", 5, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_153P6, pll1_d16_153p6, pll1_d16_153p6,
+ "pll1_d8", 2, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_102P4, pll1_d24_102p4, pll1_d24_102p4,
+ "pll1_d8", MPMU_ACGR, BIT(12), 3, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2, pll1_d48_51p2, pll1_d48_51p2,
+ "pll1_d8", MPMU_ACGR, BIT(7), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2_AP, pll1_d48_51p2_ap, pll1_d48_51p2_ap,
+ "pll1_d8", MPMU_ACGR, BIT(11), 6, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_57P6, pll1_m3d128_57p6, pll1_m3d128_57p6,
+ "pll1_d8", MPMU_ACGR, BIT(8), 16, 3);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_25P6, pll1_d96_25p6, pll1_d96_25p6,
+ "pll1_d8", MPMU_ACGR, BIT(4), 12, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8, pll1_d192_12p8, pll1_d192_12p8,
+ "pll1_d8", MPMU_ACGR, BIT(3), 24, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8_WDT, pll1_d192_12p8_wdt, pll1_d192_12p8_wdt,
+ "pll1_d8", MPMU_ACGR, BIT(19), 24, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_6P4, pll1_d384_6p4, pll1_d384_6p4,
+ "pll1_d8", MPMU_ACGR, BIT(2), 48, 1);
+
+CCU_FACTOR_DEFINE(CLK_PLL1_3P2, pll1_d768_3p2, pll1_d768_3p2,
+ "pll1_d384_6p4", 2, 1);
+CCU_FACTOR_DEFINE(CLK_PLL1_1P6, pll1_d1536_1p6, pll1_d1536_1p6,
+ "pll1_d384_6p4", 4, 1);
+CCU_FACTOR_DEFINE(CLK_PLL1_0P8, pll1_d3072_0p8, pll1_d3072_0p8,
+ "pll1_d384_6p4", 8, 1);
+
+CCU_GATE_DEFINE(CLK_PLL1_409P6, pll1_d6_409p6, pll1_d6_409p6, "pll1_d6",
+ MPMU_ACGR, BIT(0), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_204P8, pll1_d12_204p8, pll1_d12_204p8,
+ "pll1_d6", MPMU_ACGR, BIT(5), 2, 1);
+
+CCU_GATE_DEFINE(CLK_PLL1_491, pll1_d5_491p52, pll1_d5_491p52, "pll1_d5",
+ MPMU_ACGR, BIT(21), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_245P76, pll1_d10_245p76, pll1_d10_245p76,
+ "pll1_d5", MPMU_ACGR, BIT(18), 2, 1);
+
+CCU_GATE_DEFINE(CLK_PLL1_614, pll1_d4_614p4, pll1_d4_614p4, "pll1_d4",
+ MPMU_ACGR, BIT(15), 0);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_47P26, pll1_d52_47p26, pll1_d52_47p26,
+ "pll1_d4", MPMU_ACGR, BIT(10), 13, 1);
+CCU_FACTOR_GATE_DEFINE(CLK_PLL1_31P5, pll1_d78_31p5, pll1_d78_31p5,
+ "pll1_d4", MPMU_ACGR, BIT(6), 39, 2);
+
+CCU_GATE_DEFINE(CLK_PLL1_819, pll1_d3_819p2, pll1_d3_819p2, "pll1_d3",
+ MPMU_ACGR, BIT(14), 0);
+
+CCU_GATE_DEFINE(CLK_PLL1_1228, pll1_d2_1228p8, pll1_d2_1228p8, "pll1_d2",
+ MPMU_ACGR, BIT(16), 0);
+
+CCU_GATE_DEFINE(CLK_SLOW_UART, slow_uart, slow_uart, "clock-32k", MPMU_ACGR,
+ BIT(1), CLK_IGNORE_UNUSED);
+CCU_DDN_DEFINE(CLK_SLOW_UART1, slow_uart1_14p74, slow_uart1_14p74,
+ "pll1_d16_153p6", MPMU_SUCCR,
+ CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);
+CCU_DDN_DEFINE(CLK_SLOW_UART2, slow_uart2_48, slow_uart2_48,
+ "pll1_d4_614p4", MPMU_SUCCR_1,
+ CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0);
+
+CCU_GATE_DEFINE(CLK_WDT, wdt_clk, wdt_clk, "pll1_d96_25p6", MPMU_WDTPCR,
+ BIT(1), 0);
+
+CCU_FACTOR_DEFINE(CLK_I2S_153P6, i2s_153p6, i2s_153p6, "pll1_d8_307p2", 2, 1);
+
+static const char * const i2s_153p6_base_parents[] = {
+ "i2s_153p6",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DEFINE(CLK_I2S_153P6_BASE, i2s_153p6_base, i2s_153p6_base,
+ i2s_153p6_base_parents, ARRAY_SIZE(i2s_153p6_base_parents),
+ MPMU_FCCR, 29, 1, 0);
+
+static const char * const i2s_sysclk_src_parents[] = {
+ "pll1_d96_25p6",
+ "i2s_153p6_base"
+};
+
+CCU_MUX_GATE_DEFINE(CLK_I2S_SYSCLK_SRC, i2s_sysclk_src, i2s_sysclk_src,
+ i2s_sysclk_src_parents, ARRAY_SIZE(i2s_sysclk_src_parents),
+ MPMU_ISCCR, 30, 1, BIT(31), 0);
+
+CCU_DDN_DEFINE(CLK_I2S_SYSCLK, i2s_sysclk, i2s_sysclk, "i2s_sysclk_src",
+ MPMU_ISCCR, CCU_DDN_MASK(0, 15), 0, CCU_DDN_MASK(15, 12),
+ 15, 1, 0);
+
+CCU_FACTOR_DEFINE(CLK_I2S_BCLK_FACTOR, i2s_bclk_factor, i2s_bclk_factor,
+ "i2s_sysclk", 2, 1);
+/*
+ * Divider of i2s_bclk always implies a 1/2 factor, which is
+ * described by i2s_bclk_factor.
+ */
+CCU_DIV_GATE_DEFINE(CLK_I2S_BCLK, i2s_bclk, i2s_bclk, "i2s_bclk_factor",
+ MPMU_ISCCR, 27, 2, BIT(29), 0);
+
+static const char * const apb_parents[] = {
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d96_25p6",
+ "pll1_d24_102p4",
+};
+
+CCU_MUX_DEFINE(CLK_APB, apb_clk, apb_clk, apb_parents, ARRAY_SIZE(apb_parents),
+ MPMU_APBCSCR, 0, 2, 0);
+
+CCU_GATE_DEFINE(CLK_WDT_BUS, wdt_bus_clk, wdt_bus_clk, "apb_clk", MPMU_WDTPCR,
+ BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_RIPC, ripc_clk, ripc_clk, "apb_clk", MPMU_RIPCCR, 0x1, 0);
+#endif
+/* MPMU clocks end */
+
+/* APBC clocks start */
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static const char * const uart_clk_parents[] = {
+ "clock-dummy",
+ "clock-dummy",
+ "slow_uart2_48",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_UART0, uart0_clk, uart0_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART1_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+static const char * const twsi_parents[] = {
+ "pll1_d78_31p5",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+/*
+ * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero.
+ * Combine functional and bus bits together as a gate to avoid sharing the
+ * write-only register between different clock hardwares.
+ */
+CCU_GATE_DEFINE(CLK_TWSI8, twsi8_clk, twsi8_clk, "pll1_d78_31p5",
+ APBC_TWSI8_CLK_RST, BIT(1) | BIT(0), 0);
+
+#else
+static const char * const uart_clk_parents[] = {
+ "pll1_m3d128_57p6",
+ "slow_uart1_14p74",
+ "slow_uart2_48",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_UART0, uart0_clk, uart0_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART1_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+static const char * const twsi_parents[] = {
+ "pll1_d78_31p5",
+ "pll1_d48_51p2",
+ "pll1_d40_61p44",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+/*
+ * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero.
+ * Combine functional and bus bits together as a gate to avoid sharing the
+ * write-only register between different clock hardwares.
+ */
+CCU_GATE_DEFINE(CLK_TWSI8, twsi8_clk, twsi8_clk, "pll1_d78_31p5",
+ APBC_TWSI8_CLK_RST, BIT(1) | BIT(0), 0);
+
+CCU_MUX_GATE_DEFINE(CLK_UART2, uart2_clk, uart2_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART2_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART3, uart3_clk, uart3_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART3_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART4, uart4_clk, uart4_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART4_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART5, uart5_clk, uart5_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART5_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART6, uart6_clk, uart6_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART6_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART7, uart7_clk, uart7_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART7_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART8, uart8_clk, uart8_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART8_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_UART9, uart9_clk, uart9_clk, uart_clk_parents,
+ ARRAY_SIZE(uart_clk_parents), APBC_UART9_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_GPIO, gpio_clk, gpio_clk, "clock-24m", APBC_GPIO_CLK_RST,
+ BIT(1) | BIT(0), 0);
+
+static const char * const pwm_parents[] = {
+ "pll1_d192_12p8",
+ "clock-32k",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_PWM0, pwm0_clk, pwm0_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM0_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM1, pwm1_clk, pwm1_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM1_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM2, pwm2_clk, pwm2_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM2_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM3, pwm3_clk, pwm3_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM3_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM4, pwm4_clk, pwm4_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM4_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM5, pwm5_clk, pwm5_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM5_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM6, pwm6_clk, pwm6_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM6_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM7, pwm7_clk, pwm7_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM7_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM8, pwm8_clk, pwm8_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM8_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM9, pwm9_clk, pwm9_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM9_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM10, pwm10_clk, pwm10_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM10_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM11, pwm11_clk, pwm11_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM11_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM12, pwm12_clk, pwm12_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM12_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM13, pwm13_clk, pwm13_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM13_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM14, pwm14_clk, pwm14_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM14_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM15, pwm15_clk, pwm15_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM15_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM16, pwm16_clk, pwm16_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM16_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM17, pwm17_clk, pwm17_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM17_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM18, pwm18_clk, pwm18_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM18_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_PWM19, pwm19_clk, pwm19_clk, pwm_parents,
+ ARRAY_SIZE(pwm_parents), APBC_PWM19_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+
+static const char * const ssp_parents[] = {
+ "pll1_d384_6p4",
+ "pll1_d192_12p8",
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d768_3p2",
+ "pll1_d1536_1p6",
+ "pll1_d3072_0p8",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_SSP3, ssp3_clk, ssp3_clk, ssp_parents,
+ ARRAY_SIZE(ssp_parents), APBC_SSP3_CLK_RST, 4, 3,
+ BIT(1), 0);
+
+CCU_GATE_DEFINE(CLK_RTC, rtc_clk, rtc_clk, "clock-32k", APBC_RTC_CLK_RST,
+ BIT(7) | BIT(1) | BIT(0), 0);
+
+CCU_MUX_GATE_DEFINE(CLK_TWSI0, twsi0_clk, twsi0_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI0_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI1, twsi1_clk, twsi1_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI1_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI4, twsi4_clk, twsi4_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI4_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI5, twsi5_clk, twsi5_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI5_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI6, twsi6_clk, twsi6_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI6_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TWSI7, twsi7_clk, twsi7_clk, twsi_parents,
+ ARRAY_SIZE(twsi_parents), APBC_TWSI7_CLK_RST,
+ 4, 3, BIT(1) | BIT(0), 0);
+
+static const char * const timer_parents[] = {
+ "pll1_d192_12p8",
+ "clock-32k",
+ "pll1_d384_6p4",
+ "clock-3m",
+ "clock-1m",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_TIMERS1, timers1_clk, timers1_clk, timer_parents,
+ ARRAY_SIZE(timer_parents), APBC_TIMERS1_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+CCU_MUX_GATE_DEFINE(CLK_TIMERS2, timers2_clk, timers2_clk, timer_parents,
+ ARRAY_SIZE(timer_parents), APBC_TIMERS2_CLK_RST, 4, 3,
+ BIT(1) | BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_AIB, aib_clk, aib_clk, "clock-24m", APBC_AIB_CLK_RST,
+ BIT(1) | BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_ONEWIRE, onewire_clk, onewire_clk, "clock-24m",
+ APBC_ONEWIRE_CLK_RST, BIT(1) | BIT(0), 0);
+
+/*
+ * When i2s_bclk is selected as the parent clock of sspa,
+ * the hardware requires bit3 to be set
+ */
+CCU_GATE_DEFINE(CLK_SSPA0_I2S_BCLK, sspa0_i2s_bclk, sspa0_i2s_bclk, "i2s_bclk",
+ APBC_SSPA0_CLK_RST, BIT(3), 0);
+CCU_GATE_DEFINE(CLK_SSPA1_I2S_BCLK, sspa1_i2s_bclk, sspa1_i2s_bclk, "i2s_bclk",
+ APBC_SSPA1_CLK_RST, BIT(3), 0);
+
+static const char * const sspa0_parents[] = {
+ "pll1_d384_6p4",
+ "pll1_d192_12p8",
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d768_3p2",
+ "pll1_d1536_1p6",
+ "pll1_d3072_0p8",
+ "sspa0_i2s_bclk",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_SSPA0, sspa0_clk, sspa0_clk, sspa0_parents,
+ ARRAY_SIZE(sspa0_parents), APBC_SSPA0_CLK_RST, 4, 3,
+ BIT(1), 0);
+
+static const char * const sspa1_parents[] = {
+ "pll1_d384_6p4",
+ "pll1_d192_12p8",
+ "pll1_d96_25p6",
+ "pll1_d48_51p2",
+ "pll1_d768_3p2",
+ "pll1_d1536_1p6",
+ "pll1_d3072_0p8",
+ "sspa1_i2s_bclk",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_SSPA1, sspa1_clk, sspa1_clk, sspa1_parents,
+ ARRAY_SIZE(sspa1_parents), APBC_SSPA1_CLK_RST, 4, 3,
+ BIT(1), 0);
+
+CCU_GATE_DEFINE(CLK_DRO, dro_clk, dro_clk, "apb_clk", APBC_DRO_CLK_RST,
+ BIT(1) | BIT(0), 0);
+CCU_GATE_DEFINE(CLK_IR, ir_clk, ir_clk, "apb_clk", APBC_IR_CLK_RST,
+ BIT(1) | BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TSEN, tsen_clk, tsen_clk, "apb_clk", APBC_TSEN_CLK_RST,
+ BIT(1) | BIT(0), 0);
+CCU_GATE_DEFINE(CLK_IPC_AP2AUD, ipc_ap2aud_clk, ipc_ap2aud_clk, "apb_clk",
+ APBC_IPC_AP2AUD_CLK_RST, BIT(1) | BIT(0), 0);
+
+static const char * const can_parents[] = {
+ "pll3_20",
+ "pll3_40",
+ "pll3_80",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CAN0, can0_clk, can0_clk, can_parents,
+ ARRAY_SIZE(can_parents), APBC_CAN0_CLK_RST, 4, 3,
+ BIT(1), 0);
+CCU_GATE_DEFINE(CLK_CAN0_BUS, can0_bus_clk, can0_bus_clk, "clock-24m",
+ APBC_CAN0_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_UART0_BUS, uart0_bus_clk, uart0_bus_clk, "apb_clk",
+ APBC_UART1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART2_BUS, uart2_bus_clk, uart2_bus_clk, "apb_clk",
+ APBC_UART2_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART3_BUS, uart3_bus_clk, uart3_bus_clk, "apb_clk",
+ APBC_UART3_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART4_BUS, uart4_bus_clk, uart4_bus_clk, "apb_clk",
+ APBC_UART4_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART5_BUS, uart5_bus_clk, uart5_bus_clk, "apb_clk",
+ APBC_UART5_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART6_BUS, uart6_bus_clk, uart6_bus_clk, "apb_clk",
+ APBC_UART6_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART7_BUS, uart7_bus_clk, uart7_bus_clk, "apb_clk",
+ APBC_UART7_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART8_BUS, uart8_bus_clk, uart8_bus_clk, "apb_clk",
+ APBC_UART8_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_UART9_BUS, uart9_bus_clk, uart9_bus_clk, "apb_clk",
+ APBC_UART9_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_GPIO_BUS, gpio_bus_clk, gpio_bus_clk, "apb_clk",
+ APBC_GPIO_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PWM0_BUS, pwm0_bus_clk, pwm0_bus_clk, "apb_clk",
+ APBC_PWM0_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM1_BUS, pwm1_bus_clk, pwm1_bus_clk, "apb_clk",
+ APBC_PWM1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM2_BUS, pwm2_bus_clk, pwm2_bus_clk, "apb_clk",
+ APBC_PWM2_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM3_BUS, pwm3_bus_clk, pwm3_bus_clk, "apb_clk",
+ APBC_PWM3_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM4_BUS, pwm4_bus_clk, pwm4_bus_clk, "apb_clk",
+ APBC_PWM4_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM5_BUS, pwm5_bus_clk, pwm5_bus_clk, "apb_clk",
+ APBC_PWM5_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM6_BUS, pwm6_bus_clk, pwm6_bus_clk, "apb_clk",
+ APBC_PWM6_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM7_BUS, pwm7_bus_clk, pwm7_bus_clk, "apb_clk",
+ APBC_PWM7_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM8_BUS, pwm8_bus_clk, pwm8_bus_clk, "apb_clk",
+ APBC_PWM8_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM9_BUS, pwm9_bus_clk, pwm9_bus_clk, "apb_clk",
+ APBC_PWM9_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM10_BUS, pwm10_bus_clk, pwm10_bus_clk, "apb_clk",
+ APBC_PWM10_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM11_BUS, pwm11_bus_clk, pwm11_bus_clk, "apb_clk",
+ APBC_PWM11_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM12_BUS, pwm12_bus_clk, pwm12_bus_clk, "apb_clk",
+ APBC_PWM12_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM13_BUS, pwm13_bus_clk, pwm13_bus_clk, "apb_clk",
+ APBC_PWM13_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM14_BUS, pwm14_bus_clk, pwm14_bus_clk, "apb_clk",
+ APBC_PWM14_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM15_BUS, pwm15_bus_clk, pwm15_bus_clk, "apb_clk",
+ APBC_PWM15_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM16_BUS, pwm16_bus_clk, pwm16_bus_clk, "apb_clk",
+ APBC_PWM16_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM17_BUS, pwm17_bus_clk, pwm17_bus_clk, "apb_clk",
+ APBC_PWM17_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM18_BUS, pwm18_bus_clk, pwm18_bus_clk, "apb_clk",
+ APBC_PWM18_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_PWM19_BUS, pwm19_bus_clk, pwm19_bus_clk, "apb_clk",
+ APBC_PWM19_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_SSP3_BUS, ssp3_bus_clk, ssp3_bus_clk, "apb_clk",
+ APBC_SSP3_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_RTC_BUS, rtc_bus_clk, rtc_bus_clk, "apb_clk",
+ APBC_RTC_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_TWSI0_BUS, twsi0_bus_clk, twsi0_bus_clk, "apb_clk",
+ APBC_TWSI0_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI1_BUS, twsi1_bus_clk, twsi1_bus_clk, "apb_clk",
+ APBC_TWSI1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI2_BUS, twsi2_bus_clk, twsi2_bus_clk, "apb_clk",
+ APBC_TWSI2_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI4_BUS, twsi4_bus_clk, twsi4_bus_clk, "apb_clk",
+ APBC_TWSI4_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI5_BUS, twsi5_bus_clk, twsi5_bus_clk, "apb_clk",
+ APBC_TWSI5_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI6_BUS, twsi6_bus_clk, twsi6_bus_clk, "apb_clk",
+ APBC_TWSI6_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TWSI7_BUS, twsi7_bus_clk, twsi7_bus_clk, "apb_clk",
+ APBC_TWSI7_CLK_RST, BIT(0), 0);
+CCU_FACTOR_DEFINE(CLK_TWSI8_BUS, twsi8_bus_clk, twsi8_bus_clk, "apb_clk", 1, 1);
+
+CCU_GATE_DEFINE(CLK_TIMERS1_BUS, timers1_bus_clk, timers1_bus_clk, "apb_clk",
+ APBC_TIMERS1_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_TIMERS2_BUS, timers2_bus_clk, timers2_bus_clk, "apb_clk",
+ APBC_TIMERS2_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_AIB_BUS, aib_bus_clk, aib_bus_clk, "apb_clk",
+ APBC_AIB_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_ONEWIRE_BUS, onewire_bus_clk, onewire_bus_clk, "apb_clk",
+ APBC_ONEWIRE_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_SSPA0_BUS, sspa0_bus_clk, sspa0_bus_clk, "apb_clk",
+ APBC_SSPA0_CLK_RST, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_SSPA1_BUS, sspa1_bus_clk, sspa1_bus_clk, "apb_clk",
+ APBC_SSPA1_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_TSEN_BUS, tsen_bus_clk, tsen_bus_clk, "apb_clk",
+ APBC_TSEN_CLK_RST, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_IPC_AP2AUD_BUS, ipc_ap2aud_bus_clk, ipc_ap2aud_bus_clk,
+ "apb_clk", APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0);
+#endif
+/* APBC clocks end */
+
+/* APMU clocks start */
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static const char * const pmua_aclk_parents[] = {
+ "clock-dummy",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_FC_DEFINE(CLK_PMUA_ACLK, pmua_aclk, pmua_aclk, pmua_aclk_parents,
+ ARRAY_SIZE(pmua_aclk_parents),
+ APMU_ACLK_CLK_CTRL, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4),
+ 0, 1, 0);
+
+CCU_GATE_DEFINE(CLK_SDH_AXI, sdh_axi_aclk, sdh_axi_aclk, "pmua_aclk",
+ APMU_SDH0_CLK_RES_CTRL, BIT(3), 0);
+
+static const char * const sdh01_parents[] = {
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH0, sdh0_clk, sdh0_clk, sdh01_parents,
+ ARRAY_SIZE(sdh01_parents),
+ APMU_SDH0_CLK_RES_CTRL,
+ APMU_SDH0_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+
+static const char * const sdh2_parents[] = {
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH2, sdh2_clk, sdh2_clk, sdh2_parents,
+ ARRAY_SIZE(sdh2_parents),
+ APMU_SDH2_CLK_RES_CTRL,
+ APMU_SDH2_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+#else
+static const char * const pmua_aclk_parents[] = {
+ "pll1_d10_245p76",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_FC_DEFINE(CLK_PMUA_ACLK, pmua_aclk, pmua_aclk, pmua_aclk_parents,
+ ARRAY_SIZE(pmua_aclk_parents),
+ APMU_ACLK_CLK_CTRL, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4),
+ 0, 1, 0);
+
+static const char * const emmc_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll1_d52_47p26",
+ "pll1_d3_819p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_EMMC, emmc_clk, emmc_clk, emmc_parents,
+ ARRAY_SIZE(emmc_parents),
+ APMU_PMUA_EM_CLK_RES_CTRL,
+ APMU_PMUA_EM_CLK_RES_CTRL, 8, 3, BIT(11),
+ 6, 2, BIT(4), 0);
+CCU_DIV_GATE_DEFINE(CLK_EMMC_X, emmc_x_clk, emmc_x_clk, "pll1_d2_1228p8",
+ APMU_PMUA_EM_CLK_RES_CTRL, 12,
+ 3, BIT(15), 0);
+
+CCU_GATE_DEFINE(CLK_EMMC_BUS, emmc_bus_clk, emmc_bus_clk, "pmua_aclk",
+ APMU_PMUA_EM_CLK_RES_CTRL, BIT(3), 0);
+
+static const char * const cci550_clk_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll2_d3",
+};
+
+CCU_MUX_DIV_FC_DEFINE(CLK_CCI550, cci550_clk, cci550_clk, cci550_clk_parents,
+ ARRAY_SIZE(cci550_clk_parents),
+ APMU_CCI550_CLK_CTRL, APMU_CCI550_CLK_CTRL, 8, 3,
+ BIT(12), 0, 2, CLK_IS_CRITICAL);
+
+static const char * const cpu_c0_hi_clk_parents[] = {
+ "pll3_d2",
+ "pll3_d1",
+};
+
+CCU_MUX_DEFINE(CLK_CPU_C0_HI, cpu_c0_hi_clk, cpu_c0_hi_clk,
+ cpu_c0_hi_clk_parents, ARRAY_SIZE(cpu_c0_hi_clk_parents),
+ APMU_CPU_C0_CLK_CTRL, 13, 1, 0);
+static const char * const cpu_c0_clk_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d2_1228p8",
+ "pll3_d3",
+ "pll2_d3",
+ "cpu_c0_hi_clk",
+};
+
+CCU_MUX_FC_DEFINE(CLK_CPU_C0_CORE, cpu_c0_core_clk, cpu_c0_core_clk,
+ cpu_c0_clk_parents, ARRAY_SIZE(cpu_c0_clk_parents),
+ APMU_CPU_C0_CLK_CTRL, APMU_CPU_C0_CLK_CTRL,
+ BIT(12), 0, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(CLK_CPU_C0_ACE, cpu_c0_ace_clk, cpu_c0_ace_clk,
+ "cpu_c0_core_clk", APMU_CPU_C0_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(CLK_CPU_C0_TCM, cpu_c0_tcm_clk, cpu_c0_tcm_clk,
+ "cpu_c0_core_clk", APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL);
+
+static const char * const cpu_c1_hi_clk_parents[] = {
+ "pll3_d2",
+ "pll3_d1",
+};
+
+CCU_MUX_DEFINE(CLK_CPU_C1_HI, cpu_c1_hi_clk, cpu_c1_hi_clk,
+ cpu_c1_hi_clk_parents, ARRAY_SIZE(cpu_c1_hi_clk_parents),
+ APMU_CPU_C1_CLK_CTRL, 13, 1, 0);
+static const char * const cpu_c1_clk_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d2_1228p8",
+ "pll3_d3",
+ "pll2_d3",
+ "cpu_c1_hi_clk",
+};
+
+CCU_MUX_FC_DEFINE(CLK_CPU_C1_CORE, cpu_c1_core_clk, cpu_c1_core_clk,
+ cpu_c1_clk_parents, ARRAY_SIZE(cpu_c1_clk_parents),
+ APMU_CPU_C1_CLK_CTRL, APMU_CPU_C1_CLK_CTRL,
+ BIT(12), 0, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(CLK_CPU_C1_ACE, cpu_c1_ace_clk, cpu_c1_ace_clk,
+ "cpu_c1_core_clk", APMU_CPU_C1_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);
+
+static const char * const jpg_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d3_819p2",
+ "pll1_d2_1228p8",
+ "pll2_d4",
+ "pll2_d3",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_JPG, jpg_clk, jpg_clk, jpg_parents,
+ ARRAY_SIZE(jpg_parents),
+ APMU_JPG_CLK_RES_CTRL,
+ APMU_JPG_CLK_RES_CTRL,
+ 5, 3, BIT(15), 2, 3, BIT(1), 0);
+
+static const char * const ccic2phy_parents[] = {
+ "pll1_d24_102p4",
+ "pll1_d48_51p2_ap",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CCIC2PHY, ccic2phy_clk, ccic2phy_clk, ccic2phy_parents,
+ ARRAY_SIZE(ccic2phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL,
+ 7, 1, BIT(5), 0);
+
+static const char * const ccic3phy_parents[] = {
+ "pll1_d24_102p4",
+ "pll1_d48_51p2_ap",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CCIC3PHY, ccic3phy_clk, ccic3phy_clk, ccic3phy_parents,
+ ARRAY_SIZE(ccic3phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL,
+ 31, 1, BIT(30), 0);
+
+static const char * const csi_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll2_d2",
+ "pll2_d3",
+ "pll2_d4",
+ "pll1_d2_1228p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CSI, csi_clk, csi_clk, csi_parents,
+ ARRAY_SIZE(csi_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL,
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 20, 3, BIT(15),
+ 16, 3, BIT(4), 0);
+
+static const char * const camm_parents[] = {
+ "pll1_d8_307p2",
+ "pll2_d5",
+ "pll1_d6_409p6",
+ "clock-24m",
+};
+
+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM0, camm0_clk, camm0_clk, camm_parents,
+ ARRAY_SIZE(camm_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,
+ BIT(28), 0);
+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM1, camm1_clk, camm1_clk, camm_parents,
+ ARRAY_SIZE(camm_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,
+ BIT(6), 0);
+CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM2, camm2_clk, camm2_clk, camm_parents,
+ ARRAY_SIZE(camm_parents),
+ APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2,
+ BIT(3), 0);
+
+static const char * const isp_cpp_parents[] = {
+ "pll1_d8_307p2",
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_DEFINE(CLK_ISP_CPP, isp_cpp_clk, isp_cpp_clk, isp_cpp_parents,
+ ARRAY_SIZE(isp_cpp_parents),
+ APMU_ISP_CLK_RES_CTRL, 24, 2, 26, 1,
+ BIT(28), 0);
+static const char * const isp_bus_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d8_307p2",
+ "pll1_d10_245p76",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP_BUS, isp_bus_clk, isp_bus_clk,
+ isp_bus_parents, ARRAY_SIZE(isp_cpp_parents),
+ APMU_ISP_CLK_RES_CTRL,
+ APMU_ISP_CLK_RES_CTRL, 18, 3, BIT(23),
+ 21, 2, BIT(17), 0);
+static const char * const isp_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP, isp_clk, isp_clk, isp_parents,
+ ARRAY_SIZE(isp_parents),
+ APMU_ISP_CLK_RES_CTRL,
+ APMU_ISP_CLK_RES_CTRL,
+ 4, 3, BIT(7), 8, 2, BIT(1), 0);
+
+static const char * const dpumclk_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_MCLK, dpu_mclk, dpu_mclk,
+ dpumclk_parents, ARRAY_SIZE(dpumclk_parents),
+ APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,
+ 1, 4, BIT(29), 5, 3, BIT(0), 0);
+
+static const char * const dpuesc_parents[] = {
+ "pll1_d48_51p2_ap",
+ "pll1_d52_47p26",
+ "pll1_d96_25p6",
+ "pll1_d32_76p8",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_DPU_ESC, dpu_esc_clk, dpu_esc_clk, dpuesc_parents,
+ ARRAY_SIZE(dpuesc_parents), APMU_LCD_CLK_RES_CTRL1, 0, 2,
+ BIT(2), 0);
+
+static const char * const dpubit_parents[] = {
+ "pll1_d3_819p2",
+ "pll2_d2",
+ "pll2_d3",
+ "pll1_d2_1228p8",
+ "pll2_d4",
+ "pll2_d5",
+ "pll2_d7",
+ "pll2_d8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_BIT, dpu_bit_clk, dpu_bit_clk,
+ dpubit_parents, ARRAY_SIZE(dpubit_parents),
+ APMU_LCD_CLK_RES_CTRL1,
+ APMU_LCD_CLK_RES_CTRL1, 17, 3, BIT(31),
+ 20, 3, BIT(16), 0);
+
+static const char * const dpupx_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+ "pll2_d7",
+ "pll2_d8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_PXCLK, dpu_pxclk, dpu_pxclk,
+ dpupx_parents, ARRAY_SIZE(dpupx_parents),
+ APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,
+ 17, 4, BIT(30), 21, 3, BIT(16), 0);
+
+CCU_GATE_DEFINE(CLK_DPU_HCLK, dpu_hclk, dpu_hclk, "pmua_aclk",
+ APMU_LCD_CLK_RES_CTRL1, BIT(5), 0);
+
+static const char * const dpu_spi_parents[] = {
+ "pll1_d8_307p2",
+ "pll1_d6_409p6",
+ "pll1_d10_245p76",
+ "pll1_d11_223p4",
+ "pll1_d13_189",
+ "pll1_d23_106p8",
+ "pll2_d3",
+ "pll2_d5",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_SPI, dpu_spi_clk, dpu_spi_clk,
+ dpu_spi_parents, ARRAY_SIZE(dpu_spi_parents),
+ APMU_LCD_SPI_CLK_RES_CTRL,
+ APMU_LCD_SPI_CLK_RES_CTRL, 8, 3,
+ BIT(7), 12, 3, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_DPU_SPI_HBUS, dpu_spi_hbus_clk, dpu_spi_hbus_clk,
+ "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(3), 0);
+CCU_GATE_DEFINE(CLK_DPU_SPIBUS, dpu_spi_bus_clk, dpu_spi_bus_clk,
+ "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(5), 0);
+CCU_GATE_DEFINE(CLK_DPU_SPI_ACLK, dpu_spi_aclk, dpu_spi_aclk,
+ "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(6), 0);
+
+static const char * const v2d_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d6_409p6",
+ "pll1_d8_307p2",
+ "pll1_d4_614p4",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_V2D, v2d_clk, v2d_clk, v2d_parents,
+ ARRAY_SIZE(v2d_parents),
+ APMU_LCD_CLK_RES_CTRL1,
+ APMU_LCD_CLK_RES_CTRL1, 9, 3, BIT(28), 12, 2,
+ BIT(8), 0);
+
+static const char * const ccic_4x_parents[] = {
+ "pll1_d5_491p52",
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll1_d3_819p2",
+ "pll2_d2",
+ "pll2_d3",
+ "pll2_d4",
+ "pll1_d2_1228p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CCIC_4X, ccic_4x_clk, ccic_4x_clk,
+ ccic_4x_parents, ARRAY_SIZE(ccic_4x_parents),
+ APMU_CCIC_CLK_RES_CTRL,
+ APMU_CCIC_CLK_RES_CTRL, 18, 3,
+ BIT(15), 23, 2, BIT(4), 0);
+
+static const char * const ccic1phy_parents[] = {
+ "pll1_d24_102p4",
+ "pll1_d48_51p2_ap",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_CCIC1PHY, ccic1phy_clk, ccic1phy_clk, ccic1phy_parents,
+ ARRAY_SIZE(ccic1phy_parents), APMU_CCIC_CLK_RES_CTRL, 7, 1,
+ BIT(5), 0);
+
+CCU_GATE_DEFINE(CLK_SDH_AXI, sdh_axi_aclk, sdh_axi_aclk, "pmua_aclk",
+ APMU_SDH0_CLK_RES_CTRL, BIT(3), 0);
+static const char * const sdh01_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll2_d8",
+ "pll2_d5",
+ "pll1_d11_223p4",
+ "pll1_d13_189",
+ "pll1_d23_106p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH0, sdh0_clk, sdh0_clk, sdh01_parents,
+ ARRAY_SIZE(sdh01_parents),
+ APMU_SDH0_CLK_RES_CTRL,
+ APMU_SDH0_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH1, sdh1_clk, sdh1_clk, sdh01_parents,
+ ARRAY_SIZE(sdh01_parents),
+ APMU_SDH1_CLK_RES_CTRL,
+ APMU_SDH1_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+static const char * const sdh2_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d4_614p4",
+ "pll2_d8",
+ "pll1_d3_819p2",
+ "pll1_d11_223p4",
+ "pll1_d13_189",
+ "pll1_d23_106p8",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH2, sdh2_clk, sdh2_clk, sdh2_parents,
+ ARRAY_SIZE(sdh2_parents),
+ APMU_SDH2_CLK_RES_CTRL,
+ APMU_SDH2_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3,
+ BIT(4), 0);
+
+CCU_GATE_DEFINE(CLK_USB_AXI, usb_axi_clk, usb_axi_clk, "pmua_aclk",
+ APMU_USB_CLK_RES_CTRL, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_USB_P1, usb_p1_aclk, usb_p1_aclk, "pmua_aclk",
+ APMU_USB_CLK_RES_CTRL, BIT(5), 0);
+CCU_GATE_DEFINE(CLK_USB30, usb30_clk, usb30_clk, "pmua_aclk",
+ APMU_USB_CLK_RES_CTRL, BIT(8), 0);
+
+static const char * const qspi_parents[] = {
+ "pll1_d6_409p6",
+ "pll2_d8",
+ "pll1_d8_307p2",
+ "pll1_d10_245p76",
+ "pll1_d11_223p4",
+ "pll1_d23_106p8",
+ "pll1_d5_491p52",
+ "pll1_d13_189",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_QSPI, qspi_clk, qspi_clk, qspi_parents,
+ ARRAY_SIZE(qspi_parents),
+ APMU_QSPI_CLK_RES_CTRL,
+ APMU_QSPI_CLK_RES_CTRL, 9, 3, BIT(12), 6, 3,
+ BIT(4), 0);
+CCU_GATE_DEFINE(CLK_QSPI_BUS, qspi_bus_clk, qspi_bus_clk, "pmua_aclk",
+ APMU_QSPI_CLK_RES_CTRL, BIT(3), 0);
+CCU_GATE_DEFINE(CLK_DMA, dma_clk, dma_clk, "pmua_aclk", APMU_DMA_CLK_RES_CTRL,
+ BIT(3), 0);
+
+static const char * const aes_parents[] = {
+ "pll1_d12_204p8",
+ "pll1_d24_102p4",
+};
+
+CCU_MUX_GATE_DEFINE(CLK_AES, aes_clk, aes_clk, aes_parents,
+ ARRAY_SIZE(aes_parents), APMU_AES_CLK_RES_CTRL, 6, 1,
+ BIT(5), 0);
+
+static const char * const vpu_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d5_491p52",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll3_d6",
+ "pll2_d3",
+ "pll2_d4",
+ "pll2_d5",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_VPU, vpu_clk, vpu_clk, vpu_parents,
+ ARRAY_SIZE(vpu_parents), APMU_VPU_CLK_RES_CTRL,
+ APMU_VPU_CLK_RES_CTRL, 13, 3, BIT(21), 10, 3,
+ BIT(3), 0);
+
+static const char * const gpu_parents[] = {
+ "pll1_d4_614p4",
+ "pll1_d5_491p52",
+ "pll1_d3_819p2",
+ "pll1_d6_409p6",
+ "pll3_d6",
+ "pll2_d3",
+ "pll2_d4",
+ "pll2_d5",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_GPU, gpu_clk, gpu_clk, gpu_parents,
+ ARRAY_SIZE(gpu_parents), APMU_GPU_CLK_RES_CTRL,
+ APMU_GPU_CLK_RES_CTRL, 12, 3, BIT(15), 18, 3,
+ BIT(4), 0);
+
+static const char * const audio_parents[] = {
+ "pll1_aud_245p7",
+ "pll1_d8_307p2",
+ "pll1_d6_409p6",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_AUDIO, audio_clk, audio_clk, audio_parents,
+ ARRAY_SIZE(audio_parents),
+ APMU_AUDIO_CLK_RES_CTRL,
+ APMU_AUDIO_CLK_RES_CTRL, 4, 3, BIT(15),
+ 7, 3, BIT(12), 0);
+
+static const char * const hdmi_parents[] = {
+ "pll1_d6_409p6",
+ "pll1_d5_491p52",
+ "pll1_d4_614p4",
+ "pll1_d8_307p2",
+};
+
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_HDMI, hdmi_mclk, hdmi_mclk, hdmi_parents,
+ ARRAY_SIZE(hdmi_parents),
+ APMU_HDMI_CLK_RES_CTRL,
+ APMU_HDMI_CLK_RES_CTRL, 1, 4, BIT(29), 5,
+ 3, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PCIE0_MASTER, pcie0_master_clk, pcie0_master_clk,
+ "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_0, BIT(2), 0);
+CCU_GATE_DEFINE(CLK_PCIE0_SLAVE, pcie0_slave_clk, pcie0_slave_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_0, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_PCIE0_DBI, pcie0_dbi_clk, pcie0_dbi_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_0, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PCIE1_MASTER, pcie1_master_clk, pcie1_master_clk,
+ "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_1, BIT(2), 0);
+CCU_GATE_DEFINE(CLK_PCIE1_SLAVE, pcie1_slave_clk, pcie1_slave_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_1, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_PCIE1_DBI, pcie1_dbi_clk, pcie1_dbi_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_1, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_PCIE2_MASTER, pcie2_master_clk, pcie2_master_clk,
+ "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_2, BIT(2), 0);
+CCU_GATE_DEFINE(CLK_PCIE2_SLAVE, pcie2_slave_clk, pcie2_slave_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_2, BIT(1), 0);
+CCU_GATE_DEFINE(CLK_PCIE2_DBI, pcie2_dbi_clk, pcie2_dbi_clk, "pmua_aclk",
+ APMU_PCIE_CLK_RES_CTRL_2, BIT(0), 0);
+
+CCU_GATE_DEFINE(CLK_EMAC0_BUS, emac0_bus_clk, emac0_bus_clk, "pmua_aclk",
+ APMU_EMAC0_CLK_RES_CTRL, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_EMAC0_PTP, emac0_ptp_clk, emac0_ptp_clk, "pll2_d6",
+ APMU_EMAC0_CLK_RES_CTRL, BIT(15), 0);
+CCU_GATE_DEFINE(CLK_EMAC1_BUS, emac1_bus_clk, emac1_bus_clk, "pmua_aclk",
+ APMU_EMAC1_CLK_RES_CTRL, BIT(0), 0);
+CCU_GATE_DEFINE(CLK_EMAC1_PTP, emac1_ptp_clk, emac1_ptp_clk, "pll2_d6",
+ APMU_EMAC1_CLK_RES_CTRL, BIT(15), 0);
+
+#endif
+/* APMU clocks end */
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_pll_clks[] = {
+ &pll1.common.clk,
+ &pll1_d4.common.clk,
+ &pll1_d6.common.clk,
+ &pll1_d8.common.clk,
+};
+#else
+static struct clk *k1_ccu_pll_clks[] = {
+ &pll1.common.clk,
+ &pll2.common.clk,
+ &pll3.common.clk,
+ &pll1_d2.common.clk,
+ &pll1_d3.common.clk,
+ &pll1_d4.common.clk,
+ &pll1_d5.common.clk,
+ &pll1_d6.common.clk,
+ &pll1_d7.common.clk,
+ &pll1_d8.common.clk,
+ &pll1_d11_223p4.common.clk,
+ &pll1_d13_189.common.clk,
+ &pll1_d23_106p8.common.clk,
+ &pll1_d64_38p4.common.clk,
+ &pll1_aud_245p7.common.clk,
+ &pll1_aud_24p5.common.clk,
+ &pll2_d1.common.clk,
+ &pll2_d2.common.clk,
+ &pll2_d3.common.clk,
+ &pll2_d4.common.clk,
+ &pll2_d5.common.clk,
+ &pll2_d6.common.clk,
+ &pll2_d7.common.clk,
+ &pll2_d8.common.clk,
+ &pll3_d1.common.clk,
+ &pll3_d2.common.clk,
+ &pll3_d3.common.clk,
+ &pll3_d4.common.clk,
+ &pll3_d5.common.clk,
+ &pll3_d6.common.clk,
+ &pll3_d7.common.clk,
+ &pll3_d8.common.clk,
+ &pll3_80.common.clk,
+ &pll3_40.common.clk,
+ &pll3_20.common.clk,
+};
+#endif
+
+static const struct spacemit_ccu_data k1_ccu_pll_data = {
+ .clks = k1_ccu_pll_clks,
+ .num = ARRAY_SIZE(k1_ccu_pll_clks),
+ .offset = K1_PLL_ID,
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_mpmu_clks[] = {
+ &pll1_d4_614p4.common.clk,
+ &pll1_d6_409p6.common.clk,
+ &pll1_d8_307p2.common.clk,
+ &pll1_d78_31p5.common.clk,
+ &slow_uart2_48.common.clk,
+};
+#else
+static struct clk *k1_ccu_mpmu_clks[] = {
+ &pll1_d8_307p2.common.clk,
+ &pll1_d32_76p8.common.clk,
+ &pll1_d40_61p44.common.clk,
+ &pll1_d16_153p6.common.clk,
+ &pll1_d24_102p4.common.clk,
+ &pll1_d48_51p2.common.clk,
+ &pll1_d48_51p2_ap.common.clk,
+ &pll1_m3d128_57p6.common.clk,
+ &pll1_d96_25p6.common.clk,
+ &pll1_d192_12p8.common.clk,
+ &pll1_d192_12p8_wdt.common.clk,
+ &pll1_d384_6p4.common.clk,
+ &pll1_d768_3p2.common.clk,
+ &pll1_d1536_1p6.common.clk,
+ &pll1_d3072_0p8.common.clk,
+ &pll1_d6_409p6.common.clk,
+ &pll1_d12_204p8.common.clk,
+ &pll1_d5_491p52.common.clk,
+ &pll1_d10_245p76.common.clk,
+ &pll1_d4_614p4.common.clk,
+ &pll1_d52_47p26.common.clk,
+ &pll1_d78_31p5.common.clk,
+ &pll1_d3_819p2.common.clk,
+ &pll1_d2_1228p8.common.clk,
+ &slow_uart.common.clk,
+ &slow_uart1_14p74.common.clk,
+ &slow_uart2_48.common.clk,
+ &wdt_clk.common.clk,
+ &apb_clk.common.clk,
+ &ripc_clk.common.clk,
+ &i2s_153p6.common.clk,
+ &i2s_153p6_base.common.clk,
+ &i2s_sysclk_src.common.clk,
+ &i2s_sysclk.common.clk,
+ &i2s_bclk_factor.common.clk,
+ &i2s_bclk.common.clk,
+ &wdt_bus_clk.common.clk,
+};
+#endif
+
+static const struct spacemit_ccu_data k1_ccu_mpmu_data = {
+ .clks = k1_ccu_mpmu_clks,
+ .num = ARRAY_SIZE(k1_ccu_mpmu_clks),
+ .offset = K1_MPMU_ID,
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_apbc_clks[] = {
+ &uart0_clk.common.clk,
+ &twsi2_clk.common.clk,
+ &twsi8_clk.common.clk,
+};
+#else
+static struct clk *k1_ccu_apbc_clks[] = {
+ &uart0_clk.common.clk,
+ &uart2_clk.common.clk,
+ &uart3_clk.common.clk,
+ &uart4_clk.common.clk,
+ &uart5_clk.common.clk,
+ &uart6_clk.common.clk,
+ &uart7_clk.common.clk,
+ &uart8_clk.common.clk,
+ &uart9_clk.common.clk,
+ &gpio_clk.common.clk,
+ &pwm0_clk.common.clk,
+ &pwm1_clk.common.clk,
+ &pwm2_clk.common.clk,
+ &pwm3_clk.common.clk,
+ &pwm4_clk.common.clk,
+ &pwm5_clk.common.clk,
+ &pwm6_clk.common.clk,
+ &pwm7_clk.common.clk,
+ &pwm8_clk.common.clk,
+ &pwm9_clk.common.clk,
+ &pwm10_clk.common.clk,
+ &pwm11_clk.common.clk,
+ &pwm12_clk.common.clk,
+ &pwm13_clk.common.clk,
+ &pwm14_clk.common.clk,
+ &pwm15_clk.common.clk,
+ &pwm16_clk.common.clk,
+ &pwm17_clk.common.clk,
+ &pwm18_clk.common.clk,
+ &pwm19_clk.common.clk,
+ &ssp3_clk.common.clk,
+ &rtc_clk.common.clk,
+ &twsi0_clk.common.clk,
+ &twsi1_clk.common.clk,
+ &twsi2_clk.common.clk,
+ &twsi4_clk.common.clk,
+ &twsi5_clk.common.clk,
+ &twsi6_clk.common.clk,
+ &twsi7_clk.common.clk,
+ &twsi8_clk.common.clk,
+ &timers1_clk.common.clk,
+ &timers2_clk.common.clk,
+ &aib_clk.common.clk,
+ &onewire_clk.common.clk,
+ &sspa0_clk.common.clk,
+ &sspa1_clk.common.clk,
+ &dro_clk.common.clk,
+ &ir_clk.common.clk,
+ &tsen_clk.common.clk,
+ &ipc_ap2aud_clk.common.clk,
+ &can0_clk.common.clk,
+ &can0_bus_clk.common.clk,
+ &uart0_bus_clk.common.clk,
+ &uart2_bus_clk.common.clk,
+ &uart3_bus_clk.common.clk,
+ &uart4_bus_clk.common.clk,
+ &uart5_bus_clk.common.clk,
+ &uart6_bus_clk.common.clk,
+ &uart7_bus_clk.common.clk,
+ &uart8_bus_clk.common.clk,
+ &uart9_bus_clk.common.clk,
+ &gpio_bus_clk.common.clk,
+ &pwm0_bus_clk.common.clk,
+ &pwm1_bus_clk.common.clk,
+ &pwm2_bus_clk.common.clk,
+ &pwm3_bus_clk.common.clk,
+ &pwm4_bus_clk.common.clk,
+ &pwm5_bus_clk.common.clk,
+ &pwm6_bus_clk.common.clk,
+ &pwm7_bus_clk.common.clk,
+ &pwm8_bus_clk.common.clk,
+ &pwm9_bus_clk.common.clk,
+ &pwm10_bus_clk.common.clk,
+ &pwm11_bus_clk.common.clk,
+ &pwm12_bus_clk.common.clk,
+ &pwm13_bus_clk.common.clk,
+ &pwm14_bus_clk.common.clk,
+ &pwm15_bus_clk.common.clk,
+ &pwm16_bus_clk.common.clk,
+ &pwm17_bus_clk.common.clk,
+ &pwm18_bus_clk.common.clk,
+ &pwm19_bus_clk.common.clk,
+ &ssp3_bus_clk.common.clk,
+ &rtc_bus_clk.common.clk,
+ &twsi0_bus_clk.common.clk,
+ &twsi1_bus_clk.common.clk,
+ &twsi2_bus_clk.common.clk,
+ &twsi4_bus_clk.common.clk,
+ &twsi5_bus_clk.common.clk,
+ &twsi6_bus_clk.common.clk,
+ &twsi7_bus_clk.common.clk,
+ &twsi8_bus_clk.common.clk,
+ &timers1_bus_clk.common.clk,
+ &timers2_bus_clk.common.clk,
+ &aib_bus_clk.common.clk,
+ &onewire_bus_clk.common.clk,
+ &sspa0_bus_clk.common.clk,
+ &sspa1_bus_clk.common.clk,
+ &tsen_bus_clk.common.clk,
+ &ipc_ap2aud_bus_clk.common.clk,
+ &sspa0_i2s_bclk.common.clk,
+ &sspa1_i2s_bclk.common.clk,
+};
+#endif
+
+static const struct spacemit_ccu_data k1_ccu_apbc_data = {
+ .clks = k1_ccu_apbc_clks,
+ .num = ARRAY_SIZE(k1_ccu_apbc_clks),
+ .offset = K1_APBC_ID,
+};
+
+#if IS_ENABLED(CONFIG_SPL_BUILD)
+static struct clk *k1_ccu_apmu_clks[] = {
+ &pmua_aclk.common.clk,
+ &sdh_axi_aclk.common.clk,
+ &sdh0_clk.common.clk,
+ &sdh2_clk.common.clk,
+};
+#else
+static struct clk *k1_ccu_apmu_clks[] = {
+ &cci550_clk.common.clk,
+ &cpu_c0_hi_clk.common.clk,
+ &cpu_c0_core_clk.common.clk,
+ &cpu_c0_ace_clk.common.clk,
+ &cpu_c0_tcm_clk.common.clk,
+ &cpu_c1_hi_clk.common.clk,
+ &cpu_c1_core_clk.common.clk,
+ &cpu_c1_ace_clk.common.clk,
+ &ccic_4x_clk.common.clk,
+ &ccic1phy_clk.common.clk,
+ &pmua_aclk.common.clk,
+ &sdh_axi_aclk.common.clk,
+ &sdh0_clk.common.clk,
+ &sdh1_clk.common.clk,
+ &sdh2_clk.common.clk,
+ &usb_p1_aclk.common.clk,
+ &usb_axi_clk.common.clk,
+ &usb30_clk.common.clk,
+ &qspi_clk.common.clk,
+ &qspi_bus_clk.common.clk,
+ &dma_clk.common.clk,
+ &aes_clk.common.clk,
+ &vpu_clk.common.clk,
+ &gpu_clk.common.clk,
+ &emmc_clk.common.clk,
+ &emmc_x_clk.common.clk,
+ &audio_clk.common.clk,
+ &hdmi_mclk.common.clk,
+ &pcie0_master_clk.common.clk,
+ &pcie0_slave_clk.common.clk,
+ &pcie0_dbi_clk.common.clk,
+ &pcie1_master_clk.common.clk,
+ &pcie1_slave_clk.common.clk,
+ &pcie1_dbi_clk.common.clk,
+ &pcie2_master_clk.common.clk,
+ &pcie2_slave_clk.common.clk,
+ &pcie2_dbi_clk.common.clk,
+ &emac0_bus_clk.common.clk,
+ &emac0_ptp_clk.common.clk,
+ &emac1_bus_clk.common.clk,
+ &emac1_ptp_clk.common.clk,
+ &jpg_clk.common.clk,
+ &ccic2phy_clk.common.clk,
+ &ccic3phy_clk.common.clk,
+ &csi_clk.common.clk,
+ &camm0_clk.common.clk,
+ &camm1_clk.common.clk,
+ &camm2_clk.common.clk,
+ &isp_cpp_clk.common.clk,
+ &isp_bus_clk.common.clk,
+ &isp_clk.common.clk,
+ &dpu_mclk.common.clk,
+ &dpu_esc_clk.common.clk,
+ &dpu_bit_clk.common.clk,
+ &dpu_pxclk.common.clk,
+ &dpu_hclk.common.clk,
+ &dpu_spi_clk.common.clk,
+ &dpu_spi_hbus_clk.common.clk,
+ &dpu_spi_bus_clk.common.clk,
+ &dpu_spi_aclk.common.clk,
+ &v2d_clk.common.clk,
+ &emmc_bus_clk.common.clk,
+};
+#endif
+
+static int clk_k1_enable(struct clk *clk)
+{
+ const struct spacemit_ccu_data *data;
+ struct clk *c;
+ struct clk *pclk;
+ int ret, i;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev);
+ for (i = 0; i < data->num; i++) {
+ if (clk->id == data->clks[i]->id) {
+ c = data->clks[i];
+ break;
+ }
+ }
+ if (i == data->num)
+ c = clk;
+
+ pclk = clk_get_parent(c);
+ if (!IS_ERR_OR_NULL(pclk)) {
+ ret = ccf_clk_enable(pclk);
+ if (ret)
+ return ret;
+ }
+ ret = ccu_gate_enable(c);
+ return ret;
+}
+
+static int clk_k1_disable(struct clk *clk)
+{
+ const struct spacemit_ccu_data *data;
+ struct clk *c;
+ struct clk *pclk;
+ int ret, i;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev);
+ for (i = 0; i < data->num; i++) {
+ if (clk->id == data->clks[i]->id) {
+ c = data->clks[i];
+ break;
+ }
+ }
+ if (i == data->num)
+ c = clk;
+
+ pclk = clk_get_parent(c);
+ if (!IS_ERR_OR_NULL(pclk)) {
+ ret = ccf_clk_disable(pclk);
+ if (ret)
+ return ret;
+ }
+ ret = ccu_gate_disable(c);
+ return ret;
+}
+
+#define K1_CLK_OPS(name) \
+static const struct clk_ops k1_##name##_clk_ops = { \
+ .set_rate = ccf_clk_set_rate, \
+ .get_rate = ccf_clk_get_rate, \
+ .enable = clk_k1_enable, \
+ .disable = clk_k1_disable, \
+ .set_parent = ccf_clk_set_parent, \
+ .of_xlate = k1_##name##_clk_of_xlate, \
+}
+
+static const struct spacemit_ccu_data k1_ccu_apmu_data = {
+ .clks = k1_ccu_apmu_clks,
+ .num = ARRAY_SIZE(k1_ccu_apmu_clks),
+ .offset = K1_APMU_ID,
+};
+
+/*
+ * The K1 clock providers are split across separate syscon devices (PLL,
+ * MPMU, APMU, APBC) whose clocks parent across device boundaries. U-Boot's
+ * CCF resolves a parent by name at registration time and silently binds an
+ * orphan if the parent is not registered yet, so a controller must not
+ * register its clocks before the controllers owning its parents have probed.
+ * Force the parent controller to probe by its driver: this is robust against
+ * device tree node/phandle ordering and needs no helper "clocks" wiring in
+ * the syscon nodes.
+ */
+static int k1_clk_force_probe(const struct driver *drv)
+{
+ struct udevice *dev;
+
+ return uclass_get_device_by_driver(UCLASS_CLK, drv, &dev);
+}
+
+static int k1_clk_register(struct udevice *dev, struct regmap *regmap,
+ struct regmap *lock_regmap,
+ const struct spacemit_ccu_data *data)
+{
+ int i, ret;
+
+ for (i = 0; i < data->num; i++) {
+ struct clk *clk = data->clks[i];
+ struct ccu_common *common;
+
+ if (!clk)
+ continue;
+
+ common = clk_to_ccu_common(clk);
+ common->regmap = regmap;
+ common->lock_regmap = lock_regmap;
+
+ if (common->clk.id < K1_PLL_ID)
+ clk->id = common->clk.id + data->offset;
+ else
+ clk->id = common->clk.id;
+
+ ret = common->init(common);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int k1_pll_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ clk_register_fixed_rate(NULL, "clock-dummy", 0);
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ /*
+ * The lock status of PLLs locate in MPMU region, while PLLs themselves
+ * are in APBS region. Reference to MPMU syscon is required to check PLL
+ * status.
+ */
+ if (device_is_compatible(dev, "spacemit,k1-pll")) {
+ struct ofnode_phandle_args mpmu_args;
+
+ ret = dev_read_phandle_with_args(dev, "spacemit,mpmu", NULL, 0, 0,
+ &mpmu_args);
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(mpmu_args.node, &lock_regmap);
+ if (ret)
+ return ret;
+ }
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_mpmu_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ /* MPMU clocks parent off the PLL controller */
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_pll_clk));
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_apmu_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ /* APMU clocks parent off the PLL and MPMU controllers */
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_pll_clk));
+ if (ret)
+ return ret;
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_mpmu_clk));
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_apbc_clk_probe(struct udevice *dev)
+{
+ struct regmap *base_regmap, *lock_regmap = NULL;
+ const struct spacemit_ccu_data *data;
+ int ret;
+
+ /* APBC clocks parent off the PLL, MPMU and APMU controllers */
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_pll_clk));
+ if (ret)
+ return ret;
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_mpmu_clk));
+ if (ret)
+ return ret;
+ ret = k1_clk_force_probe(DM_DRIVER_GET(k1_apmu_clk));
+ if (ret)
+ return ret;
+
+ ret = regmap_init_mem(dev_ofnode(dev), &base_regmap);
+ if (ret)
+ return ret;
+
+ data = (struct spacemit_ccu_data *)dev_get_driver_data(dev);
+
+ ret = k1_clk_register(dev, base_regmap, lock_regmap, data);
+ if (ret)
+ return -EPROBE_DEFER;
+
+ return 0;
+}
+
+static int k1_pll_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_PLL_ID + args->args[0];
+ else
+ clk->id = K1_PLL_ID;
+
+ return 0;
+}
+
+static int k1_mpmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_MPMU_ID + args->args[0];
+ else
+ clk->id = K1_MPMU_ID;
+
+ return 0;
+}
+
+static int k1_apbc_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_APBC_ID + args->args[0];
+ else
+ clk->id = K1_APBC_ID;
+
+ return 0;
+}
+
+static int k1_apmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+ if (args->args_count > 1) {
+ debug("Invalid args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ if (args->args_count)
+ clk->id = K1_APMU_ID + args->args[0];
+ else
+ clk->id = K1_APMU_ID;
+
+ return 0;
+}
+
+static const struct udevice_id k1_pll_clk_match[] = {
+ { .compatible = "spacemit,k1-pll",
+ .data = (ulong)&k1_ccu_pll_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(pll);
+
+U_BOOT_DRIVER(k1_pll_clk) = {
+ .name = "k1_pll_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_pll_clk_match,
+ .probe = k1_pll_clk_probe,
+ .ops = &k1_pll_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static int k1_mpmu_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_MPMU);
+}
+
+static int k1_apbc_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_APBC);
+}
+
+static int k1_apmu_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_APMU);
+}
+
+static int k1_apbc2_clk_bind(struct udevice *dev)
+{
+ return spacemit_k1_reset_bind(dev, SPACEMIT_K1_RESET_APBC2);
+}
+
+static const struct udevice_id k1_mpmu_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-mpmu",
+ .data = (ulong)&k1_ccu_mpmu_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(mpmu);
+
+U_BOOT_DRIVER(k1_mpmu_clk) = {
+ .name = "k1_mpmu_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_mpmu_clk_match,
+ .bind = k1_mpmu_clk_bind,
+ .probe = k1_mpmu_clk_probe,
+ .ops = &k1_mpmu_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id k1_apbc_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-apbc",
+ .data = (ulong)&k1_ccu_apbc_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(apbc);
+
+U_BOOT_DRIVER(k1_apbc_clk) = {
+ .name = "k1_apbc_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_apbc_clk_match,
+ .bind = k1_apbc_clk_bind,
+ .probe = k1_apbc_clk_probe,
+ .ops = &k1_apbc_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id k1_apmu_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-apmu",
+ .data = (ulong)&k1_ccu_apmu_data },
+ { /* sentinel */ },
+};
+
+K1_CLK_OPS(apmu);
+
+U_BOOT_DRIVER(k1_apmu_clk) = {
+ .name = "k1_apmu_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_apmu_clk_match,
+ .bind = k1_apmu_clk_bind,
+ .probe = k1_apmu_clk_probe,
+ .ops = &k1_apmu_clk_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id k1_apbc2_clk_match[] = {
+ { .compatible = "spacemit,k1-syscon-apbc2" },
+ { /* sentinel */ },
+};
+
+U_BOOT_DRIVER(k1_apbc2_clk) = {
+ .name = "k1_apbc2_clk",
+ .id = UCLASS_CLK,
+ .of_match = k1_apbc2_clk_match,
+ .bind = k1_apbc2_clk_bind,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_common.h b/drivers/clk/spacemit/clk_common.h
new file mode 100644
index 00000000000..ea5ebf57784
--- /dev/null
+++ b/drivers/clk/spacemit/clk_common.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_COMMON_H_
+#define _CLK_COMMON_H_
+
+#include <linux/clk-provider.h>
+
+struct ccu_common;
+
+typedef int (*ccu_init_fn)(struct ccu_common *common);
+
+struct ccu_common {
+ struct regmap *regmap;
+ struct regmap *lock_regmap;
+ const char *name;
+ const char * const *parents;
+ size_t num_parents;
+ ccu_init_fn init;
+
+ union {
+ /* For DDN and MIX */
+ struct {
+ u32 reg_ctrl;
+ u32 reg_fc;
+ u32 mask_fc;
+ };
+
+ /* For PLL */
+ struct {
+ u32 reg_swcr1;
+ u32 reg_swcr3;
+ };
+ };
+
+ struct clk clk;
+};
+
+#define CCU_COMMON(_id, _name, _parent, _init, _flags) \
+ .name = #_name, \
+ .parents = (const char *[]) { _parent }, \
+ .num_parents = 1, \
+ .init = _init, \
+ .clk = { .flags = _flags, .id = _id, } \
+
+#define CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, _init, _flags) \
+ .name = #_name, \
+ .parents = _parents, \
+ .num_parents = _num_p, \
+ .init = _init, \
+ .clk = { .flags = _flags, .id = _id, } \
+
+static inline struct ccu_common *clk_to_ccu_common(struct clk *clk)
+{
+ return container_of(clk, struct ccu_common, clk);
+}
+
+#define ccu_read(c, reg) \
+ ({ \
+ struct ccu_common * const __ccu = (c); \
+ u32 tmp; \
+ regmap_read(__ccu->regmap, __ccu->reg_##reg, &tmp); \
+ tmp; \
+ })
+#define ccu_update(c, reg, mask, val) \
+ ({ \
+ struct ccu_common * const __ccu = (c); \
+ regmap_update_bits(__ccu->regmap, __ccu->reg_##reg, \
+ mask, val); \
+ })
+
+#endif /* _CLK_COMMON_H_ */
diff --git a/drivers/clk/spacemit/clk_ddn.c b/drivers/clk/spacemit/clk_ddn.c
new file mode 100644
index 00000000000..7b93f30d5c3
--- /dev/null
+++ b/drivers/clk/spacemit/clk_ddn.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Authors: Haylen Chu <[email protected]>
+ *
+ * DDN stands for "Divider Denominator Numerator", it's M/N clock with a
+ * constant x2 factor. This clock hardware follows the equation below,
+ *
+ * numerator Fin
+ * 2 * ------------- = -------
+ * denominator Fout
+ *
+ * Thus, Fout could be calculated with,
+ *
+ * Fin denominator
+ * Fout = ----- * -------------
+ * 2 numerator
+ */
+
+#include <dm/device.h>
+#include <regmap.h>
+#include <linux/clk-provider.h>
+#include <linux/rational.h>
+
+#include "clk_ddn.h"
+
+#define UBOOT_DM_SPACEMIT_CLK_DDN "spacemit_clk_ddn"
+
+static unsigned long ccu_ddn_calc_rate(unsigned long prate, unsigned long num,
+ unsigned long den, unsigned int pre_div)
+{
+ return prate * den / pre_div / num;
+}
+
+static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn,
+ unsigned long rate, unsigned long prate,
+ unsigned long *num, unsigned long *den)
+{
+ rational_best_approximation(rate, prate / ddn->pre_div,
+ ddn->den_mask >> ddn->den_shift,
+ ddn->num_mask >> ddn->num_shift,
+ den, num);
+ return ccu_ddn_calc_rate(prate, *num, *den, ddn->pre_div);
+}
+
+static unsigned long ccu_ddn_recalc_rate(struct clk *clk)
+{
+ struct ccu_ddn *ddn = clk_to_ccu_ddn(clk);
+ unsigned int val, num, den;
+
+ val = ccu_read(&ddn->common, ctrl);
+
+ num = (val & ddn->num_mask) >> ddn->num_shift;
+ den = (val & ddn->den_mask) >> ddn->den_shift;
+
+ return ccu_ddn_calc_rate(clk_get_parent_rate(clk), num, den, ddn->pre_div);
+}
+
+static unsigned long ccu_ddn_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct ccu_ddn *ddn = clk_to_ccu_ddn(clk);
+ unsigned long num, den;
+
+ ccu_ddn_calc_best_rate(ddn, rate, clk_get_parent_rate(clk), &num, &den);
+
+ ccu_update(&ddn->common, ctrl,
+ ddn->num_mask | ddn->den_mask,
+ (num << ddn->num_shift) | (den << ddn->den_shift));
+
+ return 0;
+}
+
+static const struct clk_ops spacemit_clk_ddn_ops = {
+ .get_rate = ccu_ddn_recalc_rate,
+ .set_rate = ccu_ddn_set_rate,
+};
+
+int spacemit_ddn_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DDN,
+ common->name, common->parents[0]);
+}
+
+U_BOOT_DRIVER(spacemit_clk_ddn) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_DDN,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_ddn_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_ddn.h b/drivers/clk/spacemit/clk_ddn.h
new file mode 100644
index 00000000000..1330ced23b1
--- /dev/null
+++ b/drivers/clk/spacemit/clk_ddn.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_DDN_H_
+#define _CLK_DDN_H_
+
+#include <linux/clk-provider.h>
+
+#include "clk_common.h"
+
+struct ccu_ddn {
+ struct ccu_common common;
+ unsigned int num_mask;
+ unsigned int num_shift;
+ unsigned int den_mask;
+ unsigned int den_shift;
+ unsigned int pre_div;
+};
+
+#define CCU_DDN_MASK(_num_shift, _num_width) \
+ GENMASK((_num_shift) + (_num_width) - 1, _num_shift)
+
+#define CCU_DDN_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _num_mask, \
+ _num_shift, _den_mask, _den_shift, _pre_div, _flags) \
+static struct ccu_ddn _var = { \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, spacemit_ddn_init, _flags) \
+ }, \
+ .num_mask = _num_mask, \
+ .num_shift = _num_shift, \
+ .den_mask = _den_mask, \
+ .den_shift = _den_shift, \
+ .pre_div = _pre_div, \
+}
+
+static inline struct ccu_ddn *clk_to_ccu_ddn(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ return container_of(common, struct ccu_ddn, common);
+}
+
+int spacemit_ddn_init(struct ccu_common *common);
+
+#endif /* _CLK_DDN_H_ */
diff --git a/drivers/clk/spacemit/clk_mix.c b/drivers/clk/spacemit/clk_mix.c
new file mode 100644
index 00000000000..a1158512a92
--- /dev/null
+++ b/drivers/clk/spacemit/clk_mix.c
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Authors: Haylen Chu <[email protected]>
+ *
+ * MIX clock type is the combination of mux, factor or divider, and gate
+ */
+
+#include <dm/device.h>
+#include <dm/uclass.h>
+#include <div64.h>
+#include <regmap.h>
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+
+#include "clk_mix.h"
+
+#define UBOOT_DM_SPACEMIT_CLK_GATE "spacemit_clk_gate"
+#define UBOOT_DM_SPACEMIT_CLK_FACTOR "spacemit_clk_factor"
+#define UBOOT_DM_SPACEMIT_CLK_MUX "spacemit_clk_mux"
+#define UBOOT_DM_SPACEMIT_CLK_DIV "spacemit_clk_div"
+#define UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE "spacemit_clk_factor_gate"
+#define UBOOT_DM_SPACEMIT_CLK_MUX_GATE "spacemit_clk_mux_gate"
+#define UBOOT_DM_SPACEMIT_CLK_DIV_GATE "spacemit_clk_div_gate"
+#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV "spacemit_clk_mux_div"
+#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE "spacemit_clk_mux_div_gate"
+
+#define MIX_FC_TIMEOUT_US 10000
+#define MIX_FC_DELAY_US 5
+
+int ccu_gate_disable(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+
+ ccu_update(&mix->common, ctrl, mix->gate.mask, 0);
+
+ return 0;
+}
+
+int ccu_gate_enable(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_gate_config *gate = &mix->gate;
+
+ ccu_update(&mix->common, ctrl, gate->mask, gate->mask);
+
+ return 0;
+}
+
+static unsigned long ccu_factor_recalc_rate(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+
+ return clk_get_parent_rate(clk) * mix->factor.mul / mix->factor.div;
+}
+
+static unsigned long ccu_div_recalc_rate(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_div_config *div = &mix->div;
+ unsigned long val;
+
+ val = ccu_read(&mix->common, ctrl) >> div->shift;
+ val &= (1 << div->width) - 1;
+
+ return divider_recalc_rate(clk, clk_get_parent_rate(clk), val, NULL, 0, div->width);
+}
+
+/*
+ * Some clocks require a "FC" (frequency change) bit to be set after changing
+ * their rates or reparenting. This bit will be automatically cleared by
+ * hardware in MIX_FC_TIMEOUT_US, which indicates the operation is completed.
+ */
+static int ccu_mix_trigger_fc(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+ unsigned int val;
+
+ if (common->reg_fc)
+ return 0;
+
+ ccu_update(common, fc, common->mask_fc, common->mask_fc);
+
+ return regmap_read_poll_timeout(common->regmap, common->reg_fc,
+ val, !(val & common->mask_fc),
+ MIX_FC_DELAY_US,
+ MIX_FC_TIMEOUT_US);
+}
+
+static unsigned long
+ccu_mix_calc_best_rate(struct clk *clk, unsigned long rate,
+ struct clk **best_parent,
+ unsigned long *best_parent_rate,
+ u32 *div_val)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ unsigned int parent_num = common->num_parents;
+ struct ccu_div_config *div = &mix->div;
+ u32 div_max = 1 << div->width;
+ unsigned long best_rate = 0;
+
+ for (int i = 0; i < parent_num; i++) {
+ struct udevice *parent_dev;
+ unsigned long parent_rate;
+ struct clk *parent;
+
+ if (uclass_get_device_by_name(UCLASS_CLK, common->parents[i],
+ &parent_dev))
+ continue;
+ parent = dev_get_clk_ptr(parent_dev);
+ if (!parent)
+ continue;
+
+ parent_rate = clk_get_rate(parent);
+
+ for (int j = 1; j <= div_max; j++) {
+ unsigned long tmp = DIV_ROUND_CLOSEST_ULL(parent_rate, j);
+
+ if (abs(tmp - rate) < abs(best_rate - rate)) {
+ best_rate = tmp;
+
+ if (div_val)
+ *div_val = j - 1;
+
+ if (best_parent) {
+ *best_parent = parent;
+ *best_parent_rate = parent_rate;
+ }
+ }
+ }
+ }
+
+ return best_rate;
+}
+
+static unsigned long ccu_mix_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_common *common = &mix->common;
+ struct ccu_div_config *div = &mix->div;
+ u32 current_div, target_div, mask;
+
+ ccu_mix_calc_best_rate(clk, rate, NULL, NULL, &target_div);
+
+ current_div = ccu_read(common, ctrl) >> div->shift;
+ current_div &= (1 << div->width) - 1;
+
+ if (current_div == target_div)
+ return 0;
+
+ mask = GENMASK(div->width + div->shift - 1, div->shift);
+
+ ccu_update(common, ctrl, mask, target_div << div->shift);
+
+ return ccu_mix_trigger_fc(clk);
+}
+
+static u8 ccu_mux_get_parent(struct clk *clk)
+{
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_mux_config *mux = &mix->mux;
+ u8 parent;
+
+ parent = ccu_read(&mix->common, ctrl) >> mux->shift;
+ parent &= (1 << mux->width) - 1;
+
+ return parent;
+}
+
+static int ccu_mux_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+ struct ccu_mix *mix = clk_to_ccu_mix(clk);
+ struct ccu_mux_config *mux = &mix->mux;
+ u32 mask;
+ int i = 0;
+
+ mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
+
+ for (i = 0; i < common->num_parents; i++) {
+ if (!strcmp(parent->dev->name, common->parents[i]))
+ break;
+ }
+
+ if (i == common->num_parents)
+ return -EINVAL;
+
+ ccu_update(&mix->common, ctrl, mask, i << mux->shift);
+
+ return ccu_mix_trigger_fc(clk);
+}
+
+int spacemit_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_GATE,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .get_rate = clk_generic_get_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_factor_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_factor_ops = {
+ .get_rate = ccu_factor_recalc_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_factor) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_FACTOR,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_factor_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_ops = {
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = clk_generic_get_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_div_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_div_ops = {
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_div) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_DIV,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_div_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_factor_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_factor_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .get_rate = ccu_factor_recalc_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_factor_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_factor_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_GATE,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = clk_generic_get_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_div_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV_GATE,
+ common->name, common->parents[0]);
+}
+
+static const struct clk_ops spacemit_clk_div_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_div_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_DIV_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_div_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_div_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_div_ops = {
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux_div) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX_DIV,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_div_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_mux_div_gate_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ u8 index;
+
+ index = ccu_mux_get_parent(clk);
+ if (index >= common->num_parents)
+ index = 0;
+
+ return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE,
+ common->name, common->parents[index]);
+}
+
+static const struct clk_ops spacemit_clk_mux_div_gate_ops = {
+ .disable = ccu_gate_disable,
+ .enable = ccu_gate_enable,
+ .set_parent = ccu_mux_set_parent,
+ .get_rate = ccu_div_recalc_rate,
+ .set_rate = ccu_mix_set_rate,
+};
+
+U_BOOT_DRIVER(spacemit_clk_mux_div_gate) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_mux_div_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_mix.h b/drivers/clk/spacemit/clk_mix.h
new file mode 100644
index 00000000000..26a12cedd0d
--- /dev/null
+++ b/drivers/clk/spacemit/clk_mix.h
@@ -0,0 +1,224 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_MIX_H_
+#define _CLK_MIX_H_
+
+#include <linux/clk-provider.h>
+
+#include "clk_common.h"
+
+/**
+ * struct ccu_gate_config - Gate configuration
+ *
+ * @mask: Mask to enable the gate. Some clocks may have more than one bit
+ * set in this field.
+ */
+struct ccu_gate_config {
+ u32 mask;
+};
+
+struct ccu_factor_config {
+ u32 div;
+ u32 mul;
+};
+
+struct ccu_mux_config {
+ u8 shift;
+ u8 width;
+};
+
+struct ccu_div_config {
+ u8 shift;
+ u8 width;
+};
+
+struct ccu_mix {
+ struct ccu_factor_config factor;
+ struct ccu_gate_config gate;
+ struct ccu_div_config div;
+ struct ccu_mux_config mux;
+ struct ccu_common common;
+};
+
+#define CCU_GATE_INIT(_mask) { .mask = _mask }
+#define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul }
+#define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width }
+#define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width }
+
+#define CCU_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \
+ _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, spacemit_gate_init, \
+ _flags) \
+ } \
+}
+
+#define CCU_FACTOR_DEFINE(_id, _var, _name, _parent, _div, _mul) \
+static struct ccu_mix _var = { \
+ .factor = CCU_FACTOR_INIT(_div, _mul), \
+ .common = { \
+ CCU_COMMON(_id, _name, _parent, spacemit_factor_init, \
+ 0) \
+ } \
+}
+
+#define CCU_MUX_DEFINE(_id, _var, _name, _parents, _num_p, _reg_ctrl, \
+ _shift, _width, _flags) \
+static struct ccu_mix _var = { \
+ .mux = CCU_MUX_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_init, _flags) \
+ } \
+}
+
+#define CCU_DIV_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _shift, \
+ _width, _flags) \
+static struct ccu_mix _var = { \
+ .div = CCU_DIV_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, spacemit_div_init, \
+ _flags) \
+ } \
+}
+
+#define CCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent, \
+ _reg_ctrl, _mask_gate, _div, _mul, \
+ _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .factor = CCU_FACTOR_INIT(_div, _mul), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, \
+ spacemit_factor_gate_init, _flags) \
+ } \
+}
+
+#define CCU_FACTOR_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \
+ _mask_gate, _div, _mul) \
+ CCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent, \
+ _reg_ctrl, _mask_gate, _div, _mul, \
+ 0)
+
+#define CCU_MUX_GATE_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _shift, _width, _mask_gate, \
+ _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .mux = CCU_MUX_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_gate_init, _flags) \
+ } \
+}
+
+#define CCU_DIV_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \
+ _shift, _width, _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .div = CCU_DIV_INIT(_shift, _width), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON(_id, _name, _parent, \
+ spacemit_div_gate_init, _flags) \
+ } \
+}
+
+#define CCU_MUX_DIV_GATE_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _mshift, _mwidth, _muxshift, \
+ _muxwidth, _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .div = CCU_DIV_INIT(_mshift, _mwidth), \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_div_gate_init, _flags) \
+ }, \
+}
+
+#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_id, _var, _name, _parents, \
+ _num_p, _reg_ctrl, _reg_fc, \
+ _mshift, _mwidth, _mask_fc, \
+ _muxshift, _muxwidth, \
+ _mask_gate, _flags) \
+static struct ccu_mix _var = { \
+ .gate = CCU_GATE_INIT(_mask_gate), \
+ .div = CCU_DIV_INIT(_mshift, _mwidth), \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ .reg_fc = _reg_fc, \
+ .mask_fc = _mask_fc, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_div_gate_init, _flags) \
+ }, \
+}
+
+#define CCU_MUX_DIV_FC_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _reg_fc, _mshift, _mwidth, \
+ _mask_fc, _muxshift, _muxwidth, _flags) \
+static struct ccu_mix _var = { \
+ .div = CCU_DIV_INIT(_mshift, _mwidth), \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ .reg_fc = _reg_fc, \
+ .mask_fc = _mask_fc, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_div_init, _flags) \
+ }, \
+}
+
+#define CCU_MUX_FC_DEFINE(_id, _var, _name, _parents, _num_p, \
+ _reg_ctrl, _reg_fc, _mask_fc, _muxshift, \
+ _muxwidth, _flags) \
+static struct ccu_mix _var = { \
+ .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \
+ .common = { \
+ .reg_ctrl = _reg_ctrl, \
+ .reg_fc = _reg_fc, \
+ .mask_fc = _mask_fc, \
+ CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \
+ spacemit_mux_init, \
+ _flags) \
+ }, \
+}
+
+static inline struct ccu_mix *clk_to_ccu_mix(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ return container_of(common, struct ccu_mix, common);
+}
+
+int ccu_gate_enable(struct clk *clk);
+int ccu_gate_disable(struct clk *clk);
+
+int spacemit_gate_init(struct ccu_common *common);
+int spacemit_factor_init(struct ccu_common *common);
+int spacemit_mux_init(struct ccu_common *common);
+int spacemit_div_init(struct ccu_common *common);
+int spacemit_factor_gate_init(struct ccu_common *common);
+int spacemit_div_gate_init(struct ccu_common *common);
+int spacemit_mux_gate_init(struct ccu_common *common);
+int spacemit_mux_div_init(struct ccu_common *common);
+int spacemit_mux_div_gate_init(struct ccu_common *common);
+
+#endif /* _CLK_MIX_H_ */
diff --git a/drivers/clk/spacemit/clk_pll.c b/drivers/clk/spacemit/clk_pll.c
new file mode 100644
index 00000000000..56da70af58a
--- /dev/null
+++ b/drivers/clk/spacemit/clk_pll.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#include <dm/device.h>
+#include <regmap.h>
+#include <linux/bug.h>
+#include <linux/clk-provider.h>
+
+#include "clk_pll.h"
+
+#define UBOOT_DM_SPACEMIT_CLK_PLL "spacemit_clk_pll"
+
+#define PLL_TIMEOUT_US 3000
+#define PLL_DELAY_US 5
+
+#define PLL_SWCR3_EN ((u32)BIT(31))
+#define PLL_SWCR3_MASK GENMASK(30, 0)
+
+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll,
+ unsigned long rate)
+{
+ struct ccu_pll_config *config = &pll->config;
+ const struct ccu_pll_rate_tbl *best_entry;
+ unsigned long best_delta = ULONG_MAX;
+ int i;
+
+ for (i = 0; i < config->tbl_num; i++) {
+ const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];
+ unsigned long delta = abs(entry->rate - rate);
+
+ if (delta < best_delta) {
+ best_delta = delta;
+ best_entry = entry;
+ }
+ }
+
+ return best_entry;
+}
+
+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_matched_entry(struct ccu_pll *pll)
+{
+ struct ccu_pll_config *config = &pll->config;
+ u32 swcr1, swcr3;
+ int i;
+
+ swcr1 = ccu_read(&pll->common, swcr1);
+ swcr3 = ccu_read(&pll->common, swcr3);
+ swcr3 &= PLL_SWCR3_MASK;
+
+ for (i = 0; i < config->tbl_num; i++) {
+ const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];
+
+ if (swcr1 == entry->swcr1 && swcr3 == entry->swcr3)
+ return entry;
+ }
+
+ return NULL;
+}
+
+static void ccu_pll_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry)
+{
+ struct ccu_common *common = &pll->common;
+
+ regmap_write(common->regmap, common->reg_swcr1, entry->swcr1);
+ ccu_update(common, swcr3, PLL_SWCR3_MASK, entry->swcr3);
+}
+
+static int ccu_pll_enable(struct clk *clk)
+{
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ struct ccu_common *common = &pll->common;
+ unsigned int tmp;
+
+ ccu_update(common, swcr3, PLL_SWCR3_EN, PLL_SWCR3_EN);
+
+ /* check lock status */
+ return regmap_read_poll_timeout(common->lock_regmap,
+ pll->config.reg_lock,
+ tmp,
+ tmp & pll->config.mask_lock,
+ PLL_DELAY_US, PLL_TIMEOUT_US);
+}
+
+static int ccu_pll_disable(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ ccu_update(common, swcr3, PLL_SWCR3_EN, 0);
+
+ return 0;
+}
+
+/*
+ * PLLs must be gated before changing rate, which is ensured by
+ * flag CLK_SET_RATE_GATE.
+ */
+static unsigned long ccu_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ const struct ccu_pll_rate_tbl *entry;
+
+ entry = ccu_pll_lookup_best_rate(pll, rate);
+ ccu_pll_update_param(pll, entry);
+
+ return 0;
+}
+
+static unsigned long ccu_pll_recalc_rate(struct clk *clk)
+{
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ const struct ccu_pll_rate_tbl *entry;
+
+ entry = ccu_pll_lookup_matched_entry(pll);
+
+ WARN_ON_ONCE(!entry);
+
+ return entry ? entry->rate : 0;
+}
+
+static const struct clk_ops spacemit_clk_pll_ops = {
+ .enable = ccu_pll_enable,
+ .disable = ccu_pll_disable,
+ .set_rate = ccu_pll_set_rate,
+ .get_rate = ccu_pll_recalc_rate,
+};
+
+int spacemit_pll_init(struct ccu_common *common)
+{
+ struct clk *clk = &common->clk;
+ struct ccu_pll *pll = clk_to_ccu_pll(clk);
+ int ret;
+
+ ret = clk_register(clk, UBOOT_DM_SPACEMIT_CLK_PLL,
+ common->name, common->parents[0]);
+ if (ret)
+ return ret;
+
+ if (ccu_pll_lookup_matched_entry(pll))
+ return 0;
+
+ ccu_pll_disable(clk);
+ ccu_pll_update_param(pll, &pll->config.rate_tbl[0]);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(spacemit_clk_pll) = {
+ .name = UBOOT_DM_SPACEMIT_CLK_PLL,
+ .id = UCLASS_CLK,
+ .ops = &spacemit_clk_pll_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/spacemit/clk_pll.h b/drivers/clk/spacemit/clk_pll.h
new file mode 100644
index 00000000000..3987cc1141b
--- /dev/null
+++ b/drivers/clk/spacemit/clk_pll.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024-2025 Haylen Chu <[email protected]>
+ * Copyright (c) 2025 Junhui Liu <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ *
+ * Authors: Haylen Chu <[email protected]>
+ */
+
+#ifndef _CLK_PLL_H_
+#define _CLK_PLL_H_
+
+#include <linux/clk-provider.h>
+
+#include "clk_common.h"
+
+/**
+ * struct ccu_pll_rate_tbl - Structure mapping between PLL rate and register
+ * configuration.
+ *
+ * @rate: PLL rate
+ * @swcr1: Register value of PLLX_SW1_CTRL (PLLx_SWCR1).
+ * @swcr3: Register value of the PLLx_SW3_CTRL's lowest 31 bits of
+ * PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling
+ * the PLL and not contained in this field.
+ */
+struct ccu_pll_rate_tbl {
+ unsigned long rate;
+ u32 swcr1;
+ u32 swcr3;
+};
+
+#define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \
+ { \
+ .rate = _rate, \
+ .swcr1 = _swcr1, \
+ .swcr3 = _swcr3, \
+ }
+
+struct ccu_pll_config {
+ const struct ccu_pll_rate_tbl *rate_tbl;
+ u32 tbl_num;
+ u32 reg_lock;
+ u32 mask_lock;
+};
+
+struct ccu_pll {
+ struct ccu_common common;
+ struct ccu_pll_config config;
+};
+
+#define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \
+ { \
+ .rate_tbl = (_table), \
+ .tbl_num = sizeof(_table) / sizeof((_table)[0]), \
+ .reg_lock = (_reg_lock), \
+ .mask_lock = (_mask_lock), \
+ }
+
+#define CCU_PLL_DEFINE(_id, _var, _name, _parent, _table, _reg_swcr1, \
+ _reg_swcr3, _reg_lock, _mask_lock, _flags) \
+static struct ccu_pll _var = { \
+ .config = CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock), \
+ .common = { \
+ .reg_swcr1 = _reg_swcr1, \
+ .reg_swcr3 = _reg_swcr3, \
+ CCU_COMMON(_id, _name, _parent, spacemit_pll_init, _flags) \
+ } \
+}
+
+static inline struct ccu_pll *clk_to_ccu_pll(struct clk *clk)
+{
+ struct ccu_common *common = clk_to_ccu_common(clk);
+
+ return container_of(common, struct ccu_pll, common);
+}
+
+int spacemit_pll_init(struct ccu_common *common);
+
+#endif /* _CLK_PLL_H_ */
diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c
index 842a0541bd6..046d5d1605a 100644
--- a/drivers/clk/sunxi/clk_sunxi.c
+++ b/drivers/clk/sunxi/clk_sunxi.c
@@ -64,7 +64,7 @@ static int sunxi_clk_disable(struct clk *clk)
return sunxi_set_gate(clk, false);
}
-struct clk_ops sunxi_clk_ops = {
+static const struct clk_ops sunxi_clk_ops = {
.enable = sunxi_clk_enable,
.disable = sunxi_clk_disable,
};
diff --git a/drivers/clk/ti/clk-ctrl.c b/drivers/clk/ti/clk-ctrl.c
index c5c97dc35c4..e3564277982 100644
--- a/drivers/clk/ti/clk-ctrl.c
+++ b/drivers/clk/ti/clk-ctrl.c
@@ -8,7 +8,11 @@
#include <dm.h>
#include <dm/device_compat.h>
#include <clk-uclass.h>
-#include <asm/arch-am33xx/clock.h>
+#include <asm/ti-common/omap_clock.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+
+#define LDELAY 1000000
struct clk_ti_ctrl_offs {
fdt_addr_t start;
@@ -33,10 +37,66 @@ static int clk_ti_ctrl_check_offs(struct clk *clk, fdt_addr_t offs)
return -EFAULT;
}
+#define IDLEST_DISABLED (MODULE_CLKCTRL_IDLEST_DISABLED << MODULE_CLKCTRL_IDLEST_SHIFT)
+#define IDLEST_TRANSITION (MODULE_CLKCTRL_IDLEST_TRANSITIONING << MODULE_CLKCTRL_IDLEST_SHIFT)
+static inline void wait_for_clk_disable(u32 addr)
+{
+ u32 bound = LDELAY;
+ int val = 0;
+
+ while ((val & MODULE_CLKCTRL_IDLEST_MASK) != IDLEST_DISABLED) {
+ val = readl(addr);
+
+ if (--bound == 0) {
+ printf("Clock disable failed for 0x%x idlest 0x%x\n",
+ addr, val);
+ return;
+ }
+ }
+}
+
+static int clk_ti_ctrl_disable_clock_module(u32 addr)
+{
+ clrsetbits_le32(addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+ MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
+ MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+ wait_for_clk_disable(addr);
+
+ return 0;
+}
+
+static inline void wait_for_clk_enable(u32 addr)
+{
+ int val = IDLEST_DISABLED;
+ u32 bound = LDELAY;
+
+ while (((val & MODULE_CLKCTRL_IDLEST_MASK) == IDLEST_DISABLED) ||
+ ((val & MODULE_CLKCTRL_IDLEST_MASK) == IDLEST_TRANSITION)) {
+ val = readl(addr);
+
+ if (--bound == 0) {
+ printf("Clock enable failed for 0x%x idlest 0x%x\n",
+ addr, val);
+ return;
+ }
+ }
+}
+
+static int clk_ti_ctrl_enable_clock_module(u32 addr)
+{
+ clrsetbits_le32(addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+ MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
+ MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+ wait_for_clk_enable(addr);
+
+ return 0;
+}
+
static int clk_ti_ctrl_disable(struct clk *clk)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
- u32 *clk_modules[2] = { };
fdt_addr_t offs;
int err;
@@ -47,16 +107,13 @@ static int clk_ti_ctrl_disable(struct clk *clk)
return err;
}
- clk_modules[0] = (u32 *)(offs);
- dev_dbg(clk->dev, "disable module @ %p\n", clk_modules[0]);
- do_disable_clocks(NULL, clk_modules, 1);
- return 0;
+ dev_dbg(clk->dev, "disable module @ %x\n", offs);
+ return clk_ti_ctrl_disable_clock_module(offs);
}
static int clk_ti_ctrl_enable(struct clk *clk)
{
struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
- u32 *clk_modules[2] = { };
fdt_addr_t offs;
int err;
@@ -67,10 +124,8 @@ static int clk_ti_ctrl_enable(struct clk *clk)
return err;
}
- clk_modules[0] = (u32 *)(offs);
- dev_dbg(clk->dev, "enable module @ %p\n", clk_modules[0]);
- do_enable_clocks(NULL, clk_modules, 1);
- return 0;
+ dev_dbg(clk->dev, "enable module @ %x\n", offs);
+ return clk_ti_ctrl_enable_clock_module(offs);
}
static ulong clk_ti_ctrl_get_rate(struct clk *clk)
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 5419bf65b5d..ae0c3466772 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -337,11 +337,19 @@ config SIMPLE_BUS_CORRECT_RANGE
config SIMPLE_PM_BUS
bool "Support simple-pm-bus driver"
- depends on DM && OF_CONTROL && CLK && POWER_DOMAIN
+ depends on DM && OF_CONTROL && POWER_DOMAIN
help
Supports the 'simple-pm-bus' driver, which is used for busses that
have power domains and/or clocks which need to be enabled before use.
+config SPL_SIMPLE_PM_BUS
+ bool "Support simple-pm-bus driver in SPL"
+ depends on SPL_DM && SPL_OF_CONTROL && SPL_POWER_DOMAIN
+ help
+ Supports the 'simple-pm-bus' driver, which is used for busses that
+ have power domains and/or clocks which need to be enabled before use,
+ in SPL.
+
config OF_TRANSLATE
bool "Translate addresses using fdt_translate_address"
depends on DM && OF_CONTROL
diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index a549890c22b..1073c26b2ed 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_$(PHASE_)ACPIGEN) += acpi.o
obj-$(CONFIG_$(PHASE_)DEVRES) += devres.o
obj-$(CONFIG_$(PHASE_)DM_DEVICE_REMOVE) += device-remove.o
obj-$(CONFIG_$(PHASE_)SIMPLE_BUS) += simple-bus.o
-obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o
+obj-$(CONFIG_$(PHASE_)SIMPLE_PM_BUS) += simple-pm-bus.o
obj-$(CONFIG_DM) += dump.o
obj-$(CONFIG_$(PHASE_)REGMAP) += regmap.o
obj-$(CONFIG_$(PHASE_)SYSCON) += syscon-uclass.o
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index 4763963914b..284fb70b036 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -87,7 +87,7 @@ int acpi_copy_name(char *out_name, const char *name)
int acpi_get_name(const struct udevice *dev, char *out_name)
{
- struct acpi_ops *aops;
+ const struct acpi_ops *aops;
const char *name;
int ret;
@@ -154,10 +154,9 @@ static int add_item(struct acpi_ctx *ctx, struct udevice *dev,
if (!item->size)
return 0;
if (type != TYPE_OTHER) {
- item->buf = malloc(item->size);
+ item->buf = memdup(start, item->size);
if (!item->buf)
return log_msg_ret("mem", -ENOMEM);
- memcpy(item->buf, start, item->size);
}
item_count++;
log_debug("* %s: Added type %d, %p, size %x\n",
@@ -276,7 +275,7 @@ static int sort_acpi_item_type(struct acpi_ctx *ctx, void *start,
acpi_method acpi_get_method(struct udevice *dev, enum method_t method)
{
- struct acpi_ops *aops;
+ const struct acpi_ops *aops;
aops = device_get_acpi_ops(dev);
if (aops) {
diff --git a/drivers/core/device.c b/drivers/core/device.c
index d365204ba11..6024534ff93 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -1147,6 +1147,8 @@ int device_set_name(struct udevice *dev, const char *name)
name = strdup(name);
if (!name)
return -ENOMEM;
+ if (dev_get_flags(dev) & DM_FLAG_NAME_ALLOCED)
+ free((char *)dev->name);
dev->name = name;
device_set_name_alloced(dev);
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index 969492aae37..f910cc9a31b 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -1071,7 +1071,7 @@ int of_add_subnode(struct device_node *parent, const char *name, int len,
* make sure we don't use a child called "trevor" when we are
* searching for "trev".
*/
- if (!strncmp(child->name, name, len) && strlen(name) == len) {
+ if (!strncmp(child->name, name, len) && strlen(child->name) == len) {
*childp = child;
return -EEXIST;
}
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index d605c0f7b7c..b5d13c43db1 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -130,8 +130,10 @@ int oftree_new(oftree *treep)
if (!fdt)
return log_msg_ret("fla", -ENOMEM);
ret = fdt_create_empty_tree(fdt, size);
- if (ret)
+ if (ret) {
+ free(fdt);
return log_msg_ret("fla", -EINVAL);
+ }
oftree_list[oftree_count++] = fdt;
tree.fdt = fdt;
}
@@ -1798,10 +1800,9 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value,
void *newval;
if (copy) {
- newval = malloc(len);
+ newval = memdup(value, len);
if (!newval)
return log_ret(-ENOMEM);
- memcpy(newval, value, len);
value = newval;
}
ret = of_write_prop(ofnode_to_np(node), propname, len, value);
diff --git a/drivers/core/read.c b/drivers/core/read.c
index c0d7a969db2..ba48862f44b 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -132,12 +132,14 @@ fdt_addr_t dev_read_addr_index(const struct udevice *dev, int index)
void *dev_read_addr_index_ptr(const struct udevice *dev, int index)
{
- fdt_addr_t addr = dev_read_addr_index(dev, index);
+ fdt_addr_t addr;
+ fdt_size_t size = 0;
+ addr = dev_read_addr_size_index(dev, index, &size);
if (addr == FDT_ADDR_T_NONE)
return NULL;
- return map_sysmem(addr, 0);
+ return map_sysmem(addr, size);
}
fdt_addr_t dev_read_addr_size_index(const struct udevice *dev, int index,
@@ -157,17 +159,19 @@ void *dev_read_addr_size_index_ptr(const struct udevice *dev, int index,
if (addr == FDT_ADDR_T_NONE)
return NULL;
- return map_sysmem(addr, 0);
+ return map_sysmem(addr, *size);
}
void *dev_remap_addr_index(const struct udevice *dev, int index)
{
- fdt_addr_t addr = dev_read_addr_index(dev, index);
+ fdt_addr_t addr;
+ fdt_size_t size = 0;
+ addr = dev_read_addr_size_index(dev, index, &size);
if (addr == FDT_ADDR_T_NONE)
return NULL;
- return map_physmem(addr, 0, MAP_NOCACHE);
+ return map_physmem(addr, size, MAP_NOCACHE);
}
fdt_addr_t dev_read_addr_name(const struct udevice *dev, const char *name)
@@ -182,12 +186,14 @@ fdt_addr_t dev_read_addr_name(const struct udevice *dev, const char *name)
void *dev_read_addr_name_ptr(const struct udevice *dev, const char *name)
{
- fdt_addr_t addr = dev_read_addr_name(dev, name);
+ fdt_addr_t addr;
+ fdt_size_t size = 0;
+ addr = dev_read_addr_size_name(dev, name, &size);
if (addr == FDT_ADDR_T_NONE)
return NULL;
- return map_sysmem(addr, 0);
+ return map_sysmem(addr, size);
}
fdt_addr_t dev_read_addr_size_name(const struct udevice *dev, const char *name,
@@ -209,17 +215,19 @@ void *dev_read_addr_size_name_ptr(const struct udevice *dev, const char *name,
if (addr == FDT_ADDR_T_NONE)
return NULL;
- return map_sysmem(addr, 0);
+ return map_sysmem(addr, *size);
}
void *dev_remap_addr_name(const struct udevice *dev, const char *name)
{
- fdt_addr_t addr = dev_read_addr_name(dev, name);
+ fdt_addr_t addr;
+ fdt_size_t size = 0;
+ addr = dev_read_addr_size_name(dev, name, &size);
if (addr == FDT_ADDR_T_NONE)
return NULL;
- return map_physmem(addr, 0, MAP_NOCACHE);
+ return map_physmem(addr, size, MAP_NOCACHE);
}
fdt_addr_t dev_read_addr(const struct udevice *dev)
@@ -229,12 +237,14 @@ fdt_addr_t dev_read_addr(const struct udevice *dev)
void *dev_read_addr_ptr(const struct udevice *dev)
{
- fdt_addr_t addr = dev_read_addr(dev);
+ fdt_addr_t addr;
+ fdt_size_t size = 0;
+ addr = dev_read_addr_size(dev, &size);
if (addr == FDT_ADDR_T_NONE)
return NULL;
- return map_sysmem(addr, 0);
+ return map_sysmem(addr, size);
}
void *dev_remap_addr(const struct udevice *dev)
diff --git a/drivers/core/root.c b/drivers/core/root.c
index d43645f34dd..2aa16d59b69 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -81,10 +81,9 @@ static int dm_setup_inst(void)
/* Now allocate space for the priv/plat data, and copy it in */
size = __priv_data_end - __priv_data_start;
- base = calloc(1, size);
+ base = memdup(__priv_data_start, size);
if (!base)
return log_msg_ret("priv", -ENOMEM);
- memcpy(base, __priv_data_start, size);
gd_set_dm_priv_base(base);
}
@@ -460,7 +459,7 @@ static int root_acpi_get_name(const struct udevice *dev, char *out_name)
return acpi_copy_name(out_name, "\\_SB");
}
-struct acpi_ops root_acpi_ops = {
+static const struct acpi_ops root_acpi_ops = {
.get_name = root_acpi_get_name,
};
#endif
diff --git a/drivers/core/tag.c b/drivers/core/tag.c
index a3c5cb7e57c..78b5ee6dc07 100644
--- a/drivers/core/tag.c
+++ b/drivers/core/tag.c
@@ -46,7 +46,7 @@ int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr)
return -EEXIST;
}
- node = calloc(sizeof(*node), 1);
+ node = calloc(1, sizeof(*node));
if (!node)
return -ENOMEM;
@@ -70,7 +70,7 @@ int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val)
return -EEXIST;
}
- node = calloc(sizeof(*node), 1);
+ node = calloc(1, sizeof(*node));
if (!node)
return -ENOMEM;
diff --git a/drivers/cpu/armv8_cpu.c b/drivers/cpu/armv8_cpu.c
index 4eedfe5e2c5..337661c23a8 100644
--- a/drivers/cpu/armv8_cpu.c
+++ b/drivers/cpu/armv8_cpu.c
@@ -124,7 +124,7 @@ int armv8_cpu_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx)
return 0;
}
-struct acpi_ops armv8_cpu_acpi_ops = {
+static const struct acpi_ops armv8_cpu_acpi_ops = {
.fill_ssdt = armv8_cpu_fill_ssdt,
.fill_madt = armv8_cpu_fill_madt,
};
diff --git a/drivers/cpu/bcm283x_cpu.c b/drivers/cpu/bcm283x_cpu.c
index ad638cd8fff..43e74d1811b 100644
--- a/drivers/cpu/bcm283x_cpu.c
+++ b/drivers/cpu/bcm283x_cpu.c
@@ -193,7 +193,7 @@ static int bcm_cpu_probe(struct udevice *dev)
return ret;
}
-struct acpi_ops bcm283x_cpu_acpi_ops = {
+static const struct acpi_ops __maybe_unused bcm283x_cpu_acpi_ops = {
.fill_ssdt = armv8_cpu_fill_ssdt,
.fill_madt = armv8_cpu_fill_madt,
};
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c
index 785c299eca5..7bb7b420176 100644
--- a/drivers/cpu/imx8_cpu.c
+++ b/drivers/cpu/imx8_cpu.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2019, 2024 NXP
+ * Copyright 2019, 2024-2026 NXP
*/
#include <cpu.h>
@@ -28,8 +28,18 @@ struct cpu_imx_plat {
u32 mpidr;
};
+__weak const char *get_cpu_variant_type_name(u32 type)
+{
+ return NULL;
+}
+
static const char *get_imx_type_str(u32 imxtype)
{
+ const char *name = get_cpu_variant_type_name(imxtype);
+
+ if (name)
+ return name;
+
switch (imxtype) {
case MXC_CPU_IMX8MM:
return "8MMQ"; /* Quad-core version of the imx8mm */
@@ -63,12 +73,18 @@ static const char *get_imx_type_str(u32 imxtype)
return "8MNano UltraLite Solo";/* Single-core UltraLite version of the imx8mn */
case MXC_CPU_IMX8MP:
return "8MP[8]"; /* Quad-core version of the imx8mp */
+ case MXC_CPU_IMX8MPD2:
+ return "8MP Dual[2]"; /* Dual-core version of the imx8mp, low cost industrial & HMI */
case MXC_CPU_IMX8MPD:
return "8MP Dual[3]"; /* Dual-core version of the imx8mp */
case MXC_CPU_IMX8MPL:
return "8MP Lite[4]"; /* Quad-core Lite version of the imx8mp */
+ case MXC_CPU_IMX8MP5:
+ return "8MP[5]"; /* Quad-core version of the imx8mp, low cost industrial & HMI */
case MXC_CPU_IMX8MP6:
return "8MP[6]"; /* Quad-core version of the imx8mp, NPU fused */
+ case MXC_CPU_IMX8MPUL:
+ return "8MP UltraLite"; /* Quad-core UltraLite version of the imx8mp */
case MXC_CPU_IMX8MQ:
return "8MQ"; /* Quad-core version of the imx8mq */
case MXC_CPU_IMX8MQL:
@@ -222,7 +238,7 @@ static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size)
ret = snprintf(buf, size, "NXP i.MX%s Rev%s %s at %u MHz",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- if (IS_ENABLED(CONFIG_IMX_TMU)) {
+ if (!IS_ENABLED(CONFIG_IMX8)) { /* imx8 does not have segment fuse */
switch (get_cpu_temp_grade(&minc, &maxc)) {
case TEMP_AUTOMOTIVE:
grade = "Automotive temperature grade";
@@ -231,7 +247,10 @@ static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size)
grade = "Industrial temperature grade";
break;
case TEMP_EXTCOMMERCIAL:
- grade = "Extended Consumer temperature grade";
+ if (IS_ENABLED(CONFIG_ARCH_IMX9))
+ grade = "Extended Industrial temperature grade";
+ else
+ grade = "Extended Consumer temperature grade";
break;
default:
grade = "Consumer temperature grade";
@@ -371,6 +390,7 @@ static int imx_cpu_probe(struct udevice *dev)
{
struct cpu_imx_plat *plat = dev_get_plat(dev);
u32 cpurev;
+ fdt_addr_t addr;
set_core_data(dev);
cpurev = get_cpu_rev();
@@ -378,12 +398,14 @@ static int imx_cpu_probe(struct udevice *dev)
get_imx_rev_str(plat, cpurev & 0xFFF);
plat->type = get_imx_type_str((cpurev & 0x1FF000) >> 12);
plat->freq_mhz = imx_get_cpu_rate(dev) / 1000000;
- plat->mpidr = dev_read_addr(dev);
- if (plat->mpidr == FDT_ADDR_T_NONE) {
+ addr = dev_read_addr(dev);
+ if (addr == FDT_ADDR_T_NONE) {
printf("%s: Failed to get CPU reg property\n", __func__);
return -EINVAL;
}
+ plat->mpidr = (u32)addr;
+
return 0;
}
diff --git a/drivers/crypto/aspeed/Kconfig b/drivers/crypto/aspeed/Kconfig
index 401225b8528..a4710257f62 100644
--- a/drivers/crypto/aspeed/Kconfig
+++ b/drivers/crypto/aspeed/Kconfig
@@ -15,11 +15,11 @@ config ASPEED_ACRY
bool "ASPEED RSA and ECC Engine"
depends on ASPEED_AST2600
help
- Select this option to enable a driver for using the RSA/ECC engine in
- the ASPEED BMC SoCs.
+ Select this option to enable a driver for using the RSA/ECC engine in
+ the ASPEED BMC SoCs.
- Enabling this allows the use of RSA/ECC operations in hardware without requiring the
- software implementations. It also improves performance and saves code size.
+ Enabling this allows the use of RSA/ECC operations in hardware without requiring the
+ software implementations. It also improves performance and saves code size.
config ASPEED_CPTRA_SHA
bool "Caliptra SHA ACC for Aspeed AST27xx SoCs"
diff --git a/drivers/crypto/aspeed/aspeed_acry.c b/drivers/crypto/aspeed/aspeed_acry.c
index e3f81ebd5c7..ff01256e150 100644
--- a/drivers/crypto/aspeed/aspeed_acry.c
+++ b/drivers/crypto/aspeed/aspeed_acry.c
@@ -144,13 +144,13 @@ static int aspeed_acry_probe(struct udevice *dev)
return ret;
}
- acry->base = devfdt_get_addr_index(dev, 0);
+ acry->base = dev_read_addr_index(dev, 0);
if (acry->base == FDT_ADDR_T_NONE) {
debug("Failed to get acry base\n");
return acry->base;
}
- acry->sram_base = devfdt_get_addr_index(dev, 1);
+ acry->sram_base = dev_read_addr_index(dev, 1);
if (acry->sram_base == FDT_ADDR_T_NONE) {
debug("Failed to get acry SRAM base\n");
return acry->sram_base;
diff --git a/drivers/crypto/aspeed/aspeed_hace.c b/drivers/crypto/aspeed/aspeed_hace.c
index 17cc30a7b54..22b5008a296 100644
--- a/drivers/crypto/aspeed/aspeed_hace.c
+++ b/drivers/crypto/aspeed/aspeed_hace.c
@@ -341,7 +341,7 @@ static int aspeed_hace_probe(struct udevice *dev)
return rc;
}
- hace->base = devfdt_get_addr(dev);
+ hace->base = dev_read_addr(dev);
return rc;
}
diff --git a/drivers/crypto/aspeed/cptra_ecdsa.c b/drivers/crypto/aspeed/cptra_ecdsa.c
index 4b70d89def7..7603ca373ff 100644
--- a/drivers/crypto/aspeed/cptra_ecdsa.c
+++ b/drivers/crypto/aspeed/cptra_ecdsa.c
@@ -149,7 +149,7 @@ static int cptra_ecdsa_probe(struct udevice *dev)
{
struct cptra_ecdsa *ce = dev_get_priv(dev);
- ce->regs = (void *)devfdt_get_addr(dev);
+ ce->regs = (void *)dev_read_addr(dev);
if (ce->regs == (void *)FDT_ADDR_T_NONE) {
debug("cannot map Caliptra mailbox registers\n");
return -EINVAL;
diff --git a/drivers/crypto/aspeed/cptra_sha.c b/drivers/crypto/aspeed/cptra_sha.c
index 26b97bdd92b..f57778e160d 100644
--- a/drivers/crypto/aspeed/cptra_sha.c
+++ b/drivers/crypto/aspeed/cptra_sha.c
@@ -219,7 +219,7 @@ static int cptra_sha_probe(struct udevice *dev)
{
struct cptra_sha *cs = dev_get_priv(dev);
- cs->regs = (void *)devfdt_get_addr(dev);
+ cs->regs = (void *)dev_read_addr(dev);
if (cs->regs == (void *)FDT_ADDR_T_NONE) {
debug("cannot map Caliptra SHA ACC registers\n");
return -ENODEV;
diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig
index eb01c6cf700..244a9bd905d 100644
--- a/drivers/crypto/fsl/Kconfig
+++ b/drivers/crypto/fsl/Kconfig
@@ -20,6 +20,7 @@ config SYS_FSL_MAX_NUM_OF_SEC
config CAAM_64BIT
bool
+ depends on FSL_CAAM
default y if PHYS_64BIT && !ARCH_IMX8M && !ARCH_IMX8
help
Select Crypto driver for 64 bits CAAM version
@@ -27,27 +28,27 @@ config CAAM_64BIT
config SYS_FSL_HAS_SEC
bool
help
- Enable Freescale Secure Boot and Trusted Architecture
+ Enable Freescale Secure Boot and Trusted Architecture
config SYS_FSL_SEC_COMPAT_2
bool
help
- Secure boot and trust architecture compatible version 2
+ Secure boot and trust architecture compatible version 2
config SYS_FSL_SEC_COMPAT_4
bool
help
- Secure boot and trust architecture compatible version 4
+ Secure boot and trust architecture compatible version 4
config SYS_FSL_SEC_COMPAT_5
bool
help
- Secure boot and trust architecture compatible version 5
+ Secure boot and trust architecture compatible version 5
config SYS_FSL_SEC_COMPAT_6
bool
help
- Secure boot and trust architecture compatible version 6
+ Secure boot and trust architecture compatible version 6
config SYS_FSL_SEC_BE
bool "Big-endian access to Freescale Secure Boot"
diff --git a/drivers/crypto/tegra/tegra_aes.c b/drivers/crypto/tegra/tegra_aes.c
index 7b374c757ba..55a4cec525b 100644
--- a/drivers/crypto/tegra/tegra_aes.c
+++ b/drivers/crypto/tegra/tegra_aes.c
@@ -518,7 +518,7 @@ static int tegra_aes_probe(struct udevice *dev)
return -EINVAL;
}
- priv->iram_addr = devfdt_get_addr_size_name_ptr(dev, "iram-buffer", &iram_size);
+ priv->iram_addr = dev_read_addr_size_name_ptr(dev, "iram-buffer", &iram_size);
if (!priv->iram_addr) {
log_debug("%s: Cannot find iram buffer address, binding failed\n", __func__);
return -EINVAL;
diff --git a/drivers/ddr/altera/sdram_agilex.c b/drivers/ddr/altera/sdram_agilex.c
index b36a765a5de..2d2b72cf766 100644
--- a/drivers/ddr/altera/sdram_agilex.c
+++ b/drivers/ddr/altera/sdram_agilex.c
@@ -104,7 +104,7 @@ int sdram_mmr_init_full(struct udevice *dev)
/* Get bank configuration from devicetree */
ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
- (phys_size_t *)&gd->ram_size, &bd);
+ (phys_size_t *)&gd->ram_size, gd);
if (ret) {
puts("DDR: Failed to decode memory node\n");
return -ENXIO;
@@ -158,7 +158,7 @@ int sdram_mmr_init_full(struct udevice *dev)
sdram_set_firewall(&bd);
- priv->info.base = bd.bi_dram[0].start;
+ priv->info.base = gd->dram[0].start;
priv->info.size = gd->ram_size;
debug("DDR: HMC init success\n");
diff --git a/drivers/ddr/altera/sdram_agilex5.c b/drivers/ddr/altera/sdram_agilex5.c
index ee66c72157a..d14e4bc5dcc 100644
--- a/drivers/ddr/altera/sdram_agilex5.c
+++ b/drivers/ddr/altera/sdram_agilex5.c
@@ -302,7 +302,7 @@ int sdram_mmr_init_full(struct udevice *dev)
/* Get bank configuration from devicetree */
ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
- (phys_size_t *)&gd->ram_size, gd->bd);
+ (phys_size_t *)&gd->ram_size, gd);
if (ret) {
puts("DDR: Failed to decode memory node\n");
ret = -ENXIO;
@@ -345,19 +345,19 @@ int sdram_mmr_init_full(struct udevice *dev)
for (i = 0; i < config_dram_banks; i++) {
remaining_size = hw_size - size_counter;
if (remaining_size <= dram_bank_info[i].max_size) {
- gd->bd->bi_dram[i].start = dram_bank_info[i].start;
- gd->bd->bi_dram[i].size = remaining_size;
+ gd->dram[i].start = dram_bank_info[i].start;
+ gd->dram[i].size = remaining_size;
debug("Memory bank[%d] Starting address: 0x%llx size: 0x%llx\n",
- i, gd->bd->bi_dram[i].start, gd->bd->bi_dram[i].size);
+ i, gd->dram[i].start, gd->dram[i].size);
break;
}
- gd->bd->bi_dram[i].start = dram_bank_info[i].start;
- gd->bd->bi_dram[i].size = dram_bank_info[i].max_size;
+ gd->dram[i].start = dram_bank_info[i].start;
+ gd->dram[i].size = dram_bank_info[i].max_size;
debug("Memory bank[%d] Starting address: 0x%llx size: 0x%llx\n",
- i, gd->bd->bi_dram[i].start, gd->bd->bi_dram[i].size);
- size_counter += gd->bd->bi_dram[i].size;
+ i, gd->dram[i].start, gd->dram[i].size);
+ size_counter += gd->dram[i].size;
}
gd->ram_size = hw_size;
@@ -408,7 +408,7 @@ int sdram_mmr_init_full(struct udevice *dev)
printf("DDR: firewall init success\n");
- priv->info.base = gd->bd->bi_dram[0].start;
+ priv->info.base = gd->dram[0].start;
priv->info.size = gd->ram_size;
/* Ending DDR driver initialization success tracking */
diff --git a/drivers/ddr/altera/sdram_agilex7m.c b/drivers/ddr/altera/sdram_agilex7m.c
index 9b3cc5c7b86..e4d522202d8 100644
--- a/drivers/ddr/altera/sdram_agilex7m.c
+++ b/drivers/ddr/altera/sdram_agilex7m.c
@@ -375,7 +375,7 @@ int sdram_mmr_init_full(struct udevice *dev)
/* Get bank configuration from devicetree */
ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
- (phys_size_t *)&gd->ram_size, &bd);
+ (phys_size_t *)&gd->ram_size, gd);
if (ret) {
printf("%s: Failed to decode memory node\n", memory_type_in_use(dev));
@@ -484,7 +484,7 @@ int sdram_mmr_init_full(struct udevice *dev)
printf("%s: firewall init success\n", (is_ddr_in_use(dev) ? io96b_ctrl->ddr_type : "HBM"));
- priv->info.base = bd.bi_dram[0].start;
+ priv->info.base = gd->dram[0].start;
priv->info.size = gd->ram_size;
/* Ending DDR driver initialization success tracking */
diff --git a/drivers/ddr/altera/sdram_arria10.c b/drivers/ddr/altera/sdram_arria10.c
index c281f711fdf..9cc809b8001 100644
--- a/drivers/ddr/altera/sdram_arria10.c
+++ b/drivers/ddr/altera/sdram_arria10.c
@@ -674,9 +674,9 @@ static void sdram_size_check(void)
debug("DDR: Running SDRAM size sanity check\n");
- ram_check = get_ram_size((long *)gd->bd->bi_dram[0].start,
- gd->bd->bi_dram[0].size);
- if (ram_check != gd->bd->bi_dram[0].size) {
+ ram_check = get_ram_size((long *)gd->dram[0].start,
+ gd->dram[0].size);
+ if (ram_check != gd->dram[0].size) {
puts("DDR: SDRAM size check failed!\n");
hang();
}
@@ -719,14 +719,14 @@ int ddr_calibration_sequence(void)
/* setup the dram info within bd */
dram_init_banksize();
- if (gd->ram_size != gd->bd->bi_dram[0].size) {
+ if (gd->ram_size != gd->dram[0].size) {
printf("DDR: Warning: DRAM size from device tree (%ld MiB)\n",
- gd->bd->bi_dram[0].size >> 20);
+ gd->dram[0].size >> 20);
printf(" mismatch with hardware (%ld MiB).\n",
gd->ram_size >> 20);
}
- if (gd->bd->bi_dram[0].size > gd->ram_size) {
+ if (gd->dram[0].size > gd->ram_size) {
printf("DDR: Error: DRAM size from device tree is greater\n");
printf(" than hardware size.\n");
hang();
diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
index 17ec6afa82b..900d4f59989 100644
--- a/drivers/ddr/altera/sdram_n5x.c
+++ b/drivers/ddr/altera/sdram_n5x.c
@@ -2279,7 +2279,7 @@ int sdram_mmr_init_full(struct udevice *dev)
/* Get bank configuration from devicetree */
ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
- (phys_size_t *)&gd->ram_size, &bd);
+ (phys_size_t *)&gd->ram_size, gd);
if (ret) {
debug("%s: Failed to decode memory node\n", __func__);
return -1;
@@ -2287,7 +2287,7 @@ int sdram_mmr_init_full(struct udevice *dev)
printf("DDR: %lld MiB\n", gd->ram_size >> 20);
- priv->info.base = bd.bi_dram[0].start;
+ priv->info.base = gd->dram[0].start;
priv->info.size = gd->ram_size;
sdram_size_check(&bd);
diff --git a/drivers/ddr/altera/sdram_s10.c b/drivers/ddr/altera/sdram_s10.c
index 4ac4c79e0ac..6664090f86a 100644
--- a/drivers/ddr/altera/sdram_s10.c
+++ b/drivers/ddr/altera/sdram_s10.c
@@ -285,7 +285,7 @@ int sdram_mmr_init_full(struct udevice *dev)
/* Get bank configuration from devicetree */
ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
- (phys_size_t *)&gd->ram_size, &bd);
+ (phys_size_t *)&gd->ram_size, gd);
if (ret) {
puts("DDR: Failed to decode memory node\n");
return -1;
@@ -328,7 +328,7 @@ int sdram_mmr_init_full(struct udevice *dev)
sdram_size_check(&bd);
- priv->info.base = bd.bi_dram[0].start;
+ priv->info.base = gd->dram[0].start;
priv->info.size = gd->ram_size;
debug("DDR: HMC init success\n");
diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c
index 8ee7049b164..93df3d1812a 100644
--- a/drivers/ddr/altera/sdram_soc64.c
+++ b/drivers/ddr/altera/sdram_soc64.c
@@ -150,8 +150,8 @@ void sdram_init_ecc_bits(struct bd_info *bd)
icache_enable();
- start_addr = bd->bi_dram[0].start;
- size = bd->bi_dram[0].size;
+ start_addr = gd->dram[0].start;
+ size = gd->dram[0].size;
/* Initialize small block for page table */
memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF);
@@ -174,8 +174,8 @@ void sdram_init_ecc_bits(struct bd_info *bd)
if (bank >= CONFIG_NR_DRAM_BANKS)
break;
- start_addr = bd->bi_dram[bank].start;
- size = bd->bi_dram[bank].size;
+ start_addr = gd->dram[bank].start;
+ size = gd->dram[bank].size;
}
dcache_disable();
@@ -198,12 +198,12 @@ void sdram_size_check(struct bd_info *bd)
phys_addr_t start = 0;
phys_size_t remaining_size;
- start = bd->bi_dram[bank].start;
- remaining_size = bd->bi_dram[bank].size;
+ start = gd->dram[bank].start;
+ remaining_size = gd->dram[bank].size;
debug("Checking bank %d: start=0x%llx, size=0x%llx\n",
bank, start, remaining_size);
- while (ram_check < bd->bi_dram[bank].size) {
+ while (ram_check < gd->dram[bank].size) {
phys_size_t size, test_size, detected_size;
size = min((phys_addr_t)SZ_1G, (phys_addr_t)remaining_size);
@@ -232,7 +232,7 @@ void sdram_size_check(struct bd_info *bd)
}
ram_check += detected_size;
- remaining_size = bd->bi_dram[bank].size - ram_check;
+ remaining_size = gd->dram[bank].size - ram_check;
}
total_ram_check += ram_check;
@@ -292,10 +292,10 @@ static void sdram_set_firewall_non_f2sdram(struct bd_info *bd)
u32 lower, upper;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
- if (!bd->bi_dram[i].size)
+ if (!gd->dram[i].size)
continue;
- value = bd->bi_dram[i].start;
+ value = gd->dram[i].start;
/* Keep first 1MB of SDRAM memory region as secure region when
* using ATF flow, where the ATF code is located.
@@ -322,7 +322,7 @@ static void sdram_set_firewall_non_f2sdram(struct bd_info *bd)
(i * 4 * sizeof(u32)));
/* Setting non-secure MPU limit and limit extended */
- value = bd->bi_dram[i].start + bd->bi_dram[i].size - 1;
+ value = gd->dram[i].start + gd->dram[i].size - 1;
lower = lower_32_bits(value);
upper = upper_32_bits(value);
@@ -354,10 +354,10 @@ static void sdram_set_firewall_f2sdram(struct bd_info *bd)
phys_size_t value;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
- if (!bd->bi_dram[i].size)
+ if (!gd->dram[i].size)
continue;
- value = bd->bi_dram[i].start;
+ value = gd->dram[i].start;
/* Keep first 1MB of SDRAM memory region as secure region when
* using ATF flow, where the ATF code is located.
@@ -376,7 +376,7 @@ static void sdram_set_firewall_f2sdram(struct bd_info *bd)
(i * 4 * sizeof(u32)));
/* Setting limit and limit extended */
- value = bd->bi_dram[i].start + bd->bi_dram[i].size - 1;
+ value = gd->dram[i].start + gd->dram[i].size - 1;
lower = lower_32_bits(value);
upper = upper_32_bits(value);
diff --git a/drivers/ddr/fsl/Kconfig b/drivers/ddr/fsl/Kconfig
index 7f8f3570dd8..b11fa79ca59 100644
--- a/drivers/ddr/fsl/Kconfig
+++ b/drivers/ddr/fsl/Kconfig
@@ -21,12 +21,12 @@ if SYS_FSL_DDR || SYS_FSL_MMDC
config SYS_FSL_DDR_BE
bool
help
- Access DDR registers in big-endian
+ Access DDR registers in big-endian
config SYS_FSL_DDR_LE
bool
help
- Access DDR registers in little-endian
+ Access DDR registers in little-endian
config FSL_DDR_BIST
bool
diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c
index d59e94779ff..2b879c63b5f 100644
--- a/drivers/ddr/fsl/main.c
+++ b/drivers/ddr/fsl/main.c
@@ -221,7 +221,7 @@ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
unsigned int i2c_address = 0;
if (ctrl_num >= CONFIG_SYS_NUM_DDR_CTLRS) {
- printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
+ printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return;
}
diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen1.c b/drivers/ddr/fsl/mpc85xx_ddr_gen1.c
index a8520754006..e43dc869fc5 100644
--- a/drivers/ddr/fsl/mpc85xx_ddr_gen1.c
+++ b/drivers/ddr/fsl/mpc85xx_ddr_gen1.c
@@ -21,7 +21,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
(struct ccsr_ddr __iomem *)CFG_SYS_FSL_DDR_ADDR;
if (ctrl_num != 0) {
- printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
+ printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return;
}
diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen2.c b/drivers/ddr/fsl/mpc85xx_ddr_gen2.c
index 00b4b376dd4..3a8ad6cc86b 100644
--- a/drivers/ddr/fsl/mpc85xx_ddr_gen2.c
+++ b/drivers/ddr/fsl/mpc85xx_ddr_gen2.c
@@ -26,7 +26,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
#endif
if (ctrl_num) {
- printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
+ printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return;
}
diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
index b0a61fa2b41..ee9811481ab 100644
--- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
+++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
@@ -71,7 +71,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
break;
#endif
default:
- printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
+ printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return;
}
diff --git a/drivers/ddr/imx/imx9/Kconfig b/drivers/ddr/imx/imx9/Kconfig
index b953bca4f06..7b3dbf53dff 100644
--- a/drivers/ddr/imx/imx9/Kconfig
+++ b/drivers/ddr/imx/imx9/Kconfig
@@ -29,4 +29,11 @@ config SAVED_DRAM_TIMING_BASE
after DRAM is trained, need to save the dram related timming
info into memory for low power use.
+config QB_SAVED_STATE_BASE
+ hex "Define the base address for saved QuickBoot state"
+ default 0x8fe00000
+ help
+ Once DRAM is trained, the resulted training info is
+ saved into memory in order to be reachable from U-Boot.
+
endmenu
diff --git a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig
index d904982c800..8c9b377e8a3 100644
--- a/drivers/dma/ti/Kconfig
+++ b/drivers/dma/ti/Kconfig
@@ -3,14 +3,14 @@
if ARCH_K3
config TI_K3_NAVSS_UDMA
- bool "Texas Instruments UDMA"
- depends on ARCH_K3
- select DEVRES
- select DMA
- select TI_K3_NAVSS_RINGACC
- select TI_K3_PSIL
- help
- Support for UDMA used in K3 devices.
+ bool "Texas Instruments UDMA"
+ depends on ARCH_K3
+ select DEVRES
+ select DMA
+ select TI_K3_NAVSS_RINGACC
+ select TI_K3_PSIL
+ help
+ Support for UDMA used in K3 devices.
endif
config TI_K3_PSIL
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index 11d9c8e8460..9bc782ccd02 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -263,7 +263,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
/* Write new kernel size to boot image header */
hdr->kernel_size = download_bytes;
res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
- if (res == 0) {
+ if (res != hdr_sectors) {
pr_err("cannot writeback boot image header\n");
fastboot_fail("cannot write back boot image header", response);
return -1;
@@ -275,7 +275,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
sectors_per_page;
res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
download_buffer);
- if (res == 0) {
+ if (res != kernel_sectors) {
pr_err("cannot write new kernel\n");
fastboot_fail("cannot write new kernel", response);
return -1;
@@ -287,7 +287,7 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
sectors_per_page;
res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
ramdisk_buffer);
- if (res == 0) {
+ if (res != ramdisk_sectors) {
pr_err("cannot write back original ramdisk\n");
fastboot_fail("cannot write back original ramdisk", response);
return -1;
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 220de731950..f524f741e54 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -14,7 +14,7 @@ config ARM_PSCI_FW
select FIRMWARE
config TI_SCI_PROTOCOL
- tristate "TI System Control Interface (TISCI) Message Protocol"
+ bool "TI System Control Interface (TISCI) Message Protocol"
depends on K3_SEC_PROXY
select DEVRES
select FIRMWARE
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index fb583580ebe..6052a31b5b4 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -3,10 +3,11 @@
* Xilinx Zynq MPSoC Firmware driver
*
* Copyright (C) 2018-2019 Xilinx, Inc.
- * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc.
+ * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc.
*/
#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <cpu_func.h>
#include <dm.h>
@@ -16,6 +17,7 @@
#include <zynqmp_firmware.h>
#include <asm/cache.h>
#include <asm/ptrace.h>
+#include <asm/system.h>
#include <linux/bitfield.h>
#if defined(CONFIG_ZYNQMP_IPI)
@@ -197,6 +199,58 @@ int zynqmp_pm_ufs_cal_reg(u32 *value)
*value = readl(PMXC_EFUSE_CACHE_BASE_ADDRESS + PMXC_UFS_CAL_1_OFFSET);
return 0;
}
+#endif /* CONFIG_ARCH_VERSAL2 */
+
+#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2)
+u32 zynqmp_pm_get_pmc_global_pggs_reg(u32 reg_addr)
+{
+ int ret;
+ u32 value = 0;
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+
+ if (reg_addr == PMC_GLOBAL_PGGS3_REG) {
+ value = 0;
+ } else if (reg_addr == PMC_GLOBAL_PGGS4_REG) {
+ value = 1;
+ } else {
+ printf("%s: not supported pggs register 0x%x\n",
+ __func__, reg_addr);
+ return 0;
+ }
+
+ ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_READ_PGGS);
+ if (ret) {
+ ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_READ_REG);
+ if (ret) {
+ printf("%s: IOCTL_READ_REG is not supported : %d\n"
+ , __func__, ret);
+ return 0;
+ }
+
+ /* find node ID from the pggs3 offset */
+ value = PM_REG_PGGS3 + value;
+
+ ret = xilinx_pm_request(PM_IOCTL, value,
+ IOCTL_READ_REG, 0, 0, 0, 0,
+ ret_payload);
+ if (ret) {
+ printf("%s: node 0x%x get pggs register failed\n",
+ __func__, value);
+ return 0;
+ }
+ } else {
+ ret = xilinx_pm_request(PM_IOCTL, PMC_GLOBAL_PGGS3_REG_NODE,
+ IOCTL_READ_PGGS, value, 0, 0, 0,
+ ret_payload);
+ if (ret) {
+ printf("%s: node 0x%x get pggs register failed\n",
+ __func__, PMC_GLOBAL_PGGS3_REG_NODE);
+ return 0;
+ }
+ }
+
+ return ret_payload[1];
+}
#endif
int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config, u32 value)
@@ -274,6 +328,93 @@ u32 zynqmp_pm_get_pmc_multi_boot_reg(void)
}
#endif
+#if defined(CONFIG_ARCH_VERSAL)
+u32 versal_pmc_multi_boot(void)
+{
+ /* At EL3 the SMC path to firmware is unavailable, read directly */
+ if (current_el() == 3)
+ return versal_multi_boot_reg();
+
+ return zynqmp_pm_get_pmc_multi_boot_reg() & PMC_MULTI_BOOT_MASK;
+}
+
+u8 versal_get_bootmode(void)
+{
+ u32 reg;
+
+ /* At EL3 the SMC path to firmware is unavailable, read directly */
+ if (current_el() == 3)
+ reg = versal_bootmode_reg();
+ else
+ reg = zynqmp_pm_get_bootmode_reg();
+
+ if (reg >> BOOT_MODE_ALT_SHIFT)
+ reg >>= BOOT_MODE_ALT_SHIFT;
+
+ return reg & BOOT_MODES_MASK;
+}
+#endif
+
+#if defined(CONFIG_ARCH_VERSAL_NET)
+u8 versal_net_get_bootmode(void)
+{
+ u32 reg;
+
+ /* At EL3 the SMC path to firmware is unavailable, read directly */
+ if (current_el() == 3)
+ reg = versal_net_bootmode_reg();
+ else
+ reg = zynqmp_pm_get_bootmode_reg();
+
+ if (reg >> BOOT_MODE_ALT_SHIFT)
+ reg >>= BOOT_MODE_ALT_SHIFT;
+
+ return reg & BOOT_MODES_MASK;
+}
+#endif
+
+#if defined(CONFIG_ARCH_ZYNQMP)
+int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value)
+{
+ /* At EL3 or in SPL the firmware (SMC) path is unavailable */
+ if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3)
+ return zynqmp_mmio_rawwrite(address, mask, value);
+
+ return xilinx_pm_request(PM_MMIO_WRITE, address, mask, value,
+ 0, 0, 0, NULL);
+}
+
+int zynqmp_mmio_read(const u32 address, u32 *value)
+{
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+ int ret;
+
+ if (!value)
+ return -EINVAL;
+
+ /* At EL3 or in SPL the firmware (SMC) path is unavailable */
+ if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3)
+ return zynqmp_mmio_rawread(address, value);
+
+ ret = xilinx_pm_request(PM_MMIO_READ, address, 0, 0, 0, 0, 0,
+ ret_payload);
+ *value = ret_payload[1];
+
+ return ret;
+}
+#endif
+
+#if defined(CONFIG_ARCH_VERSAL2)
+u32 versal2_pmc_multi_boot(void)
+{
+ /* At EL3 the SMC path to firmware is unavailable, read directly */
+ if (current_el() == 3)
+ return versal2_multi_boot_reg();
+
+ return zynqmp_pm_get_pmc_multi_boot_reg() & PMC_MULTI_BOOT_MASK;
+}
+#endif
+
int zynqmp_pm_feature(const u32 api_id)
{
int ret;
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index b6838a244d2..2e3223e1c32 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -186,10 +186,6 @@ static int psci_bind(struct udevice *dev)
NULL);
if (ret)
pr_debug("PSCI System Reset was not bound.\n");
- if (IS_ENABLED(CONFIG_SYSRESET_QCOM_PSCI) &&
- device_bind_driver(dev, "qcom_psci-sysreset",
- "qcom_psci-sysreset", NULL))
- pr_debug("QCOM PSCI System Reset was not bound.\n");
}
/* From PSCI v1.0 onward we can discover services through ARM_SMCCC_FEATURE */
diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c
index 822183c5785..69d7111a5f1 100644
--- a/drivers/fpga/altera.c
+++ b/drivers/fpga/altera.c
@@ -12,8 +12,7 @@
/*
* Altera FPGA support
*/
-#if IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX) || \
- IS_ENABLED(CONFIG_ARCH_SOCFPGA_STRATIX10)
+#if IS_ENABLED(CONFIG_FPGA_INTEL_SDM_MAILBOX)
#include <asm/arch/misc.h>
#endif
#include <errno.h>
@@ -48,8 +47,7 @@ static const struct altera_fpga {
#endif
};
-#if IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX) || \
- IS_ENABLED(CONFIG_ARCH_SOCFPGA_STRATIX10)
+#if IS_ENABLED(CONFIG_FPGA_INTEL_SDM_MAILBOX)
int fpga_is_partial_data(int devnum, size_t img_len)
{
/*
diff --git a/drivers/fpga/spartan2.c b/drivers/fpga/spartan2.c
index 792e4033428..e3715bf2b24 100644
--- a/drivers/fpga/spartan2.c
+++ b/drivers/fpga/spartan2.c
@@ -52,7 +52,7 @@ static int spartan2_load(xilinx_desc *desc, const void *buf, size_t bsize,
default:
printf ("%s: Unsupported interface type, %d\n",
- __FUNCTION__, desc->iface);
+ __func__, desc->iface);
}
return ret_val;
@@ -75,7 +75,7 @@ static int spartan2_dump(xilinx_desc *desc, const void *buf, size_t bsize)
default:
printf ("%s: Unsupported interface type, %d\n",
- __FUNCTION__, desc->iface);
+ __func__, desc->iface);
}
return ret_val;
@@ -234,7 +234,7 @@ static int spartan2_sp_load(xilinx_desc *desc, const void *buf, size_t bsize)
#endif
} else {
- printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ printf("%s: NULL Interface function table!\n", __func__);
}
return ret_val;
@@ -279,7 +279,7 @@ static int spartan2_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize)
/* XXX - checksum the data? */
} else {
- printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ printf("%s: NULL Interface function table!\n", __func__);
}
return ret_val;
@@ -423,7 +423,7 @@ static int spartan2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
#endif
} else {
- printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ printf("%s: NULL Interface function table!\n", __func__);
}
return ret_val;
@@ -434,7 +434,7 @@ static int spartan2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
/* Readback is only available through the Slave Parallel and */
/* boundary-scan interfaces. */
printf ("%s: Slave Serial Dumping is unavailable\n",
- __FUNCTION__);
+ __func__);
return FPGA_FAIL;
}
diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c
index 98405589134..6221041e092 100644
--- a/drivers/fpga/spartan3.c
+++ b/drivers/fpga/spartan3.c
@@ -57,7 +57,7 @@ static int spartan3_load(xilinx_desc *desc, const void *buf, size_t bsize,
default:
printf ("%s: Unsupported interface type, %d\n",
- __FUNCTION__, desc->iface);
+ __func__, desc->iface);
}
return ret_val;
@@ -80,7 +80,7 @@ static int spartan3_dump(xilinx_desc *desc, const void *buf, size_t bsize)
default:
printf ("%s: Unsupported interface type, %d\n",
- __FUNCTION__, desc->iface);
+ __func__, desc->iface);
}
return ret_val;
@@ -241,7 +241,7 @@ static int spartan3_sp_load(xilinx_desc *desc, const void *buf, size_t bsize)
#endif
} else {
- printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ printf("%s: NULL Interface function table!\n", __func__);
}
return ret_val;
@@ -286,7 +286,7 @@ static int spartan3_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize)
/* XXX - checksum the data? */
} else {
- printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ printf("%s: NULL Interface function table!\n", __func__);
}
return ret_val;
@@ -442,7 +442,7 @@ static int spartan3_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
#endif
} else {
- printf ("%s: NULL Interface function table!\n", __FUNCTION__);
+ printf("%s: NULL Interface function table!\n", __func__);
}
return ret_val;
@@ -453,7 +453,7 @@ static int spartan3_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
/* Readback is only available through the Slave Parallel and */
/* boundary-scan interfaces. */
printf ("%s: Slave Serial Dumping is unavailable\n",
- __FUNCTION__);
+ __func__);
return FPGA_FAIL;
}
diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c
index 44d7ad6bd54..b6966c7d2cb 100644
--- a/drivers/fpga/xilinx.c
+++ b/drivers/fpga/xilinx.c
@@ -149,8 +149,8 @@ int fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
int xilinx_load(xilinx_desc *desc, const void *buf, size_t bsize,
bitstream_type bstype, int flags)
{
- if (!xilinx_validate (desc, (char *)__FUNCTION__)) {
- printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+ if (!xilinx_validate(desc, (char *)__func__)) {
+ printf("%s: Invalid device descriptor\n", __func__);
return FPGA_FAIL;
}
@@ -200,8 +200,8 @@ int xilinx_loads(xilinx_desc *desc, const void *buf, size_t bsize,
int xilinx_dump(xilinx_desc *desc, const void *buf, size_t bsize)
{
- if (!xilinx_validate (desc, (char *)__FUNCTION__)) {
- printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+ if (!xilinx_validate(desc, (char *)__func__)) {
+ printf("%s: Invalid device descriptor\n", __func__);
return FPGA_FAIL;
}
@@ -217,7 +217,7 @@ int xilinx_info(xilinx_desc *desc)
{
int ret_val = FPGA_FAIL;
- if (xilinx_validate (desc, (char *)__FUNCTION__)) {
+ if (xilinx_validate(desc, (char *)__func__)) {
printf ("Family: \t");
switch (desc->family) {
case xilinx_spartan2:
@@ -293,7 +293,7 @@ int xilinx_info(xilinx_desc *desc)
ret_val = FPGA_SUCCESS;
} else {
- printf ("%s: Invalid device descriptor\n", __FUNCTION__);
+ printf("%s: Invalid device descriptor\n", __func__);
}
return ret_val;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0b5466b39b8..a11f3043670 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -294,9 +294,9 @@ config MAX7320_GPIO
bool "MAX7320 I2C GPIO Expander driver"
depends on DM_GPIO && DM_I2C
help
- Support for MAX7320 I2C 8/16-bit GPIO expander.
- original maxim device has 8 push/pull outputs,
- some clones offers 16bit.
+ Support for MAX7320 I2C 8/16-bit GPIO expander.
+ original maxim device has 8 push/pull outputs,
+ some clones offers 16bit.
config MAX77663_GPIO
bool "MAX77663 GPIO cell of PMIC driver"
@@ -309,27 +309,27 @@ config MAX77663_GPIO
config MCP230XX_GPIO
bool "MCP230XX GPIO driver"
- depends on DM
+ depends on DM && DM_I2C && DM_SPI
help
- Support for Microchip's MCP230XX I2C connected GPIO devices.
+ Support for Microchip's MCP230XX I2C and SPI connected GPIO devices.
The following chips are supported:
- - MCP23008
- - MCP23017
- - MCP23018
- - MCP23S08
- - MCP23S17
- - MCP23S18
+ - MCP23008
+ - MCP23017
+ - MCP23018
+ - MCP23S08
+ - MCP23S17
+ - MCP23S18
config MSCC_SGPIO
bool "Microsemi Serial GPIO driver"
depends on DM_GPIO && SOC_VCOREIII
help
Support for the VCoreIII SoC serial GPIO device. By using a
- serial interface, the SIO controller significantly extends
- the number of available GPIOs with a minimum number of
- additional pins on the device. The primary purpose of the
- SIO controller is to connect control signals from SFP
- modules and to act as an LED controller.
+ serial interface, the SIO controller significantly extends
+ the number of available GPIOs with a minimum number of
+ additional pins on the device. The primary purpose of the
+ SIO controller is to connect control signals from SFP
+ modules and to act as an LED controller.
config MSM_GPIO
bool "Qualcomm GPIO driver"
@@ -404,8 +404,8 @@ config PCF8575_GPIO
bool "PCF8575 I2C GPIO Expander driver"
depends on DM_GPIO && DM_I2C
help
- Support for PCF8575 I2C 16-bit GPIO expander. Most of these
- chips are from NXP and TI.
+ Support for PCF8575 I2C 16-bit GPIO expander. Most of these
+ chips are from NXP and TI.
config RCAR_GPIO
bool "Renesas R-Car GPIO driver"
@@ -449,6 +449,14 @@ config SANDBOX_GPIO_COUNT
of 'anonymous' GPIOs that do not belong to any device or bank.
Select a suitable value depending on your needs.
+config SPACEMIT_GPIO
+ bool "Spacemit K1 GPIO driver"
+ depends on DM_GPIO && TARGET_SPACEMIT_K1
+ help
+ Support the GPIO device in Spacemit SoCs. The GPIOs are arranged
+ into a number of banks (different for each SoC type) each with 32
+ GPIOs.
+
config SUNXI_GPIO
bool "Allwinner GPIO driver"
depends on ARCH_SUNXI
@@ -459,9 +467,9 @@ config SUNXI_GPIO
config SUNXI_NEW_PINCTRL
bool
depends on SUNXI_GPIO
- ---help---
- The Allwinner D1 and other new SoCs use a different register map
- for the GPIO block, which we need to know about in the SPL.
+ help
+ The Allwinner D1 and other new SoCs use a different register map
+ for the GPIO block, which we need to know about in the SPL.
config XILINX_GPIO
bool "Xilinx GPIO driver"
@@ -728,15 +736,15 @@ config SLG7XL45106_I2C_GPO
bool "slg7xl45106 i2c gpo expander"
depends on DM_GPIO && ARCH_ZYNQMP
help
- Support for slg7xl45106 i2c gpo expander. It is an i2c based
- 8-bit gpo expander, all gpo lines are controlled by writing
- value into data register.
+ Support for slg7xl45106 i2c gpo expander. It is an i2c based
+ 8-bit gpo expander, all gpo lines are controlled by writing
+ value into data register.
config GPIO_SCMI
bool "SCMI GPIO pinctrl driver"
depends on DM_GPIO && PINCTRL_SCMI
help
- Support pinctrl GPIO over the SCMI interface.
+ Support pinctrl GPIO over the SCMI interface.
config ADP5585_GPIO
bool "ADP5585 GPIO driver"
@@ -756,10 +764,11 @@ config SPL_ADP5585_GPIO
depends on SPL_DM_GPIO && SPL_I2C
help
Support ADP5585 GPIO expander in SPL.
+
config MPFS_GPIO
bool "Enable Polarfire SoC GPIO driver"
depends on DM_GPIO
help
- Enable to support the GPIO driver on Polarfire SoC
+ Enable to support the GPIO driver on Polarfire SoC
endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 863557e45ce..020e23c7252 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o
obj-$(CONFIG_MSM_GPIO) += msm_gpio.o
obj-$(CONFIG_$(PHASE_)PCF8575_GPIO) += pcf8575_gpio.o
obj-$(CONFIG_$(PHASE_)QCOM_PMIC_GPIO) += qcom_pmic_gpio.o qcom_spmi_gpio.o
+obj-$(CONFIG_$(PHASE_)SPACEMIT_GPIO) += spacemit_gpio.o
obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o
obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o
obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o
diff --git a/drivers/gpio/gpio-aspeed-g7.c b/drivers/gpio/gpio-aspeed-g7.c
index 4607468ca05..ae330173f38 100644
--- a/drivers/gpio/gpio-aspeed-g7.c
+++ b/drivers/gpio/gpio-aspeed-g7.c
@@ -131,7 +131,7 @@ static int aspeed_gpio_probe(struct udevice *dev)
uc_priv->bank_name = dev->name;
ofnode_read_u32(dev_ofnode(dev), "ngpios", &uc_priv->gpio_count);
- priv->regs = devfdt_get_addr_ptr(dev);
+ priv->regs = dev_read_addr_ptr(dev);
return 0;
}
diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c
index 4bbdec756f3..d6144d5706b 100644
--- a/drivers/gpio/gpio-aspeed-sgpio.c
+++ b/drivers/gpio/gpio-aspeed-sgpio.c
@@ -223,9 +223,9 @@ static int aspeed_sgpio_probe(struct udevice *dev)
ulong apb_freq;
int ret;
- priv->base = devfdt_get_addr_ptr(dev);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
+ priv->base = dev_read_addr_ptr(dev);
+ if (!priv->base)
+ return -EINVAL;
priv->pdata = (const struct aspeed_sgpio_pdata *)dev_get_driver_data(dev);
if (!priv->pdata)
diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index c5608f4a9df..54a786c4dc0 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -275,7 +275,7 @@ static int aspeed_gpio_probe(struct udevice *dev)
uc_priv->bank_name = dev->name;
ofnode_read_u32(dev_ofnode(dev), "ngpios", &uc_priv->gpio_count);
- priv->regs = devfdt_get_addr_ptr(dev);
+ priv->regs = dev_read_addr_ptr(dev);
return 0;
}
diff --git a/drivers/gpio/gpio-fxl6408.c b/drivers/gpio/gpio-fxl6408.c
index c8d2dff5f7b..180799139b3 100644
--- a/drivers/gpio/gpio-fxl6408.c
+++ b/drivers/gpio/gpio-fxl6408.c
@@ -273,7 +273,7 @@ static int fxl6408_probe(struct udevice *dev)
u32 val32;
addr = dev_read_addr(dev);
- if (addr == 0)
+ if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
info->addr = addr;
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 7651d5360d6..4d40738e5aa 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -877,8 +877,19 @@ static int get_function(struct udevice *dev, int offset, bool skip_unused,
return -ENODEV;
if (offset < 0 || offset >= uc_priv->gpio_count)
return -EINVAL;
- if (namep)
+ if (namep) {
*namep = uc_priv->name[offset];
+ /* Fall back to DT "gpio-line-names" for unrequested pins. */
+ if (CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LINE_NAME) &&
+ (!*namep || !**namep)) {
+ const char *dt_name = NULL;
+
+ if (!dev_read_string_index(dev, "gpio-line-names",
+ offset, &dt_name) &&
+ dt_name && *dt_name)
+ *namep = dt_name;
+ }
+ }
if (skip_unused && !gpio_is_claimed(uc_priv, offset))
return GPIOF_UNUSED;
if (ops->get_function) {
diff --git a/drivers/gpio/imx_rgpio2p.c b/drivers/gpio/imx_rgpio2p.c
index 7cf178f8a48..ba3c5fcf25b 100644
--- a/drivers/gpio/imx_rgpio2p.c
+++ b/drivers/gpio/imx_rgpio2p.c
@@ -194,11 +194,11 @@ static int imx_rgpio2p_bind(struct udevice *dev)
dual_base = true;
if (dual_base) {
- addr = devfdt_get_addr_index(dev, 1);
+ addr = dev_read_addr_index(dev, 1);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
} else {
- addr = devfdt_get_addr_index(dev, 0);
+ addr = dev_read_addr_index(dev, 0);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c
index 709d04017d1..40646407369 100644
--- a/drivers/gpio/mpc8xxx_gpio.c
+++ b/drivers/gpio/mpc8xxx_gpio.c
@@ -171,6 +171,58 @@ static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio)
return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
}
+static int mpc8xxx_gpio_set_flags(struct udevice *dev, uint gpio,
+ ulong flags)
+{
+ u32 mask = gpio_mask(gpio);
+ int ret;
+
+ /* The QorIQ GPIO pad supports open-drain only; open-source has
+ * no silicon counterpart, so reject it rather than silently
+ * pretending.
+ */
+ if (flags & GPIOD_OPEN_SOURCE)
+ return -EOPNOTSUPP;
+
+ /* GPODR is per-pin and meaningful in both directions (it stays
+ * latched when the pin is re-purposed), so apply it before the
+ * direction change.
+ */
+ if (flags & GPIOD_OPEN_DRAIN)
+ mpc8xxx_gpio_open_drain_on(dev, mask);
+ else
+ mpc8xxx_gpio_open_drain_off(dev, mask);
+
+ if (flags & GPIOD_IS_OUT) {
+ ret = mpc8xxx_gpio_direction_output(dev, gpio,
+ !!(flags & GPIOD_IS_OUT_ACTIVE));
+ } else if (flags & GPIOD_IS_IN) {
+ ret = mpc8xxx_gpio_direction_input(dev, gpio);
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int mpc8xxx_gpio_get_flags(struct udevice *dev, uint gpio,
+ ulong *flagsp)
+{
+ u32 mask = gpio_mask(gpio);
+ ulong flags = 0;
+
+ if (mpc8xxx_gpio_get_dir(dev, mask))
+ flags |= GPIOD_IS_OUT;
+ else
+ flags |= GPIOD_IS_IN;
+
+ if (mpc8xxx_gpio_open_drain_val(dev, mask))
+ flags |= GPIOD_OPEN_DRAIN;
+
+ *flagsp = flags;
+ return 0;
+}
+
#if CONFIG_IS_ENABLED(OF_CONTROL)
static int mpc8xxx_gpio_of_to_plat(struct udevice *dev)
{
@@ -255,6 +307,8 @@ static const struct dm_gpio_ops gpio_mpc8xxx_ops = {
.get_value = mpc8xxx_gpio_get_value,
.set_value = mpc8xxx_gpio_set_value,
.get_function = mpc8xxx_gpio_get_function,
+ .set_flags = mpc8xxx_gpio_set_flags,
+ .get_flags = mpc8xxx_gpio_get_flags,
};
static const struct udevice_id mpc8xxx_gpio_ids[] = {
diff --git a/drivers/gpio/nx_gpio.c b/drivers/gpio/nx_gpio.c
index 5abbb34daea..1c3d27eb1cc 100644
--- a/drivers/gpio/nx_gpio.c
+++ b/drivers/gpio/nx_gpio.c
@@ -213,9 +213,10 @@ static int nx_gpio_of_to_plat(struct udevice *dev)
{
struct nx_gpio_plat *plat = dev_get_plat(dev);
- plat->regs = map_physmem(devfdt_get_addr(dev),
- sizeof(struct nx_gpio_regs),
- MAP_NOCACHE);
+ plat->regs = dev_remap_addr(dev);
+ if (!plat->regs)
+ return -EINVAL;
+
plat->gpio_count = dev_read_s32_default(dev, "nexell,gpio-bank-width",
32);
plat->bank_name = dev_read_string(dev, "gpio-bank-name");
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
index 523ca8473a8..965a5fcf30b 100644
--- a/drivers/gpio/pca953x_gpio.c
+++ b/drivers/gpio/pca953x_gpio.c
@@ -312,7 +312,7 @@ static int pca953x_probe(struct udevice *dev)
u8 val[MAX_BANK];
addr = dev_read_addr(dev);
- if (addr == 0)
+ if (addr == FDT_ADDR_T_NONE)
return -ENODEV;
info->addr = addr;
diff --git a/drivers/gpio/qcom_pmic_gpio.c b/drivers/gpio/qcom_pmic_gpio.c
index 4458c55cd3d..ad4a70dd49b 100644
--- a/drivers/gpio/qcom_pmic_gpio.c
+++ b/drivers/gpio/qcom_pmic_gpio.c
@@ -344,7 +344,6 @@ static int qcom_gpio_probe(struct udevice *dev)
static const struct udevice_id qcom_gpio_ids[] = {
{ .compatible = "qcom,pm8916-gpio" },
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
- { .compatible = "qcom,pm8998-gpio" },
{ .compatible = "qcom,pms405-gpio" },
{ .compatible = "qcom,pm6125-gpio" },
{ .compatible = "qcom,pm8150-gpio" },
@@ -410,7 +409,7 @@ static int qcom_pmic_pinctrl_generic_pinmux_set_mux(struct udevice *dev, unsigne
return 0;
}
-struct pinctrl_ops qcom_pmic_pinctrl_ops = {
+static const struct pinctrl_ops qcom_pmic_pinctrl_ops = {
.get_pins_count = qcom_pmic_pinctrl_get_pins_count,
.get_pin_name = qcom_pmic_pinctrl_get_pin_name,
.set_state = pinctrl_generic_set_state,
diff --git a/drivers/gpio/qcom_spmi_gpio.c b/drivers/gpio/qcom_spmi_gpio.c
index 77a69140213..3efee206007 100644
--- a/drivers/gpio/qcom_spmi_gpio.c
+++ b/drivers/gpio/qcom_spmi_gpio.c
@@ -752,6 +752,7 @@ static const struct udevice_id qcom_spmi_pmic_gpio_ids[] = {
{ .compatible = "qcom,pm8550b-gpio" },
{ .compatible = "qcom,pm8550ve-gpio" },
{ .compatible = "qcom,pm8550vs-gpio" },
+ { .compatible = "qcom,pm8998-gpio" },
{ .compatible = "qcom,pmk8550-gpio" },
{ .compatible = "qcom,pmr735d-gpio" },
{ }
@@ -1020,7 +1021,7 @@ static int qcom_spmi_pmic_pinctrl_pinmux_set_mux(struct udevice *dev, unsigned i
return spmi_pmic_gpio_write(plat, pad, PMIC_GPIO_REG_EN_CTL, val);
}
-struct pinctrl_ops qcom_spmi_pmic_pinctrl_ops = {
+static const struct pinctrl_ops qcom_spmi_pmic_pinctrl_ops = {
.get_pins_count = qcom_spmi_pmic_pinctrl_get_pins_count,
.get_pin_name = qcom_spmi_pmic_pinctrl_get_pin_name,
.set_state = pinctrl_generic_set_state,
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index e8f50d815d7..76aff0ed5aa 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -306,7 +306,7 @@ static int sb_gpio_get_name(const struct udevice *dev, char *out_name)
return acpi_copy_name(out_name, "GPIO");
}
-struct acpi_ops gpio_sandbox_acpi_ops = {
+static const struct acpi_ops gpio_sandbox_acpi_ops = {
.get_name = sb_gpio_get_name,
};
#endif /* ACPIGEN */
@@ -568,7 +568,7 @@ static struct pinctrl_ops sandbox_pinctrl_gpio_ops = {
};
#if CONFIG_IS_ENABLED(ACPIGEN)
-struct acpi_ops pinctrl_sandbox_acpi_ops = {
+static const struct acpi_ops pinctrl_sandbox_acpi_ops = {
.get_name = sb_pinctrl_get_name,
};
#endif
diff --git a/drivers/gpio/spacemit_gpio.c b/drivers/gpio/spacemit_gpio.c
new file mode 100644
index 00000000000..de71880df15
--- /dev/null
+++ b/drivers/gpio/spacemit_gpio.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ */
+
+#include <asm/gpio.h>
+#include <clk.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/pinctrl.h>
+#include <dm/read.h>
+#include <dm/uclass.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <log.h>
+
+#define GPIO_BANK_SIZE 32
+#define GPIO_TO_BANK(pin) ((pin) / GPIO_BANK_SIZE)
+#define GPIO_TO_BIT(pin) ((pin) % GPIO_BANK_SIZE)
+
+static inline int gpio_to_reg_offset(unsigned int pin)
+{
+ unsigned int bank = GPIO_TO_BANK(pin);
+
+ if (bank == 0)
+ return 0;
+ else if (bank == 1)
+ return 4;
+ else if (bank == 2)
+ return 8;
+ else if (bank == 3)
+ return 0x100;
+ log_warning("Use default GPIO bank for an invalid GPIO[%d].\n", pin);
+ return 0;
+}
+
+#define REG_PLR(pin) (0x00 + gpio_to_reg_offset(pin))
+#define REG_PDR(pin) (0x0c + gpio_to_reg_offset(pin))
+#define REG_PSR(pin) (0x18 + gpio_to_reg_offset(pin))
+#define REG_PCR(pin) (0x24 + gpio_to_reg_offset(pin))
+#define REG_SDR(pin) (0x54 + gpio_to_reg_offset(pin))
+#define REG_CDR(pin) (0x60 + gpio_to_reg_offset(pin))
+
+struct spacemit_gpio_data {
+ u16 gpio_base;
+ u16 gpio_count;
+ u8 num_banks;
+};
+
+struct spacemit_gpio_priv {
+ void __iomem *regs;
+};
+
+static int spacemit_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+ struct ofnode_phandle_args *args)
+{
+ struct spacemit_gpio_data *data;
+ u32 bank, offset, flags;
+
+ data = (struct spacemit_gpio_data *)dev_get_driver_data(dev);
+ if (args->args_count < 3) {
+ dev_err(dev, "Invalid args count: %d, expected 3\n",
+ args->args_count);
+ return -EINVAL;
+ }
+ bank = args->args[0];
+ offset = args->args[1];
+ flags = args->args[2];
+
+ if (bank >= data->num_banks) {
+ dev_err(dev, "Invalid gpio bank: %u (max %u)\n",
+ bank, data->num_banks - 1);
+ return -EINVAL;
+ }
+ if (offset >= GPIO_BANK_SIZE) {
+ dev_err(dev, "Invalid offset: %u (max 31)\n", offset);
+ return -EINVAL;
+ }
+ desc->offset = bank * GPIO_BANK_SIZE + offset;
+ desc->flags = gpio_flags_xlate(flags);
+ return 0;
+}
+
+static int spacemit_gpio_get_value(struct udevice *dev, unsigned int offset)
+{
+ struct spacemit_gpio_priv *priv = dev_get_priv(dev);
+ void __iomem *addr;
+ u32 value, mask;
+
+ addr = priv->regs + REG_PLR(offset);
+ value = readl(addr);
+ mask = 1 << GPIO_TO_BIT(offset);
+ return !!(value & mask);
+}
+
+static int spacemit_gpio_get_function(struct udevice *dev, unsigned int offset)
+{
+ struct spacemit_gpio_priv *priv = dev_get_priv(dev);
+ void __iomem *addr;
+ u32 value, mask;
+
+ addr = priv->regs + REG_PDR(offset);
+ value = readl(addr);
+ mask = 1 << GPIO_TO_BIT(offset);
+ if (value & mask)
+ return GPIOF_OUTPUT;
+ return GPIOF_INPUT;
+}
+
+static int spacemit_gpio_get_flags(struct udevice *dev, unsigned int offset,
+ ulong *flagsp)
+{
+ ulong flags = 0;
+ u32 dir;
+
+ dir = spacemit_gpio_get_function(dev, offset);
+ if (dir) {
+ flags |= GPIOD_IS_OUT;
+ if (spacemit_gpio_get_value(dev, offset))
+ flags |= GPIOD_IS_OUT_ACTIVE;
+ } else {
+ flags |= GPIOD_IS_IN;
+ }
+ *flagsp = flags;
+ return 0;
+}
+
+static int spacemit_gpio_set_flags(struct udevice *dev, unsigned int offset,
+ ulong flags)
+{
+ struct spacemit_gpio_priv *priv = dev_get_priv(dev);
+ void __iomem *addr;
+ int value;
+
+ value = (flags & GPIOD_IS_OUT_ACTIVE) ? 1 : 0;
+ if (flags & GPIOD_IS_IN) {
+ addr = priv->regs + REG_CDR(offset);
+ writel(1 << GPIO_TO_BIT(offset), addr);
+ }
+ if (flags & GPIOD_IS_OUT) {
+ if (value) {
+ addr = priv->regs + REG_PSR(offset);
+ writel(1 << GPIO_TO_BIT(offset), addr);
+ } else {
+ addr = priv->regs + REG_PCR(offset);
+ writel(1 << GPIO_TO_BIT(offset), addr);
+ }
+ addr = priv->regs + REG_SDR(offset);
+ writel(1 << GPIO_TO_BIT(offset), addr);
+ }
+ return 0;
+}
+
+static int spacemit_gpio_request(struct udevice *dev, unsigned int offset,
+ const char *label)
+{
+ const struct pinctrl_ops *ops;
+ struct udevice *pctldev;
+ int ret;
+
+ ret = uclass_first_device_err(UCLASS_PINCTRL, &pctldev);
+ if (ret)
+ return ret;
+
+ ops = pinctrl_get_ops(pctldev);
+ if (!ops->gpio_request_enable)
+ return -ENOSYS;
+
+ return ops->gpio_request_enable(pctldev, offset);
+}
+
+static int spacemit_gpio_rfree(struct udevice *dev, unsigned int offset)
+{
+ const struct pinctrl_ops *ops;
+ struct udevice *pctldev;
+ int ret;
+
+ ret = uclass_first_device_err(UCLASS_PINCTRL, &pctldev);
+ if (ret)
+ return ret;
+
+ ops = pinctrl_get_ops(pctldev);
+ if (!ops->gpio_disable_free)
+ return -ENOSYS;
+
+ return ops->gpio_disable_free(pctldev, offset);
+}
+
+static const struct dm_gpio_ops spacemit_gpio_ops = {
+ .request = spacemit_gpio_request,
+ .rfree = spacemit_gpio_rfree,
+ .xlate = spacemit_gpio_xlate,
+ .get_value = spacemit_gpio_get_value,
+ .get_function = spacemit_gpio_get_function,
+ .get_flags = spacemit_gpio_get_flags,
+ .set_flags = spacemit_gpio_set_flags,
+};
+
+static int spacemit_gpio_probe(struct udevice *dev)
+{
+ struct spacemit_gpio_priv *priv;
+ struct spacemit_gpio_data *data;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct clk_bulk clks;
+ int ret;
+
+ data = (struct spacemit_gpio_data *)dev_get_driver_data(dev);
+ priv = dev_get_priv(dev);
+ priv->regs = dev_read_addr_ptr(dev);
+ if (!priv->regs) {
+ dev_err(dev, "Fail to get base address\n");
+ return -EINVAL;
+ }
+ uc_priv->bank_name = "GPIO";
+ uc_priv->gpio_count = data->gpio_count;
+ uc_priv->gpio_base = data->gpio_base;
+
+ ret = clk_get_bulk(dev, &clks);
+ if (ret) {
+ dev_err(dev, "Fail to get bulk clks\n");
+ return ret;
+ }
+ ret = clk_enable_bulk(&clks);
+ if (ret) {
+ dev_err(dev, "Fail to enable bulk clks\n");
+ goto out;
+ }
+ return 0;
+out:
+ clk_release_bulk(&clks);
+ return ret;
+}
+
+static const struct spacemit_gpio_data k1_gpio_data = {
+ .num_banks = 4,
+ .gpio_count = 128,
+ .gpio_base = 0,
+};
+
+static const struct udevice_id spacemit_gpio_ids[] = {
+ { .compatible = "spacemit,k1-gpio", .data = (uintptr_t)&k1_gpio_data, },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(k1_gpio) = {
+ .name = "spacemit_k1_gpio",
+ .id = UCLASS_GPIO,
+ .of_match = spacemit_gpio_ids,
+ .ops = &spacemit_gpio_ops,
+ .priv_auto = sizeof(struct spacemit_gpio_priv),
+ .probe = spacemit_gpio_probe,
+};
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 37288a47eb7..0e8b2408376 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -98,7 +98,7 @@ config SYS_I2C_EARLY_INIT
board_early_init_f.
config I2C_CROS_EC_TUNNEL
- tristate "Chrome OS EC tunnel I2C bus"
+ bool "Chrome OS EC tunnel I2C bus"
depends on CROS_EC
help
This provides an I2C bus that will tunnel i2c commands through to
@@ -110,16 +110,16 @@ config I2C_CROS_EC_TUNNEL
config I2C_CROS_EC_LDO
bool "Provide access to LDOs on the Chrome OS EC"
depends on CROS_EC
- ---help---
- On many Chromebooks the main PMIC is inaccessible to the AP. This is
- often dealt with by using an I2C pass-through interface provided by
- the EC. On some unfortunate models (e.g. Spring) the pass-through
- is not available, and an LDO message is available instead. This
- option enables a driver which provides very basic access to those
- regulators, via the EC. We implement this as an I2C bus which
- emulates just the TPS65090 messages we know about. This is done to
- avoid duplicating the logic in the TPS65090 regulator driver for
- enabling/disabling an LDO.
+ help
+ On many Chromebooks the main PMIC is inaccessible to the AP. This is
+ often dealt with by using an I2C pass-through interface provided by
+ the EC. On some unfortunate models (e.g. Spring) the pass-through
+ is not available, and an LDO message is available instead. This
+ option enables a driver which provides very basic access to those
+ regulators, via the EC. We implement this as an I2C bus which
+ emulates just the TPS65090 messages we know about. This is done to
+ avoid duplicating the logic in the TPS65090 regulator driver for
+ enabling/disabling an LDO.
config I2C_SET_DEFAULT_BUS_NUM
bool "Set default I2C bus number"
@@ -180,9 +180,9 @@ config SYS_I2C_IPROC
Say yes here to to enable the Broadco I2C driver.
config SYS_I2C_FSL
- bool "Freescale I2C bus driver"
- depends on M68K || PPC
- help
+ bool "Freescale I2C bus driver"
+ depends on M68K || PPC
+ help
Add support for Freescale I2C busses as used on MPC8240, MPC8245, and
MPC85xx processors.
@@ -213,14 +213,14 @@ config SYS_FSL_I2C4_OFFSET
endif
config SYS_I2C_CADENCE
- tristate "Cadence I2C Controller"
+ bool "Cadence I2C Controller"
depends on DM_I2C
help
Say yes here to select Cadence I2C Host Controller. This controller is
e.g. used by Xilinx Zynq.
config SYS_I2C_CA
- tristate "Cortina-Access I2C Controller"
+ bool "Cortina-Access I2C Controller"
depends on DM_I2C && CORTINA_PLATFORM
help
Add support for the Cortina Access I2C host controller.
@@ -249,14 +249,14 @@ config SYS_I2C_DW_PCI
controller.
config SYS_I2C_AST2600
- bool "AST2600 I2C Controller"
- depends on DM_I2C && ARCH_ASPEED
- help
- Say yes here to select AST2600 I2C Host Controller. The driver
- support AST2600 I2C new mode register. This I2C controller supports:
- _Standard-mode (up to 100 kHz)
- _Fast-mode (up to 400 kHz)
- _Fast-mode Plus (up to 1 MHz)
+ bool "AST2600 I2C Controller"
+ depends on DM_I2C && ARCH_ASPEED
+ help
+ Say yes here to select AST2600 I2C Host Controller. The driver
+ support AST2600 I2C new mode register. This I2C controller supports:
+ _Standard-mode (up to 100 kHz)
+ _Fast-mode (up to 400 kHz)
+ _Fast-mode Plus (up to 1 MHz)
config SYS_I2C_ASPEED
bool "Aspeed I2C Controller"
@@ -333,50 +333,50 @@ if SYS_I2C_MXC && (SYS_I2C_LEGACY || SPL_SYS_I2C_LEGACY)
config SYS_I2C_MXC_I2C1
bool "NXP MXC I2C1"
help
- Add support for NXP MXC I2C Controller 1.
- Required for SoCs which have I2C MXC controller 1 eg LS1088A, LS2080A
+ Add support for NXP MXC I2C Controller 1.
+ Required for SoCs which have I2C MXC controller 1 eg LS1088A, LS2080A
config SYS_I2C_MXC_I2C2
bool "NXP MXC I2C2"
help
- Add support for NXP MXC I2C Controller 2.
- Required for SoCs which have I2C MXC controller 2 eg LS1088A, LS2080A
+ Add support for NXP MXC I2C Controller 2.
+ Required for SoCs which have I2C MXC controller 2 eg LS1088A, LS2080A
config SYS_I2C_MXC_I2C3
bool "NXP MXC I2C3"
help
- Add support for NXP MXC I2C Controller 3.
- Required for SoCs which have I2C MXC controller 3 eg LS1088A, LS2080A
+ Add support for NXP MXC I2C Controller 3.
+ Required for SoCs which have I2C MXC controller 3 eg LS1088A, LS2080A
config SYS_I2C_MXC_I2C4
bool "NXP MXC I2C4"
help
- Add support for NXP MXC I2C Controller 4.
- Required for SoCs which have I2C MXC controller 4 eg LS1088A, LS2080A
+ Add support for NXP MXC I2C Controller 4.
+ Required for SoCs which have I2C MXC controller 4 eg LS1088A, LS2080A
config SYS_I2C_MXC_I2C5
bool "NXP MXC I2C5"
help
- Add support for NXP MXC I2C Controller 5.
- Required for SoCs which have I2C MXC controller 5 eg LX2160A
+ Add support for NXP MXC I2C Controller 5.
+ Required for SoCs which have I2C MXC controller 5 eg LX2160A
config SYS_I2C_MXC_I2C6
bool "NXP MXC I2C6"
help
- Add support for NXP MXC I2C Controller 6.
- Required for SoCs which have I2C MXC controller 6 eg LX2160A
+ Add support for NXP MXC I2C Controller 6.
+ Required for SoCs which have I2C MXC controller 6 eg LX2160A
config SYS_I2C_MXC_I2C7
bool "NXP MXC I2C7"
help
- Add support for NXP MXC I2C Controller 7.
- Required for SoCs which have I2C MXC controller 7 eg LX2160A
+ Add support for NXP MXC I2C Controller 7.
+ Required for SoCs which have I2C MXC controller 7 eg LX2160A
config SYS_I2C_MXC_I2C8
bool "NXP MXC I2C8"
help
- Add support for NXP MXC I2C Controller 8.
- Required for SoCs which have I2C MXC controller 8 eg LX2160A
+ Add support for NXP MXC I2C Controller 8.
+ Required for SoCs which have I2C MXC controller 8 eg LX2160A
endif
if SYS_I2C_MXC_I2C1
@@ -385,13 +385,13 @@ config SYS_MXC_I2C1_SPEED
default 40000000 if TARGET_LS2080A_EMU
default 100000
help
- MXC I2C Channel 1 speed
+ MXC I2C Channel 1 speed
config SYS_MXC_I2C1_SLAVE
hex "I2C1 Slave"
default 0x0
help
- MXC I2C1 Slave
+ MXC I2C1 Slave
endif
if SYS_I2C_MXC_I2C2
@@ -400,13 +400,13 @@ config SYS_MXC_I2C2_SPEED
default 40000000 if TARGET_LS2080A_EMU
default 100000
help
- MXC I2C Channel 2 speed
+ MXC I2C Channel 2 speed
config SYS_MXC_I2C2_SLAVE
hex "I2C2 Slave"
default 0x0
help
- MXC I2C2 Slave
+ MXC I2C2 Slave
endif
if SYS_I2C_MXC_I2C3
@@ -414,13 +414,13 @@ config SYS_MXC_I2C3_SPEED
int "I2C Channel 3 speed"
default 100000
help
- MXC I2C Channel 3 speed
+ MXC I2C Channel 3 speed
config SYS_MXC_I2C3_SLAVE
hex "I2C3 Slave"
default 0x0
help
- MXC I2C3 Slave
+ MXC I2C3 Slave
endif
if SYS_I2C_MXC_I2C4
@@ -428,13 +428,13 @@ config SYS_MXC_I2C4_SPEED
int "I2C Channel 4 speed"
default 100000
help
- MXC I2C Channel 4 speed
+ MXC I2C Channel 4 speed
config SYS_MXC_I2C4_SLAVE
hex "I2C4 Slave"
default 0x0
help
- MXC I2C4 Slave
+ MXC I2C4 Slave
endif
if SYS_I2C_MXC_I2C5
@@ -442,13 +442,13 @@ config SYS_MXC_I2C5_SPEED
int "I2C Channel 5 speed"
default 100000
help
- MXC I2C Channel 5 speed
+ MXC I2C Channel 5 speed
config SYS_MXC_I2C5_SLAVE
hex "I2C5 Slave"
default 0x0
help
- MXC I2C5 Slave
+ MXC I2C5 Slave
endif
if SYS_I2C_MXC_I2C6
@@ -456,13 +456,13 @@ config SYS_MXC_I2C6_SPEED
int "I2C Channel 6 speed"
default 100000
help
- MXC I2C Channel 6 speed
+ MXC I2C Channel 6 speed
config SYS_MXC_I2C6_SLAVE
hex "I2C6 Slave"
default 0x0
help
- MXC I2C6 Slave
+ MXC I2C6 Slave
endif
if SYS_I2C_MXC_I2C7
@@ -470,13 +470,13 @@ config SYS_MXC_I2C7_SPEED
int "I2C Channel 7 speed"
default 100000
help
- MXC I2C Channel 7 speed
+ MXC I2C Channel 7 speed
config SYS_MXC_I2C7_SLAVE
hex "I2C7 Slave"
default 0x0
help
- MXC I2C7 Slave
+ MXC I2C7 Slave
endif
if SYS_I2C_MXC_I2C8
@@ -484,13 +484,13 @@ config SYS_MXC_I2C8_SPEED
int "I2C Channel 8 speed"
default 100000
help
- MXC I2C Channel 8 speed
+ MXC I2C Channel 8 speed
config SYS_MXC_I2C8_SLAVE
hex "I2C8 Slave"
default 0x0
help
- MXC I2C8 Slave
+ MXC I2C8 Slave
endif
config SYS_I2C_NEXELL
@@ -668,19 +668,19 @@ config SYS_I2C_STM32F7
help
Enable this option to add support for STM32 I2C controller
introduced with STM32F7/H7 SoCs. This I2C controller supports :
- _ Slave and master modes
- _ Multimaster capability
- _ Standard-mode (up to 100 kHz)
- _ Fast-mode (up to 400 kHz)
- _ Fast-mode Plus (up to 1 MHz)
- _ 7-bit and 10-bit addressing mode
- _ Multiple 7-bit slave addresses (2 addresses, 1 with configurable mask)
- _ All 7-bit addresses acknowledge mode
- _ General call
- _ Programmable setup and hold times
- _ Easy to use event management
- _ Optional clock stretching
- _ Software reset
+ _ Slave and master modes
+ _ Multimaster capability
+ _ Standard-mode (up to 100 kHz)
+ _ Fast-mode (up to 400 kHz)
+ _ Fast-mode Plus (up to 1 MHz)
+ _ 7-bit and 10-bit addressing mode
+ _ Multiple 7-bit slave addresses (2 addresses, 1 with configurable mask)
+ _ All 7-bit addresses acknowledge mode
+ _ General call
+ _ Programmable setup and hold times
+ _ Easy to use event management
+ _ Optional clock stretching
+ _ Software reset
config SYS_I2C_SUN6I_P2WI
bool "Allwinner sun6i P2WI controller"
@@ -780,7 +780,7 @@ config SYS_I2C_BUS_MAX
int "Max I2C busses"
depends on ARCH_OMAP2PLUS || ARCH_SOCFPGA
default 3 if OMAP34XX || AM33XX || AM43XX
- default 4 if ARCH_SOCFPGA
+ default 4 if ARCH_SOCFPGA || OMAP44XX
default 5 if OMAP54XX
help
Define the maximum number of available I2C buses.
@@ -792,10 +792,17 @@ config SYS_I2C_XILINX_XIIC
Support for Xilinx AXI I2C controller.
config SYS_I2C_IHS
- bool "gdsys IHS I2C driver"
- depends on DM_I2C
- help
- Support for gdsys IHS I2C driver on FPGA bus.
+ bool "gdsys IHS I2C driver"
+ depends on DM_I2C
+ help
+ Support for gdsys IHS I2C driver on FPGA bus.
+
+config SYS_I2C_SPACEMIT_K1
+ bool "Spacemit K1 I2C driver"
+ depends on DM_I2C
+ help
+ Support for Spacemit I2C controller. It's based on
+ Driver Model.
source "drivers/i2c/muxes/Kconfig"
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 2da649e97d3..0e3a0f9fb5f 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_SYS_I2C_RZ_RIIC) += rz_riic.o
obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o exynos_hs_i2c.o
obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
+obj-$(CONFIG_SYS_I2C_SPACEMIT_K1) += k1_i2c.o
obj-$(CONFIG_SYS_I2C_STM32F7) += stm32f7_i2c.o
obj-$(CONFIG_SYS_I2C_SUN6I_P2WI) += sun6i_p2wi.o
obj-$(CONFIG_SYS_I2C_SUN8I_RSB) += sun8i_rsb.o
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 8ad716f410e..8d290acefda 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -740,13 +740,47 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr,
{
struct dw_i2c *i2c = dev_get_priv(bus);
struct i2c_regs *i2c_base = i2c->regs;
- u32 tmp;
- int ret;
+ u32 start_time, ic_status;
+ int ret = 0;
- /* Try to read the first location of the chip */
- ret = __dw_i2c_read(i2c_base, chip_addr, 0, 1, (uchar *)&tmp, 1);
+ ret = i2c_wait_for_bb(i2c_base);
if (ret)
- __dw_i2c_init(i2c_base, 0, 0);
+ return ret;
+
+ dw_i2c_enable(i2c_base, false);
+ writel(chip_addr, &i2c_base->ic_tar);
+ dw_i2c_enable(i2c_base, true);
+
+ writel(IC_STOP, &i2c_base->ic_cmd_data);
+
+ start_time = get_timer(0);
+ while (1) {
+ ic_status = readl(&i2c_base->ic_status);
+
+ if ((ic_status & IC_STATUS_TFE) && !(ic_status & IC_STATUS_MA))
+ break;
+
+ if (readl(&i2c_base->ic_raw_intr_stat) & IC_TX_ABRT) {
+ readl(&i2c_base->ic_clr_tx_abrt);
+ ret = -EREMOTEIO;
+ break;
+ }
+
+ if (get_timer(start_time) > I2C_BYTE_TO) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+ }
+
+ start_time = get_timer(0);
+ while (1) {
+ if ((readl(&i2c_base->ic_raw_intr_stat) & IC_STOP_DET)) {
+ readl(&i2c_base->ic_clr_stop_det);
+ break;
+ } else if (get_timer(start_time) > I2C_STOPDET_TO) {
+ break;
+ }
+ }
return ret;
}
diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c
index ad4122c2abd..db2706fdb6e 100644
--- a/drivers/i2c/designware_i2c_pci.c
+++ b/drivers/i2c/designware_i2c_pci.c
@@ -168,7 +168,7 @@ static int dw_i2c_acpi_fill_ssdt(const struct udevice *dev,
return 0;
}
-static struct acpi_ops dw_i2c_acpi_ops = {
+static const struct acpi_ops dw_i2c_acpi_ops = {
.fill_ssdt = dw_i2c_acpi_fill_ssdt,
};
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c
index a309fd6f07c..e2b4fd334ec 100644
--- a/drivers/i2c/imx_lpi2c.c
+++ b/drivers/i2c/imx_lpi2c.c
@@ -239,7 +239,6 @@ static int bus_i2c_stop(struct udevice *bus)
start_time = get_timer(0);
while (1) {
status = readl(&regs->msr);
- result = imx_lpci2c_check_clear_error(regs);
/* stop detect flag */
if (status & LPI2C_MSR_SDF_MASK) {
/* clear stop flag */
@@ -250,10 +249,13 @@ static int bus_i2c_stop(struct udevice *bus)
if (get_timer(start_time) > LPI2C_NACK_TOUT_MS) {
debug("stop timeout\n");
+ result = imx_lpci2c_check_clear_error(regs);
return -ETIMEDOUT;
}
}
+ result = imx_lpci2c_check_clear_error(regs);
+
return result;
}
diff --git a/drivers/i2c/k1_i2c.c b/drivers/i2c/k1_i2c.c
new file mode 100644
index 00000000000..a08ff15803d
--- /dev/null
+++ b/drivers/i2c/k1_i2c.c
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023-2026 Spacemit, Inc
+ * Copyright (C) 2025-2026 RISCstar Ltd.
+ */
+
+#include <asm/io.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <i2c.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <reset.h>
+#include "k1_i2c.h"
+
+#define ICR_OFFSET 0x00
+#define ISR_OFFSET 0x04
+#define ISAR_OFFSET 0x08
+#define IDBR_OFFSET 0x0c
+#define ILCR_OFFSET 0x10
+#define IWCR_OFFSET 0x14
+#define IRCR_OFFSET 0x18
+#define IBMR_OFFSET 0x1c
+#define WFIFO_OFFSET 0x20
+#define WFIFO_WPTR_OFFSET 0x24
+#define WFIFO_RPTR_OFFSET 0x28
+#define RFIFO_OFFSET 0x2c
+#define RFIFO_WPTR_OFFSET 0x30
+#define RFIFO_RPTR_OFFSET 0x34
+
+/* All transfers are described by this data structure */
+struct k1_i2c_msg {
+ u8 condition;
+ u8 acknack;
+ u8 direction;
+ u8 data;
+};
+
+struct k1_i2c {
+ u32 icr;
+ u32 isr;
+ u32 isar;
+ u32 idbr;
+ u32 ilcr;
+ u32 iwcr;
+ u32 irst_cyc;
+ u32 ibmr;
+};
+
+struct k1_i2c_priv {
+ int id;
+ void __iomem *base;
+ struct clk clk;
+ u32 clk_rate;
+};
+
+/*
+ * i2c_reset: - reset the host controller
+ *
+ */
+static void i2c_reset(void __iomem *base)
+{
+ u32 icr_mode;
+ u32 val;
+
+ /* Save bus mode (standard or fast speed) for later use */
+ icr_mode = readl(base + ICR_OFFSET) & ICR_MODE_MASK;
+ /* disable unit */
+ val = readl(base + ICR_OFFSET);
+ writel(val & ~ICR_IUE, base + ICR_OFFSET);
+ udelay(10);
+ /* reset the unit */
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_UR;
+ writel(val, base + ICR_OFFSET);
+ udelay(100);
+ /* disable unit */
+ val = readl(base + ICR_OFFSET);
+ writel(val & ~ICR_IUE, base + ICR_OFFSET);
+
+ /* set slave address */
+ writel(0x00, base + ISR_OFFSET);
+ /* set control reg values */
+ writel(I2C_ICR_INIT | icr_mode, base + ICR_OFFSET);
+ writel(I2C_ISR_INIT, base + ISR_OFFSET); /* set clear interrupt bits */
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_IUE;
+ writel(val, base + ICR_OFFSET); /* enable unit */
+ udelay(100);
+}
+
+static inline bool is_isr_set_or_clr(unsigned long isr, unsigned long set_mask,
+ unsigned long clr_mask)
+{
+ return ((isr & set_mask) == set_mask) && ((isr & clr_mask) == 0);
+}
+
+/*
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ * are set and cleared
+ *
+ * @return: 0 on success or -ETIMEDOUT.
+ */
+static int i2c_isr_set_cleared(void __iomem *base, unsigned long set_mask,
+ unsigned long clr_mask)
+{
+ int cnt = 1000, delay = 10, isr, ret;
+
+ ret = read_poll_timeout(readl, isr,
+ is_isr_set_or_clr(isr, set_mask, clr_mask),
+ delay, delay * cnt, base + ISR_OFFSET);
+ return ret;
+}
+
+/*
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can transfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return: 0: transfer successful or error code
+ */
+static int i2c_transfer(void __iomem *base, struct k1_i2c_msg *msg)
+{
+ int ret;
+ u32 val;
+
+ if (!msg)
+ goto transfer_error_msg_empty;
+
+ switch (msg->direction) {
+ case I2C_WRITE:
+ /* check if bus is not busy */
+ if (i2c_isr_set_cleared(base, 0, ISR_IBB))
+ goto transfer_error_bus_busy;
+
+ /* start transmission */
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_START;
+ writel(val, base + ICR_OFFSET);
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_STOP;
+ writel(val, base + ICR_OFFSET);
+ writel(msg->data, base + IDBR_OFFSET);
+ if (msg->condition == I2C_COND_START) {
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_START;
+ writel(val, base + ICR_OFFSET);
+ }
+ if (msg->condition == I2C_COND_STOP) {
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_STOP;
+ writel(val, base + ICR_OFFSET);
+ }
+ if (msg->acknack == I2C_ACKNAK_SENDNAK) {
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_ACKNAK;
+ writel(val, base + ICR_OFFSET);
+ }
+ if (msg->acknack == I2C_ACKNAK_SENDACK) {
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_ACKNAK;
+ writel(val, base + ICR_OFFSET);
+ }
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_ALDIE;
+ writel(val, base + ICR_OFFSET);
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_TB;
+ writel(val, base + ICR_OFFSET);
+
+ /* transmit register empty? */
+ if (i2c_isr_set_cleared(base, ISR_ITE, 0))
+ goto transfer_error_transmit_timeout;
+
+ /* clear 'transmit empty' state */
+ val = readl(base + ISR_OFFSET);
+ val |= ISR_ITE;
+ writel(val, base + ISR_OFFSET);
+
+ /* wait for ACK from slave */
+ if (msg->acknack == I2C_ACKNAK_WAITACK)
+ if (i2c_isr_set_cleared(base, 0, ISR_ACKNAK))
+ goto transfer_error_ack_missing;
+ break;
+
+ case I2C_READ:
+ /* check if bus is not busy */
+ if (i2c_isr_set_cleared(base, 0, ISR_IBB))
+ goto transfer_error_bus_busy;
+
+ /* start receive */
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_START;
+ writel(val, base + ICR_OFFSET);
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_STOP;
+ writel(val, base + ICR_OFFSET);
+ if (msg->condition == I2C_COND_START) {
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_START;
+ writel(val, base + ICR_OFFSET);
+ }
+ if (msg->condition == I2C_COND_STOP) {
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_STOP;
+ writel(val, base + ICR_OFFSET);
+ }
+ if (msg->acknack == I2C_ACKNAK_SENDNAK) {
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_ACKNAK;
+ writel(val, base + ICR_OFFSET);
+ }
+ if (msg->acknack == I2C_ACKNAK_SENDACK) {
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_ACKNAK;
+ writel(val, base + ICR_OFFSET);
+ }
+ val = readl(base + ICR_OFFSET);
+ val &= ~ICR_ALDIE;
+ writel(val, base + ICR_OFFSET);
+ val = readl(base + ICR_OFFSET);
+ val |= ICR_TB;
+ writel(val, base + ICR_OFFSET);
+
+ /* receive register full? */
+ if (i2c_isr_set_cleared(base, ISR_IRF, 0))
+ goto transfer_error_receive_timeout;
+
+ msg->data = readl(base + IDBR_OFFSET);
+
+ /* clear 'receive empty' state */
+ val = readl(base + ISR_OFFSET);
+ val |= ISR_IRF;
+ writel(val, base + ISR_OFFSET);
+ break;
+ default:
+ goto transfer_error_illegal_param;
+ }
+
+ return 0;
+
+transfer_error_msg_empty:
+ debug("%s: error: 'msg' is empty\n", __func__);
+ ret = -EINVAL;
+ goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+ debug("%s: error: transmit timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+ debug("%s: error: ACK missing\n", __func__);
+ ret = -EREMOTEIO;
+ goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+ debug("%s: error: receive timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+ debug("%s: error: illegal parameters\n", __func__);
+ ret = -EINVAL;
+ goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+ debug("%s: error: bus is busy\n", __func__);
+ ret = -EIO;
+ goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+ debug("%s: ISR: 0x%04x\n", __func__, readl(base + ISR_OFFSET));
+ i2c_reset(base);
+ return ret;
+}
+
+static int __i2c_read(void __iomem *base, uchar chip, u8 *addr, int alen,
+ uchar *buffer, int len)
+{
+ struct k1_i2c_msg msg;
+ int ret;
+
+ debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",
+ __func__, chip, *addr, alen, len);
+
+ if (len == 0) {
+ pr_err("reading zero byte is invalid\n");
+ return -EINVAL;
+ }
+
+ i2c_reset(base);
+
+ /* dummy chip address write */
+ debug("%s: dummy chip address write\n", __func__);
+ msg.condition = I2C_COND_START;
+ msg.acknack = I2C_ACKNAK_WAITACK;
+ msg.direction = I2C_WRITE;
+ msg.data = (chip << 1);
+ msg.data &= 0xFE;
+ ret = i2c_transfer(base, &msg);
+ if (ret)
+ return ret;
+
+ /*
+ * send memory address bytes;
+ * alen defines how much bytes we have to send.
+ */
+ while (--alen >= 0) {
+ debug("%s: send address byte %02x (alen=%d)\n",
+ __func__, *addr, alen);
+ msg.condition = I2C_COND_NORMAL;
+ msg.acknack = I2C_ACKNAK_WAITACK;
+ msg.direction = I2C_WRITE;
+ msg.data = addr[alen];
+ ret = i2c_transfer(base, &msg);
+ if (ret)
+ return ret;
+ }
+
+ /* start read sequence */
+ debug("%s: start read sequence\n", __func__);
+ msg.condition = I2C_COND_START;
+ msg.acknack = I2C_ACKNAK_WAITACK;
+ msg.direction = I2C_WRITE;
+ msg.data = (chip << 1);
+ msg.data |= 0x01;
+ ret = i2c_transfer(base, &msg);
+ if (ret)
+ return ret;
+
+ /* read bytes; send NACK at last byte */
+ while (len--) {
+ if (len == 0) {
+ msg.condition = I2C_COND_STOP;
+ msg.acknack = I2C_ACKNAK_SENDNAK;
+ } else {
+ msg.condition = I2C_COND_NORMAL;
+ msg.acknack = I2C_ACKNAK_SENDACK;
+ }
+
+ msg.direction = I2C_READ;
+ msg.data = 0x00;
+ ret = i2c_transfer(base, &msg);
+ if (ret)
+ return ret;
+
+ *buffer = msg.data;
+ debug("%s: reading byte (%p)=0x%02x\n",
+ __func__, buffer, *buffer);
+ buffer++;
+ }
+
+ i2c_reset(base);
+
+ return 0;
+}
+
+static int __i2c_write(struct k1_i2c *base, uchar chip, u8 *addr, int alen,
+ uchar *buffer, int len)
+{
+ struct k1_i2c_msg msg;
+ int ret;
+
+ debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",
+ __func__, chip, *addr, alen, len);
+
+ i2c_reset(base);
+
+ /* chip address write */
+ debug("%s: chip address write\n", __func__);
+ msg.condition = I2C_COND_START;
+ msg.acknack = I2C_ACKNAK_WAITACK;
+ msg.direction = I2C_WRITE;
+ msg.data = (chip << 1);
+ msg.data &= 0xFE;
+ ret = i2c_transfer(base, &msg);
+ if (ret)
+ return ret;
+
+ /*
+ * send memory address bytes;
+ * alen defines how much bytes we have to send.
+ */
+ while (--alen >= 0) {
+ debug("%s: send address byte %02x (alen=%d)\n",
+ __func__, *addr, alen);
+ msg.condition = I2C_COND_NORMAL;
+ msg.acknack = I2C_ACKNAK_WAITACK;
+ msg.direction = I2C_WRITE;
+ msg.data = addr[alen];
+ ret = i2c_transfer(base, &msg);
+ if (ret)
+ return ret;
+ }
+
+ /* write bytes; send NACK at last byte */
+ while (len--) {
+ debug("%s: writing byte (%p)=0x%02x\n",
+ __func__, buffer, *buffer);
+
+ if (len == 0)
+ msg.condition = I2C_COND_STOP;
+ else
+ msg.condition = I2C_COND_NORMAL;
+
+ msg.acknack = I2C_ACKNAK_WAITACK;
+ msg.direction = I2C_WRITE;
+ msg.data = *(buffer++);
+
+ ret = i2c_transfer(base, &msg);
+ if (ret)
+ return ret;
+ }
+
+ i2c_reset(base);
+
+ return 0;
+}
+
+static int k1_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+ struct k1_i2c_priv *i2c = dev_get_priv(bus);
+ struct i2c_msg *dmsg, *omsg, dummy;
+
+ memset(&dummy, 0, sizeof(struct i2c_msg));
+
+ /*
+ * We expect either two messages (one with an offset and one with the
+ * actual data) or one message (just data or offset/data combined)
+ */
+ if (nmsgs > 2 || nmsgs == 0) {
+ debug("%s: Only one or two messages are supported.", __func__);
+ return -EINVAL;
+ }
+
+ omsg = nmsgs == 1 ? &dummy : msg;
+ dmsg = nmsgs == 1 ? msg : msg + 1;
+
+ if (dmsg->flags & I2C_M_RD)
+ return __i2c_read(i2c->base, dmsg->addr, omsg->buf,
+ omsg->len, dmsg->buf, dmsg->len);
+ else
+ return __i2c_write(i2c->base, dmsg->addr, omsg->buf,
+ omsg->len, dmsg->buf, dmsg->len);
+}
+
+static int k1_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+ struct k1_i2c_priv *priv = dev_get_priv(bus);
+ void __iomem *base = priv->base;
+ u32 val;
+
+ if (speed > I2C_SPEED_STANDARD_RATE)
+ val = ICR_FM;
+ else
+ val = ICR_SM;
+ clrsetbits_le32(base + ICR_OFFSET, ICR_MODE_MASK, val);
+
+ return 0;
+}
+
+static int k1_i2c_probe(struct udevice *bus)
+{
+ struct k1_i2c_priv *priv = dev_get_priv(bus);
+ struct reset_ctl reset;
+ int ret;
+
+ priv->id = dev_seq(bus);
+
+ /*
+ * The upstream K1 dts intentionally omits the 'resets' property
+ * on i2c nodes — the apbc clock-enable path performs the
+ * controller reset internally as part of clock gating. Treat the
+ * reset lookup as optional so we work on the kernel-mainline DT.
+ */
+ ret = reset_get_by_index(bus, 0, &reset);
+ if (!ret) {
+ reset_assert(&reset);
+ udelay(10);
+ reset_deassert(&reset);
+ udelay(10);
+ } else if (ret != -ENOENT && ret != -ENODATA) {
+ dev_err(bus, "%s: reset lookup failed (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = clk_get_by_index(bus, 0, &priv->clk);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret && ret != -ENOSYS && ret != -EOPNOTSUPP) {
+ debug("%s: failed to enable clock\n", __func__);
+ return ret;
+ }
+ priv->clk_rate = clk_get_rate(&priv->clk);
+
+ priv->base = (void *)devfdt_get_addr_ptr(bus);
+ k1_i2c_set_bus_speed(bus, priv->clk_rate);
+ return 0;
+}
+
+static const struct dm_i2c_ops k1_i2c_ops = {
+ .xfer = k1_i2c_xfer,
+ .set_bus_speed = k1_i2c_set_bus_speed,
+};
+
+static const struct udevice_id k1_i2c_ids[] = {
+ { .compatible = "spacemit,k1-i2c" },
+ { }
+};
+
+U_BOOT_DRIVER(i2c_spacemit) = {
+ .name = "i2c_spacemit",
+ .id = UCLASS_I2C,
+ .of_match = k1_i2c_ids,
+ .probe = k1_i2c_probe,
+ .priv_auto = sizeof(struct k1_i2c_priv),
+ .ops = &k1_i2c_ops,
+};
diff --git a/drivers/i2c/k1_i2c.h b/drivers/i2c/k1_i2c.h
new file mode 100644
index 00000000000..856947aa43b
--- /dev/null
+++ b/drivers/i2c/k1_i2c.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2023-2026 Spacemit Ltd.
+ * Copyright (C) 2025-2026 RISCstar Ltd.
+ */
+
+#ifndef __SPACEMIT_I2C_H
+#define __SPACEMIT_I2C_H
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL 0
+#define I2C_COND_START 1
+#define I2C_COND_STOP 2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK 1
+#define I2C_ACKNAK_SENDACK 2
+#define I2C_ACKNAK_SENDNAK 4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ 0
+#define I2C_WRITE 1
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | \
+ ICR_GCD | ICR_SCLE)
+#else
+#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | \
+ ICR_SCLE)
+#endif
+
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START 0x1 /* start bit */
+#define ICR_STOP 0x2 /* stop bit */
+#define ICR_ACKNAK 0x4 /* send ACK(0) or NAK(1) */
+#define ICR_TB 0x8 /* transfer byte bit */
+#define ICR_MA BIT(12) /* master abort */
+#define ICR_SCLE BIT(13) /* master clock enable, mona SCLEA */
+#define ICR_IUE BIT(14) /* unit enable */
+#define ICR_GCD BIT(21) /* general call disable */
+#define ICR_ITEIE BIT(19) /* enable tx interrupts */
+#define ICR_IRFIE BIT(20) /* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE BIT(22) /* enable bus error ints */
+#define ICR_SSDIE BIT(24) /* slave STOP detected int enable */
+#define ICR_ALDIE BIT(18) /* enable arbitration interrupt */
+#define ICR_SADIE BIT(23) /* slave address detected int enable */
+#define ICR_UR BIT(10) /* unit reset */
+#define ICR_SM (0x0) /* Standard Mode */
+#define ICR_FM BIT(8) /* Fast Mode */
+#define ICR_MODE_MASK (0x300) /* Mode mask */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM BIT(13) /* read/write mode */
+#define ISR_ACKNAK BIT(14) /* ack/nak status */
+#define ISR_UB BIT(15) /* unit busy */
+#define ISR_IBB BIT(16) /* bus busy */
+#define ISR_SSD BIT(24) /* slave stop detected */
+#define ISR_ALD BIT(18) /* arbitration loss detected */
+#define ISR_ITE BIT(19) /* tx buffer empty */
+#define ISR_IRF BIT(20) /* rx buffer full */
+#define ISR_GCAD BIT(21) /* general call address detected */
+#define ISR_SAD BIT(23) /* slave address detected */
+#define ISR_BED BIT(22) /* bus error no ACK/NAK */
+
+#define I2C_ISR_INIT 0x1FDE000
+
+#endif
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 3b1220b2105..89a4b82458a 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -26,14 +26,14 @@ config I2C_ARB_GPIO_CHALLENGE
a GPIO.
config I2C_MUX_PCA9541
- tristate "NXP PCA9541 I2C Master Selector"
+ bool "NXP PCA9541 I2C Master Selector"
depends on I2C_MUX
help
If you say yes here you get support for the NXP PCA9541
I2C Master Selector.
config I2C_MUX_PCA954x
- tristate "TI PCA954x I2C Mux/switches"
+ bool "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
@@ -49,7 +49,7 @@ config I2C_MUX_PCA954x
MAX7356, MAX7357, MAX7358, MAX7367, MAX7368 and MAX7369
config I2C_MUX_GPIO
- tristate "GPIO-based I2C multiplexer"
+ bool "GPIO-based I2C multiplexer"
depends on I2C_MUX && DM_GPIO
select DEVRES
help
diff --git a/drivers/i2c/nx_i2c.c b/drivers/i2c/nx_i2c.c
index 706b7adefe8..5800e79ab70 100644
--- a/drivers/i2c/nx_i2c.c
+++ b/drivers/i2c/nx_i2c.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+
#include <errno.h>
#include <dm.h>
#include <i2c.h>
@@ -230,12 +232,13 @@ static void i2c_process_node(struct udevice *dev)
static int nx_i2c_probe(struct udevice *dev)
{
struct nx_i2c_bus *bus = dev_get_priv(dev);
- fdt_addr_t addr;
+ void __iomem *addr;
/* get regs = i2c base address */
- addr = devfdt_get_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_read_addr_ptr(dev);
+ if (!addr)
return -EINVAL;
+
bus->regs = (struct nx_i2c_regs *)addr;
bus->bus_num = dev_seq(dev);
diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig
index 48341f9b873..41a4177b3ae 100644
--- a/drivers/i3c/Kconfig
+++ b/drivers/i3c/Kconfig
@@ -1,5 +1,5 @@
menuconfig I3C
- tristate "I3C support"
+ bool "I3C support"
select I2C
select DEVRES
help
diff --git a/drivers/i3c/master/Kconfig b/drivers/i3c/master/Kconfig
index 79776f60ae4..63467ef9cc2 100644
--- a/drivers/i3c/master/Kconfig
+++ b/drivers/i3c/master/Kconfig
@@ -1,5 +1,5 @@
config DW_I3C_MASTER
- tristate "Synopsys DesignWare I3C master driver"
+ bool "Synopsys DesignWare I3C master driver"
depends on I3C
help
Support for Synopsys DesignWare MIPI I3C Controller.
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index de95a1debdc..04ebc24e8cf 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -133,7 +133,7 @@ config LED_GPIO
config SPL_LED_GPIO
bool "LED support for GPIO-connected LEDs in SPL"
- depends on SPL_LED && SPL_DM_GPIO
+ depends on SPL_LED && SPL_DM_GPIO
help
This option is an SPL-variant of the LED_GPIO option.
See the help of LED_GPIO for details.
diff --git a/drivers/led/led_sw_blink.c b/drivers/led/led_sw_blink.c
index ee1546d02d4..4190fde8f0f 100644
--- a/drivers/led/led_sw_blink.c
+++ b/drivers/led/led_sw_blink.c
@@ -114,9 +114,11 @@ bool led_sw_on_state_change(struct udevice *dev, enum led_state_t state)
case LEDST_ON:
ops->set_state(dev, LEDST_OFF);
sw_blink->state = LED_SW_BLINK_ST_OFF;
+ break;
default:
ops->set_state(dev, LEDST_ON);
sw_blink->state = LED_SW_BLINK_ST_ON;
+ break;
}
return true;
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index f45e611c966..1d9e284cfd1 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -32,6 +32,8 @@ config MPFS_MBOX
bool "Enable MPFS system controller support"
depends on DM_MAILBOX && ARCH_RV64I
select DEVRES
+ depends on SYSCON
+ depends on REGMAP
help
Enable support for the mailboxes that provide a communication
channel with the system controller integrated on PolarFire SoC.
diff --git a/drivers/mailbox/apple-mbox.c b/drivers/mailbox/apple-mbox.c
index 2ee49734f40..39a7edc0285 100644
--- a/drivers/mailbox/apple-mbox.c
+++ b/drivers/mailbox/apple-mbox.c
@@ -59,7 +59,7 @@ static int apple_mbox_recv(struct mbox_chan *chan, void *data)
return 0;
}
-struct mbox_ops apple_mbox_ops = {
+static const struct mbox_ops apple_mbox_ops = {
.of_xlate = apple_mbox_of_xlate,
.send = apple_mbox_send,
.recv = apple_mbox_recv,
diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index c7eaa3de96f..fd0fce21d78 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -387,7 +387,7 @@ int imx_mu_of_xlate(struct mbox_chan *chan, struct ofnode_phandle_args *args)
return plat->dcfg->of_xlate(chan, args);
}
-struct mbox_ops imx_mu_ops = {
+static const struct mbox_ops imx_mu_ops = {
.of_xlate = imx_mu_of_xlate,
.request = imx_mu_chan_request,
.rfree = imx_mu_chan_free,
diff --git a/drivers/mailbox/k3-sec-proxy.c b/drivers/mailbox/k3-sec-proxy.c
index 6f5ad37919f..6eebfcd3601 100644
--- a/drivers/mailbox/k3-sec-proxy.c
+++ b/drivers/mailbox/k3-sec-proxy.c
@@ -293,7 +293,7 @@ static int k3_sec_proxy_recv(struct mbox_chan *chan, void *data)
return 0;
}
-struct mbox_ops k3_sec_proxy_mbox_ops = {
+static const struct mbox_ops k3_sec_proxy_mbox_ops = {
.of_xlate = k3_sec_proxy_of_xlate,
.request = k3_sec_proxy_request,
.rfree = k3_sec_proxy_free,
diff --git a/drivers/mailbox/mpfs-mbox.c b/drivers/mailbox/mpfs-mbox.c
index 55238847ecd..b1ce377525e 100644
--- a/drivers/mailbox/mpfs-mbox.c
+++ b/drivers/mailbox/mpfs-mbox.c
@@ -13,19 +13,21 @@
#include <dm/device-internal.h>
#include <dm/device.h>
#include <dm/device_compat.h>
-#include <dm/devres.h>
#include <dm/ofnode.h>
#include <linux/bitops.h>
#include <linux/compat.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
+#include <linux/err.h>
+#include <linux/errno.h>
#include <log.h>
#include <mailbox-uclass.h>
-#include <malloc.h>
#include <mpfs-mailbox.h>
+#include <regmap.h>
+#include <syscon.h>
#define SERVICES_CR_OFFSET 0x50u
#define SERVICES_SR_OFFSET 0x54u
+#define MESSAGE_INT_OFFSET 0x18cu
+#define MAILBOX_REG_OFFSET 0x800u
#define SERVICE_CR_REQ_MASK 0x1u
#define SERVICE_SR_BUSY_MASK 0x2u
@@ -35,17 +37,18 @@
struct mpfs_mbox {
struct udevice *dev;
- void __iomem *ctrl_base;
void __iomem *mbox_base;
- struct mbox_chan *chan;
+ void __iomem *int_reg;
+ struct regmap *control_scb;
+ struct regmap *sysreg_scb;
};
static bool mpfs_mbox_busy(struct mbox_chan *chan)
{
struct mpfs_mbox *mbox = dev_get_priv(chan->dev);
- uint16_t status;
+ u32 status;
- status = readl(mbox->ctrl_base + SERVICES_SR_OFFSET);
+ regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &status);
return status & SERVICE_SR_BUSY_MASK;
}
@@ -80,14 +83,15 @@ static int mpfs_mbox_send(struct mbox_chan *chan, const void *data)
cmd_shifted = msg->cmd_opcode << SERVICE_CR_COMMAND_SHIFT;
cmd_shifted |= SERVICE_CR_REQ_MASK;
- writel(cmd_shifted, mbox->ctrl_base + SERVICES_CR_OFFSET);
+
+ regmap_write(mbox->control_scb, SERVICES_CR_OFFSET, cmd_shifted);
do {
- value = readl(mbox->ctrl_base + SERVICES_CR_OFFSET);
+ regmap_read(mbox->control_scb, SERVICES_CR_OFFSET, &value);
} while (SERVICE_CR_REQ_MASK == (value & SERVICE_CR_REQ_MASK));
do {
- value = readl(mbox->ctrl_base + SERVICES_SR_OFFSET);
+ regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &value);
} while (SERVICE_SR_BUSY_MASK == (value & SERVICE_SR_BUSY_MASK));
msg->response->resp_status = (value >> SERVICE_SR_STATUS_SHIFT);
@@ -118,6 +122,11 @@ static int mpfs_mbox_recv(struct mbox_chan *chan, void *data)
for (idx = 0; idx < response->resp_size; idx++)
*((u8 *)(response->resp_msg) + idx) = readb(mbox->mbox_base + msg->resp_offset + idx);
+ if (mbox->sysreg_scb)
+ regmap_write(mbox->sysreg_scb, MESSAGE_INT_OFFSET, 0);
+ else
+ writel_relaxed(0, mbox->int_reg);
+
return 0;
}
@@ -126,42 +135,71 @@ static const struct mbox_ops mpfs_mbox_ops = {
.recv = mpfs_mbox_recv,
};
-static int mpfs_mbox_probe(struct udevice *dev)
+/*
+ * Use global compatible lookup instead of phandles, as U-Boot may run
+ * with a reduced or firmware-provided device tree where mailbox syscon
+ * phandle properties are not guaranteed to be present.
+ */
+static int mpfs_mbox_syscon_probe(struct udevice *dev, struct mpfs_mbox *mbox)
{
- struct mpfs_mbox *mbox;
- struct resource regs;
ofnode node;
- int ret;
- node = dev_ofnode(dev);
+ node = ofnode_by_compatible(ofnode_null(), "microchip,mpfs-control-scb");
+ if (!ofnode_valid(node))
+ return -ENODEV;
- mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
- if (!mbox)
- return -ENOMEM;
+ mbox->control_scb = syscon_node_to_regmap(node);
+ if (IS_ERR(mbox->control_scb))
+ return PTR_ERR(mbox->control_scb);
- ret = ofnode_read_resource(node, 0, &regs);
- if (ret) {
- dev_err(dev, "No reg property for controller base\n");
- return ret;
- };
+ node = ofnode_by_compatible(ofnode_null(), "microchip,mpfs-sysreg-scb");
+ if (!ofnode_valid(node))
+ return -ENODEV;
- mbox->ctrl_base = devm_ioremap(dev, regs.start, regs.start - regs.end);
+ mbox->sysreg_scb = syscon_node_to_regmap(node);
+ if (IS_ERR(mbox->sysreg_scb))
+ return PTR_ERR(mbox->sysreg_scb);
- ret = ofnode_read_resource(node, 2, &regs);
- if (ret) {
- dev_err(dev, "No reg property for mailbox base\n");
+ mbox->mbox_base = dev_read_addr_ptr(dev);
+ if (!mbox->mbox_base)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mpfs_mbox_legacy_probe(struct udevice *dev, struct mpfs_mbox *mbox)
+{
+ int ret;
+
+ ret = regmap_init_mem_index(dev_ofnode(dev), &mbox->control_scb, 0);
+ if (ret)
return ret;
- };
- mbox->mbox_base = devm_ioremap(dev, regs.start, regs.start - regs.end);
+ mbox->mbox_base = dev_read_addr_index_ptr(dev, 2);
+ if (!mbox->mbox_base)
+ mbox->mbox_base = dev_read_addr_index_ptr(dev, 0) + MAILBOX_REG_OFFSET;
- mbox->dev = dev;
- dev_set_priv(dev, mbox);
- mbox->chan->con_priv = mbox;
+ mbox->int_reg = dev_read_addr_index_ptr(dev, 1);
+ if (!mbox->int_reg)
+ return -EINVAL;
return 0;
}
+static int mpfs_mbox_probe(struct udevice *dev)
+{
+ struct mpfs_mbox *mbox = dev_get_priv(dev);
+ int ret;
+
+ mbox->dev = dev;
+
+ ret = mpfs_mbox_syscon_probe(dev, mbox);
+ if (!ret)
+ return 0;
+
+ return mpfs_mbox_legacy_probe(dev, mbox);
+}
+
static const struct udevice_id mpfs_mbox_ids[] = {
{.compatible = "microchip,mpfs-mailbox"},
{ }
@@ -174,4 +212,4 @@ U_BOOT_DRIVER(mpfs_mbox) = {
.probe = mpfs_mbox_probe,
.priv_auto = sizeof(struct mpfs_mbox),
.ops = &mpfs_mbox_ops,
-};
+}; \ No newline at end of file
diff --git a/drivers/mailbox/renesas-mfis.c b/drivers/mailbox/renesas-mfis.c
index 1e9e8285974..19b801e56a6 100644
--- a/drivers/mailbox/renesas-mfis.c
+++ b/drivers/mailbox/renesas-mfis.c
@@ -29,7 +29,7 @@ static int mfis_send(struct mbox_chan *chan, const void *data)
return 0;
}
-struct mbox_ops mfis_mbox_ops = {
+static const struct mbox_ops mfis_mbox_ops = {
.send = mfis_send,
};
diff --git a/drivers/mailbox/sandbox-mbox.c b/drivers/mailbox/sandbox-mbox.c
index 87e06e492fe..d6ac758c4d8 100644
--- a/drivers/mailbox/sandbox-mbox.c
+++ b/drivers/mailbox/sandbox-mbox.c
@@ -86,7 +86,7 @@ static const struct udevice_id sandbox_mbox_ids[] = {
{ }
};
-struct mbox_ops sandbox_mbox_mbox_ops = {
+static const struct mbox_ops sandbox_mbox_mbox_ops = {
.request = sandbox_mbox_request,
.rfree = sandbox_mbox_free,
.send = sandbox_mbox_send,
diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c
index dda108735fc..49f7795b3cd 100644
--- a/drivers/mailbox/stm32-ipcc.c
+++ b/drivers/mailbox/stm32-ipcc.c
@@ -147,7 +147,7 @@ static const struct udevice_id stm32_ipcc_ids[] = {
{ }
};
-struct mbox_ops stm32_ipcc_mbox_ops = {
+static const struct mbox_ops stm32_ipcc_mbox_ops = {
.request = stm32_ipcc_request,
.rfree = stm32_ipcc_free,
.send = stm32_ipcc_send,
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 591d9d9c656..5f029fd3e70 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -44,18 +44,18 @@ config STM32_OMM
This driver manages the muxing between the 2 OSPI busses and
the 2 output ports. There are 4 possible muxing configurations:
- direct mode (no multiplexing): OSPI1 output is on port 1 and OSPI2
- output is on port 2
+ output is on port 2
- OSPI1 and OSPI2 are multiplexed over the same output port 1
- swapped mode (no multiplexing), OSPI1 output is on port 2,
- OSPI2 output is on port 1
+ OSPI2 output is on port 1
- OSPI1 and OSPI2 are multiplexed over the same output port 2
It also manages :
- - the split of the memory area shared between the 2 OSPI instances.
- - chip select selection override.
- - the time between 2 transactions in multiplexed mode.
+ - the split of the memory area shared between the 2 OSPI instances.
+ - chip select selection override.
+ - the time between 2 transactions in multiplexed mode.
config TI_AEMIF
- tristate "Texas Instruments AEMIF driver"
+ bool "Texas Instruments AEMIF driver"
depends on ARCH_KEYSTONE || ARCH_DAVINCI
help
This driver is for the AEMIF module available in Texas Instruments
@@ -71,9 +71,9 @@ config TI_GPMC
depends on MEMORY && CLK && OF_CONTROL
help
This driver is for the General Purpose Memory Controller (GPMC)
- present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows
- interfacing to a variety of asynchronous as well as synchronous
- memory drives like NOR, NAND, OneNAND, SRAM.
+ present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows
+ interfacing to a variety of asynchronous as well as synchronous
+ memory drives like NOR, NAND, OneNAND, SRAM.
if TI_GPMC
config TI_GPMC_DEBUG
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ae53b02f27c..79f4db9849c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1,4 +1,4 @@
config MFD_ATMEL_SMC
- bool "Atmel Static Memory Controller driver"
- help
- Say yes here to support Atmel Static Memory Controller driver.
+ bool "Atmel Static Memory Controller driver"
+ help
+ Say yes here to support Atmel Static Memory Controller driver.
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index ea785793d18..44415f24ae1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -71,9 +71,9 @@ config ATSHA204A
select BITREVERSE
depends on MISC
help
- Enable support for I2C connected Atmel's ATSHA204A
- CryptoAuthentication module found for example on the Turris Omnia
- board.
+ Enable support for I2C connected Atmel's ATSHA204A
+ CryptoAuthentication module found for example on the Turris Omnia
+ board.
config GATEWORKS_SC
bool "Gateworks System Controller Support"
@@ -94,7 +94,7 @@ config QCOM_GENI
etc.
config ROCKCHIP_EFUSE
- bool "Rockchip e-fuse support"
+ bool "Rockchip e-fuse support"
depends on MISC
help
Enable (read-only) access for the e-fuse block found in Rockchip
@@ -505,7 +505,7 @@ config TURRIS_OMNIA_MCU
board power off.
config USB_HUB_USB251XB
- tristate "USB251XB Hub Controller Configuration Driver"
+ bool "USB251XB Hub Controller Configuration Driver"
depends on I2C
help
This option enables support for configuration via SMBus of the
@@ -647,6 +647,7 @@ config IHS_FPGA
gdsys devices, which supply the majority of the functionality offered
by the devices. This driver supports both CON and CPU variants of the
devices, depending on the device tree entry.
+
config ESM_K3
bool "Enable K3 ESM driver"
depends on ARCH_K3
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index fabe4964a33..e163224b8e3 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -258,7 +258,7 @@ static int send_command_proto3(struct cros_ec_dev *cdev,
const void *dout, int dout_len,
uint8_t **dinp, int din_len)
{
- struct dm_cros_ec_ops *ops;
+ const struct dm_cros_ec_ops *ops;
int out_bytes, in_bytes;
int rv;
@@ -287,7 +287,7 @@ static int send_command(struct cros_ec_dev *dev, uint cmd, int cmd_version,
const void *dout, int dout_len,
uint8_t **dinp, int din_len)
{
- struct dm_cros_ec_ops *ops;
+ const struct dm_cros_ec_ops *ops;
int ret = -1;
/* Handle protocol version 3 support */
@@ -487,7 +487,7 @@ int cros_ec_read_build_info(struct udevice *dev, char **strp)
}
int cros_ec_read_current_image(struct udevice *dev,
- enum ec_current_image *image)
+ enum ec_image *image)
{
struct ec_response_get_version *r;
@@ -756,9 +756,8 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask,
static int cros_ec_check_version(struct udevice *dev)
{
struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
+ const struct dm_cros_ec_ops *ops;
struct ec_params_hello req;
-
- struct dm_cros_ec_ops *ops;
int ret;
ops = dm_cros_ec_get_ops(dev);
@@ -1638,7 +1637,7 @@ int cros_ec_vstore_write(struct udevice *dev, int slot, const uint8_t *data,
int cros_ec_get_switches(struct udevice *dev)
{
- struct dm_cros_ec_ops *ops;
+ const struct dm_cros_ec_ops *ops;
int ret;
ops = dm_cros_ec_get_ops(dev);
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 432b1fbb0c4..9fedca4e6b6 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -100,7 +100,7 @@ struct ec_state {
struct fdt_cros_ec ec_config;
uint8_t *flash_data;
int flash_data_len;
- enum ec_current_image current_image;
+ enum ec_image current_image;
int matrix_count;
struct ec_keymatrix_entry *matrix; /* the key matrix info */
uint8_t keyscan[KEYBOARD_COLS];
@@ -726,7 +726,7 @@ int cros_ec_probe(struct udevice *dev)
return cros_ec_register(dev);
}
-struct dm_cros_ec_ops cros_ec_ops = {
+static const struct dm_cros_ec_ops cros_ec_ops = {
.packet = cros_ec_sandbox_packet,
.get_switches = cros_ec_sandbox_get_switches,
};
diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c
index 3ad2e047ee3..40f34ad03a4 100644
--- a/drivers/misc/i2c_eeprom_emul.c
+++ b/drivers/misc/i2c_eeprom_emul.c
@@ -144,7 +144,7 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
return 0;
}
-struct dm_i2c_ops sandbox_i2c_emul_ops = {
+static const struct dm_i2c_ops sandbox_i2c_emul_ops = {
.xfer = sandbox_i2c_eeprom_xfer,
};
diff --git a/drivers/misc/imx_ele/ele_api.c b/drivers/misc/imx_ele/ele_api.c
index 8ee0a7733ca..355fd86ed8c 100644
--- a/drivers/misc/imx_ele/ele_api.c
+++ b/drivers/misc/imx_ele/ele_api.c
@@ -795,6 +795,38 @@ int ele_generate_dek_blob(u32 key_id, u32 src_paddr, u32 dst_paddr, u32 max_outp
return ret;
}
+int ele_v2x_get_state(struct v2x_get_state *state, u32 *response)
+{
+ struct udevice *dev = gd->arch.ele_dev;
+ int size = sizeof(struct ele_msg);
+ struct ele_msg msg = {};
+ int ret;
+
+ if (!dev) {
+ printf("ele dev is not initialized\n");
+ return -ENODEV;
+ }
+
+ msg.version = ELE_VERSION;
+ msg.tag = ELE_CMD_TAG;
+ msg.size = 1;
+ msg.command = ELE_V2X_GET_STATE_REQ;
+
+ ret = misc_call(dev, false, &msg, size, &msg, size);
+ if (ret)
+ printf("Error: %s: ret %d, response 0x%x\n",
+ __func__, ret, msg.data[0]);
+
+ if (response)
+ *response = msg.data[0];
+
+ state->v2x_state = msg.data[1] & 0xFF;
+ state->v2x_power_state = (msg.data[1] & 0xFF00) >> 8;
+ state->v2x_err_code = msg.data[2];
+
+ return ret;
+}
+
int ele_volt_change_start_req(void)
{
struct udevice *dev = gd->arch.ele_dev;
diff --git a/drivers/misc/imx_ele/ele_mu.c b/drivers/misc/imx_ele/ele_mu.c
index cdb85b999db..65a4779c041 100644
--- a/drivers/misc/imx_ele/ele_mu.c
+++ b/drivers/misc/imx_ele/ele_mu.c
@@ -209,7 +209,7 @@ static int imx8ulp_mu_probe(struct udevice *dev)
debug("%s(dev=%p) (priv=%p)\n", __func__, dev, priv);
- addr = devfdt_get_addr(dev);
+ addr = dev_read_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/misc/k3_avs.c b/drivers/misc/k3_avs.c
index 0774e0a4c9e..a885c99c547 100644
--- a/drivers/misc/k3_avs.c
+++ b/drivers/misc/k3_avs.c
@@ -300,7 +300,7 @@ static void k3_avs_program_tshut(struct k3_avs_privdata *priv)
void __iomem *cfg2_base;
void __iomem *fuse_base;
- cfg2_base = (void __iomem *)devfdt_get_addr_index(priv->dev, 1);
+ cfg2_base = (void __iomem *)dev_read_addr_index(priv->dev, 1);
if (IS_ERR(cfg2_base)) {
dev_err(priv->dev, "cfg base is not defined\n");
return;
@@ -319,7 +319,7 @@ static void k3_avs_program_tshut(struct k3_avs_privdata *priv)
*/
if (device_is_compatible(priv->dev, "ti,j721e-vtm")) {
- fuse_base = (void __iomem *)devfdt_get_addr_index(priv->dev, 2);
+ fuse_base = (void __iomem *)dev_read_addr_index(priv->dev, 2);
if (IS_ERR(fuse_base)) {
dev_err(priv->dev, "fuse-base is not defined for J721E Soc\n");
return;
diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index 0e002ac25f4..8a11637ca7f 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -152,7 +152,7 @@ UCLASS_DRIVER(qfw) = {
.per_device_auto = sizeof(struct qfw_dev),
};
-struct bootdev_ops qfw_bootdev_ops = {
+static const struct bootdev_ops qfw_bootdev_ops = {
.get_bootflow = qfw_get_bootflow,
};
diff --git a/drivers/misc/qfw_acpi.c b/drivers/misc/qfw_acpi.c
index 721f42ecbc3..afa3b820395 100644
--- a/drivers/misc/qfw_acpi.c
+++ b/drivers/misc/qfw_acpi.c
@@ -265,6 +265,7 @@ out:
struct acpi_rsdp *rsdp = ctx->rsdp;
rsdp->length = sizeof(*rsdp);
+ rsdp->ext_checksum = 0;
rsdp->ext_checksum = table_compute_checksum((u8 *)rsdp, sizeof(*rsdp));
gd_set_acpi_start(acpi_get_rsdp_addr());
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 24bd16ad5f3..f9f7aa5cf97 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -332,7 +332,7 @@ config MMC_MESON_GX
bool "Meson GX EMMC controller support"
depends on ARCH_MESON
help
- Support for EMMC host controller on Meson GX ARM SoCs platform (S905)
+ Support for EMMC host controller on Meson GX ARM SoCs platform (S905)
config MMC_OWL
bool "Actions OWL Multimedia Card Interface support"
@@ -415,7 +415,7 @@ config MMC_OMAP36XX_PINS
config HSMMC2_8BIT
bool "Enable 8-bit interface for eMMC (interface #2)"
- depends on MMC_OMAP_HS && (OMAP54XX || DRA7XX || AM33XX || \
+ depends on MMC_OMAP_HS && (OMAP44XX || OMAP54XX || DRA7XX || AM33XX || \
AM43XX || ARCH_KEYSTONE)
config SH_MMCIF
@@ -576,7 +576,7 @@ config MMC_SDHCI_ATMEL
specification.
config MMC_SDHCI_BCM2835
- tristate "SDHCI support for the BCM2835 SD/MMC Controller"
+ bool "SDHCI support for the BCM2835 SD/MMC Controller"
depends on ARCH_BCM283X
depends on MMC_SDHCI
select MMC_SDHCI_IO_ACCESSORS
@@ -589,7 +589,7 @@ config MMC_SDHCI_BCM2835
If unsure, say N.
config MMC_SDHCI_BCMSTB
- tristate "SDHCI support for the BCMSTB SD/MMC Controller"
+ bool "SDHCI support for the BCMSTB SD/MMC Controller"
depends on MMC_SDHCI && (ARCH_BCMSTB || ARCH_BCM283X)
help
This selects the Broadcom set-top box SD/MMC controller.
@@ -659,8 +659,8 @@ config MMC_SDHCI_MSM
depends on MMC_SDHCI && ARCH_SNAPDRAGON
help
Enables support for SDHCI 2.0 controller present on some Qualcomm
- Snapdragon devices. This device is compatible with eMMC v4.5 and
- SD 3.0 specifications. Both SD and eMMC devices are supported.
+ Snapdragon devices. This device is compatible with eMMC v4.5 and
+ SD 3.0 specifications. Both SD and eMMC devices are supported.
Card-detect gpios are not supported.
config MMC_SDHCI_MV
@@ -852,12 +852,13 @@ config FTSDC010_SDIO
bool "Support ftsdc010 sdio"
depends on FTSDC010
help
- This can enable ftsdc010 sdio function.
+ This can enable ftsdc010 sdio function.
config MMC_MTK
bool "MediaTek SD/MMC Card Interface support"
depends on ARCH_MEDIATEK || ARCH_MTMIPS || ARCH_AIROHA
depends on OF_CONTROL
+ imply LMB_LIMIT_DMA_BELOW_RAM_TOP
help
This selects the MediaTek(R) Secure digital and Multimedia card Interface.
If you have a machine with a integrated SD/MMC card reader, say Y here.
diff --git a/drivers/mmc/cv1800b_sdhci.c b/drivers/mmc/cv1800b_sdhci.c
index 036e798f374..b756649f90f 100644
--- a/drivers/mmc/cv1800b_sdhci.c
+++ b/drivers/mmc/cv1800b_sdhci.c
@@ -85,7 +85,7 @@ static int cv1800b_sdhci_probe(struct udevice *dev)
int ret;
host->name = dev->name;
- host->ioaddr = devfdt_get_addr_ptr(dev);
+ host->ioaddr = dev_read_addr_ptr(dev);
upriv->mmc = &plat->mmc;
host->mmc = &plat->mmc;
@@ -94,6 +94,9 @@ static int cv1800b_sdhci_probe(struct udevice *dev)
host->ops = &cv1800b_sdhci_sd_ops;
host->max_clk = MMC_MAX_CLOCK;
+ if (dev_read_bool(dev, "no-1-8-v"))
+ host->quirks |= SDHCI_QUIRK_NO_1_8_V;
+
ret = mmc_of_parse(dev, &plat->cfg);
if (ret)
return ret;
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index d9c05b223d5..c2424d7875c 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -645,9 +645,11 @@ static int dwmci_set_ios(struct mmc *mmc)
int ret;
if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
- ret = regulator_set_value(mmc->vqmmc_supply, 1800000);
+ ret = regulator_set_value_clamp(mmc->vqmmc_supply,
+ 1700000, 1800000, 1950000);
else
- ret = regulator_set_value(mmc->vqmmc_supply, 3300000);
+ ret = regulator_set_value_clamp(mmc->vqmmc_supply,
+ 2700000, 3300000, 3600000);
if (ret && ret != -ENOSYS)
return ret;
}
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 87125493c0d..e718a17f94c 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -36,7 +36,6 @@
#include <dm/pinctrl.h>
#include <dt-structs.h>
#include <mapmem.h>
-#include <dm/ofnode.h>
#include <linux/iopoll.h>
#include <linux/dma-mapping.h>
@@ -1393,7 +1392,6 @@ static int fsl_esdhc_of_to_plat(struct udevice *dev)
struct udevice *vqmmc_dev;
int ret;
- ofnode node = dev_ofnode(dev);
fdt_addr_t addr;
unsigned int val;
@@ -1407,15 +1405,15 @@ static int fsl_esdhc_of_to_plat(struct udevice *dev)
priv->dev = dev;
priv->mode = -1;
- val = ofnode_read_u32_default(node, "fsl,tuning-step", 1);
+ val = dev_read_u32_default(dev, "fsl,tuning-step", 1);
priv->tuning_step = val;
- val = ofnode_read_u32_default(node, "fsl,tuning-start-tap",
- ESDHC_TUNING_START_TAP_DEFAULT);
+ val = dev_read_u32_default(dev, "fsl,tuning-start-tap",
+ ESDHC_TUNING_START_TAP_DEFAULT);
priv->tuning_start_tap = val;
- val = ofnode_read_u32_default(node, "fsl,strobe-dll-delay-target",
- ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT);
+ val = dev_read_u32_default(dev, "fsl,strobe-dll-delay-target",
+ ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT);
priv->strobe_dll_delay_target = val;
- val = ofnode_read_u32_default(node, "fsl,signal-voltage-switch-extra-delay-ms", 0);
+ val = dev_read_u32_default(dev, "fsl,signal-voltage-switch-extra-delay-ms", 0);
priv->signal_voltage_switch_extra_delay_ms = val;
if (dev_read_bool(dev, "broken-cd"))
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index f0e38efb262..2e565560656 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -2721,10 +2721,11 @@ static int mmc_startup(struct mmc *mmc)
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
/*
- * If the card has already switched to 1.8V signaling, then
- * set the signal voltage to 1.8V.
+ * If voltage switch was skipped during ACMD41 but the card is
+ * already at 1.8V (retained from a previous session, e.g. warm
+ * reboot), re-configure the host to match.
*/
- if (mmc_sd_card_using_v18(mmc)) {
+ if (!(mmc->ocr & OCR_S18R) && mmc_sd_card_using_v18(mmc)) {
/*
* During a signal voltage level switch, the clock must be gated
* for 5 ms according to the SD spec.
diff --git a/drivers/mmc/mmc_bootdev.c b/drivers/mmc/mmc_bootdev.c
index 5a1688b75d0..b382521fdeb 100644
--- a/drivers/mmc/mmc_bootdev.c
+++ b/drivers/mmc/mmc_bootdev.c
@@ -19,7 +19,7 @@ static int mmc_bootdev_bind(struct udevice *dev)
return 0;
}
-struct bootdev_ops mmc_bootdev_ops = {
+static const struct bootdev_ops mmc_bootdev_ops = {
};
static const struct udevice_id mmc_bootdev_ids[] = {
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index aaa87923604..7bdb02142a2 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -64,14 +64,13 @@ static int msm_sdc_clk_init(struct udevice *dev)
{
struct msm_sdhc *prv = dev_get_priv(dev);
const struct msm_sdhc_variant_info *var_info;
- ofnode node = dev_ofnode(dev);
ulong clk_rate;
int ret, i = 0, n_clks;
const char *clk_name;
var_info = (void *)dev_get_driver_data(dev);
- if (ofnode_read_u32(node, "max-frequency", (uint *)(&clk_rate)))
+ if (dev_read_u32(dev, "max-frequency", (uint *)(&clk_rate)))
clk_rate = 201500000;
ret = clk_get_bulk(dev, &prv->clks);
@@ -87,7 +86,7 @@ static int msm_sdc_clk_init(struct udevice *dev)
}
/* If clock-names is unspecified, then the first clock is the core clock */
- if (!ofnode_get_property(node, "clock-names", &n_clks)) {
+ if (!dev_read_prop(dev, "clock-names", &n_clks)) {
if (!clk_set_rate(&prv->clks.clks[0], clk_rate)) {
log_warning("Couldn't set core clock rate: %d\n", ret);
return -EINVAL;
@@ -96,7 +95,7 @@ static int msm_sdc_clk_init(struct udevice *dev)
/* Find the index of the "core" clock */
while (i < n_clks) {
- ofnode_read_string_index(node, "clock-names", i, &clk_name);
+ dev_read_string_index(dev, "clock-names", i, &clk_name);
if (!strcmp(clk_name, "core"))
break;
i++;
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 5af1953cd14..89d511c1a6f 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -375,8 +375,8 @@ static void mvebu_window_setup(const struct mmc *mmc)
break;
}
- size = gd->bd->bi_dram[i].size;
- base = gd->bd->bi_dram[i].start;
+ size = gd->dram[i].size;
+ base = gd->dram[i].start;
if (size && attrib) {
mvebu_mmc_write(mmc, WINDOW_CTRL(i),
MVCPU_WIN_CTRL_DATA(size,
diff --git a/drivers/mmc/octeontx_hsmmc.c b/drivers/mmc/octeontx_hsmmc.c
index bb4fb29424b..b4942f99a52 100644
--- a/drivers/mmc/octeontx_hsmmc.c
+++ b/drivers/mmc/octeontx_hsmmc.c
@@ -3514,7 +3514,7 @@ static u32 xlate_voltage(u32 voltage)
*/
static bool octeontx_mmc_get_valid(struct udevice *dev)
{
- const char *stat = ofnode_read_string(dev_ofnode(dev), "status");
+ const char *stat = dev_read_string(dev, "status");
if (!stat || !strncmp(stat, "ok", 2))
return true;
@@ -3536,16 +3536,13 @@ static int octeontx_mmc_get_config(struct udevice *dev)
uint low, high;
char env_name[32];
int err;
- ofnode node = dev_ofnode(dev);
int bus_width = 1;
ulong new_max_freq;
debug("%s(%s)", __func__, dev->name);
slot->cfg.name = dev->name;
- slot->cfg.f_max = ofnode_read_s32_default(dev_ofnode(dev),
- "max-frequency",
- 26000000);
+ slot->cfg.f_max = dev_read_s32_default(dev, "max-frequency", 26000000);
snprintf(env_name, sizeof(env_name), "mmc_max_frequency%d",
slot->bus_id);
@@ -3562,26 +3559,21 @@ static int octeontx_mmc_get_config(struct udevice *dev)
if (IS_ENABLED(CONFIG_ARCH_OCTEONTX2)) {
slot->hs400_tuning_block =
- ofnode_read_s32_default(dev_ofnode(dev),
- "marvell,hs400-tuning-block",
- -1);
+ dev_read_s32_default(dev, "marvell,hs400-tuning-block", -1);
debug("%s(%s): mmc HS400 tuning block: %d\n", __func__,
dev->name, slot->hs400_tuning_block);
slot->hs200_tap_adj =
- ofnode_read_s32_default(dev_ofnode(dev),
- "marvell,hs200-tap-adjust", 0);
+ dev_read_s32_default(dev, "marvell,hs200-tap-adjust", 0);
debug("%s(%s): hs200-tap-adjust: %d\n", __func__, dev->name,
slot->hs200_tap_adj);
slot->hs400_tap_adj =
- ofnode_read_s32_default(dev_ofnode(dev),
- "marvell,hs400-tap-adjust", 0);
+ dev_read_s32_default(dev, "marvell,hs400-tap-adjust", 0);
debug("%s(%s): hs400-tap-adjust: %d\n", __func__, dev->name,
slot->hs400_tap_adj);
}
- err = ofnode_read_u32_array(dev_ofnode(dev), "voltage-ranges",
- voltages, 2);
+ err = dev_read_u32_array(dev, "voltage-ranges", voltages, 2);
if (err) {
slot->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
} else {
@@ -3601,12 +3593,12 @@ static int octeontx_mmc_get_config(struct udevice *dev)
} while (low <= high);
}
debug("%s: config voltages: 0x%x\n", __func__, slot->cfg.voltages);
- slot->slew = ofnode_read_s32_default(node, "cavium,clk-slew", -1);
- slot->drive = ofnode_read_s32_default(node, "cavium,drv-strength", -1);
+ slot->slew = dev_read_s32_default(dev, "cavium,clk-slew", -1);
+ slot->drive = dev_read_s32_default(dev, "cavium,drv-strength", -1);
gpio_request_by_name(dev, "cd-gpios", 0, &slot->cd_gpio, GPIOD_IS_IN);
- slot->cd_inverted = ofnode_read_bool(node, "cd-inverted");
+ slot->cd_inverted = dev_read_bool(dev, "cd-inverted");
gpio_request_by_name(dev, "wp-gpios", 0, &slot->wp_gpio, GPIOD_IS_IN);
- slot->wp_inverted = ofnode_read_bool(node, "wp-inverted");
+ slot->wp_inverted = dev_read_bool(dev, "wp-inverted");
if (slot->cfg.voltages & MMC_VDD_165_195) {
slot->is_1_8v = true;
slot->is_3_3v = false;
@@ -3617,7 +3609,7 @@ static int octeontx_mmc_get_config(struct udevice *dev)
slot->is_3_3v = true;
}
- bus_width = ofnode_read_u32_default(node, "bus-width", 1);
+ bus_width = dev_read_u32_default(dev, "bus-width", 1);
/* Note fall-through */
switch (bus_width) {
case 8:
@@ -3628,63 +3620,63 @@ static int octeontx_mmc_get_config(struct udevice *dev)
slot->cfg.host_caps |= MMC_MODE_1BIT;
break;
}
- if (ofnode_read_bool(node, "no-1-8-v")) {
+ if (dev_read_bool(dev, "no-1-8-v")) {
slot->is_3_3v = true;
slot->is_1_8v = false;
if (!(slot->cfg.voltages & (MMC_VDD_32_33 | MMC_VDD_33_34)))
pr_warn("%s(%s): voltages indicate 3.3v but 3.3v not supported\n",
__func__, dev->name);
}
- if (ofnode_read_bool(node, "mmc-ddr-3-3v")) {
+ if (dev_read_bool(dev, "mmc-ddr-3-3v")) {
slot->is_3_3v = true;
slot->is_1_8v = false;
if (!(slot->cfg.voltages & (MMC_VDD_32_33 | MMC_VDD_33_34)))
pr_warn("%s(%s): voltages indicate 3.3v but 3.3v not supported\n",
__func__, dev->name);
}
- if (ofnode_read_bool(node, "cap-sd-highspeed") ||
- ofnode_read_bool(node, "cap-mmc-highspeed") ||
- ofnode_read_bool(node, "sd-uhs-sdr25"))
+ if (dev_read_bool(dev, "cap-sd-highspeed") ||
+ dev_read_bool(dev, "cap-mmc-highspeed") ||
+ dev_read_bool(dev, "sd-uhs-sdr25"))
slot->cfg.host_caps |= MMC_MODE_HS;
if (slot->cfg.f_max >= 50000000 &&
slot->cfg.host_caps & MMC_MODE_HS)
slot->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
- if (ofnode_read_bool(node, "sd-uhs-sdr50"))
+ if (dev_read_bool(dev, "sd-uhs-sdr50"))
slot->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
- if (ofnode_read_bool(node, "sd-uhs-ddr50"))
+ if (dev_read_bool(dev, "sd-uhs-ddr50"))
slot->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz |
MMC_MODE_DDR_52MHz;
if (IS_ENABLED(CONFIG_ARCH_OCTEONTX2)) {
if (!slot->is_asim && !slot->is_emul) {
- if (ofnode_read_bool(node, "mmc-hs200-1_8v"))
+ if (dev_read_bool(dev, "mmc-hs200-1_8v"))
slot->cfg.host_caps |= MMC_MODE_HS200 |
MMC_MODE_HS_52MHz;
- if (ofnode_read_bool(node, "mmc-hs400-1_8v"))
+ if (dev_read_bool(dev, "mmc-hs400-1_8v"))
slot->cfg.host_caps |= MMC_MODE_HS400 |
MMC_MODE_HS_52MHz |
MMC_MODE_HS200 |
MMC_MODE_DDR_52MHz;
slot->cmd_out_hs200_delay =
- ofnode_read_u32_default(node,
+ dev_read_u32_default(dev,
"marvell,cmd-out-hs200-dly",
MMC_DEFAULT_HS200_CMD_OUT_DLY);
debug("%s(%s): HS200 cmd out delay: %d\n",
__func__, dev->name, slot->cmd_out_hs200_delay);
slot->data_out_hs200_delay =
- ofnode_read_u32_default(node,
+ dev_read_u32_default(dev,
"marvell,data-out-hs200-dly",
MMC_DEFAULT_HS200_DATA_OUT_DLY);
debug("%s(%s): HS200 data out delay: %d\n",
__func__, dev->name, slot->data_out_hs200_delay);
slot->cmd_out_hs400_delay =
- ofnode_read_u32_default(node,
+ dev_read_u32_default(dev,
"marvell,cmd-out-hs400-dly",
MMC_DEFAULT_HS400_CMD_OUT_DLY);
debug("%s(%s): HS400 cmd out delay: %d\n",
__func__, dev->name, slot->cmd_out_hs400_delay);
slot->data_out_hs400_delay =
- ofnode_read_u32_default(node,
+ dev_read_u32_default(dev,
"marvell,data-out-hs400-dly",
MMC_DEFAULT_HS400_DATA_OUT_DLY);
debug("%s(%s): HS400 data out delay: %d\n",
@@ -3692,12 +3684,10 @@ static int octeontx_mmc_get_config(struct udevice *dev)
}
}
- slot->disable_ddr = ofnode_read_bool(node, "marvell,disable-ddr");
- slot->non_removable = ofnode_read_bool(node, "non-removable");
- slot->cmd_clk_skew = ofnode_read_u32_default(node,
- "cavium,cmd-clk-skew", 0);
- slot->dat_clk_skew = ofnode_read_u32_default(node,
- "cavium,dat-clk-skew", 0);
+ slot->disable_ddr = dev_read_bool(dev, "marvell,disable-ddr");
+ slot->non_removable = dev_read_bool(dev, "non-removable");
+ slot->cmd_clk_skew = dev_read_u32_default(dev, "cavium,cmd-clk-skew", 0);
+ slot->dat_clk_skew = dev_read_u32_default(dev, "cavium,dat-clk-skew", 0);
debug("%s(%s): host caps: 0x%x\n", __func__,
dev->name, slot->cfg.host_caps);
return 0;
@@ -3843,7 +3833,6 @@ static int octeontx_mmc_host_probe(struct udevice *dev)
pr_err("%s: No device tree information found\n", __func__);
return -1;
}
- host->node = dev_ofnode(dev);
host->last_slotid = -1;
#if !defined(CONFIG_ARCH_OCTEON)
if (otx_is_platform(PLATFORM_ASIM))
@@ -3851,9 +3840,7 @@ static int octeontx_mmc_host_probe(struct udevice *dev)
if (otx_is_platform(PLATFORM_EMULATOR))
host->is_emul = true;
#endif
- host->dma_wait_delay =
- ofnode_read_u32_default(dev_ofnode(dev),
- "marvell,dma-wait-delay", 1);
+ host->dma_wait_delay = dev_read_u32_default(dev, "marvell,dma-wait-delay", 1);
/* Force reset of eMMC */
writeq(0, host->base_addr + MIO_EMM_CFG());
debug("%s: Clearing MIO_EMM_CFG\n", __func__);
@@ -3922,13 +3909,12 @@ static int octeontx_mmc_host_child_pre_probe(struct udevice *dev)
struct octeontx_mmc_host *host = dev_get_priv(dev_get_parent(dev));
struct octeontx_mmc_slot *slot;
struct mmc_uclass_priv *upriv;
- ofnode node = dev_ofnode(dev);
u32 bus_id;
char name[16];
int err;
debug("%s(%s) Pre-Probe\n", __func__, dev->name);
- if (ofnode_read_u32(node, "reg", &bus_id)) {
+ if (dev_read_u32(dev, "reg", &bus_id)) {
pr_err("%s(%s): Error: \"reg\" not found in device tree\n",
__func__, dev->name);
return -1;
diff --git a/drivers/mmc/octeontx_hsmmc.h b/drivers/mmc/octeontx_hsmmc.h
index 9849121f174..c374ce18838 100644
--- a/drivers/mmc/octeontx_hsmmc.h
+++ b/drivers/mmc/octeontx_hsmmc.h
@@ -123,7 +123,6 @@ struct octeontx_mmc_host {
union mio_emm_cfg emm_cfg;
u64 timing_taps;
struct mmc *last_mmc; /** Last mmc used */
- ofnode node;
int cur_slotid;
int last_slotid;
int max_width;
diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c
index d446c55f72b..82e393fd9d6 100644
--- a/drivers/mmc/pci_mmc.c
+++ b/drivers/mmc/pci_mmc.c
@@ -137,11 +137,11 @@ static int pci_mmc_acpi_fill_ssdt(const struct udevice *dev,
return 0;
}
-struct acpi_ops pci_mmc_acpi_ops = {
#ifdef CONFIG_ACPIGEN
+static const struct acpi_ops pci_mmc_acpi_ops = {
.fill_ssdt = pci_mmc_acpi_fill_ssdt,
-#endif
};
+#endif
static const struct udevice_id pci_mmc_match[] = {
{ .compatible = "intel,apl-sd", .data = TYPE_SD },
diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c
index a76f9e8d6bd..5bbc18dfa51 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -39,9 +39,6 @@ static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = {
{ "cdns,phy-dll-delay-strobe", SDHCI_CDNS_PHY_DLY_STROBE, },
};
-static int __maybe_unused sdhci_cdns_execute_tuning(struct udevice *dev,
- unsigned int opcode);
-
static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_plat *plat,
u8 addr, u8 data)
{
@@ -158,93 +155,8 @@ static void sdhci_cdns_set_control_reg(struct sdhci_host *host)
sdhci_cdns6_phy_adj(mmc->dev, plat, mmc->selected_mode);
}
-static __maybe_unused bool sdhci_cdns_sd_needs_tuning(struct mmc *mmc)
-{
- struct sdhci_cdns_plat *plat = dev_get_plat(mmc->dev);
-
- if (!IS_SD(mmc))
- return false;
-
- if (!dev_read_bool(mmc->dev, "cdns,sd-hs-tuning"))
- return false;
-
- /* Already tuned for this mode */
- if (plat->tuned_mode == mmc->selected_mode)
- return false;
-
- switch (mmc->selected_mode) {
- case SD_HS:
- return mmc->bus_width == 4;
- /* Add future modes here, e.g.:
- * case UHS_SDR50:
- * return true;
- */
- default:
- return false;
- }
-}
-
-static int sdhci_cdns_set_ios_post(struct sdhci_host *host)
-{
- struct mmc *mmc = host->mmc;
- struct sdhci_cdns_plat *plat = dev_get_plat(mmc->dev);
- int ret __maybe_unused;
- /*
- * The SD6HC soft PHY requires runtime DLL delay calibration
- * for SD High Speed mode. The default PHY_DLL_SLAVE_CTRL_REG
- * values (READ_DQS_CMD_DELAY and READ_DQS_DELAY = 0) do not
- * provide sufficient timing margin due to PVT and board trace
- * variations.
- *
- * Tuning is performed once per entry into SD_HS mode
- * (tracked by plat->tuned_mode state). The calibrated PHY delay
- * values remain valid while the card stays in SD_HS mode, and
- * leaving that tuned mode clears the state so re-entering SD_HS
- * triggers tuning again.
- *
- * This must be done in set_ios_post (not set_control_reg)
- * because the SDHCI controller must already be operating at
- * the target bus width, clock, and speed mode before CMD19
- * tuning commands can succeed.
- */
-
- if (IS_ENABLED(CONFIG_MMC_SUPPORTS_TUNING)) {
- if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_420 &&
- sdhci_cdns_sd_needs_tuning(mmc)) {
- ret = sdhci_cdns_execute_tuning(mmc->dev,
- MMC_CMD_SEND_TUNING_BLOCK);
- if (ret) {
- dev_err(mmc->dev,
- "SD_HS tuning failed (ret=%d), using default PHY\n",
- ret);
- /* Restore default PHY settings and avoid retrying in this mode */
- sdhci_cdns6_phy_adj(mmc->dev, plat,
- mmc->selected_mode);
- plat->tuned_mode = mmc->selected_mode;
- plat->tuned_dll_slave_ctrl = sdhci_cdns6_phy_get_dll_slave(plat);
- return 0;
- }
- /*
- * Tuning succeeded. The tuned_mode is already set by
- * execute_tuning(), so the tuned value will be preserved
- * across subsequent PHY reconfigurations.
- */
- dev_dbg(mmc->dev, "SD_HS tuning successful\n");
- }
-
- /* Reset when mode changes away from a tuned mode */
- if (mmc->selected_mode != plat->tuned_mode) {
- plat->tuned_mode = MMC_MODES_END;
- plat->tuned_dll_slave_ctrl = 0;
- }
- }
-
- return 0;
-}
-
static const struct sdhci_ops sdhci_cdns_ops = {
.set_control_reg = sdhci_cdns_set_control_reg,
- .set_ios_post = sdhci_cdns_set_ios_post,
};
static int sdhci_cdns_set_tune_val(struct sdhci_cdns_plat *plat,
@@ -292,7 +204,6 @@ static int __maybe_unused sdhci_cdns_execute_tuning(struct udevice *dev,
int cur_streak = 0;
int max_streak = 0;
int end_of_streak = 0;
- int ret;
int i;
/*
@@ -318,24 +229,7 @@ static int __maybe_unused sdhci_cdns_execute_tuning(struct udevice *dev,
return -EIO;
}
- ret = sdhci_cdns_set_tune_val(plat, end_of_streak - max_streak / 2);
- if (ret)
- return ret;
-
- /*
- * Mark this mode as tuned. This is critical for both driver tuning
- * (SD_HS via set_ios_post) and framework tuning (UHS_SDR104, MMC_HS_200,
- * MMC_HS_400) so that subsequent PHY reconfigurations restore the
- * calibrated DLL value instead of overwriting with DT defaults.
- *
- * For HS400, tuning is performed while the controller is in HS200 mode
- * (mmc->selected_mode == MMC_HS_200 and mmc->hs400_tuning == true).
- * Record the tuned mode as MMC_HS_400 so the calibrated DLL value is
- * preserved across the HS200→HS400 transition.
- */
- plat->tuned_mode = mmc->hs400_tuning ? MMC_HS_400 : mmc->selected_mode;
-
- return 0;
+ return sdhci_cdns_set_tune_val(plat, end_of_streak - max_streak / 2);
}
static struct dm_mmc_ops sdhci_cdns_mmc_ops;
diff --git a/drivers/mmc/sdhci-cadence.h b/drivers/mmc/sdhci-cadence.h
index ea517491860..7101f00b75b 100644
--- a/drivers/mmc/sdhci-cadence.h
+++ b/drivers/mmc/sdhci-cadence.h
@@ -7,8 +7,6 @@
#ifndef SDHCI_CADENCE_H_
#define SDHCI_CADENCE_H_
-#include <mmc.h>
-
/* HRS - Host Register Set (specific to Cadence) */
/* PHY access port */
#define SDHCI_CDNS_HRS04 0x10
@@ -62,13 +60,10 @@ struct sdhci_cdns_plat {
struct mmc_config cfg;
struct mmc mmc;
void __iomem *hrs_addr;
- enum bus_mode tuned_mode;
- u32 tuned_dll_slave_ctrl;
};
int sdhci_cdns6_phy_adj(struct udevice *dev, struct sdhci_cdns_plat *plat, u32 mode);
int sdhci_cdns6_phy_init(struct udevice *dev, struct sdhci_cdns_plat *plat);
int sdhci_cdns6_set_tune_val(struct sdhci_cdns_plat *plat, unsigned int val);
-u32 sdhci_cdns6_phy_get_dll_slave(struct sdhci_cdns_plat *plat);
#endif
diff --git a/drivers/mmc/sdhci-cadence6.c b/drivers/mmc/sdhci-cadence6.c
index c8b42532e17..ca1086e2359 100644
--- a/drivers/mmc/sdhci-cadence6.c
+++ b/drivers/mmc/sdhci-cadence6.c
@@ -173,30 +173,6 @@ static void sdhci_cdns6_write_phy_reg(struct sdhci_cdns_plat *plat, u32 addr, u3
writel(val, plat->hrs_addr + SDHCI_CDNS_HRS05);
}
-static bool sdhci_cdns6_mode_is_tuned(struct sdhci_cdns_plat *plat, u32 mode)
-{
- /*
- * Check if the given mode has a valid tuned DLL value.
- * Only modes that support tuning (driver or framework) can have
- * valid tuned values. This prevents the initial state (tuned_mode=0)
- * from falsely matching MMC_LEGACY.
- */
- if (plat->tuned_mode != mode)
- return false;
-
- switch (mode) {
- case SD_HS: /* Driver tuning via set_ios_post */
- case UHS_SDR50: /* Future driver tuning support */
- case UHS_SDR104: /* Framework tuning */
- case MMC_HS_200: /* Framework tuning */
- case MMC_HS_400: /* Framework tuning */
- case MMC_HS_400_ES: /* Framework tuning */
- return true;
- default:
- return false;
- }
-}
-
static int sdhci_cdns6_reset_phy_dll(struct sdhci_cdns_plat *plat, bool reset)
{
void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS09;
@@ -283,18 +259,7 @@ int sdhci_cdns6_phy_adj(struct udevice *dev, struct sdhci_cdns_plat *plat, u32 m
sdhci_cdns6_write_phy_reg(plat, PHY_DQS_TIMING_REG_ADDR, sdhci_cdns6_phy_cfgs[0].val);
sdhci_cdns6_write_phy_reg(plat, PHY_GATE_LPBK_CTRL_REG_ADDR, sdhci_cdns6_phy_cfgs[1].val);
sdhci_cdns6_write_phy_reg(plat, PHY_DLL_MASTER_CTRL_REG_ADDR, sdhci_cdns6_phy_cfgs[4].val);
- if (sdhci_cdns6_mode_is_tuned(plat, mode)) {
- /*
- * Use previously saved tuned DLL slave control value.
- * Note: 0 is a valid tuned value (e.g., optimal tap at position 0),
- * so we check both mode match AND that it's a tunable mode.
- */
- sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR,
- plat->tuned_dll_slave_ctrl);
- } else {
- sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR,
- sdhci_cdns6_phy_cfgs[2].val);
- }
+ sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR, sdhci_cdns6_phy_cfgs[2].val);
/* Switch Off the DLL Reset */
ret = sdhci_cdns6_reset_phy_dll(plat, false);
@@ -353,9 +318,6 @@ int sdhci_cdns6_set_tune_val(struct sdhci_cdns_plat *plat, unsigned int val)
sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR, tmp);
- /* Store tuned DLL slave control value which will be reapplied via set_ios(). */
- plat->tuned_dll_slave_ctrl = tmp;
-
/* Switch Off the DLL Reset */
ret = sdhci_cdns6_reset_phy_dll(plat, false);
if (ret) {
@@ -365,8 +327,3 @@ int sdhci_cdns6_set_tune_val(struct sdhci_cdns_plat *plat, unsigned int val)
return 0;
}
-
-u32 sdhci_cdns6_phy_get_dll_slave(struct sdhci_cdns_plat *plat)
-{
- return sdhci_cdns6_read_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR);
-}
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 648dfa4b5ef..71a6d8ea2f5 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -215,7 +215,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
u32 mask, flags, mode = 0;
unsigned int time = 0;
int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
- ulong start = get_timer(0);
+ ulong start;
host->start_addr = 0;
/* Timeout unit - ms */
@@ -551,7 +551,7 @@ void sdhci_set_uhs_timing(struct sdhci_host *host)
void sdhci_set_voltage(struct sdhci_host *host)
{
- if (IS_ENABLED(CONFIG_MMC_IO_VOLTAGE)) {
+ if (CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)) {
struct mmc *mmc = (struct mmc *)host->mmc;
u32 ctrl;
diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c
index 0e4902fab77..6aa73792f96 100644
--- a/drivers/mmc/xenon_sdhci.c
+++ b/drivers/mmc/xenon_sdhci.c
@@ -537,10 +537,9 @@ static int xenon_sdhci_of_to_plat(struct udevice *dev)
host->ioaddr = dev_read_addr_ptr(dev);
if (device_is_compatible(dev, "marvell,armada-3700-sdhci"))
- priv->pad_ctrl_reg = devfdt_get_addr_index_ptr(dev, 1);
+ priv->pad_ctrl_reg = dev_read_addr_index_ptr(dev, 1);
- name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "marvell,pad-type",
- NULL);
+ name = ofnode_get_property(dev_ofnode(dev), "marvell,pad-type", NULL);
if (name) {
if (0 == strncmp(name, "sd", 2)) {
priv->pad_type = SOC_PAD_SD;
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 21b8b21f6b2..38d6dd142dd 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -205,16 +205,16 @@ config HBMC_AM654
bool "HyperBus controller driver for AM65x SoC"
depends on MULTIPLEXER && (MUX_MMIO || SPL_MUX_MMIO)
help
- This is the driver for HyperBus controller on TI's AM65x and
- other SoCs
+ This is the driver for HyperBus controller on TI's AM65x and
+ other SoCs
config STM32_FLASH
bool "STM32 MCU Flash driver"
depends on ARCH_STM32
select USE_SYS_MAX_FLASH_BANKS
help
- This is the driver of embedded flash for some STMicroelectronics
- STM32 MCU.
+ This is the driver of embedded flash for some STMicroelectronics
+ STM32 MCU.
config SYS_MAX_FLASH_SECT
int "Maximum number of sectors on a flash chip"
@@ -236,17 +236,17 @@ config SYS_MAX_FLASH_BANKS
depends on USE_SYS_MAX_FLASH_BANKS
default 1
help
- Max number of Flash memory banks using by the MTD framework, in the
- flash CFI driver and in some other driver to define the flash_info
- struct declaration.
+ Max number of Flash memory banks using by the MTD framework, in the
+ flash CFI driver and in some other driver to define the flash_info
+ struct declaration.
config SYS_MAX_FLASH_BANKS_DETECT
bool "Detection of flash banks number in CFI driver"
depends on CFI_FLASH && FLASH_CFI_DRIVER
help
- This enables detection of number of flash banks in CFI driver,
- to reduce the effective number of flash bank, between 0 and
- CONFIG_SYS_MAX_FLASH_BANKS
+ This enables detection of number of flash banks in CFI driver,
+ to reduce the effective number of flash bank, between 0 and
+ CONFIG_SYS_MAX_FLASH_BANKS
source "drivers/mtd/nand/Kconfig"
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 78ae04bdcba..5ffec9502b6 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
config MTD_NAND_CORE
- tristate
+ bool
source "drivers/mtd/nand/raw/Kconfig"
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 2999e6b1710..b5dfad7380f 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -310,47 +310,47 @@ choice
prompt "ECC scheme"
default NAND_OMAP_ECCSCHEME_BCH8_CODE_HW
help
- On OMAP platforms, this CONFIG specifies NAND ECC scheme.
- It can take following values:
- OMAP_ECC_HAM1_CODE_SW
+ On OMAP platforms, this CONFIG specifies NAND ECC scheme.
+ It can take following values:
+ OMAP_ECC_HAM1_CODE_SW
1-bit Hamming code using software lib.
(for legacy devices only)
- OMAP_ECC_HAM1_CODE_HW
+ OMAP_ECC_HAM1_CODE_HW
1-bit Hamming code using GPMC hardware.
(for legacy devices only)
- OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
+ OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
4-bit BCH code (unsupported)
- OMAP_ECC_BCH4_CODE_HW
+ OMAP_ECC_BCH4_CODE_HW
4-bit BCH code (unsupported)
- OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
+ OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
8-bit BCH code with
- ecc calculation using GPMC hardware engine,
- error detection using software library.
- requires CONFIG_BCH to enable software BCH library
(For legacy device which do not have ELM h/w engine)
- OMAP_ECC_BCH8_CODE_HW
+ OMAP_ECC_BCH8_CODE_HW
8-bit BCH code with
- ecc calculation using GPMC hardware engine,
- error detection using ELM hardware engine.
- OMAP_ECC_BCH16_CODE_HW
+ OMAP_ECC_BCH16_CODE_HW
16-bit BCH code with
- ecc calculation using GPMC hardware engine,
- error detection using ELM hardware engine.
- How to select ECC scheme on OMAP and AMxx platforms ?
- -----------------------------------------------------
- Though higher ECC schemes have more capability to detect and correct
- bit-flips, but still selection of ECC scheme is dependent on following
- - hardware engines present in SoC.
+ How to select ECC scheme on OMAP and AMxx platforms ?
+ -----------------------------------------------------
+ Though higher ECC schemes have more capability to detect and correct
+ bit-flips, but still selection of ECC scheme is dependent on following
+ - hardware engines present in SoC.
Some legacy OMAP SoC do not have ELM h/w engine thus such
SoC cannot support BCHx_HW ECC schemes.
- - size of OOB/Spare region
+ - size of OOB/Spare region
With higher ECC schemes, more OOB/Spare area is required to
store ECC. So choice of ECC scheme is limited by NAND oobsize.
- In general following expression can help:
+ In general following expression can help:
NAND_OOBSIZE >= 2 + (NAND_PAGESIZE / 512) * ECC_BYTES
- where
+ where
NAND_OOBSIZE = number of bytes available in
OOB/spare area per NAND page.
NAND_PAGESIZE = bytes in main-area of NAND page.
diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c
index 7324dc72e0a..ef01d48acc0 100644
--- a/drivers/mtd/nand/raw/pxa3xx_nand.c
+++ b/drivers/mtd/nand/raw/pxa3xx_nand.c
@@ -184,6 +184,7 @@ struct pxa3xx_nand_host {
struct pxa3xx_nand_info {
struct nand_hw_control controller;
struct pxa3xx_nand_platform_data *pdata;
+ struct udevice *dev;
struct clk *clk;
void __iomem *mmio_base;
@@ -585,8 +586,7 @@ static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len)
ts = get_timer(0);
while (!(nand_readl(info, NDSR) & NDSR_RDDREQ)) {
if (get_timer(ts) > TIMEOUT_DRAIN_FIFO) {
- dev_err(info->controller.active->mtd.dev,
- "Timeout on RDDREQ while draining the FIFO\n");
+ dev_err(info->dev, "Timeout on RDDREQ while draining the FIFO\n");
return;
}
}
@@ -638,8 +638,7 @@ static void handle_data_pio(struct pxa3xx_nand_info *info)
DIV_ROUND_UP(info->step_spare_size, 4));
break;
default:
- dev_err(info->controller.active->mtd.dev,
- "%s: invalid state %d\n", __func__, info->state);
+ dev_err(info->dev, "%s: invalid state %d\n", __func__, info->state);
BUG();
}
@@ -1557,8 +1556,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->size = 512;
if (ecc_stepsize != 512 || !(nfc_layouts[i].strength)) {
- dev_err(info->controller.active->mtd.dev,
- "ECC strength %d at page size %d is not supported\n",
+ dev_err(info->dev, "ECC strength %d at page size %d is not supported\n",
strength, page_size);
return -ENODEV;
}
@@ -1799,6 +1797,7 @@ static int pxa3xx_nand_probe(struct udevice *dev)
if (ret)
return ret;
+ info->dev = dev;
pdata = info->pdata;
ret = alloc_nand_resource(dev, info);
diff --git a/drivers/mtd/nand/raw/rockchip_nfc.c b/drivers/mtd/nand/raw/rockchip_nfc.c
index f730e15d041..ea8e67d1a23 100644
--- a/drivers/mtd/nand/raw/rockchip_nfc.c
+++ b/drivers/mtd/nand/raw/rockchip_nfc.c
@@ -861,6 +861,15 @@ static int rk_nfc_ecc_init(struct rk_nfc *nfc, struct nand_chip *chip)
ecc->steps = mtd->writesize / ecc->size;
ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * chip->ecc.size), 8);
+ rknand->metadata_size = NFC_SYS_DATA_SIZE * ecc->steps;
+
+ if (rknand->metadata_size < NFC_SYS_DATA_SIZE + 2) {
+ dev_err(nfc->dev,
+ "driver needs at least %d bytes of meta data\n",
+ NFC_SYS_DATA_SIZE + 2);
+ return -EIO;
+ }
+
if (ecc->bytes * ecc->steps > mtd->oobsize - rknand->metadata_size)
return -EINVAL;
@@ -974,15 +983,6 @@ static int rk_nfc_nand_chip_init(ofnode node, struct rk_nfc *nfc, int devnum)
ret = ofnode_read_u32(node, "rockchip,boot-ecc-strength", &tmp);
rknand->boot_ecc = ret ? ecc->strength : tmp;
- rknand->metadata_size = NFC_SYS_DATA_SIZE * ecc->steps;
-
- if (rknand->metadata_size < NFC_SYS_DATA_SIZE + 2) {
- dev_err(dev,
- "driver needs at least %d bytes of meta data\n",
- NFC_SYS_DATA_SIZE + 2);
- return -EIO;
- }
-
if (!nfc->page_buf) {
nfc->page_buf = kzalloc(NFC_MAX_PAGE_SIZE, GFP_KERNEL);
if (!nfc->page_buf) {
diff --git a/drivers/mtd/nand/raw/sunxi_nand.h b/drivers/mtd/nand/raw/sunxi_nand.h
index d7a8b3dd40c..1b2c514852d 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.h
+++ b/drivers/mtd/nand/raw/sunxi_nand.h
@@ -24,10 +24,7 @@
#define SUNXI_NAND_H
#include <linux/bitops.h>
-
-/* non compile-time field get/prep */
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
+#include <linux/bitfield.h>
#define NFC_REG_CTL 0x0000
#define NFC_REG_ST 0x0004
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index de78a6cb707..4ff58380b59 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -94,39 +94,39 @@ config SPI_FLASH_SFDP_SUPPORT
bool "SFDP table parsing support for SPI NOR flashes"
depends on !SPI_FLASH_BAR
help
- Enable support for parsing and auto discovery of parameters for
- SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
- tables as per JESD216 standard.
+ Enable support for parsing and auto discovery of parameters for
+ SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP)
+ tables as per JESD216 standard.
config SPI_FLASH_SMART_HWCAPS
bool "Smart hardware capability detection based on SPI MEM supports_op() hook"
default y
help
- Enable support for smart hardware capability detection based on SPI
- MEM supports_op() hook that lets controllers express whether they
- can support a type of operation in a much more refined way compared
- to using flags like SPI_RX_DUAL, SPI_TX_QUAD, etc.
+ Enable support for smart hardware capability detection based on SPI
+ MEM supports_op() hook that lets controllers express whether they
+ can support a type of operation in a much more refined way compared
+ to using flags like SPI_RX_DUAL, SPI_TX_QUAD, etc.
config SPI_NOR_BOOT_SOFT_RESET_EXT_INVERT
bool "Command extension type is INVERT for Software Reset on boot"
help
- Because of SFDP information can not be get before boot.
- So define command extension type is INVERT when Software Reset on boot only.
+ Because of SFDP information can not be get before boot.
+ So define command extension type is INVERT when Software Reset on boot only.
config SPI_FLASH_SOFT_RESET
bool "Software Reset support for SPI NOR flashes"
help
- Enable support for xSPI Software Reset. It will be used to switch from
- Octal DTR mode to legacy mode on shutdown and boot (if enabled).
+ Enable support for xSPI Software Reset. It will be used to switch from
+ Octal DTR mode to legacy mode on shutdown and boot (if enabled).
config SPI_FLASH_SOFT_RESET_ON_BOOT
bool "Perform a Software Reset on boot on flashes that boot in stateful mode"
depends on SPI_FLASH_SOFT_RESET
help
- Perform a Software Reset on boot to allow detecting flashes that are
- handed to us in Octal DTR mode. Do not enable this config on flashes
- that are not supposed to be handed to U-Boot in Octal DTR mode, even
- if they _do_ support the Soft Reset sequence.
+ Perform a Software Reset on boot to allow detecting flashes that are
+ handed to us in Octal DTR mode. Do not enable this config on flashes
+ that are not supposed to be handed to U-Boot in Octal DTR mode, even
+ if they _do_ support the Soft Reset sequence.
config SPI_FLASH_BAR
bool "SPI flash Bank/Extended address register support"
@@ -139,18 +139,18 @@ config SPI_FLASH_LOCK
bool "Enable the Locking feature"
default y
help
- Enable the SPI flash lock support. By default this is set to y.
- If you intend not to use the lock support you should say n here.
+ Enable the SPI flash lock support. By default this is set to y.
+ If you intend not to use the lock support you should say n here.
config SPI_FLASH_UNLOCK_ALL
bool "Unlock the entire SPI flash on u-boot startup"
default y
help
- Some flashes tend to power up with the software write protection
- bits set. If this option is set, the whole flash will be unlocked.
+ Some flashes tend to power up with the software write protection
+ bits set. If this option is set, the whole flash will be unlocked.
- For legacy reasons, this option default to y. But if you intend to
- actually use the software protection bits you should say n here.
+ For legacy reasons, this option default to y. But if you intend to
+ actually use the software protection bits you should say n here.
config SPI_FLASH_ATMEL
bool "Atmel SPI flash support"
@@ -201,9 +201,9 @@ config SPI_FLASH_S28HX_T
bool "Cypress SEMPER Octal (S28) chip support"
depends on SPI_FLASH_SPANSION
help
- Add support for the Cypress S28HL-T and S28HS-T chip. This is a separate
- config because the fixup hooks for this flash add extra size overhead.
- Boards that don't use the flash can disable this to save space.
+ Add support for the Cypress S28HL-T and S28HS-T chip. This is a separate
+ config because the fixup hooks for this flash add extra size overhead.
+ Boards that don't use the flash can disable this to save space.
config SPI_FLASH_STMICRO
bool "STMicro SPI flash support"
@@ -214,9 +214,9 @@ config SPI_FLASH_MT35XU
bool "Micron MT35XU chip support"
depends on SPI_FLASH_STMICRO
help
- Add support for the Micron MT35XU chip. This is a separate config
- because the fixup hooks for this flash add extra size overhead. Boards
- that don't use the flash can disable this to save space.
+ Add support for the Micron MT35XU chip. This is a separate config
+ because the fixup hooks for this flash add extra size overhead. Boards
+ that don't use the flash can disable this to save space.
config SPI_FLASH_SST
bool "SST SPI flash support"
@@ -282,7 +282,7 @@ config SPI_FLASH_MTD
bool "SPI Flash MTD support"
depends on SPI_FLASH && MTD
help
- Enable the MTD support for spi flash layer, this adapter is for
+ Enable the MTD support for spi flash layer, this adapter is for
translating mtd_read/mtd_write commands into spi_flash_read/write
commands. It is not intended to use it within sf_cmd or the SPI
flash subsystem. Such an adapter is needed for subsystems like
@@ -294,7 +294,7 @@ config SPL_SPI_FLASH_MTD
bool "SPI flash MTD support for SPL"
depends on SPI_FLASH && SPL
help
- Enable the MTD support for the SPI flash layer in SPL.
+ Enable the MTD support for the SPI flash layer in SPL.
If unsure, say N
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index 44e67cd913a..9a96be11e6d 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -8,14 +8,13 @@ spi-nor-y := sf_probe.o spi-nor-ids.o
ifdef CONFIG_XPL_BUILD
obj-$(CONFIG_SPL_SPI_BOOT) += fsl_espi_spl.o
+endif
+
ifeq ($(CONFIG_$(PHASE_)SPI_FLASH_TINY),y)
spi-nor-y += spi-nor-tiny.o
else
spi-nor-y += spi-nor-core.o
endif
-else
-spi-nor-y += spi-nor-core.o
-endif
obj-$(CONFIG_SPI_FLASH) += spi-nor.o
obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
diff --git a/drivers/mtd/spi/sf_bootdev.c b/drivers/mtd/spi/sf_bootdev.c
index 017a74a3016..6ace4ee0aed 100644
--- a/drivers/mtd/spi/sf_bootdev.c
+++ b/drivers/mtd/spi/sf_bootdev.c
@@ -57,7 +57,7 @@ static int sf_bootdev_bind(struct udevice *dev)
return 0;
}
-struct bootdev_ops sf_bootdev_ops = {
+static const struct bootdev_ops sf_bootdev_ops = {
.get_bootflow = sf_get_bootflow,
};
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 7100b64bf22..dee03662d45 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -229,9 +229,11 @@ static int spi_flash_std_remove(struct udevice *dev)
spi_mem_dirmap_destroy(flash->dirmap.rdesc);
}
- ret = spi_nor_remove(flash);
- if (ret)
- return ret;
+ if (CONFIG_IS_ENABLED(SPI_FLASH_SOFT_RESET)) {
+ ret = spi_nor_remove(flash);
+ if (ret)
+ return ret;
+ }
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
spi_flash_mtd_unregister(flash);
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index c0fa98424aa..31a2ba49a87 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -231,6 +231,10 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+ {
+ INFO("gd55lb02gf", 0xc8601c, 0, 64 * 1024, 4096,
+ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES)
+ },
#endif
#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
/* ISSI */
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index ba77c034736..e523a4c4707 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -82,8 +82,8 @@ config MTD_UBI_BEB_LIMIT
config MTD_UBI_FASTMAP
bool "UBI Fastmap (Experimental feature)"
help
- Important: this feature is experimental so far and the on-flash
- format for fastmap may change in the next kernel versions
+ Important: this feature is experimental so far and the on-flash
+ format for fastmap may change in the next kernel versions
Fastmap is a mechanism which allows attaching an UBI device
in nearly constant time. Instead of scanning the whole MTD device it
diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index de74e5d5e4e..383dac532c1 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -5,17 +5,17 @@ config MULTIPLEXER
depends on DM
select DEVRES
help
- The mux framework is a minimalistic subsystem that handles multiplexer
- controllers. It provides the same API as Linux and mux drivers should
- be portable with a minimum effort.
+ The mux framework is a minimalistic subsystem that handles multiplexer
+ controllers. It provides the same API as Linux and mux drivers should
+ be portable with a minimum effort.
if MULTIPLEXER
config SPL_MUX_MMIO
bool "MMIO register bitfield-controlled Multiplexer"
- depends on MULTIPLEXER && SYSCON
- help
- MMIO register bitfield-controlled Multiplexer controller.
+ depends on MULTIPLEXER && SYSCON
+ help
+ MMIO register bitfield-controlled Multiplexer controller.
The driver builds multiplexer controllers for bitfields in a syscon
register. For N bit wide bitfields, there will be 2^N possible
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 666618681df..4399c6c7a99 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -184,10 +184,10 @@ config CALXEDA_XGMAC
config DWC_ETH_XGMAC
bool
select PHYLIB
- help
- This driver supports the Synopsys Designware Ethernet XGMAC (10G
- Ethernet MAC) IP block. The IP supports many options for bus type,
- clocking/reset structure, and feature list.
+ help
+ This driver supports the Synopsys Designware Ethernet XGMAC (10G
+ Ethernet MAC) IP block. The IP supports many options for bus type,
+ clocking/reset structure, and feature list.
config DWC_ETH_XGMAC_SOCFPGA
bool "Synopsys DWC Ethernet XGMAC device support for SOCFPGA"
@@ -229,8 +229,8 @@ config DWC_ETH_QOS_ADI
bool "Synopsys DWC Ethernet QOS device support for ADI SC59x-64 parts"
depends on DWC_ETH_QOS && ARCH_SC5XX
help
- The Synopsis Designware Ethernet QoS IP block with the specific
- configuration used in the ADI ADSP-SC59X 64 bit SoCs
+ The Synopsis Designware Ethernet QoS IP block with the specific
+ configuration used in the ADI ADSP-SC59X 64 bit SoCs
config DWC_ETH_QOS_IMX
bool "Synopsys DWC Ethernet QOS device support for IMX"
@@ -246,6 +246,20 @@ config DWC_ETH_QOS_INTEL
The Synopsys Designware Ethernet QOS IP block with the specific
configuration used in the Intel Elkhart-Lake soc.
+config DWC_ETH_QOS_MTK
+ bool "Synopsys DWC Ethernet QOS device support for MediaTek SoCs"
+ depends on DWC_ETH_QOS && ARCH_MEDIATEK
+ help
+ The Synopsys Designware Ethernet QOS IP block with the specific
+ configuration used in MediaTek SoCs.
+
+config DWC_ETH_QOS_QCOM
+ bool "Synopsys DWC Ethernet QOS device support for Qcom SoCs"
+ depends on DWC_ETH_QOS
+ help
+ The Synopsys Designware Ethernet QOS IP block with specific
+ configuration used in Qcom QCS404 SoC.
+
config DWC_ETH_QOS_ROCKCHIP
bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs"
depends on DWC_ETH_QOS && ARCH_ROCKCHIP
@@ -254,6 +268,13 @@ config DWC_ETH_QOS_ROCKCHIP
The Synopsys Designware Ethernet QOS IP block with specific
configuration used in Rockchip SoCs.
+config DWC_ETH_QOS_STARFIVE
+ bool "Synopsys DWC Ethernet QOS device support for STARFIVE"
+ depends on DWC_ETH_QOS
+ help
+ The Synopsys Designware Ethernet QOS IP block with specific
+ configuration used in STARFIVE JH7110 soc.
+
config DWC_ETH_QOS_STM32
bool "Synopsys DWC Ethernet QOS device support for STM32"
depends on DWC_ETH_QOS && ARCH_STM32MP
@@ -271,20 +292,6 @@ config DWC_ETH_QOS_TEGRA186
The Synopsys Designware Ethernet QOS IP block with specific
configuration used in NVIDIA's Tegra186 chip.
-config DWC_ETH_QOS_QCOM
- bool "Synopsys DWC Ethernet QOS device support for Qcom SoCs"
- depends on DWC_ETH_QOS
- help
- The Synopsys Designware Ethernet QOS IP block with specific
- configuration used in Qcom QCS404 SoC.
-
-config DWC_ETH_QOS_STARFIVE
- bool "Synopsys DWC Ethernet QOS device support for STARFIVE"
- depends on DWC_ETH_QOS
- help
- The Synopsys Designware Ethernet QOS IP block with specific
- configuration used in STARFIVE JH7110 soc.
-
config E1000
bool "Intel PRO/1000 Gigabit Ethernet support"
depends on PCI
@@ -460,9 +467,9 @@ config FSL_FM_10GEC_REGULAR_NOTATION
help
On SoCs T4240, T2080, LS1043A, etc, the notation between 10GEC and
MAC as below:
- 10GEC1->MAC9, 10GEC2->MAC10, 10GEC3->MAC1, 10GEC4->MAC2
+ 10GEC1->MAC9, 10GEC2->MAC10, 10GEC3->MAC1, 10GEC4->MAC2
While on SoCs T1024, etc, the notation between 10GEC and MAC as below:
- 10GEC1->MAC1, 10GEC2->MAC2
+ 10GEC1->MAC1, 10GEC2->MAC2
so we introduce CONFIG_FSL_FM_10GEC_REGULAR_NOTATION to identify the
new SoCs on which 10GEC enumeration is consistent with MAC
enumeration.
@@ -529,7 +536,7 @@ config KSZ9477
config LITEETH
bool "LiteX LiteEth Ethernet MAC"
help
- Driver for the LiteEth Ethernet MAC from LiteX.
+ Driver for the LiteEth Ethernet MAC from LiteX.
config MV88E6XXX
bool "Marvell MV88E6xxx Ethernet switch DSA driver"
@@ -701,12 +708,12 @@ config SJA1105
family. These are 5-port devices and are managed over an SPI
interface. Probing is handled based on OF bindings. The driver
supports the following revisions:
- - SJA1105E (Gen. 1, No TT-Ethernet)
- - SJA1105T (Gen. 1, TT-Ethernet)
- - SJA1105P (Gen. 2, No SGMII, No TT-Ethernet)
- - SJA1105Q (Gen. 2, No SGMII, TT-Ethernet)
- - SJA1105R (Gen. 2, SGMII, No TT-Ethernet)
- - SJA1105S (Gen. 2, SGMII, TT-Ethernet)
+ - SJA1105E (Gen. 1, No TT-Ethernet)
+ - SJA1105T (Gen. 1, TT-Ethernet)
+ - SJA1105P (Gen. 2, No SGMII, No TT-Ethernet)
+ - SJA1105Q (Gen. 2, No SGMII, TT-Ethernet)
+ - SJA1105R (Gen. 2, SGMII, No TT-Ethernet)
+ - SJA1105S (Gen. 2, SGMII, TT-Ethernet)
config SMC911X
bool "SMSC LAN911x and LAN921x controller driver"
@@ -740,11 +747,11 @@ config SUN4I_EMAC
This driver supports the Allwinner based SUN4I Ethernet MAC.
config SUN8I_EMAC
- bool "Allwinner Sun8i Ethernet MAC support"
- select PHYLIB
+ bool "Allwinner Sun8i Ethernet MAC support"
+ select PHYLIB
select PHY_GIGE
- help
- This driver supports the Allwinner based SUN8I/SUN50I Ethernet MAC.
+ help
+ This driver supports the Allwinner based SUN8I/SUN50I Ethernet MAC.
It can be found in H3/A64/A83T based SoCs and compatible with both
External and Internal PHYs.
@@ -905,7 +912,7 @@ config FEC1_PHY
help
Define to the hardcoded PHY address which corresponds
to the given FEC; i. e.
- #define CONFIG_FEC1_PHY 4
+ #define CONFIG_FEC1_PHY 4
means that the PHY with address 4 is connected to FEC1
When set to -1, means to probe for first available.
@@ -929,7 +936,7 @@ config FEC2_PHY
help
Define to the hardcoded PHY address which corresponds
to the given FEC; i. e.
- #define CONFIG_FEC1_PHY 4
+ #define CONFIG_FEC1_PHY 4
means that the PHY with address 4 is connected to FEC1
When set to -1, means to probe for first available.
@@ -1018,8 +1025,8 @@ config FSL_ENETC
config FSL_ENETC_NETC_BLK_CTRL
bool "NXP ENETC NETC blocks control driver"
depends on FSL_ENETC
- depends on IMX95 || IMX94
- default y if IMX95 || IMX94
+ depends on IMX95 || IMX94 || IMX952
+ default y if IMX95 || IMX94 || IMX952
help
This driver configures Integrated Endpoint Register Block (IERB) and
Privileged Register Block (PRB) of NETC. For i.MX platforms, it also
@@ -1034,7 +1041,7 @@ config MDIO_GPIO_BITBANG
bool "GPIO bitbanging MDIO driver"
depends on DM_MDIO && DM_GPIO
help
- Driver for bitbanging MDIO
+ Driver for bitbanging MDIO
config MDIO_MUX_I2CREG
bool "MDIO MUX accessed as a register over I2C"
@@ -1080,8 +1087,8 @@ config MDIO_MSCC_MIIM
depends on DM_MDIO
select REGMAP
help
- This driver supports MDIO interface found in Microsemi and Microchip
- network switches.
+ This driver supports MDIO interface found in Microsemi and Microchip
+ network switches.
config MDIO_MUX_MMIOREG
bool "MDIO MUX accessed as a MMIO register access"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5e90183d090..761f7f0f451 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -5,7 +5,6 @@
obj-$(CONFIG_AG7XXX) += ag7xxx.o
-obj-y += airoha/
obj-$(CONFIG_AIROHA_ETH) += airoha_eth.o
obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
obj-$(CONFIG_ASPEED_MDIO) += aspeed_mdio.o
@@ -22,12 +21,13 @@ obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
obj-$(CONFIG_DWC_ETH_QOS_ADI) += dwc_eth_qos_adi.o
obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o
obj-$(CONFIG_DWC_ETH_QOS_INTEL) += dwc_eth_qos_intel.o
-obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o
+obj-$(CONFIG_DWC_ETH_QOS_MTK) += dwc_eth_qos_mtk.o
obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o
-obj-$(CONFIG_DWC_ETH_XGMAC) += dwc_eth_xgmac.o
-obj-$(CONFIG_DWC_ETH_XGMAC_SOCFPGA) += dwc_eth_xgmac_socfpga.o
+obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o
obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o
obj-$(CONFIG_DWC_ETH_QOS_STM32) += dwc_eth_qos_stm32.o
+obj-$(CONFIG_DWC_ETH_XGMAC) += dwc_eth_xgmac.o
+obj-$(CONFIG_DWC_ETH_XGMAC_SOCFPGA) += dwc_eth_xgmac_socfpga.o
obj-$(CONFIG_E1000) += e1000.o
obj-$(CONFIG_E1000_SPI) += e1000_spi.o
obj-$(CONFIG_EEPRO100) += eepro100.o
@@ -62,9 +62,9 @@ obj-$(CONFIG_KSZ9477) += ksz9477.o
obj-$(CONFIG_LITEETH) += liteeth.o
obj-$(CONFIG_MACB) += macb.o
obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
+obj-$(CONFIG_MDIO_GPIO_BITBANG) += mdio_gpio.o
obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o
obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
-obj-$(CONFIG_MDIO_GPIO_BITBANG) += mdio_gpio.o
obj-$(CONFIG_MDIO_MT7531_MMIO) += mdio-mt7531-mmio.o
obj-$(CONFIG_MDIO_MUX_I2CREG) += mdio_mux_i2creg.o
obj-$(CONFIG_MDIO_MUX_MESON_G12A) += mdio_mux_meson_g12a.o
@@ -109,6 +109,7 @@ obj-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o
obj-$(CONFIG_XILINX_AXIMRMAC) += xilinx_axi_mrmac.o
obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
+obj-y += airoha/
obj-y += mscc_eswitch/
obj-y += phy/
obj-y += qe/
diff --git a/drivers/net/airoha_eth.c b/drivers/net/airoha_eth.c
index 84ee9b2ad76..e5d39b95cc5 100644
--- a/drivers/net/airoha_eth.c
+++ b/drivers/net/airoha_eth.c
@@ -845,11 +845,45 @@ static int airoha_alloc_gdm_port(struct udevice *dev, ofnode node)
(ulong)eth, node, &gdm_dev);
}
+static struct udevice *airoha_switch_mdio_init(struct udevice *dev)
+{
+ struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev);
+ ofnode switch_node, mdio_node;
+ struct udevice *mdio_dev;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(MDIO_MT7531_MMIO))
+ return NULL;
+
+ switch_node = ofnode_by_compatible(ofnode_null(),
+ data->switch_compatible);
+ if (!ofnode_valid(switch_node)) {
+ debug("Warning: missing airoha switch node\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ mdio_node = ofnode_find_subnode(switch_node, "mdio");
+ if (!ofnode_valid(mdio_node)) {
+ debug("Warning: missing airoha switch mdio subnode\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ ret = device_bind_driver_to_node(dev, "mt7531-mdio-mmio", "mt7531-mdio",
+ mdio_node, &mdio_dev);
+ if (ret) {
+ debug("Warning: failed to bind airoha switch mdio\n");
+ return ERR_PTR(ret);
+ }
+
+ return mdio_dev;
+}
+
static int airoha_eth_probe(struct udevice *dev)
{
struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev);
struct airoha_eth *eth = dev_get_priv(dev);
struct regmap *scu_regmap;
+ struct udevice *mdio_dev;
ofnode node;
int i, ret;
@@ -908,10 +942,10 @@ static int airoha_eth_probe(struct udevice *dev)
if (ret)
return ret;
- if (eth->switch_mdio_dev) {
- if (!device_probe(eth->switch_mdio_dev))
- debug("Warning: failed to probe airoha switch mdio\n");
- }
+ /* Airoha switch mdio PHYs maybe used by several GDM devices */
+ mdio_dev = airoha_switch_mdio_init(dev);
+ if (!IS_ERR_OR_NULL(mdio_dev))
+ eth->switch_mdio_dev = mdio_dev;
ofnode_for_each_subnode(node, dev_ofnode(dev)) {
if (!ofnode_device_is_compatible(node, "airoha,eth-mac"))
@@ -957,6 +991,16 @@ static int airoha_eth_port_probe(struct udevice *dev)
#else
return -EINVAL;
#endif
+ } else {
+ /*
+ * GDM1 device connected to airoha switch. Probe airoha switch
+ * mdio to be able set/query states of corresponding LAN ports.
+ */
+ ret = device_probe(eth->switch_mdio_dev);
+ if (ret) {
+ debug("Warning: failed to probe airoha switch mdio\n");
+ eth->switch_mdio_dev = NULL;
+ }
}
return 0;
@@ -1202,38 +1246,12 @@ static int arht_eth_write_hwaddr(struct udevice *dev)
static int airoha_eth_bind(struct udevice *dev)
{
- struct airoha_eth_soc_data *data = (void *)dev_get_driver_data(dev);
- struct airoha_eth *eth = dev_get_priv(dev);
- ofnode switch_node, mdio_node;
- int ret;
-
/*
* Force Probe as we set the Main ETH driver as misc
* to register multiple eth port for each GDM
*/
dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
- if (!CONFIG_IS_ENABLED(MDIO_MT7531_MMIO))
- return 0;
-
- switch_node = ofnode_by_compatible(ofnode_null(),
- data->switch_compatible);
- if (!ofnode_valid(switch_node)) {
- debug("Warning: missing switch node\n");
- return 0;
- }
-
- mdio_node = ofnode_find_subnode(switch_node, "mdio");
- if (!ofnode_valid(mdio_node)) {
- debug("Warning: missing mdio node\n");
- return 0;
- }
-
- ret = device_bind_driver_to_node(dev, "mt7531-mdio-mmio", "mt7531-mdio",
- mdio_node, &eth->switch_mdio_dev);
- if (ret)
- debug("Warning: failed to bind mdio controller\n");
-
return 0;
}
diff --git a/drivers/net/calxedaxgmac.c b/drivers/net/calxedaxgmac.c
index 92990fa6d47..df0ed820e06 100644
--- a/drivers/net/calxedaxgmac.c
+++ b/drivers/net/calxedaxgmac.c
@@ -555,7 +555,7 @@ static int xgmac_ofdata_to_platdata(struct udevice *dev)
return -ENOMEM;
dev_set_priv(dev, priv);
- pdata->iobase = devfdt_get_addr(dev);
+ pdata->iobase = dev_read_addr(dev);
if (pdata->iobase == FDT_ADDR_T_NONE) {
printf("%s: Cannot find XGMAC base address\n", __func__);
return -EINVAL;
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
index 8fa549280aa..2a21eceac57 100644
--- a/drivers/net/dc2114x.c
+++ b/drivers/net/dc2114x.c
@@ -653,7 +653,7 @@ static int dc2114x_of_to_plat(struct udevice *dev)
struct eth_pdata *plat = dev_get_plat(dev);
struct dc2114x_priv *priv = dev_get_priv(dev);
- plat->iobase = (phys_addr_t)map_physmem((phys_addr_t)devfdt_get_addr(dev), 0, MAP_NOCACHE);
+ plat->iobase = (phys_addr_t)dev_remap_addr(dev);
priv->iobase = (void *)plat->iobase;
return 0;
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 0f31d646845..b7e6299c307 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1659,6 +1659,12 @@ static const struct udevice_id eqos_ids[] = {
.data = (ulong)&eqos_adi_config
},
#endif
+#if IS_ENABLED(CONFIG_DWC_ETH_QOS_MTK)
+ {
+ .compatible = "mediatek,mt8189-gmac",
+ .data = (ulong)&eqos_mtk_config
+ },
+#endif
{ }
};
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index ba16f1a37cb..978b848b46e 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -97,6 +97,7 @@ struct eqos_mac_regs {
#define EQOS_MAC_MDIO_ADDRESS_PA_MASK GENMASK(25, 21)
#define EQOS_MAC_MDIO_ADDRESS_RDA_MASK GENMASK(20, 16)
#define EQOS_MAC_MDIO_ADDRESS_CR_MASK GENMASK(11, 8)
+#define EQOS_MAC_MDIO_ADDRESS_CR_60_100 0
#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1
#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2
#define EQOS_MAC_MDIO_ADDRESS_CR_150_250 4
@@ -316,3 +317,4 @@ extern struct eqos_config eqos_stm32mp15_config;
extern struct eqos_config eqos_stm32mp25_config;
extern struct eqos_config eqos_jh7110_config;
extern struct eqos_config eqos_adi_config;
+extern struct eqos_config eqos_mtk_config;
diff --git a/drivers/net/dwc_eth_qos_mtk.c b/drivers/net/dwc_eth_qos_mtk.c
new file mode 100644
index 00000000000..43e1085dfe5
--- /dev/null
+++ b/drivers/net/dwc_eth_qos_mtk.c
@@ -0,0 +1,442 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Julien Stephan <[email protected]>
+ */
+
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <linux/bitfield.h>
+#include <net.h>
+#include <phy.h>
+#include <regmap.h>
+#include <syscon.h>
+
+#include "dwc_eth_qos.h"
+
+/*
+ * Peri Configuration register is SoC specific,
+ * so add a SoC specific prefix.
+ */
+#define MT8189_PERI_ETH_CTRL0 0x270
+#define MT8189_PERI_ETH_CTRL1 0x274
+#define MT8189_PERI_ETH_CTRL2 0x278
+
+#define EQOS_MTK_RMII_CLK_SRC_INTERNAL BIT(28)
+#define EQOS_MTK_RMII_CLK_SRC_RXC BIT(27)
+#define EQOS_MTK_ETH_INTF_SEL GENMASK(26, 24)
+#define EQOS_MTK_PHY_INTF_MII 0
+#define EQOS_MTK_PHY_INTF_RGMII 1
+#define EQOS_MTK_PHY_INTF_RMII 4
+#define EQOS_MTK_RGMII_TXC_PHASE_CTRL BIT(22)
+#define EQOS_MTK_EXT_PHY_MODE BIT(21)
+#define EQOS_MTK_TXC_OUT_OP BIT(20)
+#define EQOS_MTK_DLY_GTXC_INV BIT(12)
+#define EQOS_MTK_DLY_GTXC_STAGE_FINE GENMASK(11, 6)
+#define EQOS_MTK_DLY_GTXC_ENABLE BIT(5)
+#define EQOS_MTK_DLY_GTXC_STAGES GENMASK(4, 0)
+
+#define EQOS_MTK_DLY_RXC_INV BIT(25)
+#define EQOS_MTK_DLY_RXC_ENABLE BIT(18)
+#define EQOS_MTK_DLY_RXC_STAGES GENMASK(17, 13)
+#define EQOS_MTK_DLY_TXC_INV BIT(12)
+#define EQOS_MTK_DLY_TXC_ENABLE BIT(5)
+#define EQOS_MTK_DLY_TXC_STAGES GENMASK(4, 0)
+
+#define EQOS_MTK_DLY_RMII_RXC_INV BIT(25)
+#define EQOS_MTK_DLY_RMII_RXC_ENABLE BIT(18)
+#define EQOS_MTK_DLY_RMII_RXC_STAGES GENMASK(17, 13)
+#define EQOS_MTK_DLY_RMII_TXC_INV BIT(12)
+#define EQOS_MTK_DLY_RMII_TXC_ENABLE BIT(5)
+#define EQOS_MTK_DLY_RMII_TXC_STAGES GENMASK(4, 0)
+
+#define DELAY_MAX_PS 9800
+#define DELAY_PS_PER_STAGE 290
+
+struct eqos_mtk_priv {
+ struct regmap *peri_regmap;
+ bool rmii_clk_from_mac;
+ bool rmii_rxc;
+ u32 tx_delay_stage;
+ u32 rx_delay_stage;
+ bool tx_inv;
+ bool rx_inv;
+};
+
+static int mtk_clk_init(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ int ret;
+
+ ret = clk_get_by_name(dev, "mac_main", &eqos->clk_tx);
+ if (ret) {
+ dev_err(dev, "clk_get_by_name(mac_main) failed: %d", ret);
+ return ret;
+ }
+
+ ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
+ if (ret) {
+ dev_err(dev, "clk_get_by_name(ptp_ref) failed: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mtk_set_delay(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct eqos_mtk_priv *mtk_pdata = pdata->priv_pdata;
+ u32 gtxc_delay_val = 0, delay_val = 0, rmii_delay_val = 0;
+
+ switch (pdata->phy_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_TXC_ENABLE,
+ !!mtk_pdata->tx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_TXC_STAGES, mtk_pdata->tx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_TXC_INV, mtk_pdata->tx_inv);
+
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_ENABLE,
+ !!mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_STAGES, mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_INV, mtk_pdata->rx_inv);
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ if (mtk_pdata->rmii_clk_from_mac) {
+ /* case 1: mac provides the rmii reference clock,
+ * and the clock output to TXC pin.
+ * The egress timing can be adjusted by RMII_TXC delay macro circuit.
+ * The ingress timing can be adjusted by RMII_RXC delay macro circuit.
+ */
+ rmii_delay_val |= FIELD_PREP(EQOS_MTK_DLY_RMII_TXC_ENABLE,
+ !!mtk_pdata->tx_delay_stage);
+ rmii_delay_val |= FIELD_PREP(EQOS_MTK_DLY_RMII_TXC_STAGES,
+ mtk_pdata->tx_delay_stage);
+ rmii_delay_val |= FIELD_PREP(EQOS_MTK_DLY_RMII_TXC_INV,
+ mtk_pdata->tx_inv);
+
+ rmii_delay_val |= FIELD_PREP(EQOS_MTK_DLY_RMII_RXC_ENABLE,
+ !!mtk_pdata->rx_delay_stage);
+ rmii_delay_val |= FIELD_PREP(EQOS_MTK_DLY_RMII_RXC_STAGES,
+ mtk_pdata->rx_delay_stage);
+ rmii_delay_val |= FIELD_PREP(EQOS_MTK_DLY_RMII_RXC_INV,
+ mtk_pdata->rx_inv);
+ } else {
+ /* case 2: the rmii reference clock is from external phy,
+ * and the property "rmii_rxc" indicates which pin(TXC/RXC)
+ * the reference clk is connected to. The reference clock is a
+ * received signal, so rx_delay_stage/rx_inv are used to indicate
+ * the reference clock timing adjustment
+ */
+ if (mtk_pdata->rmii_rxc) {
+ /* the rmii reference clock from outside is connected
+ * to RXC pin, the reference clock will be adjusted
+ * by RXC delay macro circuit.
+ */
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_ENABLE,
+ !!mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_STAGES,
+ mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_INV,
+ mtk_pdata->rx_inv);
+ } else {
+ /* the rmii reference clock from outside is connected
+ * to TXC pin, the reference clock will be adjusted
+ * by TXC delay macro circuit.
+ */
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_TXC_ENABLE,
+ !!mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_TXC_STAGES,
+ mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_TXC_INV,
+ mtk_pdata->rx_inv);
+ }
+ }
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ gtxc_delay_val |= FIELD_PREP(EQOS_MTK_DLY_GTXC_ENABLE,
+ !!mtk_pdata->tx_delay_stage);
+ gtxc_delay_val |= FIELD_PREP(EQOS_MTK_DLY_GTXC_STAGES,
+ mtk_pdata->tx_delay_stage);
+ gtxc_delay_val |= FIELD_PREP(EQOS_MTK_DLY_GTXC_INV, mtk_pdata->tx_inv);
+ gtxc_delay_val |= EQOS_MTK_DLY_GTXC_STAGE_FINE;
+
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_ENABLE,
+ !!mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_STAGES, mtk_pdata->rx_delay_stage);
+ delay_val |= FIELD_PREP(EQOS_MTK_DLY_RXC_INV, mtk_pdata->rx_inv);
+
+ break;
+ default:
+ dev_err(dev, "phy interface not supported\n");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(mtk_pdata->peri_regmap,
+ MT8189_PERI_ETH_CTRL0,
+ EQOS_MTK_RGMII_TXC_PHASE_CTRL |
+ EQOS_MTK_DLY_GTXC_ENABLE |
+ EQOS_MTK_DLY_GTXC_INV |
+ EQOS_MTK_DLY_GTXC_STAGE_FINE |
+ EQOS_MTK_DLY_GTXC_STAGES,
+ gtxc_delay_val);
+ regmap_write(mtk_pdata->peri_regmap, MT8189_PERI_ETH_CTRL1, delay_val);
+ regmap_write(mtk_pdata->peri_regmap, MT8189_PERI_ETH_CTRL2, rmii_delay_val);
+
+ return 0;
+}
+
+static int mtk_set_interface(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct eqos_mtk_priv *mtk_pdata = pdata->priv_pdata;
+ int rmii_clk_from_mac = mtk_pdata->rmii_clk_from_mac ? EQOS_MTK_RMII_CLK_SRC_INTERNAL : 0;
+ int rmii_rxc = mtk_pdata->rmii_rxc ? EQOS_MTK_RMII_CLK_SRC_RXC : 0;
+ u32 intf_val = 0;
+
+ /* select phy interface in top control domain */
+ switch (pdata->phy_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ intf_val |= FIELD_PREP(EQOS_MTK_ETH_INTF_SEL, EQOS_MTK_PHY_INTF_MII);
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ intf_val |= (rmii_rxc | rmii_clk_from_mac);
+ intf_val |= FIELD_PREP(EQOS_MTK_ETH_INTF_SEL, EQOS_MTK_PHY_INTF_RMII);
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ intf_val |= FIELD_PREP(EQOS_MTK_ETH_INTF_SEL, EQOS_MTK_PHY_INTF_RGMII);
+ break;
+ default:
+ dev_err(dev, "phy interface not supported\n");
+ return -EINVAL;
+ }
+
+ /* only support external PHY */
+ intf_val |= EQOS_MTK_EXT_PHY_MODE;
+
+ intf_val |= EQOS_MTK_TXC_OUT_OP;
+
+ regmap_write(mtk_pdata->peri_regmap, MT8189_PERI_ETH_CTRL0, intf_val);
+
+ return 0;
+}
+
+static int mtk_config_dt(struct udevice *dev)
+{ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct eqos_mtk_priv *mtk_pdata = pdata->priv_pdata;
+ struct ofnode_phandle_args args;
+ u32 tx_delay_ps = 0, rx_delay_ps = 0;
+ int ret;
+
+ if (!dev_read_u32(dev, "mediatek,tx-delay-ps", &tx_delay_ps)) {
+ if (tx_delay_ps > DELAY_MAX_PS) {
+ dev_err(dev, "Invalid TX clock delay: %dps\n", tx_delay_ps);
+ return -EINVAL;
+ }
+ }
+
+ if (!dev_read_u32(dev, "mediatek,rx-delay-ps", &rx_delay_ps)) {
+ if (rx_delay_ps > DELAY_MAX_PS) {
+ dev_err(dev, "Invalid RX clock delay: %dps\n", rx_delay_ps);
+ return -EINVAL;
+ }
+ }
+
+ mtk_pdata->tx_delay_stage = tx_delay_ps / DELAY_PS_PER_STAGE;
+ mtk_pdata->rx_delay_stage = rx_delay_ps / DELAY_PS_PER_STAGE;
+
+ mtk_pdata->tx_inv = dev_read_bool(dev, "mediatek,txc-inverse");
+ mtk_pdata->rx_inv = dev_read_bool(dev, "mediatek,rxc-inverse");
+ mtk_pdata->rmii_clk_from_mac = dev_read_bool(dev, "mediatek,rmii-clk-from-mac");
+ mtk_pdata->rmii_rxc = dev_read_bool(dev, "mediatek,rmii-rxc");
+
+ ret = dev_read_phandle_with_args(dev, "mediatek,pericfg", NULL, 0, 0, &args);
+ if (ret) {
+ dev_err(dev, "Failed to get mediatek,pericfg property: %d\n", ret);
+ return ret;
+ }
+
+ mtk_pdata->peri_regmap = syscon_node_to_regmap(args.node);
+ if (IS_ERR(mtk_pdata->peri_regmap)) {
+ dev_err(dev, "fail to get regmap: %d\n", (int)PTR_ERR(mtk_pdata->peri_regmap));
+ return PTR_ERR(mtk_pdata->peri_regmap);
+ }
+
+ return 0;
+}
+
+static int eqos_probe_resources_mtk(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct eqos_mtk_priv *mtk_pdata;
+ int ret;
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ ret = eqos_get_base_addr_dt(dev);
+ if (ret) {
+ dev_err(dev, "eqos_get_base_addr_dt failed: %d\n", ret);
+ return ret;
+ }
+
+ mtk_pdata = calloc(1, sizeof(struct eqos_mtk_priv));
+ if (!mtk_pdata)
+ return -ENOMEM;
+
+ pdata->priv_pdata = mtk_pdata;
+
+ ret = mtk_config_dt(dev);
+ if (ret) {
+ dev_err(dev, "mtk config dt failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = mtk_clk_init(dev);
+ if (ret)
+ goto err;
+
+ pdata->phy_interface = eqos->config->interface(dev);
+ if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
+ dev_err(dev, "Invalid PHY interface\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = mtk_set_interface(dev);
+ if (ret)
+ goto err;
+
+ ret = mtk_set_delay(dev);
+ if (ret)
+ goto err;
+
+ debug("%s: OK\n", __func__);
+ return 0;
+err:
+ free(mtk_pdata);
+ return ret;
+}
+
+static int eqos_remove_resources_mtk(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct eqos_mtk_priv *mtk_pdata = pdata->priv_pdata;
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ free(mtk_pdata);
+
+ debug("%s: OK\n", __func__);
+ return 0;
+}
+
+static int eqos_stop_clks_mtk(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ clk_disable(&eqos->clk_ptp_ref);
+ clk_disable(&eqos->clk_tx);
+
+ debug("%s: OK\n", __func__);
+ return 0;
+}
+
+static int eqos_start_clks_mtk(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ int ret;
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ ret = clk_enable(&eqos->clk_tx);
+ if (ret < 0) {
+ dev_err(dev, "clk_enable(mac_main) failed: %d", ret);
+ goto err;
+ }
+
+ ret = clk_enable(&eqos->clk_ptp_ref);
+ if (ret < 0) {
+ dev_err(dev, "clk_enable(ptp_ref) failed: %d", ret);
+ goto err_disable_clk_mac_main;
+ }
+
+ debug("%s: OK\n", __func__);
+ return 0;
+
+err_disable_clk_mac_main:
+ clk_disable(&eqos->clk_tx);
+err:
+ debug("%s: FAILED: %d\n", __func__, ret);
+ return ret;
+}
+
+static int eqos_fix_mac_speed_mtk(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct eqos_mtk_priv *mtk_pdata = pdata->priv_pdata;
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ switch (pdata->phy_interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ if (eqos->phy->speed == SPEED_1000)
+ regmap_update_bits(mtk_pdata->peri_regmap,
+ MT8189_PERI_ETH_CTRL0,
+ EQOS_MTK_RGMII_TXC_PHASE_CTRL |
+ EQOS_MTK_DLY_GTXC_ENABLE |
+ EQOS_MTK_DLY_GTXC_INV |
+ EQOS_MTK_DLY_GTXC_STAGE_FINE |
+ EQOS_MTK_DLY_GTXC_STAGES,
+ EQOS_MTK_RGMII_TXC_PHASE_CTRL);
+ else
+ mtk_set_delay(dev);
+ break;
+ default:
+ debug("%s: dev=%p no need to adjust mac delay\n", __func__, dev);
+ break;
+ }
+
+ debug("%s: OK\n", __func__);
+ return 0;
+}
+
+static struct eqos_ops eqos_mtk_ops = {
+ .eqos_inval_desc = eqos_inval_desc_generic,
+ .eqos_flush_desc = eqos_flush_desc_generic,
+ .eqos_inval_buffer = eqos_inval_buffer_generic,
+ .eqos_flush_buffer = eqos_flush_buffer_generic,
+ .eqos_probe_resources = eqos_probe_resources_mtk,
+ .eqos_remove_resources = eqos_remove_resources_mtk,
+ .eqos_stop_resets = eqos_null_ops,
+ .eqos_start_resets = eqos_null_ops,
+ .eqos_stop_clks = eqos_stop_clks_mtk,
+ .eqos_start_clks = eqos_start_clks_mtk,
+ .eqos_calibrate_pads = eqos_null_ops,
+ .eqos_disable_calibration = eqos_null_ops,
+ .eqos_set_tx_clk_speed = eqos_fix_mac_speed_mtk,
+ .eqos_get_enetaddr = eqos_null_ops,
+};
+
+struct eqos_config eqos_mtk_config = {
+ .reg_access_always_ok = false,
+ .mdio_wait = 10000,
+ .swr_wait = 10,
+ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
+ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_60_100,
+ .axi_bus_width = EQOS_AXI_WIDTH_64,
+ .interface = dev_read_phy_mode,
+ .ops = &eqos_mtk_ops
+};
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index dc7e6f1929f..87b2b3426c8 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -686,7 +686,7 @@ static int ethoc_of_to_plat(struct udevice *dev)
fdt_addr_t addr;
pdata->eth_pdata.iobase = dev_read_addr(dev);
- addr = devfdt_get_addr_index(dev, 1);
+ addr = dev_read_addr_index(dev, 1);
if (addr != FDT_ADDR_T_NONE)
pdata->packet_base = addr;
return 0;
diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c
index 206f1a381bb..f393af40e27 100644
--- a/drivers/net/fsl_enetc.c
+++ b/drivers/net/fsl_enetc.c
@@ -18,6 +18,7 @@
#include <asm/io.h>
#include <pci.h>
#include <miiphy.h>
+#include <linux/bitfield.h>
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/build_bug.h>
@@ -74,10 +75,36 @@ static int enetc_is_ls1028a(struct udevice *dev)
pplat->vendor == PCI_VENDOR_ID_FREESCALE;
}
+static int enetc_dev_id_imx(struct udevice *dev)
+{
+ if (IS_ENABLED(CONFIG_IMX952)) {
+ int bus_devfn;
+ u32 reg[5];
+ int error;
+
+ error = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg));
+ if (error)
+ return error;
+
+ bus_devfn = (reg[0] >> 8) & 0xffff;
+
+ switch (bus_devfn) {
+ case 0:
+ return 0;
+ case 0x100:
+ return 1;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return PCI_DEV(pci_get_devfn(dev)) >> 3;
+}
+
static int enetc_dev_id(struct udevice *dev)
{
if (enetc_is_imx95(dev))
- return PCI_DEV(pci_get_devfn(dev)) >> 3;
+ return enetc_dev_id_imx(dev);
if (enetc_is_ls1028a(dev))
return PCI_FUNC(pci_get_devfn(dev));
@@ -396,7 +423,7 @@ static int enetc_init_sgmii(struct udevice *dev)
/* set up MAC for RGMII */
static void enetc_init_rgmii(struct udevice *dev, struct phy_device *phydev)
{
- u32 old_val, val, dpx = 0;
+ u32 old_val, val = 0;
old_val = val = enetc_read_mac_port(dev, ENETC_PM_IF_MODE);
@@ -416,15 +443,14 @@ static void enetc_init_rgmii(struct udevice *dev, struct phy_device *phydev)
val |= ENETC_PM_IFM_SSP_10;
}
- if (enetc_is_imx95(dev))
- dpx = ENETC_PM_IFM_FULL_DPX_IMX;
+ if (enetc_is_imx95(dev))
+ val = u32_replace_bits(val,
+ phydev->duplex == DUPLEX_FULL ? 0 : 1,
+ ENETC_PM_IFM_FULL_DPX_IMX);
else if (enetc_is_ls1028a(dev))
- dpx = ENETC_PM_IFM_FULL_DPX_LS;
-
- if (phydev->duplex == DUPLEX_FULL)
- val |= dpx;
- else
- val &= ~dpx;
+ val = u32_replace_bits(val,
+ phydev->duplex == DUPLEX_FULL ? 1 : 0,
+ ENETC_PM_IFM_FULL_DPX_LS);
if (val == old_val)
return;
diff --git a/drivers/net/fsl_enetc_netc_blk_ctrl.c b/drivers/net/fsl_enetc_netc_blk_ctrl.c
index 8577bb75632..0c87d80ea5c 100644
--- a/drivers/net/fsl_enetc_netc_blk_ctrl.c
+++ b/drivers/net/fsl_enetc_netc_blk_ctrl.c
@@ -35,6 +35,7 @@
#define MII_PROT_RGMII 0x2
#define MII_PROT_SERIAL 0x3
#define MII_PROT(port, prot) (((prot) & 0xf) << ((port) << 2))
+#define MII_PROT_GET(reg, port) (((reg) >> ((port) << 2)) & 0xf)
#define IMX95_CFG_LINK_PCS_PROT(a) (0x8 + (a) * 4)
#define PCS_PROT_1G_SGMII BIT(0)
@@ -97,6 +98,9 @@
#define IMX94_TIMER1_ID 1
#define IMX94_TIMER2_ID 2
+#define IMX952_ENETC0_BUS_DEVFN 0x0
+#define IMX952_ENETC1_BUS_DEVFN 0x100
+
/* Flags for different platforms */
#define NETC_HAS_NETCMIX BIT(0)
@@ -567,6 +571,69 @@ static int netc_prb_check_error(struct netc_blk_ctrl *priv)
return 0;
}
+static int imx952_netcmix_init(struct udevice *dev)
+{
+ struct netc_blk_ctrl *priv = dev_get_priv(dev);
+ ofnode child, gchild;
+ phy_interface_t interface;
+ int bus_devfn, mii_proto;
+ u32 val;
+
+ /* Default setting */
+ val = MII_PROT(0, MII_PROT_RGMII) | MII_PROT(1, MII_PROT_RGMII);
+
+ /* Update the link MII protocol through parsing phy-mode */
+ dev_for_each_subnode(child, dev) {
+ if (!ofnode_is_enabled(child))
+ continue;
+
+ ofnode_for_each_subnode(gchild, child) {
+ if (!ofnode_is_enabled(gchild))
+ continue;
+
+ if (!ofnode_device_is_compatible(gchild, "pci1131,e101"))
+ continue;
+
+ bus_devfn = netc_of_pci_get_bus_devfn(gchild);
+ if (bus_devfn < 0)
+ return -EINVAL;
+
+ interface = ofnode_read_phy_mode(gchild);
+ if (interface == -1)
+ continue;
+
+ mii_proto = netc_get_link_mii_protocol(interface);
+ if (mii_proto < 0)
+ return -EINVAL;
+
+ switch (bus_devfn) {
+ case IMX952_ENETC0_BUS_DEVFN:
+ val &= ~CFG_LINK_MII_PORT_0;
+ val |= FIELD_PREP(CFG_LINK_MII_PORT_0, mii_proto);
+ break;
+ case IMX952_ENETC1_BUS_DEVFN:
+ val &= ~CFG_LINK_MII_PORT_1;
+ val |= FIELD_PREP(CFG_LINK_MII_PORT_1, mii_proto);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (MII_PROT_GET(val, 1) == MII_PROT_SERIAL) {
+ /* Configure Link I/O variant */
+ netc_reg_write(priv->netcmix, IMX95_CFG_LINK_IO_VAR,
+ IO_VAR(1, IO_VAR_16FF_16G_SERDES));
+ /* Configure Link 2 PCS protocol */
+ netc_reg_write(priv->netcmix, IMX95_CFG_LINK_PCS_PROT(1),
+ PCS_PROT_2500M_SGMII);
+ }
+ netc_reg_write(priv->netcmix, IMX95_CFG_LINK_MII_PROT, val);
+
+ return 0;
+}
+
static const struct netc_devinfo imx95_devinfo = {
.netcmix_init = imx95_netcmix_init,
.ierb_init = imx95_ierb_init,
@@ -578,9 +645,14 @@ static const struct netc_devinfo imx94_devinfo = {
.xpcs_port_init = imx94_netc_xpcs_port_init,
};
+static const struct netc_devinfo imx952_devinfo = {
+ .netcmix_init = imx952_netcmix_init,
+};
+
static const struct udevice_id netc_blk_ctrl_match[] = {
{ .compatible = "nxp,imx95-netc-blk-ctrl", .data = (ulong)&imx95_devinfo },
{ .compatible = "nxp,imx94-netc-blk-ctrl", .data = (ulong)&imx94_devinfo },
+ { .compatible = "nxp,imx952-netc-blk-ctrl", .data = (ulong)&imx952_devinfo },
{},
};
diff --git a/drivers/net/hifemac.c b/drivers/net/hifemac.c
index 62182f922f8..7dda8cb8815 100644
--- a/drivers/net/hifemac.c
+++ b/drivers/net/hifemac.c
@@ -401,9 +401,6 @@ static void hisi_femac_get_strings(struct udevice *dev, u8 *data)
strcpy(data + i * ETH_GSTRING_LEN, hisi_femac_stats_table[i].name);
}
-/* Non-constant mask variant of FIELD_GET/FIELD_PREP */
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-
static void hisi_femac_get_stats(struct udevice *dev, u64 *data)
{
int i;
diff --git a/drivers/net/mcfmii.c b/drivers/net/mcfmii.c
index 9bf887035d7..79ad6348de8 100644
--- a/drivers/net/mcfmii.c
+++ b/drivers/net/mcfmii.c
@@ -112,7 +112,7 @@ uint mii_send(uint mii_cmd)
ep->eir = FEC_EIR_MII; /* clear MII complete */
#ifdef ET_DEBUG
printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
- __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply);
+ __FILE__, __LINE__, __func__, mii_cmd, mii_reply);
#endif
return (mii_reply & 0xffff); /* data read from phy */
diff --git a/drivers/net/mtk_eth/Kconfig b/drivers/net/mtk_eth/Kconfig
index 5d4e54ab90e..7d58f542bde 100644
--- a/drivers/net/mtk_eth/Kconfig
+++ b/drivers/net/mtk_eth/Kconfig
@@ -5,6 +5,7 @@ config MEDIATEK_ETH
select PHYLIB
select DM_GPIO
select DM_RESET
+ select LMB_LIMIT_DMA_BELOW_RAM_TOP
help
This Driver support MediaTek Ethernet GMAC
Say Y to enable support for the MediaTek Ethernet GMAC.
diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index 107a33aa9f5..4dc738980cb 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -256,8 +256,8 @@ static void set_dram_access(struct mvgbe_registers *regs)
win_param.access_ctrl = EWIN_ACCESS_FULL;
win_param.high_addr = 0;
/* Get bank base and size */
- win_param.base_addr = gd->bd->bi_dram[i].start;
- win_param.size = gd->bd->bi_dram[i].size;
+ win_param.base_addr = gd->dram[i].start;
+ win_param.size = gd->dram[i].size;
if (win_param.size == 0)
win_param.enable = 0;
else
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index f9e979c4d58..ae5920a0201 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -4528,7 +4528,7 @@ static void mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port)
*/
if (phy_dev &&
phy_dev->drv->uid == 0xffffffff) {/* Generic phy */
- dev_warn(port->phy_dev->dev,
+ dev_warn(dev,
"Marking phy as invalid, link will not be checked\n");
/* set phy_addr to invalid value */
port->phyaddr = PHY_MAX_ADDR;
@@ -4540,7 +4540,7 @@ static void mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port)
port->phy_dev = phy_dev;
if (!phy_dev) {
- dev_err(port->phy_dev->dev, "cannot connect to phy\n");
+ dev_err(dev, "cannot connect to phy\n");
return;
}
phy_dev->supported &= PHY_GBIT_FEATURES;
@@ -4731,33 +4731,32 @@ static int mvpp2_port_init(struct udevice *dev, struct mvpp2_port *port)
static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
{
- int port_node = dev_of_offset(dev);
- int phy_node;
+ ofnode port_node = dev_ofnode(dev);
+ ofnode phy_node;
u32 id;
int phyaddr = 0;
- int fixed_link = 0;
+ ofnode fixed_link;
int ret;
- phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy");
- fixed_link = fdt_subnode_offset(gd->fdt_blob, port_node, "fixed-link");
+ phy_node = ofnode_parse_phandle(port_node, "phy", 0);
+ fixed_link = ofnode_find_subnode(port_node, "fixed-link");
- if (phy_node > 0) {
- int parent;
+ if (ofnode_valid(phy_node)) {
+ ofnode parent;
- if (fixed_link != -FDT_ERR_NOTFOUND) {
+ if (ofnode_valid(fixed_link)) {
/* phy_addr is set to invalid value for fixed links */
phyaddr = PHY_MAX_ADDR;
} else {
- phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node,
- "reg", 0);
+ phyaddr = ofnode_read_s32_default(phy_node, "reg", 0);
if (phyaddr < 0) {
dev_err(dev, "could not find phy address\n");
return -1;
}
}
- parent = fdt_parent_offset(gd->fdt_blob, phy_node);
- ret = uclass_get_device_by_of_offset(UCLASS_MDIO, parent,
- &port->mdio_dev);
+ parent = ofnode_get_parent(phy_node);
+ ret = uclass_get_device_by_ofnode(UCLASS_MDIO, parent,
+ &port->mdio_dev);
if (ret)
return ret;
} else {
@@ -4771,7 +4770,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
return -EINVAL;
}
- id = fdtdec_get_int(gd->fdt_blob, port_node, "port-id", -1);
+ id = dev_read_s32_default(dev, "port-id", -1);
if (id == -1) {
dev_err(dev, "missing port-id value\n");
return -EINVAL;
@@ -4812,7 +4811,7 @@ static void mvpp2_gpio_init(struct mvpp2_port *port)
/* Ports initialization */
static int mvpp2_port_probe(struct udevice *dev,
struct mvpp2_port *port,
- int port_node,
+ ofnode port_node,
struct mvpp2 *priv)
{
int err;
@@ -5296,16 +5295,16 @@ static int mvpp2_base_probe(struct udevice *dev)
}
/* Save base addresses for later use */
- priv->base = devfdt_get_addr_index_ptr(dev, 0);
+ priv->base = dev_read_addr_index_ptr(dev, 0);
if (!priv->base)
return -EINVAL;
if (priv->hw_version == MVPP21) {
- priv->lms_base = devfdt_get_addr_index_ptr(dev, 1);
+ priv->lms_base = dev_read_addr_index_ptr(dev, 1);
if (!priv->lms_base)
return -EINVAL;
} else {
- priv->iface_base = devfdt_get_addr_index_ptr(dev, 1);
+ priv->iface_base = dev_read_addr_index_ptr(dev, 1);
if (!priv->iface_base)
return -EINVAL;
@@ -5346,13 +5345,11 @@ static int mvpp2_probe(struct udevice *dev)
if (priv->hw_version == MVPP21) {
int priv_common_regs_num = 2;
- port->base = devfdt_get_addr_index_ptr(
- dev->parent, priv_common_regs_num + port->id);
+ port->base = dev_read_addr_index_ptr(dev->parent, priv_common_regs_num + port->id);
if (!port->base)
return -EINVAL;
} else {
- port->gop_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "gop-port-id", -1);
+ port->gop_id = ofnode_read_s32_default(dev_ofnode(dev), "gop-port-id", -1);
if (port->gop_id == -1) {
dev_err(dev, "missing gop-port-id value\n");
return -EINVAL;
@@ -5376,7 +5373,7 @@ static int mvpp2_probe(struct udevice *dev)
priv->probe_done = 1;
}
- err = mvpp2_port_probe(dev, port, dev_of_offset(dev), priv);
+ err = mvpp2_port_probe(dev, port, dev_ofnode(dev), priv);
if (err)
return err;
@@ -5437,13 +5434,11 @@ static struct driver mvpp2_driver = {
*/
static int mvpp2_base_bind(struct udevice *parent)
{
- const void *blob = gd->fdt_blob;
- int node = dev_of_offset(parent);
struct uclass_driver *drv;
struct udevice *dev;
struct eth_pdata *plat;
char *name;
- int subnode;
+ ofnode subnode;
u32 id;
int base_id_add;
@@ -5456,19 +5451,19 @@ static int mvpp2_base_bind(struct udevice *parent)
base_id_add = base_id;
- fdt_for_each_subnode(subnode, blob, node) {
+ dev_for_each_subnode(subnode, parent) {
/* Increment base_id for all subnodes, also the disabled ones */
base_id++;
/* Skip disabled ports */
- if (!fdtdec_get_is_enabled(blob, subnode))
+ if (!ofnode_is_enabled(subnode))
continue;
plat = calloc(1, sizeof(*plat));
if (!plat)
return -ENOMEM;
- id = fdtdec_get_int(blob, subnode, "port-id", -1);
+ id = ofnode_read_s32_default(subnode, "port-id", -1);
id += base_id_add;
name = calloc(1, 16);
@@ -5479,8 +5474,7 @@ static int mvpp2_base_bind(struct udevice *parent)
sprintf(name, "mvpp2-%d", id);
/* Create child device UCLASS_ETH and bind it */
- device_bind(parent, &mvpp2_driver, name, plat,
- offset_to_ofnode(subnode), &dev);
+ device_bind(parent, &mvpp2_driver, name, plat, subnode, &dev);
}
return 0;
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 0025c895f12..ee438524490 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -81,7 +81,7 @@ config PHYLIB_10G
config PHY_ADIN
bool "Analog Devices Industrial Ethernet PHYs"
help
- Add support for configuring RGMII on Analog Devices ADIN PHYs.
+ Add support for configuring RGMII on Analog Devices ADIN PHYs.
menuconfig PHY_AQUANTIA
bool "Aquantia Ethernet PHYs support"
@@ -126,9 +126,9 @@ config SYS_CORTINA_NO_FW_UPLOAD
bool "Cortina firmware loading support"
depends on PHY_CORTINA
help
- Cortina phy has provision to store phy firmware in attached dedicated
- EEPROM. And boards designed with such EEPROM does not require firmware
- upload.
+ Cortina phy has provision to store phy firmware in attached dedicated
+ EEPROM. And boards designed with such EEPROM does not require firmware
+ upload.
choice
prompt "Location of the Cortina firmware"
@@ -167,7 +167,7 @@ config PHY_CORTINA_ACCESS
default y
depends on CORTINA_NI_ENET
help
- Cortina Access Ethernet PHYs init process
+ Cortina Access Ethernet PHYs init process
config PHY_DAVICOM
bool "Davicom Ethernet PHYs support"
@@ -233,7 +233,7 @@ config PHY_MICREL_KSZ8XXX
endif # PHY_MICREL
config PHY_MOTORCOMM
- tristate "Motorcomm PHYs"
+ bool "Motorcomm PHYs"
help
Enables support for Motorcomm network PHYs.
Currently supports the YT8511 and YT8531 Gigabit Ethernet PHYs.
@@ -246,7 +246,7 @@ config PHY_NATSEMI
bool "National Semiconductor Ethernet PHYs support"
config PHY_NXP_C45_TJA11XX
- tristate "NXP C45 TJA11XX PHYs"
+ bool "NXP C45 TJA11XX PHYs"
select DEVRES
help
Enable support for NXP C45 TJA11XX PHYs.
@@ -317,13 +317,13 @@ config PHY_TERANETICS
config PHY_TI
bool "Texas Instruments Ethernet PHYs support"
- ---help---
+ help
Adds PHY registration support for TI PHYs.
config PHY_TI_DP83867
select PHY_TI
bool "Texas Instruments Ethernet DP83867 PHY support"
- ---help---
+ help
Adds support for the TI DP83867 1Gbit PHY.
config SPL_PHY_TI_DP83867
@@ -333,13 +333,13 @@ config SPL_PHY_TI_DP83867
config PHY_TI_DP83869
select PHY_TI
bool "Texas Instruments Ethernet DP83869 PHY support"
- ---help---
+ help
Adds support for the TI DP83869 1Gbit PHY.
config PHY_TI_GENERIC
select PHY_TI
bool "Texas Instruments Generic Ethernet PHYs support"
- ---help---
+ help
Adds support for Generic TI PHYs that don't need special handling but
the PHY name is associated with a PHY ID.
diff --git a/drivers/net/phy/airoha/Kconfig b/drivers/net/phy/airoha/Kconfig
index 4139df343ad..2d58d674200 100644
--- a/drivers/net/phy/airoha/Kconfig
+++ b/drivers/net/phy/airoha/Kconfig
@@ -2,12 +2,25 @@
menuconfig PHY_AIROHA
bool "Airoha Ethernet PHYs support"
+config PHY_AIROHA_AN8801
+ bool "Airoha Ethernet AN8801 support"
+ depends on PHY_AIROHA
+ select PHY_AIROHA_PHYLIB
+ help
+ Currently support AIROHA AN8801 1G PHY.
+
config PHY_AIROHA_EN8811
bool "Airoha Ethernet EN8811H support"
depends on PHY_AIROHA
depends on SUPPORTS_FW_LOADER
select FW_LOADER
+ select PHY_AIROHA_PHYLIB
select PHY_COMMON_PROPS
help
AIROHA EN8811H supported.
AIROHA AN8811HB supported.
+
+config PHY_AIROHA_PHYLIB
+ bool
+ help
+ Airoha Ethernet PHY common library
diff --git a/drivers/net/phy/airoha/Makefile b/drivers/net/phy/airoha/Makefile
index 84d23b19ab0..25e44004cfd 100644
--- a/drivers/net/phy/airoha/Makefile
+++ b/drivers/net/phy/airoha/Makefile
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_AIROHA_AN8801) += air_an8801.o
obj-$(CONFIG_PHY_AIROHA_EN8811) += air_en8811.o
+obj-$(CONFIG_PHY_AIROHA_PHYLIB) += air_phy_lib.o
diff --git a/drivers/net/phy/airoha/air_an8801.c b/drivers/net/phy/airoha/air_an8801.c
new file mode 100644
index 00000000000..9d9958fc665
--- /dev/null
+++ b/drivers/net/phy/airoha/air_an8801.c
@@ -0,0 +1,594 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * air_an8801.c - PHY driver for Airoha AN8801.
+ * Copyright (c) 2026 Airoha Technology Corp.
+ * Copyright (C) 2026 BayLibre, SAS.
+ * Author: Kevin-KW Huang <[email protected]>
+ * Sita Huang <[email protected]>
+ * Julien Stephan <[email protected]>
+ */
+
+#include <malloc.h>
+#include <phy.h>
+#include <dm/device_compat.h>
+
+#include "air_phy_lib.h"
+
+#define AN8801R_PHY_ID1 0xc0ff
+#define AN8801R_PHY_ID2 0x0421
+#define AN8801R_PHY_ID ((u32)((AN8801R_PHY_ID1 << 16) | AN8801R_PHY_ID2))
+
+#define AN8801R_MAX_LED_SIZE 3
+
+/* MII Registers - Airoha Page 4 */
+#define AN8801_PBUS_ACCESS BIT(28)
+
+/* BPBUS Registers */
+#define AN8801_BPBUS_REG_LED_GPIO 0x54
+#define AN8801_BPBUS_REG_LED_ID_SEL 0x58
+#define LED_ID_GPIO_SEL(led, gpio) ((led) << ((gpio) * 3))
+
+#define AN8801_BPBUS_REG_GPIO_MODE 0x70
+
+#define AN8801_BPBUS_REG_LINK_MODE 0x5054
+#define AN8801_BPBUS_LINK_MODE_1000 BIT(0)
+
+#define AN8801_BPBUS_REG_BYPASS_PTP 0x21c004
+#define AN8801_BYP_PTP_RGMII_TO_GPHY BIT(0)
+
+#define AN8801_BPBUS_REG_TXDLY_STEP 0x21c024
+#define RGMII_DELAY_STEP_MASK GENMASK(2, 0)
+#define AIR_RGMII_DELAY_NOSTEP 0
+#define AIR_RGMII_DELAY_STEP_1 1
+#define AIR_RGMII_DELAY_STEP_2 2
+#define AIR_RGMII_DELAY_STEP_3 3
+#define AIR_RGMII_DELAY_STEP_4 4
+#define AIR_RGMII_DELAY_STEP_5 5
+#define AIR_RGMII_DELAY_STEP_6 6
+#define AIR_RGMII_DELAY_STEP_7 7
+#define RGMII_TXDELAY_FORCE_MODE BIT(24)
+
+#define AN8801_BPBUS_REG_RXDLY_STEP 0x21c02c
+#define RGMII_RXDELAY_ALIGN BIT(4)
+#define RGMII_RXDELAY_FORCE_MODE BIT(24)
+
+#define AN8801_BPBUS_REG_EFIFO_CTL(x) (0x270004 + (0x100 * (x))) /* 0..2 */
+#define AN8801_EFIFO_ALL_EN GENMASK(7, 0)
+#define AN8801_EFIFO_RX_EN BIT(0)
+#define AN8801_EFIFO_TX_EN BIT(1)
+#define AN8801_EFIFO_RX_CLK_EN BIT(2)
+#define AN8801_EFIFO_TX_CLK_EN BIT(3)
+#define AN8801_EFIFO_RX_EEE_EN BIT(4)
+#define AN8801_EFIFO_TX_EEE_EN BIT(5)
+#define AN8801_EFIFO_RX_ODD_NIBBLE_EN BIT(6)
+#define AN8801_EFIFO_TX_ODD_NIBBLE_EN BIT(7)
+
+#define AN8801_BPBUS_REG_HWRST_DE_GLITCH 0xc8
+#define AN8801_DE_GLITCH_EN BIT(2)
+#define AN8801_11_CYCLE_XTAL_PERIOD_DE_GLITCH GENMASK(1, 0)
+
+#define LED_BCR 0x21
+#define LED_BCR_MODE_MASK GENMASK(1, 0)
+#define LED_BCR_TIME_TEST BIT(2)
+#define LED_BCR_CLK_EN BIT(3)
+#define LED_BCR_EVT_ALL BIT(4)
+#define LED_BCR_EXT_CTRL BIT(15)
+#define LED_BCR_MODE_DISABLE 0
+#define LED_BCR_MODE_2LED 1
+#define LED_BCR_MODE_3LED_1 2
+#define LED_BCR_MODE_3LED_2 3
+
+#define LED_ON_DUR 0x22
+#define LED_ON_DUR_MASK GENMASK(15, 0)
+
+#define LED_BLINK_DUR 0x23
+#define LED_BLINK_DUR_MASK GENMASK(15, 0)
+
+#define LED_ON_CTRL(i) (0x024 + ((i) * 2))
+#define LED_ON_EVT_MASK GENMASK(6, 0)
+#define LED_ON_EVT_LINK_1000M BIT(0)
+#define LED_ON_EVT_LINK_100M BIT(1)
+#define LED_ON_EVT_LINK_10M BIT(2)
+#define LED_ON_EVT_LINK_DN BIT(3)
+#define LED_ON_EVT_FDX BIT(4)
+#define LED_ON_EVT_HDX BIT(5)
+#define LED_ON_EVT_FORCE BIT(6)
+#define LED_ON_POL BIT(14)
+#define LED_ON_EN BIT(15)
+
+#define LED_BLINK_CTRL(i) (0x025 + ((i) * 2))
+#define LED_BLINK_EVT_MASK GENMASK(9, 0)
+#define LED_BLINK_EVT_1000M_TX BIT(0)
+#define LED_BLINK_EVT_1000M_RX BIT(1)
+#define LED_BLINK_EVT_100M_TX BIT(2)
+#define LED_BLINK_EVT_100M_RX BIT(3)
+#define LED_BLINK_EVT_10M_TX BIT(4)
+#define LED_BLINK_EVT_10M_RX BIT(5)
+#define LED_BLINK_EVT_FORCE BIT(9)
+
+#define UNIT_LED_BLINK_DURATION 780
+#define LED_BLINK_DURATION(f) (UNIT_LED_BLINK_DURATION << (f))
+
+/* Link on(1G/100M/10M), no activity */
+#define AIR_LED0_ON \
+ (LED_ON_EVT_LINK_1000M | LED_ON_EVT_LINK_100M | LED_ON_EVT_LINK_10M)
+#define AIR_LED0_BLINK 0x0
+/* No link on, activity(1G/100M/10M TX/RX) */
+#define AIR_LED1_ON 0x0
+#define AIR_LED1_BLINK \
+ (LED_BLINK_EVT_1000M_TX | LED_BLINK_EVT_1000M_RX | \
+ LED_BLINK_EVT_100M_TX | LED_BLINK_EVT_100M_RX | \
+ LED_BLINK_EVT_10M_TX | LED_BLINK_EVT_10M_RX)
+/* Link on(100M/10M), activity(100M/10M TX/RX) */
+#define AIR_LED2_ON \
+ (LED_ON_EVT_LINK_100M | LED_ON_EVT_LINK_10M)
+#define AIR_LED2_BLINK \
+ (LED_BLINK_EVT_100M_TX | LED_BLINK_EVT_100M_RX | \
+ LED_BLINK_EVT_10M_TX | LED_BLINK_EVT_10M_RX)
+
+#define INVALID_DATA GENMASK(31, 0)
+
+#define AN8801_REG_PHY_INTERNAL0 0x600
+#define AN8801_REG_PHY_INTERNAL1 0x601
+
+#define AN8801_LED_ENABLE 1
+
+enum air_led_gpio_pin {
+ AIR_LED_GPIO1 = 1,
+ AIR_LED_GPIO2,
+ AIR_LED_GPIO3
+};
+
+enum air_led {
+ AIR_LED0 = 0,
+ AIR_LED1,
+ AIR_LED2,
+ AIR_LED3
+};
+
+enum air_led_blink_dut {
+ AIR_LED_BLINK_DUR_32M = 0,
+ AIR_LED_BLINK_DUR_64M,
+ AIR_LED_BLINK_DUR_128M,
+ AIR_LED_BLINK_DUR_256M,
+ AIR_LED_BLINK_DUR_512M,
+ AIR_LED_BLINK_DUR_1024M,
+ AIR_LED_BLINK_DUR_LAST
+};
+
+enum air_led_polarity {
+ AIR_ACTIVE_LOW = 0,
+ AIR_ACTIVE_HIGH,
+};
+
+enum air_led_mode {
+ AIR_LED_MODE_DISABLE = 0,
+ AIR_LED_MODE_USER_DEFINE,
+ AIR_LED_MODE_LAST
+};
+
+struct air_led_cfg {
+ u16 led_en;
+ u16 gpio;
+ u16 led_polarity;
+ u16 led_on_cfg;
+ u16 led_blk_cfg;
+};
+
+struct an8801r_priv {
+ struct air_led_cfg led_cfg[AN8801R_MAX_LED_SIZE];
+ u32 led_blink_cfg;
+ u8 rxdelay_force;
+ u8 txdelay_force;
+ u16 rxdelay_step;
+ u8 rxdelay_align;
+ u16 txdelay_step;
+};
+
+#define phydev_cfg(phy) ((struct an8801r_priv *)(phy)->priv)
+
+/*
+ * GPIO1 <-> LED0,
+ * GPIO2 <-> LED1,
+ * GPIO3 <-> LED2,
+ */
+static const struct an8801r_priv an8801r_priv_defaults = {
+ .led_cfg = {
+ /* LED Enable, GPIO, LED Polarity, LED ON, LED Blink */
+ {AN8801_LED_ENABLE, AIR_LED_GPIO1, AIR_ACTIVE_LOW, AIR_LED0_ON, AIR_LED0_BLINK},
+ {AN8801_LED_ENABLE, AIR_LED_GPIO2, AIR_ACTIVE_HIGH, AIR_LED1_ON, AIR_LED1_BLINK},
+ {AN8801_LED_ENABLE, AIR_LED_GPIO3, AIR_ACTIVE_HIGH, AIR_LED2_ON, AIR_LED2_BLINK},
+ },
+ .led_blink_cfg = AIR_LED_BLINK_DUR_64M,
+ .rxdelay_force = false,
+ .txdelay_force = false,
+ .rxdelay_step = AIR_RGMII_DELAY_NOSTEP,
+ .rxdelay_align = false,
+ .txdelay_step = AIR_RGMII_DELAY_NOSTEP,
+};
+
+static int an8801_buckpbus_reg_rmw(struct phy_device *phydev,
+ u32 addr, u32 mask, u32 set)
+{
+ return air_phy_buckpbus_reg_modify(phydev,
+ addr | AN8801_PBUS_ACCESS,
+ mask, set);
+}
+
+static int an8801_buckpbus_reg_set_bits(struct phy_device *phydev,
+ u32 addr, u32 mask)
+{
+ return air_phy_buckpbus_reg_modify(phydev,
+ addr | AN8801_PBUS_ACCESS,
+ mask, mask);
+}
+
+static int an8801_buckpbus_reg_clear_bits(struct phy_device *phydev,
+ u32 addr, u32 mask)
+{
+ return air_phy_buckpbus_reg_modify(phydev,
+ addr | AN8801_PBUS_ACCESS,
+ mask, 0);
+}
+
+static int an8801_buckpbus_reg_write(struct phy_device *phydev, u32 addr, u32 data)
+{
+ return air_phy_buckpbus_reg_write(phydev, addr | AN8801_PBUS_ACCESS, data);
+}
+
+static int an8801r_led_set_usr_def(struct phy_device *phydev, u8 entity,
+ u16 polar, u16 on_evt, u16 blk_evt)
+{
+ int ret;
+
+ if (polar == AIR_ACTIVE_HIGH)
+ on_evt |= LED_ON_POL;
+ else
+ on_evt &= ~LED_ON_POL;
+
+ on_evt |= LED_ON_EN;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, LED_ON_CTRL(entity), on_evt);
+ if (ret)
+ return ret;
+
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, LED_BLINK_CTRL(entity), blk_evt);
+}
+
+static int an8801r_led_set_blink(struct phy_device *phydev, u16 blink)
+{
+ int ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, LED_BLINK_DUR,
+ LED_BLINK_DURATION(blink));
+ if (ret)
+ return ret;
+
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, LED_ON_DUR,
+ LED_BLINK_DURATION(blink) / 2);
+}
+
+static int an8801r_led_set_mode(struct phy_device *phydev, u8 mode)
+{
+ int ret;
+
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, LED_BCR);
+ if (ret < 0)
+ return ret;
+
+ switch (mode) {
+ case AIR_LED_MODE_DISABLE:
+ ret &= ~LED_BCR_EXT_CTRL;
+ ret &= ~LED_BCR_MODE_MASK;
+ ret |= LED_BCR_MODE_DISABLE;
+ break;
+ case AIR_LED_MODE_USER_DEFINE:
+ ret |= LED_BCR_EXT_CTRL | LED_BCR_CLK_EN;
+ break;
+ }
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, LED_BCR, ret);
+}
+
+static int an8801r_led_set_state(struct phy_device *phydev, u8 entity, u8 state)
+{
+ int ret;
+
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, LED_ON_CTRL(entity));
+ if (ret < 0)
+ return ret;
+
+ if (state)
+ ret |= LED_ON_EN;
+ else
+ ret &= ~LED_ON_EN;
+
+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, LED_ON_CTRL(entity), ret);
+}
+
+static int an8801r_led_init(struct phy_device *phydev)
+{
+ struct an8801r_priv *priv = phydev_cfg(phydev);
+ struct air_led_cfg *led_cfg = priv->led_cfg;
+ u16 led_blink_cfg = priv->led_blink_cfg;
+ int ret, led_id;
+
+ ret = an8801r_led_set_blink(phydev, led_blink_cfg);
+ if (ret)
+ return ret;
+
+ ret = an8801r_led_set_mode(phydev, AIR_LED_MODE_USER_DEFINE);
+ if (ret) {
+ dev_err(phydev->dev, "AN8801R: Fail to set LED mode, ret %d!\n", ret);
+ return ret;
+ }
+
+ for (led_id = AIR_LED0; led_id < AN8801R_MAX_LED_SIZE; led_id++) {
+ ret = an8801r_led_set_state(phydev, led_id, led_cfg[led_id].led_en);
+ if (ret) {
+ dev_err(phydev->dev, "AN8801R: Fail to set LED%d state, ret %d!\n",
+ led_id, ret);
+ return ret;
+ }
+
+ if (!led_cfg[led_id].led_en)
+ continue;
+
+ ret = an8801_buckpbus_reg_set_bits(phydev, AN8801_BPBUS_REG_LED_GPIO,
+ BIT(led_cfg[led_id].gpio));
+ if (ret)
+ return ret;
+
+ ret = an8801_buckpbus_reg_set_bits(phydev, AN8801_BPBUS_REG_LED_ID_SEL,
+ LED_ID_GPIO_SEL(led_id,
+ led_cfg[led_id].gpio));
+ if (ret)
+ return ret;
+
+ ret = an8801_buckpbus_reg_clear_bits(phydev, AN8801_BPBUS_REG_GPIO_MODE,
+ BIT(led_cfg[led_id].gpio));
+ if (ret)
+ return ret;
+
+ ret = an8801r_led_set_usr_def(phydev, led_id,
+ led_cfg[led_id].led_polarity,
+ led_cfg[led_id].led_on_cfg,
+ led_cfg[led_id].led_blk_cfg);
+ if (ret) {
+ dev_err(phydev->dev, "AN8801R: Fail to set LED%d, ret %d!\n",
+ led_id, ret);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int an8801r_of_init(struct phy_device *phydev)
+{
+ struct an8801r_priv *priv = phydev_cfg(phydev);
+ ofnode node = phy_get_ofnode(phydev);
+ u32 val = 0;
+ int ret;
+
+ if (!ofnode_valid(node))
+ return -EINVAL;
+
+ if (ofnode_has_property(node, "airoha,rxclk-delay")) {
+ ret = ofnode_read_u32(node, "airoha,rxclk-delay", &val);
+ if (ret) {
+ dev_err(phydev->dev, "airoha,rxclk-delay value is invalid.\n");
+ return ret;
+ }
+ if (val > AIR_RGMII_DELAY_STEP_7) {
+ dev_err(phydev->dev, "airoha,rxclk-delay value %u out of range.\n", val);
+ return -EINVAL;
+ }
+ priv->rxdelay_force = true;
+ priv->rxdelay_step = val;
+ priv->rxdelay_align = ofnode_read_bool(node,
+ "airoha,rxclk-delay-align");
+ }
+
+ if (ofnode_has_property(node, "airoha,txclk-delay")) {
+ ret = ofnode_read_u32(node, "airoha,txclk-delay", &val);
+ if (ret) {
+ dev_err(phydev->dev, "airoha,txclk-delay value is invalid.\n");
+ return ret;
+ }
+ if (val > AIR_RGMII_DELAY_STEP_7) {
+ dev_err(phydev->dev, "airoha,txclk-delay value %u out of range.\n", val);
+ return -EINVAL;
+ }
+ priv->txdelay_force = true;
+ priv->txdelay_step = val;
+ }
+ return 0;
+}
+
+static int an8801r_rgmii_rxdelay(struct phy_device *phydev, u16 delay, u8 align)
+{
+ u32 reg_val = delay & RGMII_DELAY_STEP_MASK;
+ int ret;
+
+ if (align) {
+ reg_val |= RGMII_RXDELAY_ALIGN;
+ debug("AN8801R: Rxdelay align\n");
+ }
+ reg_val |= RGMII_RXDELAY_FORCE_MODE;
+ ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_RXDLY_STEP, reg_val);
+ if (ret)
+ return ret;
+
+ debug("AN8801R: Force rxdelay = %d(0x%x)\n", delay, reg_val);
+ return 0;
+}
+
+static int an8801r_rgmii_txdelay(struct phy_device *phydev, u16 delay)
+{
+ u32 reg_val = delay & RGMII_DELAY_STEP_MASK;
+ int ret;
+
+ reg_val |= RGMII_TXDELAY_FORCE_MODE;
+ ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_TXDLY_STEP, reg_val);
+ if (ret)
+ return ret;
+
+ debug("AN8801R: Force txdelay = %d(0x%x)\n", delay, reg_val);
+ return 0;
+}
+
+static int an8801r_rgmii_delay_config(struct phy_device *phydev)
+{
+ struct an8801r_priv *priv = phydev_cfg(phydev);
+ int ret;
+
+ switch (phydev->interface) {
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ return an8801r_rgmii_txdelay(phydev, AIR_RGMII_DELAY_STEP_4);
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ return an8801r_rgmii_rxdelay(phydev, AIR_RGMII_DELAY_NOSTEP, true);
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ ret = an8801r_rgmii_txdelay(phydev, AIR_RGMII_DELAY_STEP_4);
+ if (ret)
+ return ret;
+ return an8801r_rgmii_rxdelay(phydev, AIR_RGMII_DELAY_NOSTEP, true);
+ case PHY_INTERFACE_MODE_RGMII:
+ default:
+ if (priv->rxdelay_force) {
+ ret = an8801r_rgmii_rxdelay(phydev, priv->rxdelay_step,
+ priv->rxdelay_align);
+ if (ret)
+ return ret;
+ }
+ if (priv->txdelay_force)
+ return an8801r_rgmii_txdelay(phydev, priv->txdelay_step);
+ return 0;
+ }
+}
+
+static int an8801r_config_init(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = an8801r_of_init(phydev);
+ if (ret < 0)
+ return ret;
+
+ ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_HWRST_DE_GLITCH,
+ AN8801_DE_GLITCH_EN |
+ AN8801_11_CYCLE_XTAL_PERIOD_DE_GLITCH);
+ if (ret)
+ return ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AN8801_REG_PHY_INTERNAL0, 0x1e);
+ if (ret)
+ return ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AN8801_REG_PHY_INTERNAL1, 0x02);
+ if (ret)
+ return ret;
+
+ ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
+ if (ret)
+ return ret;
+
+ ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_BYPASS_PTP,
+ AN8801_BYP_PTP_RGMII_TO_GPHY);
+ if (ret)
+ return ret;
+
+ ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_EFIFO_CTL(0),
+ AN8801_EFIFO_RX_EN |
+ AN8801_EFIFO_TX_EN |
+ AN8801_EFIFO_RX_CLK_EN |
+ AN8801_EFIFO_TX_CLK_EN |
+ AN8801_EFIFO_RX_EEE_EN |
+ AN8801_EFIFO_TX_EEE_EN);
+ if (ret)
+ return ret;
+
+ ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_EFIFO_CTL(1),
+ AN8801_EFIFO_ALL_EN);
+ if (ret)
+ return ret;
+
+ ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_EFIFO_CTL(2),
+ AN8801_EFIFO_ALL_EN);
+ if (ret)
+ return ret;
+
+ ret = an8801r_rgmii_delay_config(phydev);
+ if (ret)
+ return ret;
+
+ ret = an8801r_led_init(phydev);
+ if (ret) {
+ dev_err(phydev->dev, "AN8801R: LED initialize fail, ret %d!\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int an8801r_phy_probe(struct phy_device *phydev)
+{
+ struct an8801r_priv *priv;
+ u32 phy_id;
+ int ret;
+
+ ret = get_phy_id(phydev->bus, phydev->addr, MDIO_DEVAD_NONE, &phy_id);
+ if (ret)
+ return ret;
+
+ if (phy_id != AN8801R_PHY_ID) {
+ dev_err(phydev->dev,
+ "AN8801R can't be detected (id=0x%08x).\n", phy_id);
+ return -ENODEV;
+ }
+
+ priv = malloc(sizeof(*priv));
+ if (!priv)
+ return -ENOMEM;
+
+ *priv = an8801r_priv_defaults;
+
+ phydev->priv = priv;
+
+ return 0;
+}
+
+static int an8801r_read_status(struct phy_device *phydev)
+{
+ u32 data;
+
+ if (!phydev->link)
+ return 0;
+
+ debug("AN8801R: SPEED %d\n", phydev->speed);
+ data = phydev->speed == SPEED_1000 ? AN8801_BPBUS_LINK_MODE_1000 : 0;
+
+ return an8801_buckpbus_reg_rmw(phydev, AN8801_BPBUS_REG_LINK_MODE,
+ AN8801_BPBUS_LINK_MODE_1000, data);
+}
+
+static int an8801r_startup(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = genphy_startup(phydev);
+ if (ret)
+ return ret;
+
+ return an8801r_read_status(phydev);
+}
+
+U_BOOT_PHY_DRIVER(an8801r) = {
+ .name = "Airoha AN8801R",
+ .uid = AN8801R_PHY_ID,
+ .mask = 0x0ffffff0,
+ .features = PHY_GBIT_FEATURES,
+ .probe = &an8801r_phy_probe,
+ .config = &an8801r_config_init,
+ .read_page = &air_phy_read_page,
+ .write_page = &air_phy_write_page,
+ .startup = &an8801r_startup,
+ .shutdown = &genphy_shutdown,
+};
diff --git a/drivers/net/phy/airoha/air_en8811.c b/drivers/net/phy/airoha/air_en8811.c
index 32f06dd6dfa..7a07be2e956 100644
--- a/drivers/net/phy/airoha/air_en8811.c
+++ b/drivers/net/phy/airoha/air_en8811.c
@@ -25,6 +25,8 @@
#include <u-boot/crc.h>
#include <linux/phy/phy-common-props.h>
+#include "air_phy_lib.h"
+
/* MII Registers */
#define AIR_AUX_CTRL_STATUS 0x1d
#define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2)
@@ -33,10 +35,6 @@
#define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8
#define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc
-#define AIR_EXT_PAGE_ACCESS 0x1f
-#define AIR_PHY_PAGE_STANDARD 0x0000
-#define AIR_PHY_PAGE_EXTENDED_4 0x0004
-
#define AIR_PBUS_MODE_ADDR_HIGH 0x1c
/* MII Registers Page 4 */
#define AIR_BPBUS_MODE 0x10
@@ -310,166 +308,6 @@ static int air_pbus_reg_write(struct phy_device *phydev,
return ret;
}
-static int air_buckpbus_reg_write(struct phy_device *phydev,
- u32 pbus_address, u32 pbus_data)
-{
- int ret, saved_page;
-
- saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
- if (saved_page < 0)
- return saved_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
- AIR_BPBUS_MODE_ADDR_FIXED);
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
- upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
- lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
- upper_16_bits(pbus_data));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
- lower_16_bits(pbus_data));
- if (ret < 0)
- goto restore_page;
-
-restore_page:
- if (ret < 0)
- dev_err(phydev->dev, "%s 0x%08x failed: %d\n", __func__,
- pbus_address, ret);
-
- return phy_restore_page(phydev, saved_page, ret);
-}
-
-static int air_buckpbus_reg_read(struct phy_device *phydev,
- u32 pbus_address, u32 *pbus_data)
-{
- int pbus_data_low, pbus_data_high;
- int ret = 0, saved_page;
-
- saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
- if (saved_page < 0)
- return saved_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
- AIR_BPBUS_MODE_ADDR_FIXED);
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
- upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
- lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);
- if (pbus_data_high < 0) {
- ret = pbus_data_high;
- goto restore_page;
- }
-
- pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);
- if (pbus_data_low < 0) {
- ret = pbus_data_low;
- goto restore_page;
- }
-
- *pbus_data = pbus_data_low | (pbus_data_high << 16);
-
-restore_page:
- if (ret < 0)
- dev_err(phydev->dev, "%s 0x%08x failed: %d\n", __func__,
- pbus_address, ret);
-
- return phy_restore_page(phydev, saved_page, ret);
-}
-
-static int air_buckpbus_reg_modify(struct phy_device *phydev,
- u32 pbus_address, u32 mask, u32 set)
-{
- int pbus_data_low, pbus_data_high;
- u32 pbus_data_old, pbus_data_new;
- int ret = 0, saved_page;
-
- saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
- if (saved_page < 0)
- return saved_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
- AIR_BPBUS_MODE_ADDR_FIXED);
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
- upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
- lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH);
- if (pbus_data_high < 0) {
- ret = pbus_data_high;
- goto restore_page;
- }
-
- pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW);
- if (pbus_data_low < 0) {
- ret = pbus_data_low;
- goto restore_page;
- }
-
- pbus_data_old = pbus_data_low | (pbus_data_high << 16);
- pbus_data_new = (pbus_data_old & ~mask) | set;
- if (pbus_data_new == pbus_data_old)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
- upper_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
- lower_16_bits(pbus_address));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
- upper_16_bits(pbus_data_new));
- if (ret < 0)
- goto restore_page;
-
- ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
- lower_16_bits(pbus_data_new));
- if (ret < 0)
- goto restore_page;
-
-restore_page:
- if (ret < 0)
- dev_err(phydev->dev, "%s 0x%08x failed: %d\n", __func__,
- pbus_address, ret);
-
- return phy_restore_page(phydev, saved_page, ret);
-}
-
static int air_write_buf(struct phy_device *phydev, unsigned long address,
unsigned long array_size, const unsigned char *buffer)
{
@@ -540,12 +378,12 @@ static int an8811hb_check_crc(struct phy_device *phydev,
u32 pbus_value;
/* Configure CRC */
- ret = air_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN,
- AN8811HB_CRC_RD_EN);
+ ret = air_phy_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN,
+ AN8811HB_CRC_RD_EN);
if (ret < 0)
return ret;
- ret = air_buckpbus_reg_read(phydev, set1, &pbus_value);
+ ret = air_phy_buckpbus_reg_read(phydev, set1, &pbus_value);
if (ret < 0)
return ret;
@@ -554,14 +392,14 @@ static int an8811hb_check_crc(struct phy_device *phydev,
do {
mdelay(300);
- ret = air_buckpbus_reg_read(phydev, mon2, &pbus_value);
+ ret = air_phy_buckpbus_reg_read(phydev, mon2, &pbus_value);
if (ret < 0)
return ret;
debug("%d: reg 0x%x val 0x%x!\n", __LINE__, mon2, pbus_value);
if (pbus_value & AN8811HB_CRC_ST) {
- ret = air_buckpbus_reg_read(phydev, mon3, &pbus_value);
+ ret = air_phy_buckpbus_reg_read(phydev, mon3, &pbus_value);
if (ret < 0)
return ret;
@@ -585,11 +423,11 @@ static int an8811hb_check_crc(struct phy_device *phydev,
}
} while (--retry);
- ret = air_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN, 0);
+ ret = air_phy_buckpbus_reg_modify(phydev, set1, AN8811HB_CRC_RD_EN, 0);
if (ret < 0)
return ret;
- ret = air_buckpbus_reg_read(phydev, set1, &pbus_value);
+ ret = air_phy_buckpbus_reg_read(phydev, set1, &pbus_value);
if (ret < 0)
return ret;
@@ -647,9 +485,9 @@ static int an8811hb_surge_protect_cfg(struct phy_device *phydev)
return ret;
}
- ret = air_buckpbus_reg_modify(phydev, AIR_PHY_CONTROL,
- AIR_PHY_CONTROL_SURGE_5R,
- AIR_PHY_CONTROL_SURGE_5R);
+ ret = air_phy_buckpbus_reg_modify(phydev, AIR_PHY_CONTROL,
+ AIR_PHY_CONTROL_SURGE_5R,
+ AIR_PHY_CONTROL_SURGE_5R);
if (ret < 0)
return ret;
@@ -707,14 +545,14 @@ static int en8811h_load_firmware(struct phy_device *phydev)
goto en8811h_load_firmware_out;
}
- ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_START);
+ ret = air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
+ EN8811H_FW_CTRL_1_START);
if (ret < 0)
goto en8811h_load_firmware_out;
- ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
- EN8811H_FW_CTRL_2_LOADING,
- EN8811H_FW_CTRL_2_LOADING);
+ ret = air_phy_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
+ EN8811H_FW_CTRL_2_LOADING,
+ EN8811H_FW_CTRL_2_LOADING);
if (ret < 0)
goto en8811h_load_firmware_out;
@@ -728,13 +566,13 @@ static int en8811h_load_firmware(struct phy_device *phydev)
if (ret < 0)
goto en8811h_load_firmware_out;
- ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
- EN8811H_FW_CTRL_2_LOADING, 0);
+ ret = air_phy_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2,
+ EN8811H_FW_CTRL_2_LOADING, 0);
if (ret < 0)
goto en8811h_load_firmware_out;
- ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_FINISH);
+ ret = air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
+ EN8811H_FW_CTRL_1_FINISH);
if (ret < 0)
goto en8811h_load_firmware_out;
@@ -742,8 +580,8 @@ static int en8811h_load_firmware(struct phy_device *phydev)
if (ret < 0)
goto en8811h_load_firmware_out;
- air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,
- &priv->firmware_version);
+ air_phy_buckpbus_reg_read(phydev, EN8811H_FW_VERSION,
+ &priv->firmware_version);
dev_info(phydev->dev, "MD32 firmware version: %08x\n",
priv->firmware_version);
@@ -779,8 +617,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)
if (ret < 0)
goto an8811hb_load_firmware_out;
- ret = air_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,
- AIR_PHY_FW_CTRL_1_START);
+ ret = air_phy_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,
+ AIR_PHY_FW_CTRL_1_START);
if (ret < 0)
goto an8811hb_load_firmware_out;
@@ -804,8 +642,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)
if (ret < 0)
goto an8811hb_load_firmware_out;
- ret = air_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,
- AIR_PHY_FW_CTRL_1_FINISH);
+ ret = air_phy_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,
+ AIR_PHY_FW_CTRL_1_FINISH);
if (ret < 0)
goto an8811hb_load_firmware_out;
@@ -818,7 +656,7 @@ static int an8811hb_load_firmware(struct phy_device *phydev)
do {
mdelay(300);
- ret = air_buckpbus_reg_read(phydev, AIR_PHY_FW_CTRL_1, &reg_val);
+ ret = air_phy_buckpbus_reg_read(phydev, AIR_PHY_FW_CTRL_1, &reg_val);
if (ret < 0)
goto an8811hb_load_firmware_out;
@@ -828,8 +666,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)
debug("%d: reg 0x%x val 0x%x!\n", __LINE__, AIR_PHY_FW_CTRL_1,
reg_val);
- ret = air_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,
- AIR_PHY_FW_CTRL_1_FINISH);
+ ret = air_phy_buckpbus_reg_write(phydev, AIR_PHY_FW_CTRL_1,
+ AIR_PHY_FW_CTRL_1_FINISH);
if (ret < 0)
goto an8811hb_load_firmware_out;
@@ -839,8 +677,8 @@ static int an8811hb_load_firmware(struct phy_device *phydev)
if (ret < 0)
goto an8811hb_load_firmware_out;
- air_buckpbus_reg_read(phydev, AIR_PHY_MD32FW_VERSION,
- &priv->firmware_version);
+ air_phy_buckpbus_reg_read(phydev, AIR_PHY_MD32FW_VERSION,
+ &priv->firmware_version);
debug("MD32 firmware version: %08x\n", priv->firmware_version);
@@ -859,17 +697,17 @@ int an8811hb_cko_cfg(struct phy_device *phydev)
int ret = 0;
if (!ofnode_read_bool(node, "airoha,phy-output-clock")) {
- ret = air_buckpbus_reg_modify(phydev, AN8811HB_CLK_DRV,
- AN8811HB_CLK_DRV_CKO_MASK,
- AN8811HB_CLK_DRV_CKOPWD |
- AN8811HB_CLK_DRV_CKO_LDPWD |
- AN8811HB_CLK_DRV_CKO_LPPWD);
+ ret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_CLK_DRV,
+ AN8811HB_CLK_DRV_CKO_MASK,
+ AN8811HB_CLK_DRV_CKOPWD |
+ AN8811HB_CLK_DRV_CKO_LDPWD |
+ AN8811HB_CLK_DRV_CKO_LPPWD);
if (ret < 0)
return ret;
debug("CKO Output mode - Disabled\n");
} else {
- ret = air_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);
+ ret = air_phy_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);
if (ret < 0)
return ret;
@@ -888,13 +726,13 @@ static int en8811h_restart_mcu(struct phy_device *phydev)
if (ret < 0)
return ret;
- ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_START);
+ ret = air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
+ EN8811H_FW_CTRL_1_START);
if (ret < 0)
return ret;
- return air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
- EN8811H_FW_CTRL_1_FINISH);
+ return air_phy_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
+ EN8811H_FW_CTRL_1_FINISH);
}
static int air_led_hw_control_set(struct phy_device *phydev, u8 index,
@@ -1083,9 +921,10 @@ static int en8811h_config_serdes_polarity(struct phy_device *phydev)
if (pol == PHY_POL_NORMAL)
pbus_value |= EN8811H_POLARITY_TX_NORMAL;
- return air_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
- EN8811H_POLARITY_RX_REVERSE |
- EN8811H_POLARITY_TX_NORMAL, pbus_value);
+ return air_phy_buckpbus_reg_modify(phydev, EN8811H_POLARITY,
+ EN8811H_POLARITY_RX_REVERSE |
+ EN8811H_POLARITY_TX_NORMAL,
+ pbus_value);
}
static int en8811h_config(struct phy_device *phydev)
@@ -1170,12 +1009,12 @@ static int an8811hb_config(struct phy_device *phydev)
priv->mcu_needs_restart = true;
}
- ret = air_buckpbus_reg_read(phydev, AN8811HB_PRO_ID, &pbus_value);
+ ret = air_phy_buckpbus_reg_read(phydev, AN8811HB_PRO_ID, &pbus_value);
if (ret < 0)
return ret;
priv->pro_id = (pbus_value & AN8811HB_PRO_ID_VERSION) + 1;
- ret = air_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);
+ ret = air_phy_buckpbus_reg_read(phydev, AN8811HB_HWTRAP2, &pbus_value);
if (ret < 0)
return ret;
priv->pkg_sel = (pbus_value & AN8811HB_HWTRAP2_PKG) >> 12;
@@ -1191,8 +1030,8 @@ static int an8811hb_config(struct phy_device *phydev)
pbus_value |= AN8811HB_RX_POLARITY_NORMAL;
debug("1 pbus_value 0x%x\n", pbus_value);
- ret = air_buckpbus_reg_modify(phydev, AN8811HB_RX_POLARITY,
- AN8811HB_RX_POLARITY_NORMAL, pbus_value);
+ ret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_RX_POLARITY,
+ AN8811HB_RX_POLARITY_NORMAL, pbus_value);
if (ret < 0)
return ret;
@@ -1203,35 +1042,35 @@ static int an8811hb_config(struct phy_device *phydev)
pbus_value |= AN8811HB_TX_POLARITY_NORMAL;
debug("2 pbus_value 0x%x\n", pbus_value);
- ret = air_buckpbus_reg_modify(phydev, AN8811HB_TX_POLARITY,
- AN8811HB_TX_POLARITY_NORMAL, pbus_value);
+ ret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_TX_POLARITY,
+ AN8811HB_TX_POLARITY_NORMAL, pbus_value);
if (ret < 0)
return ret;
/* Configure led gpio pins as output */
if (priv->pkg_sel) {
- ret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,
- AN8811HB_GPIO_OUTPUT_MASK,
- AN8811HB_GPIO_OUTPUT_0115);
+ ret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,
+ AN8811HB_GPIO_OUTPUT_MASK,
+ AN8811HB_GPIO_OUTPUT_0115);
if (ret < 0)
return ret;
- ret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_1,
- AN8811HB_GPIO_SEL_1_0_MASK |
- AN8811HB_GPIO_SEL_1_1_MASK,
- AN8811HB_GPIO_SEL_1_0 |
- AN8811HB_GPIO_SEL_1_1);
+ ret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_1,
+ AN8811HB_GPIO_SEL_1_0_MASK |
+ AN8811HB_GPIO_SEL_1_1_MASK,
+ AN8811HB_GPIO_SEL_1_0 |
+ AN8811HB_GPIO_SEL_1_1);
if (ret < 0)
return ret;
- ret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_2,
- AN8811HB_GPIO_SEL_2_15_MASK,
- AN8811HB_GPIO_SEL_2_15);
+ ret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_SEL_2,
+ AN8811HB_GPIO_SEL_2_15_MASK,
+ AN8811HB_GPIO_SEL_2_15);
if (ret < 0)
return ret;
} else {
- ret = air_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,
- AN8811HB_GPIO_OUTPUT_345,
- AN8811HB_GPIO_OUTPUT_345);
+ ret = air_phy_buckpbus_reg_modify(phydev, AN8811HB_GPIO_OUTPUT,
+ AN8811HB_GPIO_OUTPUT_345,
+ AN8811HB_GPIO_OUTPUT_345);
if (ret < 0)
return ret;
}
@@ -1401,16 +1240,6 @@ static int en8811h_probe(struct phy_device *phydev)
return 0;
}
-static int air_phy_read_page(struct phy_device *phydev)
-{
- return phy_read(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS);
-}
-
-static int air_phy_write_page(struct phy_device *phydev, int page)
-{
- return phy_write(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS, page);
-}
-
U_BOOT_PHY_DRIVER(en8811h) = {
.name = "Airoha EN8811H",
.uid = EN8811H_PHY_ID,
diff --git a/drivers/net/phy/airoha/air_phy_lib.c b/drivers/net/phy/airoha/air_phy_lib.c
new file mode 100644
index 00000000000..61c3bf82822
--- /dev/null
+++ b/drivers/net/phy/airoha/air_phy_lib.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Airoha Ethernet PHY common library
+ *
+ * Copyright (C) 2026 Airoha Technology Corp.
+ * Copyright (C) 2026 Collabora Ltd.
+ * Louis-Alexis Eyraud <[email protected]>
+ *
+ * Adapated from https://lore.kernel.org/all/20260326-add-airoha-an8801-support-v2-2-1a42d6b6050f@collabora.com/
+ */
+
+#include <dm/device_compat.h>
+#include <linux/compat.h>
+#include <phy.h>
+
+#include "air_phy_lib.h"
+
+#define AIR_EXT_PAGE_ACCESS 0x1f
+
+static int __air_buckpbus_reg_read(struct phy_device *phydev,
+ u32 pbus_address, u32 *pbus_data)
+{
+ int pbus_data_low, pbus_data_high;
+ int ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
+ AIR_BPBUS_MODE_ADDR_FIXED);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
+ upper_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
+ lower_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE,
+ AIR_BPBUS_RD_DATA_HIGH);
+ if (pbus_data_high < 0)
+ return pbus_data_high;
+
+ pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE,
+ AIR_BPBUS_RD_DATA_LOW);
+ if (pbus_data_low < 0)
+ return pbus_data_low;
+
+ *pbus_data = pbus_data_low | (pbus_data_high << 16);
+ return 0;
+}
+
+static int __air_buckpbus_reg_write(struct phy_device *phydev,
+ u32 pbus_address, u32 pbus_data)
+{
+ int ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
+ AIR_BPBUS_MODE_ADDR_FIXED);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
+ upper_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
+ lower_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
+ upper_16_bits(pbus_data));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
+ lower_16_bits(pbus_data));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int __air_buckpbus_reg_modify(struct phy_device *phydev,
+ u32 pbus_address, u32 mask, u32 set)
+{
+ int pbus_data_low, pbus_data_high;
+ u32 pbus_data_old, pbus_data_new;
+ int ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE,
+ AIR_BPBUS_MODE_ADDR_FIXED);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH,
+ upper_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW,
+ lower_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE,
+ AIR_BPBUS_RD_DATA_HIGH);
+ if (pbus_data_high < 0)
+ return pbus_data_high;
+
+ pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE,
+ AIR_BPBUS_RD_DATA_LOW);
+ if (pbus_data_low < 0)
+ return pbus_data_low;
+
+ pbus_data_old = pbus_data_low | (pbus_data_high << 16);
+ pbus_data_new = (pbus_data_old & ~mask) | set;
+ if (pbus_data_new == pbus_data_old)
+ return 0;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH,
+ upper_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW,
+ lower_16_bits(pbus_address));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH,
+ upper_16_bits(pbus_data_new));
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW,
+ lower_16_bits(pbus_data_new));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int air_phy_buckpbus_reg_read(struct phy_device *phydev, u32 pbus_address,
+ u32 *pbus_data)
+{
+ int saved_page;
+ int ret = 0;
+
+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
+
+ if (saved_page >= 0) {
+ ret = __air_buckpbus_reg_read(phydev, pbus_address, pbus_data);
+ if (ret < 0)
+ dev_err(phydev->dev, "%s 0x%08x failed: %d\n", __func__,
+ pbus_address, ret);
+ }
+
+ return phy_restore_page(phydev, saved_page, ret);
+}
+
+int air_phy_buckpbus_reg_write(struct phy_device *phydev, u32 pbus_address,
+ u32 pbus_data)
+{
+ int saved_page;
+ int ret = 0;
+
+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
+
+ if (saved_page >= 0) {
+ ret = __air_buckpbus_reg_write(phydev, pbus_address,
+ pbus_data);
+ if (ret < 0)
+ dev_err(phydev->dev, "%s 0x%08x failed: %d\n", __func__,
+ pbus_address, ret);
+ }
+
+ return phy_restore_page(phydev, saved_page, ret);
+}
+
+int air_phy_buckpbus_reg_modify(struct phy_device *phydev, u32 pbus_address,
+ u32 mask, u32 set)
+{
+ int saved_page;
+ int ret = 0;
+
+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
+
+ if (saved_page >= 0) {
+ ret = __air_buckpbus_reg_modify(phydev, pbus_address, mask,
+ set);
+ if (ret < 0)
+ dev_err(phydev->dev, "%s 0x%08x failed: %d\n", __func__,
+ pbus_address, ret);
+ }
+
+ return phy_restore_page(phydev, saved_page, ret);
+}
+
+int air_phy_read_page(struct phy_device *phydev)
+{
+ return phy_read(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS);
+}
+
+int air_phy_write_page(struct phy_device *phydev, int page)
+{
+ return phy_write(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS, page);
+}
+
+MODULE_DESCRIPTION("Airoha PHY Library");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Louis-Alexis Eyraud");
diff --git a/drivers/net/phy/airoha/air_phy_lib.h b/drivers/net/phy/airoha/air_phy_lib.h
new file mode 100644
index 00000000000..845d2f7cfb4
--- /dev/null
+++ b/drivers/net/phy/airoha/air_phy_lib.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2026 Airoha Technology Corp.
+ * Copyright (C) 2026 Collabora Ltd.
+ * Louis-Alexis Eyraud <[email protected]>
+ */
+
+#ifndef __AIR_PHY_LIB_H
+#define __AIR_PHY_LIB_H
+
+#define AIR_EXT_PAGE_ACCESS 0x1f
+
+#define AIR_PHY_PAGE_STANDARD 0x0000
+#define AIR_PHY_PAGE_EXTENDED_1 0x0001
+#define AIR_PHY_PAGE_EXTENDED_4 0x0004
+
+/* MII Registers Page 4*/
+#define AIR_BPBUS_MODE 0x10
+#define AIR_BPBUS_MODE_ADDR_FIXED 0x0000
+#define AIR_BPBUS_MODE_ADDR_INCR BIT(15)
+#define AIR_BPBUS_WR_ADDR_HIGH 0x11
+#define AIR_BPBUS_WR_ADDR_LOW 0x12
+#define AIR_BPBUS_WR_DATA_HIGH 0x13
+#define AIR_BPBUS_WR_DATA_LOW 0x14
+#define AIR_BPBUS_RD_ADDR_HIGH 0x15
+#define AIR_BPBUS_RD_ADDR_LOW 0x16
+#define AIR_BPBUS_RD_DATA_HIGH 0x17
+#define AIR_BPBUS_RD_DATA_LOW 0x18
+
+int air_phy_buckpbus_reg_modify(struct phy_device *phydev, u32 pbus_address,
+ u32 mask, u32 set);
+int air_phy_buckpbus_reg_read(struct phy_device *phydev, u32 pbus_address,
+ u32 *pbus_data);
+int air_phy_buckpbus_reg_write(struct phy_device *phydev, u32 pbus_address,
+ u32 pbus_data);
+int air_phy_read_page(struct phy_device *phydev);
+int air_phy_write_page(struct phy_device *phydev, int page);
+
+#endif /* __AIR_PHY_LIB_H */
diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index a1e4c3d053b..9814ac498ed 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -343,7 +343,7 @@ static int nxp_c45_probe(struct phy_device *phydev)
{
struct nxp_c45_phy *priv;
- priv = devm_kzalloc(phydev->priv, sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
diff --git a/drivers/net/qe/dm_qe_uec.c b/drivers/net/qe/dm_qe_uec.c
index ac3aedd8b49..f9bc5d49c8f 100644
--- a/drivers/net/qe/dm_qe_uec.c
+++ b/drivers/net/qe/dm_qe_uec.c
@@ -1133,7 +1133,7 @@ static int qe_uec_of_to_plat(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
- pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
+ pdata->iobase = (phys_addr_t)dev_read_addr(dev);
pdata->phy_interface = dev_read_phy_mode(dev);
if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index 5b093623619..e203faed26b 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -404,7 +404,7 @@ static int rtl8169_init_board(unsigned long dev_iobase, const char *name)
u32 tmp;
#ifdef DEBUG_RTL8169
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
ioaddr = dev_iobase;
@@ -534,7 +534,7 @@ static int rtl_recv_common(struct udevice *dev, unsigned long dev_iobase,
int length = 0;
#ifdef DEBUG_RTL8169_RX
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
ioaddr = dev_iobase;
@@ -608,7 +608,7 @@ static int rtl_send_common(struct udevice *dev, unsigned long dev_iobase,
#ifdef DEBUG_RTL8169_TX
int stime = currticks();
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
printf("sending %d bytes\n", len);
#endif
@@ -679,7 +679,7 @@ static void rtl8169_set_rx_mode(void)
u32 tmp = 0;
#ifdef DEBUG_RTL8169
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
/* IFF_ALLMULTI */
@@ -701,7 +701,7 @@ static void rtl8169_hw_start(struct udevice *dev)
#ifdef DEBUG_RTL8169
int stime = currticks();
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
#if 0
@@ -771,7 +771,7 @@ static void rtl8169_init_ring(struct udevice *dev)
#ifdef DEBUG_RTL8169
int stime = currticks();
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
tpc->cur_rx = 0;
@@ -810,7 +810,7 @@ static void rtl8169_common_start(struct udevice *dev, unsigned char *enetaddr,
#ifdef DEBUG_RTL8169
int stime = currticks();
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
ioaddr = dev_iobase;
@@ -851,7 +851,7 @@ static void rtl_halt_common(struct udevice *dev)
int i;
#ifdef DEBUG_RTL8169
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
ioaddr = priv->iobase;
@@ -906,7 +906,7 @@ static int rtl_init(unsigned long dev_ioaddr, const char *name,
int option = -1, Cap10_100 = 0, Cap1000 = 0;
#ifdef DEBUG_RTL8169
- printf ("%s\n", __FUNCTION__);
+ printf("%s\n", __func__);
#endif
ioaddr = dev_ioaddr;
diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
index 93c3a0c35f2..2d72af8aade 100644
--- a/drivers/net/ti/Kconfig
+++ b/drivers/net/ti/Kconfig
@@ -14,7 +14,7 @@ config DRIVER_TI_EMAC
bool "TI Davinci EMAC"
depends on ARCH_DAVINCI || ARCH_OMAP2PLUS
help
- Support for davinci emac
+ Support for davinci emac
config DRIVER_TI_EMAC_USE_RMII
depends on DRIVER_TI_EMAC
@@ -26,7 +26,7 @@ config DRIVER_TI_KEYSTONE_NET
bool "TI Keystone 2 Ethernet"
depends on ARCH_KEYSTONE
help
- This driver supports the TI Keystone 2 Ethernet subsystem
+ This driver supports the TI Keystone 2 Ethernet subsystem
choice
prompt "TI Keystone 2 Ethernet NETCP IP revision"
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 12a162b9d68..4796d0d67cd 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -496,14 +496,15 @@ static int prueth_port_probe(struct udevice *dev)
{
struct prueth_priv *priv = dev_get_priv(dev);
struct prueth *prueth;
- char portname[15];
+ char portname[64];
int ret;
priv->dev = dev;
prueth = dev_get_priv(dev->parent);
priv->prueth = prueth;
- sprintf(portname, "%s-%s", dev->parent->name, dev->name);
+ snprintf(portname, sizeof(portname), "%s-%s", dev->parent->name, dev->name);
+ portname[sizeof(portname) - 1] = '\0';
device_set_name(dev, portname);
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index bd4ebdd745a..d03368b9408 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -37,6 +37,23 @@
)
#endif /* CFG_TSEC_TBICR_SETTINGS */
+struct tsec_private {
+ struct txbd8 __iomem txbd[TX_BUF_CNT];
+ struct rxbd8 __iomem rxbd[PKTBUFSRX];
+ struct tsec __iomem *regs;
+ struct tsec_mii_mng __iomem *phyregs_sgmii;
+ struct phy_device *phydev;
+ phy_interface_t interface;
+ struct mii_dev *bus;
+ uint phyaddr;
+ uint tbiaddr;
+ char mii_devname[16];
+ u32 flags;
+ uint rx_idx; /* index of the current RX buffer */
+ uint tx_idx; /* index of the current TX buffer */
+ struct udevice *dev;
+};
+
/* Configure the TBI for SGMII operation */
static void tsec_configure_serdes(struct tsec_private *priv)
{
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 0631b190b97..147a104149e 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -27,6 +27,23 @@
#define IO_TIMEOUT 30
#define MAX_PRP_POOL 512
+/**
+ * nvme_invalidate_cache_aligned() - invalidate cache with proper alignment
+ *
+ * Aligns cache invalidation to cacheline boundaries to ensure correct
+ * behavior even when the DMA buffer is not aligned to page boundaries.
+ *
+ * @addr: The start address of the buffer
+ * @length: The length of the buffer in bytes
+ */
+static inline void nvme_invalidate_cache_aligned(uintptr_t addr, int length)
+{
+ uintptr_t start_addr = addr & ~(ARCH_DMA_MINALIGN - 1);
+ uintptr_t end_addr = ALIGN(addr + length, ARCH_DMA_MINALIGN);
+
+ invalidate_dcache_range(start_addr, end_addr);
+}
+
static int nvme_wait_csts(struct nvme_dev *dev, u32 mask, u32 val)
{
int timeout;
@@ -182,8 +199,10 @@ static int nvme_submit_sync_cmd(struct nvme_queue *nvmeq,
if ((status & 0x01) == phase)
break;
if (timeout_us > 0 && (timer_get_us() - start_time)
- >= timeout_us)
+ >= timeout_us) {
+ pr_warn("nvme: cmd %#x timed out\n", cmd->common.command_id);
return -ETIMEDOUT;
+ }
}
ops = (struct nvme_ops *)nvmeq->dev->udev->driver->ops;
@@ -281,11 +300,6 @@ static int nvme_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
return nvme_submit_admin_cmd(dev, &c, NULL);
}
-static int nvme_delete_sq(struct nvme_dev *dev, u16 sqid)
-{
- return nvme_delete_queue(dev, nvme_admin_delete_sq, sqid);
-}
-
static int nvme_delete_cq(struct nvme_dev *dev, u16 cqid)
{
return nvme_delete_queue(dev, nvme_admin_delete_cq, cqid);
@@ -456,6 +470,7 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
u32 page_size = dev->page_size;
int offset = dma_addr & (page_size - 1);
int length = sizeof(struct nvme_id_ctrl);
+ dma_addr_t orig_dma_addr = dma_addr;
int ret;
memset(&c, 0, sizeof(c));
@@ -473,13 +488,13 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
c.identify.cns = cpu_to_le32(cns);
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ nvme_invalidate_cache_aligned((uintptr_t)orig_dma_addr,
+ sizeof(struct nvme_id_ctrl));
ret = nvme_submit_admin_cmd(dev, &c, NULL);
if (!ret)
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ nvme_invalidate_cache_aligned((uintptr_t)orig_dma_addr,
+ sizeof(struct nvme_id_ctrl));
return ret;
}
@@ -545,20 +560,19 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
nvmeq->cq_vector = qid - 1;
result = nvme_alloc_cq(dev, qid, nvmeq);
if (result < 0)
- goto release_cq;
+ goto release_ret;
result = nvme_alloc_sq(dev, qid, nvmeq);
if (result < 0)
- goto release_sq;
+ goto release_cq;
nvme_init_queue(nvmeq, qid);
return result;
- release_sq:
- nvme_delete_sq(dev, qid);
release_cq:
nvme_delete_cq(dev, qid);
+ release_ret:
return result;
}
@@ -868,14 +882,14 @@ int nvme_init(struct udevice *udev)
if (!ndev->prp_pool) {
ret = -ENOMEM;
printf("Error: %s: Out of memory!\n", udev->name);
- goto free_nvme;
+ goto free_queue;
}
ndev->prp_entry_num = MAX_PRP_POOL >> 3;
ret = nvme_setup_io_queues(ndev);
if (ret) {
log_debug("Unable to setup I/O queues(err=%dE)\n", ret);
- goto free_queue;
+ goto free_prp_pool;
}
nvme_get_info_from_identify(ndev);
@@ -885,7 +899,7 @@ int nvme_init(struct udevice *udev)
id = memalign(ndev->page_size, sizeof(struct nvme_id_ns));
if (!id) {
ret = -ENOMEM;
- goto free_queue;
+ goto free_prp_pool;
}
for (int i = 1; i <= ndev->nn; i++) {
@@ -930,6 +944,8 @@ int nvme_init(struct udevice *udev)
free_id:
free(id);
+free_prp_pool:
+ free((void *)ndev->prp_pool);
free_queue:
free((void *)ndev->queues);
free_nvme:
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 39df0e776df..9ffccc3a80b 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -101,11 +101,11 @@ config PCI_ENHANCED_ALLOCATION
devices in place of traditional BARS for allocation of resources.
config PCI_ARID
- bool "Enable Alternate Routing-ID support for PCI"
- help
- Say Y here if you want to enable Alternate Routing-ID capability
- support on PCI devices. This helps to skip some devices in BDF
- scan that are not present.
+ bool "Enable Alternate Routing-ID support for PCI"
+ help
+ Say Y here if you want to enable Alternate Routing-ID capability
+ support on PCI devices. This helps to skip some devices in BDF
+ scan that are not present.
config PCI_SCAN_SHOW
bool "Show PCI devices during startup"
@@ -287,7 +287,7 @@ config PCI_IOMMU_EXTRA_MAPPINGS
the node describing the PCI controller.
The intent is to cover SR-IOV scenarios which need mappings for VFs
and PCI hot-plug scenarios. More documentation can be found under:
- arch/arm/cpu/armv8/fsl-layerscape/doc/README.pci_iommu_extra
+ arch/arm/cpu/armv8/fsl-layerscape/doc/README.pci_iommu_extra
config PCIE_LAYERSCAPE_EP
bool "Layerscape PCIe Endpoint mode support"
@@ -440,8 +440,8 @@ config PCIE_XILINX_NWL
bool "Xilinx NWL PCIe controller"
depends on ARCH_ZYNQMP
help
- Say 'Y' here if you want support for Xilinx / AMD NWL PCIe
- controller as Root Port.
+ Say 'Y' here if you want support for Xilinx / AMD NWL PCIe
+ controller as Root Port.
config PCIE_PLDA_COMMON
bool
diff --git a/drivers/pci/pci-rcar-gen2.c b/drivers/pci/pci-rcar-gen2.c
index 08d5c4fbb8b..53cb0916741 100644
--- a/drivers/pci/pci-rcar-gen2.c
+++ b/drivers/pci/pci-rcar-gen2.c
@@ -10,6 +10,7 @@
#include <clk.h>
#include <dm.h>
#include <errno.h>
+#include <fdtdec.h>
#include <pci.h>
#include <linux/bitops.h>
@@ -235,9 +236,9 @@ static int rcar_gen2_pci_of_to_plat(struct udevice *dev)
{
struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);
- priv->cfg_base = devfdt_get_addr_index(dev, 0);
- priv->mem_base = devfdt_get_addr_index(dev, 1);
- if (!priv->cfg_base || !priv->mem_base)
+ priv->cfg_base = dev_read_addr_index(dev, 0);
+ priv->mem_base = dev_read_addr_index(dev, 1);
+ if (priv->cfg_base == FDT_ADDR_T_NONE || priv->mem_base == FDT_ADDR_T_NONE)
return -EINVAL;
return 0;
diff --git a/drivers/pci/pci-rcar-gen3.c b/drivers/pci/pci-rcar-gen3.c
index d4b4037ce19..1925d968c16 100644
--- a/drivers/pci/pci-rcar-gen3.c
+++ b/drivers/pci/pci-rcar-gen3.c
@@ -19,6 +19,7 @@
#include <clk.h>
#include <dm.h>
#include <errno.h>
+#include <fdtdec.h>
#include <pci.h>
#include <wait_bit.h>
#include <linux/bitops.h>
@@ -391,8 +392,8 @@ static int rcar_gen3_pcie_of_to_plat(struct udevice *dev)
{
struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);
- priv->regs = devfdt_get_addr_index(dev, 0);
- if (!priv->regs)
+ priv->regs = dev_read_addr_index(dev, 0);
+ if (priv->regs == FDT_ADDR_T_NONE)
return -EINVAL;
return 0;
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index f58d542ef75..4bdd1f7477f 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -1126,14 +1126,14 @@ static int decode_regions(struct pci_controller *hose, ofnode parent_node,
return 0;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
- if (bd->bi_dram[i].size) {
- phys_addr_t start = bd->bi_dram[i].start;
+ if (gd->dram[i].size) {
+ phys_addr_t start = gd->dram[i].start;
if (IS_ENABLED(CONFIG_PCI_MAP_SYSTEM_MEMORY))
- start = virt_to_phys((void *)(uintptr_t)bd->bi_dram[i].start);
+ start = virt_to_phys((void *)(uintptr_t)gd->dram[i].start);
pci_set_region(hose->regions + hose->region_count++,
- start, start, bd->bi_dram[i].size,
+ start, start, gd->dram[i].size,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
}
}
diff --git a/drivers/pci/pci_mpc85xx.c b/drivers/pci/pci_mpc85xx.c
index c07feba7976..96550a9ff8f 100644
--- a/drivers/pci/pci_mpc85xx.c
+++ b/drivers/pci/pci_mpc85xx.c
@@ -170,13 +170,14 @@ static int mpc85xx_pci_dm_remove(struct udevice *dev)
static int mpc85xx_pci_of_to_plat(struct udevice *dev)
{
struct mpc85xx_pci_priv *priv = dev_get_priv(dev);
- fdt_addr_t addr;
+ void __iomem *addr;
- addr = devfdt_get_addr_index(dev, 0);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_remap_addr_index(dev, 0);
+ if (!addr)
return -EINVAL;
- priv->cfg_addr = (void __iomem *)map_physmem(addr, 0, MAP_NOCACHE);
- priv->cfg_data = (void __iomem *)((ulong)priv->cfg_addr + 4);
+
+ priv->cfg_addr = addr;
+ priv->cfg_data = priv->cfg_addr + 4;
return 0;
}
diff --git a/drivers/pci/pcie_brcmstb.c b/drivers/pci/pcie_brcmstb.c
index f089c48f028..1b03b0a7b05 100644
--- a/drivers/pci/pcie_brcmstb.c
+++ b/drivers/pci/pcie_brcmstb.c
@@ -21,6 +21,7 @@
#include <linux/bitfield.h>
#include <linux/log2.h>
#include <linux/iopoll.h>
+#include <reset.h>
/* PCIe parameters */
#define BRCM_NUM_PCIE_OUT_WINS 4
@@ -49,6 +50,47 @@
#define SSC_STATUS_PLL_LOCK_MASK 0x800
#define SSC_STATUS_PLL_LOCK_SHIFT 11
+#define PCIE_RC_PL_PHY_CTL_15 0x184c
+#define PCIE_RC_PL_PHY_CTL_15_DIS_PLL_PD_MASK 0x400000
+#define PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK 0xff
+
+#define PCIE_MISC_UBUS_CTRL 0x40a4
+#define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK BIT(13)
+#define PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK BIT(19)
+#define PCIE_MISC_AXI_READ_ERROR_DATA 0x4170
+#define PCIE_MISC_UBUS_TIMEOUT 0x40A8
+#define PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT 0x405c
+#define PCIE_MISC_RC_BAR4_CONFIG_LO 0x40d4
+#define PCIE_MISC_RC_BAR4_CONFIG_HI 0x40d8
+#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_HI_MASK 0xff
+#define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_HI 0x4110
+#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_ENABLE 0x1
+#define PCIE_MISC_UBUS_BAR_CONFIG_REMAP_LO_MASK 0xfffff000
+#define PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_LO 0x410c
+
+#define PCIE_MISC_UBUS_BAR1_CONFIG_REMAP 0x40ac
+#define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP 0x40b4
+#define PCIE_MISC_UBUS_BAR2_CONFIG_REMAP_ACCESS_ENABLE_MASK BIT(0)
+#define MISC_CTRL_PCIE_RCB_MPS_MODE_MASK 0x400
+
+enum {
+ RGR1_SW_INIT_1,
+ PCIE_HARD_DEBUG,
+};
+
+enum brcm_pcie_type {
+ BCM2711,
+ BCM2712
+};
+
+struct brcm_pcie;
+
+struct brcm_pcie_cfg_data {
+ const int *offsets;
+ const enum brcm_pcie_type type;
+ void (*perst_set)(struct brcm_pcie *pcie, u32 val);
+};
+
/**
* struct brcm_pcie - the PCIe controller state
* @base: Base address of memory mapped IO registers of the controller
@@ -61,6 +103,9 @@ struct brcm_pcie {
int gen;
bool ssc;
+ struct reset_ctl rescal;
+ struct reset_ctl bridge_reset;
+ const struct brcm_pcie_cfg_data *pcie_cfg;
};
/**
@@ -79,8 +124,8 @@ static int brcm_pcie_encode_ibar_size(u64 size)
if (log2_in >= 12 && log2_in <= 15)
/* Covers 4KB to 32KB (inclusive) */
return (log2_in - 12) + 0x1c;
- else if (log2_in >= 16 && log2_in <= 37)
- /* Covers 64KB to 32GB, (inclusive) */
+ else if (log2_in >= 16 && log2_in <= 36)
+ /* Covers 64KB to 64GB, (inclusive) */
return log2_in - 15;
/* Something is awry so disable */
@@ -104,6 +149,80 @@ static bool brcm_pcie_rc_mode(struct brcm_pcie *pcie)
return (val & STATUS_PCIE_PORT_MASK) >> STATUS_PCIE_PORT_SHIFT;
}
+static void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val)
+{
+ if (val)
+ setbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_PERST_MASK);
+ else
+ clrbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_PERST_MASK);
+}
+
+static void brcm_pcie_perst_set_2712(struct brcm_pcie *pcie, u32 val)
+{
+ u32 tmp;
+
+ /* Perst bit has moved and assert value is 0 */
+ tmp = readl(pcie->base + PCIE_MISC_PCIE_CTRL);
+ u32p_replace_bits(&tmp, !val, RGR1_SW_INIT_1_PERSTB_MASK);
+ writel(tmp, pcie->base + PCIE_MISC_PCIE_CTRL);
+}
+
+static int brcm_pcie_get_resets_dt(struct udevice *dev)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ int ret;
+
+ ret = reset_get_by_name(dev, "rescal", &pcie->rescal);
+ if (ret) {
+ printf("Unable to get rescal reset\n");
+ return ret;
+ }
+
+ ret = reset_get_by_name(dev, "bridge", &pcie->bridge_reset);
+ if (ret)
+ printf("Unable to get bridge reset\n");
+
+ return ret;
+}
+
+static int brcm_pcie_do_reset(struct udevice *dev)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ int ret;
+
+ ret = reset_deassert(&pcie->rescal);
+ if (ret)
+ printf("failed to deassert 'rescal'\n");
+ return ret;
+}
+
+static int brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, u32 val)
+{
+ int ret = 0;
+
+ if (reset_valid(&pcie->bridge_reset))
+ {
+ if (val)
+ ret = reset_assert(&pcie->bridge_reset);
+ else
+ ret = reset_deassert(&pcie->bridge_reset);
+ if (ret)
+ log_err("failed to %sassert bridge reset, err=%d\n",
+ val ? "" : "de", ret);
+ return ret;
+ }
+
+ if (val)
+ setbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_INIT_MASK);
+ else
+ clrbits_le32(pcie->base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ RGR1_SW_INIT_1_INIT_MASK);
+ return 0;
+}
+
/**
* brcm_pcie_link_up() - Check whether the PCIe link is up
* @pcie: Pointer to the PCIe controller state
@@ -125,7 +244,7 @@ static int brcm_pcie_config_address(const struct udevice *dev, pci_dev_t bdf,
uint offset, void **paddress)
{
struct brcm_pcie *pcie = dev_get_priv(dev);
- unsigned int pci_bus = PCI_BUS(bdf);
+ unsigned int pci_bus = PCI_BUS(bdf) - dev_seq(dev);
unsigned int pci_dev = PCI_DEV(bdf);
unsigned int pci_func = PCI_FUNC(bdf);
int idx;
@@ -345,28 +464,150 @@ static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
writel(tmp, base + PCIE_MEM_WIN0_LIMIT_HI(win));
}
+static u32 brcm_bar_reg_offset(int bar)
+{
+ if (bar <= 3)
+ return PCIE_MISC_RC_BAR1_CONFIG_LO + 8 * (bar - 1);
+ else
+ return PCIE_MISC_RC_BAR4_CONFIG_LO + 8 * (bar - 4);
+}
+
+static u32 brcm_ubus_reg_offset(int bar)
+{
+ if (bar <= 3)
+ return PCIE_MISC_UBUS_BAR1_CONFIG_REMAP + 8 * (bar - 1);
+ else
+ return PCIE_MISC_UBUS_BAR4_CONFIG_REMAP_LO + 8 * (bar - 4);
+}
+
+/*
+ * Round size up to the next power of two, as required by
+ * brcm_pcie_encode_ibar_size(). If size is already a power of two
+ * fls64(size - 1) still gives the correct result because the hardware
+ * encodes the exponent, not the raw value.
+ */
+static u64 brcm_ibar_round_size(u64 size)
+{
+ return 1ULL << fls64(size - 1);
+}
+
+static void brcm_pcie_set_inbound_windows(struct udevice *dev)
+{
+ struct brcm_pcie *pcie = dev_get_priv(dev);
+ void __iomem *base = pcie->base;
+ bool is_2712 = (pcie->pcie_cfg->type == BCM2712);
+ int i, ibar_no, ret;
+ u32 tmp;
+
+ ibar_no = 0;
+ /* pre-2712 chips leave the first entry empty */
+ if (pcie->pcie_cfg->type != BCM2712)
+ ibar_no++;
+
+ /* program inbound windows from OF property "dma-regions" */
+ for (i = 0; i < 7; i++, ibar_no++) {
+ u64 bar_cpu, bar_size, bar_pci;
+ struct pci_region region;
+ int ubus_bar_offset, rc_bar_offset;
+
+ ret = pci_get_dma_regions(dev, &region, i);
+ if (ret) /* no region #i? Then we're done. */
+ break;
+ ubus_bar_offset = brcm_ubus_reg_offset(ibar_no + 1);
+ rc_bar_offset = brcm_bar_reg_offset(ibar_no + 1);
+
+ bar_pci = region.bus_start;
+ bar_cpu = region.phys_start;
+ bar_size = region.size;
+
+ if (is_2712) {
+ /* BCM2712: BAR holds raw PCI address; UBUS remap
+ * registers supply the CPU-side translation. */
+ tmp = lower_32_bits(bar_pci);
+ u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(bar_size),
+ RC_BAR2_CONFIG_LO_SIZE_MASK);
+ writel(tmp, base + rc_bar_offset);
+ writel(upper_32_bits(bar_pci), base + rc_bar_offset + 4);
+
+ tmp = lower_32_bits(bar_cpu) &
+ PCIE_MISC_UBUS_BAR_CONFIG_REMAP_LO_MASK;
+ tmp |= PCIE_MISC_UBUS_BAR_CONFIG_REMAP_ENABLE;
+ writel(tmp, base + ubus_bar_offset);
+
+ tmp = upper_32_bits(bar_cpu) &
+ PCIE_MISC_UBUS_BAR_CONFIG_REMAP_HI_MASK;
+ writel(tmp, base + ubus_bar_offset + 4);
+ } else {
+ /* Pre-BCM2712 (e.g. BCM2711 / RPi4): the BAR config
+ * register holds the offset (bus_start - phys_start),
+ * not the raw PCI address. The size must be rounded
+ * up to the next power of two before encoding. */
+ u64 bar_offset = bar_pci - bar_cpu;
+ u64 bar_size_po2 = brcm_ibar_round_size(bar_size);
+
+ tmp = lower_32_bits(bar_offset);
+ u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(bar_size_po2),
+ RC_BAR2_CONFIG_LO_SIZE_MASK);
+ writel(tmp, base + rc_bar_offset);
+ writel(upper_32_bits(bar_offset), base + rc_bar_offset + 4);
+ /* UBUS remap registers are not used on pre-2712 hardware. */
+ }
+ }
+}
+
+static void brcm_pcie_munge_pll(struct brcm_pcie *pcie)
+{
+ u32 tmp;
+ int ret, i;
+ u8 regs[] = { 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1e };
+ u16 data[] = { 0x50b9, 0xbda1, 0x0094, 0x97b4, 0x5030, 0x5030, 0x0007 };
+
+ ret = brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, SET_ADDR_OFFSET,
+ 0x1600);
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ brcm_pcie_mdio_read(pcie->base, MDIO_PORT0, regs[i], &tmp);
+ debug("PCIE MDIO pre_refclk 0x%02x = 0x%04x\n",
+ regs[i], tmp);
+ }
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ brcm_pcie_mdio_write(pcie->base, MDIO_PORT0, regs[i], data[i]);
+ brcm_pcie_mdio_read(pcie->base, MDIO_PORT0, regs[i], &tmp);
+ debug("PCIE MDIO post_refclk 0x%02x = 0x%04x\n",
+ regs[i], tmp);
+ }
+
+ udelay(200);
+}
+
static int brcm_pcie_probe(struct udevice *dev)
{
struct udevice *ctlr = pci_get_controller(dev);
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
struct brcm_pcie *pcie = dev_get_priv(dev);
void __iomem *base = pcie->base;
- struct pci_region region;
bool ssc_good = false;
int num_out_wins = 0;
- u64 rc_bar2_offset, rc_bar2_size;
- unsigned int scb_size_val;
- int i, ret;
+ int i, ret = 0;
u16 nlw, cls, lnksta;
u32 tmp;
/*
+ * Ensure rescal reset for BCM2712 is really disabled.
+ */
+ if (pcie->pcie_cfg->type == BCM2712)
+ ret = brcm_pcie_do_reset(dev);
+ if (ret)
+ return ret;
+ /*
* Reset the bridge, assert the fundamental reset. Note for some SoCs,
* e.g. BCM7278, the fundamental reset should not be asserted here.
* This will need to be changed when support for other SoCs is added.
*/
- setbits_le32(base + PCIE_RGR1_SW_INIT_1,
- PCIE_RGR1_SW_INIT_1_INIT_MASK | PCIE_RGR1_SW_INIT_1_PERST_MASK);
+ ret = brcm_pcie_bridge_sw_init_set(pcie, 1);
+ if (ret)
+ return ret;
+ if (pcie->pcie_cfg->type != BCM2712)
+ pcie->pcie_cfg->perst_set(pcie, 1);
/*
* The delay is a safety precaution to preclude the reset signal
* from looking like a glitch.
@@ -374,39 +615,77 @@ static int brcm_pcie_probe(struct udevice *dev)
udelay(100);
/* Take the bridge out of reset */
- clrbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK);
-
- clrbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+ ret = brcm_pcie_bridge_sw_init_set(pcie, 0);
+ if (ret)
+ return ret;
+ clrbits_le32(base + pcie->pcie_cfg->offsets[PCIE_HARD_DEBUG],
PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
/* Wait for SerDes to be stable */
udelay(100);
+ if (pcie->pcie_cfg->type == BCM2712) {
+ /* Allow a 54MHz (xosc) refclk source */
+ brcm_pcie_munge_pll(pcie);
+ /* Fix for L1SS errata */
+ tmp = readl(base + PCIE_RC_PL_PHY_CTL_15);
+ tmp &= ~PCIE_RC_PL_PHY_CTL_15_PM_CLK_PERIOD_MASK;
+ /* PM clock period is 18.52ns (round down) */
+ tmp |= 0x12;
+ writel(tmp, base + PCIE_RC_PL_PHY_CTL_15);
+ }
+
+ tmp = (pcie->pcie_cfg->type == BCM2712) ?
+ MISC_CTRL_MAX_BURST_SIZE_128_2712 :
+ MISC_CTRL_MAX_BURST_SIZE_128;
/* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */
clrsetbits_le32(base + PCIE_MISC_MISC_CTRL,
MISC_CTRL_MAX_BURST_SIZE_MASK,
MISC_CTRL_SCB_ACCESS_EN_MASK |
MISC_CTRL_CFG_READ_UR_MODE_MASK |
- MISC_CTRL_MAX_BURST_SIZE_128);
+ MISC_CTRL_PCIE_RCB_MPS_MODE_MASK |
+ tmp);
- pci_get_dma_regions(dev, &region, 0);
- rc_bar2_offset = region.bus_start - region.phys_start;
- rc_bar2_size = 1ULL << fls64(region.size - 1);
+ tmp = readl(base + PCIE_MISC_MISC_CTRL);
+ if (pcie->pcie_cfg->type == BCM2712) {
+ /* BCM2712: fixed 32GB SCB0 window */
+ u32p_replace_bits(&tmp, 20, MISC_CTRL_SCB0_SIZE_MASK);
+ } else {
+ /* Pre-BCM2712: size SCB0 to match the actual DMA region.
+ * rc_bar2_size must be a power of two; ilog2(size) - 15
+ * gives the hardware encoding (e.g. 1GB -> 15). */
+ struct pci_region region;
+ u64 rc_bar2_size;
- tmp = lower_32_bits(rc_bar2_offset);
- u32p_replace_bits(&tmp, brcm_pcie_encode_ibar_size(rc_bar2_size),
- RC_BAR2_CONFIG_LO_SIZE_MASK);
- writel(tmp, base + PCIE_MISC_RC_BAR2_CONFIG_LO);
- writel(upper_32_bits(rc_bar2_offset),
- base + PCIE_MISC_RC_BAR2_CONFIG_HI);
+ pci_get_dma_regions(dev, &region, 0);
+ rc_bar2_size = brcm_ibar_round_size(region.size);
+ u32p_replace_bits(&tmp, rc_bar2_size ? ilog2(rc_bar2_size) - 15 : 0xf,
+ MISC_CTRL_SCB0_SIZE_MASK);
+ }
+ writel(tmp, base + PCIE_MISC_MISC_CTRL);
- scb_size_val = rc_bar2_size ?
- ilog2(rc_bar2_size) - 15 : 0xf; /* 0xf is 1GB */
+ if (pcie->pcie_cfg->type == BCM2712) {
+ /* Suppress AXI error responses and return 1s for read failures */
+ tmp = readl(base + PCIE_MISC_UBUS_CTRL);
+ u32p_replace_bits(&tmp, 1, PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_ERR_DIS_MASK);
+ u32p_replace_bits(&tmp, 1, PCIE_MISC_UBUS_CTRL_UBUS_PCIE_REPLY_DECERR_DIS_MASK);
+ writel(tmp, base + PCIE_MISC_UBUS_CTRL);
+ writel(0xffffffff, base + PCIE_MISC_AXI_READ_ERROR_DATA);
- tmp = readl(base + PCIE_MISC_MISC_CTRL);
- u32p_replace_bits(&tmp, scb_size_val,
- MISC_CTRL_SCB0_SIZE_MASK);
- writel(tmp, base + PCIE_MISC_MISC_CTRL);
+ /*
+ * Adjust timeouts. The UBUS timeout also affects CRS
+ * completion retries, as the request will get terminated if
+ * either timeout expires, so both have to be a large value
+ * (in clocks of 750MHz).
+ * Set UBUS timeout to 250ms, then set RC config retry timeout
+ * to be ~240ms.
+ *
+ * Setting CRSVis=1 will stop the core from blocking on a CRS
+ * response, but does require the device to be well-behaved...
+ */
+ writel(0xB2D0000, base + PCIE_MISC_UBUS_TIMEOUT);
+ writel(0xABA0000, base + PCIE_MISC_RC_CONFIG_RETRY_TIMEOUT);
+ }
/* Disable the PCIe->GISB memory window (RC_BAR1) */
clrbits_le32(base + PCIE_MISC_RC_BAR1_CONFIG_LO,
@@ -422,12 +701,13 @@ static int brcm_pcie_probe(struct udevice *dev)
/* Clear any interrupts we find on boot */
writel(0xffffffff, base + PCIE_MSI_INTR2_CLR);
+ brcm_pcie_set_inbound_windows(dev);
+
if (pcie->gen)
brcm_pcie_set_gen(pcie, pcie->gen);
/* Unassert the fundamental reset */
- clrbits_le32(pcie->base + PCIE_RGR1_SW_INIT_1,
- PCIE_RGR1_SW_INIT_1_PERST_MASK);
+ pcie->pcie_cfg->perst_set(pcie, 0);
/*
* Wait for 100ms after PERST# deassertion; see PCIe CEM specification
@@ -514,14 +794,25 @@ static int brcm_pcie_remove(struct udevice *dev)
void __iomem *base = pcie->base;
/* Assert fundamental reset */
- setbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_PERST_MASK);
+ setbits_le32(base + pcie->pcie_cfg->offsets[RGR1_SW_INIT_1],
+ PCIE_RGR1_SW_INIT_1_PERST_MASK);
/* Turn off SerDes */
- setbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG,
+ setbits_le32(base + pcie->pcie_cfg->offsets[PCIE_HARD_DEBUG],
PCIE_HARD_DEBUG_SERDES_IDDQ_MASK);
/* Shutdown bridge */
- setbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK);
+ brcm_pcie_bridge_sw_init_set(pcie, 1);
+
+ /*
+ * For the controllers that are utilizing reset for bridge Sw init,
+ * such as BCM2712, reset should be deasserted after assertion.
+ * Leaving it in asserted state may lead to unexpected hangs in
+ * the Linux Kernel driver because it do not perform reset initialization
+ * and start accessing device memory.
+ */
+ if (pcie->pcie_cfg->type == BCM2712)
+ brcm_pcie_bridge_sw_init_set(pcie, 0);
return 0;
}
@@ -546,6 +837,11 @@ static int brcm_pcie_of_to_plat(struct udevice *dev)
else
pcie->gen = max_link_speed;
+ pcie->pcie_cfg = (const struct brcm_pcie_cfg_data *)dev_get_driver_data(dev);
+
+ if (pcie->pcie_cfg->type == BCM2712)
+ return brcm_pcie_get_resets_dt(dev);
+
return 0;
}
@@ -554,8 +850,31 @@ static const struct dm_pci_ops brcm_pcie_ops = {
.write_config = brcm_pcie_write_config,
};
+static const int pcie_offsets[] = {
+ [RGR1_SW_INIT_1] = 0x9210,
+ [PCIE_HARD_DEBUG] = 0x4204,
+};
+
+static const struct brcm_pcie_cfg_data bcm2711_cfg = {
+ .offsets = pcie_offsets,
+ .type = BCM2711,
+ .perst_set = brcm_pcie_perst_set_generic,
+};
+
+static const int pcie_offsets_bcm2712[] = {
+ [RGR1_SW_INIT_1] = 0x0,
+ [PCIE_HARD_DEBUG] = 0x4304,
+};
+
+static const struct brcm_pcie_cfg_data bcm2712_cfg = {
+ .offsets = pcie_offsets_bcm2712,
+ .type = BCM2712,
+ .perst_set = brcm_pcie_perst_set_2712,
+};
+
static const struct udevice_id brcm_pcie_ids[] = {
- { .compatible = "brcm,bcm2711-pcie" },
+ { .compatible = "brcm,bcm2711-pcie", .data = (ulong)&bcm2711_cfg },
+ { .compatible = "brcm,bcm2712-pcie", .data = (ulong)&bcm2712_cfg },
{ }
};
diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c
index 43b919175c9..5a177478afc 100644
--- a/drivers/pci/pcie_dw_mvebu.c
+++ b/drivers/pci/pcie_dw_mvebu.c
@@ -565,13 +565,12 @@ static int pcie_dw_mvebu_of_to_plat(struct udevice *dev)
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
/* Get the controller base address */
- pcie->ctrl_base = devfdt_get_addr_index_ptr(dev, 0);
+ pcie->ctrl_base = dev_read_addr_index_ptr(dev, 0);
if (!pcie->ctrl_base)
return -EINVAL;
/* Get the config space base address and size */
- pcie->cfg_base = devfdt_get_addr_size_index_ptr(dev, 1,
- &pcie->cfg_size);
+ pcie->cfg_base = dev_read_addr_size_index_ptr(dev, 1, &pcie->cfg_size);
if (!pcie->cfg_base)
return -EINVAL;
diff --git a/drivers/pci/pcie_dw_qcom.c b/drivers/pci/pcie_dw_qcom.c
index 10c45aaba20..ce6b4d97d1d 100644
--- a/drivers/pci/pcie_dw_qcom.c
+++ b/drivers/pci/pcie_dw_qcom.c
@@ -22,7 +22,7 @@
struct qcom_pcie;
-struct qcom_pcie_ops {
+static const struct qcom_pcie_ops {
int (*config_sid)(struct qcom_pcie *priv);
};
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c
index 8d853ecf2c2..c8b8e171e39 100644
--- a/drivers/pci/pcie_imx.c
+++ b/drivers/pci/pcie_imx.c
@@ -774,8 +774,8 @@ static int imx_pcie_of_to_plat(struct udevice *dev)
{
struct imx_pcie_priv *priv = dev_get_priv(dev);
- priv->dbi_base = devfdt_get_addr_index_ptr(dev, 0);
- priv->cfg_base = devfdt_get_addr_index_ptr(dev, 1);
+ priv->dbi_base = dev_read_addr_index_ptr(dev, 0);
+ priv->cfg_base = dev_read_addr_index_ptr(dev, 1);
if (!priv->dbi_base || !priv->cfg_base)
return -EINVAL;
diff --git a/drivers/pci/pcie_layerscape.h b/drivers/pci/pcie_layerscape.h
index d5f4930e181..e6d47241e71 100644
--- a/drivers/pci/pcie_layerscape.h
+++ b/drivers/pci/pcie_layerscape.h
@@ -10,6 +10,7 @@
#include <fdtdec.h>
#include <pci.h>
+#include <linux/ioport.h>
#include <linux/sizes.h>
#include <linux/types.h>
#include <asm/arch-fsl-layerscape/svr.h>
@@ -164,7 +165,7 @@ struct ls_pcie_rc {
};
struct ls_pcie_ep {
- struct fdt_resource addr_res;
+ struct resource addr_res;
struct ls_pcie *pcie;
struct udevice *bus;
void __iomem *addr;
diff --git a/drivers/pci/pcie_layerscape_ep.c b/drivers/pci/pcie_layerscape_ep.c
index 3520488b345..b7809857565 100644
--- a/drivers/pci/pcie_layerscape_ep.c
+++ b/drivers/pci/pcie_layerscape_ep.c
@@ -7,7 +7,6 @@
#include <config.h>
#include <asm/arch/fsl_serdes.h>
#include <dm.h>
-#include <asm/global_data.h>
#include <dm/devres.h>
#include <errno.h>
#include <pci_ep.h>
@@ -16,8 +15,6 @@
#include <linux/log2.h>
#include "pcie_layerscape.h"
-DECLARE_GLOBAL_DATA_PTR;
-
static void ls_pcie_ep_enable_cfg(struct ls_pcie_ep *pcie_ep)
{
struct ls_pcie *pcie = pcie_ep->pcie;
@@ -250,17 +247,15 @@ static int ls_pcie_ep_probe(struct udevice *dev)
pcie_ep->pcie = pcie;
- pcie->dbi = devfdt_get_addr_index_ptr(dev, 0);
+ pcie->dbi = dev_read_addr_index_ptr(dev, 0);
if (!pcie->dbi)
return -EINVAL;
- pcie->ctrl = devfdt_get_addr_index_ptr(dev, 1);
+ pcie->ctrl = dev_read_addr_index_ptr(dev, 1);
if (!pcie->ctrl)
return -EINVAL;
- ret = fdt_get_named_resource(gd->fdt_blob, dev_of_offset(dev),
- "reg", "reg-names",
- "addr_space", &pcie_ep->addr_res);
+ ret = dev_read_resource_byname(dev, "addr_space", &pcie_ep->addr_res);
if (ret) {
printf("%s: resource \"addr_space\" not found\n", dev->name);
return ret;
@@ -273,8 +268,7 @@ static int ls_pcie_ep_probe(struct udevice *dev)
if (!is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx)))
return 0;
- pcie->big_endian = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
- "big-endian");
+ pcie->big_endian = dev_read_bool(dev, "big-endian");
svr = SVR_SOC_VER(get_svr());
@@ -294,13 +288,9 @@ static int ls_pcie_ep_probe(struct udevice *dev)
if (pcie->mode != PCI_HEADER_TYPE_NORMAL)
return 0;
- pcie_ep->max_functions = fdtdec_get_int(gd->fdt_blob,
- dev_of_offset(dev),
- "max-functions", 1);
- pcie_ep->num_ib_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "num-ib-windows", 8);
- pcie_ep->num_ob_wins = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "num-ob-windows", 8);
+ pcie_ep->max_functions = dev_read_s32_default(dev, "max-functions", 1);
+ pcie_ep->num_ib_wins = dev_read_s32_default(dev, "num-ib-windows", 8);
+ pcie_ep->num_ob_wins = dev_read_s32_default(dev, "num-ob-windows", 8);
printf("PCIe%u: %s %s", PCIE_SRDS_PRTCL(pcie->idx), dev->name,
"Endpoint");
diff --git a/drivers/pci_endpoint/Kconfig b/drivers/pci_endpoint/Kconfig
index 9900481daa6..d1db4951a0c 100644
--- a/drivers/pci_endpoint/Kconfig
+++ b/drivers/pci_endpoint/Kconfig
@@ -9,10 +9,10 @@ config PCI_ENDPOINT
bool "PCI Endpoint Support"
depends on DM
help
- Enable this configuration option to support configurable PCI
- endpoints. This should be enabled if the platform has a PCI
- controllers that can operate in endpoint mode (as a device
- connected to PCI host or bridge).
+ Enable this configuration option to support configurable PCI
+ endpoints. This should be enabled if the platform has a PCI
+ controllers that can operate in endpoint mode (as a device
+ connected to PCI host or bridge).
config PCIE_CADENCE_EP
bool "Cadence PCIe endpoint controller"
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 5c8ec2b146f..89d84df96ae 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -72,14 +72,14 @@ config AB8500_USB_PHY
Support for the USB OTG PHY in ST-Ericsson AB8500.
config APPLE_ATCPHY
- bool "Apple Type-C PHY Driver"
- depends on PHY && ARCH_APPLE
- default y
- help
- Support for the Apple Type-C PHY.
+ bool "Apple Type-C PHY Driver"
+ depends on PHY && ARCH_APPLE
+ default y
+ help
+ Support for the Apple Type-C PHY.
- This is a dummy driver since the PHY is initialized
- sufficiently by previous stage firmware.
+ This is a dummy driver since the PHY is initialized
+ sufficiently by previous stage firmware.
config BCM6318_USBH_PHY
bool "BCM6318 USBH PHY support"
@@ -114,7 +114,7 @@ config BCM_SR_PCIE_PHY
If unsure, say N.
config PHY_DA8XX_USB
- tristate "TI DA8xx USB PHY Driver"
+ bool "TI DA8xx USB PHY Driver"
depends on PHY && ARCH_DAVINCI
help
Enable this to support the USB PHY on DA8xx SoCs.
@@ -138,7 +138,7 @@ config SPL_PIPE3_PHY
and omap5
config AM654_PHY
- tristate "TI AM654 SERDES support"
+ bool "TI AM654 SERDES support"
depends on PHY && ARCH_K3
select REGMAP
select SYSCON
@@ -155,7 +155,7 @@ config STI_USB_PHY
STiH407 SoC families.
config PHY_RCAR_GEN2
- tristate "Renesas R-Car Gen2 USB PHY"
+ bool "Renesas R-Car Gen2 USB PHY"
depends on PHY && RCAR_GEN2
help
Support for the Renesas R-Car Gen2 USB PHY. This driver operates the
@@ -163,7 +163,7 @@ config PHY_RCAR_GEN2
allows configuring the module multiplexing.
config PHY_RCAR_GEN3
- tristate "Renesas R-Car Gen3 USB PHY"
+ bool "Renesas R-Car Gen3 USB PHY"
depends on PHY && CLK && DM_REGULATOR && (RCAR_GEN3 || RZG2L)
default y if (RCAR_GEN3 || RZG2L)
help
@@ -171,7 +171,7 @@ config PHY_RCAR_GEN3
PHY connected to EHCI USB module and controls USB OTG operation.
config PHY_STM32_USBPHYC
- tristate "STMicroelectronics STM32 SoC USB HS PHY driver"
+ bool "STMicroelectronics STM32 SoC USB HS PHY driver"
depends on PHY && ARCH_STM32MP
help
Enable this to support the High-Speed USB transceiver that is part of
@@ -249,14 +249,14 @@ config MT7620_USB_PHY
depends on PHY
depends on SOC_MT7620
help
- Support the intergated USB PHY in MediaTek MT7620 SoC
+ Support the intergated USB PHY in MediaTek MT7620 SoC
config MT76X8_USB_PHY
bool "MediaTek MT76x8 (7628/88) USB PHY support"
depends on PHY
depends on SOC_MT7628
help
- Support the USB PHY in MT76x8 SoCs
+ Support the USB PHY in MT76x8 SoCs
This PHY is found on MT76x8 devices supporting USB.
@@ -283,7 +283,7 @@ config PHY_MTK_TPHY
so you can easily distinguish them by banks layout.
config PHY_MTK_UFS
- tristate "MediaTek UFS M-PHY driver"
+ bool "MediaTek UFS M-PHY driver"
depends on ARCH_MEDIATEK
depends on PHY
help
@@ -337,7 +337,7 @@ config PHY_IMX8M_PCIE
This PHY is found on i.MX8M devices supporting PCIe.
config PHY_XILINX_ZYNQMP
- tristate "Xilinx ZynqMP PHY driver"
+ bool "Xilinx ZynqMP PHY driver"
depends on PHY && ARCH_ZYNQMP
help
Enable this to support ZynqMP High Speed Gigabit Transceiver
diff --git a/drivers/phy/cadence/Kconfig b/drivers/phy/cadence/Kconfig
index 8c0ab80fbbc..f5f096889fe 100644
--- a/drivers/phy/cadence/Kconfig
+++ b/drivers/phy/cadence/Kconfig
@@ -1,11 +1,11 @@
config PHY_CADENCE_SIERRA
- tristate "Cadence Sierra PHY Driver"
+ bool "Cadence Sierra PHY Driver"
depends on DM_RESET
help
Enable this to support the Cadence Sierra PHY driver
config PHY_CADENCE_TORRENT
- tristate "Cadence Torrent PHY Driver"
+ bool "Cadence Torrent PHY Driver"
depends on DM_RESET
help
Enable this to support the Cadence Torrent PHY driver
diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index bd7ab9d1b77..9f8a6d8d43d 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -1068,12 +1068,12 @@ static int cdns_sierra_phy_probe(struct udevice *dev)
sp->dev = dev;
- sp->base = devfdt_remap_addr_index(dev, 0);
+ sp->base = dev_remap_addr_index(dev, 0);
if (!sp->base) {
dev_err(dev, "unable to map regs\n");
return -ENOMEM;
}
- devfdt_get_addr_size_index(dev, 0, (fdt_size_t *)&sp->size);
+ dev_read_addr_size_index(dev, 0, (fdt_size_t *)&sp->size);
/* Get init data for this PHY */
data = (struct cdns_sierra_data *)dev_get_driver_data(dev);
diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c
index 933533b2b0b..814aff15070 100644
--- a/drivers/phy/cadence/phy-cadence-torrent.c
+++ b/drivers/phy/cadence/phy-cadence-torrent.c
@@ -791,10 +791,10 @@ static int cdns_torrent_phy_probe(struct udevice *dev)
return ret;
}
- cdns_phy->sd_base = devfdt_remap_addr_index(dev, 0);
- if (IS_ERR(cdns_phy->sd_base))
- return PTR_ERR(cdns_phy->sd_base);
- devfdt_get_addr_size_index(dev, 0, (fdt_size_t *)&cdns_phy->size);
+ cdns_phy->sd_base = dev_remap_addr_index(dev, 0);
+ if (!cdns_phy->sd_base)
+ return -EINVAL;
+ dev_read_addr_size_index(dev, 0, (fdt_size_t *)&cdns_phy->size);
dev_for_each_subnode(child, dev)
subnodes++;
diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c
index b074d58f9f6..0ab5f9a3f0a 100644
--- a/drivers/phy/marvell/comphy_core.c
+++ b/drivers/phy/marvell/comphy_core.c
@@ -84,11 +84,11 @@ static int comphy_probe(struct udevice *dev)
int res;
/* Save base addresses for later use */
- chip_cfg->comphy_base_addr = devfdt_get_addr_index_ptr(dev, 0);
+ chip_cfg->comphy_base_addr = dev_read_addr_index_ptr(dev, 0);
if (!chip_cfg->comphy_base_addr)
return -EINVAL;
- chip_cfg->hpipe3_base_addr = devfdt_get_addr_index_ptr(dev, 1);
+ chip_cfg->hpipe3_base_addr = dev_read_addr_index_ptr(dev, 1);
if (!chip_cfg->hpipe3_base_addr)
return -EINVAL;
diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig
index 49f830abf01..1fdadaccb12 100644
--- a/drivers/phy/qcom/Kconfig
+++ b/drivers/phy/qcom/Kconfig
@@ -2,12 +2,12 @@ config MSM8916_USB_PHY
bool
select PHY
help
- Support the Qualcomm MSM8916 USB PHY
+ Support the Qualcomm MSM8916 USB PHY
This PHY is found on qualcomm dragonboard410c development board.
config PHY_QCOM_IPQ4019_USB
- tristate "Qualcomm IPQ4019 USB PHY driver"
+ bool "Qualcomm IPQ4019 USB PHY driver"
depends on PHY && ARCH_IPQ40XX
help
Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s.
@@ -21,26 +21,26 @@ config PHY_QCOM_QMP_COMBO
PHY (USB3 + DisplayPort). Currently only USB3 mode is supported.
config PHY_QCOM_QMP_PCIE
- tristate "Qualcomm QMP PCIe PHY driver"
+ bool "Qualcomm QMP PCIe PHY driver"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the PCIe QMP PHY on various Qualcomm chipsets.
config PHY_QCOM_QMP_UFS
- tristate "Qualcomm QMP UFS PHY driver"
+ bool "Qualcomm QMP UFS PHY driver"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the UFS QMP PHY on various Qualcomm chipsets.
config PHY_QCOM_QUSB2
- tristate "Qualcomm USB QUSB2 PHY driver"
+ bool "Qualcomm USB QUSB2 PHY driver"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Super-Speed USB transceiver on various
Qualcomm chipsets.
config PHY_QCOM_USB_SNPS_FEMTO_V2
- tristate "Qualcomm SNPS FEMTO USB HS PHY v2"
+ bool "Qualcomm SNPS FEMTO USB HS PHY v2"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Qualcomm Synopsys DesignWare Core 7nm
@@ -48,7 +48,7 @@ config PHY_QCOM_USB_SNPS_FEMTO_V2
is usually paired with Synopsys DWC3 USB IPs on MSM SOCs.
config PHY_QCOM_SNPS_EUSB2
- tristate "Qualcomm Synopsys eUSB2 High-Speed PHY"
+ bool "Qualcomm Synopsys eUSB2 High-Speed PHY"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Qualcomm Synopsys DesignWare eUSB2
@@ -56,7 +56,7 @@ config PHY_QCOM_SNPS_EUSB2
is usually paired with Synopsys DWC3 USB IPs on MSM SOCs.
config PHY_QCOM_USB_HS_28NM
- tristate "Qualcomm 28nm High-Speed PHY"
+ bool "Qualcomm 28nm High-Speed PHY"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Qualcomm Synopsys DesignWare Core 28nm
@@ -65,7 +65,7 @@ config PHY_QCOM_USB_HS_28NM
IPs on MSM SOCs.
config PHY_QCOM_USB_SS
- tristate "Qualcomm USB Super-Speed PHY driver"
+ bool "Qualcomm USB Super-Speed PHY driver"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Super-Speed USB transceiver on various
diff --git a/drivers/phy/qcom/phy-qcom-qmp-ufs.c b/drivers/phy/qcom/phy-qcom-qmp-ufs.c
index 80eba734a63..3df88189a90 100644
--- a/drivers/phy/qcom/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qcom/phy-qcom-qmp-ufs.c
@@ -1741,6 +1741,8 @@ static const struct udevice_id qmp_ufs_ids[] = {
{ .compatible = "qcom,milos-qmp-ufs-phy", .data = (ulong)&milos_ufsphy_cfg, },
{ .compatible = "qcom,sa8775p-qmp-ufs-phy", .data = (ulong)&sa8775p_ufsphy_cfg, },
{ .compatible = "qcom,sdm845-qmp-ufs-phy", .data = (ulong)&sdm845_ufsphy_cfg },
+ { .compatible = "qcom,sm6115-qmp-ufs-phy", .data = (ulong)&sm6115_ufsphy_cfg, },
+ { .compatible = "qcom,sm6125-qmp-ufs-phy", .data = (ulong)&sm6115_ufsphy_cfg, },
{ .compatible = "qcom,sm6350-qmp-ufs-phy", .data = (ulong)&sdm845_ufsphy_cfg },
{ .compatible = "qcom,sm7150-qmp-ufs-phy", .data = (ulong)&sm7150_ufsphy_cfg },
{ .compatible = "qcom,sm8150-qmp-ufs-phy", .data = (ulong)&sm8150_ufsphy_cfg },
diff --git a/drivers/phy/renesas/Kconfig b/drivers/phy/renesas/Kconfig
index affbee0500c..3358d454e59 100644
--- a/drivers/phy/renesas/Kconfig
+++ b/drivers/phy/renesas/Kconfig
@@ -3,19 +3,19 @@
# Phy drivers for Renesas platforms
config PHY_R8A779F0_ETHERNET_SERDES
- tristate "Renesas R-Car S4-8 Ethernet SERDES driver"
+ bool "Renesas R-Car S4-8 Ethernet SERDES driver"
depends on RCAR_64 && PHY
help
Support for Ethernet SERDES found on Renesas R-Car S4-8 SoCs.
config PHY_R8A78000_ETHERNET_PCS
- tristate "Renesas R-Car X5H Ethernet PCS driver"
+ bool "Renesas R-Car X5H Ethernet PCS driver"
depends on RCAR_64 && PHY
help
Support for Ethernet PCS found on Renesas R-Car X5H SoCs.
config PHY_R8A78000_MP_PHY
- tristate "Renesas R-Car X5H Multi-Protocol PHY driver"
+ bool "Renesas R-Car X5H Multi-Protocol PHY driver"
depends on RCAR_64 && PHY
help
Support for Multi-Protocol PHY on Renesas R-Car X5H SoCs.
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 80128335d52..6f3d7ebe29e 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -49,7 +49,7 @@ config PHY_ROCKCHIP_SNPS_PCIE3
also be able splited into multiple combinations of lanes.
config PHY_ROCKCHIP_USBDP
- tristate "Rockchip USBDP COMBO PHY Driver"
+ bool "Rockchip USBDP COMBO PHY Driver"
depends on ARCH_ROCKCHIP
select PHY
help
diff --git a/drivers/phy/ti-pipe3-phy.c b/drivers/phy/ti-pipe3-phy.c
index 62f6cc2bfbf..080016ba417 100644
--- a/drivers/phy/ti-pipe3-phy.c
+++ b/drivers/phy/ti-pipe3-phy.c
@@ -6,6 +6,7 @@
#include <dm.h>
#include <dm/device.h>
+#include <dm/device_compat.h>
#include <generic-phy.h>
#include <asm/global_data.h>
#include <asm/io.h>
@@ -428,10 +429,10 @@ static int pipe3_exit(struct phy *phy)
static void *get_reg(struct udevice *dev, const char *name)
{
+ struct ofnode_phandle_args phandle;
struct udevice *syscon;
struct regmap *regmap;
- const fdt32_t *cell;
- int len, err;
+ int err;
void *base;
err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
@@ -449,10 +450,14 @@ static void *get_reg(struct udevice *dev, const char *name)
return NULL;
}
- cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), name,
- &len);
- if (len < 2*sizeof(fdt32_t)) {
- pr_err("offset not available for %s\n", name);
+ err = dev_read_phandle_with_args(dev, name, NULL, 0, 0, &phandle);
+ if (err) {
+ dev_err(dev, "parse %s failed: %d\n", name, err);
+ return NULL;
+ }
+
+ if (phandle.args_count < 1) {
+ dev_err(dev, "%s: missing args\n", name);
return NULL;
}
@@ -460,7 +465,7 @@ static void *get_reg(struct udevice *dev, const char *name)
if (!base)
return NULL;
- return fdtdec_get_number(cell + 1, 1) + base;
+ return base + phandle.args[0];
}
static int pipe3_phy_probe(struct udevice *dev)
@@ -471,7 +476,7 @@ static int pipe3_phy_probe(struct udevice *dev)
struct pipe3_data *data;
/* PHY_RX */
- addr = devfdt_get_addr_size_index(dev, 0, &sz);
+ addr = dev_read_addr_size_index(dev, 0, &sz);
if (addr == FDT_ADDR_T_NONE) {
pr_err("missing phy_rx address\n");
return -EINVAL;
@@ -484,7 +489,7 @@ static int pipe3_phy_probe(struct udevice *dev)
}
/* PLLCTRL */
- addr = devfdt_get_addr_size_index(dev, 2, &sz);
+ addr = dev_read_addr_size_index(dev, 2, &sz);
if (addr == FDT_ADDR_T_NONE) {
pr_err("missing pll ctrl address\n");
return -EINVAL;
diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig
index df750b26d66..fe96eb6806f 100644
--- a/drivers/phy/ti/Kconfig
+++ b/drivers/phy/ti/Kconfig
@@ -1,5 +1,5 @@
config PHY_J721E_WIZ
- tristate "TI J721E WIZ (SERDES Wrapper) support"
+ bool "TI J721E WIZ (SERDES Wrapper) support"
depends on ARCH_K3
help
This option enables support for WIZ module present in TI's J721E
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 578edbf8168..fd30aaeeaa8 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -378,6 +378,26 @@ config ASPEED_AST2600_PINCTRL
uses Generic Pinctrl framework and is compatible with the Linux
driver, i.e. it uses the same device tree configuration.
+config ASPEED_AST2700_SOC0_PINCTRL
+ bool "Aspeed AST2700 SoC0 pin control driver"
+ depends on DM && PINCTRL_GENERIC && ASPEED_AST2700
+ select PINCONF
+ default y
+ help
+ Support pin multiplexing control on Aspeed ast2700 SoC0. The driver
+ uses Generic Pinctrl framework and is compatible with the Linux
+ driver, i.e. it uses the same device tree configuration.
+
+config ASPEED_AST2700_SOC1_PINCTRL
+ bool "Aspeed AST2700 SoC1 pin control driver"
+ depends on DM && PINCTRL_GENERIC && ASPEED_AST2700
+ select PINCONF
+ default y
+ help
+ Support pin multiplexing control on Aspeed ast2700 SoC1. The driver
+ uses Generic Pinctrl framework and is compatible with the Linux
+ driver, i.e. it uses the same device tree configuration.
+
config PINCTRL_K210
bool "Kendryte K210 Fully-Programmable Input/Output Array driver"
depends on DM && PINCTRL_GENERIC
@@ -405,6 +425,7 @@ config SPL_PINCTRL_ZYNQMP
endif
+source "drivers/pinctrl/airoha/Kconfig"
source "drivers/pinctrl/broadcom/Kconfig"
source "drivers/pinctrl/exynos/Kconfig"
source "drivers/pinctrl/intel/Kconfig"
@@ -419,6 +440,7 @@ source "drivers/pinctrl/nxp/Kconfig"
source "drivers/pinctrl/qcom/Kconfig"
source "drivers/pinctrl/renesas/Kconfig"
source "drivers/pinctrl/rockchip/Kconfig"
+source "drivers/pinctrl/spacemit/Kconfig"
source "drivers/pinctrl/sunxi/Kconfig"
source "drivers/pinctrl/tegra/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 29fb9b484d0..91149796bb5 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -3,39 +3,43 @@
obj-y += pinctrl-uclass.o
obj-$(CONFIG_$(PHASE_)PINCTRL_GENERIC) += pinctrl-generic.o
+obj-y += broadcom/
+obj-y += nxp/
+
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
+obj-$(CONFIG_ARCH_ATH79) += ath79/
+obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
+obj-$(CONFIG_ARCH_MVEBU) += mvebu/
+obj-$(CONFIG_ARCH_NEXELL) += nexell/
+obj-$(CONFIG_ARCH_NPCM) += nuvoton/
+obj-$(CONFIG_ARCH_RENESAS) += renesas/
+
obj-$(CONFIG_PINCTRL_ADI) += pinctrl-adi-adsp.o
+obj-$(CONFIG_PINCTRL_AIROHA) += airoha/
obj-$(CONFIG_PINCTRL_APPLE) += pinctrl-apple.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
-obj-y += nxp/
+obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/
+obj-$(CONFIG_PINCTRL_INTEL) += intel/
+obj-$(CONFIG_PINCTRL_K210) += pinctrl-k210.o
+obj-$(CONFIG_PINCTRL_MESON) += meson/
+obj-$(CONFIG_PINCTRL_MSCC) += mscc/
+obj-$(CONFIG_PINCTRL_MTK) += mediatek/
+obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o
+obj-$(CONFIG_PINCTRL_QCOM) += qcom/
+obj-$(CONFIG_PINCTRL_QE) += pinctrl-qe-io.o
obj-$(CONFIG_$(PHASE_)PINCTRL_ROCKCHIP) += rockchip/
-obj-$(CONFIG_ARCH_ASPEED) += aspeed/
-obj-$(CONFIG_ARCH_ATH79) += ath79/
-obj-$(CONFIG_PINCTRL_INTEL) += intel/
-obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
-obj-$(CONFIG_ARCH_NPCM) += nuvoton/
-obj-$(CONFIG_PINCTRL_QCOM) += qcom/
-obj-$(CONFIG_ARCH_RENESAS) += renesas/
-obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
-obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/
-obj-$(CONFIG_$(PHASE_)PINCTRL_TEGRA) += tegra/
-obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
-obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o
-obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/
-obj-$(CONFIG_PINCTRL_K210) += pinctrl-k210.o
-obj-$(CONFIG_PINCTRL_MESON) += meson/
-obj-$(CONFIG_PINCTRL_MTK) += mediatek/
-obj-$(CONFIG_PINCTRL_MSCC) += mscc/
-obj-$(CONFIG_ARCH_MVEBU) += mvebu/
-obj-$(CONFIG_ARCH_NEXELL) += nexell/
-obj-$(CONFIG_PINCTRL_QE) += pinctrl-qe-io.o
-obj-$(CONFIG_PINCTRL_SCMI) += pinctrl-scmi.o
-obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
-obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
-obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o
-obj-$(CONFIG_$(PHASE_)PINCTRL_SX150X) += pinctrl-sx150x.o
+obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
+obj-$(CONFIG_PINCTRL_SCMI) += pinctrl-scmi.o
+obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
+obj-$(CONFIG_$(PHASE_)PINCTRL_SPACEMIT_K1) += spacemit/
+obj-$(CONFIG_PINCTRL_STARFIVE) += starfive/
+obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
+obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o
obj-$(CONFIG_$(PHASE_)PINCTRL_STMFX) += pinctrl-stmfx.o
-obj-$(CONFIG_PINCTRL_TH1520) += pinctrl-th1520.o
-obj-y += broadcom/
+obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/
+obj-$(CONFIG_$(PHASE_)PINCTRL_SX150X) += pinctrl-sx150x.o
+obj-$(CONFIG_$(PHASE_)PINCTRL_TEGRA) += tegra/
+obj-$(CONFIG_PINCTRL_TH1520) += pinctrl-th1520.o
+obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_$(PHASE_)PINCTRL_ZYNQMP) += pinctrl-zynqmp.o
-obj-$(CONFIG_PINCTRL_STARFIVE) += starfive/
diff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig
new file mode 100644
index 00000000000..f5d948b27eb
--- /dev/null
+++ b/drivers/pinctrl/airoha/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config PINCTRL_AIROHA
+ depends on ARCH_AIROHA
+ select PINCTRL_FULL
+ select PINCTRL_GENERIC
+ select PINMUX
+ select PINCONF
+ select REGMAP
+ select SYSCON
+ bool
+
+config PINCTRL_AIROHA_EN7523
+ bool "Airoha EN7523 pin controller and gpio driver"
+ depends on TARGET_EN7523
+ select PINCTRL_AIROHA
+
+config PINCTRL_AIROHA_AN7581
+ bool "Airoha AN7581 pin controller and gpio driver"
+ depends on TARGET_AN7581
+ select PINCTRL_AIROHA
+
+config PINCTRL_AIROHA_AN7583
+ bool "Airoha AN7583 pin controller and gpio driver"
+ depends on TARGET_AN7583
+ select PINCTRL_AIROHA
diff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile
new file mode 100644
index 00000000000..b90bd180591
--- /dev/null
+++ b/drivers/pinctrl/airoha/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o
+
+obj-$(CONFIG_PINCTRL_AIROHA_EN7523) += pinctrl-en7523.o
+obj-$(CONFIG_PINCTRL_AIROHA_AN7581) += pinctrl-an7581.o
+obj-$(CONFIG_PINCTRL_AIROHA_AN7583) += pinctrl-an7583.o
diff --git a/drivers/pinctrl/airoha/airoha-common.h b/drivers/pinctrl/airoha/airoha-common.h
new file mode 100644
index 00000000000..4354b0eb6b4
--- /dev/null
+++ b/drivers/pinctrl/airoha/airoha-common.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __AIROHA_COMMON_HEADER__
+#define __AIROHA_COMMON_HEADER__
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include <dm/device.h>
+#include <dm/pinctrl.h>
+
+/* GPIOs */
+#define REG_GPIO_CTRL 0x0000
+#define REG_GPIO_DATA 0x0004
+#define REG_GPIO_INT 0x0008
+#define REG_GPIO_INT_EDGE 0x000c
+#define REG_GPIO_INT_LEVEL 0x0010
+#define REG_GPIO_OE 0x0014
+#define REG_GPIO_CTRL1 0x0020
+#define REG_GPIO_CTRL2 0x0060
+#define REG_GPIO_CTRL3 0x0064
+#define REG_GPIO_DATA1 0x0070
+#define REG_GPIO_OE1 0x0078
+#define REG_GPIO_INT1 0x007c
+#define REG_GPIO_INT_EDGE1 0x0080
+#define REG_GPIO_INT_EDGE2 0x0084
+#define REG_GPIO_INT_EDGE3 0x0088
+#define REG_GPIO_INT_LEVEL1 0x008c
+#define REG_GPIO_INT_LEVEL2 0x0090
+#define REG_GPIO_INT_LEVEL3 0x0094
+
+#define AIROHA_NUM_PINS 64
+#define AIROHA_PIN_BANK_SIZE (AIROHA_NUM_PINS / 2)
+#define AIROHA_REG_GPIOCTRL_NUM_PIN (AIROHA_NUM_PINS / 4)
+
+#define PINCTRL_PIN_GROUP(id, table) \
+ PINCTRL_PINGROUP(id, table##_pins, ARRAY_SIZE(table##_pins))
+
+#define PINCTRL_FUNC_DESC(id, table) \
+ { \
+ .desc = PINCTRL_PINFUNCTION(id, table##_groups, \
+ ARRAY_SIZE(table##_groups)),\
+ .groups = table##_func_group, \
+ .group_size = ARRAY_SIZE(table##_func_group), \
+ }
+
+#define PINCTRL_CONF_DESC(p, offset, mask) \
+ { \
+ .pin = p, \
+ .reg = { offset, mask }, \
+ }
+
+struct airoha_pinctrl_reg {
+ u32 offset;
+ u32 mask;
+};
+
+enum airoha_pinctrl_mux_func {
+ AIROHA_FUNC_MUX,
+ AIROHA_FUNC_PWM_MUX,
+ AIROHA_FUNC_PWM_EXT_MUX,
+};
+
+struct airoha_pinctrl_func_group {
+ const char *name;
+ struct {
+ enum airoha_pinctrl_mux_func mux;
+ u32 offset;
+ u32 mask;
+ u32 val;
+ } regmap[2];
+ int regmap_size;
+};
+
+struct airoha_pinctrl_func {
+ const struct pinfunction desc;
+ const struct airoha_pinctrl_func_group *groups;
+ u8 group_size;
+};
+
+struct airoha_pinctrl_conf {
+ u32 pin;
+ struct airoha_pinctrl_reg reg;
+};
+
+struct airoha_pinctrl_gpiochip {
+ /* gpio */
+ const u32 *data;
+ const u32 *dir;
+ const u32 *out;
+ /* irq */
+ const u32 *status;
+ const u32 *level;
+ const u32 *edge;
+
+ u32 irq_type[AIROHA_NUM_PINS];
+};
+
+struct airoha_pinctrl_confs_info {
+ const struct airoha_pinctrl_conf *confs;
+ unsigned int num_confs;
+};
+
+enum airoha_pinctrl_confs_type {
+ AIROHA_PINCTRL_CONFS_PULLUP,
+ AIROHA_PINCTRL_CONFS_PULLDOWN,
+ AIROHA_PINCTRL_CONFS_DRIVE_E2,
+ AIROHA_PINCTRL_CONFS_DRIVE_E4,
+ AIROHA_PINCTRL_CONFS_PCIE_RST_OD,
+
+ AIROHA_PINCTRL_CONFS_MAX
+};
+
+struct airoha_pinctrl {
+ struct udevice *dev;
+
+ struct regmap *chip_scu;
+ struct regmap *regmap;
+
+ struct airoha_pinctrl_match_data *data;
+
+ struct airoha_pinctrl_gpiochip gpiochip;
+};
+
+struct airoha_pinctrl_match_data {
+ const int gpio_offs;
+ const int gpio_pin_cnt;
+ const char *chip_scu_compatible;
+ const struct pinctrl_pin_desc *pins;
+ const unsigned int num_pins;
+ const struct pingroup *grps;
+ const unsigned int num_grps;
+ const struct airoha_pinctrl_func *funcs;
+ const unsigned int num_funcs;
+ const struct airoha_pinctrl_confs_info confs_info[AIROHA_PINCTRL_CONFS_MAX];
+};
+
+extern const struct pinctrl_ops airoha_pinctrl_ops;
+
+int airoha_pinctrl_probe(struct udevice *dev);
+int airoha_pinctrl_bind(struct udevice *dev);
+
+#endif
diff --git a/drivers/pinctrl/airoha/pinctrl-airoha.c b/drivers/pinctrl/airoha/pinctrl-airoha.c
new file mode 100644
index 00000000000..60c48c0960c
--- /dev/null
+++ b/drivers/pinctrl/airoha/pinctrl-airoha.c
@@ -0,0 +1,958 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Author: Lorenzo Bianconi <[email protected]>
+ * Author: Benjamin Larsson <[email protected]>
+ * Author: Markus Gothe <[email protected]>
+ * Author: Mikhail Kshevetskiy <[email protected]>
+ */
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/ofnode.h>
+#include <asm-generic/gpio.h>
+#include <asm/arch/scu-regmap.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+#include <regmap.h>
+#include <syscon.h>
+
+#include "airoha-common.h"
+
+#define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \
+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \
+ (pin), (val))
+#define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val) \
+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \
+ (pin), (val))
+#define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val) \
+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \
+ (pin), (val))
+#define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val) \
+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \
+ (pin), (val))
+#define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val) \
+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \
+ (pin), (val))
+#define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val) \
+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \
+ (pin), (val))
+#define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val) \
+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \
+ (pin), (val))
+#define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val) \
+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \
+ (pin), (val))
+#define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val) \
+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \
+ (pin), (val))
+#define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val) \
+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \
+ (pin), (val))
+
+static const u32 gpio_data_regs[] = {
+ REG_GPIO_DATA,
+ REG_GPIO_DATA1
+};
+
+static const u32 gpio_out_regs[] = {
+ REG_GPIO_OE,
+ REG_GPIO_OE1
+};
+
+static const u32 gpio_dir_regs[] = {
+ REG_GPIO_CTRL,
+ REG_GPIO_CTRL1,
+ REG_GPIO_CTRL2,
+ REG_GPIO_CTRL3
+};
+
+static const u32 irq_status_regs[] = {
+ REG_GPIO_INT,
+ REG_GPIO_INT1
+};
+
+static const u32 irq_level_regs[] = {
+ REG_GPIO_INT_LEVEL,
+ REG_GPIO_INT_LEVEL1,
+ REG_GPIO_INT_LEVEL2,
+ REG_GPIO_INT_LEVEL3
+};
+
+static const u32 irq_edge_regs[] = {
+ REG_GPIO_INT_EDGE,
+ REG_GPIO_INT_EDGE1,
+ REG_GPIO_INT_EDGE2,
+ REG_GPIO_INT_EDGE3
+};
+
+static int pin_in_group(unsigned int pin, const struct pingroup *grp)
+{
+ for (int i = 0; i < grp->npins; i++) {
+ if (grp->pins[i] == pin)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int pin_to_gpio(struct airoha_pinctrl *pinctrl, unsigned int pin)
+{
+ struct airoha_pinctrl_match_data *data = pinctrl->data;
+
+ if (pin < data->gpio_offs ||
+ pin >= data->gpio_offs + data->gpio_pin_cnt)
+ return -EINVAL;
+
+ return pin - data->gpio_offs;
+}
+
+/* gpio callbacks */
+static int airoha_gpio_set(struct airoha_pinctrl *pinctrl, unsigned int gpio,
+ int value)
+{
+ u32 offset = gpio % AIROHA_PIN_BANK_SIZE;
+ u8 index = gpio / AIROHA_PIN_BANK_SIZE;
+
+ return regmap_update_bits(pinctrl->regmap,
+ pinctrl->gpiochip.data[index],
+ BIT(offset), value ? BIT(offset) : 0);
+}
+
+static int airoha_gpio_get(struct airoha_pinctrl *pinctrl, unsigned int gpio)
+{
+ u32 val, pin = gpio % AIROHA_PIN_BANK_SIZE;
+ u8 index = gpio / AIROHA_PIN_BANK_SIZE;
+ int err;
+
+ err = regmap_read(pinctrl->regmap,
+ pinctrl->gpiochip.data[index], &val);
+
+ return err ? err : !!(val & BIT(pin));
+}
+
+static int airoha_gpio_get_direction(struct airoha_pinctrl *pinctrl, unsigned int gpio)
+{
+ u32 mask, index, val;
+ int err, field_shift;
+
+ field_shift = 2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN);
+ mask = GENMASK(field_shift + 1, field_shift);
+ index = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;
+
+ err = regmap_read(pinctrl->regmap,
+ pinctrl->gpiochip.dir[index], &val);
+ if (err)
+ return err;
+
+ if ((val & mask) > BIT(field_shift))
+ return -EINVAL;
+
+ return (val & mask) ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static int airoha_gpio_set_direction(struct airoha_pinctrl *pinctrl,
+ unsigned int gpio, bool input)
+{
+ u32 mask, index;
+ int err, field_shift;
+
+ /* set output enable */
+ mask = BIT(gpio % AIROHA_PIN_BANK_SIZE);
+ index = gpio / AIROHA_PIN_BANK_SIZE;
+ err = regmap_update_bits(pinctrl->regmap, pinctrl->gpiochip.out[index],
+ mask, !input ? mask : 0);
+ if (err)
+ return err;
+
+ /* set direction */
+ field_shift = 2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN);
+ mask = GENMASK(field_shift + 1, field_shift);
+ index = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;
+
+ return regmap_update_bits(pinctrl->regmap,
+ pinctrl->gpiochip.dir[index],
+ mask, !input ? BIT(field_shift) : 0);
+}
+
+/* pinmux callbacks */
+static int airoha_pinmux_set_mux(struct airoha_pinctrl *pinctrl,
+ unsigned int func_selector,
+ unsigned int group_selector)
+{
+ const struct airoha_pinctrl_func *func;
+ const struct pingroup *grp;
+ int i;
+
+ func = &pinctrl->data->funcs[func_selector];
+ grp = &pinctrl->data->grps[group_selector];
+
+ dev_dbg(pinctrl->dev, "enable function %s group %s\n",
+ func->desc.name, grp->name);
+
+ for (i = 0; i < func->group_size; i++) {
+ const struct airoha_pinctrl_func_group *group;
+ int j;
+
+ group = &func->groups[i];
+ if (strcmp(group->name, grp->name))
+ continue;
+
+ for (j = 0; j < group->regmap_size; j++) {
+ switch (group->regmap[j].mux) {
+ case AIROHA_FUNC_PWM_EXT_MUX:
+ case AIROHA_FUNC_PWM_MUX:
+ regmap_update_bits(pinctrl->regmap,
+ group->regmap[j].offset,
+ group->regmap[j].mask,
+ group->regmap[j].val);
+ break;
+ default:
+ regmap_update_bits(pinctrl->chip_scu,
+ group->regmap[j].offset,
+ group->regmap[j].mask,
+ group->regmap[j].val);
+ break;
+ }
+ }
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int airoha_pinmux_set_direction(struct airoha_pinctrl *pinctrl,
+ unsigned int p, bool input)
+{
+ int gpio;
+
+ gpio = pin_to_gpio(pinctrl, p);
+ if (gpio < 0)
+ return gpio;
+
+ return airoha_gpio_set_direction(pinctrl, gpio, input);
+}
+
+/* pinconf callbacks */
+static const struct airoha_pinctrl_reg *
+airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf,
+ int conf_size, int pin)
+{
+ int i;
+
+ for (i = 0; i < conf_size; i++) {
+ if (conf[i].pin == pin)
+ return &conf[i].reg;
+ }
+
+ return NULL;
+}
+
+static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl,
+ enum airoha_pinctrl_confs_type conf_type,
+ int pin, u32 *val)
+{
+ const struct airoha_pinctrl_confs_info *confs_info;
+ const struct airoha_pinctrl_reg *reg;
+
+ confs_info = &pinctrl->data->confs_info[conf_type];
+
+ reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
+ confs_info->num_confs,
+ pin);
+ if (!reg)
+ return -EINVAL;
+
+ if (regmap_read(pinctrl->chip_scu, reg->offset, val))
+ return -EINVAL;
+
+ *val = field_get(reg->mask, *val);
+
+ return 0;
+}
+
+static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl,
+ enum airoha_pinctrl_confs_type conf_type,
+ int pin, u32 val)
+{
+ const struct airoha_pinctrl_confs_info *confs_info;
+ const struct airoha_pinctrl_reg *reg = NULL;
+
+ confs_info = &pinctrl->data->confs_info[conf_type];
+
+ reg = airoha_pinctrl_get_conf_reg(confs_info->confs,
+ confs_info->num_confs,
+ pin);
+ if (!reg)
+ return -EINVAL;
+
+ if (regmap_update_bits(pinctrl->chip_scu, reg->offset, reg->mask,
+ field_prep(reg->mask, val)))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int airoha_pinconf_get_direction(struct airoha_pinctrl *pinctrl, u32 p)
+{
+ int gpio;
+
+ gpio = pin_to_gpio(pinctrl, p);
+ if (gpio < 0)
+ return gpio;
+
+ return airoha_gpio_get_direction(pinctrl, gpio);
+}
+
+static int airoha_pinconf_get(struct airoha_pinctrl *pinctrl,
+ unsigned int pin, unsigned long *config)
+{
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 arg;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_UP: {
+ u32 pull_up, pull_down;
+
+ if (airoha_pinctrl_get_pullup_conf(pinctrl, pin, &pull_up) ||
+ airoha_pinctrl_get_pulldown_conf(pinctrl, pin, &pull_down))
+ return -EINVAL;
+
+ if (param == PIN_CONFIG_BIAS_PULL_UP &&
+ !(pull_up && !pull_down))
+ return -EINVAL;
+ else if (param == PIN_CONFIG_BIAS_PULL_DOWN &&
+ !(pull_down && !pull_up))
+ return -EINVAL;
+ else if (pull_up || pull_down)
+ return -EINVAL;
+
+ arg = 1;
+ break;
+ }
+ case PIN_CONFIG_DRIVE_STRENGTH: {
+ u32 e2, e4;
+
+ if (airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, &e2) ||
+ airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, &e4))
+ return -EINVAL;
+
+ arg = e4 << 1 | e2;
+ break;
+ }
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ if (airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, &arg))
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_OUTPUT_ENABLE:
+ case PIN_CONFIG_INPUT_ENABLE:
+ arg = airoha_pinconf_get_direction(pinctrl, pin);
+ if ((param != PIN_CONFIG_OUTPUT_ENABLE || arg != GPIOF_OUTPUT) &&
+ (param != PIN_CONFIG_INPUT_ENABLE || arg != GPIOF_INPUT))
+ return -EINVAL;
+
+ arg = 1;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int airoha_pinconf_set_pin_value(struct airoha_pinctrl *pinctrl,
+ unsigned int p, bool value)
+{
+ int gpio;
+
+ gpio = pin_to_gpio(pinctrl, p);
+ if (gpio < 0)
+ return gpio;
+
+ return airoha_gpio_set(pinctrl, gpio, value);
+}
+
+static int airoha_pinconf_set(struct airoha_pinctrl *pinctrl,
+ unsigned int pin, unsigned long *configs,
+ unsigned int num_configs)
+{
+ int i, err;
+
+ for (i = 0; i < num_configs; i++) {
+ u32 param = pinconf_to_config_param(configs[i]);
+ u32 arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
+ if (err)
+ return err;
+
+ err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
+ if (err)
+ return err;
+
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+ err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);
+ if (err)
+ return err;
+
+ err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 1);
+ if (err)
+ return err;
+
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ err = airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 1);
+ if (err)
+ return err;
+
+ err = airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);
+ if (err)
+ return err;
+
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH: {
+ u32 e2 = 0, e4 = 0;
+
+ switch (arg) {
+ case MTK_DRIVE_2mA:
+ break;
+ case MTK_DRIVE_4mA:
+ e2 = 1;
+ break;
+ case MTK_DRIVE_6mA:
+ e4 = 1;
+ break;
+ case MTK_DRIVE_8mA:
+ e2 = 1;
+ e4 = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ err = airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, e2);
+ if (err)
+ return err;
+
+ err = airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, e4);
+ if (err)
+ return err;
+
+ break;
+ }
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ err = airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, !!arg);
+ if (err)
+ return err;
+
+ break;
+
+ case PIN_CONFIG_OUTPUT_ENABLE:
+ case PIN_CONFIG_INPUT_ENABLE:
+ case PIN_CONFIG_OUTPUT: {
+ bool input = param == PIN_CONFIG_INPUT_ENABLE;
+
+ err = airoha_pinmux_set_direction(pinctrl, pin, input);
+ if (err)
+ return err;
+
+ if (param == PIN_CONFIG_OUTPUT) {
+ err = airoha_pinconf_set_pin_value(pinctrl,
+ pin, !!arg);
+ if (err)
+ return err;
+ }
+
+ break;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+static int airoha_pinconf_group_set(struct airoha_pinctrl *pinctrl,
+ unsigned int group, unsigned long *configs,
+ unsigned int num_configs)
+{
+ int i;
+
+ for (i = 0; i < pinctrl->data->grps[group].npins; i++) {
+ int err;
+
+ err = airoha_pinconf_set(pinctrl,
+ pinctrl->data->grps[group].pins[i],
+ configs, num_configs);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int func_grp_active(struct airoha_pinctrl *pinctrl,
+ const struct airoha_pinctrl_func *func,
+ const char *grp_name)
+{
+ const struct airoha_pinctrl_func_group *func_grp;
+ u32 val, match;
+ int ret;
+
+ for (int i = 0; i < func->group_size; i++) {
+ if (strcmp(func->groups[i].name, grp_name))
+ continue;
+
+ match = 0;
+ func_grp = &func->groups[i];
+ for (int j = 0; j < func_grp->regmap_size; j++) {
+ switch (func_grp->regmap[j].mux) {
+ case AIROHA_FUNC_PWM_EXT_MUX:
+ case AIROHA_FUNC_PWM_MUX:
+ ret = regmap_read(pinctrl->regmap,
+ func_grp->regmap[j].offset,
+ &val);
+ break;
+ default:
+ ret = regmap_read(pinctrl->chip_scu,
+ func_grp->regmap[j].offset,
+ &val);
+ break;
+ }
+
+ if (ret)
+ break;
+
+ if ((val & func_grp->regmap[j].mask) !=
+ func_grp->regmap[j].val)
+ break;
+
+ match++;
+ }
+
+ return match == func->groups[i].regmap_size;
+ }
+
+ return 0;
+}
+
+/***********************
+ * gpio driver interface
+ ***********************/
+static int airoha_pinctrl_gpio_set(struct udevice *dev, unsigned int gpio,
+ int value)
+{
+ return airoha_gpio_set(dev_get_priv(dev->parent), gpio, value);
+}
+
+static int airoha_pinctrl_gpio_get(struct udevice *dev, unsigned int gpio)
+{
+ return airoha_gpio_get(dev_get_priv(dev->parent), gpio);
+}
+
+static int airoha_pinctrl_gpio_get_direction(struct udevice *dev,
+ unsigned int gpio)
+{
+ return airoha_gpio_get_direction(dev_get_priv(dev->parent), gpio);
+}
+
+static int airoha_pinctrl_gpio_direction_input(struct udevice *dev,
+ unsigned int gpio)
+{
+ return airoha_gpio_set_direction(dev_get_priv(dev->parent),
+ gpio, true);
+}
+
+static int airoha_pinctrl_gpio_direction_output(struct udevice *dev,
+ unsigned int gpio, int val)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);
+ int err;
+
+ err = airoha_gpio_set_direction(pinctrl, gpio, false);
+ if (err)
+ return err;
+
+ return airoha_gpio_set(pinctrl, gpio, val);
+}
+
+static int airoha_pinctrl_gpio_probe(struct udevice *dev)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);
+ struct gpio_dev_priv *uc_priv;
+
+ uc_priv = dev_get_uclass_priv(dev);
+ uc_priv->bank_name = "airoha";
+ uc_priv->gpio_count = pinctrl->data->gpio_pin_cnt;
+
+ return 0;
+}
+
+static int airoha_pinctrl_gpio_bind(struct udevice *dev)
+{
+ dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+
+ return 0;
+}
+
+static const struct dm_gpio_ops airoha_pinctrl_gpio_ops = {
+ .set_value = airoha_pinctrl_gpio_set,
+ .get_value = airoha_pinctrl_gpio_get,
+ .get_function = airoha_pinctrl_gpio_get_direction,
+ .direction_input = airoha_pinctrl_gpio_direction_input,
+ .direction_output = airoha_pinctrl_gpio_direction_output,
+};
+
+static struct driver airoha_pinctrl_gpio_driver = {
+ .name = "airoha_pinctrl_gpio",
+ .id = UCLASS_GPIO,
+ .probe = airoha_pinctrl_gpio_probe,
+ .bind = airoha_pinctrl_gpio_bind,
+ .ops = &airoha_pinctrl_gpio_ops,
+};
+
+static int airoha_pinctrl_gpio_register(struct udevice *parent)
+{
+ struct uclass_driver *drv;
+ ofnode node;
+ int ret;
+
+ drv = lists_uclass_lookup(UCLASS_GPIO);
+ if (!drv)
+ return -ENOENT;
+
+ /*
+ * Support upstream linux DTSI that define gpio-controller
+ * in the root node (instead of a dedicated subnode)
+ */
+ if (dev_read_bool(parent, "gpio-controller")) {
+ /* upstream DTSI, use current node */
+ node = dev_ofnode(parent);
+ } else {
+ /* legacy DTSI, search for gpio-controller subnode */
+ ret = -ENOENT;
+ dev_for_each_subnode(node, parent)
+ if (ofnode_read_bool(node, "gpio-controller")) {
+ ret = 0;
+ break;
+ }
+
+ if (ret)
+ return ret;
+ }
+
+ return device_bind_with_driver_data(parent,
+ &airoha_pinctrl_gpio_driver,
+ "airoha_pinctrl_gpio",
+ 0, node, NULL);
+}
+
+/**************************
+ * pinctrl driver interface
+ **************************/
+static int airoha_get_pins_count(struct udevice *dev)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ return pinctrl->data->num_pins;
+}
+
+static const char *airoha_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ return pinctrl->data->pins[selector].name;
+}
+
+static int airoha_get_groups_count(struct udevice *dev)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ return pinctrl->data->num_grps;
+}
+
+static const char *airoha_get_group_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ return pinctrl->data->grps[selector].name;
+}
+
+static int airoha_get_funcs_count(struct udevice *dev)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ return pinctrl->data->num_funcs;
+}
+
+static const char *airoha_get_func_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ return pinctrl->data->funcs[selector].desc.name;
+}
+
+static int airoha_pinmux_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int func_selector)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ dev_dbg(dev, "enabling %s function for pin group %s\n",
+ airoha_get_func_name(dev, func_selector),
+ airoha_get_group_name(dev, group_selector));
+
+ return airoha_pinmux_set_mux(pinctrl, func_selector, group_selector);
+}
+
+static int airoha_pinmux_set(struct udevice *dev,
+ unsigned int pin_selector,
+ unsigned int func_selector)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+ const struct airoha_pinctrl_match_data *data = pinctrl->data;
+ const char *pin_name;
+ unsigned int selector;
+
+ pin_name = data->pins[pin_selector].name;
+
+ /* find group matching the pin_name */
+ for (selector = 0; selector < data->num_grps; selector++) {
+ if (!strcmp(pin_name, data->grps[selector].name))
+ return airoha_pinmux_group_set(dev, selector,
+ func_selector);
+ }
+
+ return -ENOENT;
+}
+
+static const struct pinconf_param airoha_pinconf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+ { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
+ { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
+ { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
+};
+
+static const char *airoha_pinconf_param_name(unsigned int param)
+{
+ for (int i = 0; i < ARRAY_SIZE(airoha_pinconf_params); i++) {
+ if (airoha_pinconf_params[i].param == param)
+ return airoha_pinconf_params[i].property;
+ }
+
+ return NULL;
+}
+
+static int airoha_pinconf_set_handler(struct udevice *dev,
+ unsigned pin_selector,
+ unsigned int param,
+ unsigned int argument)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+ unsigned long configs[1] = { pinconf_to_config_packed(param, argument) };
+ unsigned int pin = pinctrl->data->pins[pin_selector].number;
+
+ dev_dbg(dev, "enabling %s=%d property for pin %s\n",
+ airoha_pinconf_param_name(param), argument,
+ airoha_get_pin_name(dev, pin_selector));
+
+ return airoha_pinconf_set(pinctrl, pin, configs,
+ ARRAY_SIZE(configs));
+}
+
+static int airoha_pinconf_group_set_handler(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int param,
+ unsigned int argument)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+ unsigned long configs[1] = { pinconf_to_config_packed(param, argument) };
+
+ dev_dbg(dev, "enabling %s=%d property for pin group %s\n",
+ airoha_pinconf_param_name(param), argument,
+ airoha_get_group_name(dev, group_selector));
+
+ return airoha_pinconf_group_set(pinctrl, group_selector,
+ configs, ARRAY_SIZE(configs));
+}
+
+static int airoha_get_pin_muxing(struct udevice *dev, unsigned int selector,
+ char *buf, int size)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+ struct airoha_pinctrl_match_data *data = pinctrl->data;
+ const char *name, *type;
+ int ret, gpio, found = 0;
+ unsigned long config;
+ unsigned int param, pin;
+ u32 val;
+
+ pin = data->pins[selector].number;
+ for (int i = 0; i < data->num_grps; i++) {
+ if (!pin_in_group(pin, &data->grps[i]))
+ continue;
+
+ name = data->grps[i].name;
+ for (int j = 0; j < data->num_funcs; j++) {
+ if (!func_grp_active(pinctrl, &data->funcs[j], name))
+ continue;
+
+ ret = scnprintf(buf, size, "%s(%s)",
+ data->funcs[j].desc.name, name);
+ if (ret < 0)
+ return -ENOSPC;
+
+ found = 1;
+ buf += ret;
+ size -= ret;
+ break;
+ }
+
+ if (found)
+ break;
+ }
+
+ if (!found) {
+ gpio = pin_to_gpio(pinctrl, pin);
+ if (gpio < 0) {
+ /*
+ * WARNING: non-gpio pin with unknown function.
+ *
+ * This should not have happened, the function group
+ * tables are incomplete. Please fix ASAP.
+ */
+ ret = scnprintf(buf, size, "default");
+ } else {
+ /* assume gpio */
+ val = airoha_gpio_get(pinctrl, gpio);
+ switch (airoha_gpio_get_direction(pinctrl, gpio)) {
+ case GPIOF_INPUT:
+ type = "input";
+ break;
+ case GPIOF_OUTPUT:
+ type = "output";
+ break;
+ default:
+ type = "unknown";
+ break;
+ };
+ ret = scnprintf(buf, size, "gpio%d, %s(%d)",
+ gpio, type, val);
+ }
+
+ if (ret < 0)
+ return -ENOSPC;
+
+ buf += ret;
+ size -= ret;
+ }
+
+ for (int i = 0; i < ARRAY_SIZE(airoha_pinconf_params); i++) {
+ param = airoha_pinconf_params[i].param;
+ config = pinconf_to_config_packed(param, 0);
+ ret = airoha_pinconf_get(pinctrl, pin, &config);
+ if (ret < 0)
+ continue;
+
+ name = airoha_pinconf_params[i].property;
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ ret = scnprintf(buf, size, ", %s", name);
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ val = pinconf_to_config_argument(config);
+ ret = scnprintf(buf, size, ", %s(%d)", name, val);
+ break;
+
+ default:
+ break;
+ }
+
+ if (ret < 0)
+ return -ENOSPC;
+
+ buf += ret;
+ size -= ret;
+ }
+
+ return 0;
+}
+
+const struct pinctrl_ops airoha_pinctrl_ops = {
+ .get_pins_count = airoha_get_pins_count,
+ .get_pin_name = airoha_get_pin_name,
+ .get_groups_count = airoha_get_groups_count,
+ .get_group_name = airoha_get_group_name,
+ .get_functions_count = airoha_get_funcs_count,
+ .get_function_name = airoha_get_func_name,
+ .pinmux_set = airoha_pinmux_set,
+ .pinmux_group_set = airoha_pinmux_group_set,
+
+ .pinconf_num_params = ARRAY_SIZE(airoha_pinconf_params),
+ .pinconf_params = airoha_pinconf_params,
+ .pinconf_set = airoha_pinconf_set_handler,
+ .pinconf_group_set = airoha_pinconf_group_set_handler,
+
+ .set_state = pinctrl_generic_set_state,
+ .get_pin_muxing = airoha_get_pin_muxing,
+};
+
+int airoha_pinctrl_probe(struct udevice *dev)
+{
+ struct airoha_pinctrl *pinctrl = dev_get_priv(dev);
+
+ pinctrl->dev = dev;
+ pinctrl->data = (struct airoha_pinctrl_match_data *)dev_get_driver_data(dev);
+
+ pinctrl->regmap = syscon_node_to_regmap(dev_ofnode(dev->parent));
+ if (IS_ERR(pinctrl->regmap))
+ return PTR_ERR(pinctrl->regmap);
+
+ pinctrl->chip_scu = airoha_get_chip_scu_regmap();
+ if (IS_ERR(pinctrl->chip_scu))
+ return PTR_ERR(pinctrl->chip_scu);
+
+ pinctrl->gpiochip.data = gpio_data_regs;
+ pinctrl->gpiochip.dir = gpio_dir_regs;
+ pinctrl->gpiochip.out = gpio_out_regs;
+ pinctrl->gpiochip.status = irq_status_regs;
+ pinctrl->gpiochip.level = irq_level_regs;
+ pinctrl->gpiochip.edge = irq_edge_regs;
+
+ return 0;
+}
+
+int airoha_pinctrl_bind(struct udevice *dev)
+{
+ if (airoha_pinctrl_gpio_register(dev))
+ debug("Warning: can't bind gpio driver with device node\n");
+
+ /*
+ * Make sure that the pinctrl driver gets probed after binding,
+ * otherwise GPIO interface driver will not be probed as well.
+ * GPIOs of non-probed driver can't be used.
+ */
+ dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+
+ return 0;
+}
diff --git a/drivers/pinctrl/airoha/pinctrl-an7581.c b/drivers/pinctrl/airoha/pinctrl-an7581.c
new file mode 100644
index 00000000000..4f7da74a1cf
--- /dev/null
+++ b/drivers/pinctrl/airoha/pinctrl-an7581.c
@@ -0,0 +1,1484 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Author: Lorenzo Bianconi <[email protected]>
+ * Author: Benjamin Larsson <[email protected]>
+ * Author: Markus Gothe <[email protected]>
+ */
+
+#include "airoha-common.h"
+
+/* MUX */
+#define REG_GPIO_2ND_I2C_MODE 0x0214
+#define GPIO_MDC_IO_MASTER_MODE_MASK BIT(14)
+#define GPIO_I2C_MASTER_MODE_MODE BIT(13)
+#define GPIO_I2S_MODE_MASK BIT(12)
+#define GPIO_I2C_SLAVE_MODE_MODE BIT(11)
+#define GPIO_LAN3_LED1_MODE_MASK BIT(10)
+#define GPIO_LAN3_LED0_MODE_MASK BIT(9)
+#define GPIO_LAN2_LED1_MODE_MASK BIT(8)
+#define GPIO_LAN2_LED0_MODE_MASK BIT(7)
+#define GPIO_LAN1_LED1_MODE_MASK BIT(6)
+#define GPIO_LAN1_LED0_MODE_MASK BIT(5)
+#define GPIO_LAN0_LED1_MODE_MASK BIT(4)
+#define GPIO_LAN0_LED0_MODE_MASK BIT(3)
+#define PON_TOD_1PPS_MODE_MASK BIT(2)
+#define GSW_TOD_1PPS_MODE_MASK BIT(1)
+#define GPIO_2ND_I2C_MODE_MASK BIT(0)
+
+#define REG_GPIO_SPI_CS1_MODE 0x0218
+#define GPIO_PCM_SPI_CS4_MODE_MASK BIT(21)
+#define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20)
+#define GPIO_PCM_SPI_CS2_MODE_P156_MASK BIT(19)
+#define GPIO_PCM_SPI_CS2_MODE_P128_MASK BIT(18)
+#define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17)
+#define GPIO_PCM_SPI_MODE_MASK BIT(16)
+#define GPIO_PCM2_MODE_MASK BIT(13)
+#define GPIO_PCM1_MODE_MASK BIT(12)
+#define GPIO_PCM_INT_MODE_MASK BIT(9)
+#define GPIO_PCM_RESET_MODE_MASK BIT(8)
+#define GPIO_SPI_QUAD_MODE_MASK BIT(4)
+#define GPIO_SPI_CS4_MODE_MASK BIT(3)
+#define GPIO_SPI_CS3_MODE_MASK BIT(2)
+#define GPIO_SPI_CS2_MODE_MASK BIT(1)
+#define GPIO_SPI_CS1_MODE_MASK BIT(0)
+
+#define REG_GPIO_PON_MODE 0x021c
+#define GPIO_PARALLEL_NAND_MODE_MASK BIT(14)
+#define GPIO_SGMII_MDIO_MODE_MASK BIT(13)
+#define GPIO_PCIE_RESET2_MASK BIT(12)
+#define SIPO_RCLK_MODE_MASK BIT(11)
+#define GPIO_PCIE_RESET1_MASK BIT(10)
+#define GPIO_PCIE_RESET0_MASK BIT(9)
+#define GPIO_UART5_MODE_MASK BIT(8)
+#define GPIO_UART4_MODE_MASK BIT(7)
+#define GPIO_HSUART_CTS_RTS_MODE_MASK BIT(6)
+#define GPIO_HSUART_MODE_MASK BIT(5)
+#define GPIO_UART2_CTS_RTS_MODE_MASK BIT(4)
+#define GPIO_UART2_MODE_MASK BIT(3)
+#define GPIO_SIPO_MODE_MASK BIT(2)
+#define GPIO_EMMC_MODE_MASK BIT(1)
+#define GPIO_PON_MODE_MASK BIT(0)
+
+#define REG_NPU_UART_EN 0x0224
+#define JTAG_UDI_EN_MASK BIT(4)
+#define JTAG_DFD_EN_MASK BIT(3)
+
+#define REG_FORCE_GPIO_EN 0x0228
+#define FORCE_GPIO_EN(n) BIT(n)
+
+/* LED MAP */
+#define REG_LAN_LED0_MAPPING 0x027c
+#define REG_LAN_LED1_MAPPING 0x0280
+
+#define LAN4_LED_MAPPING_MASK GENMASK(18, 16)
+#define LAN4_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN4_LED_MAPPING_MASK, (_n))
+
+#define LAN3_LED_MAPPING_MASK GENMASK(14, 12)
+#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n))
+
+#define LAN2_LED_MAPPING_MASK GENMASK(10, 8)
+#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n))
+
+#define LAN1_LED_MAPPING_MASK GENMASK(6, 4)
+#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n))
+
+#define LAN0_LED_MAPPING_MASK GENMASK(2, 0)
+#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n))
+
+/* CONF */
+#define REG_I2C_SDA_E2 0x001c
+#define SPI_MISO_E2_MASK BIT(14)
+#define SPI_MOSI_E2_MASK BIT(13)
+#define SPI_CLK_E2_MASK BIT(12)
+#define SPI_CS0_E2_MASK BIT(11)
+#define PCIE2_RESET_E2_MASK BIT(10)
+#define PCIE1_RESET_E2_MASK BIT(9)
+#define PCIE0_RESET_E2_MASK BIT(8)
+#define UART1_RXD_E2_MASK BIT(3)
+#define UART1_TXD_E2_MASK BIT(2)
+#define I2C_SCL_E2_MASK BIT(1)
+#define I2C_SDA_E2_MASK BIT(0)
+
+#define REG_I2C_SDA_E4 0x0020
+#define SPI_MISO_E4_MASK BIT(14)
+#define SPI_MOSI_E4_MASK BIT(13)
+#define SPI_CLK_E4_MASK BIT(12)
+#define SPI_CS0_E4_MASK BIT(11)
+#define PCIE2_RESET_E4_MASK BIT(10)
+#define PCIE1_RESET_E4_MASK BIT(9)
+#define PCIE0_RESET_E4_MASK BIT(8)
+#define UART1_RXD_E4_MASK BIT(3)
+#define UART1_TXD_E4_MASK BIT(2)
+#define I2C_SCL_E4_MASK BIT(1)
+#define I2C_SDA_E4_MASK BIT(0)
+
+#define REG_GPIO_L_E2 0x0024
+#define REG_GPIO_L_E4 0x0028
+#define REG_GPIO_H_E2 0x002c
+#define REG_GPIO_H_E4 0x0030
+
+#define REG_I2C_SDA_PU 0x0044
+#define SPI_MISO_PU_MASK BIT(14)
+#define SPI_MOSI_PU_MASK BIT(13)
+#define SPI_CLK_PU_MASK BIT(12)
+#define SPI_CS0_PU_MASK BIT(11)
+#define PCIE2_RESET_PU_MASK BIT(10)
+#define PCIE1_RESET_PU_MASK BIT(9)
+#define PCIE0_RESET_PU_MASK BIT(8)
+#define UART1_RXD_PU_MASK BIT(3)
+#define UART1_TXD_PU_MASK BIT(2)
+#define I2C_SCL_PU_MASK BIT(1)
+#define I2C_SDA_PU_MASK BIT(0)
+
+#define REG_I2C_SDA_PD 0x0048
+#define SPI_MISO_PD_MASK BIT(14)
+#define SPI_MOSI_PD_MASK BIT(13)
+#define SPI_CLK_PD_MASK BIT(12)
+#define SPI_CS0_PD_MASK BIT(11)
+#define PCIE2_RESET_PD_MASK BIT(10)
+#define PCIE1_RESET_PD_MASK BIT(9)
+#define PCIE0_RESET_PD_MASK BIT(8)
+#define UART1_RXD_PD_MASK BIT(3)
+#define UART1_TXD_PD_MASK BIT(2)
+#define I2C_SCL_PD_MASK BIT(1)
+#define I2C_SDA_PD_MASK BIT(0)
+
+#define REG_GPIO_L_PU 0x004c
+#define REG_GPIO_L_PD 0x0050
+#define REG_GPIO_H_PU 0x0054
+#define REG_GPIO_H_PD 0x0058
+
+#define REG_PCIE_RESET_OD 0x018c
+#define PCIE2_RESET_OD_MASK BIT(2)
+#define PCIE1_RESET_OD_MASK BIT(1)
+#define PCIE0_RESET_OD_MASK BIT(0)
+
+/* PWM MODE CONF */
+#define REG_GPIO_FLASH_MODE_CFG 0x0034
+#define GPIO15_FLASH_MODE_CFG BIT(15)
+#define GPIO14_FLASH_MODE_CFG BIT(14)
+#define GPIO13_FLASH_MODE_CFG BIT(13)
+#define GPIO12_FLASH_MODE_CFG BIT(12)
+#define GPIO11_FLASH_MODE_CFG BIT(11)
+#define GPIO10_FLASH_MODE_CFG BIT(10)
+#define GPIO9_FLASH_MODE_CFG BIT(9)
+#define GPIO8_FLASH_MODE_CFG BIT(8)
+#define GPIO7_FLASH_MODE_CFG BIT(7)
+#define GPIO6_FLASH_MODE_CFG BIT(6)
+#define GPIO5_FLASH_MODE_CFG BIT(5)
+#define GPIO4_FLASH_MODE_CFG BIT(4)
+#define GPIO3_FLASH_MODE_CFG BIT(3)
+#define GPIO2_FLASH_MODE_CFG BIT(2)
+#define GPIO1_FLASH_MODE_CFG BIT(1)
+#define GPIO0_FLASH_MODE_CFG BIT(0)
+
+/* PWM MODE CONF EXT */
+#define REG_GPIO_FLASH_MODE_CFG_EXT 0x0068
+#define GPIO51_FLASH_MODE_CFG BIT(31)
+#define GPIO50_FLASH_MODE_CFG BIT(30)
+#define GPIO49_FLASH_MODE_CFG BIT(29)
+#define GPIO48_FLASH_MODE_CFG BIT(28)
+#define GPIO47_FLASH_MODE_CFG BIT(27)
+#define GPIO46_FLASH_MODE_CFG BIT(26)
+#define GPIO45_FLASH_MODE_CFG BIT(25)
+#define GPIO44_FLASH_MODE_CFG BIT(24)
+#define GPIO43_FLASH_MODE_CFG BIT(23)
+#define GPIO42_FLASH_MODE_CFG BIT(22)
+#define GPIO41_FLASH_MODE_CFG BIT(21)
+#define GPIO40_FLASH_MODE_CFG BIT(20)
+#define GPIO39_FLASH_MODE_CFG BIT(19)
+#define GPIO38_FLASH_MODE_CFG BIT(18)
+#define GPIO37_FLASH_MODE_CFG BIT(17)
+#define GPIO36_FLASH_MODE_CFG BIT(16)
+#define GPIO31_FLASH_MODE_CFG BIT(15)
+#define GPIO30_FLASH_MODE_CFG BIT(14)
+#define GPIO29_FLASH_MODE_CFG BIT(13)
+#define GPIO28_FLASH_MODE_CFG BIT(12)
+#define GPIO27_FLASH_MODE_CFG BIT(11)
+#define GPIO26_FLASH_MODE_CFG BIT(10)
+#define GPIO25_FLASH_MODE_CFG BIT(9)
+#define GPIO24_FLASH_MODE_CFG BIT(8)
+#define GPIO23_FLASH_MODE_CFG BIT(7)
+#define GPIO22_FLASH_MODE_CFG BIT(6)
+#define GPIO21_FLASH_MODE_CFG BIT(5)
+#define GPIO20_FLASH_MODE_CFG BIT(4)
+#define GPIO19_FLASH_MODE_CFG BIT(3)
+#define GPIO18_FLASH_MODE_CFG BIT(2)
+#define GPIO17_FLASH_MODE_CFG BIT(1)
+#define GPIO16_FLASH_MODE_CFG BIT(0)
+
+#define AIROHA_PINCTRL_GPIO(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_GPIO_EXT(gpio, mux_val, smux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ 0 \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (smux_val), \
+ (smux_val) \
+ }, \
+ .regmap_size = 2, \
+ }
+
+/* PWM */
+#define AIROHA_PINCTRL_PWM(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_MUX, \
+ REG_GPIO_FLASH_MODE_CFG, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_PWM_EXT(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_PWM_EXT_SEC(gpio, mux_val, smux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (smux_val), \
+ (smux_val) \
+ }, \
+ .regmap_size = 2, \
+ }
+
+#define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_2ND_I2C_MODE, \
+ (mux_val), \
+ (mux_val), \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_LAN_LED0_MAPPING, \
+ (map_mask), \
+ (map_val), \
+ }, \
+ .regmap_size = 2, \
+ }
+
+#define AIROHA_PINCTRL_PHY_LED1(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_2ND_I2C_MODE, \
+ (mux_val), \
+ (mux_val), \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_LAN_LED1_MAPPING, \
+ (map_mask), \
+ (map_val), \
+ }, \
+ .regmap_size = 2, \
+ }
+
+static struct pinctrl_pin_desc pinctrl_pins[] = {
+ PINCTRL_PIN(0, "uart1_txd"),
+ PINCTRL_PIN(1, "uart1_rxd"),
+ PINCTRL_PIN(2, "i2c_scl"),
+ PINCTRL_PIN(3, "i2c_sda"),
+ PINCTRL_PIN(4, "spi_cs0"),
+ PINCTRL_PIN(5, "spi_clk"),
+ PINCTRL_PIN(6, "spi_mosi"),
+ PINCTRL_PIN(7, "spi_miso"),
+ PINCTRL_PIN(13, "gpio0"),
+ PINCTRL_PIN(14, "gpio1"),
+ PINCTRL_PIN(15, "gpio2"),
+ PINCTRL_PIN(16, "gpio3"),
+ PINCTRL_PIN(17, "gpio4"),
+ PINCTRL_PIN(18, "gpio5"),
+ PINCTRL_PIN(19, "gpio6"),
+ PINCTRL_PIN(20, "gpio7"),
+ PINCTRL_PIN(21, "gpio8"),
+ PINCTRL_PIN(22, "gpio9"),
+ PINCTRL_PIN(23, "gpio10"),
+ PINCTRL_PIN(24, "gpio11"),
+ PINCTRL_PIN(25, "gpio12"),
+ PINCTRL_PIN(26, "gpio13"),
+ PINCTRL_PIN(27, "gpio14"),
+ PINCTRL_PIN(28, "gpio15"),
+ PINCTRL_PIN(29, "gpio16"),
+ PINCTRL_PIN(30, "gpio17"),
+ PINCTRL_PIN(31, "gpio18"),
+ PINCTRL_PIN(32, "gpio19"),
+ PINCTRL_PIN(33, "gpio20"),
+ PINCTRL_PIN(34, "gpio21"),
+ PINCTRL_PIN(35, "gpio22"),
+ PINCTRL_PIN(36, "gpio23"),
+ PINCTRL_PIN(37, "gpio24"),
+ PINCTRL_PIN(38, "gpio25"),
+ PINCTRL_PIN(39, "gpio26"),
+ PINCTRL_PIN(40, "gpio27"),
+ PINCTRL_PIN(41, "gpio28"),
+ PINCTRL_PIN(42, "gpio29"),
+ PINCTRL_PIN(43, "gpio30"),
+ PINCTRL_PIN(44, "gpio31"),
+ PINCTRL_PIN(45, "gpio32"),
+ PINCTRL_PIN(46, "gpio33"),
+ PINCTRL_PIN(47, "gpio34"),
+ PINCTRL_PIN(48, "gpio35"),
+ PINCTRL_PIN(49, "gpio36"),
+ PINCTRL_PIN(50, "gpio37"),
+ PINCTRL_PIN(51, "gpio38"),
+ PINCTRL_PIN(52, "gpio39"),
+ PINCTRL_PIN(53, "gpio40"),
+ PINCTRL_PIN(54, "gpio41"),
+ PINCTRL_PIN(55, "gpio42"),
+ PINCTRL_PIN(56, "gpio43"),
+ PINCTRL_PIN(57, "gpio44"),
+ PINCTRL_PIN(58, "gpio45"),
+ PINCTRL_PIN(59, "gpio46"),
+ PINCTRL_PIN(60, "pcie_reset0"),
+ PINCTRL_PIN(61, "pcie_reset1"),
+ PINCTRL_PIN(62, "pcie_reset2"),
+};
+
+static const int pon_pins[] = { 49, 50, 51, 52, 53, 54 };
+static const int pon_tod_1pps_pins[] = { 46 };
+static const int gsw_tod_1pps_pins[] = { 46 };
+static const int sipo_pins[] = { 16, 17 };
+static const int sipo_rclk_pins[] = { 16, 17, 43 };
+static const int mdio_pins[] = { 14, 15 };
+static const int uart2_pins[] = { 48, 55 };
+static const int uart2_cts_rts_pins[] = { 46, 47 };
+static const int hsuart_pins[] = { 28, 29 };
+static const int hsuart_cts_rts_pins[] = { 26, 27 };
+static const int uart4_pins[] = { 38, 39 };
+static const int uart5_pins[] = { 18, 19 };
+static const int i2c0_pins[] = { 2, 3 };
+static const int i2c1_pins[] = { 14, 15 };
+static const int jtag_udi_pins[] = { 16, 17, 18, 19, 20 };
+static const int jtag_dfd_pins[] = { 16, 17, 18, 19, 20 };
+static const int i2s_pins[] = { 26, 27, 28, 29 };
+static const int pcm1_pins[] = { 22, 23, 24, 25 };
+static const int pcm2_pins[] = { 18, 19, 20, 21 };
+static const int spi_quad_pins[] = { 32, 33 };
+static const int spi_pins[] = { 4, 5, 6, 7 };
+static const int spi_cs1_pins[] = { 34 };
+static const int pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 };
+static const int pcm_spi_int_pins[] = { 14 };
+static const int pcm_spi_rst_pins[] = { 15 };
+static const int pcm_spi_cs1_pins[] = { 43 };
+static const int pcm_spi_cs2_pins[] = { 40 };
+static const int pcm_spi_cs2_p128_pins[] = { 40 };
+static const int pcm_spi_cs2_p156_pins[] = { 40 };
+static const int pcm_spi_cs3_pins[] = { 41 };
+static const int pcm_spi_cs4_pins[] = { 42 };
+static const int emmc_pins[] = {
+ 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37
+};
+static const int pnand_pins[] = {
+ 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42
+};
+static const int gpio0_pins[] = { 13 };
+static const int gpio1_pins[] = { 14 };
+static const int gpio2_pins[] = { 15 };
+static const int gpio3_pins[] = { 16 };
+static const int gpio4_pins[] = { 17 };
+static const int gpio5_pins[] = { 18 };
+static const int gpio6_pins[] = { 19 };
+static const int gpio7_pins[] = { 20 };
+static const int gpio8_pins[] = { 21 };
+static const int gpio9_pins[] = { 22 };
+static const int gpio10_pins[] = { 23 };
+static const int gpio11_pins[] = { 24 };
+static const int gpio12_pins[] = { 25 };
+static const int gpio13_pins[] = { 26 };
+static const int gpio14_pins[] = { 27 };
+static const int gpio15_pins[] = { 28 };
+static const int gpio16_pins[] = { 29 };
+static const int gpio17_pins[] = { 30 };
+static const int gpio18_pins[] = { 31 };
+static const int gpio19_pins[] = { 32 };
+static const int gpio20_pins[] = { 33 };
+static const int gpio21_pins[] = { 34 };
+static const int gpio22_pins[] = { 35 };
+static const int gpio23_pins[] = { 36 };
+static const int gpio24_pins[] = { 37 };
+static const int gpio25_pins[] = { 38 };
+static const int gpio26_pins[] = { 39 };
+static const int gpio27_pins[] = { 40 };
+static const int gpio28_pins[] = { 41 };
+static const int gpio29_pins[] = { 42 };
+static const int gpio30_pins[] = { 43 };
+static const int gpio31_pins[] = { 44 };
+static const int gpio32_pins[] = { 45 };
+static const int gpio33_pins[] = { 46 };
+static const int gpio34_pins[] = { 47 };
+static const int gpio35_pins[] = { 48 };
+static const int gpio36_pins[] = { 49 };
+static const int gpio37_pins[] = { 50 };
+static const int gpio38_pins[] = { 51 };
+static const int gpio39_pins[] = { 52 };
+static const int gpio40_pins[] = { 53 };
+static const int gpio41_pins[] = { 54 };
+static const int gpio42_pins[] = { 55 };
+static const int gpio43_pins[] = { 56 };
+static const int gpio44_pins[] = { 57 };
+static const int gpio45_pins[] = { 58 };
+static const int gpio46_pins[] = { 59 };
+static const int gpio47_pins[] = { 60 };
+static const int gpio48_pins[] = { 61 };
+static const int gpio49_pins[] = { 62 };
+static const int pcie_reset0_pins[] = { 60 };
+static const int pcie_reset1_pins[] = { 61 };
+static const int pcie_reset2_pins[] = { 62 };
+
+static const struct pingroup pinctrl_groups[] = {
+ PINCTRL_PIN_GROUP("pon", pon),
+ PINCTRL_PIN_GROUP("pon_tod_1pps", pon_tod_1pps),
+ PINCTRL_PIN_GROUP("gsw_tod_1pps", gsw_tod_1pps),
+ PINCTRL_PIN_GROUP("sipo", sipo),
+ PINCTRL_PIN_GROUP("sipo_rclk", sipo_rclk),
+ PINCTRL_PIN_GROUP("mdio", mdio),
+ PINCTRL_PIN_GROUP("uart2", uart2),
+ PINCTRL_PIN_GROUP("uart2_cts_rts", uart2_cts_rts),
+ PINCTRL_PIN_GROUP("hsuart", hsuart),
+ PINCTRL_PIN_GROUP("hsuart_cts_rts", hsuart_cts_rts),
+ PINCTRL_PIN_GROUP("uart4", uart4),
+ PINCTRL_PIN_GROUP("uart5", uart5),
+ PINCTRL_PIN_GROUP("i2c0", i2c0),
+ PINCTRL_PIN_GROUP("i2c1", i2c1),
+ PINCTRL_PIN_GROUP("jtag_udi", jtag_udi),
+ PINCTRL_PIN_GROUP("jtag_dfd", jtag_dfd),
+ PINCTRL_PIN_GROUP("i2s", i2s),
+ PINCTRL_PIN_GROUP("pcm1", pcm1),
+ PINCTRL_PIN_GROUP("pcm2", pcm2),
+ PINCTRL_PIN_GROUP("spi", spi),
+ PINCTRL_PIN_GROUP("spi_quad", spi_quad),
+ PINCTRL_PIN_GROUP("spi_cs1", spi_cs1),
+ PINCTRL_PIN_GROUP("pcm_spi", pcm_spi),
+ PINCTRL_PIN_GROUP("pcm_spi_int", pcm_spi_int),
+ PINCTRL_PIN_GROUP("pcm_spi_rst", pcm_spi_rst),
+ PINCTRL_PIN_GROUP("pcm_spi_cs1", pcm_spi_cs1),
+ PINCTRL_PIN_GROUP("pcm_spi_cs2_p128", pcm_spi_cs2_p128),
+ PINCTRL_PIN_GROUP("pcm_spi_cs2_p156", pcm_spi_cs2_p156),
+ PINCTRL_PIN_GROUP("pcm_spi_cs2", pcm_spi_cs2),
+ PINCTRL_PIN_GROUP("pcm_spi_cs3", pcm_spi_cs3),
+ PINCTRL_PIN_GROUP("pcm_spi_cs4", pcm_spi_cs4),
+ PINCTRL_PIN_GROUP("emmc", emmc),
+ PINCTRL_PIN_GROUP("pnand", pnand),
+ PINCTRL_PIN_GROUP("gpio0", gpio0),
+ PINCTRL_PIN_GROUP("gpio1", gpio1),
+ PINCTRL_PIN_GROUP("gpio2", gpio2),
+ PINCTRL_PIN_GROUP("gpio3", gpio3),
+ PINCTRL_PIN_GROUP("gpio4", gpio4),
+ PINCTRL_PIN_GROUP("gpio5", gpio5),
+ PINCTRL_PIN_GROUP("gpio6", gpio6),
+ PINCTRL_PIN_GROUP("gpio7", gpio7),
+ PINCTRL_PIN_GROUP("gpio8", gpio8),
+ PINCTRL_PIN_GROUP("gpio9", gpio9),
+ PINCTRL_PIN_GROUP("gpio10", gpio10),
+ PINCTRL_PIN_GROUP("gpio11", gpio11),
+ PINCTRL_PIN_GROUP("gpio12", gpio12),
+ PINCTRL_PIN_GROUP("gpio13", gpio13),
+ PINCTRL_PIN_GROUP("gpio14", gpio14),
+ PINCTRL_PIN_GROUP("gpio15", gpio15),
+ PINCTRL_PIN_GROUP("gpio16", gpio16),
+ PINCTRL_PIN_GROUP("gpio17", gpio17),
+ PINCTRL_PIN_GROUP("gpio18", gpio18),
+ PINCTRL_PIN_GROUP("gpio19", gpio19),
+ PINCTRL_PIN_GROUP("gpio20", gpio20),
+ PINCTRL_PIN_GROUP("gpio21", gpio21),
+ PINCTRL_PIN_GROUP("gpio22", gpio22),
+ PINCTRL_PIN_GROUP("gpio23", gpio23),
+ PINCTRL_PIN_GROUP("gpio24", gpio24),
+ PINCTRL_PIN_GROUP("gpio25", gpio25),
+ PINCTRL_PIN_GROUP("gpio26", gpio26),
+ PINCTRL_PIN_GROUP("gpio27", gpio27),
+ PINCTRL_PIN_GROUP("gpio28", gpio28),
+ PINCTRL_PIN_GROUP("gpio29", gpio29),
+ PINCTRL_PIN_GROUP("gpio30", gpio30),
+ PINCTRL_PIN_GROUP("gpio31", gpio31),
+ PINCTRL_PIN_GROUP("gpio32", gpio32),
+ PINCTRL_PIN_GROUP("gpio33", gpio33),
+ PINCTRL_PIN_GROUP("gpio34", gpio34),
+ PINCTRL_PIN_GROUP("gpio35", gpio35),
+ PINCTRL_PIN_GROUP("gpio36", gpio36),
+ PINCTRL_PIN_GROUP("gpio37", gpio37),
+ PINCTRL_PIN_GROUP("gpio38", gpio38),
+ PINCTRL_PIN_GROUP("gpio39", gpio39),
+ PINCTRL_PIN_GROUP("gpio40", gpio40),
+ PINCTRL_PIN_GROUP("gpio41", gpio41),
+ PINCTRL_PIN_GROUP("gpio42", gpio42),
+ PINCTRL_PIN_GROUP("gpio43", gpio43),
+ PINCTRL_PIN_GROUP("gpio44", gpio44),
+ PINCTRL_PIN_GROUP("gpio45", gpio45),
+ PINCTRL_PIN_GROUP("gpio46", gpio46),
+ PINCTRL_PIN_GROUP("gpio47", gpio47),
+ PINCTRL_PIN_GROUP("gpio48", gpio48),
+ PINCTRL_PIN_GROUP("gpio49", gpio49),
+ PINCTRL_PIN_GROUP("pcie_reset0", pcie_reset0),
+ PINCTRL_PIN_GROUP("pcie_reset1", pcie_reset1),
+ PINCTRL_PIN_GROUP("pcie_reset2", pcie_reset2),
+};
+
+static const char *const pon_groups[] = { "pon" };
+static const char *const tod_1pps_groups[] = {
+ "pon_tod_1pps", "gsw_tod_1pps"
+};
+static const char *const sipo_groups[] = { "sipo", "sipo_rclk" };
+static const char *const mdio_groups[] = { "mdio" };
+static const char *const uart_groups[] = {
+ "uart2", "uart2_cts_rts", "hsuart", "hsuart_cts_rts",
+ "uart4", "uart5"
+};
+static const char *const i2c_groups[] = { "i2c1" };
+static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" };
+static const char *const pcm_groups[] = { "pcm1", "pcm2" };
+static const char *const spi_groups[] = { "spi_quad", "spi_cs1" };
+static const char *const pcm_spi_groups[] = {
+ "pcm_spi", "pcm_spi_int", "pcm_spi_rst", "pcm_spi_cs1",
+ "pcm_spi_cs2_p156", "pcm_spi_cs2_p128", "pcm_spi_cs3",
+ "pcm_spi_cs4"
+};
+static const char *const i2s_groups[] = { "i2s" };
+static const char *const emmc_groups[] = { "emmc" };
+static const char *const pnand_groups[] = { "pnand" };
+static const char *const gpio_groups[] = { "gpio47", "gpio48", "gpio49" };
+static const char *const pcie_reset_groups[] = {
+ "pcie_reset0", "pcie_reset1", "pcie_reset2"
+};
+static const char *const pwm_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
+ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
+ "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17",
+ "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23",
+ "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",
+ "gpio30", "gpio31", "gpio36", "gpio37", "gpio38", "gpio39",
+ "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
+ "gpio46", "gpio47", "gpio48", "gpio49"
+};
+static const char *const phy1_led0_groups[] = {
+ "gpio33", "gpio34", "gpio35", "gpio42"
+};
+static const char *const phy2_led0_groups[] = {
+ "gpio33", "gpio34", "gpio35", "gpio42"
+};
+static const char *const phy3_led0_groups[] = {
+ "gpio33", "gpio34", "gpio35", "gpio42"
+};
+static const char *const phy4_led0_groups[] = {
+ "gpio33", "gpio34", "gpio35", "gpio42"
+};
+static const char *const phy1_led1_groups[] = {
+ "gpio43", "gpio44", "gpio45", "gpio46"
+};
+static const char *const phy2_led1_groups[] = {
+ "gpio43", "gpio44", "gpio45", "gpio46"
+};
+static const char *const phy3_led1_groups[] = {
+ "gpio43", "gpio44", "gpio45", "gpio46"
+};
+static const char *const phy4_led1_groups[] = {
+ "gpio43", "gpio44", "gpio45", "gpio46"
+};
+
+static const struct airoha_pinctrl_func_group pon_func_group[] = {
+ {
+ .name = "pon",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PON_MODE_MASK,
+ GPIO_PON_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = {
+ {
+ .name = "pon_tod_1pps",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ PON_TOD_1PPS_MODE_MASK,
+ PON_TOD_1PPS_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "gsw_tod_1pps",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ GSW_TOD_1PPS_MODE_MASK,
+ GSW_TOD_1PPS_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group sipo_func_group[] = {
+ {
+ .name = "sipo",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+ GPIO_SIPO_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "sipo_rclk",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group mdio_func_group[] = {
+ {
+ .name = "mdio",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ GPIO_MDC_IO_MASTER_MODE_MASK,
+ GPIO_MDC_IO_MASTER_MODE_MASK
+ },
+ .regmap[1] = {
+ AIROHA_FUNC_MUX,
+ REG_FORCE_GPIO_EN,
+ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2),
+ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2)
+ },
+ .regmap_size = 2,
+ },
+};
+
+static const struct airoha_pinctrl_func_group uart_func_group[] = {
+ {
+ .name = "uart2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART2_MODE_MASK,
+ GPIO_UART2_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "uart2_cts_rts",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK,
+ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "hsuart",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
+ GPIO_HSUART_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+ {
+ .name = "hsuart_cts_rts",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "uart4",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART4_MODE_MASK,
+ GPIO_UART4_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "uart5",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART5_MODE_MASK,
+ GPIO_UART5_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group i2c_func_group[] = {
+ {
+ .name = "i2c1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ GPIO_2ND_I2C_MODE_MASK,
+ GPIO_2ND_I2C_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group jtag_func_group[] = {
+ {
+ .name = "jtag_udi",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ JTAG_UDI_EN_MASK,
+ JTAG_UDI_EN_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "jtag_dfd",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ JTAG_DFD_EN_MASK,
+ JTAG_DFD_EN_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pcm_func_group[] = {
+ {
+ .name = "pcm1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM1_MODE_MASK,
+ GPIO_PCM1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM2_MODE_MASK,
+ GPIO_PCM2_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group spi_func_group[] = {
+ {
+ .name = "spi_quad",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_QUAD_MODE_MASK,
+ GPIO_SPI_QUAD_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS1_MODE_MASK,
+ GPIO_SPI_CS1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS2_MODE_MASK,
+ GPIO_SPI_CS2_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs3",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS3_MODE_MASK,
+ GPIO_SPI_CS3_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs4",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS4_MODE_MASK,
+ GPIO_SPI_CS4_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pcm_spi_func_group[] = {
+ {
+ .name = "pcm_spi",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_MODE_MASK,
+ GPIO_PCM_SPI_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_int",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_INT_MODE_MASK,
+ GPIO_PCM_INT_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_rst",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_RESET_MODE_MASK,
+ GPIO_PCM_RESET_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS1_MODE_MASK,
+ GPIO_PCM_SPI_CS1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs2_p128",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS2_MODE_P128_MASK,
+ GPIO_PCM_SPI_CS2_MODE_P128_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs2_p156",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS2_MODE_P156_MASK,
+ GPIO_PCM_SPI_CS2_MODE_P156_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs3",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS3_MODE_MASK,
+ GPIO_PCM_SPI_CS3_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs4",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS4_MODE_MASK,
+ GPIO_PCM_SPI_CS4_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group i2s_func_group[] = {
+ {
+ .name = "i2s",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ GPIO_I2S_MODE_MASK,
+ GPIO_I2S_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group emmc_func_group[] = {
+ {
+ .name = "emmc",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_EMMC_MODE_MASK,
+ GPIO_EMMC_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pnand_func_group[] = {
+ {
+ .name = "pnand",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PARALLEL_NAND_MODE_MASK,
+ GPIO_PARALLEL_NAND_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group gpio_func_group[] = {
+ AIROHA_PINCTRL_GPIO_EXT("gpio47", GPIO47_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET0_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio48", GPIO48_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET1_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio49", GPIO49_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET2_MASK),
+};
+
+static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = {
+ {
+ .name = "pcie_reset0",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PCIE_RESET0_MASK,
+ 0
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcie_reset1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PCIE_RESET1_MASK,
+ 0
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcie_reset2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PCIE_RESET2_MASK,
+ 0
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pwm_func_group[] = {
+ AIROHA_PINCTRL_PWM("gpio0", GPIO0_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio1", GPIO1_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio2", GPIO2_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio3", GPIO3_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio4", GPIO4_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio5", GPIO5_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio6", GPIO6_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio7", GPIO7_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio8", GPIO8_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio9", GPIO9_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio10", GPIO10_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio11", GPIO11_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio12", GPIO12_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio13", GPIO13_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio14", GPIO14_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio15", GPIO15_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio16", GPIO16_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio17", GPIO17_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio18", GPIO18_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio19", GPIO19_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio20", GPIO20_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio21", GPIO21_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio22", GPIO22_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio23", GPIO23_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio24", GPIO24_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio25", GPIO25_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio26", GPIO26_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio27", GPIO27_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio28", GPIO28_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio29", GPIO29_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio30", GPIO30_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio31", GPIO31_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio36", GPIO36_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio37", GPIO37_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio38", GPIO38_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio39", GPIO39_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio40", GPIO40_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio41", GPIO41_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio42", GPIO42_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio43", GPIO43_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio44", GPIO44_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio45", GPIO45_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio46", GPIO46_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio47", GPIO47_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET0_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio48", GPIO48_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET1_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio49", GPIO49_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET2_MASK),
+};
+
+static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+};
+
+static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+};
+
+static const struct airoha_pinctrl_func pinctrl_funcs[] = {
+ PINCTRL_FUNC_DESC("pon", pon),
+ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps),
+ PINCTRL_FUNC_DESC("sipo", sipo),
+ PINCTRL_FUNC_DESC("mdio", mdio),
+ PINCTRL_FUNC_DESC("uart", uart),
+ PINCTRL_FUNC_DESC("i2c", i2c),
+ PINCTRL_FUNC_DESC("jtag", jtag),
+ PINCTRL_FUNC_DESC("pcm", pcm),
+ PINCTRL_FUNC_DESC("spi", spi),
+ PINCTRL_FUNC_DESC("pcm_spi", pcm_spi),
+ PINCTRL_FUNC_DESC("i2s", i2s),
+ PINCTRL_FUNC_DESC("emmc", emmc),
+ PINCTRL_FUNC_DESC("pnand", pnand),
+ PINCTRL_FUNC_DESC("gpio", gpio),
+ PINCTRL_FUNC_DESC("pcie_reset", pcie_reset),
+ PINCTRL_FUNC_DESC("pwm", pwm),
+ PINCTRL_FUNC_DESC("phy1_led0", phy1_led0),
+ PINCTRL_FUNC_DESC("phy2_led0", phy2_led0),
+ PINCTRL_FUNC_DESC("phy3_led0", phy3_led0),
+ PINCTRL_FUNC_DESC("phy4_led0", phy4_led0),
+ PINCTRL_FUNC_DESC("phy1_led1", phy1_led1),
+ PINCTRL_FUNC_DESC("phy2_led1", phy2_led1),
+ PINCTRL_FUNC_DESC("phy3_led1", phy3_led1),
+ PINCTRL_FUNC_DESC("phy4_led1", phy4_led1),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pullup_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_PU, I2C_SDA_PU_MASK),
+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_PU, I2C_SCL_PU_MASK),
+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_PU, SPI_CS0_PU_MASK),
+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_PU, SPI_CLK_PU_MASK),
+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK),
+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_PU, SPI_MISO_PU_MASK),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(0)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(1)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(2)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(3)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(4)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(5)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(6)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(7)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(8)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(9)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(10)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(11)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(12)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(13)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(14)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(15)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(16)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(17)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(18)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(19)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(20)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_PU, BIT(21)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_PU, BIT(22)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_PU, BIT(23)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_PU, BIT(24)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_PU, BIT(25)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_PU, BIT(26)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_PU, BIT(27)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_PU, BIT(28)),
+ PINCTRL_CONF_DESC(42, REG_GPIO_L_PU, BIT(29)),
+ PINCTRL_CONF_DESC(43, REG_GPIO_L_PU, BIT(30)),
+ PINCTRL_CONF_DESC(44, REG_GPIO_L_PU, BIT(31)),
+ PINCTRL_CONF_DESC(45, REG_GPIO_H_PU, BIT(0)),
+ PINCTRL_CONF_DESC(46, REG_GPIO_H_PU, BIT(1)),
+ PINCTRL_CONF_DESC(47, REG_GPIO_H_PU, BIT(2)),
+ PINCTRL_CONF_DESC(48, REG_GPIO_H_PU, BIT(3)),
+ PINCTRL_CONF_DESC(49, REG_GPIO_H_PU, BIT(4)),
+ PINCTRL_CONF_DESC(50, REG_GPIO_H_PU, BIT(5)),
+ PINCTRL_CONF_DESC(51, REG_GPIO_H_PU, BIT(6)),
+ PINCTRL_CONF_DESC(52, REG_GPIO_H_PU, BIT(7)),
+ PINCTRL_CONF_DESC(53, REG_GPIO_H_PU, BIT(8)),
+ PINCTRL_CONF_DESC(54, REG_GPIO_H_PU, BIT(9)),
+ PINCTRL_CONF_DESC(55, REG_GPIO_H_PU, BIT(10)),
+ PINCTRL_CONF_DESC(56, REG_GPIO_H_PU, BIT(11)),
+ PINCTRL_CONF_DESC(57, REG_GPIO_H_PU, BIT(12)),
+ PINCTRL_CONF_DESC(58, REG_GPIO_H_PU, BIT(13)),
+ PINCTRL_CONF_DESC(59, REG_GPIO_H_PU, BIT(14)),
+ PINCTRL_CONF_DESC(60, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK),
+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK),
+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pulldown_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_PD, I2C_SDA_PD_MASK),
+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_PD, I2C_SCL_PD_MASK),
+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_PD, SPI_CS0_PD_MASK),
+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_PD, SPI_CLK_PD_MASK),
+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK),
+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_PD, SPI_MISO_PD_MASK),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(0)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(1)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(2)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(3)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(4)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(5)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(6)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(7)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(8)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(9)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(10)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(11)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(12)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(13)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(14)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(15)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(16)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(17)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(18)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(19)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(20)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_PD, BIT(21)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_PD, BIT(22)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_PD, BIT(23)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_PD, BIT(24)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_PD, BIT(25)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_PD, BIT(26)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_PD, BIT(27)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_PD, BIT(28)),
+ PINCTRL_CONF_DESC(42, REG_GPIO_L_PD, BIT(29)),
+ PINCTRL_CONF_DESC(43, REG_GPIO_L_PD, BIT(30)),
+ PINCTRL_CONF_DESC(44, REG_GPIO_L_PD, BIT(31)),
+ PINCTRL_CONF_DESC(45, REG_GPIO_H_PD, BIT(0)),
+ PINCTRL_CONF_DESC(46, REG_GPIO_H_PD, BIT(1)),
+ PINCTRL_CONF_DESC(47, REG_GPIO_H_PD, BIT(2)),
+ PINCTRL_CONF_DESC(48, REG_GPIO_H_PD, BIT(3)),
+ PINCTRL_CONF_DESC(49, REG_GPIO_H_PD, BIT(4)),
+ PINCTRL_CONF_DESC(50, REG_GPIO_H_PD, BIT(5)),
+ PINCTRL_CONF_DESC(51, REG_GPIO_H_PD, BIT(6)),
+ PINCTRL_CONF_DESC(52, REG_GPIO_H_PD, BIT(7)),
+ PINCTRL_CONF_DESC(53, REG_GPIO_H_PD, BIT(8)),
+ PINCTRL_CONF_DESC(54, REG_GPIO_H_PD, BIT(9)),
+ PINCTRL_CONF_DESC(55, REG_GPIO_H_PD, BIT(10)),
+ PINCTRL_CONF_DESC(56, REG_GPIO_H_PD, BIT(11)),
+ PINCTRL_CONF_DESC(57, REG_GPIO_H_PD, BIT(12)),
+ PINCTRL_CONF_DESC(58, REG_GPIO_H_PD, BIT(13)),
+ PINCTRL_CONF_DESC(59, REG_GPIO_H_PD, BIT(14)),
+ PINCTRL_CONF_DESC(60, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK),
+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK),
+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_drive_e2_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_E2, I2C_SDA_E2_MASK),
+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_E2, I2C_SCL_E2_MASK),
+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_E2, SPI_CS0_E2_MASK),
+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_E2, SPI_CLK_E2_MASK),
+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK),
+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_E2, SPI_MISO_E2_MASK),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(0)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(1)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(2)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(3)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(4)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(5)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(6)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(7)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(8)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(9)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(10)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(11)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(12)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(13)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(14)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(15)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(16)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(17)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(18)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(19)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(20)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_E2, BIT(21)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_E2, BIT(22)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_E2, BIT(23)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_E2, BIT(24)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_E2, BIT(25)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_E2, BIT(26)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_E2, BIT(27)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_E2, BIT(28)),
+ PINCTRL_CONF_DESC(42, REG_GPIO_L_E2, BIT(29)),
+ PINCTRL_CONF_DESC(43, REG_GPIO_L_E2, BIT(30)),
+ PINCTRL_CONF_DESC(44, REG_GPIO_L_E2, BIT(31)),
+ PINCTRL_CONF_DESC(45, REG_GPIO_H_E2, BIT(0)),
+ PINCTRL_CONF_DESC(46, REG_GPIO_H_E2, BIT(1)),
+ PINCTRL_CONF_DESC(47, REG_GPIO_H_E2, BIT(2)),
+ PINCTRL_CONF_DESC(48, REG_GPIO_H_E2, BIT(3)),
+ PINCTRL_CONF_DESC(49, REG_GPIO_H_E2, BIT(4)),
+ PINCTRL_CONF_DESC(50, REG_GPIO_H_E2, BIT(5)),
+ PINCTRL_CONF_DESC(51, REG_GPIO_H_E2, BIT(6)),
+ PINCTRL_CONF_DESC(52, REG_GPIO_H_E2, BIT(7)),
+ PINCTRL_CONF_DESC(53, REG_GPIO_H_E2, BIT(8)),
+ PINCTRL_CONF_DESC(54, REG_GPIO_H_E2, BIT(9)),
+ PINCTRL_CONF_DESC(55, REG_GPIO_H_E2, BIT(10)),
+ PINCTRL_CONF_DESC(56, REG_GPIO_H_E2, BIT(11)),
+ PINCTRL_CONF_DESC(57, REG_GPIO_H_E2, BIT(12)),
+ PINCTRL_CONF_DESC(58, REG_GPIO_H_E2, BIT(13)),
+ PINCTRL_CONF_DESC(59, REG_GPIO_H_E2, BIT(14)),
+ PINCTRL_CONF_DESC(60, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK),
+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK),
+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_drive_e4_conf[] = {
+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK),
+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK),
+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_E4, I2C_SDA_E4_MASK),
+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_E4, I2C_SCL_E4_MASK),
+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_E4, SPI_CS0_E4_MASK),
+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_E4, SPI_CLK_E4_MASK),
+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK),
+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_E4, SPI_MISO_E4_MASK),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(0)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(1)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(2)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(3)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(4)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(5)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(6)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(7)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(8)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(9)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(10)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(11)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(12)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(13)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(14)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(15)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(16)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(17)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(18)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(19)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(20)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_E4, BIT(21)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_E4, BIT(22)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_E4, BIT(23)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_E4, BIT(24)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_E4, BIT(25)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_E4, BIT(26)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_E4, BIT(27)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_E4, BIT(28)),
+ PINCTRL_CONF_DESC(42, REG_GPIO_L_E4, BIT(29)),
+ PINCTRL_CONF_DESC(43, REG_GPIO_L_E4, BIT(30)),
+ PINCTRL_CONF_DESC(44, REG_GPIO_L_E4, BIT(31)),
+ PINCTRL_CONF_DESC(45, REG_GPIO_H_E4, BIT(0)),
+ PINCTRL_CONF_DESC(46, REG_GPIO_H_E4, BIT(1)),
+ PINCTRL_CONF_DESC(47, REG_GPIO_H_E4, BIT(2)),
+ PINCTRL_CONF_DESC(48, REG_GPIO_H_E4, BIT(3)),
+ PINCTRL_CONF_DESC(49, REG_GPIO_H_E4, BIT(4)),
+ PINCTRL_CONF_DESC(50, REG_GPIO_H_E4, BIT(5)),
+ PINCTRL_CONF_DESC(51, REG_GPIO_H_E4, BIT(6)),
+ PINCTRL_CONF_DESC(52, REG_GPIO_H_E4, BIT(7)),
+ PINCTRL_CONF_DESC(53, REG_GPIO_H_E4, BIT(8)),
+ PINCTRL_CONF_DESC(54, REG_GPIO_H_E4, BIT(9)),
+ PINCTRL_CONF_DESC(55, REG_GPIO_H_E4, BIT(10)),
+ PINCTRL_CONF_DESC(56, REG_GPIO_H_E4, BIT(11)),
+ PINCTRL_CONF_DESC(57, REG_GPIO_H_E4, BIT(12)),
+ PINCTRL_CONF_DESC(58, REG_GPIO_H_E4, BIT(13)),
+ PINCTRL_CONF_DESC(59, REG_GPIO_H_E4, BIT(14)),
+ PINCTRL_CONF_DESC(60, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK),
+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK),
+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pcie_rst_od_conf[] = {
+ PINCTRL_CONF_DESC(60, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK),
+ PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK),
+ PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK),
+};
+
+static const struct airoha_pinctrl_match_data pinctrl_match_data = {
+ .gpio_offs = 13,
+ .gpio_pin_cnt = 50,
+ .chip_scu_compatible = "airoha,en7581-chip-scu",
+ .pins = pinctrl_pins,
+ .num_pins = ARRAY_SIZE(pinctrl_pins),
+ .grps = pinctrl_groups,
+ .num_grps = ARRAY_SIZE(pinctrl_groups),
+ .funcs = pinctrl_funcs,
+ .num_funcs = ARRAY_SIZE(pinctrl_funcs),
+ .confs_info = {
+ [AIROHA_PINCTRL_CONFS_PULLUP] = {
+ .confs = pinctrl_pullup_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pullup_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
+ .confs = pinctrl_pulldown_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pulldown_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
+ .confs = pinctrl_drive_e2_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_drive_e2_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
+ .confs = pinctrl_drive_e4_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_drive_e4_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = {
+ .confs = pinctrl_pcie_rst_od_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pcie_rst_od_conf),
+ },
+ },
+};
+
+static const struct udevice_id pinctrl_of_match[] = {
+ { .compatible = "airoha,en7581-pinctrl",
+ .data = (uintptr_t)&pinctrl_match_data },
+ { .compatible = "airoha,an7581-pinctrl",
+ .data = (uintptr_t)&pinctrl_match_data },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(airoha_an7581_pinctrl) = {
+ .name = "airoha-an7581-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = of_match_ptr(pinctrl_of_match),
+ .probe = airoha_pinctrl_probe,
+ .bind = airoha_pinctrl_bind,
+ .priv_auto = sizeof(struct airoha_pinctrl),
+ .ops = &airoha_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/airoha/pinctrl-an7583.c b/drivers/pinctrl/airoha/pinctrl-an7583.c
new file mode 100644
index 00000000000..2f6f3651ec8
--- /dev/null
+++ b/drivers/pinctrl/airoha/pinctrl-an7583.c
@@ -0,0 +1,1492 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Author: Lorenzo Bianconi <[email protected]>
+ * Author: Benjamin Larsson <[email protected]>
+ * Author: Markus Gothe <[email protected]>
+ */
+
+#include "airoha-common.h"
+
+/* MUX */
+#define REG_SW_TOD_1PPS_MODE 0x0214
+#define GPIO_LAN3_LED1_MODE_MASK BIT(10)
+#define GPIO_LAN3_LED0_MODE_MASK BIT(9)
+#define GPIO_LAN2_LED1_MODE_MASK BIT(8)
+#define GPIO_LAN2_LED0_MODE_MASK BIT(7)
+#define GPIO_LAN1_LED1_MODE_MASK BIT(6)
+#define GPIO_LAN1_LED0_MODE_MASK BIT(5)
+#define GPIO_LAN0_LED1_MODE_MASK BIT(4)
+#define GPIO_LAN0_LED0_MODE_MASK BIT(3)
+#define PON_TOD_1PPS_MODE_MASK BIT(2)
+#define GSW_TOD_1PPS_MODE_MASK BIT(1)
+
+#define REG_GPIO_SPI_CS1_MODE 0x0218
+#define GPIO_MDC_IO_MASTER_MODE_MASK BIT(22)
+#define GPIO_PCM_SPI_CS4_MODE_MASK BIT(21)
+#define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20)
+#define GPIO_PCM_SPI_CS2_MODE_MASK BIT(18)
+#define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17)
+#define GPIO_PCM_SPI_MODE_MASK BIT(16)
+#define GPIO_PCM2_MODE_MASK BIT(13)
+#define GPIO_PCM1_MODE_MASK BIT(12)
+#define GPIO_PCM_INT_MODE_MASK BIT(9)
+#define GPIO_PCM_RESET_MODE_MASK BIT(8)
+#define GPIO_SPI_QUAD_MODE_MASK BIT(4)
+#define GPIO_SPI_CS4_MODE_MASK BIT(3)
+#define GPIO_SPI_CS3_MODE_MASK BIT(2)
+#define GPIO_SPI_CS2_MODE_MASK BIT(1)
+#define GPIO_SPI_CS1_MODE_MASK BIT(0)
+
+#define REG_GPIO_PON_MODE 0x021c
+#define GPIO_PON_ALT_MODE_MASK BIT(27)
+#define MDIO_0_GPIO_MODE_MASK BIT(26)
+#define MDC_0_GPIO_MODE_MASK BIT(25)
+#define UART_RXD_GPIO_MODE_MASK BIT(24)
+#define UART_TXD_GPIO_MODE_MASK BIT(23)
+#define SPI_MISO_GPIO_MODE_MASK BIT(22)
+#define SPI_MOSI_GPIO_MODE_MASK BIT(21)
+#define SPI_CS_GPIO_MODE_MASK BIT(20)
+#define SPI_CLK_GPIO_MODE_MASK BIT(19)
+#define I2C1_SDA_GPIO_MODE_MASK BIT(18)
+#define I2C1_SCL_GPIO_MODE_MASK BIT(17)
+#define I2C0_SDA_GPIO_MODE_MASK BIT(16)
+#define I2C0_SCL_GPIO_MODE_MASK BIT(15)
+#define GPIO_PARALLEL_NAND_MODE_MASK BIT(14)
+#define GPIO_SGMII_MDIO_MODE_MASK BIT(13)
+#define GPIO_OLT_MODE_MASK BIT(12)
+#define SIPO_RCLK_MODE_MASK BIT(11)
+#define GPIO_PCIE_RESET1_MASK BIT(10)
+#define GPIO_PCIE_RESET0_MASK BIT(9)
+#define GPIO_UART5_MODE_MASK BIT(8)
+#define GPIO_UART4_MODE_MASK BIT(7)
+#define GPIO_HSUART_CTS_RTS_MODE_MASK BIT(6)
+#define GPIO_HSUART_MODE_MASK BIT(5)
+#define GPIO_UART2_CTS_RTS_MODE_MASK BIT(4)
+#define GPIO_UART2_MODE_MASK BIT(3)
+#define GPIO_SIPO_MODE_MASK BIT(2)
+#define GPIO_EMMC_MODE_MASK BIT(1)
+#define GPIO_PON_MODE_MASK BIT(0)
+
+#define REG_NPU_UART_EN 0x0224
+#define JTAG_UDI_EN_MASK BIT(4)
+#define JTAG_DFD_EN_MASK BIT(3)
+#define NPU_UART_EN_MASK BIT(2)
+
+#define REG_FORCE_GPIO_EN 0x0228
+#define FORCE_GPIO_EN(n) BIT(n)
+
+/* LED MAP */
+#define REG_LAN_LED0_MAPPING 0x027c
+#define REG_LAN_LED1_MAPPING 0x0280
+
+#define LAN4_LED_MAPPING_MASK GENMASK(18, 16)
+#define LAN4_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN4_LED_MAPPING_MASK, (_n))
+
+#define LAN3_LED_MAPPING_MASK GENMASK(14, 12)
+#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n))
+
+#define LAN2_LED_MAPPING_MASK GENMASK(10, 8)
+#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n))
+
+#define LAN1_LED_MAPPING_MASK GENMASK(6, 4)
+#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n))
+
+#define LAN0_LED_MAPPING_MASK GENMASK(2, 0)
+#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n))
+
+/* CONF */
+#define REG_I2C_SDA_E2 0x001c
+#define I2C1_SCL_E2_MASK BIT(16)
+#define I2C1_SDA_E2_MASK BIT(15)
+#define SPI_MISO_E2_MASK BIT(14)
+#define SPI_MOSI_E2_MASK BIT(13)
+#define SPI_CLK_E2_MASK BIT(12)
+#define SPI_CS0_E2_MASK BIT(11)
+#define PCIE1_RESET_E2_MASK BIT(9)
+#define PCIE0_RESET_E2_MASK BIT(8)
+#define MDIO_0_E2_MASK BIT(5)
+#define MDC_0_E2_MASK BIT(4)
+#define UART1_RXD_E2_MASK BIT(3)
+#define UART1_TXD_E2_MASK BIT(2)
+#define I2C_SCL_E2_MASK BIT(1)
+#define I2C_SDA_E2_MASK BIT(0)
+
+#define REG_I2C_SDA_E4 0x0020
+#define I2C1_SCL_E4_MASK BIT(16)
+#define I2C1_SDA_E4_MASK BIT(15)
+#define SPI_MISO_E4_MASK BIT(14)
+#define SPI_MOSI_E4_MASK BIT(13)
+#define SPI_CLK_E4_MASK BIT(12)
+#define SPI_CS0_E4_MASK BIT(11)
+#define PCIE1_RESET_E4_MASK BIT(9)
+#define PCIE0_RESET_E4_MASK BIT(8)
+#define MDIO_0_E4_MASK BIT(5)
+#define MDC_0_E4_MASK BIT(4)
+#define UART1_RXD_E4_MASK BIT(3)
+#define UART1_TXD_E4_MASK BIT(2)
+#define I2C_SCL_E4_MASK BIT(1)
+#define I2C_SDA_E4_MASK BIT(0)
+
+#define REG_GPIO_L_E2 0x0024
+#define REG_GPIO_L_E4 0x0028
+#define REG_GPIO_H_E2 0x002c
+#define REG_GPIO_H_E4 0x0030
+
+#define REG_I2C_SDA_PU 0x0044
+#define I2C1_SCL_PU_MASK BIT(16)
+#define I2C1_SDA_PU_MASK BIT(15)
+#define SPI_MISO_PU_MASK BIT(14)
+#define SPI_MOSI_PU_MASK BIT(13)
+#define SPI_CLK_PU_MASK BIT(12)
+#define SPI_CS0_PU_MASK BIT(11)
+#define PCIE1_RESET_PU_MASK BIT(9)
+#define PCIE0_RESET_PU_MASK BIT(8)
+#define MDIO_0_PU_MASK BIT(5)
+#define MDC_0_PU_MASK BIT(4)
+#define UART1_RXD_PU_MASK BIT(3)
+#define UART1_TXD_PU_MASK BIT(2)
+#define I2C_SCL_PU_MASK BIT(1)
+#define I2C_SDA_PU_MASK BIT(0)
+
+#define REG_I2C_SDA_PD 0x0048
+#define I2C1_SCL_PD_MASK BIT(16)
+#define I2C1_SDA_PD_MASK BIT(15)
+#define SPI_MISO_PD_MASK BIT(14)
+#define SPI_MOSI_PD_MASK BIT(13)
+#define SPI_CLK_PD_MASK BIT(12)
+#define SPI_CS0_PD_MASK BIT(11)
+#define PCIE1_RESET_PD_MASK BIT(9)
+#define PCIE0_RESET_PD_MASK BIT(8)
+#define MDIO_0_PD_MASK BIT(5)
+#define MDC_0_PD_MASK BIT(4)
+#define UART1_RXD_PD_MASK BIT(3)
+#define UART1_TXD_PD_MASK BIT(2)
+#define I2C_SCL_PD_MASK BIT(1)
+#define I2C_SDA_PD_MASK BIT(0)
+
+#define REG_GPIO_L_PU 0x004c
+#define REG_GPIO_L_PD 0x0050
+#define REG_GPIO_H_PU 0x0054
+#define REG_GPIO_H_PD 0x0058
+
+#define REG_PCIE_RESET_OD 0x018c
+#define PCIE1_RESET_OD_MASK BIT(1)
+#define PCIE0_RESET_OD_MASK BIT(0)
+
+/* PWM MODE CONF */
+#define REG_GPIO_FLASH_MODE_CFG 0x0034
+#define GPIO15_FLASH_MODE_CFG BIT(15)
+#define GPIO14_FLASH_MODE_CFG BIT(14)
+#define GPIO13_FLASH_MODE_CFG BIT(13)
+#define GPIO12_FLASH_MODE_CFG BIT(12)
+#define GPIO11_FLASH_MODE_CFG BIT(11)
+#define GPIO10_FLASH_MODE_CFG BIT(10)
+#define GPIO9_FLASH_MODE_CFG BIT(9)
+#define GPIO8_FLASH_MODE_CFG BIT(8)
+#define GPIO7_FLASH_MODE_CFG BIT(7)
+#define GPIO6_FLASH_MODE_CFG BIT(6)
+#define GPIO5_FLASH_MODE_CFG BIT(5)
+#define GPIO4_FLASH_MODE_CFG BIT(4)
+#define GPIO3_FLASH_MODE_CFG BIT(3)
+#define GPIO2_FLASH_MODE_CFG BIT(2)
+#define GPIO1_FLASH_MODE_CFG BIT(1)
+#define GPIO0_FLASH_MODE_CFG BIT(0)
+
+/* PWM MODE CONF EXT */
+#define REG_GPIO_FLASH_MODE_CFG_EXT 0x0068
+#define GPIO51_FLASH_MODE_CFG BIT(31)
+#define GPIO50_FLASH_MODE_CFG BIT(30)
+#define GPIO49_FLASH_MODE_CFG BIT(29)
+#define GPIO48_FLASH_MODE_CFG BIT(28)
+#define GPIO47_FLASH_MODE_CFG BIT(27)
+#define GPIO46_FLASH_MODE_CFG BIT(26)
+#define GPIO45_FLASH_MODE_CFG BIT(25)
+#define GPIO44_FLASH_MODE_CFG BIT(24)
+#define GPIO43_FLASH_MODE_CFG BIT(23)
+#define GPIO42_FLASH_MODE_CFG BIT(22)
+#define GPIO41_FLASH_MODE_CFG BIT(21)
+#define GPIO40_FLASH_MODE_CFG BIT(20)
+#define GPIO39_FLASH_MODE_CFG BIT(19)
+#define GPIO38_FLASH_MODE_CFG BIT(18)
+#define GPIO37_FLASH_MODE_CFG BIT(17)
+#define GPIO36_FLASH_MODE_CFG BIT(16)
+#define GPIO31_FLASH_MODE_CFG BIT(15)
+#define GPIO30_FLASH_MODE_CFG BIT(14)
+#define GPIO29_FLASH_MODE_CFG BIT(13)
+#define GPIO28_FLASH_MODE_CFG BIT(12)
+#define GPIO27_FLASH_MODE_CFG BIT(11)
+#define GPIO26_FLASH_MODE_CFG BIT(10)
+#define GPIO25_FLASH_MODE_CFG BIT(9)
+#define GPIO24_FLASH_MODE_CFG BIT(8)
+#define GPIO23_FLASH_MODE_CFG BIT(7)
+#define GPIO22_FLASH_MODE_CFG BIT(6)
+#define GPIO21_FLASH_MODE_CFG BIT(5)
+#define GPIO20_FLASH_MODE_CFG BIT(4)
+#define GPIO19_FLASH_MODE_CFG BIT(3)
+#define GPIO18_FLASH_MODE_CFG BIT(2)
+#define GPIO17_FLASH_MODE_CFG BIT(1)
+#define GPIO16_FLASH_MODE_CFG BIT(0)
+
+#define AIROHA_PINCTRL_GPIO(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_GPIO_EXT(gpio, mux_val, smux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ 0 \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (smux_val), \
+ (smux_val) \
+ }, \
+ .regmap_size = 2, \
+ }
+
+/* PWM */
+#define AIROHA_PINCTRL_PWM(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_MUX, \
+ REG_GPIO_FLASH_MODE_CFG, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_PWM_EXT(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_PWM_EXT_SEC(gpio, mux_val, smux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (smux_val), \
+ (smux_val) \
+ }, \
+ .regmap_size = 2, \
+ }
+
+#define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_SW_TOD_1PPS_MODE, \
+ (mux_val), \
+ (mux_val), \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_LAN_LED0_MAPPING, \
+ (map_mask), \
+ (map_val), \
+ }, \
+ .regmap_size = 2, \
+ }
+
+#define AIROHA_PINCTRL_PHY_LED1(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_SW_TOD_1PPS_MODE, \
+ (mux_val), \
+ (mux_val), \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_LAN_LED1_MAPPING, \
+ (map_mask), \
+ (map_val), \
+ }, \
+ .regmap_size = 2, \
+ }
+
+static struct pinctrl_pin_desc pinctrl_pins[] = {
+ PINCTRL_PIN(2, "gpio0"),
+ PINCTRL_PIN(3, "gpio1"),
+ PINCTRL_PIN(4, "gpio2"),
+ PINCTRL_PIN(5, "gpio3"),
+ PINCTRL_PIN(6, "gpio4"),
+ PINCTRL_PIN(7, "gpio5"),
+ PINCTRL_PIN(8, "gpio6"),
+ PINCTRL_PIN(9, "gpio7"),
+ PINCTRL_PIN(10, "gpio8"),
+ PINCTRL_PIN(11, "gpio9"),
+ PINCTRL_PIN(12, "gpio10"),
+ PINCTRL_PIN(13, "gpio11"),
+ PINCTRL_PIN(14, "gpio12"),
+ PINCTRL_PIN(15, "gpio13"),
+ PINCTRL_PIN(16, "gpio14"),
+ PINCTRL_PIN(17, "gpio15"),
+ PINCTRL_PIN(18, "gpio16"),
+ PINCTRL_PIN(19, "gpio17"),
+ PINCTRL_PIN(20, "gpio18"),
+ PINCTRL_PIN(21, "gpio19"),
+ PINCTRL_PIN(22, "gpio20"),
+ PINCTRL_PIN(23, "gpio21"),
+ PINCTRL_PIN(24, "gpio22"),
+ PINCTRL_PIN(25, "gpio23"),
+ PINCTRL_PIN(26, "gpio24"),
+ PINCTRL_PIN(27, "gpio25"),
+ PINCTRL_PIN(28, "gpio26"),
+ PINCTRL_PIN(29, "gpio27"),
+ PINCTRL_PIN(30, "gpio28"),
+ PINCTRL_PIN(31, "gpio29"),
+ PINCTRL_PIN(32, "gpio30"),
+ PINCTRL_PIN(33, "gpio31"),
+ PINCTRL_PIN(34, "gpio32"),
+ PINCTRL_PIN(35, "gpio33"),
+ PINCTRL_PIN(36, "gpio34"),
+ PINCTRL_PIN(37, "gpio35"),
+ PINCTRL_PIN(38, "gpio36"),
+ PINCTRL_PIN(39, "gpio37"),
+ PINCTRL_PIN(40, "gpio38"),
+ PINCTRL_PIN(41, "i2c0_scl"),
+ PINCTRL_PIN(42, "i2c0_sda"),
+ PINCTRL_PIN(43, "i2c1_scl"),
+ PINCTRL_PIN(44, "i2c1_sda"),
+ PINCTRL_PIN(45, "spi_clk"),
+ PINCTRL_PIN(46, "spi_cs"),
+ PINCTRL_PIN(47, "spi_mosi"),
+ PINCTRL_PIN(48, "spi_miso"),
+ PINCTRL_PIN(49, "uart_txd"),
+ PINCTRL_PIN(50, "uart_rxd"),
+ PINCTRL_PIN(51, "pcie_reset0"),
+ PINCTRL_PIN(52, "pcie_reset1"),
+ PINCTRL_PIN(53, "mdc_0"),
+ PINCTRL_PIN(54, "mdio_0"),
+};
+
+static const int pon_pins[] = { 15, 16, 17, 18, 19, 20 };
+static const int pon_alt_pins[] = { 36, 37, 38, 39, 40 };
+static const int olt_pins[] = { 36, 37, 38, 39, 40 };
+static const int pon_tod_1pps_pins[] = { 32 };
+static const int gsw_tod_1pps_pins[] = { 32 };
+static const int sipo_pins[] = { 34, 35 };
+static const int sipo_rclk_pins[] = { 34, 35, 33 };
+static const int mdio_pins[] = { 43, 44 };
+static const int uart2_pins[] = { 34, 35 };
+static const int uart2_cts_rts_pins[] = { 32, 33 };
+static const int hsuart_pins[] = { 30, 31 };
+static const int hsuart_cts_rts_pins[] = { 28, 29 };
+static const int npu_uart_pins[] = { 7, 8 };
+static const int uart4_pins[] = { 7, 8 };
+static const int uart5_pins[] = { 23, 24 };
+static const int i2c0_pins[] = { 41, 42 };
+static const int i2c1_pins[] = { 43, 44 };
+static const int jtag_udi_pins[] = { 23, 24, 22, 25, 26 };
+static const int jtag_dfd_pins[] = { 23, 24, 22, 25, 26 };
+static const int pcm1_pins[] = { 10, 11, 12, 13, 14 };
+static const int pcm2_pins[] = { 28, 29, 30, 31, 24 };
+static const int spi_pins[] = { 28, 29, 30, 31 };
+static const int spi_quad_pins[] = { 25, 26 };
+static const int spi_cs1_pins[] = { 27 };
+static const int pcm_spi_pins[] = { 28, 29, 30, 31, 10, 11, 12, 13 };
+static const int pcm_spi_rst_pins[] = { 14 };
+static const int pcm_spi_cs1_pins[] = { 24 };
+static const int emmc_pins[] = {
+ 7, 8, 9, 22, 23, 24, 25, 26, 45, 46, 47
+};
+static const int pnand_pins[] = {
+ 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 45, 46, 47, 48
+};
+static const int gpio0_pins[] = { 2 };
+static const int gpio1_pins[] = { 3 };
+static const int gpio2_pins[] = { 4 };
+static const int gpio3_pins[] = { 5 };
+static const int gpio4_pins[] = { 6 };
+static const int gpio5_pins[] = { 7 };
+static const int gpio6_pins[] = { 8 };
+static const int gpio7_pins[] = { 9 };
+static const int gpio8_pins[] = { 10 };
+static const int gpio9_pins[] = { 11 };
+static const int gpio10_pins[] = { 12 };
+static const int gpio11_pins[] = { 13 };
+static const int gpio12_pins[] = { 14 };
+static const int gpio13_pins[] = { 15 };
+static const int gpio14_pins[] = { 16 };
+static const int gpio15_pins[] = { 17 };
+static const int gpio16_pins[] = { 18 };
+static const int gpio17_pins[] = { 19 };
+static const int gpio18_pins[] = { 20 };
+static const int gpio19_pins[] = { 21 };
+static const int gpio20_pins[] = { 22 };
+static const int gpio21_pins[] = { 23 };
+static const int gpio22_pins[] = { 24 };
+static const int gpio23_pins[] = { 25 };
+static const int gpio24_pins[] = { 26 };
+static const int gpio25_pins[] = { 27 };
+static const int gpio26_pins[] = { 28 };
+static const int gpio27_pins[] = { 29 };
+static const int gpio28_pins[] = { 30 };
+static const int gpio29_pins[] = { 31 };
+static const int gpio30_pins[] = { 32 };
+static const int gpio31_pins[] = { 33 };
+static const int gpio32_pins[] = { 34 };
+static const int gpio33_pins[] = { 35 };
+static const int gpio34_pins[] = { 36 };
+static const int gpio35_pins[] = { 37 };
+static const int gpio36_pins[] = { 38 };
+static const int gpio37_pins[] = { 39 };
+static const int gpio38_pins[] = { 40 };
+static const int gpio39_pins[] = { 41 };
+static const int gpio40_pins[] = { 42 };
+static const int gpio41_pins[] = { 43 };
+static const int gpio42_pins[] = { 44 };
+static const int gpio43_pins[] = { 45 };
+static const int gpio44_pins[] = { 46 };
+static const int gpio45_pins[] = { 47 };
+static const int gpio46_pins[] = { 48 };
+static const int gpio47_pins[] = { 49 };
+static const int gpio48_pins[] = { 50 };
+static const int gpio49_pins[] = { 51 };
+static const int gpio50_pins[] = { 52 };
+static const int gpio51_pins[] = { 53 };
+static const int gpio52_pins[] = { 54 };
+static const int pcie_reset0_pins[] = { 51 };
+static const int pcie_reset1_pins[] = { 52 };
+
+static const struct pingroup pinctrl_groups[] = {
+ PINCTRL_PIN_GROUP("pon", pon),
+ PINCTRL_PIN_GROUP("pon_alt", pon_alt),
+ PINCTRL_PIN_GROUP("olt", olt),
+ PINCTRL_PIN_GROUP("pon_tod_1pps", pon_tod_1pps),
+ PINCTRL_PIN_GROUP("gsw_tod_1pps", gsw_tod_1pps),
+ PINCTRL_PIN_GROUP("sipo", sipo),
+ PINCTRL_PIN_GROUP("sipo_rclk", sipo_rclk),
+ PINCTRL_PIN_GROUP("mdio", mdio),
+ PINCTRL_PIN_GROUP("uart2", uart2),
+ PINCTRL_PIN_GROUP("uart2_cts_rts", uart2_cts_rts),
+ PINCTRL_PIN_GROUP("hsuart", hsuart),
+ PINCTRL_PIN_GROUP("hsuart_cts_rts", hsuart_cts_rts),
+ PINCTRL_PIN_GROUP("npu_uart", npu_uart),
+ PINCTRL_PIN_GROUP("uart4", uart4),
+ PINCTRL_PIN_GROUP("uart5", uart5),
+ PINCTRL_PIN_GROUP("i2c0", i2c0),
+ PINCTRL_PIN_GROUP("i2c1", i2c1),
+ PINCTRL_PIN_GROUP("jtag_udi", jtag_udi),
+ PINCTRL_PIN_GROUP("jtag_dfd", jtag_dfd),
+ PINCTRL_PIN_GROUP("pcm1", pcm1),
+ PINCTRL_PIN_GROUP("pcm2", pcm2),
+ PINCTRL_PIN_GROUP("spi", spi),
+ PINCTRL_PIN_GROUP("spi_quad", spi_quad),
+ PINCTRL_PIN_GROUP("spi_cs1", spi_cs1),
+ PINCTRL_PIN_GROUP("pcm_spi", pcm_spi),
+ PINCTRL_PIN_GROUP("pcm_spi_rst", pcm_spi_rst),
+ PINCTRL_PIN_GROUP("pcm_spi_cs1", pcm_spi_cs1),
+ PINCTRL_PIN_GROUP("emmc", emmc),
+ PINCTRL_PIN_GROUP("pnand", pnand),
+ PINCTRL_PIN_GROUP("gpio0", gpio0),
+ PINCTRL_PIN_GROUP("gpio1", gpio1),
+ PINCTRL_PIN_GROUP("gpio2", gpio2),
+ PINCTRL_PIN_GROUP("gpio3", gpio3),
+ PINCTRL_PIN_GROUP("gpio4", gpio4),
+ PINCTRL_PIN_GROUP("gpio5", gpio5),
+ PINCTRL_PIN_GROUP("gpio6", gpio6),
+ PINCTRL_PIN_GROUP("gpio7", gpio7),
+ PINCTRL_PIN_GROUP("gpio8", gpio8),
+ PINCTRL_PIN_GROUP("gpio9", gpio9),
+ PINCTRL_PIN_GROUP("gpio10", gpio10),
+ PINCTRL_PIN_GROUP("gpio11", gpio11),
+ PINCTRL_PIN_GROUP("gpio12", gpio12),
+ PINCTRL_PIN_GROUP("gpio13", gpio13),
+ PINCTRL_PIN_GROUP("gpio14", gpio14),
+ PINCTRL_PIN_GROUP("gpio15", gpio15),
+ PINCTRL_PIN_GROUP("gpio16", gpio16),
+ PINCTRL_PIN_GROUP("gpio17", gpio17),
+ PINCTRL_PIN_GROUP("gpio18", gpio18),
+ PINCTRL_PIN_GROUP("gpio19", gpio19),
+ PINCTRL_PIN_GROUP("gpio20", gpio20),
+ PINCTRL_PIN_GROUP("gpio21", gpio21),
+ PINCTRL_PIN_GROUP("gpio22", gpio22),
+ PINCTRL_PIN_GROUP("gpio23", gpio23),
+ PINCTRL_PIN_GROUP("gpio24", gpio24),
+ PINCTRL_PIN_GROUP("gpio25", gpio25),
+ PINCTRL_PIN_GROUP("gpio26", gpio26),
+ PINCTRL_PIN_GROUP("gpio27", gpio27),
+ PINCTRL_PIN_GROUP("gpio28", gpio28),
+ PINCTRL_PIN_GROUP("gpio29", gpio29),
+ PINCTRL_PIN_GROUP("gpio30", gpio30),
+ PINCTRL_PIN_GROUP("gpio31", gpio31),
+ PINCTRL_PIN_GROUP("gpio32", gpio32),
+ PINCTRL_PIN_GROUP("gpio33", gpio33),
+ PINCTRL_PIN_GROUP("gpio34", gpio34),
+ PINCTRL_PIN_GROUP("gpio35", gpio35),
+ PINCTRL_PIN_GROUP("gpio36", gpio36),
+ PINCTRL_PIN_GROUP("gpio37", gpio37),
+ PINCTRL_PIN_GROUP("gpio38", gpio38),
+ PINCTRL_PIN_GROUP("gpio39", gpio39),
+ PINCTRL_PIN_GROUP("gpio40", gpio40),
+ PINCTRL_PIN_GROUP("gpio41", gpio41),
+ PINCTRL_PIN_GROUP("gpio42", gpio42),
+ PINCTRL_PIN_GROUP("gpio43", gpio43),
+ PINCTRL_PIN_GROUP("gpio44", gpio44),
+ PINCTRL_PIN_GROUP("gpio45", gpio45),
+ PINCTRL_PIN_GROUP("gpio46", gpio46),
+ PINCTRL_PIN_GROUP("gpio47", gpio47),
+ PINCTRL_PIN_GROUP("gpio48", gpio48),
+ PINCTRL_PIN_GROUP("gpio49", gpio49),
+ PINCTRL_PIN_GROUP("gpio50", gpio50),
+ PINCTRL_PIN_GROUP("gpio51", gpio51),
+ PINCTRL_PIN_GROUP("gpio52", gpio52),
+ PINCTRL_PIN_GROUP("pcie_reset0", pcie_reset0),
+ PINCTRL_PIN_GROUP("pcie_reset1", pcie_reset1),
+};
+
+static const char *const pon_groups[] = { "pon", "pon_alt" };
+static const char *const olt_groups[] = { "olt" };
+static const char *const tod_1pps_groups[] = {
+ "pon_tod_1pps", "gsw_tod_1pps"
+};
+static const char *const sipo_groups[] = { "sipo", "sipo_rclk" };
+static const char *const mdio_groups[] = { "mdio" };
+static const char *const uart_groups[] = {
+ "uart2", "uart2_cts_rts", "hsuart", "hsuart_cts_rts",
+ "uart4", "uart5", "npu_uart"
+};
+static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" };
+static const char *const pcm_groups[] = { "pcm1", "pcm2" };
+static const char *const spi_groups[] = { "spi_quad", "spi_cs1" };
+static const char *const pcm_spi_groups[] = {
+ "pcm_spi", "pcm_spi_rst", "pcm_spi_cs1"
+};
+static const char *const emmc_groups[] = { "emmc" };
+static const char *const pnand_groups[] = { "pnand" };
+static const char *const gpio_groups[] = {
+ "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
+ "gpio44", "gpio45", "gpio46", "gpio47", "gpio48",
+ "gpio49", "gpio50", "gpio51", "gpio52"
+};
+static const char *const pcie_reset_groups[] = {
+ "pcie_reset0", "pcie_reset1"
+};
+static const char *const pwm_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
+ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
+ "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17",
+ "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23",
+ "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",
+ "gpio30", "gpio31", "gpio36", "gpio37", "gpio38", "gpio39",
+ "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
+ "gpio46", "gpio47", "gpio48", "gpio49", "gpio50", "gpio51"
+};
+static const char *const phy1_led0_groups[] = {
+ "gpio1", "gpio2", "gpio3", "gpio4"
+};
+static const char *const phy2_led0_groups[] = {
+ "gpio1", "gpio2", "gpio3", "gpio4"
+};
+static const char *const phy3_led0_groups[] = {
+ "gpio1", "gpio2", "gpio3", "gpio4"
+};
+static const char *const phy4_led0_groups[] = {
+ "gpio1", "gpio2", "gpio3", "gpio4"
+};
+static const char *const phy1_led1_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio11"
+};
+static const char *const phy2_led1_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio11"
+};
+static const char *const phy3_led1_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio11"
+};
+static const char *const phy4_led1_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio11"
+};
+
+static const struct airoha_pinctrl_func_group pon_func_group[] = {
+ {
+ .name = "pon",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PON_MODE_MASK | GPIO_PON_ALT_MODE_MASK,
+ GPIO_PON_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pon_alt",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PON_MODE_MASK | GPIO_PON_ALT_MODE_MASK,
+ GPIO_PON_ALT_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group olt_func_group[] = {
+ {
+ .name = "olt",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_OLT_MODE_MASK,
+ GPIO_OLT_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = {
+ {
+ .name = "pon_tod_1pps",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_SW_TOD_1PPS_MODE,
+ PON_TOD_1PPS_MODE_MASK,
+ PON_TOD_1PPS_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "gsw_tod_1pps",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_SW_TOD_1PPS_MODE,
+ GSW_TOD_1PPS_MODE_MASK,
+ GSW_TOD_1PPS_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group sipo_func_group[] = {
+ {
+ .name = "sipo",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+ GPIO_SIPO_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "sipo_rclk",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group mdio_func_group[] = {
+ {
+ .name = "mdio",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SGMII_MDIO_MODE_MASK,
+ GPIO_SGMII_MDIO_MODE_MASK
+ },
+ .regmap[1] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_MDC_IO_MASTER_MODE_MASK,
+ GPIO_MDC_IO_MASTER_MODE_MASK
+ },
+ .regmap_size = 2,
+ },
+};
+
+static const struct airoha_pinctrl_func_group uart_func_group[] = {
+ {
+ .name = "uart2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART2_MODE_MASK,
+ GPIO_UART2_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "uart2_cts_rts",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK,
+ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "hsuart",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
+ GPIO_HSUART_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+ {
+ .name = "hsuart_cts_rts",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK,
+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "uart4",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART4_MODE_MASK,
+ GPIO_UART4_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "uart5",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART5_MODE_MASK,
+ GPIO_UART5_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "npu_uart",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ NPU_UART_EN_MASK,
+ NPU_UART_EN_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group jtag_func_group[] = {
+ {
+ .name = "jtag_udi",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ JTAG_UDI_EN_MASK,
+ JTAG_UDI_EN_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "jtag_dfd",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ JTAG_DFD_EN_MASK,
+ JTAG_DFD_EN_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pcm_func_group[] = {
+ {
+ .name = "pcm1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM1_MODE_MASK,
+ GPIO_PCM1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM2_MODE_MASK,
+ GPIO_PCM2_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group spi_func_group[] = {
+ {
+ .name = "spi_quad",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_QUAD_MODE_MASK,
+ GPIO_SPI_QUAD_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS1_MODE_MASK,
+ GPIO_SPI_CS1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS2_MODE_MASK,
+ GPIO_SPI_CS2_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs3",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS3_MODE_MASK,
+ GPIO_SPI_CS3_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs4",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS4_MODE_MASK,
+ GPIO_SPI_CS4_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pcm_spi_func_group[] = {
+ {
+ .name = "pcm_spi",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_MODE_MASK,
+ GPIO_PCM_SPI_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_int",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_INT_MODE_MASK,
+ GPIO_PCM_INT_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_rst",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_RESET_MODE_MASK,
+ GPIO_PCM_RESET_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS1_MODE_MASK,
+ GPIO_PCM_SPI_CS1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS2_MODE_MASK,
+ GPIO_PCM_SPI_CS2_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs3",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS3_MODE_MASK,
+ GPIO_PCM_SPI_CS3_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs4",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS4_MODE_MASK,
+ GPIO_PCM_SPI_CS4_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group emmc_func_group[] = {
+ {
+ .name = "emmc",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_EMMC_MODE_MASK,
+ GPIO_EMMC_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pnand_func_group[] = {
+ {
+ .name = "pnand",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PARALLEL_NAND_MODE_MASK,
+ GPIO_PARALLEL_NAND_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group gpio_func_group[] = {
+ AIROHA_PINCTRL_GPIO_EXT("gpio39", GPIO39_FLASH_MODE_CFG,
+ I2C0_SCL_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio40", GPIO40_FLASH_MODE_CFG,
+ I2C0_SDA_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio41", GPIO41_FLASH_MODE_CFG,
+ I2C1_SCL_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio42", GPIO42_FLASH_MODE_CFG,
+ I2C1_SDA_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio43", GPIO43_FLASH_MODE_CFG,
+ SPI_CLK_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio44", GPIO44_FLASH_MODE_CFG,
+ SPI_CS_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio45", GPIO45_FLASH_MODE_CFG,
+ SPI_MOSI_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio46", GPIO46_FLASH_MODE_CFG,
+ SPI_MISO_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio47", GPIO47_FLASH_MODE_CFG,
+ UART_TXD_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio48", GPIO48_FLASH_MODE_CFG,
+ UART_RXD_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio49", GPIO49_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET0_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio50", GPIO50_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET1_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio51", GPIO51_FLASH_MODE_CFG,
+ MDC_0_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_GPIO("gpio52", MDIO_0_GPIO_MODE_MASK),
+};
+
+static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = {
+ {
+ .name = "pcie_reset0",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PCIE_RESET0_MASK,
+ 0
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcie_reset1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PCIE_RESET1_MASK,
+ 0
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pwm_func_group[] = {
+ AIROHA_PINCTRL_PWM("gpio0", GPIO0_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio1", GPIO1_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio2", GPIO2_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio3", GPIO3_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio4", GPIO4_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio5", GPIO5_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio6", GPIO6_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio7", GPIO7_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio8", GPIO8_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio9", GPIO9_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio10", GPIO10_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio11", GPIO11_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio12", GPIO12_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio13", GPIO13_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio14", GPIO14_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio15", GPIO15_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio16", GPIO16_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio17", GPIO17_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio18", GPIO18_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio19", GPIO19_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio20", GPIO20_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio21", GPIO21_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio22", GPIO22_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio23", GPIO23_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio24", GPIO24_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio25", GPIO25_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio26", GPIO26_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio27", GPIO27_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio28", GPIO28_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio29", GPIO29_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio30", GPIO30_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio31", GPIO31_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio36", GPIO36_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio37", GPIO37_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio38", GPIO38_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio39", GPIO39_FLASH_MODE_CFG,
+ I2C0_SCL_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio40", GPIO40_FLASH_MODE_CFG,
+ I2C0_SDA_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio41", GPIO41_FLASH_MODE_CFG,
+ I2C1_SCL_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio42", GPIO42_FLASH_MODE_CFG,
+ I2C1_SDA_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio43", GPIO43_FLASH_MODE_CFG,
+ SPI_CLK_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio44", GPIO44_FLASH_MODE_CFG,
+ SPI_CS_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio45", GPIO45_FLASH_MODE_CFG,
+ SPI_MOSI_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio46", GPIO46_FLASH_MODE_CFG,
+ SPI_MISO_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio47", GPIO47_FLASH_MODE_CFG,
+ UART_TXD_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio48", GPIO48_FLASH_MODE_CFG,
+ UART_RXD_GPIO_MODE_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio49", GPIO49_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET0_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio50", GPIO50_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET1_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio51", GPIO51_FLASH_MODE_CFG,
+ MDC_0_GPIO_MODE_MASK),
+};
+
+static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+};
+
+static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+};
+
+static const struct airoha_pinctrl_func pinctrl_funcs[] = {
+ PINCTRL_FUNC_DESC("pon", pon),
+ PINCTRL_FUNC_DESC("olt", olt),
+ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps),
+ PINCTRL_FUNC_DESC("sipo", sipo),
+ PINCTRL_FUNC_DESC("mdio", mdio),
+ PINCTRL_FUNC_DESC("uart", uart),
+ PINCTRL_FUNC_DESC("jtag", jtag),
+ PINCTRL_FUNC_DESC("pcm", pcm),
+ PINCTRL_FUNC_DESC("spi", spi),
+ PINCTRL_FUNC_DESC("pcm_spi", pcm_spi),
+ PINCTRL_FUNC_DESC("emmc", emmc),
+ PINCTRL_FUNC_DESC("pnand", pnand),
+ PINCTRL_FUNC_DESC("gpio", gpio),
+ PINCTRL_FUNC_DESC("pcie_reset", pcie_reset),
+ PINCTRL_FUNC_DESC("pwm", pwm),
+ PINCTRL_FUNC_DESC("phy1_led0", phy1_led0),
+ PINCTRL_FUNC_DESC("phy2_led0", phy2_led0),
+ PINCTRL_FUNC_DESC("phy3_led0", phy3_led0),
+ PINCTRL_FUNC_DESC("phy4_led0", phy4_led0),
+ PINCTRL_FUNC_DESC("phy1_led1", phy1_led1),
+ PINCTRL_FUNC_DESC("phy2_led1", phy2_led1),
+ PINCTRL_FUNC_DESC("phy3_led1", phy3_led1),
+ PINCTRL_FUNC_DESC("phy4_led1", phy4_led1),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pullup_conf[] = {
+ PINCTRL_CONF_DESC(2, REG_GPIO_L_PU, BIT(0)),
+ PINCTRL_CONF_DESC(3, REG_GPIO_L_PU, BIT(1)),
+ PINCTRL_CONF_DESC(4, REG_GPIO_L_PU, BIT(2)),
+ PINCTRL_CONF_DESC(5, REG_GPIO_L_PU, BIT(3)),
+ PINCTRL_CONF_DESC(6, REG_GPIO_L_PU, BIT(4)),
+ PINCTRL_CONF_DESC(7, REG_GPIO_L_PU, BIT(5)),
+ PINCTRL_CONF_DESC(8, REG_GPIO_L_PU, BIT(6)),
+ PINCTRL_CONF_DESC(9, REG_GPIO_L_PU, BIT(7)),
+ PINCTRL_CONF_DESC(10, REG_GPIO_L_PU, BIT(8)),
+ PINCTRL_CONF_DESC(11, REG_GPIO_L_PU, BIT(9)),
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_PU, BIT(10)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(11)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(12)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(13)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(14)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(15)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(16)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(17)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(18)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(19)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(20)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(21)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(22)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(23)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(24)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(25)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(26)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(27)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(28)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(29)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(30)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(31)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_H_PU, BIT(0)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_H_PU, BIT(1)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_H_PU, BIT(2)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_H_PU, BIT(3)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_H_PU, BIT(4)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_H_PU, BIT(5)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_H_PU, BIT(6)),
+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PU, I2C_SCL_PU_MASK),
+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PU, I2C_SDA_PU_MASK),
+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PU, I2C1_SCL_PU_MASK),
+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PU, I2C1_SDA_PU_MASK),
+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PU, SPI_CLK_PU_MASK),
+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PU, SPI_CS0_PU_MASK),
+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK),
+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PU, SPI_MISO_PU_MASK),
+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PU, UART1_TXD_PU_MASK),
+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PU, UART1_RXD_PU_MASK),
+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK),
+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK),
+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PU, MDC_0_PU_MASK),
+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PU, MDIO_0_PU_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pulldown_conf[] = {
+ PINCTRL_CONF_DESC(2, REG_GPIO_L_PD, BIT(0)),
+ PINCTRL_CONF_DESC(3, REG_GPIO_L_PD, BIT(1)),
+ PINCTRL_CONF_DESC(4, REG_GPIO_L_PD, BIT(2)),
+ PINCTRL_CONF_DESC(5, REG_GPIO_L_PD, BIT(3)),
+ PINCTRL_CONF_DESC(6, REG_GPIO_L_PD, BIT(4)),
+ PINCTRL_CONF_DESC(7, REG_GPIO_L_PD, BIT(5)),
+ PINCTRL_CONF_DESC(8, REG_GPIO_L_PD, BIT(6)),
+ PINCTRL_CONF_DESC(9, REG_GPIO_L_PD, BIT(7)),
+ PINCTRL_CONF_DESC(10, REG_GPIO_L_PD, BIT(8)),
+ PINCTRL_CONF_DESC(11, REG_GPIO_L_PD, BIT(9)),
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_PD, BIT(10)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(11)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(12)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(13)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(14)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(15)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(16)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(17)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(18)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(19)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(20)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(21)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(22)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(23)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(24)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(25)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(26)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(27)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(28)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(29)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(30)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(31)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_H_PD, BIT(0)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_H_PD, BIT(1)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_H_PD, BIT(2)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_H_PD, BIT(3)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_H_PD, BIT(4)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_H_PD, BIT(5)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_H_PD, BIT(6)),
+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PD, I2C_SCL_PD_MASK),
+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PD, I2C_SDA_PD_MASK),
+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PD, I2C1_SCL_PD_MASK),
+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PD, I2C1_SDA_PD_MASK),
+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PD, SPI_CLK_PD_MASK),
+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PD, SPI_CS0_PD_MASK),
+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK),
+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PD, SPI_MISO_PD_MASK),
+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PD, UART1_TXD_PD_MASK),
+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PD, UART1_RXD_PD_MASK),
+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK),
+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK),
+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PD, MDC_0_PD_MASK),
+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PD, MDIO_0_PD_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_drive_e2_conf[] = {
+ PINCTRL_CONF_DESC(2, REG_GPIO_L_E2, BIT(0)),
+ PINCTRL_CONF_DESC(3, REG_GPIO_L_E2, BIT(1)),
+ PINCTRL_CONF_DESC(4, REG_GPIO_L_E2, BIT(2)),
+ PINCTRL_CONF_DESC(5, REG_GPIO_L_E2, BIT(3)),
+ PINCTRL_CONF_DESC(6, REG_GPIO_L_E2, BIT(4)),
+ PINCTRL_CONF_DESC(7, REG_GPIO_L_E2, BIT(5)),
+ PINCTRL_CONF_DESC(8, REG_GPIO_L_E2, BIT(6)),
+ PINCTRL_CONF_DESC(9, REG_GPIO_L_E2, BIT(7)),
+ PINCTRL_CONF_DESC(10, REG_GPIO_L_E2, BIT(8)),
+ PINCTRL_CONF_DESC(11, REG_GPIO_L_E2, BIT(9)),
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_E2, BIT(10)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(11)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(12)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(13)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(14)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(15)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(16)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(17)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(18)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(19)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(20)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(21)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(22)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(23)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(24)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(25)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(26)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(27)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(28)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(29)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(30)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(31)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_H_E2, BIT(0)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_H_E2, BIT(1)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_H_E2, BIT(2)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_H_E2, BIT(3)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_H_E2, BIT(4)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_H_E2, BIT(5)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_H_E2, BIT(6)),
+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E2, I2C_SCL_E2_MASK),
+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E2, I2C_SDA_E2_MASK),
+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E2, I2C1_SCL_E2_MASK),
+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E2, I2C1_SDA_E2_MASK),
+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E2, SPI_CLK_E2_MASK),
+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E2, SPI_CS0_E2_MASK),
+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK),
+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E2, SPI_MISO_E2_MASK),
+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E2, UART1_TXD_E2_MASK),
+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E2, UART1_RXD_E2_MASK),
+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK),
+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK),
+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E2, MDC_0_E2_MASK),
+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E2, MDIO_0_E2_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_drive_e4_conf[] = {
+ PINCTRL_CONF_DESC(2, REG_GPIO_L_E4, BIT(0)),
+ PINCTRL_CONF_DESC(3, REG_GPIO_L_E4, BIT(1)),
+ PINCTRL_CONF_DESC(4, REG_GPIO_L_E4, BIT(2)),
+ PINCTRL_CONF_DESC(5, REG_GPIO_L_E4, BIT(3)),
+ PINCTRL_CONF_DESC(6, REG_GPIO_L_E4, BIT(4)),
+ PINCTRL_CONF_DESC(7, REG_GPIO_L_E4, BIT(5)),
+ PINCTRL_CONF_DESC(8, REG_GPIO_L_E4, BIT(6)),
+ PINCTRL_CONF_DESC(9, REG_GPIO_L_E4, BIT(7)),
+ PINCTRL_CONF_DESC(10, REG_GPIO_L_E4, BIT(8)),
+ PINCTRL_CONF_DESC(11, REG_GPIO_L_E4, BIT(9)),
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_E4, BIT(10)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(11)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(12)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(13)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(14)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(15)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(16)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(17)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(18)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(19)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(20)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(21)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(22)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(23)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(24)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(25)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(26)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(27)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(28)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(29)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(30)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(31)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_H_E4, BIT(0)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_H_E4, BIT(1)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_H_E4, BIT(2)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_H_E4, BIT(3)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_H_E4, BIT(4)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_H_E4, BIT(5)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_H_E4, BIT(6)),
+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E4, I2C_SCL_E4_MASK),
+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E4, I2C_SDA_E4_MASK),
+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E4, I2C1_SCL_E4_MASK),
+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E4, I2C1_SDA_E4_MASK),
+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E4, SPI_CLK_E4_MASK),
+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E4, SPI_CS0_E4_MASK),
+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK),
+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E4, SPI_MISO_E4_MASK),
+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E4, UART1_TXD_E4_MASK),
+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E4, UART1_RXD_E4_MASK),
+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK),
+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK),
+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E4, MDC_0_E4_MASK),
+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E4, MDIO_0_E4_MASK),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pcie_rst_od_conf[] = {
+ PINCTRL_CONF_DESC(51, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK),
+ PINCTRL_CONF_DESC(52, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK),
+};
+
+static const struct airoha_pinctrl_match_data pinctrl_match_data = {
+ .gpio_offs = 2,
+ .gpio_pin_cnt = 53,
+ .chip_scu_compatible = "airoha,en7581-chip-scu",
+ .pins = pinctrl_pins,
+ .num_pins = ARRAY_SIZE(pinctrl_pins),
+ .grps = pinctrl_groups,
+ .num_grps = ARRAY_SIZE(pinctrl_groups),
+ .funcs = pinctrl_funcs,
+ .num_funcs = ARRAY_SIZE(pinctrl_funcs),
+ .confs_info = {
+ [AIROHA_PINCTRL_CONFS_PULLUP] = {
+ .confs = pinctrl_pullup_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pullup_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
+ .confs = pinctrl_pulldown_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pulldown_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
+ .confs = pinctrl_drive_e2_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_drive_e2_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
+ .confs = pinctrl_drive_e4_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_drive_e4_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = {
+ .confs = pinctrl_pcie_rst_od_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pcie_rst_od_conf),
+ },
+ },
+};
+
+static const struct udevice_id pinctrl_of_match[] = {
+ { .compatible = "airoha,an7583-pinctrl",
+ .data = (uintptr_t)&pinctrl_match_data },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(airoha_an7583_pinctrl) = {
+ .name = "airoha-an7583-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = of_match_ptr(pinctrl_of_match),
+ .probe = airoha_pinctrl_probe,
+ .bind = airoha_pinctrl_bind,
+ .priv_auto = sizeof(struct airoha_pinctrl),
+ .ops = &airoha_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/airoha/pinctrl-en7523.c b/drivers/pinctrl/airoha/pinctrl-en7523.c
new file mode 100644
index 00000000000..958fcc8418f
--- /dev/null
+++ b/drivers/pinctrl/airoha/pinctrl-en7523.c
@@ -0,0 +1,1118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Author: Lorenzo Bianconi <[email protected]>
+ * Author: Benjamin Larsson <[email protected]>
+ * Author: Markus Gothe <[email protected]>
+ * Author: Matheus Sampaio Queiroga <[email protected]>
+ * Author: Mikhail Kshevetskiy <[email protected]>
+ */
+#include "airoha-common.h"
+
+/* MUX */
+#define REG_GPIO_2ND_I2C_MODE 0x0210
+#define GPIO_I2S_MODE_MASK BIT(12)
+#define GPIO_I2C_SLAVE_MODE_MODE BIT(11)
+#define GPIO_LAN3_LED1_MODE_MASK BIT(10)
+#define GPIO_LAN3_LED0_MODE_MASK BIT(9)
+#define GPIO_LAN2_LED1_MODE_MASK BIT(8)
+#define GPIO_LAN2_LED0_MODE_MASK BIT(7)
+#define GPIO_LAN1_LED1_MODE_MASK BIT(6)
+#define GPIO_LAN1_LED0_MODE_MASK BIT(5)
+#define GPIO_LAN0_LED1_MODE_MASK BIT(4)
+#define GPIO_LAN0_LED0_MODE_MASK BIT(3)
+#define PON_TOD_1PPS_MODE_MASK BIT(2)
+#define GSW_TOD_1PPS_MODE_MASK BIT(1)
+#define GPIO_2ND_I2C_MODE_MASK BIT(0)
+
+#define REG_GPIO_SPI_CS1_MODE 0x0214
+#define GPIO_PCM_SPI_CS4_MODE_MASK BIT(21)
+#define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20)
+#define GPIO_PCM_SPI_CS2_MODE_P156_MASK BIT(19)
+#define GPIO_PCM_SPI_CS2_MODE_P128_MASK BIT(18)
+#define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17)
+#define GPIO_PCM_SPI_MODE_MASK BIT(16)
+#define GPIO_PCM2_MODE_MASK BIT(13)
+#define GPIO_PCM1_MODE_MASK BIT(12)
+#define GPIO_PCM_INT_MODE_MASK BIT(9)
+#define GPIO_PCM_RESET_MODE_MASK BIT(8)
+#define GPIO_SPI_QUAD_MODE_MASK BIT(4)
+#define GPIO_SPI_CS1_MODE_MASK BIT(0)
+
+#define REG_GPIO_PON_MODE 0x0218
+#define GPIO_SGMII_MDIO_MODE_MASK BIT(13)
+#define SIPO_RCLK_MODE_MASK BIT(11)
+#define GPIO_PCIE_RESET1_MASK BIT(10)
+#define GPIO_PCIE_RESET0_MASK BIT(9)
+#define GPIO_UART2_MODE_MASK BIT(3)
+#define GPIO_SIPO_MODE_MASK BIT(2)
+#define GPIO_PON_MODE_MASK BIT(0)
+
+#define REG_NPU_UART_EN 0x0220
+#define JTAG_UDI_EN_MASK BIT(4)
+#define JTAG_DFD_EN_MASK BIT(3)
+#define NPU_UART_EN_MASK BIT(2)
+
+#define REG_FORCE_GPIO_EN 0x0224
+#define FORCE_GPIO_EN(n) BIT(n)
+
+/* LED MAP */
+#define REG_LAN_LED0_MAPPING 0x0278
+#define REG_LAN_LED1_MAPPING 0x027c
+
+#define LAN3_LED_MAPPING_MASK GENMASK(14, 12)
+#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n))
+
+#define LAN2_LED_MAPPING_MASK GENMASK(10, 8)
+#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n))
+
+#define LAN1_LED_MAPPING_MASK GENMASK(6, 4)
+#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n))
+
+#define LAN0_LED_MAPPING_MASK GENMASK(2, 0)
+#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n))
+
+/* CONF */
+#define REG_I2C_SDA_E2 0x001c
+#define SPI_MISO_E2_MASK BIT(13)
+#define SPI_MOSI_E2_MASK BIT(12)
+#define SPI_CLK_E2_MASK BIT(11)
+#define SPI_CS0_E2_MASK BIT(10)
+#define PCIE1_RESET_E2_MASK BIT(9)
+#define PCIE0_RESET_E2_MASK BIT(8)
+#define UART1_RXD_E2_MASK BIT(3)
+#define UART1_TXD_E2_MASK BIT(2)
+#define I2C_SCL_E2_MASK BIT(1)
+#define I2C_SDA_E2_MASK BIT(0)
+
+#define REG_I2C_SDA_E4 0x0020
+#define SPI_MISO_E4_MASK BIT(13)
+#define SPI_MOSI_E4_MASK BIT(12)
+#define SPI_CLK_E4_MASK BIT(11)
+#define SPI_CS0_E4_MASK BIT(10)
+#define PCIE1_RESET_E4_MASK BIT(9)
+#define PCIE0_RESET_E4_MASK BIT(8)
+#define UART1_RXD_E4_MASK BIT(3)
+#define UART1_TXD_E4_MASK BIT(2)
+#define I2C_SCL_E4_MASK BIT(1)
+#define I2C_SDA_E4_MASK BIT(0)
+
+#define REG_GPIO_L_E2 0x0024
+#define REG_GPIO_L_E4 0x0028
+
+#define REG_I2C_SDA_PU 0x0044
+#define SPI_MISO_PU_MASK BIT(13)
+#define SPI_MOSI_PU_MASK BIT(12)
+#define SPI_CLK_PU_MASK BIT(11)
+#define SPI_CS0_PU_MASK BIT(10)
+#define PCIE1_RESET_PU_MASK BIT(9)
+#define PCIE0_RESET_PU_MASK BIT(8)
+#define UART1_RXD_PU_MASK BIT(3)
+#define UART1_TXD_PU_MASK BIT(2)
+#define I2C_SCL_PU_MASK BIT(1)
+#define I2C_SDA_PU_MASK BIT(0)
+
+#define REG_I2C_SDA_PD 0x0048
+#define SPI_MISO_PD_MASK BIT(13)
+#define SPI_MOSI_PD_MASK BIT(12)
+#define SPI_CLK_PD_MASK BIT(11)
+#define SPI_CS0_PD_MASK BIT(10)
+#define PCIE1_RESET_PD_MASK BIT(9)
+#define PCIE0_RESET_PD_MASK BIT(8)
+#define UART1_RXD_PD_MASK BIT(3)
+#define UART1_TXD_PD_MASK BIT(2)
+#define I2C_SCL_PD_MASK BIT(1)
+#define I2C_SDA_PD_MASK BIT(0)
+
+#define REG_GPIO_L_PU 0x004c
+#define REG_GPIO_L_PD 0x0050
+
+/* PWM MODE CONF */
+#define REG_GPIO_FLASH_MODE_CFG 0x0034
+#define GPIO15_FLASH_MODE_CFG BIT(15)
+#define GPIO14_FLASH_MODE_CFG BIT(14)
+#define GPIO13_FLASH_MODE_CFG BIT(13)
+#define GPIO12_FLASH_MODE_CFG BIT(12)
+#define GPIO11_FLASH_MODE_CFG BIT(11)
+#define GPIO10_FLASH_MODE_CFG BIT(10)
+#define GPIO9_FLASH_MODE_CFG BIT(9)
+#define GPIO8_FLASH_MODE_CFG BIT(8)
+#define GPIO7_FLASH_MODE_CFG BIT(7)
+#define GPIO6_FLASH_MODE_CFG BIT(6)
+#define GPIO5_FLASH_MODE_CFG BIT(5)
+#define GPIO4_FLASH_MODE_CFG BIT(4)
+#define GPIO3_FLASH_MODE_CFG BIT(3)
+#define GPIO2_FLASH_MODE_CFG BIT(2)
+#define GPIO1_FLASH_MODE_CFG BIT(1)
+#define GPIO0_FLASH_MODE_CFG BIT(0)
+
+/* PWM MODE CONF EXT */
+#define REG_GPIO_FLASH_MODE_CFG_EXT 0x0068
+#define GPIO51_FLASH_MODE_CFG BIT(31)
+#define GPIO50_FLASH_MODE_CFG BIT(30)
+#define GPIO49_FLASH_MODE_CFG BIT(29)
+#define GPIO48_FLASH_MODE_CFG BIT(28)
+#define GPIO47_FLASH_MODE_CFG BIT(27)
+#define GPIO46_FLASH_MODE_CFG BIT(26)
+#define GPIO45_FLASH_MODE_CFG BIT(25)
+#define GPIO44_FLASH_MODE_CFG BIT(24)
+#define GPIO43_FLASH_MODE_CFG BIT(23)
+#define GPIO42_FLASH_MODE_CFG BIT(22)
+#define GPIO41_FLASH_MODE_CFG BIT(21)
+#define GPIO40_FLASH_MODE_CFG BIT(20)
+#define GPIO39_FLASH_MODE_CFG BIT(19)
+#define GPIO38_FLASH_MODE_CFG BIT(18)
+#define GPIO37_FLASH_MODE_CFG BIT(17)
+#define GPIO36_FLASH_MODE_CFG BIT(16)
+#define GPIO31_FLASH_MODE_CFG BIT(15)
+#define GPIO30_FLASH_MODE_CFG BIT(14)
+#define GPIO29_FLASH_MODE_CFG BIT(13)
+#define GPIO28_FLASH_MODE_CFG BIT(12)
+#define GPIO27_FLASH_MODE_CFG BIT(11)
+#define GPIO26_FLASH_MODE_CFG BIT(10)
+#define GPIO25_FLASH_MODE_CFG BIT(9)
+#define GPIO24_FLASH_MODE_CFG BIT(8)
+#define GPIO23_FLASH_MODE_CFG BIT(7)
+#define GPIO22_FLASH_MODE_CFG BIT(6)
+#define GPIO21_FLASH_MODE_CFG BIT(5)
+#define GPIO20_FLASH_MODE_CFG BIT(4)
+#define GPIO19_FLASH_MODE_CFG BIT(3)
+#define GPIO18_FLASH_MODE_CFG BIT(2)
+#define GPIO17_FLASH_MODE_CFG BIT(1)
+#define GPIO16_FLASH_MODE_CFG BIT(0)
+
+#define AIROHA_PINCTRL_GPIO(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_GPIO_EXT(gpio, mux_val, smux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ 0 \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (smux_val), \
+ (smux_val) \
+ }, \
+ .regmap_size = 2, \
+ }
+
+/* PWM */
+#define AIROHA_PINCTRL_PWM(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_MUX, \
+ REG_GPIO_FLASH_MODE_CFG, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_PWM_EXT(gpio, mux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap_size = 1, \
+ }
+
+#define AIROHA_PINCTRL_PWM_EXT_SEC(gpio, mux_val, smux_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_PWM_EXT_MUX, \
+ REG_GPIO_FLASH_MODE_CFG_EXT, \
+ (mux_val), \
+ (mux_val) \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_PON_MODE, \
+ (smux_val), \
+ (smux_val) \
+ }, \
+ .regmap_size = 2, \
+ }
+
+#define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_2ND_I2C_MODE, \
+ (mux_val), \
+ (mux_val), \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_LAN_LED0_MAPPING, \
+ (map_mask), \
+ (map_val), \
+ }, \
+ .regmap_size = 2, \
+ }
+
+#define AIROHA_PINCTRL_PHY_LED1(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_2ND_I2C_MODE, \
+ (mux_val), \
+ (mux_val), \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_LAN_LED1_MAPPING, \
+ (map_mask), \
+ (map_val), \
+ }, \
+ .regmap_size = 2, \
+ }
+
+static struct pinctrl_pin_desc pinctrl_pins[] = {
+ PINCTRL_PIN(2, "i2c_sda"),
+ PINCTRL_PIN(3, "i2c_scl"),
+ PINCTRL_PIN(4, "spi_cs0"),
+ PINCTRL_PIN(5, "spi_clk"),
+ PINCTRL_PIN(6, "spi_mosi"),
+ PINCTRL_PIN(7, "spi_miso"),
+ PINCTRL_PIN(8, "uart1_txd"),
+ PINCTRL_PIN(9, "uart1_rxd"),
+ PINCTRL_PIN(12, "gpio0"),
+ PINCTRL_PIN(13, "gpio1"),
+ PINCTRL_PIN(14, "gpio2"),
+ PINCTRL_PIN(15, "gpio3"),
+ PINCTRL_PIN(16, "gpio4"),
+ PINCTRL_PIN(17, "gpio5"),
+ PINCTRL_PIN(18, "gpio6"),
+ PINCTRL_PIN(19, "gpio7"),
+ PINCTRL_PIN(20, "gpio8"),
+ PINCTRL_PIN(21, "gpio9"),
+ PINCTRL_PIN(22, "gpio10"),
+ PINCTRL_PIN(23, "gpio11"),
+ PINCTRL_PIN(24, "gpio12"),
+ PINCTRL_PIN(25, "gpio13"),
+ PINCTRL_PIN(26, "gpio14"),
+ PINCTRL_PIN(27, "gpio15"),
+ PINCTRL_PIN(28, "gpio16"),
+ PINCTRL_PIN(29, "gpio17"),
+ PINCTRL_PIN(30, "gpio18"),
+ PINCTRL_PIN(31, "gpio19"),
+ PINCTRL_PIN(32, "gpio20"),
+ PINCTRL_PIN(33, "gpio21"),
+ PINCTRL_PIN(34, "gpio22"),
+ PINCTRL_PIN(35, "gpio23"),
+ PINCTRL_PIN(36, "gpio24"),
+ PINCTRL_PIN(37, "gpio25"),
+ PINCTRL_PIN(38, "gpio26"),
+ PINCTRL_PIN(39, "gpio27"),
+ PINCTRL_PIN(40, "pcie_reset0"),
+ PINCTRL_PIN(41, "pcie_reset1"),
+};
+
+static const int pon_pins[] = { 28, 29, 30, 31, 32, 33 };
+static const int pon_tod_1pps_pins[] = { 21 };
+static const int gsw_tod_1pps_pins[] = { 21 };
+static const int sipo_pins[] = { 13, 38 };
+static const int sipo_rclk_pins[] = { 13, 30, 38 };
+static const int mdio_pins[] = { 20, 21 };
+static const int uart2_pins[] = { 20, 21 };
+static const int npu_uart_pins[] = { 13, 38 };
+static const int i2c0_pins[] = { 2, 3 };
+static const int i2c1_pins[] = { 14, 15 };
+static const int jtag_udi_pins[] = { 34, 35, 36, 37, 38 };
+static const int jtag_dfd_pins[] = { 34, 35, 36, 37, 38 };
+static const int i2s_pins[] = { 16, 17, 18, 19 };
+static const int pcm1_pins[] = { 24, 25, 26, 27 };
+static const int pcm2_pins[] = { 16, 17, 18, 19 };
+static const int spi_pins[] = { 4, 5, 6, 7 };
+static const int spi_quad_pins[] = { 14, 15 };
+static const int spi_cs1_pins[] = { 21 };
+static const int pcm_spi_pins[] = { 16, 17, 18, 19, 24, 25, 26, 27 };
+static const int pcm_spi_int_pins[] = { 15 };
+static const int pcm_spi_rst_pins[] = { 14 };
+static const int pcm_spi_cs1_pins[] = { 22 };
+static const int pcm_spi_cs2_p128_pins[] = { 39 };
+static const int pcm_spi_cs2_p156_pins[] = { 39 };
+static const int pcm_spi_cs3_pins[] = { 20 };
+static const int pcm_spi_cs4_pins[] = { 23 };
+static const int gpio0_pins[] = { 12 };
+static const int gpio1_pins[] = { 13 };
+static const int gpio2_pins[] = { 14 };
+static const int gpio3_pins[] = { 15 };
+static const int gpio4_pins[] = { 16 };
+static const int gpio5_pins[] = { 17 };
+static const int gpio6_pins[] = { 18 };
+static const int gpio7_pins[] = { 19 };
+static const int gpio8_pins[] = { 20 };
+static const int gpio9_pins[] = { 21 };
+static const int gpio10_pins[] = { 22 };
+static const int gpio11_pins[] = { 23 };
+static const int gpio12_pins[] = { 24 };
+static const int gpio13_pins[] = { 25 };
+static const int gpio14_pins[] = { 26 };
+static const int gpio15_pins[] = { 27 };
+static const int gpio16_pins[] = { 28 };
+static const int gpio17_pins[] = { 29 };
+static const int gpio18_pins[] = { 30 };
+static const int gpio19_pins[] = { 31 };
+static const int gpio20_pins[] = { 32 };
+static const int gpio21_pins[] = { 33 };
+static const int gpio22_pins[] = { 34 };
+static const int gpio23_pins[] = { 35 };
+static const int gpio24_pins[] = { 36 };
+static const int gpio25_pins[] = { 37 };
+static const int gpio26_pins[] = { 38 };
+static const int gpio27_pins[] = { 39 };
+static const int gpio28_pins[] = { 40 };
+static const int gpio29_pins[] = { 41 };
+static const int pcie_reset0_pins[] = { 40 };
+static const int pcie_reset1_pins[] = { 41 };
+
+static const struct pingroup pinctrl_groups[] = {
+ PINCTRL_PIN_GROUP("pon", pon),
+ PINCTRL_PIN_GROUP("pon_tod_1pps", pon_tod_1pps),
+ PINCTRL_PIN_GROUP("gsw_tod_1pps", gsw_tod_1pps),
+ PINCTRL_PIN_GROUP("sipo", sipo),
+ PINCTRL_PIN_GROUP("sipo_rclk", sipo_rclk),
+ PINCTRL_PIN_GROUP("mdio", mdio),
+ PINCTRL_PIN_GROUP("uart2", uart2),
+ PINCTRL_PIN_GROUP("npu_uart", npu_uart),
+ PINCTRL_PIN_GROUP("i2c0", i2c0),
+ PINCTRL_PIN_GROUP("i2c1", i2c1),
+ PINCTRL_PIN_GROUP("jtag_udi", jtag_udi),
+ PINCTRL_PIN_GROUP("jtag_dfd", jtag_dfd),
+ PINCTRL_PIN_GROUP("i2s", i2s),
+ PINCTRL_PIN_GROUP("pcm1", pcm1),
+ PINCTRL_PIN_GROUP("pcm2", pcm2),
+ PINCTRL_PIN_GROUP("spi", spi),
+ PINCTRL_PIN_GROUP("spi_quad", spi_quad),
+ PINCTRL_PIN_GROUP("spi_cs1", spi_cs1),
+ PINCTRL_PIN_GROUP("pcm_spi", pcm_spi),
+ PINCTRL_PIN_GROUP("pcm_spi_int", pcm_spi_int),
+ PINCTRL_PIN_GROUP("pcm_spi_rst", pcm_spi_rst),
+ PINCTRL_PIN_GROUP("pcm_spi_cs1", pcm_spi_cs1),
+ PINCTRL_PIN_GROUP("pcm_spi_cs2_p128", pcm_spi_cs2_p128),
+ PINCTRL_PIN_GROUP("pcm_spi_cs2_p156", pcm_spi_cs2_p156),
+ PINCTRL_PIN_GROUP("pcm_spi_cs3", pcm_spi_cs3),
+ PINCTRL_PIN_GROUP("pcm_spi_cs4", pcm_spi_cs4),
+ PINCTRL_PIN_GROUP("gpio0", gpio0),
+ PINCTRL_PIN_GROUP("gpio1", gpio1),
+ PINCTRL_PIN_GROUP("gpio2", gpio2),
+ PINCTRL_PIN_GROUP("gpio3", gpio3),
+ PINCTRL_PIN_GROUP("gpio4", gpio4),
+ PINCTRL_PIN_GROUP("gpio5", gpio5),
+ PINCTRL_PIN_GROUP("gpio6", gpio6),
+ PINCTRL_PIN_GROUP("gpio7", gpio7),
+ PINCTRL_PIN_GROUP("gpio8", gpio8),
+ PINCTRL_PIN_GROUP("gpio9", gpio9),
+ PINCTRL_PIN_GROUP("gpio10", gpio10),
+ PINCTRL_PIN_GROUP("gpio11", gpio11),
+ PINCTRL_PIN_GROUP("gpio12", gpio12),
+ PINCTRL_PIN_GROUP("gpio13", gpio13),
+ PINCTRL_PIN_GROUP("gpio14", gpio14),
+ PINCTRL_PIN_GROUP("gpio15", gpio15),
+ PINCTRL_PIN_GROUP("gpio16", gpio16),
+ PINCTRL_PIN_GROUP("gpio17", gpio17),
+ PINCTRL_PIN_GROUP("gpio18", gpio18),
+ PINCTRL_PIN_GROUP("gpio19", gpio19),
+ PINCTRL_PIN_GROUP("gpio20", gpio20),
+ PINCTRL_PIN_GROUP("gpio21", gpio21),
+ PINCTRL_PIN_GROUP("gpio22", gpio22),
+ PINCTRL_PIN_GROUP("gpio23", gpio23),
+ PINCTRL_PIN_GROUP("gpio24", gpio24),
+ PINCTRL_PIN_GROUP("gpio25", gpio25),
+ PINCTRL_PIN_GROUP("gpio26", gpio26),
+ PINCTRL_PIN_GROUP("gpio27", gpio27),
+ PINCTRL_PIN_GROUP("gpio28", gpio28),
+ PINCTRL_PIN_GROUP("gpio29", gpio29),
+ PINCTRL_PIN_GROUP("pcie_reset0", pcie_reset0),
+ PINCTRL_PIN_GROUP("pcie_reset1", pcie_reset1),
+};
+
+static const char *const pon_groups[] = { "pon" };
+static const char *const tod_1pps_groups[] = {
+ "pon_tod_1pps", "gsw_tod_1pps"
+};
+static const char *const sipo_groups[] = { "sipo", "sipo_rclk" };
+static const char *const mdio_groups[] = { "mdio" };
+static const char *const uart_groups[] = { "uart2", "npu_uart" };
+static const char *const i2c_groups[] = { "i2c1" };
+static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" };
+static const char *const pcm_groups[] = { "pcm1", "pcm2" };
+static const char *const spi_groups[] = { "spi_quad", "spi_cs1" };
+static const char *const pcm_spi_groups[] = {
+ "pcm_spi", "pcm_spi_int", "pcm_spi_rst", "pcm_spi_cs1",
+ "pcm_spi_cs2_p156", "pcm_spi_cs2_p128", "pcm_spi_cs3", "pcm_spi_cs4"
+};
+static const char *const i2s_groups[] = { "i2s" };
+static const char *const gpio_groups[] = { "gpio28", "gpio29" };
+static const char *const pcie_reset_groups[] = {
+ "pcie_reset0", "pcie_reset1"
+};
+static const char *const pwm_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
+ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
+ "gpio12", "gpio13", "gpio14", "gpio15", "gpio16", "gpio17",
+ "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23",
+ "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29"
+};
+static const char *const phy1_led0_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+static const char *const phy2_led0_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+static const char *const phy3_led0_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+static const char *const phy4_led0_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+static const char *const phy1_led1_groups[] = {
+ "gpio7", "gpio6", "gpio5", "gpio4"
+};
+static const char *const phy2_led1_groups[] = {
+ "gpio7", "gpio6", "gpio5", "gpio4"
+};
+static const char *const phy3_led1_groups[] = {
+ "gpio7", "gpio6", "gpio5", "gpio4"
+};
+static const char *const phy4_led1_groups[] = {
+ "gpio7", "gpio6", "gpio5", "gpio4"
+};
+
+static const struct airoha_pinctrl_func_group pon_func_group[] = {
+ {
+ .name = "pon",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PON_MODE_MASK,
+ GPIO_PON_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = {
+ {
+ .name = "pon_tod_1pps",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ PON_TOD_1PPS_MODE_MASK,
+ PON_TOD_1PPS_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "gsw_tod_1pps",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ GSW_TOD_1PPS_MODE_MASK,
+ GSW_TOD_1PPS_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group sipo_func_group[] = {
+ {
+ .name = "sipo",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+ GPIO_SIPO_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "sipo_rclk",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK,
+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group mdio_func_group[] = {
+ {
+ .name = "mdio",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_SGMII_MDIO_MODE_MASK,
+ GPIO_SGMII_MDIO_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group uart_func_group[] = {
+ {
+ .name = "uart2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_UART2_MODE_MASK,
+ GPIO_UART2_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "npu_uart",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ NPU_UART_EN_MASK,
+ NPU_UART_EN_MASK
+ },
+ .regmap_size = 1,
+ }
+};
+
+static const struct airoha_pinctrl_func_group i2c_func_group[] = {
+ {
+ .name = "i2c1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ GPIO_2ND_I2C_MODE_MASK,
+ GPIO_2ND_I2C_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group jtag_func_group[] = {
+ {
+ .name = "jtag_udi",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ JTAG_UDI_EN_MASK,
+ JTAG_UDI_EN_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "jtag_dfd",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_NPU_UART_EN,
+ JTAG_DFD_EN_MASK,
+ JTAG_DFD_EN_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pcm_func_group[] = {
+ {
+ .name = "pcm1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM1_MODE_MASK,
+ GPIO_PCM1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm2",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM2_MODE_MASK,
+ GPIO_PCM2_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group spi_func_group[] = {
+ {
+ .name = "spi_quad",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_QUAD_MODE_MASK,
+ GPIO_SPI_QUAD_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "spi_cs1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_SPI_CS1_MODE_MASK,
+ GPIO_SPI_CS1_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pcm_spi_func_group[] = {
+ {
+ .name = "pcm_spi",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_MODE_MASK,
+ GPIO_PCM_SPI_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_int",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_INT_MODE_MASK,
+ GPIO_PCM_INT_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_rst",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_RESET_MODE_MASK,
+ GPIO_PCM_RESET_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS1_MODE_MASK,
+ GPIO_PCM_SPI_CS1_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs2_p128",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS2_MODE_P128_MASK,
+ GPIO_PCM_SPI_CS2_MODE_P128_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs2_p156",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS2_MODE_P156_MASK,
+ GPIO_PCM_SPI_CS2_MODE_P156_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs3",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS3_MODE_MASK,
+ GPIO_PCM_SPI_CS3_MODE_MASK
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcm_spi_cs4",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_SPI_CS1_MODE,
+ GPIO_PCM_SPI_CS4_MODE_MASK,
+ GPIO_PCM_SPI_CS4_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group i2s_func_group[] = {
+ {
+ .name = "i2s",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_2ND_I2C_MODE,
+ GPIO_I2S_MODE_MASK,
+ GPIO_I2S_MODE_MASK
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group gpio_func_group[] = {
+ AIROHA_PINCTRL_GPIO_EXT("gpio28", GPIO28_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET0_MASK),
+ AIROHA_PINCTRL_GPIO_EXT("gpio29", GPIO29_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET1_MASK),
+};
+
+static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = {
+ {
+ .name = "pcie_reset0",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PCIE_RESET0_MASK,
+ 0
+ },
+ .regmap_size = 1,
+ }, {
+ .name = "pcie_reset1",
+ .regmap[0] = {
+ AIROHA_FUNC_MUX,
+ REG_GPIO_PON_MODE,
+ GPIO_PCIE_RESET1_MASK,
+ 0
+ },
+ .regmap_size = 1,
+ },
+};
+
+static const struct airoha_pinctrl_func_group pwm_func_group[] = {
+ AIROHA_PINCTRL_PWM("gpio0", GPIO0_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio1", GPIO1_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio2", GPIO2_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio3", GPIO3_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio4", GPIO4_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio5", GPIO5_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio6", GPIO6_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio7", GPIO7_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio8", GPIO8_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio9", GPIO9_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio10", GPIO10_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio11", GPIO11_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio12", GPIO12_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio13", GPIO13_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio14", GPIO14_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM("gpio15", GPIO15_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio16", GPIO16_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio17", GPIO17_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio18", GPIO18_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio19", GPIO19_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio20", GPIO20_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio21", GPIO21_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio22", GPIO22_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio23", GPIO23_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio24", GPIO24_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio25", GPIO25_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio26", GPIO26_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT("gpio27", GPIO27_FLASH_MODE_CFG),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio28", GPIO28_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET0_MASK),
+ AIROHA_PINCTRL_PWM_EXT_SEC("gpio29", GPIO29_FLASH_MODE_CFG,
+ GPIO_PCIE_RESET1_MASK),
+};
+
+static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio25", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio25", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio25", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED0("gpio22", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio23", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio24", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio25", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+};
+
+static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio4", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio4", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio4", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED1("gpio7", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio6", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio5", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED1("gpio4", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+};
+
+static const struct airoha_pinctrl_func pinctrl_funcs[] = {
+ PINCTRL_FUNC_DESC("pon", pon),
+ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps),
+ PINCTRL_FUNC_DESC("sipo", sipo),
+ PINCTRL_FUNC_DESC("mdio", mdio),
+ PINCTRL_FUNC_DESC("uart", uart),
+ PINCTRL_FUNC_DESC("i2c", i2c),
+ PINCTRL_FUNC_DESC("jtag", jtag),
+ PINCTRL_FUNC_DESC("pcm", pcm),
+ PINCTRL_FUNC_DESC("spi", spi),
+ PINCTRL_FUNC_DESC("pcm_spi", pcm_spi),
+ PINCTRL_FUNC_DESC("i2s", i2s),
+ PINCTRL_FUNC_DESC("gpio", gpio),
+ PINCTRL_FUNC_DESC("pcie_reset", pcie_reset),
+ PINCTRL_FUNC_DESC("pwm", pwm),
+ PINCTRL_FUNC_DESC("phy1_led0", phy1_led0),
+ PINCTRL_FUNC_DESC("phy2_led0", phy2_led0),
+ PINCTRL_FUNC_DESC("phy3_led0", phy3_led0),
+ PINCTRL_FUNC_DESC("phy4_led0", phy4_led0),
+ PINCTRL_FUNC_DESC("phy1_led1", phy1_led1),
+ PINCTRL_FUNC_DESC("phy2_led1", phy2_led1),
+ PINCTRL_FUNC_DESC("phy3_led1", phy3_led1),
+ PINCTRL_FUNC_DESC("phy4_led1", phy4_led1),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pullup_conf[] = {
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_PU, BIT(0)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(1)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(2)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(3)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(4)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(5)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(6)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(7)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(8)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(9)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(10)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(11)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(12)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(13)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(14)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(15)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(16)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(17)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(18)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(19)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(20)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(21)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_PU, BIT(22)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_PU, BIT(23)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_PU, BIT(24)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_PU, BIT(25)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_PU, BIT(26)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_PU, BIT(27)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_PU, BIT(28)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_PU, BIT(29)),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_pulldown_conf[] = {
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_PD, BIT(0)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(1)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(2)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(3)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(4)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(5)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(6)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(7)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(8)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(9)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(10)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(11)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(12)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(13)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(14)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(15)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(16)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(17)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(18)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(19)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(20)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(21)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_PD, BIT(22)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_PD, BIT(23)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_PD, BIT(24)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_PD, BIT(25)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_PD, BIT(26)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_PD, BIT(27)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_PD, BIT(28)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_PD, BIT(29)),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_drive_e2_conf[] = {
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_E2, BIT(0)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(1)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(2)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(3)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(4)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(5)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(6)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(7)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(8)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(9)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(10)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(11)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(12)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(13)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(14)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(15)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(16)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(17)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(18)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(19)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(20)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(21)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_E2, BIT(22)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_E2, BIT(23)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_E2, BIT(24)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_E2, BIT(25)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_E2, BIT(26)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_E2, BIT(27)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_E2, BIT(28)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_E2, BIT(29)),
+};
+
+static const struct airoha_pinctrl_conf pinctrl_drive_e4_conf[] = {
+ PINCTRL_CONF_DESC(12, REG_GPIO_L_E4, BIT(0)),
+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(1)),
+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(2)),
+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(3)),
+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(4)),
+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(5)),
+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(6)),
+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(7)),
+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(8)),
+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(9)),
+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(10)),
+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(11)),
+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(12)),
+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(13)),
+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(14)),
+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(15)),
+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(16)),
+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(17)),
+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(18)),
+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(19)),
+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(20)),
+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(21)),
+ PINCTRL_CONF_DESC(34, REG_GPIO_L_E4, BIT(22)),
+ PINCTRL_CONF_DESC(35, REG_GPIO_L_E4, BIT(23)),
+ PINCTRL_CONF_DESC(36, REG_GPIO_L_E4, BIT(24)),
+ PINCTRL_CONF_DESC(37, REG_GPIO_L_E4, BIT(25)),
+ PINCTRL_CONF_DESC(38, REG_GPIO_L_E4, BIT(26)),
+ PINCTRL_CONF_DESC(39, REG_GPIO_L_E4, BIT(27)),
+ PINCTRL_CONF_DESC(40, REG_GPIO_L_E4, BIT(28)),
+ PINCTRL_CONF_DESC(41, REG_GPIO_L_E4, BIT(29)),
+};
+
+static const struct airoha_pinctrl_match_data pinctrl_match_data = {
+ .gpio_offs = 12,
+ .gpio_pin_cnt = 30,
+ .chip_scu_compatible = "airoha,en7523-chip-scu",
+ .pins = pinctrl_pins,
+ .num_pins = ARRAY_SIZE(pinctrl_pins),
+ .grps = pinctrl_groups,
+ .num_grps = ARRAY_SIZE(pinctrl_groups),
+ .funcs = pinctrl_funcs,
+ .num_funcs = ARRAY_SIZE(pinctrl_funcs),
+ .confs_info = {
+ [AIROHA_PINCTRL_CONFS_PULLUP] = {
+ .confs = pinctrl_pullup_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pullup_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_PULLDOWN] = {
+ .confs = pinctrl_pulldown_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_pulldown_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = {
+ .confs = pinctrl_drive_e2_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_drive_e2_conf),
+ },
+ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = {
+ .confs = pinctrl_drive_e4_conf,
+ .num_confs = ARRAY_SIZE(pinctrl_drive_e4_conf),
+ },
+ },
+};
+
+static const struct udevice_id pinctrl_of_match[] = {
+ { .compatible = "airoha,en7523-pinctrl",
+ .data = (uintptr_t)&pinctrl_match_data },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(airoha_en7523_pinctrl) = {
+ .name = "airoha-en7523-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = of_match_ptr(pinctrl_of_match),
+ .probe = airoha_pinctrl_probe,
+ .bind = airoha_pinctrl_bind,
+ .priv_auto = sizeof(struct airoha_pinctrl),
+ .ops = &airoha_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
index a3e01ed1ca9..33b23fce629 100644
--- a/drivers/pinctrl/aspeed/Makefile
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -1,2 +1,4 @@
obj-$(CONFIG_ASPEED_AST2500_PINCTRL) += pinctrl_ast2500.o
obj-$(CONFIG_ASPEED_AST2600_PINCTRL) += pinctrl_ast2600.o
+obj-$(CONFIG_ASPEED_AST2700_SOC0_PINCTRL) += pinctrl_ast2700_soc0.o
+obj-$(CONFIG_ASPEED_AST2700_SOC1_PINCTRL) += pinctrl_ast2700_soc1.o
diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2700_soc0.c b/drivers/pinctrl/aspeed/pinctrl_ast2700_soc0.c
new file mode 100644
index 00000000000..b5111d7ee15
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2700_soc0.c
@@ -0,0 +1,623 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 ASPEED Technology Inc.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <errno.h>
+#include <vsprintf.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#define SCU010 0x010
+#define SCU200 0x200
+#define SCU400 0x400
+#define SCU404 0x404
+#define SCU408 0x408
+#define SCU410 0x410
+/* One IO control register per ball, GPIO18A0..GPIO18B3 */
+#define SCU480 0x480
+
+/* Indexes into ast2700_soc0_pins[], in GPIO18A0..GPIO18B3 order */
+enum {
+ AC14,
+ AE15,
+ AD14,
+ AE14,
+ AF14,
+ AB13,
+ AB14,
+ AF15,
+ AF13,
+ AC13,
+ AD13,
+ AE13,
+};
+
+#define USB_PORTA_ROUTE BIT(9)
+#define USB_PORTB_ROUTE BIT(10)
+
+#define PORTA_U3_MODE GENMASK(1, 0)
+#define PORTA_U2_MODE GENMASK(3, 2)
+#define PORTB_U3_MODE GENMASK(5, 4)
+#define PORTB_U2_MODE GENMASK(7, 6)
+#define PORTA_MODE GENMASK(25, 24)
+#define PORTB_MODE GENMASK(29, 28)
+
+#define PINMUX(_function, _group, _offset, _mask, _val) \
+ { \
+ .function = _function, \
+ .group = _group, \
+ .offset = _offset, \
+ .mask = _mask, \
+ .val = _val, \
+ }
+
+struct ast2700_soc0_pinmux {
+ const char *function;
+ const char *group;
+ u32 offset;
+ u32 mask;
+ u32 val;
+};
+
+struct ast2700_soc0_sig {
+ u32 offset;
+ u32 mask;
+ const char *name;
+};
+
+struct ast2700_soc0_pin {
+ const char *name;
+ const struct ast2700_soc0_sig *sigs;
+ unsigned int nsigs;
+};
+
+struct ast2700_soc0_pinctrl_priv {
+ void __iomem *base;
+};
+
+struct ast2700_soc0_group {
+ const char *name;
+ const u8 *pins;
+ unsigned int npins;
+};
+
+static const u8 ast2700_soc0_emmcg1_pins[] = { AC14, AE15, AD14 };
+static const u8 ast2700_soc0_emmcg4_pins[] = {
+ AC14, AE15, AD14, AE14, AF14, AB13,
+};
+
+static const u8 ast2700_soc0_emmcg8_pins[] = {
+ AC14, AE15, AD14, AE14, AF14, AB13, AF13, AC13, AD13, AE13,
+};
+
+static const u8 ast2700_soc0_emmcwpn_pins[] = { AF15 };
+static const u8 ast2700_soc0_emmccdn_pins[] = { AB14 };
+static const u8 ast2700_soc0_vgaddc_pins[] = { AD13, AE13 };
+static const u8 ast2700_soc0_vb1_pins[] = { AC14, AE15, AD14, AE14 };
+static const u8 ast2700_soc0_vb0_pins[] = { AF15, AB14, AF13, AC13 };
+static const u8 ast2700_soc0_tsprstn_pins[] = { AF13 };
+static const u8 ast2700_soc0_ufsclki_pins[] = { AC13 };
+
+#define AST2700_SOC0_GROUP(_name, _pins) \
+ { \
+ .name = _name, \
+ .pins = _pins, \
+ .npins = ARRAY_SIZE(_pins), \
+ }
+
+/*
+ * The USB, JTAG and PCIe RC groups control internal routing only; they
+ * have no package balls, hence no group pins to configure.
+ */
+static const struct ast2700_soc0_group ast2700_soc0_groups[] = {
+ AST2700_SOC0_GROUP("EMMCG1", ast2700_soc0_emmcg1_pins),
+ AST2700_SOC0_GROUP("EMMCG4", ast2700_soc0_emmcg4_pins),
+ AST2700_SOC0_GROUP("EMMCG8", ast2700_soc0_emmcg8_pins),
+ AST2700_SOC0_GROUP("EMMCWPN", ast2700_soc0_emmcwpn_pins),
+ AST2700_SOC0_GROUP("EMMCCDN", ast2700_soc0_emmccdn_pins),
+ AST2700_SOC0_GROUP("VGADDC", ast2700_soc0_vgaddc_pins),
+ AST2700_SOC0_GROUP("VB1", ast2700_soc0_vb1_pins),
+ AST2700_SOC0_GROUP("VB0", ast2700_soc0_vb0_pins),
+ AST2700_SOC0_GROUP("TSPRSTN", ast2700_soc0_tsprstn_pins),
+ AST2700_SOC0_GROUP("UFSCLKI", ast2700_soc0_ufsclki_pins),
+ { "USB3A" },
+ { "USB3AAP" },
+ { "USB3ABP" },
+ { "USB3B" },
+ { "USB3BAP" },
+ { "USB3BBP" },
+ { "USB2A" },
+ { "USB2AAP" },
+ { "USB2ABP" },
+ { "USB2ADAP" },
+ { "USB2AH" },
+ { "USB2AHAP" },
+ { "USB2B" },
+ { "USB2BBP" },
+ { "USB2BAP" },
+ { "USB2BDBP" },
+ { "USB2BH" },
+ { "USB2BHBP" },
+ { "JTAG0" },
+ { "PCIERC0PERST" },
+ { "PCIERC1PERST" },
+};
+
+static const char * const ast2700_soc0_functions[] = {
+ "EMMC",
+ "VB",
+ "TSPRSTN",
+ "UFSCLKI",
+ "VGADDC",
+ "USB3AXHD",
+ "USB3AXHPD",
+ "USB3AXH",
+ "USB3AXHP",
+ "USB3AXH2B",
+ "USB3AXHP2B",
+ "USB3BXHD",
+ "USB3BXHPD",
+ "USB3BXH",
+ "USB3BXHP",
+ "USB3BXH2A",
+ "USB3BXHP2A",
+ "USB2AXHD1",
+ "USB2AXHPD1",
+ "USB2AXH",
+ "USB2AXHP",
+ "USB2AXH2B",
+ "USB2AXHP2B",
+ "USB2AD1",
+ "USB2AHPD0",
+ "USB2AH",
+ "USB2AHP",
+ "USB2AD0",
+ "USB2BXHD1",
+ "USB2BXHPD1",
+ "USB2BXH",
+ "USB2BXHP",
+ "USB2BXH2A",
+ "USB2BXHP2A",
+ "USB2BD1",
+ "USB2BHPD0",
+ "USB2BH",
+ "USB2BHP",
+ "USB2BD0",
+ "JTAGPSP",
+ "JTAGSSP",
+ "JTAGTSP",
+ "JTAGDDR",
+ "JTAGUSB3A",
+ "JTAGUSB3B",
+ "JTAGPCIEA",
+ "JTAGPCIEB",
+ "JTAGM0",
+ "PCIERC0PERST",
+ "PCIERC1PERST",
+};
+
+static const struct ast2700_soc0_pinmux ast2700_soc0_pinmuxes[] = {
+ PINMUX("EMMC", "EMMCG1", SCU400, GENMASK(2, 0), GENMASK(2, 0)),
+ PINMUX("EMMC", "EMMCG4", SCU400, GENMASK(5, 0), GENMASK(5, 0)),
+ PINMUX("EMMC", "EMMCG8", SCU400,
+ GENMASK(5, 0) | GENMASK(11, 8),
+ GENMASK(5, 0) | GENMASK(11, 8)),
+ PINMUX("EMMC", "EMMCWPN", SCU400, BIT(7), BIT(7)),
+ PINMUX("EMMC", "EMMCCDN", SCU400, BIT(6), BIT(6)),
+ PINMUX("VB", "VB1", SCU404, GENMASK(3, 0), GENMASK(3, 0)),
+ PINMUX("VB", "VB0", SCU010, BIT(17), BIT(17)),
+ PINMUX("TSPRSTN", "TSPRSTN", SCU010, BIT(9), BIT(9)),
+ PINMUX("UFSCLKI", "UFSCLKI", SCU010, BIT(19), BIT(19)),
+ PINMUX("VGADDC", "VGADDC", SCU404, GENMASK(11, 10),
+ GENMASK(11, 10)),
+
+ /*
+ * The Linux driver models the USB2/USB3 routing with additional
+ * virtual PHY pins (PORTA/PORTB_U2_PHY, PORTA/PORTB_U3_PHY) purely
+ * to reject conflicting cross-coupled selections; they carry no
+ * register writes. U-Boot applies the states given by the device
+ * tree without strict conflict checking, so only the real selector
+ * fields are programmed here while the group names stay identical.
+ */
+ PINMUX("USB3AXHD", "USB3A", SCU410,
+ PORTA_U3_MODE | USB_PORTA_ROUTE, USB_PORTA_ROUTE),
+ PINMUX("USB3AXHPD", "USB3A", SCU410,
+ PORTA_U3_MODE | USB_PORTA_ROUTE, 0),
+ PINMUX("USB3AXH", "USB3AAP", SCU410,
+ PORTA_U3_MODE | USB_PORTA_ROUTE, (2 << 0) | USB_PORTA_ROUTE),
+ PINMUX("USB3AXHP", "USB3AAP", SCU410,
+ PORTA_U3_MODE | USB_PORTA_ROUTE, 2 << 0),
+ PINMUX("USB3AXH2B", "USB3ABP", SCU410,
+ PORTA_U3_MODE | USB_PORTA_ROUTE, (3 << 0) | USB_PORTA_ROUTE),
+ PINMUX("USB3AXHP2B", "USB3ABP", SCU410,
+ PORTA_U3_MODE | USB_PORTA_ROUTE, 3 << 0),
+
+ PINMUX("USB3BXHD", "USB3B", SCU410,
+ PORTB_U3_MODE | USB_PORTB_ROUTE, USB_PORTB_ROUTE),
+ PINMUX("USB3BXHPD", "USB3B", SCU410,
+ PORTB_U3_MODE | USB_PORTB_ROUTE, 0),
+ PINMUX("USB3BXH", "USB3BBP", SCU410,
+ PORTB_U3_MODE | USB_PORTB_ROUTE, (2 << 4) | USB_PORTB_ROUTE),
+ PINMUX("USB3BXHP", "USB3BBP", SCU410,
+ PORTB_U3_MODE | USB_PORTB_ROUTE, 2 << 4),
+ PINMUX("USB3BXH2A", "USB3BAP", SCU410,
+ PORTB_U3_MODE | USB_PORTB_ROUTE, (3 << 4) | USB_PORTB_ROUTE),
+ PINMUX("USB3BXHP2A", "USB3BAP", SCU410,
+ PORTB_U3_MODE | USB_PORTB_ROUTE, 3 << 4),
+
+ PINMUX("USB2AXHD1", "USB2A", SCU410,
+ PORTA_U2_MODE | USB_PORTA_ROUTE, USB_PORTA_ROUTE),
+ PINMUX("USB2AXHPD1", "USB2A", SCU410,
+ PORTA_U2_MODE | USB_PORTA_ROUTE, 0),
+ PINMUX("USB2AXH", "USB2AAP", SCU410,
+ PORTA_U2_MODE | USB_PORTA_ROUTE, (2 << 2) | USB_PORTA_ROUTE),
+ PINMUX("USB2AXHP", "USB2AAP", SCU410,
+ PORTA_U2_MODE | USB_PORTA_ROUTE, 2 << 2),
+ PINMUX("USB2AXH2B", "USB2ABP", SCU410,
+ PORTA_U2_MODE | USB_PORTA_ROUTE, (3 << 2) | USB_PORTA_ROUTE),
+ PINMUX("USB2AXHP2B", "USB2ABP", SCU410,
+ PORTA_U2_MODE | USB_PORTA_ROUTE, 3 << 2),
+ PINMUX("USB2AD1", "USB2ADAP", SCU410, PORTA_U2_MODE, 1 << 2),
+ PINMUX("USB2AHPD0", "USB2AH", SCU410, PORTA_MODE, 0),
+ PINMUX("USB2AH", "USB2AHAP", SCU410, PORTA_MODE, 2 << 24),
+ PINMUX("USB2AHP", "USB2AHAP", SCU410, PORTA_MODE, 3 << 24),
+ PINMUX("USB2AD0", "USB2AHAP", SCU410, PORTA_MODE, 1 << 24),
+
+ PINMUX("USB2BXHD1", "USB2B", SCU410,
+ PORTB_U2_MODE | USB_PORTB_ROUTE, USB_PORTB_ROUTE),
+ PINMUX("USB2BXHPD1", "USB2B", SCU410,
+ PORTB_U2_MODE | USB_PORTB_ROUTE, 0),
+ PINMUX("USB2BXH", "USB2BBP", SCU410,
+ PORTB_U2_MODE | USB_PORTB_ROUTE, (2 << 6) | USB_PORTB_ROUTE),
+ PINMUX("USB2BXHP", "USB2BBP", SCU410,
+ PORTB_U2_MODE | USB_PORTB_ROUTE, 2 << 6),
+ PINMUX("USB2BXH2A", "USB2BAP", SCU410,
+ PORTB_U2_MODE | USB_PORTB_ROUTE, (3 << 6) | USB_PORTB_ROUTE),
+ PINMUX("USB2BXHP2A", "USB2BAP", SCU410,
+ PORTB_U2_MODE | USB_PORTB_ROUTE, 3 << 6),
+ PINMUX("USB2BD1", "USB2BDBP", SCU410, PORTB_U2_MODE, 1 << 6),
+ PINMUX("USB2BHPD0", "USB2BH", SCU410, PORTB_MODE, 0),
+ PINMUX("USB2BH", "USB2BHBP", SCU410, PORTB_MODE, 2 << 28),
+ PINMUX("USB2BHP", "USB2BHBP", SCU410, PORTB_MODE, 3 << 28),
+ PINMUX("USB2BD0", "USB2BHBP", SCU410, PORTB_MODE, 1 << 28),
+
+ PINMUX("JTAGPSP", "JTAG0", SCU408, GENMASK(12, 5), 0x00 << 5),
+ PINMUX("JTAGSSP", "JTAG0", SCU408, GENMASK(12, 5), 0x41 << 5),
+ PINMUX("JTAGTSP", "JTAG0", SCU408, GENMASK(12, 5), 0x42 << 5),
+ PINMUX("JTAGDDR", "JTAG0", SCU408, GENMASK(12, 5), 0x43 << 5),
+ PINMUX("JTAGUSB3A", "JTAG0", SCU408, GENMASK(12, 5), 0x44 << 5),
+ PINMUX("JTAGUSB3B", "JTAG0", SCU408, GENMASK(12, 5), 0x45 << 5),
+ PINMUX("JTAGPCIEA", "JTAG0", SCU408, GENMASK(12, 5), 0x46 << 5),
+ PINMUX("JTAGPCIEB", "JTAG0", SCU408, GENMASK(12, 5), 0x47 << 5),
+ PINMUX("JTAGM0", "JTAG0", SCU408, GENMASK(12, 5), 0x08 << 5),
+ PINMUX("PCIERC0PERST", "PCIERC0PERST", SCU200, BIT(21), BIT(21)),
+ PINMUX("PCIERC1PERST", "PCIERC1PERST", SCU200, BIT(19), BIT(19)),
+};
+
+/*
+ * Signals muxable on each package ball, strongest first. A pin acts as
+ * GPIO when none of its signal enable bits are set; gpio_request_enable
+ * clears them all. The pin order follows the GPIO18A0..GPIO18B3 numbering
+ * used by the gpio-ranges of the SoC0 GPIO controller.
+ */
+static const struct ast2700_soc0_sig ast2700_soc0_ac14_sigs[] = {
+ { SCU400, BIT(0), "EMMCCLK" },
+ { SCU404, BIT(0), "VB1CS" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ae15_sigs[] = {
+ { SCU400, BIT(1), "EMMCCMD" },
+ { SCU404, BIT(1), "VB1CK" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ad14_sigs[] = {
+ { SCU400, BIT(2), "EMMCDAT0" },
+ { SCU404, BIT(2), "VB1MOSI" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ae14_sigs[] = {
+ { SCU400, BIT(3), "EMMCDAT1" },
+ { SCU404, BIT(3), "VB1MISO" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_af14_sigs[] = {
+ { SCU400, BIT(4), "EMMCDAT2" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ab13_sigs[] = {
+ { SCU400, BIT(5), "EMMCDAT3" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ab14_sigs[] = {
+ { SCU400, BIT(6), "EMMCCDN" },
+ { SCU010, BIT(17), "VB0CS" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_af15_sigs[] = {
+ { SCU400, BIT(7), "EMMCWPN" },
+ { SCU010, BIT(17), "VB0CK" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_af13_sigs[] = {
+ { SCU010, BIT(9), "TSPRSTN" },
+ { SCU400, BIT(8), "EMMCDAT4" },
+ { SCU010, BIT(17), "VB0MOSI" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ac13_sigs[] = {
+ { SCU010, BIT(19), "UFSCLKI" },
+ { SCU400, BIT(9), "EMMCDAT5" },
+ { SCU010, BIT(17), "VB0MISO" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ad13_sigs[] = {
+ { SCU400, BIT(10), "EMMCDAT6" },
+ { SCU404, BIT(10), "DDCCLK" },
+};
+
+static const struct ast2700_soc0_sig ast2700_soc0_ae13_sigs[] = {
+ { SCU400, BIT(11), "EMMCDAT7" },
+ { SCU404, BIT(11), "DDCDAT" },
+};
+
+#define AST2700_SOC0_PIN(_name, _sigs) \
+ { \
+ .name = _name, \
+ .sigs = _sigs, \
+ .nsigs = ARRAY_SIZE(_sigs), \
+ }
+
+static const struct ast2700_soc0_pin ast2700_soc0_pins[] = {
+ AST2700_SOC0_PIN("AC14", ast2700_soc0_ac14_sigs),
+ AST2700_SOC0_PIN("AE15", ast2700_soc0_ae15_sigs),
+ AST2700_SOC0_PIN("AD14", ast2700_soc0_ad14_sigs),
+ AST2700_SOC0_PIN("AE14", ast2700_soc0_ae14_sigs),
+ AST2700_SOC0_PIN("AF14", ast2700_soc0_af14_sigs),
+ AST2700_SOC0_PIN("AB13", ast2700_soc0_ab13_sigs),
+ AST2700_SOC0_PIN("AB14", ast2700_soc0_ab14_sigs),
+ AST2700_SOC0_PIN("AF15", ast2700_soc0_af15_sigs),
+ AST2700_SOC0_PIN("AF13", ast2700_soc0_af13_sigs),
+ AST2700_SOC0_PIN("AC13", ast2700_soc0_ac13_sigs),
+ AST2700_SOC0_PIN("AD13", ast2700_soc0_ad13_sigs),
+ AST2700_SOC0_PIN("AE13", ast2700_soc0_ae13_sigs),
+};
+
+static int ast2700_soc0_pinctrl_probe(struct udevice *dev)
+{
+ struct ast2700_soc0_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_remap_addr(dev->parent);
+ if (!priv->base)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int ast2700_soc0_pinctrl_get_groups_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(ast2700_soc0_groups);
+}
+
+static const char *ast2700_soc0_pinctrl_get_group_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return ast2700_soc0_groups[selector].name;
+}
+
+static int ast2700_soc0_pinctrl_get_functions_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(ast2700_soc0_functions);
+}
+
+static const char *ast2700_soc0_pinctrl_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return ast2700_soc0_functions[selector];
+}
+
+static int ast2700_soc0_pinctrl_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int func_selector)
+{
+ struct ast2700_soc0_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct ast2700_soc0_pinmux *pinmux;
+ const char *function;
+ const char *group;
+ u32 i;
+
+ if (group_selector >= ARRAY_SIZE(ast2700_soc0_groups) ||
+ func_selector >= ARRAY_SIZE(ast2700_soc0_functions))
+ return -EINVAL;
+
+ function = ast2700_soc0_functions[func_selector];
+ group = ast2700_soc0_groups[group_selector].name;
+
+ for (i = 0; i < ARRAY_SIZE(ast2700_soc0_pinmuxes); i++) {
+ pinmux = &ast2700_soc0_pinmuxes[i];
+ if (strcmp(pinmux->function, function) ||
+ strcmp(pinmux->group, group))
+ continue;
+
+ clrsetbits_le32(priv->base + pinmux->offset, pinmux->mask,
+ pinmux->val);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int ast2700_soc0_pinctrl_gpio_request_enable(struct udevice *dev,
+ unsigned int selector)
+{
+ struct ast2700_soc0_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct ast2700_soc0_pin *pin;
+ u32 i;
+
+ if (selector >= ARRAY_SIZE(ast2700_soc0_pins))
+ return -EINVAL;
+
+ pin = &ast2700_soc0_pins[selector];
+ for (i = 0; i < pin->nsigs; i++)
+ clrbits_le32(priv->base + pin->sigs[i].offset,
+ pin->sigs[i].mask);
+
+ return 0;
+}
+
+static int ast2700_soc0_pinctrl_get_pins_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(ast2700_soc0_pins);
+}
+
+static const char *ast2700_soc0_pinctrl_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ if (selector >= ARRAY_SIZE(ast2700_soc0_pins))
+ return NULL;
+
+ return ast2700_soc0_pins[selector].name;
+}
+
+static int ast2700_soc0_pinctrl_get_pin_muxing(struct udevice *dev,
+ unsigned int selector,
+ char *buf, int size)
+{
+ struct ast2700_soc0_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct ast2700_soc0_pin *pin;
+ const struct ast2700_soc0_sig *sig;
+ u32 i;
+
+ if (selector >= ARRAY_SIZE(ast2700_soc0_pins))
+ return -EINVAL;
+
+ pin = &ast2700_soc0_pins[selector];
+ for (i = 0; i < pin->nsigs; i++) {
+ sig = &pin->sigs[i];
+ if ((readl(priv->base + sig->offset) & sig->mask) ==
+ sig->mask) {
+ snprintf(buf, size, "%s", sig->name);
+ return 0;
+ }
+ }
+
+ snprintf(buf, size, "GPIO");
+
+ return 0;
+}
+
+/* Drive strength in mA selectable by the IO control register [3:0] */
+static const u8 ast2700_soc0_drv_ma[] = {
+ 3, 6, 8, 11, 16, 18, 20, 23, 30, 32, 33, 35, 37, 38, 39, 41,
+};
+
+static const struct pinconf_param ast2700_soc0_pinconf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 0 },
+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 0 },
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+};
+
+static int ast2700_soc0_pinctrl_pinconf_set(struct udevice *dev,
+ unsigned int selector,
+ unsigned int param,
+ unsigned int arg)
+{
+ struct ast2700_soc0_pinctrl_priv *priv = dev_get_priv(dev);
+ u32 mask, val, i;
+
+ if (selector >= ARRAY_SIZE(ast2700_soc0_pins))
+ return -EINVAL;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ mask = BIT(5);
+ val = 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ mask = GENMASK(5, 4);
+ val = 2 << 4;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ mask = GENMASK(5, 4);
+ val = 3 << 4;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ for (i = 0; i < ARRAY_SIZE(ast2700_soc0_drv_ma); i++) {
+ if (ast2700_soc0_drv_ma[i] == arg)
+ break;
+ }
+ if (i == ARRAY_SIZE(ast2700_soc0_drv_ma))
+ return -EINVAL;
+ mask = GENMASK(3, 0);
+ val = i;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ clrsetbits_le32(priv->base + SCU480 + selector * 4, mask, val);
+
+ return 0;
+}
+
+static int ast2700_soc0_pinctrl_pinconf_group_set(struct udevice *dev,
+ unsigned int selector,
+ unsigned int param,
+ unsigned int arg)
+{
+ const struct ast2700_soc0_group *group;
+ u32 i;
+ int ret;
+
+ if (selector >= ARRAY_SIZE(ast2700_soc0_groups))
+ return -EINVAL;
+
+ group = &ast2700_soc0_groups[selector];
+ if (!group->npins)
+ return -ENOTSUPP;
+
+ for (i = 0; i < group->npins; i++) {
+ ret = ast2700_soc0_pinctrl_pinconf_set(dev, group->pins[i],
+ param, arg);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct pinctrl_ops ast2700_soc0_pinctrl_ops = {
+ .set_state = pinctrl_generic_set_state,
+ .get_pins_count = ast2700_soc0_pinctrl_get_pins_count,
+ .get_pin_name = ast2700_soc0_pinctrl_get_pin_name,
+ .get_pin_muxing = ast2700_soc0_pinctrl_get_pin_muxing,
+ .get_groups_count = ast2700_soc0_pinctrl_get_groups_count,
+ .get_group_name = ast2700_soc0_pinctrl_get_group_name,
+ .get_functions_count = ast2700_soc0_pinctrl_get_functions_count,
+ .get_function_name = ast2700_soc0_pinctrl_get_function_name,
+ .pinmux_group_set = ast2700_soc0_pinctrl_group_set,
+ .gpio_request_enable = ast2700_soc0_pinctrl_gpio_request_enable,
+ .pinconf_num_params = ARRAY_SIZE(ast2700_soc0_pinconf_params),
+ .pinconf_params = ast2700_soc0_pinconf_params,
+ .pinconf_set = ast2700_soc0_pinctrl_pinconf_set,
+ .pinconf_group_set = ast2700_soc0_pinctrl_pinconf_group_set,
+};
+
+static const struct udevice_id ast2700_soc0_pinctrl_ids[] = {
+ { .compatible = "aspeed,ast2700-soc0-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_ast2700_soc0) = {
+ .name = "aspeed_ast2700_soc0_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = ast2700_soc0_pinctrl_ids,
+ .priv_auto = sizeof(struct ast2700_soc0_pinctrl_priv),
+ .ops = &ast2700_soc0_pinctrl_ops,
+ .probe = ast2700_soc0_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2700_soc1.c b/drivers/pinctrl/aspeed/pinctrl_ast2700_soc1.c
new file mode 100644
index 00000000000..05656c38ad2
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2700_soc1.c
@@ -0,0 +1,1642 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 ASPEED Technology Inc.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <errno.h>
+#include <vsprintf.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#define AST2700_SOC1_MUX_BASE 0x400
+#define AST2700_SOC1_PCIE_REG 0x908
+#define AST2700_SOC1_USB_MODE_REG 0x3b0
+#define AST2700_SOC1_SGMII_REG 0x47c
+#define AST2700_SOC1_MUX_MASK 0x7
+#define AST2700_SOC1_MUX_BITS_PER_PIN 4
+#define AST2700_SOC1_MUX_PINS_PER_REG 8
+
+#define AST2700_SOC1_BIAS_BASE 0x480
+#define AST2700_SOC1_BIAS_PINS_PER_REG 32
+
+#define AST2700_SOC1_DRV_BASE 0x4c0
+#define AST2700_SOC1_DRV_MASK 0x3
+#define AST2700_SOC1_DRV_BITS_PER_PIN 2
+#define AST2700_SOC1_DRV_PINS_PER_REG 16
+#define AST2700_SOC1_DRV_STEP_MA 4
+#define AST2700_SOC1_DRV_MIN_MA 4
+#define AST2700_SOC1_DRV_MAX_MA 16
+
+enum {
+ C16,
+ C14,
+ C11,
+ D9,
+ F14,
+ D10,
+ C12,
+ C13,
+ AC26,
+ AA25,
+ AB23,
+ U22,
+ V21,
+ N26,
+ P25,
+ N25,
+ V23,
+ W22,
+ AB26,
+ AD26,
+ P26,
+ AE26,
+ AF26,
+ AF25,
+ AE25,
+ AD25,
+ AF23,
+ AF20,
+ AF21,
+ AE21,
+ AE23,
+ AD22,
+ AF17,
+ AA16,
+ Y16,
+ V17,
+ J13,
+ AB16,
+ AC16,
+ AF16,
+ AA15,
+ AB15,
+ AC15,
+ AD15,
+ Y15,
+ AA14,
+ W16,
+ V16,
+ AB18,
+ AC18,
+ K13,
+ AA17,
+ AB17,
+ AD16,
+ AC17,
+ AD17,
+ AE16,
+ AE17,
+ AB24,
+ W26,
+ HOLE0,
+ HOLE1,
+ HOLE2,
+ HOLE3,
+ W25,
+ Y23,
+ Y24,
+ W21,
+ AA23,
+ AC22,
+ AB22,
+ Y21,
+ AE20,
+ AF19,
+ Y22,
+ AA20,
+ AA22,
+ AB20,
+ AF18,
+ AE19,
+ AD20,
+ AC20,
+ AA21,
+ AB21,
+ AC19,
+ AE18,
+ AD19,
+ AD18,
+ U25,
+ U26,
+ Y26,
+ AA24,
+ R25,
+ AA26,
+ R26,
+ Y25,
+ B16,
+ D14,
+ B15,
+ B14,
+ C17,
+ B13,
+ E14,
+ C15,
+ D24,
+ B23,
+ B22,
+ C23,
+ B18,
+ B21,
+ M15,
+ B19,
+ B26,
+ A25,
+ A24,
+ B24,
+ E26,
+ A21,
+ A19,
+ A18,
+ D26,
+ C26,
+ A23,
+ A22,
+ B25,
+ F26,
+ A26,
+ A14,
+ E10,
+ E13,
+ D12,
+ F10,
+ E11,
+ F11,
+ F13,
+ N15,
+ C20,
+ C19,
+ A8,
+ R14,
+ A7,
+ P14,
+ D20,
+ A6,
+ B6,
+ N14,
+ B7,
+ B8,
+ B9,
+ M14,
+ J11,
+ E7,
+ D19,
+ B11,
+ D15,
+ B12,
+ B10,
+ P13,
+ C18,
+ C6,
+ C7,
+ D7,
+ N13,
+ C8,
+ C9,
+ C10,
+ M16,
+ A15,
+ G11,
+ H7,
+ H8,
+ H9,
+ H10,
+ H11,
+ J9,
+ J10,
+ E9,
+ F9,
+ F8,
+ M13,
+ F7,
+ D8,
+ E8,
+ L12,
+ F12,
+ E12,
+ J12,
+ G7,
+ G8,
+ G9,
+ G10,
+ K12,
+ W17,
+ V18,
+ W18,
+ Y17,
+ AA18,
+ AA13,
+ Y18,
+ AA12,
+ W20,
+ V20,
+ Y11,
+ V14,
+ V19,
+ W14,
+ Y20,
+ AB19,
+ U21,
+ T24,
+ V24,
+ V22,
+ T23,
+ AC25,
+ AB25,
+ AC24,
+ PCIERC2_PERST,
+ PORTC_MODE,
+ PORTD_MODE,
+ SGMII0,
+};
+
+struct ast2700_soc1_field {
+ u32 reg;
+ u32 shift;
+ u32 mask;
+};
+
+struct ast2700_soc1_group {
+ const char *name;
+ const unsigned int *pins;
+ unsigned int npins;
+};
+
+struct ast2700_soc1_function {
+ const char *name;
+ const char *const *groups;
+ const u8 *muxvals;
+ unsigned int ngroups;
+};
+
+struct ast2700_soc1_pinctrl_priv {
+ void __iomem *scu;
+};
+
+#define PIN(n) \
+ [n] = #n
+
+static const char *const ast2700_soc1_pin_names[] = {
+ PIN(C16),
+ PIN(C14),
+ PIN(C11),
+ PIN(D9),
+ PIN(F14),
+ PIN(D10),
+ PIN(C12),
+ PIN(C13),
+ PIN(AC26),
+ PIN(AA25),
+ PIN(AB23),
+ PIN(U22),
+ PIN(V21),
+ PIN(N26),
+ PIN(P25),
+ PIN(N25),
+ PIN(V23),
+ PIN(W22),
+ PIN(AB26),
+ PIN(AD26),
+ PIN(P26),
+ PIN(AE26),
+ PIN(AF26),
+ PIN(AF25),
+ PIN(AE25),
+ PIN(AD25),
+ PIN(AF23),
+ PIN(AF20),
+ PIN(AF21),
+ PIN(AE21),
+ PIN(AE23),
+ PIN(AD22),
+ PIN(AF17),
+ PIN(AA16),
+ PIN(Y16),
+ PIN(V17),
+ PIN(J13),
+ PIN(AB16),
+ PIN(AC16),
+ PIN(AF16),
+ PIN(AA15),
+ PIN(AB15),
+ PIN(AC15),
+ PIN(AD15),
+ PIN(Y15),
+ PIN(AA14),
+ PIN(W16),
+ PIN(V16),
+ PIN(AB18),
+ PIN(AC18),
+ PIN(K13),
+ PIN(AA17),
+ PIN(AB17),
+ PIN(AD16),
+ PIN(AC17),
+ PIN(AD17),
+ PIN(AE16),
+ PIN(AE17),
+ PIN(AB24),
+ PIN(W26),
+ PIN(HOLE0),
+ PIN(HOLE1),
+ PIN(HOLE2),
+ PIN(HOLE3),
+ PIN(W25),
+ PIN(Y23),
+ PIN(Y24),
+ PIN(W21),
+ PIN(AA23),
+ PIN(AC22),
+ PIN(AB22),
+ PIN(Y21),
+ PIN(AE20),
+ PIN(AF19),
+ PIN(Y22),
+ PIN(AA20),
+ PIN(AA22),
+ PIN(AB20),
+ PIN(AF18),
+ PIN(AE19),
+ PIN(AD20),
+ PIN(AC20),
+ PIN(AA21),
+ PIN(AB21),
+ PIN(AC19),
+ PIN(AE18),
+ PIN(AD19),
+ PIN(AD18),
+ PIN(U25),
+ PIN(U26),
+ PIN(Y26),
+ PIN(AA24),
+ PIN(R25),
+ PIN(AA26),
+ PIN(R26),
+ PIN(Y25),
+ PIN(B16),
+ PIN(D14),
+ PIN(B15),
+ PIN(B14),
+ PIN(C17),
+ PIN(B13),
+ PIN(E14),
+ PIN(C15),
+ PIN(D24),
+ PIN(B23),
+ PIN(B22),
+ PIN(C23),
+ PIN(B18),
+ PIN(B21),
+ PIN(M15),
+ PIN(B19),
+ PIN(B26),
+ PIN(A25),
+ PIN(A24),
+ PIN(B24),
+ PIN(E26),
+ PIN(A21),
+ PIN(A19),
+ PIN(A18),
+ PIN(D26),
+ PIN(C26),
+ PIN(A23),
+ PIN(A22),
+ PIN(B25),
+ PIN(F26),
+ PIN(A26),
+ PIN(A14),
+ PIN(E10),
+ PIN(E13),
+ PIN(D12),
+ PIN(F10),
+ PIN(E11),
+ PIN(F11),
+ PIN(F13),
+ PIN(N15),
+ PIN(C20),
+ PIN(C19),
+ PIN(A8),
+ PIN(R14),
+ PIN(A7),
+ PIN(P14),
+ PIN(D20),
+ PIN(A6),
+ PIN(B6),
+ PIN(N14),
+ PIN(B7),
+ PIN(B8),
+ PIN(B9),
+ PIN(M14),
+ PIN(J11),
+ PIN(E7),
+ PIN(D19),
+ PIN(B11),
+ PIN(D15),
+ PIN(B12),
+ PIN(B10),
+ PIN(P13),
+ PIN(C18),
+ PIN(C6),
+ PIN(C7),
+ PIN(D7),
+ PIN(N13),
+ PIN(C8),
+ PIN(C9),
+ PIN(C10),
+ PIN(M16),
+ PIN(A15),
+ PIN(G11),
+ PIN(H7),
+ PIN(H8),
+ PIN(H9),
+ PIN(H10),
+ PIN(H11),
+ PIN(J9),
+ PIN(J10),
+ PIN(E9),
+ PIN(F9),
+ PIN(F8),
+ PIN(M13),
+ PIN(F7),
+ PIN(D8),
+ PIN(E8),
+ PIN(L12),
+ PIN(F12),
+ PIN(E12),
+ PIN(J12),
+ PIN(G7),
+ PIN(G8),
+ PIN(G9),
+ PIN(G10),
+ PIN(K12),
+ PIN(W17),
+ PIN(V18),
+ PIN(W18),
+ PIN(Y17),
+ PIN(AA18),
+ PIN(AA13),
+ PIN(Y18),
+ PIN(AA12),
+ PIN(W20),
+ PIN(V20),
+ PIN(Y11),
+ PIN(V14),
+ PIN(V19),
+ PIN(W14),
+ PIN(Y20),
+ PIN(AB19),
+ PIN(U21),
+ PIN(T24),
+ PIN(V24),
+ PIN(V22),
+ PIN(T23),
+ PIN(AC25),
+ PIN(AB25),
+ PIN(AC24),
+ PIN(PCIERC2_PERST),
+ PIN(PORTC_MODE),
+ PIN(PORTD_MODE),
+ PIN(SGMII0),
+};
+
+#define PIN_GROUP(name, ...) \
+ static const unsigned int name##_pins[] = { __VA_ARGS__ }
+
+/* Pin groups and functions */
+PIN_GROUP(ADC0, W17);
+PIN_GROUP(ADC1, V18);
+PIN_GROUP(ADC10, Y11);
+PIN_GROUP(ADC11, V14);
+PIN_GROUP(ADC12, V19);
+PIN_GROUP(ADC13, W14);
+PIN_GROUP(ADC14, Y20);
+PIN_GROUP(ADC15, AB19);
+PIN_GROUP(ADC2, W18);
+PIN_GROUP(ADC3, Y17);
+PIN_GROUP(ADC4, AA18);
+PIN_GROUP(ADC5, AA13);
+PIN_GROUP(ADC6, Y18);
+PIN_GROUP(ADC7, AA12);
+PIN_GROUP(ADC8, W20);
+PIN_GROUP(ADC9, V20);
+PIN_GROUP(AUXPWRGOOD0, W14);
+PIN_GROUP(AUXPWRGOOD1, Y20);
+PIN_GROUP(CANBUS, G7, G8, G9);
+PIN_GROUP(DI2C0, C16, D9);
+PIN_GROUP(DI2C1, C14, F14);
+PIN_GROUP(DI2C10, R25, AA26);
+PIN_GROUP(DI2C11, R26, Y25);
+PIN_GROUP(DI2C12, W25, Y23);
+PIN_GROUP(DI2C13, Y24, W21);
+PIN_GROUP(DI2C14, AA23, AC22);
+PIN_GROUP(DI2C15, AB22, Y21);
+PIN_GROUP(DI2C2, D10, C12);
+PIN_GROUP(DI2C3, C11, C13);
+PIN_GROUP(DI2C8, U25, U26);
+PIN_GROUP(DI2C9, Y26, AA24);
+PIN_GROUP(DSGPM0, D19, B10, C7, D7);
+PIN_GROUP(ESPI0, B16, D14, B15, B14, C17, B13, E14, C15);
+PIN_GROUP(ESPI1, C16, C14, C11, D9, F14, D10, C12, C13);
+PIN_GROUP(FSI0, AD20, AC20);
+PIN_GROUP(FSI1, AA21, AB21);
+PIN_GROUP(FSI2, AC19, AE18);
+PIN_GROUP(FSI3, AD19, AD18);
+PIN_GROUP(FWQSPI, M16, A15);
+PIN_GROUP(FWSPIABR, A14);
+PIN_GROUP(FWWPN, N15);
+PIN_GROUP(HBLED, V24);
+PIN_GROUP(HVI3C0, U25, U26);
+PIN_GROUP(HVI3C1, Y26, AA24);
+PIN_GROUP(HVI3C12, W25, Y23);
+PIN_GROUP(HVI3C13, Y24, W21);
+PIN_GROUP(HVI3C14, AA23, AC22);
+PIN_GROUP(HVI3C15, AB22, Y21);
+PIN_GROUP(HVI3C2, R25, AA26);
+PIN_GROUP(HVI3C3, R26, Y25);
+PIN_GROUP(I2C0, G11, H7);
+PIN_GROUP(I2C1, H8, H9);
+PIN_GROUP(I2C10, G8, G9);
+PIN_GROUP(I2C11, G10, K12);
+PIN_GROUP(I2C12, AC18, AA17);
+PIN_GROUP(I2C13, AB17, AD16);
+PIN_GROUP(I2C14, AC17, AD17);
+PIN_GROUP(I2C15, AE16, AE17);
+PIN_GROUP(I2C2, H10, H11);
+PIN_GROUP(I2C3, J9, J10);
+PIN_GROUP(I2C4, E9, F9);
+PIN_GROUP(I2C5, F8, M13);
+PIN_GROUP(I2C6, F7, D8);
+PIN_GROUP(I2C7, E8, L12);
+PIN_GROUP(I2C8, F12, E12);
+PIN_GROUP(I2C9, J12, G7);
+PIN_GROUP(I2CF0, F12, E12, J12, G7);
+PIN_GROUP(I2CF1, E9, F9, F8, M13);
+PIN_GROUP(I2CF2, F7, D8, E8, L12);
+PIN_GROUP(I3C10, AC19, AE18);
+PIN_GROUP(I3C11, AD19, AD18);
+PIN_GROUP(I3C4, AE20, AF19);
+PIN_GROUP(I3C5, Y22, AA20);
+PIN_GROUP(I3C6, AA22, AB20);
+PIN_GROUP(I3C7, AF18, AE19);
+PIN_GROUP(I3C8, AD20, AC20);
+PIN_GROUP(I3C9, AA21, AB21);
+PIN_GROUP(JTAGM1, D12, F10, E11, F11, F13);
+PIN_GROUP(LPC0, AF26, AF25, B16, D14, B15, B14, C17, B13, E14, C15);
+PIN_GROUP(LPC1, C16, C14, C11, D9, F14, D10, C12, C13, AE16, AE17);
+PIN_GROUP(LTPI, U25, U26, Y26, AA24);
+PIN_GROUP(LTPI_PS_I2C0, G11, H7);
+PIN_GROUP(LTPI_PS_I2C1, H8, H9);
+PIN_GROUP(LTPI_PS_I2C2, H10, H11);
+PIN_GROUP(LTPI_PS_I2C3, J9, J10);
+PIN_GROUP(MACLINK0, U21);
+PIN_GROUP(MACLINK1, AC24);
+PIN_GROUP(MACLINK2, T24);
+PIN_GROUP(MDIO0, B9, M14);
+PIN_GROUP(MDIO1, C9, C10);
+PIN_GROUP(MDIO2, E10, E13);
+PIN_GROUP(NCTS0, AF17);
+PIN_GROUP(NCTS1, AA15);
+PIN_GROUP(NCTS5, V21);
+PIN_GROUP(NCTS6, AB26);
+PIN_GROUP(NDCD0, AA16);
+PIN_GROUP(NDCD1, AB15);
+PIN_GROUP(NDCD5, N26);
+PIN_GROUP(NDCD6, AD26);
+PIN_GROUP(NDSR0, Y16);
+PIN_GROUP(NDSR1, AC15);
+PIN_GROUP(NDSR5, P25);
+PIN_GROUP(NDSR6, P26);
+PIN_GROUP(NDTR0, J13);
+PIN_GROUP(NDTR1, Y15);
+PIN_GROUP(NDTR5, V23);
+PIN_GROUP(NDTR6, AF26);
+PIN_GROUP(NRI0, V17);
+PIN_GROUP(NRI1, AD15);
+PIN_GROUP(NRI5, N25);
+PIN_GROUP(NRI6, AE26);
+PIN_GROUP(NRTS0, AB16);
+PIN_GROUP(NRTS1, AA14);
+PIN_GROUP(NRTS5, W22);
+PIN_GROUP(NRTS6, AF25);
+PIN_GROUP(OSCCLK, C17);
+PIN_GROUP(PE2SGRSTN, E10, PCIERC2_PERST);
+PIN_GROUP(PWM0, AE25);
+PIN_GROUP(PWM1, AD25);
+PIN_GROUP(PWM10, AB17);
+PIN_GROUP(PWM11, AD16);
+PIN_GROUP(PWM12, AC17);
+PIN_GROUP(PWM13, AD17);
+PIN_GROUP(PWM14, AE16);
+PIN_GROUP(PWM15, AE17);
+PIN_GROUP(PWM2, AF23);
+PIN_GROUP(PWM3, AF20);
+PIN_GROUP(PWM4, AF21);
+PIN_GROUP(PWM5, AE21);
+PIN_GROUP(PWM6, AE23);
+PIN_GROUP(PWM7, AD22);
+PIN_GROUP(PWM8, K13);
+PIN_GROUP(PWM9, AA17);
+PIN_GROUP(QSPI0, C23, B18);
+PIN_GROUP(QSPI1, B24, E26);
+PIN_GROUP(QSPI2, B25, F26);
+PIN_GROUP(RGMII0, C20, C19, A8, R14, A7, P14, D20, A6, B6, N14, B7, B8);
+PIN_GROUP(RGMII1, D19, B11, D15, B12, B10, P13, C18, C6, C7, D7, N13, C8);
+PIN_GROUP(RMII0, C20, A8, R14, A7, P14, A6, B6, N14);
+PIN_GROUP(RMII0RCLKO, D20);
+PIN_GROUP(RMII1, D19, D15, B12, B10, P13, C6, C7, D7);
+PIN_GROUP(RMII1RCLKO, C18);
+PIN_GROUP(SALT0, AC17);
+PIN_GROUP(SALT1, AD17);
+PIN_GROUP(SALT10, Y18);
+PIN_GROUP(SALT11, AA12);
+PIN_GROUP(SALT12, AB26);
+PIN_GROUP(SALT13, AD26);
+PIN_GROUP(SALT14, P26);
+PIN_GROUP(SALT15, AE26);
+PIN_GROUP(SALT2, AC15);
+PIN_GROUP(SALT3, AD15);
+PIN_GROUP(SALT4, W17);
+PIN_GROUP(SALT5, V18);
+PIN_GROUP(SALT6, W18);
+PIN_GROUP(SALT7, Y17);
+PIN_GROUP(SALT8, AA18);
+PIN_GROUP(SALT9, AA13);
+PIN_GROUP(SD, C16, C14, C11, D9, F14, D10, C12, C13);
+PIN_GROUP(SGMII, SGMII0);
+PIN_GROUP(SGPM0, U21, T24, V22, T23);
+PIN_GROUP(SGPM1, AC25, AB25, AB24, W26);
+PIN_GROUP(SGPS, B11, C18, N13, C8);
+PIN_GROUP(SIOONCTRLN0, AE23);
+PIN_GROUP(SIOONCTRLN1, AA15);
+PIN_GROUP(SIOPBIN0, AD25);
+PIN_GROUP(SIOPBIN1, AA16);
+PIN_GROUP(SIOPBON0, AE25);
+PIN_GROUP(SIOPBON1, AF17);
+PIN_GROUP(SIOPWREQN0, AE21);
+PIN_GROUP(SIOPWREQN1, AB16);
+PIN_GROUP(SIOPWRGD1, AB15);
+PIN_GROUP(SIOS3N0, AF20);
+PIN_GROUP(SIOS3N1, V17);
+PIN_GROUP(SIOS5N0, AF21);
+PIN_GROUP(SIOS5N1, J13);
+PIN_GROUP(SIOSCIN0, AF23);
+PIN_GROUP(SIOSCIN1, Y16);
+PIN_GROUP(SMON0, U21, T24, V22, T23);
+PIN_GROUP(SMON1, W26, AC25, AB25);
+PIN_GROUP(SPI0, D24, B23, B22);
+PIN_GROUP(SPI0ABR, M15);
+PIN_GROUP(SPI0CS1, B21);
+PIN_GROUP(SPI0WPN, B19);
+PIN_GROUP(SPI1, B26, A25, A24);
+PIN_GROUP(SPI1ABR, A19);
+PIN_GROUP(SPI1CS1, A21);
+PIN_GROUP(SPI1WPN, A18);
+PIN_GROUP(SPI2, D26, C26, A23, A22);
+PIN_GROUP(SPI2CS1, A26);
+PIN_GROUP(TACH0, AC26);
+PIN_GROUP(TACH1, AA25);
+PIN_GROUP(TACH10, AB26);
+PIN_GROUP(TACH11, AD26);
+PIN_GROUP(TACH12, P26);
+PIN_GROUP(TACH13, AE26);
+PIN_GROUP(TACH14, AF26);
+PIN_GROUP(TACH15, AF25);
+PIN_GROUP(TACH2, AB23);
+PIN_GROUP(TACH3, U22);
+PIN_GROUP(TACH4, V21);
+PIN_GROUP(TACH5, N26);
+PIN_GROUP(TACH6, P25);
+PIN_GROUP(TACH7, N25);
+PIN_GROUP(TACH8, V23);
+PIN_GROUP(TACH9, W22);
+PIN_GROUP(THRU0, AC26, AA25);
+PIN_GROUP(THRU1, AB23, U22);
+PIN_GROUP(THRU2, A19, A18);
+PIN_GROUP(THRU3, B25, F26);
+PIN_GROUP(UART0, AC16, AF16);
+PIN_GROUP(UART1, W16, V16);
+PIN_GROUP(UART2, AB18, AC18);
+PIN_GROUP(UART3, K13, AA17);
+PIN_GROUP(UART5, AB17, AD16);
+PIN_GROUP(UART6, AC17, AD17);
+PIN_GROUP(UART7, AE16, AE17);
+PIN_GROUP(UART8, M15, B19);
+PIN_GROUP(UART9, B26, A25);
+PIN_GROUP(UART10, A24, B24);
+PIN_GROUP(UART11, E26, A21);
+PIN_GROUP(USB2CD, PORTC_MODE);
+PIN_GROUP(USB2CH, PORTC_MODE);
+PIN_GROUP(USB2CU, PORTC_MODE);
+PIN_GROUP(USB2CUD, PORTC_MODE);
+PIN_GROUP(USB2DD, PORTD_MODE);
+PIN_GROUP(USB2DH, PORTD_MODE);
+PIN_GROUP(USBUART, G10, K12);
+PIN_GROUP(VGA, J11, E7);
+PIN_GROUP(VPI, C16, C14, C11, D9, F14, D10, AC26, AA25, AB23, U22, V21, N26,
+ P25, N25, V23, W22, AB26, AD26, P26, AE26, AF26, AF25, AE25, AD25,
+ AF23, AF20, AF21, AE21);
+PIN_GROUP(WDTRST0N, K13);
+PIN_GROUP(WDTRST1N, AA17);
+PIN_GROUP(WDTRST2N, AB17);
+PIN_GROUP(WDTRST3N, AD16);
+PIN_GROUP(WDTRST4N, AC25);
+PIN_GROUP(WDTRST5N, AB25);
+PIN_GROUP(WDTRST6N, AC24);
+PIN_GROUP(WDTRST7N, AB24);
+
+#define GROUP(n) \
+ { .name = #n, .pins = n##_pins, .npins = ARRAY_SIZE(n##_pins) }
+
+static const struct ast2700_soc1_group ast2700_soc1_groups[] = {
+ GROUP(ADC0),
+ GROUP(ADC1),
+ GROUP(ADC10),
+ GROUP(ADC11),
+ GROUP(ADC12),
+ GROUP(ADC13),
+ GROUP(ADC14),
+ GROUP(ADC15),
+ GROUP(ADC2),
+ GROUP(ADC3),
+ GROUP(ADC4),
+ GROUP(ADC5),
+ GROUP(ADC6),
+ GROUP(ADC7),
+ GROUP(ADC8),
+ GROUP(ADC9),
+ GROUP(AUXPWRGOOD0),
+ GROUP(AUXPWRGOOD1),
+ GROUP(CANBUS),
+ GROUP(DI2C0),
+ GROUP(DI2C1),
+ GROUP(DI2C10),
+ GROUP(DI2C11),
+ GROUP(DI2C12),
+ GROUP(DI2C13),
+ GROUP(DI2C14),
+ GROUP(DI2C15),
+ GROUP(DI2C2),
+ GROUP(DI2C3),
+ GROUP(DI2C8),
+ GROUP(DI2C9),
+ GROUP(DSGPM0),
+ GROUP(ESPI0),
+ GROUP(ESPI1),
+ GROUP(FSI0),
+ GROUP(FSI1),
+ GROUP(FSI2),
+ GROUP(FSI3),
+ GROUP(FWQSPI),
+ GROUP(FWSPIABR),
+ GROUP(FWWPN),
+ GROUP(HBLED),
+ GROUP(HVI3C0),
+ GROUP(HVI3C1),
+ GROUP(HVI3C12),
+ GROUP(HVI3C13),
+ GROUP(HVI3C14),
+ GROUP(HVI3C15),
+ GROUP(HVI3C2),
+ GROUP(HVI3C3),
+ GROUP(I2C0),
+ GROUP(I2C1),
+ GROUP(I2C10),
+ GROUP(I2C11),
+ GROUP(I2C12),
+ GROUP(I2C13),
+ GROUP(I2C14),
+ GROUP(I2C15),
+ GROUP(I2C2),
+ GROUP(I2C3),
+ GROUP(I2C4),
+ GROUP(I2C5),
+ GROUP(I2C6),
+ GROUP(I2C7),
+ GROUP(I2C8),
+ GROUP(I2C9),
+ GROUP(I2CF0),
+ GROUP(I2CF1),
+ GROUP(I2CF2),
+ GROUP(I3C10),
+ GROUP(I3C11),
+ GROUP(I3C4),
+ GROUP(I3C5),
+ GROUP(I3C6),
+ GROUP(I3C7),
+ GROUP(I3C8),
+ GROUP(I3C9),
+ GROUP(JTAGM1),
+ GROUP(LPC0),
+ GROUP(LPC1),
+ GROUP(LTPI),
+ GROUP(LTPI_PS_I2C0),
+ GROUP(LTPI_PS_I2C1),
+ GROUP(LTPI_PS_I2C2),
+ GROUP(LTPI_PS_I2C3),
+ GROUP(MACLINK0),
+ GROUP(MACLINK1),
+ GROUP(MACLINK2),
+ GROUP(MDIO0),
+ GROUP(MDIO1),
+ GROUP(MDIO2),
+ GROUP(NCTS0),
+ GROUP(NCTS1),
+ GROUP(NCTS5),
+ GROUP(NCTS6),
+ GROUP(NDCD0),
+ GROUP(NDCD1),
+ GROUP(NDCD5),
+ GROUP(NDCD6),
+ GROUP(NDSR0),
+ GROUP(NDSR1),
+ GROUP(NDSR5),
+ GROUP(NDSR6),
+ GROUP(NDTR0),
+ GROUP(NDTR1),
+ GROUP(NDTR5),
+ GROUP(NDTR6),
+ GROUP(NRI0),
+ GROUP(NRI1),
+ GROUP(NRI5),
+ GROUP(NRI6),
+ GROUP(NRTS0),
+ GROUP(NRTS1),
+ GROUP(NRTS5),
+ GROUP(NRTS6),
+ GROUP(OSCCLK),
+ GROUP(PE2SGRSTN),
+ GROUP(PWM0),
+ GROUP(PWM1),
+ GROUP(PWM10),
+ GROUP(PWM11),
+ GROUP(PWM12),
+ GROUP(PWM13),
+ GROUP(PWM14),
+ GROUP(PWM15),
+ GROUP(PWM2),
+ GROUP(PWM3),
+ GROUP(PWM4),
+ GROUP(PWM5),
+ GROUP(PWM6),
+ GROUP(PWM7),
+ GROUP(PWM8),
+ GROUP(PWM9),
+ GROUP(QSPI0),
+ GROUP(QSPI1),
+ GROUP(QSPI2),
+ GROUP(RGMII0),
+ GROUP(RGMII1),
+ GROUP(RMII0),
+ GROUP(RMII0RCLKO),
+ GROUP(RMII1),
+ GROUP(RMII1RCLKO),
+ GROUP(SALT0),
+ GROUP(SALT1),
+ GROUP(SALT10),
+ GROUP(SALT11),
+ GROUP(SALT12),
+ GROUP(SALT13),
+ GROUP(SALT14),
+ GROUP(SALT15),
+ GROUP(SALT2),
+ GROUP(SALT3),
+ GROUP(SALT4),
+ GROUP(SALT5),
+ GROUP(SALT6),
+ GROUP(SALT7),
+ GROUP(SALT8),
+ GROUP(SALT9),
+ GROUP(SD),
+ GROUP(SGMII),
+ GROUP(SGPM0),
+ GROUP(SGPM1),
+ GROUP(SGPS),
+ GROUP(SIOONCTRLN0),
+ GROUP(SIOONCTRLN1),
+ GROUP(SIOPBIN0),
+ GROUP(SIOPBIN1),
+ GROUP(SIOPBON0),
+ GROUP(SIOPBON1),
+ GROUP(SIOPWREQN0),
+ GROUP(SIOPWREQN1),
+ GROUP(SIOPWRGD1),
+ GROUP(SIOS3N0),
+ GROUP(SIOS3N1),
+ GROUP(SIOS5N0),
+ GROUP(SIOS5N1),
+ GROUP(SIOSCIN0),
+ GROUP(SIOSCIN1),
+ GROUP(SMON0),
+ GROUP(SMON1),
+ GROUP(SPI0),
+ GROUP(SPI0ABR),
+ GROUP(SPI0CS1),
+ GROUP(SPI0WPN),
+ GROUP(SPI1),
+ GROUP(SPI1ABR),
+ GROUP(SPI1CS1),
+ GROUP(SPI1WPN),
+ GROUP(SPI2),
+ GROUP(SPI2CS1),
+ GROUP(TACH0),
+ GROUP(TACH1),
+ GROUP(TACH10),
+ GROUP(TACH11),
+ GROUP(TACH12),
+ GROUP(TACH13),
+ GROUP(TACH14),
+ GROUP(TACH15),
+ GROUP(TACH2),
+ GROUP(TACH3),
+ GROUP(TACH4),
+ GROUP(TACH5),
+ GROUP(TACH6),
+ GROUP(TACH7),
+ GROUP(TACH8),
+ GROUP(TACH9),
+ GROUP(THRU0),
+ GROUP(THRU1),
+ GROUP(THRU2),
+ GROUP(THRU3),
+ GROUP(UART0),
+ GROUP(UART1),
+ GROUP(UART10),
+ GROUP(UART11),
+ GROUP(UART2),
+ GROUP(UART3),
+ GROUP(UART5),
+ GROUP(UART6),
+ GROUP(UART7),
+ GROUP(UART8),
+ GROUP(UART9),
+ GROUP(USB2CD),
+ GROUP(USB2CH),
+ GROUP(USB2CU),
+ GROUP(USB2CUD),
+ GROUP(USB2DD),
+ GROUP(USB2DH),
+ GROUP(USBUART),
+ GROUP(VGA),
+ GROUP(VPI),
+ GROUP(WDTRST0N),
+ GROUP(WDTRST1N),
+ GROUP(WDTRST2N),
+ GROUP(WDTRST3N),
+ GROUP(WDTRST4N),
+ GROUP(WDTRST5N),
+ GROUP(WDTRST6N),
+ GROUP(WDTRST7N),
+};
+
+/**
+ * VM() - Helper macro to unwrap a parenthesized list of arguments.
+ * @...: The parenthesized list to be unwrapped.
+ *
+ * Since the C preprocessor treats commas inside braces {} as argument
+ * separators for macros, wrap mux value lists in parentheses and strip
+ * them here when initializing the compound literal.
+ */
+#define VM(...) __VA_ARGS__
+
+/**
+ * FUNC() - Initialize an ast2700_soc1_function entry.
+ * @n: Name of the pin function.
+ * @m: Parenthesized list of mux values mapped 1:1 to the groups list.
+ * @...: Variable list of pin group names associated with this function.
+ */
+#define FUNC(n, m, ...) \
+ { \
+ .name = #n, \
+ .groups = (const char *const[]){ __VA_ARGS__ }, \
+ .muxvals = (const u8[]){ VM m }, \
+ .ngroups = sizeof((const char *const[]){ __VA_ARGS__ }) / \
+ sizeof(char *), \
+ }
+
+static const struct ast2700_soc1_function ast2700_soc1_functions[] = {
+ FUNC(ADC0, (0), "ADC0"),
+ FUNC(ADC1, (0), "ADC1"),
+ FUNC(ADC10, (0), "ADC10"),
+ FUNC(ADC11, (0), "ADC11"),
+ FUNC(ADC12, (0), "ADC12"),
+ FUNC(ADC13, (0), "ADC13"),
+ FUNC(ADC14, (0), "ADC14"),
+ FUNC(ADC15, (0), "ADC15"),
+ FUNC(ADC2, (0), "ADC2"),
+ FUNC(ADC3, (0), "ADC3"),
+ FUNC(ADC4, (0), "ADC4"),
+ FUNC(ADC5, (0), "ADC5"),
+ FUNC(ADC6, (0), "ADC6"),
+ FUNC(ADC7, (0), "ADC7"),
+ FUNC(ADC8, (0), "ADC8"),
+ FUNC(ADC9, (0), "ADC9"),
+ FUNC(AUXPWRGOOD0, (2), "AUXPWRGOOD0"),
+ FUNC(AUXPWRGOOD1, (2), "AUXPWRGOOD1"),
+ FUNC(CANBUS, (2), "CANBUS"),
+ FUNC(ESPI0, (1), "ESPI0"),
+ FUNC(ESPI1, (1), "ESPI1"),
+ FUNC(FSI0, (2), "FSI0"),
+ FUNC(FSI1, (2), "FSI1"),
+ FUNC(FSI2, (2), "FSI2"),
+ FUNC(FSI3, (2), "FSI3"),
+ FUNC(FWQSPI, (1), "FWQSPI"),
+ FUNC(FWSPIABR, (1), "FWSPIABR"),
+ FUNC(FWWPN, (1), "FWWPN"),
+ FUNC(HBLED, (2), "HBLED"),
+ FUNC(I2C0, (1, 2, 4), "I2C0", "LTPI_PS_I2C0", "DI2C0"),
+ FUNC(I2C1, (1, 2, 4), "I2C1", "LTPI_PS_I2C1", "DI2C1"),
+ FUNC(I2C10, (1, 2), "I2C10", "DI2C10"),
+ FUNC(I2C11, (1, 2), "I2C11", "DI2C11"),
+ FUNC(I2C12, (4, 2), "I2C12", "DI2C12"),
+ FUNC(I2C13, (4, 2), "I2C13", "DI2C13"),
+ FUNC(I2C14, (4, 2), "I2C14", "DI2C14"),
+ FUNC(I2C15, (2, 2), "I2C15", "DI2C15"),
+ FUNC(I2C2, (1, 2, 4), "I2C2", "LTPI_PS_I2C2", "DI2C2"),
+ FUNC(I2C3, (1, 2, 4), "I2C3", "LTPI_PS_I2C3", "DI2C3"),
+ FUNC(I2C4, (1), "I2C4"),
+ FUNC(I2C5, (1), "I2C5"),
+ FUNC(I2C6, (1), "I2C6"),
+ FUNC(I2C7, (1), "I2C7"),
+ FUNC(I2C8, (1, 2), "I2C8", "DI2C8"),
+ FUNC(I2C9, (1, 2), "I2C9", "DI2C9"),
+ FUNC(I2CF0, (5), "I2CF0"),
+ FUNC(I2CF1, (5), "I2CF1"),
+ FUNC(I2CF2, (5), "I2CF2"),
+ FUNC(I3C0, (1), "HVI3C0"),
+ FUNC(I3C1, (1), "HVI3C1"),
+ FUNC(I3C10, (1), "I3C10"),
+ FUNC(I3C11, (1), "I3C11"),
+ FUNC(I3C12, (1), "HVI3C12"),
+ FUNC(I3C13, (1), "HVI3C13"),
+ FUNC(I3C14, (1), "HVI3C14"),
+ FUNC(I3C15, (1), "HVI3C15"),
+ FUNC(I3C2, (1), "HVI3C2"),
+ FUNC(I3C3, (1), "HVI3C3"),
+ FUNC(I3C4, (1), "I3C4"),
+ FUNC(I3C5, (1), "I3C5"),
+ FUNC(I3C6, (1), "I3C6"),
+ FUNC(I3C7, (1), "I3C7"),
+ FUNC(I3C8, (1), "I3C8"),
+ FUNC(I3C9, (1), "I3C9"),
+ FUNC(JTAGM1, (1), "JTAGM1"),
+ FUNC(LPC0, (2), "LPC0"),
+ FUNC(LPC1, (2), "LPC1"),
+ FUNC(LTPI, (2), "LTPI"),
+ FUNC(MACLINK0, (4), "MACLINK0"),
+ FUNC(MACLINK1, (3), "MACLINK1"),
+ FUNC(MACLINK2, (4), "MACLINK2"),
+ FUNC(MDIO0, (1), "MDIO0"),
+ FUNC(MDIO1, (1), "MDIO1"),
+ FUNC(MDIO2, (1), "MDIO2"),
+ FUNC(NCTS0, (1), "NCTS0"),
+ FUNC(NCTS1, (1), "NCTS1"),
+ FUNC(NCTS5, (4), "NCTS5"),
+ FUNC(NCTS6, (4), "NCTS6"),
+ FUNC(NDCD0, (1), "NDCD0"),
+ FUNC(NDCD1, (1), "NDCD1"),
+ FUNC(NDCD5, (4), "NDCD5"),
+ FUNC(NDCD6, (4), "NDCD6"),
+ FUNC(NDSR0, (1), "NDSR0"),
+ FUNC(NDSR1, (1), "NDSR1"),
+ FUNC(NDSR5, (4), "NDSR5"),
+ FUNC(NDSR6, (4), "NDSR6"),
+ FUNC(NDTR0, (1), "NDTR0"),
+ FUNC(NDTR1, (1), "NDTR1"),
+ FUNC(NDTR5, (4), "NDTR5"),
+ FUNC(NDTR6, (4), "NDTR6"),
+ FUNC(NRI0, (1), "NRI0"),
+ FUNC(NRI1, (1), "NRI1"),
+ FUNC(NRI5, (4), "NRI5"),
+ FUNC(NRI6, (4), "NRI6"),
+ FUNC(NRTS0, (1), "NRTS0"),
+ FUNC(NRTS1, (1), "NRTS1"),
+ FUNC(NRTS5, (4), "NRTS5"),
+ FUNC(NRTS6, (4), "NRTS6"),
+ FUNC(OSCCLK, (3), "OSCCLK"),
+ FUNC(PCIERC, (2), "PE2SGRSTN"),
+ FUNC(PWM0, (1), "PWM0"),
+ FUNC(PWM1, (1), "PWM1"),
+ FUNC(PWM10, (3), "PWM10"),
+ FUNC(PWM11, (3), "PWM11"),
+ FUNC(PWM12, (3), "PWM12"),
+ FUNC(PWM13, (3), "PWM13"),
+ FUNC(PWM14, (3), "PWM14"),
+ FUNC(PWM15, (3), "PWM15"),
+ FUNC(PWM2, (1), "PWM2"),
+ FUNC(PWM3, (1), "PWM3"),
+ FUNC(PWM4, (1), "PWM4"),
+ FUNC(PWM5, (1), "PWM5"),
+ FUNC(PWM6, (1), "PWM6"),
+ FUNC(PWM7, (1), "PWM7"),
+ FUNC(PWM8, (3), "PWM8"),
+ FUNC(PWM9, (3), "PWM9"),
+ FUNC(QSPI0, (1), "QSPI0"),
+ FUNC(QSPI1, (1), "QSPI1"),
+ FUNC(QSPI2, (1), "QSPI2"),
+ FUNC(RGMII0, (1), "RGMII0"),
+ FUNC(RGMII1, (1), "RGMII1"),
+ FUNC(RMII0, (2), "RMII0"),
+ FUNC(RMII0RCLKO, (2), "RMII0RCLKO"),
+ FUNC(RMII1, (2), "RMII1"),
+ FUNC(RMII1RCLKO, (2), "RMII1RCLKO"),
+ FUNC(SALT0, (2), "SALT0"),
+ FUNC(SALT1, (2), "SALT1"),
+ FUNC(SALT10, (2), "SALT10"),
+ FUNC(SALT11, (2), "SALT11"),
+ FUNC(SALT12, (2), "SALT12"),
+ FUNC(SALT13, (2), "SALT13"),
+ FUNC(SALT14, (2), "SALT14"),
+ FUNC(SALT15, (2), "SALT15"),
+ FUNC(SALT2, (2), "SALT2"),
+ FUNC(SALT3, (2), "SALT3"),
+ FUNC(SALT4, (2), "SALT4"),
+ FUNC(SALT5, (2), "SALT5"),
+ FUNC(SALT6, (2), "SALT6"),
+ FUNC(SALT7, (2), "SALT7"),
+ FUNC(SALT8, (2), "SALT8"),
+ FUNC(SALT9, (2), "SALT9"),
+ FUNC(SD, (3), "SD"),
+ FUNC(SGMII, (1), "SGMII"),
+ FUNC(SGPM0, (1, 4), "SGPM0", "DSGPM0"),
+ FUNC(SGPM1, (1), "SGPM1"),
+ FUNC(SGPS, (5), "SGPS"),
+ FUNC(SIOONCTRLN0, (2), "SIOONCTRLN0"),
+ FUNC(SIOONCTRLN1, (2), "SIOONCTRLN1"),
+ FUNC(SIOPBIN0, (2), "SIOPBIN0"),
+ FUNC(SIOPBIN1, (2), "SIOPBIN1"),
+ FUNC(SIOPBON0, (2), "SIOPBON0"),
+ FUNC(SIOPBON1, (2), "SIOPBON1"),
+ FUNC(SIOPWREQN0, (2), "SIOPWREQN0"),
+ FUNC(SIOPWREQN1, (2), "SIOPWREQN1"),
+ FUNC(SIOPWRGD1, (2), "SIOPWRGD1"),
+ FUNC(SIOS3N0, (2), "SIOS3N0"),
+ FUNC(SIOS3N1, (2), "SIOS3N1"),
+ FUNC(SIOS5N0, (2), "SIOS5N0"),
+ FUNC(SIOS5N1, (2), "SIOS5N1"),
+ FUNC(SIOSCIN0, (2), "SIOSCIN0"),
+ FUNC(SIOSCIN1, (2), "SIOSCIN1"),
+ FUNC(SMON0, (2), "SMON0"),
+ FUNC(SMON1, (4), "SMON1"),
+ FUNC(SPI0, (1), "SPI0"),
+ FUNC(SPI0ABR, (1), "SPI0ABR"),
+ FUNC(SPI0CS1, (1), "SPI0CS1"),
+ FUNC(SPI0WPN, (1), "SPI0WPN"),
+ FUNC(SPI1, (1), "SPI1"),
+ FUNC(SPI1ABR, (1), "SPI1ABR"),
+ FUNC(SPI1CS1, (1), "SPI1CS1"),
+ FUNC(SPI1WPN, (1), "SPI1WPN"),
+ FUNC(SPI2, (1), "SPI2"),
+ FUNC(SPI2CS1, (1), "SPI2CS1"),
+ FUNC(TACH0, (1), "TACH0"),
+ FUNC(TACH1, (1), "TACH1"),
+ FUNC(TACH10, (1), "TACH10"),
+ FUNC(TACH11, (1), "TACH11"),
+ FUNC(TACH12, (1), "TACH12"),
+ FUNC(TACH13, (1), "TACH13"),
+ FUNC(TACH14, (1), "TACH14"),
+ FUNC(TACH15, (1), "TACH15"),
+ FUNC(TACH2, (1), "TACH2"),
+ FUNC(TACH3, (1), "TACH3"),
+ FUNC(TACH4, (1), "TACH4"),
+ FUNC(TACH5, (1), "TACH5"),
+ FUNC(TACH6, (1), "TACH6"),
+ FUNC(TACH7, (1), "TACH7"),
+ FUNC(TACH8, (1), "TACH8"),
+ FUNC(TACH9, (1), "TACH9"),
+ FUNC(THRU0, (2), "THRU0"),
+ FUNC(THRU1, (2), "THRU1"),
+ FUNC(THRU2, (4), "THRU2"),
+ FUNC(THRU3, (4), "THRU3"),
+ FUNC(UART0, (1), "UART0"),
+ FUNC(UART1, (1), "UART1"),
+ FUNC(UART10, (3), "UART10"),
+ FUNC(UART11, (3), "UART11"),
+ FUNC(UART2, (1), "UART2"),
+ FUNC(UART3, (1), "UART3"),
+ FUNC(UART5, (1), "UART5"),
+ FUNC(UART6, (1), "UART6"),
+ FUNC(UART7, (1), "UART7"),
+ FUNC(UART8, (3), "UART8"),
+ FUNC(UART9, (3), "UART9"),
+ FUNC(USB2C, (0, 1, 2, 3), "USB2CUD", "USB2CD", "USB2CH", "USB2CU"),
+ FUNC(USB2D, (1, 2), "USB2DD", "USB2DH"),
+ FUNC(USBUART, (2), "USBUART"),
+ FUNC(VGA, (1), "VGA"),
+ FUNC(VPI, (5), "VPI"),
+ FUNC(WDTRST0N, (2), "WDTRST0N"),
+ FUNC(WDTRST1N, (2), "WDTRST1N"),
+ FUNC(WDTRST2N, (2), "WDTRST2N"),
+ FUNC(WDTRST3N, (2), "WDTRST3N"),
+ FUNC(WDTRST4N, (2), "WDTRST4N"),
+ FUNC(WDTRST5N, (2), "WDTRST5N"),
+ FUNC(WDTRST6N, (2), "WDTRST6N"),
+ FUNC(WDTRST7N, (2), "WDTRST7N"),
+};
+
+static struct ast2700_soc1_field
+ast2700_soc1_pinmux_field_from_pin(unsigned int pin)
+{
+ return (struct ast2700_soc1_field){
+ .reg = AST2700_SOC1_MUX_BASE +
+ (pin / AST2700_SOC1_MUX_PINS_PER_REG) * sizeof(u32),
+ .shift = (pin % AST2700_SOC1_MUX_PINS_PER_REG) *
+ AST2700_SOC1_MUX_BITS_PER_PIN,
+ .mask = AST2700_SOC1_MUX_MASK,
+ };
+}
+
+static void __iomem *ast2700_soc1_reg(struct ast2700_soc1_pinctrl_priv *priv,
+ unsigned int offset)
+{
+ return (u8 __iomem *)priv->scu + offset;
+}
+
+static struct ast2700_soc1_field
+ast2700_soc1_field_from_pin(unsigned int pin)
+{
+ switch (pin) {
+ case PCIERC2_PERST:
+ return (struct ast2700_soc1_field){
+ .reg = AST2700_SOC1_PCIE_REG,
+ .shift = 0,
+ .mask = 0x1,
+ };
+ case PORTC_MODE:
+ return (struct ast2700_soc1_field){
+ .reg = AST2700_SOC1_USB_MODE_REG,
+ .shift = 0,
+ .mask = 0x3,
+ };
+ case PORTD_MODE:
+ return (struct ast2700_soc1_field){
+ .reg = AST2700_SOC1_USB_MODE_REG,
+ .shift = 2,
+ .mask = 0x3,
+ };
+ case SGMII0:
+ return (struct ast2700_soc1_field){
+ .reg = AST2700_SOC1_SGMII_REG,
+ .shift = 0,
+ .mask = 0x1,
+ };
+ default:
+ return ast2700_soc1_pinmux_field_from_pin(pin);
+ }
+}
+
+static void
+ast2700_soc1_set_muxval(struct ast2700_soc1_pinctrl_priv *priv,
+ unsigned int pin, unsigned int muxval)
+{
+ struct ast2700_soc1_field field = ast2700_soc1_field_from_pin(pin);
+
+ /*
+ * PCIERC2_PERST is controlled by a 1-bit enable instead of the
+ * function mux value.
+ */
+ if (pin == PCIERC2_PERST)
+ muxval = 1;
+
+ clrsetbits_le32(ast2700_soc1_reg(priv, field.reg),
+ field.mask << field.shift,
+ (muxval & field.mask) << field.shift);
+}
+
+static int ast2700_soc1_pinctrl_get_pins_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(ast2700_soc1_pin_names);
+}
+
+static const char *
+ast2700_soc1_pinctrl_get_pin_name(struct udevice *dev, unsigned int selector)
+{
+ if (selector >= ARRAY_SIZE(ast2700_soc1_pin_names))
+ return NULL;
+
+ return ast2700_soc1_pin_names[selector];
+}
+
+static const struct ast2700_soc1_group *
+ast2700_soc1_find_group(const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ast2700_soc1_groups); i++) {
+ if (!strcmp(ast2700_soc1_groups[i].name, name))
+ return &ast2700_soc1_groups[i];
+ }
+
+ return NULL;
+}
+
+static int ast2700_soc1_pinctrl_get_pin_muxing(struct udevice *dev,
+ unsigned int selector,
+ char *buf, int size)
+{
+ struct ast2700_soc1_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct ast2700_soc1_function *func;
+ const struct ast2700_soc1_group *group;
+ struct ast2700_soc1_field field;
+ unsigned int muxval, want, f, g, i;
+ bool adc_pin;
+
+ if (selector >= ARRAY_SIZE(ast2700_soc1_pin_names))
+ return -EINVAL;
+
+ field = ast2700_soc1_field_from_pin(selector);
+ muxval = (readl(ast2700_soc1_reg(priv, field.reg)) >> field.shift) &
+ field.mask;
+
+ /* Mux value 0 selects GPIO, except on the ADC balls where it is 1 */
+ adc_pin = selector >= W17 && selector <= AB19;
+ if (selector <= AC24 && muxval == (adc_pin ? 1 : 0)) {
+ snprintf(buf, size, "GPIO");
+ return 0;
+ }
+
+ for (f = 0; f < ARRAY_SIZE(ast2700_soc1_functions); f++) {
+ func = &ast2700_soc1_functions[f];
+ for (g = 0; g < func->ngroups; g++) {
+ want = func->muxvals[g];
+ /* PCIERC2_PERST is a 1-bit enable, not a mux value */
+ if (selector == PCIERC2_PERST)
+ want = 1;
+ if (want != muxval)
+ continue;
+ group = ast2700_soc1_find_group(func->groups[g]);
+ if (!group)
+ continue;
+ for (i = 0; i < group->npins; i++) {
+ if (group->pins[i] != selector)
+ continue;
+ snprintf(buf, size, "%s (%s)", func->name,
+ group->name);
+ return 0;
+ }
+ }
+ }
+
+ snprintf(buf, size, "unknown (mux 0x%x)", muxval);
+
+ return 0;
+}
+
+static int ast2700_soc1_pinctrl_get_groups_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(ast2700_soc1_groups);
+}
+
+static const char *
+ast2700_soc1_pinctrl_get_group_name(struct udevice *dev,
+ unsigned int selector)
+{
+ if (selector >= ARRAY_SIZE(ast2700_soc1_groups))
+ return NULL;
+
+ return ast2700_soc1_groups[selector].name;
+}
+
+static int ast2700_soc1_pinctrl_get_functions_count(struct udevice *dev)
+{
+ return ARRAY_SIZE(ast2700_soc1_functions);
+}
+
+static const char *
+ast2700_soc1_pinctrl_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ if (selector >= ARRAY_SIZE(ast2700_soc1_functions))
+ return NULL;
+
+ return ast2700_soc1_functions[selector].name;
+}
+
+static int
+ast2700_soc1_pinctrl_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int func_selector)
+{
+ struct ast2700_soc1_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct ast2700_soc1_function *func;
+ const struct ast2700_soc1_group *group;
+ unsigned int muxval = 0;
+ unsigned int i;
+
+ if (group_selector >= ARRAY_SIZE(ast2700_soc1_groups) ||
+ func_selector >= ARRAY_SIZE(ast2700_soc1_functions))
+ return -EINVAL;
+
+ group = &ast2700_soc1_groups[group_selector];
+ func = &ast2700_soc1_functions[func_selector];
+
+ for (i = 0; i < func->ngroups; i++) {
+ if (!strcmp(group->name, func->groups[i])) {
+ muxval = func->muxvals[i];
+ break;
+ }
+ }
+
+ if (i == func->ngroups)
+ return -EINVAL;
+
+ for (i = 0; i < group->npins; i++)
+ ast2700_soc1_set_muxval(priv, group->pins[i], muxval);
+
+ return 0;
+}
+
+static int
+ast2700_soc1_pinctrl_gpio_request_enable(struct udevice *dev,
+ unsigned int selector)
+{
+ struct ast2700_soc1_pinctrl_priv *priv = dev_get_priv(dev);
+ unsigned int muxval = 0;
+
+ if (selector > AC24)
+ return -ENOTSUPP;
+
+ if (selector >= W17 && selector <= AB19)
+ muxval = 1;
+
+ ast2700_soc1_set_muxval(priv, selector, muxval);
+
+ return 0;
+}
+
+/*
+ * Drive strength is controlled by 2-bit fields in the registers at
+ * DRV_BASE, but the mapping from pins to fields is sparse and
+ * non-linear: only a subset of the pins supports drive strength
+ * selection. The table stores (field index + 1) so that the implicit
+ * zero initialization marks the unsupported pins.
+ */
+static const u8 ast2700_soc1_drv_map[] = {
+ [C16] = 1, [C14] = 2, [C11] = 3, [D9] = 4, [F14] = 5,
+ [D10] = 6, [C12] = 7, [C13] = 8, [W25] = 9, [Y23] = 10,
+ [Y24] = 11, [W21] = 12, [AA23] = 13, [AC22] = 14, [AB22] = 15,
+ [Y21] = 16, [AE20] = 17, [AF19] = 18, [Y22] = 19, [AA20] = 20,
+ [AA22] = 21, [AB20] = 22, [AF18] = 23, [AE19] = 24, [AD20] = 25,
+ [AC20] = 26, [AA21] = 27, [AB21] = 28, [AC19] = 29, [AE18] = 30,
+ [AD19] = 31, [AD18] = 32, [U25] = 33, [U26] = 34, [Y26] = 35,
+ [AA24] = 36, [R25] = 37, [AA26] = 38, [R26] = 39, [Y25] = 40,
+ [B16] = 41, [D14] = 42, [B15] = 43, [B14] = 44, [C17] = 45,
+ [B13] = 46, [E14] = 47, [C15] = 48, [D24] = 49, [B23] = 50,
+ [B22] = 51, [C23] = 52, [B18] = 53, [B21] = 54, [M15] = 55,
+ [B19] = 56, [B26] = 57, [A25] = 58, [A24] = 59, [B24] = 60,
+ [E26] = 61, [A21] = 62, [A19] = 63, [A18] = 64, [D26] = 65,
+ [C26] = 66, [A23] = 67, [A22] = 68, [B25] = 69, [F26] = 70,
+ [A26] = 71, [A14] = 72, [E10] = 73, [E13] = 74, [D12] = 75,
+ [F10] = 76, [E11] = 77, [F11] = 78, [F13] = 79, [N15] = 80,
+ [C20] = 81, [C19] = 82, [A8] = 83, [R14] = 84, [A7] = 85,
+ [P14] = 86, [D20] = 87, [A6] = 88, [B6] = 89, [N14] = 90,
+ [B7] = 91, [B8] = 92, [B9] = 93, [M14] = 94, [J11] = 95,
+ [E7] = 96, [D19] = 97, [B11] = 98, [D15] = 99, [B12] = 100,
+ [B10] = 101, [P13] = 102, [C18] = 103, [C6] = 104, [C7] = 105,
+ [D7] = 106, [N13] = 107, [C8] = 108, [C9] = 109, [C10] = 110,
+ [M16] = 111, [A15] = 112, [E9] = 113, [F9] = 114, [F8] = 115,
+ [M13] = 116, [F7] = 117, [D8] = 118, [E8] = 119, [L12] = 120,
+};
+
+static struct ast2700_soc1_field
+ast2700_soc1_bias_field_from_pin(unsigned int pin)
+{
+ return (struct ast2700_soc1_field){
+ .reg = AST2700_SOC1_BIAS_BASE +
+ (pin / AST2700_SOC1_BIAS_PINS_PER_REG) * sizeof(u32),
+ .shift = pin % AST2700_SOC1_BIAS_PINS_PER_REG,
+ .mask = 0x1,
+ };
+}
+
+static struct ast2700_soc1_field
+ast2700_soc1_drv_field_from_idx(unsigned int idx)
+{
+ return (struct ast2700_soc1_field){
+ .reg = AST2700_SOC1_DRV_BASE +
+ (idx / AST2700_SOC1_DRV_PINS_PER_REG) * sizeof(u32),
+ .shift = (idx % AST2700_SOC1_DRV_PINS_PER_REG) *
+ AST2700_SOC1_DRV_BITS_PER_PIN,
+ .mask = AST2700_SOC1_DRV_MASK,
+ };
+}
+
+static const struct pinconf_param ast2700_soc1_pinconf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 0 },
+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 0 },
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+};
+
+static int ast2700_soc1_pinctrl_pinconf_set(struct udevice *dev,
+ unsigned int selector,
+ unsigned int param,
+ unsigned int arg)
+{
+ struct ast2700_soc1_pinctrl_priv *priv = dev_get_priv(dev);
+ struct ast2700_soc1_field field;
+ unsigned int val, idx;
+
+ if (selector > AC24)
+ return -EINVAL;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ /*
+ * One bias enable bit per pin; the pull direction is fixed
+ * in silicon. Setting the bit disables the bias.
+ */
+ field = ast2700_soc1_bias_field_from_pin(selector);
+ val = param == PIN_CONFIG_BIAS_DISABLE ? 1 : 0;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ if (selector >= ARRAY_SIZE(ast2700_soc1_drv_map) ||
+ !ast2700_soc1_drv_map[selector])
+ return -ENOTSUPP;
+ if (arg < AST2700_SOC1_DRV_MIN_MA ||
+ arg > AST2700_SOC1_DRV_MAX_MA ||
+ arg % AST2700_SOC1_DRV_STEP_MA)
+ return -EINVAL;
+ idx = ast2700_soc1_drv_map[selector] - 1;
+ field = ast2700_soc1_drv_field_from_idx(idx);
+ val = arg / AST2700_SOC1_DRV_STEP_MA - 1;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ clrsetbits_le32(ast2700_soc1_reg(priv, field.reg),
+ field.mask << field.shift, val << field.shift);
+
+ return 0;
+}
+
+static int ast2700_soc1_pinctrl_pinconf_group_set(struct udevice *dev,
+ unsigned int selector,
+ unsigned int param,
+ unsigned int arg)
+{
+ const struct ast2700_soc1_group *group;
+ unsigned int i;
+ int ret;
+
+ if (selector >= ARRAY_SIZE(ast2700_soc1_groups))
+ return -EINVAL;
+
+ group = &ast2700_soc1_groups[selector];
+ for (i = 0; i < group->npins; i++) {
+ ret = ast2700_soc1_pinctrl_pinconf_set(dev, group->pins[i],
+ param, arg);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ast2700_soc1_pinctrl_probe(struct udevice *dev)
+{
+ struct ast2700_soc1_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->scu = dev_remap_addr(dev->parent);
+ if (!priv->scu)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static const struct pinctrl_ops ast2700_soc1_pinctrl_ops = {
+ .set_state = pinctrl_generic_set_state,
+ .get_pins_count = ast2700_soc1_pinctrl_get_pins_count,
+ .get_pin_name = ast2700_soc1_pinctrl_get_pin_name,
+ .get_pin_muxing = ast2700_soc1_pinctrl_get_pin_muxing,
+ .get_groups_count = ast2700_soc1_pinctrl_get_groups_count,
+ .get_group_name = ast2700_soc1_pinctrl_get_group_name,
+ .get_functions_count = ast2700_soc1_pinctrl_get_functions_count,
+ .get_function_name = ast2700_soc1_pinctrl_get_function_name,
+ .pinmux_group_set = ast2700_soc1_pinctrl_group_set,
+ .gpio_request_enable = ast2700_soc1_pinctrl_gpio_request_enable,
+ .pinconf_num_params = ARRAY_SIZE(ast2700_soc1_pinconf_params),
+ .pinconf_params = ast2700_soc1_pinconf_params,
+ .pinconf_set = ast2700_soc1_pinctrl_pinconf_set,
+ .pinconf_group_set = ast2700_soc1_pinctrl_pinconf_group_set,
+};
+
+static const struct udevice_id ast2700_soc1_pinctrl_ids[] = {
+ { .compatible = "aspeed,ast2700-soc1-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_ast2700_soc1) = {
+ .name = "aspeed_ast2700_soc1_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = ast2700_soc1_pinctrl_ids,
+ .priv_auto = sizeof(struct ast2700_soc1_pinctrl_priv),
+ .ops = &ast2700_soc1_pinctrl_ops,
+ .probe = ast2700_soc1_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/broadcom/Kconfig b/drivers/pinctrl/broadcom/Kconfig
index b01b725583a..d7cf3855928 100644
--- a/drivers/pinctrl/broadcom/Kconfig
+++ b/drivers/pinctrl/broadcom/Kconfig
@@ -3,13 +3,13 @@ config PINCTRL_BCM283X
default y
bool "Broadcom 283x family pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Broadcom's 283x family of SoCs.
+ Support pin multiplexing and pin configuration control on
+ Broadcom's 283x family of SoCs.
config PINCTRL_BCM6838
depends on ARCH_BMIPS && PINCTRL_FULL && OF_CONTROL
default y
bool "Broadcom 6838 family pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Broadcom's 6838 family of SoCs.
+ Support pin multiplexing and pin configuration control on
+ Broadcom's 6838 family of SoCs.
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index cf72a7df62c..5a90d74a9e1 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -59,7 +59,7 @@ config PINCTRL_MT8516
select PINCTRL_MTK
config PINCTRL_MT8518
- bool "MT8518 SoC pinctrl driver"
+ bool "MT8518 SoC pinctrl driver"
select PINCTRL_MTK
endif
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index cfffbaeef84..01f67f09407 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -251,7 +251,7 @@ static int mtk_pinconf_get(struct udevice *dev, u32 pin, char *buf, size_t size)
if (mtk_get_pin_io_type(dev, pin, &io_type))
return 0;
- pos = snprintf(buf, size, " (%s)", io_type.name);
+ pos = scnprintf(buf, size, " (%s)", io_type.name);
if (pos >= size)
return pos;
@@ -306,7 +306,7 @@ static int mtk_get_pin_muxing(struct udevice *dev, unsigned int selector,
if (err)
return err;
- pos = snprintf(buf, size, "Aux Func.%d", val);
+ pos = scnprintf(buf, size, "Aux Func.%d", val);
if (pos >= size)
return 0;
@@ -721,7 +721,7 @@ int mtk_pinconf_get_pu_pd(struct udevice *dev, u32 pin, char *buf, size_t size)
if (err)
return err;
- return snprintf(buf, size, " PU:%d PD:%d", pu, pd);
+ return scnprintf(buf, size, " PU:%d PD:%d", pu, pd);
}
int mtk_pinconf_get_pupd_r1_r0(struct udevice *dev, u32 pin, char *buf, size_t size)
@@ -740,7 +740,7 @@ int mtk_pinconf_get_pupd_r1_r0(struct udevice *dev, u32 pin, char *buf, size_t s
if (err)
return err;
- return snprintf(buf, size, " PUPD:%d R1:%d R0:%d", pupd, r1, r0);
+ return scnprintf(buf, size, " PUPD:%d R1:%d R0:%d", pupd, r1, r0);
}
int mtk_pinconf_get_pu_pd_rsel(struct udevice *dev, u32 pin, char *buf, size_t size)
@@ -755,7 +755,7 @@ int mtk_pinconf_get_pu_pd_rsel(struct udevice *dev, u32 pin, char *buf, size_t s
if (err)
return err;
- return pos + snprintf(buf + pos, size - pos, " RSEL:%d", rsel);
+ return pos + scnprintf(buf + pos, size - pos, " RSEL:%d", rsel);
}
#endif
diff --git a/drivers/pinctrl/mscc/Kconfig b/drivers/pinctrl/mscc/Kconfig
index 567c93f404c..285787c4467 100644
--- a/drivers/pinctrl/mscc/Kconfig
+++ b/drivers/pinctrl/mscc/Kconfig
@@ -10,8 +10,8 @@ config PINCTRL_MSCC_OCELOT
default y
bool "Microsemi ocelot family pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Microsemi ocelot SoCs.
+ Support pin multiplexing and pin configuration control on
+ Microsemi ocelot SoCs.
config PINCTRL_MSCC_LUTON
depends on SOC_LUTON && PINCTRL_FULL && OF_CONTROL
@@ -19,8 +19,8 @@ config PINCTRL_MSCC_LUTON
default y
bool "Microsemi luton family pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Microsemi luton SoCs.
+ Support pin multiplexing and pin configuration control on
+ Microsemi luton SoCs.
config PINCTRL_MSCC_JR2
depends on SOC_JR2 && PINCTRL_FULL && OF_CONTROL
@@ -28,8 +28,8 @@ config PINCTRL_MSCC_JR2
default y
bool "Microsemi jr2 family pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Microsemi jr2 SoCs.
+ Support pin multiplexing and pin configuration control on
+ Microsemi jr2 SoCs.
config PINCTRL_MSCC_SERVALT
depends on SOC_SERVALT && PINCTRL_FULL && OF_CONTROL
@@ -37,8 +37,8 @@ config PINCTRL_MSCC_SERVALT
default y
bool "Microsemi servalt family pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Microsemi servalt SoCs.
+ Support pin multiplexing and pin configuration control on
+ Microsemi servalt SoCs.
config PINCTRL_MSCC_SERVAL
depends on SOC_SERVAL && PINCTRL_FULL && OF_CONTROL
@@ -46,6 +46,6 @@ config PINCTRL_MSCC_SERVAL
default y
bool "Microsemi serval family pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Microsemi serval SoCs.
+ Support pin multiplexing and pin configuration control on
+ Microsemi serval SoCs.
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig
index 10ba440f246..72b97a7935d 100644
--- a/drivers/pinctrl/mvebu/Kconfig
+++ b/drivers/pinctrl/mvebu/Kconfig
@@ -4,22 +4,22 @@ config PINCTRL_ARMADA_38X
depends on ARMADA_38X && PINCTRL_FULL
bool "Armada 38x pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Marvell's Armada-38x SoC.
+ Support pin multiplexing and pin configuration control on
+ Marvell's Armada-38x SoC.
config PINCTRL_ARMADA_37XX
depends on ARMADA_3700 && PINCTRL_FULL
select DEVRES
bool "Armada 37xx pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Marvell's Armada-37xx SoC.
+ Support pin multiplexing and pin configuration control on
+ Marvell's Armada-37xx SoC.
config PINCTRL_ARMADA_8K
depends on (ARMADA_8K || ALLEYCAT_5) && PINCTRL_FULL
bool "Armada 7k/8k pin control driver"
help
- Support pin multiplexing and pin configuration control on
- Marvell's Armada-8K SoC.
+ Support pin multiplexing and pin configuration control on
+ Marvell's Armada-8K SoC.
endif
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-38x.c b/drivers/pinctrl/mvebu/pinctrl-armada-38x.c
index 78184d2860a..c18afe958dc 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-38x.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-38x.c
@@ -550,7 +550,7 @@ static int armada_38x_pinctrl_probe(struct udevice *dev)
return 0;
}
-struct pinctrl_ops armada_37xx_pinctrl_ops = {
+static const struct pinctrl_ops armada_37xx_pinctrl_ops = {
.get_pins_count = armada_38x_pinctrl_get_pins_count,
.get_pin_name = armada_38x_pinctrl_get_pin_name,
.get_functions_count = armada_38x_pinctrl_get_functions_count,
diff --git a/drivers/pinctrl/nexell/pinctrl-nexell.c b/drivers/pinctrl/nexell/pinctrl-nexell.c
index af1acd91649..bd89e779864 100644
--- a/drivers/pinctrl/nexell/pinctrl-nexell.c
+++ b/drivers/pinctrl/nexell/pinctrl-nexell.c
@@ -49,7 +49,7 @@ int nexell_pinctrl_probe(struct udevice *dev)
if (!priv)
return -EINVAL;
- base = devfdt_get_addr(dev);
+ base = dev_read_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 2938635ed95..50a130d700f 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -527,7 +527,7 @@ static int at91_pinctrl_probe(struct udevice *dev)
if (list_empty(&dev->child_head)) {
for (index = 0; index < MAX_GPIO_BANKS; index++) {
- addr_base = devfdt_get_addr_index(dev, index);
+ addr_base = dev_read_addr_index(dev, index);
if (addr_base == FDT_ADDR_T_NONE)
break;
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 11e6763b5f3..0bea461fcc3 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -79,12 +79,12 @@ config PINCTRL_QCOM_QCS404
as well as the associated GPIO driver.
config PINCTRL_QCOM_QCS615
- bool "Qualcomm QCS615 Pinctrl"
+ bool "Qualcomm QCS615 Pinctrl"
default y if PINCTRL_QCOM_GENERIC
- select PINCTRL_QCOM
- help
- Say Y here to enable support for pinctrl on the Snapdragon QCS615 SoC,
- as well as the associated GPIO driver.
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable support for pinctrl on the Snapdragon QCS615 SoC,
+ as well as the associated GPIO driver.
config PINCTRL_QCOM_SA8775P
bool "Qualcomm SA8775P Pinctrl"
@@ -133,6 +133,14 @@ config PINCTRL_QCOM_SM6115
Say Y here to enable support for pinctrl on the Snapdragon SM6115 SoC,
as well as the associated GPIO driver.
+config PINCTRL_QCOM_SM6125
+ bool "Qualcomm SM6125 Pinctrl"
+ default y if PINCTRL_QCOM_GENERIC
+ select PINCTRL_QCOM
+ help
+ Say Y here to enable support for pinctrl on the Snapdragon SM6125 SoC,
+ as well as the associated GPIO driver.
+
config PINCTRL_QCOM_SM6350
bool "Qualcomm SM6350 Pinctrl"
default y if PINCTRL_QCOM_GENERIC
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 4096c1aa491..87cb128c4d4 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_PINCTRL_QCOM_SDM660) += pinctrl-sdm660.o
obj-$(CONFIG_PINCTRL_QCOM_SDM670) += pinctrl-sdm670.o
obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o
+obj-$(CONFIG_PINCTRL_QCOM_SM6125) += pinctrl-sm6125.o
obj-$(CONFIG_PINCTRL_QCOM_SM6350) += pinctrl-sm6350.o
obj-$(CONFIG_PINCTRL_QCOM_SM7150) += pinctrl-sm7150.o
obj-$(CONFIG_PINCTRL_QCOM_SM8150) += pinctrl-sm8150.o
diff --git a/drivers/pinctrl/qcom/pinctrl-sm6125.c b/drivers/pinctrl/qcom/pinctrl-sm6125.c
new file mode 100644
index 00000000000..82f8972ff5b
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sm6125.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Pinctrl driver for Qualcomm SM6125
+ *
+ * (C) Copyright 2026 Biswapriyo Nath <[email protected]>
+ *
+ * Based on Linux Kernel driver
+ */
+
+#include <dm.h>
+
+#include "pinctrl-qcom.h"
+
+#define TLMM_BASE 0x00500000
+#define WEST (0x00500000 - TLMM_BASE) /* 0x0 */
+#define SOUTH (0x00900000 - TLMM_BASE) /* 0x400000 */
+#define EAST (0x00d00000 - TLMM_BASE) /* 0x800000 */
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+ { "qup04", 1 },
+ { "gpio", 0 },
+};
+
+#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ }
+
+#define UFS_RESET(pg_name, offset) \
+ { \
+ .name = pg_name, \
+ .ctl_reg = offset, \
+ .io_reg = offset + 0x4, \
+ .pull_bit = 3, \
+ .drv_bit = 0, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = 0, \
+ }
+
+static const struct msm_special_pin_data msm_special_pins_data[] = {
+ [0] = UFS_RESET("ufs_reset", 0x190000),
+ [1] = SDC_QDSD_PINGROUP("sdc1_rclk", WEST + 0x18d000, 15, 0),
+ [2] = SDC_QDSD_PINGROUP("sdc1_clk", WEST + 0x18d000, 13, 6),
+ [3] = SDC_QDSD_PINGROUP("sdc1_cmd", WEST + 0x18d000, 11, 3),
+ [4] = SDC_QDSD_PINGROUP("sdc1_data", WEST + 0x18d000, 9, 0),
+ [5] = SDC_QDSD_PINGROUP("sdc2_clk", SOUTH + 0x58b000, 14, 6),
+ [6] = SDC_QDSD_PINGROUP("sdc2_cmd", SOUTH + 0x58b000, 11, 3),
+ [7] = SDC_QDSD_PINGROUP("sdc2_data", SOUTH + 0x58b000, 9, 0),
+};
+
+static const unsigned int sm6125_pin_offsets[] = {
+ [0] = WEST, [1] = WEST, [2] = WEST, [3] = WEST,
+ [4] = WEST, [5] = WEST, [6] = WEST, [7] = WEST,
+ [8] = WEST, [9] = WEST, [10] = EAST, [11] = EAST,
+ [12] = EAST, [13] = EAST, [14] = WEST, [15] = WEST,
+ [16] = WEST, [17] = WEST, [18] = EAST, [19] = EAST,
+ [20] = EAST, [21] = EAST, [22] = WEST, [23] = WEST,
+ [24] = WEST, [25] = WEST, [26] = WEST, [27] = WEST,
+ [28] = WEST, [29] = WEST, [30] = WEST, [31] = WEST,
+ [32] = WEST, [33] = WEST, [34] = SOUTH, [35] = SOUTH,
+ [36] = SOUTH, [37] = SOUTH, [38] = EAST, [39] = EAST,
+ [40] = EAST, [41] = EAST, [42] = EAST, [43] = EAST,
+ [44] = SOUTH, [45] = SOUTH, [46] = SOUTH, [47] = SOUTH,
+ [48] = SOUTH, [49] = SOUTH, [50] = SOUTH, [51] = SOUTH,
+ [52] = SOUTH, [53] = SOUTH, [54] = SOUTH, [55] = SOUTH,
+ [56] = SOUTH, [57] = SOUTH, [58] = SOUTH, [59] = SOUTH,
+ [60] = SOUTH, [61] = SOUTH, [62] = SOUTH, [63] = SOUTH,
+ [64] = SOUTH, [65] = SOUTH, [66] = SOUTH, [67] = SOUTH,
+ [68] = SOUTH, [69] = SOUTH, [70] = SOUTH, [71] = SOUTH,
+ [72] = SOUTH, [73] = SOUTH, [74] = SOUTH, [75] = SOUTH,
+ [76] = SOUTH, [77] = SOUTH, [78] = SOUTH, [79] = SOUTH,
+ [80] = SOUTH, [81] = SOUTH, [82] = SOUTH, [83] = SOUTH,
+ [84] = SOUTH, [85] = SOUTH, [86] = SOUTH, [87] = WEST,
+ [88] = WEST, [89] = WEST, [90] = WEST, [91] = WEST,
+ [92] = WEST, [93] = WEST, [94] = SOUTH, [95] = SOUTH,
+ [96] = SOUTH, [97] = SOUTH, [98] = SOUTH, [99] = SOUTH,
+ [100] = SOUTH, [101] = SOUTH, [102] = SOUTH, [103] = SOUTH,
+ [104] = EAST, [105] = EAST, [106] = EAST, [107] = EAST,
+ [108] = EAST, [109] = EAST, [110] = EAST, [111] = EAST,
+ [112] = EAST, [113] = EAST, [114] = EAST, [115] = EAST,
+ [116] = EAST, [117] = SOUTH, [118] = SOUTH, [119] = SOUTH,
+ [120] = SOUTH, [121] = EAST, [122] = EAST, [123] = EAST,
+ [124] = EAST, [125] = EAST, [126] = EAST, [127] = EAST,
+ [128] = EAST, [129] = SOUTH, [130] = SOUTH, [131] = SOUTH,
+ [132] = SOUTH,
+};
+
+static const char *sm6125_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].name;
+}
+
+static const char *sm6125_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ if (selector >= 133 && selector <= 140)
+ snprintf(pin_name, MAX_PIN_NAME_LEN,
+ msm_special_pins_data[selector - 133].name);
+ else
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
+
+ return pin_name;
+}
+
+static int sm6125_get_function_mux(__maybe_unused unsigned int pin,
+ unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].val;
+}
+
+static struct msm_pinctrl_data sm6125_data = {
+ .pin_data = {
+ .pin_offsets = sm6125_pin_offsets,
+ .pin_count = 141,
+ .special_pins_start = 133,
+ .special_pins_data = msm_special_pins_data,
+ },
+ .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+ .get_function_name = sm6125_get_function_name,
+ .get_function_mux = sm6125_get_function_mux,
+ .get_pin_name = sm6125_get_pin_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+ { .compatible = "qcom,sm6125-tlmm", .data = (ulong)&sm6125_data },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(pinctrl_sm6125) = {
+ .name = "pinctrl_sm6125",
+ .id = UCLASS_NOP,
+ .of_match = msm_pinctrl_ids,
+ .ops = &msm_pinctrl_ops,
+ .bind = msm_pinctrl_bind,
+};
diff --git a/drivers/pinctrl/spacemit/Kconfig b/drivers/pinctrl/spacemit/Kconfig
new file mode 100644
index 00000000000..6aab89e160c
--- /dev/null
+++ b/drivers/pinctrl/spacemit/Kconfig
@@ -0,0 +1,9 @@
+config PINCTRL_SPACEMIT_K1
+ bool "Spacemit K1 SoC pinctrl driver"
+ depends on PINCTRL_GENERIC && DM
+ help
+ Supports pin multiplexing control on Spacemit K1 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.
diff --git a/drivers/pinctrl/spacemit/Makefile b/drivers/pinctrl/spacemit/Makefile
new file mode 100644
index 00000000000..0dc43c72cb1
--- /dev/null
+++ b/drivers/pinctrl/spacemit/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y += pinctrl-k1.o
diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c
new file mode 100644
index 00000000000..a6a22eacac7
--- /dev/null
+++ b/drivers/pinctrl/spacemit/pinctrl-k1.c
@@ -0,0 +1,550 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Yixun Lan <[email protected]>
+ * Copyright (c) 2025-2026 RISCstar Ltd.
+ */
+
+#include <clk.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/pinctrl.h>
+#include <dm/read.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+/*
+ * +---------+----------+-----------+--------+--------+----------+--------+
+ * | pull | drive | schmitter | slew | edge | strong | mux |
+ * | up/down | strength | trigger | rate | detect | pull | mode |
+ * +---------+----------+-----------+--------+--------+----------+--------+
+ * 3 bits 3 bits 2 bits 1 bit 3 bits 1 bit 3 bits
+ */
+
+#define PAD_MUX GENMASK(2, 0)
+#define PAD_STRONG_PULL BIT(3)
+#define PAD_EDGE_RISE BIT(4)
+#define PAD_EDGE_FALL BIT(5)
+#define PAD_EDGE_CLEAR BIT(6)
+#define PAD_SLEW_RATE GENMASK(12, 11)
+#define PAD_SLEW_RATE_EN BIT(7)
+#define PAD_SCHMITT GENMASK(9, 8)
+#define PAD_DRIVE GENMASK(12, 10)
+#define PAD_PULLDOWN BIT(13)
+#define PAD_PULLUP BIT(14)
+#define PAD_PULL_EN BIT(15)
+
+#define PIN_POWER_STATE_1V8 1800
+#define PIN_POWER_STATE_3V3 3300
+
+enum spacemit_pin_io_type {
+ IO_TYPE_NONE = 0,
+ IO_TYPE_1V8,
+ IO_TYPE_3V3,
+ IO_TYPE_EXTERNAL,
+};
+
+struct spacemit_pin_io {
+ unsigned int pin : 12; // 0~4095
+ unsigned int io_type : 4; // 0~15
+ unsigned int ds : 8; // 0~255
+ unsigned int reserved : 8;
+};
+
+struct spacemit_pinctrl_data {
+ struct spacemit_pin_io *io_pins;
+ int nr_io_pins;
+
+ void __iomem * (*pin_to_reg)(struct udevice *dev, unsigned int pin);
+ int (*get_gpio_mux)(struct udevice *dev, unsigned int pin);
+ int (*get_pins)(struct udevice *dev);
+ int (*get_functions)(struct udevice *dev);
+ int (*get_io_type)(struct udevice *dev, unsigned int pin);
+};
+
+struct spacemit_pinctrl_priv {
+ void __iomem *regs;
+ struct spacemit_pin_io *io_pins;
+ int nr_io_pins;
+};
+
+struct spacemit_pin_mux_config {
+ const struct spacemit_pin *pin;
+ u32 config;
+};
+
+struct spacemit_pin_drv_strength {
+ unsigned int val : 8;
+ unsigned int ma : 16;
+ unsigned int reserved : 8;
+};
+
+static char pin_name[PINNAME_SIZE];
+
+/* External: IO voltage via external source, can be 1.8V or 3.3V */
+static struct spacemit_pin_io k1_io_pins[] = {
+ { 47, IO_TYPE_EXTERNAL, 0, },
+ { 48, IO_TYPE_EXTERNAL, 0, },
+ { 49, IO_TYPE_EXTERNAL, 0, },
+ { 50, IO_TYPE_EXTERNAL, 0, },
+ { 51, IO_TYPE_EXTERNAL, 0, },
+ { 52, IO_TYPE_EXTERNAL, 0, },
+ { 75, IO_TYPE_EXTERNAL, 0, },
+ { 76, IO_TYPE_EXTERNAL, 0, },
+ { 77, IO_TYPE_EXTERNAL, 0, },
+ { 78, IO_TYPE_EXTERNAL, 0, },
+ { 79, IO_TYPE_EXTERNAL, 0, },
+ { 80, IO_TYPE_EXTERNAL, 0, },
+ { 98, IO_TYPE_EXTERNAL, 0, },
+ { 99, IO_TYPE_EXTERNAL, 0, },
+ { 100, IO_TYPE_EXTERNAL, 0, },
+ { 101, IO_TYPE_EXTERNAL, 0, },
+ { 102, IO_TYPE_EXTERNAL, 0, },
+ { 103, IO_TYPE_EXTERNAL, 0, },
+ { 104, IO_TYPE_EXTERNAL, 0, },
+ { 105, IO_TYPE_EXTERNAL, 0, },
+ { 106, IO_TYPE_EXTERNAL, 0, },
+ { 107, IO_TYPE_EXTERNAL, 0, },
+ { 108, IO_TYPE_EXTERNAL, 0, },
+ { 109, IO_TYPE_EXTERNAL, 0, },
+};
+
+static inline int k1_get_pins(struct udevice *dev)
+{
+ return 128;
+}
+
+static inline int k1_get_functions(struct udevice *dev)
+{
+ return 7;
+}
+
+// The pin number equals to the gpio number.
+static void __iomem *k1_pin_to_reg(struct udevice *dev, unsigned int pin)
+{
+ struct spacemit_pinctrl_priv *priv = dev_get_priv(dev);
+ unsigned int offset = 1;
+
+ if (pin < 86) {
+ offset += pin;
+ } else if (pin < 93) {
+ offset += pin + 36;
+ } else if (pin < 98) {
+ offset += pin + 23;
+ } else if (pin == 98) { // QSPI_DAT3
+ offset += 92;
+ } else if (pin == 99) { // QSPI_DAT2
+ offset += 91;
+ } else if (pin == 100) { // QSPI_DAT1
+ offset += 90;
+ } else if (pin == 101) { // QSPI_DAT0
+ offset += 89;
+ } else if (pin == 102) { // QSPI_CLK
+ offset += 94;
+ } else if (pin == 103) { // QSPI_CS1
+ offset += 93;
+ } else if (pin < 111) {
+ offset += pin + 5;
+ } else if (pin < 128) {
+ offset += pin + 19;
+ } else {
+ dev_err(dev, "Invalid pin (%u)\n", pin);
+ return NULL;
+ }
+ return priv->regs + (offset << 2);
+}
+
+static int k1_get_gpio_mux(struct udevice *dev, unsigned int selector)
+{
+ u32 mux = 0;
+
+ if (selector < 70) {
+ mux = 0;
+ } else if (selector < 74) {
+ mux = 1;
+ } else if (selector < 93) {
+ mux = 0;
+ } else if (selector < 104) {
+ mux = 1;
+ } else if (selector < 110) {
+ mux = 4;
+ } else if (selector < 128) {
+ mux = 0;
+ } else {
+ dev_err(dev, "Invalid pin (%u)\n", selector);
+ return -EINVAL;
+ }
+ return mux;
+}
+
+static int k1_get_io_type(struct udevice *dev, unsigned int selector)
+{
+ if (selector < 47)
+ return IO_TYPE_1V8;
+ else if (selector < 53)
+ return IO_TYPE_EXTERNAL;
+ else if (selector < 75)
+ return IO_TYPE_1V8;
+ else if (selector < 81)
+ return IO_TYPE_EXTERNAL;
+ else if (selector < 98)
+ return IO_TYPE_1V8;
+ else if (selector < 110)
+ return IO_TYPE_EXTERNAL;
+ else if (selector < 128)
+ return IO_TYPE_1V8;
+ return -EINVAL;
+}
+
+/* use IO high level output current as the table */
+static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = {
+ { 0, 11 },
+ { 2, 21 },
+ { 4, 32 },
+ { 6, 42 },
+};
+
+static struct spacemit_pin_drv_strength spacemit_ds_3v3_tbl[8] = {
+ { 0, 7 },
+ { 2, 10 },
+ { 4, 13 },
+ { 6, 16 },
+ { 1, 19 },
+ { 3, 23 },
+ { 5, 26 },
+ { 7, 29 },
+};
+
+static inline u8 spacemit_get_ds_value(struct spacemit_pin_drv_strength *tbl,
+ u32 num, u32 ma)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ if (ma <= tbl[i].ma)
+ return tbl[i].val;
+
+ return tbl[num - 1].val;
+}
+
+static inline u32 spacemit_get_ds_ma(struct spacemit_pin_drv_strength *tbl,
+ u32 num, u32 val)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ if (val == tbl[i].val)
+ return tbl[i].ma;
+
+ return 0;
+}
+
+static inline u8 spacemit_get_drive_strength(enum spacemit_pin_io_type type,
+ u32 ma)
+{
+ switch (type) {
+ case IO_TYPE_1V8:
+ return spacemit_get_ds_value(spacemit_ds_1v8_tbl,
+ ARRAY_SIZE(spacemit_ds_1v8_tbl),
+ ma);
+ case IO_TYPE_3V3:
+ return spacemit_get_ds_value(spacemit_ds_3v3_tbl,
+ ARRAY_SIZE(spacemit_ds_3v3_tbl),
+ ma);
+ default:
+ return 0;
+ }
+}
+
+static inline u32 spacemit_get_drive_strength_ma(enum spacemit_pin_io_type type,
+ u32 value)
+{
+ switch (type) {
+ case IO_TYPE_1V8:
+ return spacemit_get_ds_ma(spacemit_ds_1v8_tbl,
+ ARRAY_SIZE(spacemit_ds_1v8_tbl),
+ value & 0x6);
+ case IO_TYPE_3V3:
+ return spacemit_get_ds_ma(spacemit_ds_3v3_tbl,
+ ARRAY_SIZE(spacemit_ds_3v3_tbl),
+ value);
+ default:
+ return 0;
+ }
+}
+
+static inline u16 spacemit_dt_get_pin(u32 value)
+{
+ return value >> 16;
+}
+
+static inline u16 spacemit_dt_get_pin_mux(u32 value)
+{
+ return value & GENMASK(15, 0);
+}
+
+static int spacemit_get_pins_count(struct udevice *dev)
+{
+ struct spacemit_pinctrl_data *data;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ if (!data || !data->get_pins)
+ return -EINVAL;
+ return data->get_pins(dev);
+}
+
+static const char *spacemit_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct spacemit_pinctrl_data *data;
+ unsigned int npins;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ if (!data || !data->get_pins)
+ return NULL;
+ npins = data->get_pins(dev);
+
+ if (selector >= npins)
+ snprintf(pin_name, PINNAME_SIZE, "Error");
+ else
+ snprintf(pin_name, PINNAME_SIZE, "PIN%u", selector);
+
+ return pin_name;
+}
+
+static int spacemit_get_functions_count(struct udevice *dev)
+{
+ struct spacemit_pinctrl_data *data;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ if (!data || !data->get_functions)
+ return -EINVAL;
+ return data->get_functions(dev);
+}
+
+static int spacemit_get_pin_muxing(struct udevice *dev, unsigned int pin,
+ char *buf, int size)
+{
+ struct spacemit_pinctrl_data *data;
+ void __iomem *addr;
+ u32 mux, val;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ if (!data || !data->pin_to_reg)
+ return -EINVAL;
+
+ addr = data->pin_to_reg(dev, pin);
+ if (!addr)
+ return -EINVAL;
+
+ val = readl(addr);
+ mux = val & PAD_MUX;
+ snprintf(buf, size, "[%p] 0x%08x MUX%d", addr, val, mux);
+ return 0;
+}
+
+static int spacemit_pinctrl_request_gpio(struct udevice *dev,
+ unsigned int selector)
+{
+ struct spacemit_pinctrl_data *data;
+ void __iomem *addr;
+ int mux;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ if (!data || !data->pin_to_reg || !data->get_gpio_mux)
+ return -EINVAL;
+ addr = data->pin_to_reg(dev, selector);
+ mux = data->get_gpio_mux(dev, selector);
+ if (mux < 0) {
+ dev_err(dev, "Invalid pin (%d)\n", selector);
+ return -EINVAL;
+ }
+ clrsetbits_le32(addr, PAD_MUX, mux & PAD_MUX);
+ return 0;
+}
+
+static int spacemit_pinctrl_free_gpio(struct udevice *dev,
+ unsigned int selector)
+{
+ return 0;
+}
+
+static int spacemit_pinmux_set(struct udevice *dev, unsigned int pin,
+ unsigned int mux)
+{
+ struct spacemit_pinctrl_data *data;
+ void __iomem *addr;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ if (!data || !data->pin_to_reg)
+ return -EINVAL;
+ addr = data->pin_to_reg(dev, pin);
+ clrsetbits_le32(addr, PAD_MUX, mux & PAD_MUX);
+ return 0;
+}
+
+static int spacemit_pinmux_property_set(struct udevice *dev, u32 pinmux_group)
+{
+ u32 pin, mux;
+
+ pin = spacemit_dt_get_pin(pinmux_group);
+ mux = spacemit_dt_get_pin_mux(pinmux_group);
+ return spacemit_pinmux_set(dev, pin, mux);
+}
+
+static const struct pinconf_param spacemit_pinconf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+ { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, U32_MAX },
+ { "power-source", PIN_CONFIG_POWER_SOURCE, U32_MAX },
+};
+
+static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,
+ unsigned int param, unsigned int argument)
+{
+ struct spacemit_pinctrl_data *data;
+ struct spacemit_pinctrl_priv *priv = dev_get_priv(dev);
+ void __iomem *addr;
+ u32 mask = 0;
+ unsigned int io_type;
+ u8 ds;
+ bool found;
+ int i;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ if (!data || !data->pin_to_reg)
+ return -EINVAL;
+ addr = data->pin_to_reg(dev, pin_selector);
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ clrbits_le32(addr, PAD_PULLUP | PAD_PULLDOWN | PAD_PULL_EN);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ mask = PAD_PULLDOWN | PAD_PULLUP | PAD_PULL_EN;
+ clrsetbits_le32(addr, mask, PAD_PULLDOWN | PAD_PULL_EN);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ mask = PAD_PULLDOWN | PAD_PULLUP | PAD_PULL_EN;
+ clrsetbits_le32(addr, mask, PAD_PULLUP | PAD_PULL_EN);
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ io_type = IO_TYPE_1V8;
+ for (i = 0; i < priv->nr_io_pins; i++) {
+ if (priv->io_pins[i].pin != pin_selector)
+ continue;
+ io_type = priv->io_pins[i].io_type;
+ break;
+ }
+ if (io_type != IO_TYPE_3V3 && io_type != IO_TYPE_1V8) {
+ dev_err(dev, "Invalid IO type (%d)\n", io_type);
+ return -EINVAL;
+ }
+ ds = spacemit_get_drive_strength(io_type, argument);
+ clrsetbits_le32(addr, PAD_DRIVE, ds);
+ break;
+ case PIN_CONFIG_POWER_SOURCE:
+ for (i = 0, found = false; i < priv->nr_io_pins; i++) {
+ if (priv->io_pins[i].pin != pin_selector)
+ continue;
+ if (argument == PIN_POWER_STATE_3V3) {
+ priv->io_pins[i].io_type = IO_TYPE_3V3;
+ found = true;
+ } else if (argument == PIN_POWER_STATE_1V8) {
+ priv->io_pins[i].io_type = IO_TYPE_1V8;
+ found = true;
+ }
+ break;
+ }
+ if (!found && argument != PIN_POWER_STATE_1V8) {
+ dev_err(dev, "Invalid power source (%d)\n", argument);
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static int spacemit_pinctrl_probe(struct udevice *dev)
+{
+ struct spacemit_pinctrl_data *data;
+ struct spacemit_pinctrl_priv *priv;
+ struct clk_bulk clks;
+ size_t size;
+ int ret;
+
+ data = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);
+ priv = dev_get_priv(dev);
+ priv->regs = dev_read_addr_ptr(dev);
+ if (!priv->regs) {
+ dev_err(dev, "Fail to get base address\n");
+ return -EINVAL;
+ }
+ priv->nr_io_pins = data->nr_io_pins;
+ size = priv->nr_io_pins * sizeof(struct spacemit_pin_io);
+ priv->io_pins = (struct spacemit_pin_io *)memdup(data->io_pins, size);
+ if (!priv->io_pins) {
+ dev_err(dev, "Fail to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ ret = clk_get_bulk(dev, &clks);
+ if (ret) {
+ dev_err(dev, "Fail to get bulk clks\n");
+ goto out_get_clk;
+ }
+ ret = clk_enable_bulk(&clks);
+ if (ret) {
+ dev_err(dev, "Fail to enable bulk clks\n");
+ goto out_clks;
+ }
+ return 0;
+out_clks:
+ clk_release_bulk(&clks);
+out_get_clk:
+ free(priv->io_pins);
+ return ret;
+}
+
+static const struct spacemit_pinctrl_data k1_pinctrl_data = {
+ .io_pins = k1_io_pins,
+ .nr_io_pins = ARRAY_SIZE(k1_io_pins),
+ .pin_to_reg = k1_pin_to_reg,
+ .get_gpio_mux = k1_get_gpio_mux,
+ .get_pins = k1_get_pins,
+ .get_functions = k1_get_functions,
+ .get_io_type = k1_get_io_type,
+};
+
+static const struct udevice_id spacemit_pinctrl_ids[] = {
+ {
+ .compatible = "spacemit,k1-pinctrl",
+ .data = (uintptr_t)&k1_pinctrl_data,
+ }, { /* sentinel */ }
+};
+
+static const struct pinctrl_ops spacemit_pinctrl_ops = {
+ .get_pins_count = spacemit_get_pins_count,
+ .get_pin_name = spacemit_get_pin_name,
+ .get_functions_count = spacemit_get_functions_count,
+ .get_pin_muxing = spacemit_get_pin_muxing,
+ .set_state = pinctrl_generic_set_state,
+ .gpio_request_enable = spacemit_pinctrl_request_gpio,
+ .gpio_disable_free = spacemit_pinctrl_free_gpio,
+ .pinmux_set = spacemit_pinmux_set,
+ .pinmux_property_set = spacemit_pinmux_property_set,
+ .pinconf_num_params = ARRAY_SIZE(spacemit_pinconf_params),
+ .pinconf_params = spacemit_pinconf_params,
+ .pinconf_set = spacemit_pinconf_set,
+};
+
+U_BOOT_DRIVER(spacemit_pinctrl) = {
+ .name = "spacemit_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = spacemit_pinctrl_ids,
+ .ops = &spacemit_pinctrl_ops,
+ .priv_auto = sizeof(struct spacemit_pinctrl_priv),
+ .probe = spacemit_pinctrl_probe,
+};
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 1b06d8a66c7..66c389d073b 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -1,7 +1,7 @@
menuconfig POWER
- bool "Power"
- default y
- help
+ bool "Power"
+ default y
+ help
Enable support for power control in U-Boot. This includes support
for PMICs (Power-management Integrated Circuits) and some of the
features provided by PMICs. In particular, voltage regulators can
@@ -63,98 +63,98 @@ choice
config SUNXI_NO_PMIC
bool "board without a pmic"
- ---help---
- Select this for boards which do not use a PMIC.
+ help
+ Select this for boards which do not use a PMIC.
config AXP152_POWER
bool "axp152 pmic support"
depends on MACH_SUN5I
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Select this to enable support for the axp152 pmic found on most
- A10s boards.
+ help
+ Select this to enable support for the axp152 pmic found on most
+ A10s boards.
config AXP209_POWER
bool "axp209 pmic support"
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUN8I_V3S
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Select this to enable support for the axp209 pmic found on most
- A10, A13 and A20 boards.
+ help
+ Select this to enable support for the axp209 pmic found on most
+ A10, A13 and A20 boards.
config AXP221_POWER
bool "axp221 / axp223 pmic support"
depends on MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Select this to enable support for the axp221/axp223 pmic found on most
- A23 and A31 boards.
+ help
+ Select this to enable support for the axp221/axp223 pmic found on most
+ A23 and A31 boards.
config AXP305_POWER
bool "axp305 pmic support"
depends on MACH_SUN50I_H616
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Select this to enable support for the axp305 pmic found on most
- H616 boards.
+ help
+ Select this to enable support for the axp305 pmic found on most
+ H616 boards.
config AXP313_POWER
bool "axp313 pmic support"
depends on MACH_SUN50I_H616
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Select this to enable support for the AXP313 PMIC found on some
- H616 boards.
+ help
+ Select this to enable support for the AXP313 PMIC found on some
+ H616 boards.
config AXP717_POWER
bool "axp717 pmic support"
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Select this to enable support for the AXP717 PMIC found on some boards.
+ help
+ Select this to enable support for the AXP717 PMIC found on some boards.
config AXP803_POWER
bool "AXP803 PMIC support"
select AXP_PMIC_BUS
- ---help---
- Select this to enable support for the AXP803 PMIC found on some boards.
+ help
+ Select this to enable support for the AXP803 PMIC found on some boards.
config AXP809_POWER
bool "axp809 pmic support"
depends on MACH_SUN9I
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Say y here to enable support for the axp809 pmic found on A80 boards.
+ help
+ Say y here to enable support for the axp809 pmic found on A80 boards.
config AXP818_POWER
bool "axp818 pmic support"
depends on MACH_SUN8I_A83T
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Say y here to enable support for the axp818 pmic found on
- A83T dev board.
+ help
+ Say y here to enable support for the axp818 pmic found on
+ A83T dev board.
config AXP318W_POWER
bool "axp318w pmic support"
select AXP_PMIC_BUS
select CMD_POWEROFF
- ---help---
- Select this to enable support for the AXP318W PMIC found on some
- A733 boards.
+ help
+ Select this to enable support for the AXP318W PMIC found on some
+ A733 boards.
config SY8106A_POWER
bool "SY8106A pmic support"
depends on MACH_SUNXI_H3_H5
- ---help---
- Select this to enable support for the SY8106A pmic found on some
- H3 boards.
+ help
+ Select this to enable support for the SY8106A pmic found on some
+ H3 boards.
endchoice
@@ -166,22 +166,22 @@ config AXP_I2C_ADDRESS
default 0x36 if AXP318W_POWER
default 0x30 if AXP152_POWER
default 0x34
- ---help---
- I2C address of the AXP PMIC, used for the SPL only.
+ help
+ I2C address of the AXP PMIC, used for the SPL only.
config AXP_DCDC1_VOLT
int "axp pmic dcdc1 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP803_POWER
default 3300 if AXP818_POWER || MACH_SUN8I_R40 || AXP803_POWER
default 3000 if MACH_SUN6I || MACH_SUN8I || MACH_SUN9I
- ---help---
- Set the voltage (mV) to program the axp pmic dcdc1 at, set to 0 to
- disable dcdc1. On A23 / A31 / A33 (axp221) boards dcdc1 is used for
- generic 3.3V IO voltage for external devices like the lcd-panal and
- sdcard interfaces, etc. On most boards dcdc1 is undervolted to 3.0V to
- save battery. On A31 devices dcdc1 is also used for VCC-IO. On A83T
- dcdc1 is used for VCC-IO, nand, usb0, sd , etc. On A80 dcdc1 normally
- powers some of the pingroups, NAND/eMMC, SD/MMC, and USB OTG.
+ help
+ Set the voltage (mV) to program the axp pmic dcdc1 at, set to 0 to
+ disable dcdc1. On A23 / A31 / A33 (axp221) boards dcdc1 is used for
+ generic 3.3V IO voltage for external devices like the lcd-panal and
+ sdcard interfaces, etc. On most boards dcdc1 is undervolted to 3.0V to
+ save battery. On A31 devices dcdc1 is also used for VCC-IO. On A83T
+ dcdc1 is used for VCC-IO, nand, usb0, sd , etc. On A80 dcdc1 normally
+ powers some of the pingroups, NAND/eMMC, SD/MMC, and USB OTG.
config AXP_DCDC2_VOLT
int "axp pmic dcdc2 voltage"
@@ -194,16 +194,16 @@ config AXP_DCDC2_VOLT
default 1200 if MACH_SUN6I
default 1100 if MACH_SUN8I
default 0 if MACH_SUN9I
- ---help---
- Set the voltage (mV) to program the axp pmic dcdc2 at, set to 0 to
- disable dcdc2.
- On A10(s) / A13 / A20 boards dcdc2 is VDD-CPU and should be 1.4V.
- On A31 boards dcdc2 is used for VDD-GPU and should be 1.2V.
- On A23/A33 boards dcdc2 is used for VDD-SYS and should be 1.1V.
- On A80 boards dcdc2 powers the GPU and can be left off.
- On A83T boards dcdc2 is used for VDD-CPUA(cluster 0) and should be 0.9V.
- On R40 boards dcdc2 is VDD-CPU and should be 1.1V
- On boards using the AXP313 or AXP717 it's often VDD-CPU.
+ help
+ Set the voltage (mV) to program the axp pmic dcdc2 at, set to 0 to
+ disable dcdc2.
+ On A10(s) / A13 / A20 boards dcdc2 is VDD-CPU and should be 1.4V.
+ On A31 boards dcdc2 is used for VDD-GPU and should be 1.2V.
+ On A23/A33 boards dcdc2 is used for VDD-SYS and should be 1.1V.
+ On A80 boards dcdc2 powers the GPU and can be left off.
+ On A83T boards dcdc2 is used for VDD-CPUA(cluster 0) and should be 0.9V.
+ On R40 boards dcdc2 is VDD-CPU and should be 1.1V
+ On boards using the AXP313 or AXP717 it's often VDD-CPU.
config AXP_DCDC3_VOLT
int "axp pmic dcdc3 voltage"
@@ -214,18 +214,18 @@ config AXP_DCDC3_VOLT
default 1100 if AXP313_POWER
default 1100 if MACH_SUN8I_R40
default 1200 if MACH_SUN6I || MACH_SUN8I
- ---help---
- Set the voltage (mV) to program the axp pmic dcdc3 at, set to 0 to
- disable dcdc3.
- On A10(s) / A13 / A20 boards with an axp209 dcdc3 is VDD-INT-DLL and
- should be 1.25V.
- On A10s boards with an axp152 dcdc3 is VCC-DRAM and should be 1.5V.
- On A23 / A31 / A33 boards dcdc3 is VDD-CPU and should be 1.2V.
- On A80 boards dcdc3 is used for VDD-CPUA(cluster 0) and should be 0.9V.
- On A83T boards dcdc3 is used for VDD-CPUB(cluster 1) and should be 0.9V.
- On R40 boards dcdc3 is VDD-SYS and VDD-GPU and should be 1.1V.
- On boards using the AXP313 or AXP717 it's often VDD-DRAM and should
- be 1.1V for LPDDR4.
+ help
+ Set the voltage (mV) to program the axp pmic dcdc3 at, set to 0 to
+ disable dcdc3.
+ On A10(s) / A13 / A20 boards with an axp209 dcdc3 is VDD-INT-DLL and
+ should be 1.25V.
+ On A10s boards with an axp152 dcdc3 is VCC-DRAM and should be 1.5V.
+ On A23 / A31 / A33 boards dcdc3 is VDD-CPU and should be 1.2V.
+ On A80 boards dcdc3 is used for VDD-CPUA(cluster 0) and should be 0.9V.
+ On A83T boards dcdc3 is used for VDD-CPUB(cluster 1) and should be 0.9V.
+ On R40 boards dcdc3 is VDD-SYS and VDD-GPU and should be 1.1V.
+ On boards using the AXP313 or AXP717 it's often VDD-DRAM and should
+ be 1.1V for LPDDR4.
config AXP_DCDC4_VOLT
int "axp pmic dcdc4 voltage"
@@ -235,25 +235,25 @@ config AXP_DCDC4_VOLT
default 0 if MACH_SUN8I
default 900 if MACH_SUN9I
default 1500 if AXP305_POWER
- ---help---
- Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to
- disable dcdc4.
- On A10s boards with an axp152 dcdc4 is VDD-INT-DLL and should be 1.25V.
- On A31 boards dcdc4 is used for VDD-SYS and should be 1.2V.
- On A23 / A33 boards dcdc4 is unused and should be disabled.
- On A80 boards dcdc4 powers VDD-SYS, HDMI, USB OTG and should be 0.9V.
- On A83T boards dcdc4 is used for VDD-GPU.
- On H616 boards dcdcd is used for VCC-DRAM.
+ help
+ Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to
+ disable dcdc4.
+ On A10s boards with an axp152 dcdc4 is VDD-INT-DLL and should be 1.25V.
+ On A31 boards dcdc4 is used for VDD-SYS and should be 1.2V.
+ On A23 / A33 boards dcdc4 is unused and should be disabled.
+ On A80 boards dcdc4 powers VDD-SYS, HDMI, USB OTG and should be 0.9V.
+ On A83T boards dcdc4 is used for VDD-GPU.
+ On H616 boards dcdcd is used for VCC-DRAM.
config AXP_DCDC5_VOLT
int "axp pmic dcdc5 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP803_POWER
default 1500 if MACH_SUN6I || MACH_SUN8I || MACH_SUN9I
- ---help---
- Set the voltage (mV) to program the axp pmic dcdc5 at, set to 0 to
- disable dcdc5.
- On A23 / A31 / A33 / A80 / A83T / R40 boards dcdc5 is VCC-DRAM and
- should be 1.5V, 1.35V if DDR3L is used.
+ help
+ Set the voltage (mV) to program the axp pmic dcdc5 at, set to 0 to
+ disable dcdc5.
+ On A23 / A31 / A33 / A80 / A83T / R40 boards dcdc5 is VCC-DRAM and
+ should be 1.5V, 1.35V if DDR3L is used.
config AXP_ALDO1_VOLT
int "axp pmic (a)ldo1 voltage"
@@ -261,14 +261,14 @@ config AXP_ALDO1_VOLT
default 0 if MACH_SUN6I || MACH_SUN8I_R40
default 1800 if MACH_SUN8I_A83T
default 3000 if MACH_SUN8I || MACH_SUN9I
- ---help---
- Set the voltage (mV) to program the axp pmic aldo1 at, set to 0 to
- disable aldo1.
- On A31 boards aldo1 is often used to power the wifi module.
- On A23 / A33 boards aldo1 is used for VCC-IO and should be 3.0V.
- On A80 boards aldo1 powers the USB hosts and should be 3.0V.
- On A83T / H8 boards aldo1 is used for MIPI CSI, DSI, HDMI, EFUSE, and
- should be 1.8V.
+ help
+ Set the voltage (mV) to program the axp pmic aldo1 at, set to 0 to
+ disable aldo1.
+ On A31 boards aldo1 is often used to power the wifi module.
+ On A23 / A33 boards aldo1 is used for VCC-IO and should be 3.0V.
+ On A80 boards aldo1 powers the USB hosts and should be 3.0V.
+ On A83T / H8 boards aldo1 is used for MIPI CSI, DSI, HDMI, EFUSE, and
+ should be 1.8V.
config AXP_ALDO2_VOLT
int "axp pmic (a)ldo2 voltage"
@@ -277,188 +277,188 @@ config AXP_ALDO2_VOLT
default 0 if MACH_SUN6I || MACH_SUN9I
default 1800 if MACH_SUN8I_A83T
default 2500 if MACH_SUN8I
- ---help---
- Set the voltage (mV) to program the axp pmic aldo2 at, set to 0 to
- disable aldo2.
- On A10(s) / A13 / A20 boards aldo2 is AVCC and should be 3.0V.
- On A31 boards aldo2 is typically unused and should be disabled.
- On A31 boards aldo2 may be used for LPDDR2 then it should be 1.8V.
- On A23 / A33 boards aldo2 is used for VDD-DLL and should be 2.5V.
- On A80 boards aldo2 powers PB pingroup and camera IO and can be left off.
- On A83T / H8 boards aldo2 powers VDD-DLL, VCC18-PLL, CPVDD, VDD18-ADC,
- LPDDR2, and the codec. It should be 1.8V.
+ help
+ Set the voltage (mV) to program the axp pmic aldo2 at, set to 0 to
+ disable aldo2.
+ On A10(s) / A13 / A20 boards aldo2 is AVCC and should be 3.0V.
+ On A31 boards aldo2 is typically unused and should be disabled.
+ On A31 boards aldo2 may be used for LPDDR2 then it should be 1.8V.
+ On A23 / A33 boards aldo2 is used for VDD-DLL and should be 2.5V.
+ On A80 boards aldo2 powers PB pingroup and camera IO and can be left off.
+ On A83T / H8 boards aldo2 powers VDD-DLL, VCC18-PLL, CPVDD, VDD18-ADC,
+ LPDDR2, and the codec. It should be 1.8V.
config AXP_ALDO3_VOLT
int "axp pmic (a)ldo3 voltage"
depends on AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER
default 0 if AXP209_POWER || MACH_SUN9I
default 3000 if MACH_SUN6I || MACH_SUN8I
- ---help---
- Set the voltage (mV) to program the axp pmic aldo3 at, set to 0 to
- disable aldo3.
- On A10(s) / A13 / A20 boards aldo3 should be 2.8V.
- On A23 / A31 / A33 / R40 boards aldo3 is VCC-PLL and AVCC and should
- be 3.0V.
- On A80 boards aldo3 is normally not used.
- On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be
- 3.0V.
+ help
+ Set the voltage (mV) to program the axp pmic aldo3 at, set to 0 to
+ disable aldo3.
+ On A10(s) / A13 / A20 boards aldo3 should be 2.8V.
+ On A23 / A31 / A33 / R40 boards aldo3 is VCC-PLL and AVCC and should
+ be 3.0V.
+ On A80 boards aldo3 is normally not used.
+ On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be
+ 3.0V.
choice
prompt "axp pmic (a)ldo3 voltage rate control"
depends on AXP209_POWER
default AXP_ALDO3_VOLT_SLOPE_NONE
- ---help---
- The AXP can slowly ramp up voltage to reduce the inrush current when
- changing voltages.
- Note, this does not apply when enabling/disabling LDO3. See
- "axp pmic (a)ldo3 inrush quirk" below to enable a slew rate to limit
- inrush current on broken board designs.
+ help
+ The AXP can slowly ramp up voltage to reduce the inrush current when
+ changing voltages.
+ Note, this does not apply when enabling/disabling LDO3. See
+ "axp pmic (a)ldo3 inrush quirk" below to enable a slew rate to limit
+ inrush current on broken board designs.
config AXP_ALDO3_VOLT_SLOPE_NONE
bool "No voltage slope"
- ---help---
- Tries to reach the next voltage setting near instantaneously. Measurements
- indicate that this is about 0.0167 V/uS.
+ help
+ Tries to reach the next voltage setting near instantaneously. Measurements
+ indicate that this is about 0.0167 V/uS.
config AXP_ALDO3_VOLT_SLOPE_16
bool "1.6 mV per uS"
- ---help---
- Increases the voltage by 1.6 mV per uS until the final voltage has
- been reached. Note that the scaling is in 25 mV steps and thus
- the slew rate in reality is about 25 mV/31.250 uS.
+ help
+ Increases the voltage by 1.6 mV per uS until the final voltage has
+ been reached. Note that the scaling is in 25 mV steps and thus
+ the slew rate in reality is about 25 mV/31.250 uS.
config AXP_ALDO3_VOLT_SLOPE_08
bool "0.8 mV per uS"
- ---help---
- Increases the voltage by 0.8 mV per uS until the final voltage has
- been reached. Note that the scaling is in 25 mV steps however and thus
- the slew rate in reality is about 25 mV/15.625 uS.
- This is the slowest supported rate.
+ help
+ Increases the voltage by 0.8 mV per uS until the final voltage has
+ been reached. Note that the scaling is in 25 mV steps however and thus
+ the slew rate in reality is about 25 mV/15.625 uS.
+ This is the slowest supported rate.
endchoice
config AXP_ALDO3_INRUSH_QUIRK
bool "axp pmic (a)ldo3 inrush quirk"
depends on AXP209_POWER
- ---help---
- The reference design denotes a value of 4.7 uF for the output capacitor
- of LDO3. Some boards have too high capacitance causing an inrush current
- and resulting an AXP209 shutdown.
+ help
+ The reference design denotes a value of 4.7 uF for the output capacitor
+ of LDO3. Some boards have too high capacitance causing an inrush current
+ and resulting an AXP209 shutdown.
config AXP_ALDO4_VOLT
int "axp pmic (a)ldo4 voltage"
depends on AXP209_POWER
default 0 if AXP209_POWER
- ---help---
- Set the voltage (mV) to program the axp pmic aldo4 at, set to 0 to
- disable aldo4.
- On A10(s) / A13 / A20 boards aldo4 should be 2.8V.
+ help
+ Set the voltage (mV) to program the axp pmic aldo4 at, set to 0 to
+ disable aldo4.
+ On A10(s) / A13 / A20 boards aldo4 should be 2.8V.
config AXP_DLDO1_VOLT
int "axp pmic dldo1 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic dldo1 at, set to 0 to
- disable dldo1. On sun6i (A31) boards with ethernet dldo1 is often used
- to power the ethernet phy. On A23, A33 and A80 boards this is often
- used to power the wifi.
+ help
+ Set the voltage (mV) to program the axp pmic dldo1 at, set to 0 to
+ disable dldo1. On sun6i (A31) boards with ethernet dldo1 is often used
+ to power the ethernet phy. On A23, A33 and A80 boards this is often
+ used to power the wifi.
config AXP_DLDO2_VOLT
int "axp pmic dldo2 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER
default 3000 if MACH_SUN9I
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic dldo2 at, set to 0 to
- disable dldo2.
- On A80 boards dldo2 normally powers the PL pins and should be 3.0V.
+ help
+ Set the voltage (mV) to program the axp pmic dldo2 at, set to 0 to
+ disable dldo2.
+ On A80 boards dldo2 normally powers the PL pins and should be 3.0V.
config AXP_DLDO3_VOLT
int "axp pmic dldo3 voltage"
depends on AXP221_POWER || AXP818_POWER
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic dldo3 at, set to 0 to
- disable dldo3.
+ help
+ Set the voltage (mV) to program the axp pmic dldo3 at, set to 0 to
+ disable dldo3.
config AXP_DLDO4_VOLT
int "axp pmic dldo4 voltage"
depends on AXP221_POWER || AXP818_POWER
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic dldo4 at, set to 0 to
- disable dldo4.
+ help
+ Set the voltage (mV) to program the axp pmic dldo4 at, set to 0 to
+ disable dldo4.
config AXP_ELDO1_VOLT
int "axp pmic eldo1 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic eldo1 at, set to 0 to
- disable eldo1.
+ help
+ Set the voltage (mV) to program the axp pmic eldo1 at, set to 0 to
+ disable eldo1.
config AXP_ELDO2_VOLT
int "axp pmic eldo2 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic eldo2 at, set to 0 to
- disable eldo2.
+ help
+ Set the voltage (mV) to program the axp pmic eldo2 at, set to 0 to
+ disable eldo2.
config AXP_ELDO3_VOLT
int "axp pmic eldo3 voltage"
depends on AXP221_POWER || AXP809_POWER || AXP818_POWER
default 3000 if MACH_SUN9I
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic eldo3 at, set to 0 to
- disable eldo3. On some A31(s) tablets it might be used to supply
- 1.2V for the SSD2828 chip (converter of parallel LCD interface
- into MIPI DSI).
- On A80 boards it powers the PM pingroup and should be 3.0V.
+ help
+ Set the voltage (mV) to program the axp pmic eldo3 at, set to 0 to
+ disable eldo3. On some A31(s) tablets it might be used to supply
+ 1.2V for the SSD2828 chip (converter of parallel LCD interface
+ into MIPI DSI).
+ On A80 boards it powers the PM pingroup and should be 3.0V.
config AXP_FLDO1_VOLT
int "axp pmic fldo1 voltage"
depends on AXP818_POWER
default 0 if MACH_SUN8I_A83T
- ---help---
- Set the voltage (mV) to program the axp pmic fldo1 at, set to 0 to
- disable fldo1.
- On A83T / H8 boards fldo1 is VCC-HSIC and should be 1.2V if HSIC is
- used.
+ help
+ Set the voltage (mV) to program the axp pmic fldo1 at, set to 0 to
+ disable fldo1.
+ On A83T / H8 boards fldo1 is VCC-HSIC and should be 1.2V if HSIC is
+ used.
config AXP_FLDO2_VOLT
int "axp pmic fldo2 voltage"
depends on AXP818_POWER
default 900 if MACH_SUN8I_A83T
- ---help---
- Set the voltage (mV) to program the axp pmic fldo2 at, set to 0 to
- disable fldo2.
- On A83T / H8 boards fldo2 is VCC-CPUS and should be 0.9V.
+ help
+ Set the voltage (mV) to program the axp pmic fldo2 at, set to 0 to
+ disable fldo2.
+ On A83T / H8 boards fldo2 is VCC-CPUS and should be 0.9V.
config AXP_FLDO3_VOLT
int "axp pmic fldo3 voltage"
depends on AXP818_POWER
default 0
- ---help---
- Set the voltage (mV) to program the axp pmic fldo3 at, set to 0 to
- disable fldo3.
+ help
+ Set the voltage (mV) to program the axp pmic fldo3 at, set to 0 to
+ disable fldo3.
config AXP_SW_ON
bool "axp pmic sw on"
depends on AXP809_POWER || AXP818_POWER
- ---help---
- Enable to turn on axp pmic sw.
+ help
+ Enable to turn on axp pmic sw.
config SY8106A_VOUT1_VOLT
int "SY8106A pmic VOUT1 voltage"
depends on SY8106A_POWER
default 1200
- ---help---
- Set the voltage (mV) to program the SY8106A pmic VOUT1. This
- is typically used to power the VDD-CPU and should be 1200mV.
- Values can range from 680mV till 1950mV.
+ help
+ Set the voltage (mV) to program the SY8106A pmic VOUT1. This
+ is typically used to power the VDD-CPU and should be 1200mV.
+ Values can range from 680mV till 1950mV.
config TPS6586X_POWER
bool "Enable legacy driver for TI TPS6586x power management chip"
@@ -467,9 +467,9 @@ config TWL4030_POWER
depends on OMAP34XX
bool "Enable driver for TI TWL4030 power management chip"
imply CMD_POWEROFF
- ---help---
- The TWL4030 in a combination audio CODEC/power management with
- GPIO and it is commonly used with the OMAP3 family of processors
+ help
+ The TWL4030 in a combination audio CODEC/power management with
+ GPIO and it is commonly used with the OMAP3 family of processors
config POWER_MT6323
bool "Poweroff driver for mediatek mt6323"
diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index 4112b777371..bb9c52155d2 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -35,10 +35,10 @@ config BCM6328_POWER_DOMAIN
config IMX8_POWER_DOMAIN
bool "Enable i.MX8 power domain driver"
- depends on ARCH_IMX8
- help
- Enable support for manipulating NXP i.MX8 on-SoC power domains via IPC
- requests to the SCU.
+ depends on ARCH_IMX8
+ help
+ Enable support for manipulating NXP i.MX8 on-SoC power domains via IPC
+ requests to the SCU.
config IMX8M_POWER_DOMAIN
bool "Enable i.MX8M power domain driver"
diff --git a/drivers/power/domain/apple-pmgr.c b/drivers/power/domain/apple-pmgr.c
index 71fedb405da..9873d3cd8db 100644
--- a/drivers/power/domain/apple-pmgr.c
+++ b/drivers/power/domain/apple-pmgr.c
@@ -67,7 +67,7 @@ static int apple_reset_deassert(struct reset_ctl *reset_ctl)
return 0;
}
-struct reset_ops apple_reset_ops = {
+static const struct reset_ops apple_reset_ops = {
.of_xlate = apple_reset_of_xlate,
.rst_assert = apple_reset_assert,
.rst_deassert = apple_reset_deassert,
@@ -139,7 +139,7 @@ static int apple_pmgr_probe(struct udevice *dev)
return 0;
}
-struct power_domain_ops apple_pmgr_ops = {
+static const struct power_domain_ops apple_pmgr_ops = {
.on = apple_pmgr_on,
.of_xlate = apple_pmgr_of_xlate,
};
diff --git a/drivers/power/domain/bcm6328-power-domain.c b/drivers/power/domain/bcm6328-power-domain.c
index 36b5a933748..5b449f4c29d 100644
--- a/drivers/power/domain/bcm6328-power-domain.c
+++ b/drivers/power/domain/bcm6328-power-domain.c
@@ -57,7 +57,7 @@ static const struct udevice_id bcm6328_power_domain_ids[] = {
{ /* sentinel */ }
};
-struct power_domain_ops bcm6328_power_domain_ops = {
+static const struct power_domain_ops bcm6328_power_domain_ops = {
.off = bcm6328_power_domain_off,
.on = bcm6328_power_domain_on,
.request = bcm6328_power_domain_request,
diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c
index 713a51d7807..a646f667039 100644
--- a/drivers/power/domain/imx8-power-domain-legacy.c
+++ b/drivers/power/domain/imx8-power-domain-legacy.c
@@ -347,7 +347,7 @@ static const struct udevice_id imx8_power_domain_ids[] = {
{ }
};
-struct power_domain_ops imx8_power_domain_ops = {
+static const struct power_domain_ops imx8_power_domain_ops = {
.on = imx8_power_domain_on,
.off = imx8_power_domain_off,
.of_xlate = imx8_power_domain_of_xlate,
diff --git a/drivers/power/domain/imx8-power-domain.c b/drivers/power/domain/imx8-power-domain.c
index e8dcc057fee..5740cd686db 100644
--- a/drivers/power/domain/imx8-power-domain.c
+++ b/drivers/power/domain/imx8-power-domain.c
@@ -51,7 +51,7 @@ static const struct udevice_id imx8_power_domain_ids[] = {
{ }
};
-struct power_domain_ops imx8_power_domain_ops_v2 = {
+static const struct power_domain_ops imx8_power_domain_ops_v2 = {
.on = imx8_power_domain_on,
.off = imx8_power_domain_off,
};
diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c
index 1c731b897cc..a3ef49aa67c 100644
--- a/drivers/power/domain/imx8m-power-domain.c
+++ b/drivers/power/domain/imx8m-power-domain.c
@@ -476,7 +476,7 @@ static int imx8m_power_domain_bind(struct udevice *dev)
const char *name;
int ret = 0;
- ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
+ dev_for_each_subnode(subnode, dev) {
/* Bind the subnode to this driver */
name = ofnode_get_name(subnode);
@@ -531,7 +531,7 @@ static int imx8m_power_domain_of_to_plat(struct udevice *dev)
struct imx_pgc_domain_data *domain_data =
(struct imx_pgc_domain_data *)dev_get_driver_data(dev);
- pdata->resource_id = ofnode_read_u32_default(dev_ofnode(dev), "reg", -1);
+ pdata->resource_id = dev_read_u32_default(dev, "reg", -1);
pdata->domain = &domain_data->domains[pdata->resource_id];
pdata->regs = domain_data->pgc_regs;
pdata->base = dev_read_addr_ptr(dev->parent);
@@ -558,7 +558,7 @@ static const struct udevice_id imx8m_power_domain_ids[] = {
{ }
};
-struct power_domain_ops imx8m_power_domain_ops = {
+static const struct power_domain_ops imx8m_power_domain_ops = {
.on = imx8m_power_domain_on,
.off = imx8m_power_domain_off,
.of_xlate = imx8m_power_domain_of_xlate,
diff --git a/drivers/power/domain/imx8mp-mediamix.c b/drivers/power/domain/imx8mp-mediamix.c
index 504c22f7d36..66ea5d8e60c 100644
--- a/drivers/power/domain/imx8mp-mediamix.c
+++ b/drivers/power/domain/imx8mp-mediamix.c
@@ -194,7 +194,7 @@ static const struct udevice_id imx8mp_mediamix_ids[] = {
{ }
};
-struct power_domain_ops imx8mp_mediamix_ops = {
+static const struct power_domain_ops imx8mp_mediamix_ops = {
.on = imx8mp_mediamix_on,
.off = imx8mp_mediamix_off,
.of_xlate = imx8mp_mediamix_of_xlate,
diff --git a/drivers/power/domain/meson-ee-pwrc.c b/drivers/power/domain/meson-ee-pwrc.c
index 4d9f3bba644..882238f2937 100644
--- a/drivers/power/domain/meson-ee-pwrc.c
+++ b/drivers/power/domain/meson-ee-pwrc.c
@@ -386,7 +386,7 @@ static int meson_ee_pwrc_of_xlate(struct power_domain *power_domain,
return 0;
}
-struct power_domain_ops meson_ee_pwrc_ops = {
+static const struct power_domain_ops meson_ee_pwrc_ops = {
.off = meson_ee_pwrc_off,
.on = meson_ee_pwrc_on,
.of_xlate = meson_ee_pwrc_of_xlate,
@@ -435,8 +435,7 @@ static const struct udevice_id meson_ee_pwrc_ids[] = {
static int meson_ee_pwrc_probe(struct udevice *dev)
{
struct meson_ee_pwrc_priv *priv = dev_get_priv(dev);
- u32 ao_phandle;
- ofnode ao_node;
+ struct ofnode_phandle_args args;
int ret;
priv->data = (void *)dev_get_driver_data(dev);
@@ -447,16 +446,12 @@ static int meson_ee_pwrc_probe(struct udevice *dev)
if (IS_ERR(priv->regmap_hhi))
return PTR_ERR(priv->regmap_hhi);
- ret = ofnode_read_u32(dev_ofnode(dev), "amlogic,ao-sysctrl",
- &ao_phandle);
+ ret = dev_read_phandle_with_args(dev, "amlogic,ao-sysctrl", NULL, 0, 0,
+ &args);
if (ret)
return ret;
- ao_node = ofnode_get_by_phandle(ao_phandle);
- if (!ofnode_valid(ao_node))
- return -EINVAL;
-
- priv->regmap_ao = syscon_node_to_regmap(ao_node);
+ priv->regmap_ao = syscon_node_to_regmap(args.node);
if (IS_ERR(priv->regmap_ao))
return PTR_ERR(priv->regmap_ao);
diff --git a/drivers/power/domain/meson-gx-pwrc-vpu.c b/drivers/power/domain/meson-gx-pwrc-vpu.c
index 1c56e8508c3..e08c0fac49a 100644
--- a/drivers/power/domain/meson-gx-pwrc-vpu.c
+++ b/drivers/power/domain/meson-gx-pwrc-vpu.c
@@ -262,7 +262,7 @@ static int meson_pwrc_vpu_of_xlate(struct power_domain *power_domain,
return 0;
}
-struct power_domain_ops meson_gx_pwrc_vpu_ops = {
+static const struct power_domain_ops meson_gx_pwrc_vpu_ops = {
.off = meson_pwrc_vpu_off,
.on = meson_pwrc_vpu_on,
.of_xlate = meson_pwrc_vpu_of_xlate,
@@ -283,24 +283,19 @@ static const struct udevice_id meson_gx_pwrc_vpu_ids[] = {
static int meson_gx_pwrc_vpu_probe(struct udevice *dev)
{
struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(dev);
- u32 hhi_phandle;
- ofnode hhi_node;
+ struct ofnode_phandle_args args;
int ret;
priv->regmap_ao = syscon_node_to_regmap(dev_ofnode(dev_get_parent(dev)));
if (IS_ERR(priv->regmap_ao))
return PTR_ERR(priv->regmap_ao);
- ret = ofnode_read_u32(dev_ofnode(dev), "amlogic,hhi-sysctrl",
- &hhi_phandle);
+ ret = dev_read_phandle_with_args(dev, "amlogic,hhi-sysctrl", NULL, 0, 0,
+ &args);
if (ret)
return ret;
- hhi_node = ofnode_get_by_phandle(hhi_phandle);
- if (!ofnode_valid(hhi_node))
- return -EINVAL;
-
- priv->regmap_hhi = syscon_node_to_regmap(hhi_node);
+ priv->regmap_hhi = syscon_node_to_regmap(args.node);
if (IS_ERR(priv->regmap_hhi))
return PTR_ERR(priv->regmap_hhi);
diff --git a/drivers/power/domain/meson-secure-pwrc.c b/drivers/power/domain/meson-secure-pwrc.c
index f70f8e02423..1b82b58f3e5 100644
--- a/drivers/power/domain/meson-secure-pwrc.c
+++ b/drivers/power/domain/meson-secure-pwrc.c
@@ -120,7 +120,7 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
SEC_PD(RSA),
};
-struct power_domain_ops meson_secure_pwrc_ops = {
+static const struct power_domain_ops meson_secure_pwrc_ops = {
.on = meson_secure_pwrc_on,
.off = meson_secure_pwrc_off,
.of_xlate = meson_secure_pwrc_of_xlate,
diff --git a/drivers/power/domain/mtk-power-domain.c b/drivers/power/domain/mtk-power-domain.c
index 2d1ba1855a5..24dd540897d 100644
--- a/drivers/power/domain/mtk-power-domain.c
+++ b/drivers/power/domain/mtk-power-domain.c
@@ -392,7 +392,7 @@ static const struct udevice_id mtk_power_domain_ids[] = {
{ /* sentinel */ }
};
-struct power_domain_ops mtk_power_domain_ops = {
+static const struct power_domain_ops mtk_power_domain_ops = {
.off = scpsys_power_off,
.on = scpsys_power_on,
.request = scpsys_power_request,
diff --git a/drivers/power/domain/renesas-r8a78000-power-domain.c b/drivers/power/domain/renesas-r8a78000-power-domain.c
index d621373f90d..57b3b56b2d9 100644
--- a/drivers/power/domain/renesas-r8a78000-power-domain.c
+++ b/drivers/power/domain/renesas-r8a78000-power-domain.c
@@ -11,6 +11,7 @@
#include <dm/lists.h>
#include <linux/io.h>
#include <linux/iopoll.h>
+#include <linux/bitfield.h>
#include <power-domain-uclass.h>
#include <reset-uclass.h>
@@ -21,9 +22,6 @@
#include <dt-bindings/power/r8a78000-power-scmi.h>
#include <dt-bindings/reset/r8a78000-reset-scmi.h>
-#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
-
#define PKC_PROT_LOCK 0xa5a5a500
#define PKC_PROT_UNLOCK 0xa5a5a501
diff --git a/drivers/power/domain/sandbox-power-domain.c b/drivers/power/domain/sandbox-power-domain.c
index a8031657638..a30826a3b4d 100644
--- a/drivers/power/domain/sandbox-power-domain.c
+++ b/drivers/power/domain/sandbox-power-domain.c
@@ -78,7 +78,7 @@ static const struct udevice_id sandbox_power_domain_ids[] = {
{ }
};
-struct power_domain_ops sandbox_power_domain_ops = {
+static const struct power_domain_ops sandbox_power_domain_ops = {
.request = sandbox_power_domain_request,
.rfree = sandbox_power_domain_free,
.on = sandbox_power_domain_on,
diff --git a/drivers/power/domain/scmi-power-domain.c b/drivers/power/domain/scmi-power-domain.c
index e8c0ba8878e..a369fe52f2f 100644
--- a/drivers/power/domain/scmi-power-domain.c
+++ b/drivers/power/domain/scmi-power-domain.c
@@ -165,21 +165,15 @@ static int scmi_power_domain_probe(struct udevice *dev)
for (i = 0; i < priv->num_pwdoms; i++) {
ret = scmi_pwd_attrs(dev, i, &priv->prop[i].attributes,
&priv->prop[i].name);
- if (ret) {
+ if (ret)
dev_err(dev, "failed to get attributes pwd:%d (%d)\n",
i, ret);
- for (i--; i >= 0; i--)
- free(priv->prop[i].name);
- free(priv->prop);
-
- return ret;
- }
}
return 0;
}
-struct power_domain_ops scmi_power_domain_ops = {
+static const struct power_domain_ops scmi_power_domain_ops = {
.on = scmi_power_domain_on,
.off = scmi_power_domain_off,
};
diff --git a/drivers/power/domain/tegra186-power-domain.c b/drivers/power/domain/tegra186-power-domain.c
index 334c460c805..3865cd4cf47 100644
--- a/drivers/power/domain/tegra186-power-domain.c
+++ b/drivers/power/domain/tegra186-power-domain.c
@@ -55,7 +55,7 @@ static int tegra186_power_domain_off(struct power_domain *power_domain)
return tegra186_power_domain_common(power_domain, false);
}
-struct power_domain_ops tegra186_power_domain_ops = {
+static const struct power_domain_ops tegra186_power_domain_ops = {
.on = tegra186_power_domain_on,
.off = tegra186_power_domain_off,
};
diff --git a/drivers/power/domain/zynqmp-power-domain.c b/drivers/power/domain/zynqmp-power-domain.c
index a54de5c1439..0acfc54e787 100644
--- a/drivers/power/domain/zynqmp-power-domain.c
+++ b/drivers/power/domain/zynqmp-power-domain.c
@@ -57,7 +57,7 @@ static int zynqmp_power_domain_off(struct power_domain *power_domain)
return 0;
}
-struct power_domain_ops zynqmp_power_domain_ops = {
+static const struct power_domain_ops zynqmp_power_domain_ops = {
.request = zynqmp_power_domain_request,
.rfree = zynqmp_power_domain_free,
.on = zynqmp_power_domain_on,
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 5bc14842e66..d45869cb30f 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -1,14 +1,14 @@
config DM_PMIC
bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC)"
depends on DM
- ---help---
- This config enables the driver-model PMIC support.
- UCLASS_PMIC - designed to provide an I/O interface for PMIC devices.
- For the multi-function PMIC devices, this can be used as parent I/O
- device for each IC's interface. Then, each children uses its parent
- for read/write. For detailed description, please refer to the files:
- - 'drivers/power/pmic/pmic-uclass.c'
- - 'include/power/pmic.h'
+ help
+ This config enables the driver-model PMIC support.
+ UCLASS_PMIC - designed to provide an I/O interface for PMIC devices.
+ For the multi-function PMIC devices, this can be used as parent I/O
+ device for each IC's interface. Then, each children uses its parent
+ for read/write. For detailed description, please refer to the files:
+ - 'drivers/power/pmic/pmic-uclass.c'
+ - 'include/power/pmic.h'
if DM_PMIC
@@ -16,34 +16,34 @@ config SPL_DM_PMIC
bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC) in SPL"
depends on SPL_DM
default y
- ---help---
- This config enables the driver-model PMIC support in SPL.
- UCLASS_PMIC - designed to provide an I/O interface for PMIC devices.
- For the multi-function PMIC devices, this can be used as parent I/O
- device for each IC's interface. Then, each children uses its parent
- for read/write. For detailed description, please refer to the files:
- - 'drivers/power/pmic/pmic-uclass.c'
- - 'include/power/pmic.h'
+ help
+ This config enables the driver-model PMIC support in SPL.
+ UCLASS_PMIC - designed to provide an I/O interface for PMIC devices.
+ For the multi-function PMIC devices, this can be used as parent I/O
+ device for each IC's interface. Then, each children uses its parent
+ for read/write. For detailed description, please refer to the files:
+ - 'drivers/power/pmic/pmic-uclass.c'
+ - 'include/power/pmic.h'
config PMIC_CHILDREN
bool "Allow child devices for PMICs"
default y
- ---help---
- This allows PMICs to support child devices (such as regulators) in
- SPL. This adds quite a bit of code so if you are not using this
- feature you can turn it off. Most likely you should turn it on for
- U-Boot proper.
+ help
+ This allows PMICs to support child devices (such as regulators) in
+ SPL. This adds quite a bit of code so if you are not using this
+ feature you can turn it off. Most likely you should turn it on for
+ U-Boot proper.
config SPL_PMIC_CHILDREN
bool "Allow child devices for PMICs in SPL"
depends on SPL_DM_PMIC
default y
- ---help---
- This allows PMICs to support child devices (such as regulators) in
- SPL. This adds quite a bit of code so if you are not using this
- feature you can turn it off. In this case you may need a 'back door'
- to call your regulator code (e.g. see rk8xx.c for direct functions
- for use in SPL).
+ help
+ This allows PMICs to support child devices (such as regulators) in
+ SPL. This adds quite a bit of code so if you are not using this
+ feature you can turn it off. In this case you may need a 'back door'
+ to call your regulator code (e.g. see rk8xx.c for direct functions
+ for use in SPL).
config PMIC_AB8500
bool "Enable driver for ST-Ericsson AB8500 PMIC via PRCMU"
@@ -57,11 +57,11 @@ config PMIC_AB8500
config PMIC_ACT8846
bool "Enable support for the active-semi 8846 PMIC"
depends on DM_I2C
- ---help---
- This PMIC includes 4 DC/DC step-down buck regulators and 8 low-dropout
- regulators (LDOs). It also provides some GPIO, reset and battery
- functions. It uses an I2C interface and is designed for use with
- tablets and smartphones.
+ help
+ This PMIC includes 4 DC/DC step-down buck regulators and 8 low-dropout
+ regulators (LDOs). It also provides some GPIO, reset and battery
+ functions. It uses an I2C interface and is designed for use with
+ tablets and smartphones.
config PMIC_AXP
bool "Enable Driver Model for X-Powers AXP PMICs"
@@ -101,8 +101,8 @@ config PMIC_AS3722
required for a tablets or laptop.
config DM_PMIC_BD71837
- bool "Enable Driver Model for PMIC BD71837"
- help
+ bool "Enable Driver Model for PMIC BD71837"
+ help
This config enables implementation of driver-model pmic uclass features
for PMIC BD71837. The driver implements read/write operations.
@@ -173,257 +173,257 @@ config SPL_DM_PMIC_PCA9450
config DM_PMIC_PFUZE100
bool "Enable Driver Model for PMIC PFUZE100"
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for PMIC PFUZE100. The driver implements read/write operations.
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC PFUZE100. The driver implements read/write operations.
config SPL_DM_PMIC_PFUZE100
bool "Enable Driver Model for PMIC PFUZE100 in SPL"
depends on SPL_DM_PMIC
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for PMIC PFUZE100 in SPL. The driver implements read/write operations.
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC PFUZE100 in SPL. The driver implements read/write operations.
config DM_PMIC_MAX8907
bool "Enable Driver Model for PMIC MAX8907"
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for PMIC MAX8907. The driver implements read/write operations.
- This is a Power Management IC with a decent set of peripherals from which
- 3 DC-to-DC Step-Down (SD) Regulators, 20 Low-Dropout Linear (LDO) Regulators,
- Real-Time Clock (RTC) and more with I2C Compatible Interface.
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC MAX8907. The driver implements read/write operations.
+ This is a Power Management IC with a decent set of peripherals from which
+ 3 DC-to-DC Step-Down (SD) Regulators, 20 Low-Dropout Linear (LDO) Regulators,
+ Real-Time Clock (RTC) and more with I2C Compatible Interface.
config DM_PMIC_MAX77663
bool "Enable Driver Model for PMIC MAX77663"
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for PMIC MAX77663. The driver implements read/write operations.
- This is a Power Management IC with a decent set of peripherals from which
- 4 DC-to-DC Step-Down (SD) Regulators, 9 Low-Dropout Linear (LDO) Regulators,
- 8 GPIOs, Real-Time Clock (RTC) and more with I2C Compatible Interface.
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC MAX77663. The driver implements read/write operations.
+ This is a Power Management IC with a decent set of peripherals from which
+ 4 DC-to-DC Step-Down (SD) Regulators, 9 Low-Dropout Linear (LDO) Regulators,
+ 8 GPIOs, Real-Time Clock (RTC) and more with I2C Compatible Interface.
config DM_PMIC_MAX77686
bool "Enable Driver Model for PMIC MAX77686"
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for PMIC MAX77686. The driver implements read/write operations.
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC MAX77686. The driver implements read/write operations.
config DM_PMIC_MAX8998
bool "Enable Driver Model for PMIC MAX8998"
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for PMIC MAX8998. The driver implements read/write operations.
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC MAX8998. The driver implements read/write operations.
config DM_PMIC_MC34708
bool "Enable Driver Model for PMIC MC34708"
help
- This config enables implementation of driver-model pmic uclass features
- for PMIC MC34708. The driver implements read/write operations.
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC MC34708. The driver implements read/write operations.
config PMIC_MAX8997
bool "Enable Driver Model for PMIC MAX8997"
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for PMIC MAX8997. The driver implements read/write operations.
- This is a Power Management IC with RTC, Fuel Gauge, MUIC control on Chip.
- - 21x LDOs
- - 12x GPIOs
- - Haptic motor driver
- - RTC with two alarms
- - Fuel Gauge and one backup battery charger
- - MUIC
- - Others
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for PMIC MAX8997. The driver implements read/write operations.
+ This is a Power Management IC with RTC, Fuel Gauge, MUIC control on Chip.
+ - 21x LDOs
+ - 12x GPIOs
+ - Haptic motor driver
+ - RTC with two alarms
+ - Fuel Gauge and one backup battery charger
+ - MUIC
+ - Others
config PMIC_QCOM
bool "Enable Driver Model for Qualcomm generic PMIC"
- ---help---
- The Qcom PMIC is connected to one (or several) processors
- with SPMI bus. It has 2 slaves with several peripherals:
- - 18x LDO
- - 4x GPIO
- - Power and Reset buttons
- - Watchdog
- - RTC
- - Vibrator drivers
- - Others
+ help
+ The Qcom PMIC is connected to one (or several) processors
+ with SPMI bus. It has 2 slaves with several peripherals:
+ - 18x LDO
+ - 4x GPIO
+ - Power and Reset buttons
+ - Watchdog
+ - RTC
+ - Vibrator drivers
+ - Others
- Driver binding info: doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt
+ Driver binding info: doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt
config PMIC_RK8XX
bool "Enable support for Rockchip PMIC RK8XX"
select SYSRESET_CMD_POWEROFF if SYSRESET && CMD_POWEROFF
- ---help---
- The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
- an RTC and two low Rds (resistance (drain to source)) switches. It is
- accessed via an I2C interface. The device is used with Rockchip SoCs.
- This driver implements register read/write operations.
+ help
+ The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
+ an RTC and two low Rds (resistance (drain to source)) switches. It is
+ accessed via an I2C interface. The device is used with Rockchip SoCs.
+ This driver implements register read/write operations.
config SPL_PMIC_RK8XX
bool "Enable support for Rockchip PMIC RK8XX in SPL"
depends on SPL_DM_PMIC
- ---help---
- The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
- an RTC and two low Rds (resistance (drain to source)) switches. It is
- accessed via an I2C interface. The device is used with Rockchip SoCs.
- This driver implements register read/write operations.
+ help
+ The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
+ an RTC and two low Rds (resistance (drain to source)) switches. It is
+ accessed via an I2C interface. The device is used with Rockchip SoCs.
+ This driver implements register read/write operations.
config PMIC_S2MPS11
bool "Enable Driver Model for PMIC Samsung S2MPS11"
- ---help---
- The Samsung S2MPS11 PMIC provides:
- - 38 adjustable LDO regulators
- - 9 High-Efficiency Buck Converters
- - 1 BuckBoost Converter
- - RTC with two alarms
- - Backup battery charger
- - I2C Configuration Interface
- This driver provides access to I/O interface only.
- Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+ help
+ The Samsung S2MPS11 PMIC provides:
+ - 38 adjustable LDO regulators
+ - 9 High-Efficiency Buck Converters
+ - 1 BuckBoost Converter
+ - RTC with two alarms
+ - Backup battery charger
+ - I2C Configuration Interface
+ This driver provides access to I/O interface only.
+ Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
config DM_PMIC_SANDBOX
bool "Enable Driver Model for emulated Sandbox PMIC"
- ---help---
- Enable the driver for Sandbox PMIC emulation. The emulated PMIC device
- depends on two drivers:
- - sandbox PMIC I/O driver - implements dm pmic operations
- - sandbox PMIC i2c emul driver - emulates the PMIC's I2C transmission
+ help
+ Enable the driver for Sandbox PMIC emulation. The emulated PMIC device
+ depends on two drivers:
+ - sandbox PMIC I/O driver - implements dm pmic operations
+ - sandbox PMIC i2c emul driver - emulates the PMIC's I2C transmission
- A detailed information can be found in header: '<power/sandbox_pmic.h>'
+ A detailed information can be found in header: '<power/sandbox_pmic.h>'
- The Sandbox PMIC info:
- * I/O interface:
- - I2C chip address: 0x40
- - first register address: 0x0
- - register count: 0x10
- * Adjustable outputs:
- - 2x LDO
- - 2x BUCK
- - Each, with a different operating conditions (header).
- * Reset values:
- - set by i2c emul driver's probe() (defaults in header)
+ The Sandbox PMIC info:
+ * I/O interface:
+ - I2C chip address: 0x40
+ - first register address: 0x0
+ - register count: 0x10
+ * Adjustable outputs:
+ - 2x LDO
+ - 2x BUCK
+ - Each, with a different operating conditions (header).
+ * Reset values:
+ - set by i2c emul driver's probe() (defaults in header)
- Driver binding info: doc/device-tree-bindings/pmic/sandbox.txt
+ Driver binding info: doc/device-tree-bindings/pmic/sandbox.txt
config DM_PMIC_CPCAP
bool "Enable Driver Model for Motorola CPCAP"
help
- The CPCAP is a Motorola/ST-Ericsson creation, a multifunctional IC
- whose main purpose is power control. It was used in a wide variety of
- Motorola products, both Tegra and OMAP based. The most notable devices
- using this PMIC are the Motorola Droid 4, Atrix 4G, and Droid X2.
- Unlike most PMICs, this one is not I2C based; it uses the SPI bus. The
- core driver provides both read and write access to the device registers.
+ The CPCAP is a Motorola/ST-Ericsson creation, a multifunctional IC
+ whose main purpose is power control. It was used in a wide variety of
+ Motorola products, both Tegra and OMAP based. The most notable devices
+ using this PMIC are the Motorola Droid 4, Atrix 4G, and Droid X2.
+ Unlike most PMICs, this one is not I2C based; it uses the SPI bus. The
+ core driver provides both read and write access to the device registers.
config PMIC_S5M8767
bool "Enable Driver Model for the Samsung S5M8767 PMIC"
- ---help---
- The S5M8767 PMIC provides a large array of LDOs and BUCKs for use
- as a SoC power controller. It also provides 32KHz clock outputs. This
- driver provides basic register access and sets up the attached
- regulators if regulator support is enabled.
+ help
+ The S5M8767 PMIC provides a large array of LDOs and BUCKs for use
+ as a SoC power controller. It also provides 32KHz clock outputs. This
+ driver provides basic register access and sets up the attached
+ regulators if regulator support is enabled.
config PMIC_RN5T567
bool "Enable driver for Ricoh RN5T567 PMIC"
- ---help---
- The RN5T567 is a PMIC with 4 step-down DC/DC converters, 5 LDO
- regulators Real-Time Clock and 4 GPIOs. This driver provides
- register access only.
+ help
+ The RN5T567 is a PMIC with 4 step-down DC/DC converters, 5 LDO
+ regulators Real-Time Clock and 4 GPIOs. This driver provides
+ register access only.
config SPL_PMIC_RN5T567
bool "Enable driver for Ricoh RN5T567 PMIC in SPL"
depends on SPL_DM_PMIC
- ---help---
- The RN5T567 is a PMIC with 4 step-down DC/DC converters, 5 LDO
- regulators Real-Time Clock and 4 GPIOs. This driver provides
- register access only.
+ help
+ The RN5T567 is a PMIC with 4 step-down DC/DC converters, 5 LDO
+ regulators Real-Time Clock and 4 GPIOs. This driver provides
+ register access only.
config PMIC_TPS65090
bool "Enable driver for Texas Instruments TPS65090 PMIC"
- ---help---
- The TPS65090 is a PMIC containing several LDOs, DC to DC convertors,
- FETs and a battery charger. This driver provides register access
- only, and you can enable the regulator/charger drivers separately if
- required.
+ help
+ The TPS65090 is a PMIC containing several LDOs, DC to DC convertors,
+ FETs and a battery charger. This driver provides register access
+ only, and you can enable the regulator/charger drivers separately if
+ required.
config PMIC_PALMAS
bool "Enable driver for Texas Instruments PALMAS PMIC"
- ---help---
- The PALMAS is a PMIC containing several LDOs, SMPS.
- This driver binds the pmic children.
+ help
+ The PALMAS is a PMIC containing several LDOs, SMPS.
+ This driver binds the pmic children.
config PMIC_LP873X
bool "Enable driver for Texas Instruments LP873X PMIC"
- ---help---
- The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
- This driver binds the pmic children.
+ help
+ The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
+ This driver binds the pmic children.
config PMIC_LP87565
bool "Enable driver for Texas Instruments LP87565 PMIC"
- ---help---
- The LP87565 is a PMIC containing a bunch of SMPS.
- This driver binds the pmic children.
+ help
+ The LP87565 is a PMIC containing a bunch of SMPS.
+ This driver binds the pmic children.
config DM_PMIC_TPS65910
bool "Enable driver for Texas Instruments TPS65910 PMIC"
- ---help---
- The TPS65910 is a PMIC containing 3 buck DC-DC converters, one boost
- DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO
- pmic children.
+ help
+ The TPS65910 is a PMIC containing 3 buck DC-DC converters, one boost
+ DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO
+ pmic children.
config DM_PMIC_TPS80031
bool "Enable driver for Texas Instruments TPS80031/TPS80032 PMIC"
- ---help---
- This config enables implementation of driver-model pmic uclass features
- for TPS80031/TPS80032 PMICs. The driver implements read/write operations.
- This is a Power Management IC with a decent set of peripherals from which
- 5 Buck Converters refered as Switched-mode power supply (SMPS), 11 General-
- Purpose Low-Dropout Voltage Regulators (LDO), USB OTG Module, Real-Time
- Clock (RTC) with Timer and Alarm Wake-Up, Two Digital PWM Outputs and more
- with I2C Compatible Interface. PMIC occupies 4 I2C addresses.
+ help
+ This config enables implementation of driver-model pmic uclass features
+ for TPS80031/TPS80032 PMICs. The driver implements read/write operations.
+ This is a Power Management IC with a decent set of peripherals from which
+ 5 Buck Converters referred as Switched-mode power supply (SMPS), 11 General-
+ Purpose Low-Dropout Voltage Regulators (LDO), USB OTG Module, Real-Time
+ Clock (RTC) with Timer and Alarm Wake-Up, Two Digital PWM Outputs and more
+ with I2C Compatible Interface. PMIC occupies 4 I2C addresses.
config PMIC_STPMIC1
bool "Enable support for STMicroelectronics STPMIC1 PMIC"
depends on DM_I2C
select SYSRESET_CMD_POWEROFF if SYSRESET && CMD_POWEROFF && !ARM_PSCI_FW
- ---help---
- 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.
+ help
+ 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.
config SPL_PMIC_PALMAS
bool "Enable driver for Texas Instruments PALMAS PMIC"
depends on SPL_DM_PMIC
help
- The PALMAS is a PMIC containing several LDOs, SMPS.
- This driver binds the pmic children in SPL.
+ The PALMAS is a PMIC containing several LDOs, SMPS.
+ This driver binds the pmic children in SPL.
config SPL_PMIC_LP873X
bool "Enable driver for Texas Instruments LP873X PMIC"
depends on SPL_DM_PMIC
help
- The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
- This driver binds the pmic children in SPL.
+ The LP873X is a PMIC containing couple of LDOs and couple of SMPS.
+ This driver binds the pmic children in SPL.
config SPL_PMIC_LP87565
bool "Enable driver for Texas Instruments LP87565 PMIC"
depends on SPL_DM_PMIC
help
- The LP87565 is a PMIC containing a bunch of SMPS.
- This driver binds the pmic children in SPL.
+ The LP87565 is a PMIC containing a bunch of SMPS.
+ This driver binds the pmic children in SPL.
config PMIC_TPS65941
bool "Enable driver for Texas Instruments TPS65941 PMIC"
depends on DM_PMIC
help
- The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
- This driver binds the pmic children.
+ The TPS65941 is a PMIC containing a bunch of SMPS & LDOs.
+ This driver binds the pmic children.
config PMIC_TPS65219
bool "Enable driver for Texas Instruments TPS65219 PMIC"
depends on DM_PMIC
help
- The TPS65219 is a PMIC containing a bunch of SMPS & LDOs.
- This driver binds the pmic children.
+ The TPS65219 is a PMIC containing a bunch of SMPS & LDOs.
+ This driver binds the pmic children.
config PMIC_RAA215300
bool "Renesas RAA215300 PMIC driver"
@@ -434,6 +434,14 @@ config PMIC_RAA215300
allows register access and will bind the sysreset driver
(CONFIG_SYSRESET_RAA215300) if it is enabled.
+config PMIC_SPACEMIT_P1
+ bool "Enable driver for Spacemit P1 power management chip"
+ depends on DM_PMIC
+ help
+ The P1 PMIC integrates multiple functions including
+ voltage regulators, a watchdog timer, GPIO interfaces, and a
+ real-time clock.
+
config DM_PMIC_MTK_PWRAP
bool "Enable driver for MediaTek PMIC Wrapper Support"
help
@@ -445,11 +453,11 @@ endif
config PMIC_TPS65217
bool "Enable driver for Texas Instruments TPS65217 PMIC"
- ---help---
- The TPS65217 is a PMIC containing several LDOs, DC to DC convertors,
- FETs and a battery charger. This driver provides register access
- only, and you can enable the regulator/charger drivers separately if
- required.
+ help
+ The TPS65217 is a PMIC containing several LDOs, DC to DC convertors,
+ FETs and a battery charger. This driver provides register access
+ only, and you can enable the regulator/charger drivers separately if
+ required.
config POWER_TPS65218
bool "Enable legacy driver for TPS65218 PMIC"
@@ -485,9 +493,9 @@ config POWER_PFUZE3000
config POWER_MC34VR500
bool "Enable driver for Freescale MC34VR500 PMIC"
- ---help---
- The MC34VR500 is used in conjunction with the FSL T1 and LS1 series
- SoC. It provides 4 buck DC-DC convertors and 5 LDOs, and it is accessed
- via an I2C interface.
+ help
+ The MC34VR500 is used in conjunction with the FSL T1 and LS1 series
+ SoC. It provides 4 buck DC-DC convertors and 5 LDOs, and it is accessed
+ via an I2C interface.
endif
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index 2cda5a892fd..0ac92084221 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_$(PHASE_)DM_PMIC_TPS80031) += tps80031.o
obj-$(CONFIG_$(PHASE_)PMIC_PALMAS) += palmas.o
obj-$(CONFIG_$(PHASE_)PMIC_LP873X) += lp873x.o
obj-$(CONFIG_$(PHASE_)PMIC_LP87565) += lp87565.o
+obj-$(CONFIG_PMIC_SPACEMIT_P1) += pmic_spacemit_p1.o
obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o
obj-$(CONFIG_PMIC_TPS65217) += pmic_tps65217.o
obj-$(CONFIG_PMIC_TPS65219) += tps65219.o
diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c
index 6e81b9c3427..b5c8efd427a 100644
--- a/drivers/power/pmic/i2c_pmic_emul.c
+++ b/drivers/power/pmic/i2c_pmic_emul.c
@@ -146,7 +146,7 @@ static int sandbox_i2c_pmic_probe(struct udevice *emul)
return 0;
}
-struct dm_i2c_ops sandbox_i2c_pmic_emul_ops = {
+static const struct dm_i2c_ops sandbox_i2c_pmic_emul_ops = {
.xfer = sandbox_i2c_pmic_xfer,
};
diff --git a/drivers/power/pmic/pca9450.c b/drivers/power/pmic/pca9450.c
index c95e6357ee8..cbe8cd05be7 100644
--- a/drivers/power/pmic/pca9450.c
+++ b/drivers/power/pmic/pca9450.c
@@ -90,7 +90,7 @@ static int pca9450_probe(struct udevice *dev)
return ret;
}
- if (ofnode_read_bool(dev_ofnode(dev), "nxp,wdog_b-warm-reset"))
+ if (dev_read_bool(dev, "nxp,wdog_b-warm-reset"))
reset_ctrl = PCA9450_PMIC_RESET_WDOG_B_CFG_WARM;
else
reset_ctrl = PCA9450_PMIC_RESET_WDOG_B_CFG_COLD_LDO12;
diff --git a/drivers/power/pmic/pmic_qcom.c b/drivers/power/pmic/pmic_qcom.c
index 92d0a95859b..4b8dcc6104c 100644
--- a/drivers/power/pmic/pmic_qcom.c
+++ b/drivers/power/pmic/pmic_qcom.c
@@ -72,7 +72,7 @@ static int pmic_qcom_probe(struct udevice *dev)
* contains two discrete values, not a single 64-bit address.
* The address is the first value.
*/
- ret = ofnode_read_u32_index(dev_ofnode(dev), "reg", 0, &priv->usid);
+ ret = dev_read_u32_index(dev, "reg", 0, &priv->usid);
if (ret < 0)
return -EINVAL;
diff --git a/drivers/power/pmic/pmic_spacemit_p1.c b/drivers/power/pmic/pmic_spacemit_p1.c
new file mode 100644
index 00000000000..46c5926874c
--- /dev/null
+++ b/drivers/power/pmic/pmic_spacemit_p1.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025-2026 RISCstar Ltd.
+ */
+
+#include <dm.h>
+#include <power/pmic.h>
+#include <power/spacemit_p1.h>
+
+static int pmic_p1_reg_count(struct udevice *dev)
+{
+ return P1_MAX_REGS;
+}
+
+static int pmic_p1_write(struct udevice *dev, uint reg, const u8 *buffer,
+ int len)
+{
+ int ret;
+
+ ret = dm_i2c_write(dev, reg, buffer, len);
+ if (ret)
+ pr_err("%s write error on register %02x\n", dev->name, reg);
+
+ return ret;
+}
+
+static int pmic_p1_read(struct udevice *dev, uint reg, u8 *buffer,
+ int len)
+{
+ int ret;
+
+ ret = dm_i2c_read(dev, reg, buffer, len);
+ if (ret)
+ pr_err("%s read error on register %02x\n", dev->name, reg);
+
+ return ret;
+}
+
+static const struct pmic_child_info p1_children_info[] = {
+ { .prefix = "buck", .driver = P1_BUCK_DRIVER },
+ { .prefix = "aldo", .driver = P1_ALDO_DRIVER },
+ { .prefix = "dldo", .driver = P1_DLDO_DRIVER },
+ { },
+};
+
+static int pmic_p1_bind(struct udevice *dev)
+{
+ const struct pmic_child_info *p1_children_info =
+ (struct pmic_child_info *)dev_get_driver_data(dev);
+ ofnode regulators_node;
+ int children;
+
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
+ debug("%s regulators subnode not found\n", dev->name);
+ return -EINVAL;
+ }
+
+ children = pmic_bind_children(dev, regulators_node,
+ p1_children_info);
+ if (!children)
+ debug("%s has no children (regulators)\n", dev->name);
+
+ return 0;
+}
+
+static int pmic_p1_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+static struct dm_pmic_ops pmic_p1_ops = {
+ .reg_count = pmic_p1_reg_count,
+ .read = pmic_p1_read,
+ .write = pmic_p1_write,
+};
+
+static const struct udevice_id pmic_p1_match[] = {
+ {
+ .compatible = "spacemit,p1",
+ .data = (ulong)&p1_children_info,
+ }, {
+ /* sentinel */
+ }
+};
+
+U_BOOT_DRIVER(pmic_p1) = {
+ .name = "pmic_p1",
+ .id = UCLASS_PMIC,
+ .of_match = pmic_p1_match,
+ .bind = pmic_p1_bind,
+ .probe = pmic_p1_probe,
+ .ops = &pmic_p1_ops,
+};
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index ca5de5b8726..c3dc5d6f97b 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -1,38 +1,38 @@
config DM_REGULATOR
bool "Enable Driver Model for REGULATOR drivers (UCLASS_REGULATOR)"
depends on DM
- ---help---
- This config enables the driver model regulator support.
- UCLASS_REGULATOR - designed to provide a common API for basic regulator's
- functions, like get/set Voltage or Current value, enable state, etc...
- Note:
- When enabling this, please read the description, found in the files:
- - 'include/power/pmic.h'
- - 'include/power/regulator.h'
- - 'drivers/power/pmic/pmic-uclass.c'
- - 'drivers/power/pmic/regulator-uclass.c'
- It's important to call the device_bind() with the proper node offset,
- when binding the regulator devices. The pmic_bind_childs() can be used
- for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_dev()
- otherwise. Detailed information can be found in the header file.
+ help
+ This config enables the driver model regulator support.
+ UCLASS_REGULATOR - designed to provide a common API for basic regulator's
+ functions, like get/set Voltage or Current value, enable state, etc...
+ Note:
+ When enabling this, please read the description, found in the files:
+ - 'include/power/pmic.h'
+ - 'include/power/regulator.h'
+ - 'drivers/power/pmic/pmic-uclass.c'
+ - 'drivers/power/pmic/regulator-uclass.c'
+ It's important to call the device_bind() with the proper node offset,
+ when binding the regulator devices. The pmic_bind_childs() can be used
+ for this purpose if PMIC I/O driver is implemented or dm_scan_fdt_dev()
+ otherwise. Detailed information can be found in the header file.
config SPL_DM_REGULATOR
bool "Enable regulators for SPL"
depends on DM_REGULATOR && SPL_POWER
- ---help---
- Regulators are seldom needed in SPL. Even if they are accessed, some
- code space can be saved by accessing the PMIC registers directly.
- Enable this option if you need regulators in SPL and can cope with
- the extra code size.
+ help
+ Regulators are seldom needed in SPL. Even if they are accessed, some
+ code space can be saved by accessing the PMIC registers directly.
+ Enable this option if you need regulators in SPL and can cope with
+ the extra code size.
config REGULATOR_ACT8846
bool "Enable driver for ACT8846 regulator"
depends on DM_REGULATOR && PMIC_ACT8846
- ---help---
- Enable support for the regulator functions of the ACT8846 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.
+ help
+ Enable support for the regulator functions of the ACT8846 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 REGULATOR_AS3722
bool "Enable driver for AS7322 regulator"
@@ -75,33 +75,33 @@ config DM_REGULATOR_BD71837
bool "Enable Driver Model for ROHM BD71837/BD71847 regulators"
depends on DM_REGULATOR && DM_PMIC_BD71837
help
- This config enables implementation of driver-model regulator uclass
- features for regulators on ROHM BD71837 and BD71847 PMICs.
- BD71837 contains 8 bucks and 7 LDOS. BD71847 is reduced version
- containing 6 bucks and 6 LDOs. The driver implements get/set api for
- value and enable.
+ This config enables implementation of driver-model regulator uclass
+ features for regulators on ROHM BD71837 and BD71847 PMICs.
+ BD71837 contains 8 bucks and 7 LDOS. BD71847 is reduced version
+ containing 6 bucks and 6 LDOs. The driver implements get/set api for
+ value and enable.
config SPL_DM_REGULATOR_BD71837
bool "Enable Driver Model for ROHM BD71837/BD71847 regulators in SPL"
depends on DM_REGULATOR_BD71837 && SPL
help
- This config enables implementation of driver-model regulator uclass
- features for regulators on ROHM BD71837 and BD71847 in SPL.
+ This config enables implementation of driver-model regulator uclass
+ features for regulators on ROHM BD71837 and BD71847 in SPL.
config DM_REGULATOR_PCA9450
bool "Enable Driver Model for NXP PCA9450 regulators"
depends on DM_REGULATOR && DM_PMIC_PCA9450
help
- This config enables implementation of driver-model regulator uclass
- features for regulators on NXP PCA9450 PMICs. PCA9450 contains 6 bucks
- and 5 LDOS. The driver implements get/set api for value and enable.
+ This config enables implementation of driver-model regulator uclass
+ features for regulators on NXP PCA9450 PMICs. PCA9450 contains 6 bucks
+ and 5 LDOS. The driver implements get/set api for value and enable.
config SPL_DM_REGULATOR_PCA9450
bool "Enable Driver Model for NXP PCA9450 regulators in SPL"
depends on DM_REGULATOR_PCA9450 && SPL
help
- This config enables implementation of driver-model regulator uclass
- features for regulators on ROHM PCA9450 in SPL.
+ This config enables implementation of driver-model regulator uclass
+ features for regulators on ROHM PCA9450 in SPL.
config DM_REGULATOR_DA9063
bool "Enable Driver Model for REGULATOR DA9063"
@@ -127,55 +127,55 @@ config DM_REGULATOR_PFUZE100
bool "Enable Driver Model for REGULATOR PFUZE100"
depends on DM_REGULATOR && DM_PMIC_PFUZE100
default DM_PMIC_PFUZE100
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for REGULATOR PFUZE100. The driver implements get/set api for:
- value, enable and mode.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for REGULATOR PFUZE100. The driver implements get/set api for:
+ value, enable and mode.
config SPL_DM_REGULATOR_PFUZE100
bool "Enable Driver Model for REGULATOR PFUZE100 in SPL"
depends on SPL_DM_REGULATOR && SPL_DM_PMIC_PFUZE100
default SPL_DM_PMIC_PFUZE100
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for REGULATOR PFUZE100. The driver implements get/set api for:
- value, enable and mode.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for REGULATOR PFUZE100. The driver implements get/set api for:
+ value, enable and mode.
config REGULATOR_PWM
bool "Enable driver for PWM regulators"
depends on DM_REGULATOR && DM_PWM
- ---help---
- Enable support for the PWM regulator functions which voltage are
- controlled by PWM duty ratio. Some of Rockchip board using this kind
- of regulator. The driver implements get/set api for the various BUCKS.
- This driver is controlled by a device tree node
- which includes voltage limits.
+ help
+ Enable support for the PWM regulator functions which voltage are
+ controlled by PWM duty ratio. Some of Rockchip board using this kind
+ of regulator. The driver implements get/set api for the various BUCKS.
+ This driver is controlled by a device tree node
+ which includes voltage limits.
config DM_REGULATOR_MAX8907
bool "Enable Driver Model for REGULATOR MAX8907"
depends on DM_REGULATOR && DM_PMIC_MAX8907
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for REGULATOR MAX8907. The driver supports both DC-to-DC
- Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators
- found in MAX8907 PMIC and implements get/set api for value and enable.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for REGULATOR MAX8907. The driver supports both DC-to-DC
+ Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators
+ found in MAX8907 PMIC and implements get/set api for value and enable.
config DM_REGULATOR_MAX77663
bool "Enable Driver Model for REGULATOR MAX77663"
depends on DM_REGULATOR && DM_PMIC_MAX77663
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for REGULATOR MAX77663. The driver supports both DC-to-DC
- Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators
- found in MAX77663 PMIC and implements get/set api for value and enable.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for REGULATOR MAX77663. The driver supports both DC-to-DC
+ Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators
+ found in MAX77663 PMIC and implements get/set api for value and enable.
config DM_REGULATOR_MAX77686
bool "Enable Driver Model for REGULATOR MAX77686"
depends on DM_REGULATOR && DM_PMIC_MAX77686
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for REGULATOR MAX77686. The driver implements get/set api for:
- value, enable and mode.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for REGULATOR MAX77686. The driver implements get/set api for:
+ value, enable and mode.
config DM_REGULATOR_NPCM8XX
bool "Enable Driver Model for NPCM8xx voltage supply"
@@ -221,33 +221,33 @@ config DM_REGULATOR_FIXED
bool "Enable Driver Model for REGULATOR Fixed value"
depends on DM_REGULATOR
select DM_REGULATOR_COMMON
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for fixed value regulators. The driver implements get/set api
- for enable and get only for voltage value.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for fixed value regulators. The driver implements get/set api
+ for enable and get only for voltage value.
config SPL_DM_REGULATOR_FIXED
bool "Enable Driver Model for REGULATOR Fixed value in SPL"
depends on DM_REGULATOR_FIXED && SPL
select SPL_DM_REGULATOR_COMMON
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for fixed value regulators in SPL.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for fixed value regulators in SPL.
config DM_REGULATOR_GPIO
bool "Enable Driver Model for GPIO REGULATOR"
depends on DM_REGULATOR && DM_GPIO
select DM_REGULATOR_COMMON
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for gpio regulators. The driver implements get/set for
- voltage value.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for gpio regulators. The driver implements get/set for
+ voltage value.
config DM_REGULATOR_QCOM_RPMH
bool "Enable driver model for Qualcomm RPMh regulator"
depends on DM_REGULATOR && QCOM_RPMH
select DEVRES
- ---help---
+ help
Enable support for the Qualcomm RPMh regulator. The driver
implements get/set api for a limited set of regulators used
by u-boot.
@@ -255,7 +255,7 @@ config DM_REGULATOR_QCOM_RPMH
config DM_REGULATOR_QCOM_USB_VBUS
bool "Enable driver model for Qualcomm USB vbus regulator"
depends on DM_REGULATOR && DM_PMIC
- ---help---
+ help
Enable support for the Qualcomm USB Vbus regulator. The driver
implements get/set api for the regulator to be used by u-boot.
@@ -263,18 +263,18 @@ config SPL_DM_REGULATOR_GPIO
bool "Enable Driver Model for GPIO REGULATOR in SPL"
depends on DM_REGULATOR_GPIO && SPL_DM_GPIO
select SPL_DM_REGULATOR_COMMON
- ---help---
- This config enables implementation of driver-model regulator uclass
- features for gpio regulators in SPL.
+ help
+ This config enables implementation of driver-model regulator uclass
+ features for gpio regulators in SPL.
config REGULATOR_RK8XX
bool "Enable driver for RK8XX regulators"
depends on DM_REGULATOR && PMIC_RK8XX
- ---help---
- Enable support for the regulator functions of the RK8XX 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.
+ help
+ Enable support for the regulator functions of the RK8XX 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_REGULATOR_RK8XX
bool "Enable driver for RK8XX regulators in SPL"
@@ -288,162 +288,162 @@ config SPL_REGULATOR_RK8XX
config DM_REGULATOR_S2MPS11
bool "Enable driver for S2MPS11 regulator"
depends on DM_REGULATOR && PMIC_S2MPS11
- ---help---
- This enables implementation of driver-model regulator uclass
- features for REGULATOR S2MPS11.
- The driver implements get/set api for: value and enable.
+ help
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR S2MPS11.
+ The driver implements get/set api for: value and enable.
config REGULATOR_S5M8767
bool "Enable support for S5M8767 regulator"
depends on DM_REGULATOR && PMIC_S5M8767
- ---help---
- This enables the regulator features of the S5M8767, allowing voltages
- to be set, etc. The driver is not fully complete but supports most
- common requirements, including all LDOs and BUCKs. This allows many
- supplies to be set automatically using the device tree values.
+ help
+ This enables the regulator features of the S5M8767, allowing voltages
+ to be set, etc. The driver is not fully complete but supports most
+ common requirements, including all LDOs and BUCKs. This allows many
+ supplies to be set automatically using the device tree values.
config DM_REGULATOR_SANDBOX
bool "Enable Driver Model for Sandbox PMIC regulator"
depends on DM_REGULATOR && DM_PMIC_SANDBOX
- ---help---
- Enable the regulator driver for emulated Sandbox PMIC.
- The emulated PMIC device depends on two drivers:
- - sandbox PMIC I/O driver - implements dm pmic operations
- - sandbox PMIC regulator driver - implements dm regulator operations
- - sandbox PMIC i2c emul driver - emulates the PMIC's I2C transmission
+ help
+ Enable the regulator driver for emulated Sandbox PMIC.
+ The emulated PMIC device depends on two drivers:
+ - sandbox PMIC I/O driver - implements dm pmic operations
+ - sandbox PMIC regulator driver - implements dm regulator operations
+ - sandbox PMIC i2c emul driver - emulates the PMIC's I2C transmission
- The regulator driver provides uclass operations for sandbox PMIC's
- regulators. The driver implements get/set api for: voltage, current,
- operation mode and enable state.
- The driver supports LDO and BUCK regulators.
+ The regulator driver provides uclass operations for sandbox PMIC's
+ regulators. The driver implements get/set api for: voltage, current,
+ operation mode and enable state.
+ The driver supports LDO and BUCK regulators.
- The Sandbox PMIC info:
- * I/O interface:
- - I2C chip address: 0x40
- - first register address: 0x0
- - register count: 0x10
- * Adjustable outputs:
- - 2x LDO
- - 2x BUCK
- - Each, with a different operating conditions (header).
- * Reset values:
- - set by i2c emul driver's probe() (defaults in header)
+ The Sandbox PMIC info:
+ * I/O interface:
+ - I2C chip address: 0x40
+ - first register address: 0x0
+ - register count: 0x10
+ * Adjustable outputs:
+ - 2x LDO
+ - 2x BUCK
+ - Each, with a different operating conditions (header).
+ * Reset values:
+ - set by i2c emul driver's probe() (defaults in header)
- A detailed information can be found in header: '<power/sandbox_pmic.h>'
- Binding info: 'doc/device-tree-bindings/pmic/max77686.txt'
+ A detailed information can be found in header: '<power/sandbox_pmic.h>'
+ Binding info: 'doc/device-tree-bindings/pmic/max77686.txt'
config REGULATOR_TPS65090
bool "Enable driver for TPS65090 PMIC regulators"
depends on PMIC_TPS65090
- ---help---
- The TPS65090 provides several FETs (Field-effect Transistors,
- effectively switches) which are supported by this driver as
- regulators, one for each FET. The standard regulator interface is
- supported, but it is only possible to turn the regulators on or off.
- There is no voltage/current control.
+ help
+ The TPS65090 provides several FETs (Field-effect Transistors,
+ effectively switches) which are supported by this driver as
+ regulators, one for each FET. The standard regulator interface is
+ supported, but it is only possible to turn the regulators on or off.
+ There is no voltage/current control.
config DM_REGULATOR_PALMAS
bool "Enable driver for PALMAS PMIC regulators"
- depends on PMIC_PALMAS
- ---help---
- This enables implementation of driver-model regulator uclass
- features for REGULATOR PALMAS and the family of PALMAS PMICs.
- The driver implements get/set api for: value and enable.
+ depends on PMIC_PALMAS
+ help
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR PALMAS and the family of PALMAS PMICs.
+ The driver implements get/set api for: value and enable.
config DM_REGULATOR_PBIAS
bool "Enable driver for PBIAS regulator"
depends on DM_REGULATOR
select REGMAP
select SYSCON
- ---help---
- This enables implementation of driver-model regulator uclass
- features for pseudo-regulator PBIAS found in the OMAP SOCs.
- This pseudo-regulator is used to provide a BIAS voltage to MMC1
- signal pads and must be configured properly during a voltage switch.
- Voltage switching is required by some operating modes of SDcards and
- eMMC.
+ help
+ This enables implementation of driver-model regulator uclass
+ features for pseudo-regulator PBIAS found in the OMAP SOCs.
+ This pseudo-regulator is used to provide a BIAS voltage to MMC1
+ signal pads and must be configured properly during a voltage switch.
+ Voltage switching is required by some operating modes of SDcards and
+ eMMC.
config DM_REGULATOR_LP873X
bool "Enable driver for LP873X PMIC regulators"
- depends on PMIC_LP873X
- ---help---
- This enables implementation of driver-model regulator uclass
- features for REGULATOR LP873X and the family of LP873X PMICs.
- The driver implements get/set api for: value and enable.
+ depends on PMIC_LP873X
+ help
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR LP873X and the family of LP873X PMICs.
+ The driver implements get/set api for: value and enable.
config DM_REGULATOR_LP87565
bool "Enable driver for LP87565 PMIC regulators"
- depends on PMIC_LP87565
- ---help---
- This enables implementation of driver-model regulator uclass
- features for REGULATOR LP87565 and the family of LP87565 PMICs.
- LP87565 series of PMICs have 4 single phase BUCKs that can also
- be configured in multi phase modes. The driver implements
- get/set api for value and enable.
+ depends on PMIC_LP87565
+ help
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR LP87565 and the family of LP87565 PMICs.
+ LP87565 series of PMICs have 4 single phase BUCKs that can also
+ be configured in multi phase modes. The driver implements
+ get/set api for value and enable.
config DM_REGULATOR_STM32_VREFBUF
bool "Enable driver for STMicroelectronics STM32 VREFBUF"
depends on DM_REGULATOR && (STM32H7 || ARCH_STM32MP)
help
- This driver supports STMicroelectronics STM32 VREFBUF (voltage
- reference buffer) which can be used as voltage reference for
- internal ADCs, DACs and also for external components through
- dedicated Vref+ pin.
+ This driver supports STMicroelectronics STM32 VREFBUF (voltage
+ reference buffer) which can be used as voltage reference for
+ internal ADCs, DACs and also for external components through
+ dedicated Vref+ pin.
config DM_REGULATOR_TPS65910
bool "Enable driver for TPS65910 PMIC regulators"
depends on DM_PMIC_TPS65910
- ---help---
- The TPS65910 PMIC provides 4 SMPSs and 8 LDOs. This driver supports all
- regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements
- the get/set api for value and enable.
+ help
+ The TPS65910 PMIC provides 4 SMPSs and 8 LDOs. This driver supports all
+ regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements
+ the get/set api for value and enable.
config DM_REGULATOR_TPS65911
bool "Enable driver for TPS65911 PMIC regulators"
depends on DM_PMIC_TPS65910
- ---help---
- This config enables implementation of driver-model regulator
- uclass features for the TPS65911 PMIC. The driver supports Step-Down
- DC-DC Converters for Processor Cores (VDD1 and VDD2), Step-Down DC-DC
- Converter for I/O Power (VIO), Controller for External FETs (VDDCtrl)
- and LDO Voltage Regulators found in TPS65911 PMIC and implements
- get/set api for value and enable.
+ help
+ This config enables implementation of driver-model regulator
+ uclass features for the TPS65911 PMIC. The driver supports Step-Down
+ DC-DC Converters for Processor Cores (VDD1 and VDD2), Step-Down DC-DC
+ Converter for I/O Power (VIO), Controller for External FETs (VDDCtrl)
+ and LDO Voltage Regulators found in TPS65911 PMIC and implements
+ get/set api for value and enable.
config DM_REGULATOR_TPS62360
bool "Enable driver for TPS6236x Power Regulator"
depends on DM_REGULATOR
help
- The TPS6236X DC/DC step down converter provides a single output
- power line peaking at 3A current. This driver supports all four
- variants of the chip (TPS62360, TPS62361, TPS62362, TPS62363). It
- implements the get/set api for value only, as the power line is
- always on.
+ The TPS6236X DC/DC step down converter provides a single output
+ power line peaking at 3A current. This driver supports all four
+ variants of the chip (TPS62360, TPS62361, TPS62362, TPS62363). It
+ implements the get/set api for value only, as the power line is
+ always on.
config DM_REGULATOR_TPS80031
bool "Enable driver for TPS80031/TPS80032 PMIC regulators"
depends on DM_PMIC_TPS80031
- ---help---
- This enables implementation of driver-model regulator uclass
- features for TPS80031/TPS80032 PMICs. The driver implements
- get/set api for: value and enable.
+ help
+ This enables implementation of driver-model regulator uclass
+ features for TPS80031/TPS80032 PMICs. The driver implements
+ get/set api for: value and enable.
config DM_REGULATOR_TPS6287X
bool "Enable driver for TPS6287x Power Regulator"
depends on DM_REGULATOR
help
- The TPS6287X is a step down converter with a fast transient
- response. This driver supports all four variants of the chip
- (TPS62870, TPS62871, TPS62872, TPS62873). It implements the
- get/set api for value only, as the power line is always on.
+ The TPS6287X is a step down converter with a fast transient
+ response. This driver supports all four variants of the chip
+ (TPS62870, TPS62871, TPS62872, TPS62873). It implements the
+ get/set api for value only, as the power line is always on.
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 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.
+ help
+ 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 DM_REGULATOR_ANATOP
bool "Enable driver for ANATOP regulators"
@@ -451,18 +451,18 @@ config DM_REGULATOR_ANATOP
select REGMAP
select SYSCON
help
- Enable support for the Freescale i.MX on-chip ANATOP LDO
- regulators. It is recommended that this option be enabled on
- i.MX6 platform.
+ Enable support for the Freescale i.MX on-chip ANATOP LDO
+ regulators. It is recommended that this option be enabled on
+ i.MX6 platform.
config SPL_DM_REGULATOR_TPS6287X
bool "Enable driver for TPS6287x Power Regulator"
depends on SPL_DM_REGULATOR
help
- The TPS6287X is a step down converter with a fast transient
- response. This driver supports all four variants of the chip
- (TPS62870, TPS62871, TPS62872, TPS62873). It implements the
- get/set api for value only, as the power line is always on.
+ The TPS6287X is a step down converter with a fast transient
+ response. This driver supports all four variants of the chip
+ (TPS62870, TPS62871, TPS62872, TPS62873). It implements the
+ get/set api for value only, as the power line is always on.
config SPL_DM_REGULATOR_STPMIC1
bool "Enable driver for STPMIC1 regulators in SPL"
@@ -474,54 +474,54 @@ config SPL_DM_REGULATOR_PALMAS
bool "Enable driver for PALMAS PMIC regulators"
depends on SPL_PMIC_PALMAS
help
- This enables implementation of driver-model regulator uclass
- features for REGULATOR PALMAS and the family of PALMAS PMICs.
- The driver implements get/set api for: value and enable in SPL.
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR PALMAS and the family of PALMAS PMICs.
+ The driver implements get/set api for: value and enable in SPL.
config SPL_DM_REGULATOR_LP87565
bool "Enable driver for LP87565 PMIC regulators"
depends on SPL_PMIC_LP87565
help
- This enables implementation of driver-model regulator uclass
- features for REGULATOR LP87565 and the family of LP87565 PMICs.
- LP87565 series of PMICs have 4 single phase BUCKs that can also
- be configured in multi phase modes. The driver implements
- get/set api for value and enable in SPL.
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR LP87565 and the family of LP87565 PMICs.
+ LP87565 series of PMICs have 4 single phase BUCKs that can also
+ be configured in multi phase modes. The driver implements
+ get/set api for value and enable in SPL.
config SPL_DM_REGULATOR_LP873X
bool "Enable driver for LP873X PMIC regulators"
depends on SPL_PMIC_LP873X
help
- This enables implementation of driver-model regulator uclass
- features for REGULATOR LP873X and the family of LP873X PMICs.
- The driver implements get/set api for: value and enable in SPL.
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR LP873X and the family of LP873X PMICs.
+ The driver implements get/set api for: value and enable in SPL.
config DM_REGULATOR_TPS65941
bool "Enable driver for TPS65941 PMIC regulators"
- depends on PMIC_TPS65941
+ depends on PMIC_TPS65941
help
- This enables implementation of driver-model regulator uclass
- features for REGULATOR TPS65941 and the family of TPS65941 PMICs.
- TPS65941 series of PMICs have 5 single phase BUCKs that can also
- be configured in multi phase modes & 4 LDOs. The driver implements
- get/set api for value and enable.
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR TPS65941 and the family of TPS65941 PMICs.
+ TPS65941 series of PMICs have 5 single phase BUCKs that can also
+ be configured in multi phase modes & 4 LDOs. The driver implements
+ get/set api for value and enable.
config DM_REGULATOR_SCMI
bool "Enable driver for SCMI voltage domain regulators"
depends on DM_REGULATOR
select SCMI_AGENT
- help
- Enable this option if you want to support regulators exposed through
+ help
+ Enable this option if you want to support regulators exposed through
the SCMI voltage domain protocol by a SCMI server.
config DM_REGULATOR_TPS65219
bool "Enable driver for TPS65219 PMIC regulators"
- depends on PMIC_TPS65219
+ depends on PMIC_TPS65219
help
- This enables implementation of driver-model regulator uclass
- features for REGULATOR TPS65219 and the family of TPS65219 PMICs.
- TPS65219 series of PMICs have 3 single phase BUCKs & 4 LDOs.
- The driver implements get/set api for value and enable.
+ This enables implementation of driver-model regulator uclass
+ features for REGULATOR TPS65219 and the family of TPS65219 PMICs.
+ TPS65219 series of PMICs have 3 single phase BUCKs & 4 LDOs.
+ The driver implements get/set api for value and enable.
config REGULATOR_RZG2L_USBPHY
bool "Enable driver for RZ/G2L USB PHY VBUS supply"
@@ -534,11 +534,11 @@ config REGULATOR_RZG2L_USBPHY
config DM_REGULATOR_CPCAP
bool "Enable driver for CPCAP PMIC regulators"
depends on DM_REGULATOR && DM_PMIC_CPCAP
- ---help---
- Enable implementation of driver-model regulator uclass features for
- REGULATOR CPCAP. The driver supports both DC-to-DC Step-Down Switching
- (SW) Regulators and Low-Dropout Linear (LDO) Regulators found in CPCAP
- PMIC and implements get/set api for voltage and state.
+ help
+ Enable implementation of driver-model regulator uclass features for
+ REGULATOR CPCAP. The driver supports both DC-to-DC Step-Down Switching
+ (SW) Regulators and Low-Dropout Linear (LDO) Regulators found in CPCAP
+ PMIC and implements get/set api for voltage and state.
config DM_REGULATOR_MT6357
bool "Enable driver for MediaTek MT6357 PMIC regulators"
@@ -557,3 +557,53 @@ config DM_REGULATOR_MT6359
MediaTek MT6359 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
+
+config DM_REGULATOR_PMBUS_HELPER
+ bool "Shared regulator helpers for PMBus chip drivers"
+ depends on DM_REGULATOR && PMBUS && DM_I2C
+ help
+ Provide shared get_value / set_value / get_enable / set_enable
+ operations for UCLASS_REGULATOR drivers that bind PMBus 1.x
+ compliant voltage regulators. Per chip drivers
+ (mps,mpq8785, lltc,ltc3882, ...) consume this helper to avoid
+ duplicating the LINEAR16 / DIRECT decoder dispatch and the
+ VOUT_MODE / VOUT_COMMAND / OPERATION transport sequences.
+
+config DM_REGULATOR_PMBUS_GENERIC
+ bool "Generic PMBus 1.x regulator driver (compatible=\"pmbus\")"
+ depends on DM_REGULATOR_PMBUS_HELPER
+ help
+ Catch all UCLASS_REGULATOR driver bound to compatible = "pmbus".
+ Auto detects the VOUT numeric format from the chip's VOUT_MODE
+ register and exposes telemetry plus voltage set / get against
+ the standard PMBus 1.x command codes. Use this for PMBus
+ compliant chips that have no per chip driver yet; promote to a
+ per chip driver only when chip specific quirks (vendor
+ registers, VID coercion, ADDR pin auto promotion, non standard
+ m / b / R coefficients) need handling.
+
+config DM_REGULATOR_MPQ8785
+ bool "MPS MPQ8785 / MPM3695 / MPM82504 PMBus voltage regulator"
+ depends on DM_REGULATOR_PMBUS_HELPER
+ help
+ Driver for the Monolithic Power Systems MPQ8785 family of
+ digital multiphase voltage regulators with PMBus. Supports
+ MPM3695, MPM3695-25, MPM82504, and MPQ8785. Adapted from the
+ Linux drivers/hwmon/pmbus/mpq8785.c reference.
+
+config SANDBOX_PMBUS
+ bool "Sandbox PMBus 1.x chip emulator"
+ depends on SANDBOX && PMBUS && DM_I2C
+ help
+ Emulate a PMBus 1.x compliant chip behind a sandbox I2C bus so
+ the PMBus framework (lib/pmbus.c), the generic regulator
+ (DM_REGULATOR_PMBUS_GENERIC) and the pmbus CLI command can be
+ exercised by the dm unit tests with no real hardware. Only
+ useful for testing; say N on real boards.
+
+config DM_REGULATOR_SPACEMIT_P1
+ bool "Enable driver for Spacemit P1 PMIC regulators"
+ depends on DM_REGULATOR && PMIC_SPACEMIT_P1
+ help
+ Enable implementation of driver-model regulator uclass features
+ for regulator P1. The driver supports BUCKs, LDOs and SWITCHes.
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 36a84e7cd71..3a148545387 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_$(PHASE_)REGULATOR_RK8XX) += rk8xx.o
obj-$(CONFIG_DM_REGULATOR_S2MPS11) += s2mps11_regulator.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
+obj-$(CONFIG_DM_REGULATOR_SPACEMIT_P1) += spacemit_p1_regulator.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
obj-$(CONFIG_$(PHASE_)DM_REGULATOR_PALMAS) += palmas_regulator.o
obj-$(CONFIG_$(PHASE_)DM_REGULATOR_PBIAS) += pbias_regulator.o
@@ -49,3 +50,7 @@ obj-$(CONFIG_REGULATOR_RZG2L_USBPHY) += rzg2l-usbphy-regulator.o
obj-$(CONFIG_$(PHASE_)DM_REGULATOR_CPCAP) += cpcap_regulator.o
obj-$(CONFIG_DM_REGULATOR_MT6357) += mt6357_regulator.o
obj-$(CONFIG_DM_REGULATOR_MT6359) += mt6359_regulator.o
+obj-$(CONFIG_DM_REGULATOR_PMBUS_HELPER) += pmbus_helper.o
+obj-$(CONFIG_DM_REGULATOR_PMBUS_GENERIC) += pmbus_generic.o
+obj-$(CONFIG_DM_REGULATOR_MPQ8785) += mpq8785.o
+obj-$(CONFIG_SANDBOX_PMBUS) += sandbox_pmbus.o
diff --git a/drivers/power/regulator/anatop_regulator.c b/drivers/power/regulator/anatop_regulator.c
index 824a753db16..88570a1f624 100644
--- a/drivers/power/regulator/anatop_regulator.c
+++ b/drivers/power/regulator/anatop_regulator.c
@@ -170,8 +170,7 @@ static int anatop_regulator_probe(struct udevice *dev)
anatop_reg = dev_get_plat(dev);
uc_pdata = dev_get_uclass_plat(dev);
- anatop_reg->name = ofnode_read_string(dev_ofnode(dev),
- "regulator-name");
+ anatop_reg->name = dev_read_string(dev, "regulator-name");
if (!anatop_reg->name)
return log_msg_ret("regulator-name", -EINVAL);
diff --git a/drivers/power/regulator/mpq8785.c b/drivers/power/regulator/mpq8785.c
new file mode 100644
index 00000000000..dc321f0e410
--- /dev/null
+++ b/drivers/power/regulator/mpq8785.c
@@ -0,0 +1,494 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Free Mobile, Vincent Jardin
+ *
+ * MPS MPQ8785 / MPM3695 / MPM3695-25 / MPM82504 PMBus voltage
+ * regulator driver. Adapted from
+ * linux/drivers/hwmon/pmbus/mpq8785.c
+ * (Charles Hsu, GPL-2.0-or-later) with the kernel hwmon publication
+ * and caching layers stripped.
+ *
+ * Hooks the shared pmbus_helper UCLASS_REGULATOR ops + adds the MPS
+ * specific identify (VOUT_MODE switch between LINEAR16 and DIRECT
+ * m=64 R=1 for the chip's "VID" mode), the MPS vendor extension
+ * (pmbus mps last|clear last|clear force), and ADDR_VBOOT auto
+ * promotion when the DT declared address fails the MFR_ID probe.
+ */
+
+#include <command.h>
+#include <dm.h>
+#include <i2c.h>
+#include <log.h>
+#include <pmbus.h>
+#include <vsprintf.h>
+#include <linux/bitops.h>
+#include <power/regulator.h>
+
+#include "pmbus_helper.h"
+
+/* Chip family identifiers (driver_data). */
+enum mpq_chip_id {
+ MPQ_MPM3695 = 0,
+ MPQ_MPM3695_25 = 1,
+ MPQ_MPM82504 = 2,
+ MPQ_MPQ8785 = 3,
+};
+
+/*
+ * MPS vendor extended command codes (NOT in PMBus 1.3 Part II).
+ *
+ * CLEAR_LAST_FAULT (08h) clears the NVM backed PROTECTION_LAST
+ * register. Gated by MFR_CFG_EXT (F5h)
+ * bit[6] = 1; chip silently no ops if the
+ * gate is cleared.
+ * PROTECTION_LAST (FBh) single event, NVM backed log of the last
+ * protection event. Survives the chip's own
+ * power cycle. The boot time post mortem the
+ * SoC has no other way to obtain.
+ *
+ * NEVER issue CLEAR_LAST_FAULT (08h) implicitly; it would erase the
+ * post mortem trail. Only the explicit pmbus mps clear last and
+ * pmbus mps clear force subcommands write it.
+ */
+#define PMBUS_CLEAR_LAST_FAULT 0x08
+#define MPS_PROTECTION_LAST 0xfb
+
+/*
+ * MFR_CFG_EXT (F5h) is an MPS extended config WORD (16 bits, not a
+ * byte). Bit[6] (MFR_CLR_FAULT_CFG) gates CLEAR_LAST_FAULT (08h)
+ * clearing PROTECTION_LAST. Several other bits are fixed and MUST be
+ * preserved on writeback; always read modify write the full 16 bits,
+ * only flip bit[6], restore on the way out.
+ */
+#define MPS_MFR_CFG_EXT 0xf5
+#define MPS_MFR_CFG_EXT_CLR_LAST_EN BIT(6)
+
+/*
+ * MPQ8785 driver_info (transcribed from Linux's
+ * drivers/hwmon/pmbus/mpq8785.c::mpq8785_info). DIRECT format with
+ * chip specific m / b / R coefficients on VIN, IOUT, TEMPERATURE.
+ * VOUT format is selected at probe time from VOUT_MODE: bits[7:5] == 0
+ * selects LINEAR16, bits[7:5] == 1 or 2 selects DIRECT m=64 R=1.
+ */
+
+/*
+ * MPS-extended STATUS_* bit names. The MPQ8785 family reuses several
+ * bit positions documented as RESERVED / UNKNOWN / NONE_ABOVE /
+ * MFR_SPECIFIC by PMBus 1.3 for chip specific signals. The override
+ * table below substitutes the chip name for the standard one when
+ * the bit is set, leaving every other PMBus 1.3 standard bit
+ * (VOUT_OV, IOUT_OC, TEMP, CML, ...) unchanged.
+ *
+ * STATUS_WORD bit[12] spec MFR_SPECIFIC chip NVM_SUMMARY (NVM
+ * backed PROTECTION_LAST
+ * register is non zero)
+ * STATUS_WORD bit[8] spec UNKNOWN chip WATCH_DOG (internal
+ * calculation FSM watchdog
+ * overflow)
+ * STATUS_WORD bit[0] spec NONE_ABOVE chip DRMOS_FAULT (DrMOS
+ * stage fault)
+ * STATUS_CML bit[4] spec MEMORY chip MTP_CRC_FAULT (NVM
+ * CRC mismatch on restore)
+ * STATUS_CML bit[0] spec OTHER_MEM_LOGIC chip MTP_FAULT (NVM
+ * signature fault)
+ * STATUS_TEMPERATURE bit[0] (PMBus leaves bits[3:0] reserved on
+ * this register) chip
+ * OT_SELF (controller die
+ * OT condition)
+ */
+static const struct pmbus_status_override mpq8785_status_overrides[] = {
+ { PMBUS_STATUS_WORD, BIT(12), "NVM_SUMMARY" },
+ { PMBUS_STATUS_WORD, BIT(8), "WATCH_DOG" },
+ { PMBUS_STATUS_WORD, BIT(0), "DRMOS_FAULT" },
+ { PMBUS_STATUS_CML, BIT(4), "MTP_CRC_FAULT" },
+ { PMBUS_STATUS_CML, BIT(0), "MTP_FAULT" },
+ { PMBUS_STATUS_TEMPERATURE, BIT(0), "OT_SELF" },
+ { /* sentinel */ }
+};
+
+static struct pmbus_driver_info mpq8785_info = {
+ .pages = 1,
+ .format[PSC_VOLTAGE_IN] = pmbus_fmt_direct,
+ .format[PSC_VOLTAGE_OUT] = pmbus_fmt_linear, /* refined per VOUT_MODE */
+ .format[PSC_CURRENT_OUT] = pmbus_fmt_direct,
+ .format[PSC_TEMPERATURE] = pmbus_fmt_direct,
+ .m[PSC_VOLTAGE_IN] = 4, .b[PSC_VOLTAGE_IN] = 0, .R[PSC_VOLTAGE_IN] = 1,
+ .m[PSC_CURRENT_OUT] = 16, .b[PSC_CURRENT_OUT] = 0, .R[PSC_CURRENT_OUT] = 0,
+ .m[PSC_TEMPERATURE] = 1, .b[PSC_TEMPERATURE] = 0, .R[PSC_TEMPERATURE] = 0,
+ /*
+ * Sensor set this family actually implements with calibrated
+ * coefficients: VIN, VOUT, IOUT, TEMP. READ_IIN / READ_POUT are
+ * ACKed by the silicon but uncalibrated here (the kernel's mpq8646
+ * / mpq8785 drivers expose neither), so declaring the set keeps
+ * pmbus_print_telemetry from printing a bogus POUT / IIN -- matching
+ * the kernel's per-chip sensor list.
+ */
+ .classes_present = BIT(PSC_VOLTAGE_IN) | BIT(PSC_VOLTAGE_OUT) |
+ BIT(PSC_CURRENT_OUT) | BIT(PSC_TEMPERATURE),
+ .status_overrides = mpq8785_status_overrides,
+};
+
+/*
+ * MPM3695 / MPM3695-25 / MPM82504 driver_info: VOUT in DIRECT format
+ * with chip family default m=8 R=2. Other sensor classes default to
+ * LINEAR (the chip family does not document non standard formats for
+ * VIN / IOUT / TEMPERATURE; the helper falls back to LINEAR11 when
+ * the active info is non NULL but format[c] is linear).
+ */
+static struct pmbus_driver_info mpm82504_info = {
+ .pages = 1,
+ .format[PSC_VOLTAGE_OUT] = pmbus_fmt_direct,
+ .m[PSC_VOLTAGE_OUT] = 8, .b[PSC_VOLTAGE_OUT] = 0, .R[PSC_VOLTAGE_OUT] = 2,
+ .format[PSC_VOLTAGE_IN] = pmbus_fmt_linear,
+ .format[PSC_CURRENT_OUT] = pmbus_fmt_linear,
+ .format[PSC_TEMPERATURE] = pmbus_fmt_linear,
+};
+
+/*
+ * Chip match for the framework's pmbus dev <bus>:<addr> raw I2C
+ * path. Used when the operator selects the chip directly by address
+ * instead of by regulator-name; the framework probes MFR_ID, sees
+ * "MPS" (after the byte reverse helper), and caches mpq8785_info.
+ */
+static const struct pmbus_chip_match mpq8785_match = {
+ .mfr_id = "MPS",
+ .mfr_id_reverse = true,
+ .vendor = "mps",
+ .info = &mpq8785_info,
+};
+
+static const struct pmbus_bit mpq_protection_last_bits[] = {
+ { 1u << 15, "INIT_FAULT" },
+ { 1u << 14, "NVM_CRC_ERROR" },
+ { 1u << 13, "NVM_FAULT" },
+ { 1u << 12, "OC_PHASE_FAULT" },
+ { 1u << 11, "OTP_SELF_FAULT" },
+ { 1u << 9, "SWITCH_PRD_FAULT" },
+ { 1u << 8, "VIN_OV_FAULT" },
+ { 1u << 7, "VOUT_OV_FAULT" },
+ { 1u << 6, "VOUT_UV_FAULT" },
+ { 1u << 5, "OC_TOT_FAULT" },
+ { 1u << 4, "VIN_UVLO_FAULT" },
+ { 1u << 3, "DRMOS_OTP" },
+ { /* sentinel */ }
+};
+
+static int mps_require_active(struct udevice **chip)
+{
+ const struct pmbus_active_dev *act = pmbus_active();
+
+ if (!act) {
+ printf("pmbus mps: no active device. Use 'pmbus dev <bus>:<addr>' first.\n");
+ return CMD_RET_FAILURE;
+ }
+ if (strcmp(act->vendor, "mps") != 0) {
+ printf("pmbus mps: active device is not from vendor 'mps' (got '%s')\n",
+ act->vendor[0] ? act->vendor : "(generic)");
+ return CMD_RET_FAILURE;
+ }
+ if (pmbus_active_get_i2c(chip)) {
+ printf("pmbus mps: cannot reach i2c%d:0x%02x\n",
+ act->bus_seq, act->addr);
+ return CMD_RET_FAILURE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int mps_do_last(struct udevice *chip)
+{
+ u16 prot_last = 0;
+
+ if (pmbus_read_word(chip, MPS_PROTECTION_LAST, &prot_last)) {
+ printf("pmbus mps: PROTECTION_LAST (FBh) read failed\n");
+ return CMD_RET_FAILURE;
+ }
+ printf("PROTECTION_LAST (FBh) = 0x%04x [", prot_last);
+ pmbus_print_bits(prot_last, mpq_protection_last_bits);
+ printf("] (NVM, survives MPQ power cycle)\n");
+ return CMD_RET_SUCCESS;
+}
+
+static int mps_do_clear_last(struct udevice *chip)
+{
+ int ret;
+
+ printf("pmbus mps: WARNING, erasing NVM PROTECTION_LAST (FBh) post mortem\n");
+ ret = dm_i2c_write(chip, PMBUS_CLEAR_LAST_FAULT, NULL, 0);
+ if (ret) {
+ printf("pmbus mps: CLEAR_LAST_FAULT (08h) write failed (%d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
+ printf("pmbus mps: CLEAR_LAST_FAULT (08h) issued; gated by MFR_CFG_EXT bit[6]\n");
+ printf(" (chip silently no ops if F5h bit[6] = 0; verify by re reading FBh)\n");
+ return CMD_RET_SUCCESS;
+}
+
+static int mps_do_clear_force(struct udevice *chip)
+{
+ u8 wp_orig = 0;
+ u16 cfg_orig = 0, cfg_unlocked;
+ int ret, last_rc = 0, rc;
+
+ printf("pmbus mps: FORCE; temporarily lowering WRITE_PROTECT and MFR_CFG_EXT.CLEAR_LAST_EN\n");
+ printf("pmbus mps: WARNING, erasing NVM PROTECTION_LAST (FBh) post mortem\n");
+
+ ret = pmbus_read_byte(chip, PMBUS_WRITE_PROTECT, &wp_orig);
+ if (ret) {
+ printf("pmbus mps: WRITE_PROTECT (10h) read failed (%d), aborting force\n", ret);
+ return CMD_RET_FAILURE;
+ }
+ ret = pmbus_read_word(chip, MPS_MFR_CFG_EXT, &cfg_orig);
+ if (ret) {
+ printf("pmbus mps: MFR_CFG_EXT (F5h) read failed (%d), aborting force\n", ret);
+ return CMD_RET_FAILURE;
+ }
+ printf("pmbus mps: saved WRITE_PROTECT=0x%02x MFR_CFG_EXT=0x%04x\n",
+ wp_orig, cfg_orig);
+
+ if (wp_orig != 0) {
+ u8 wp_open = 0x00;
+
+ ret = dm_i2c_write(chip, PMBUS_WRITE_PROTECT, &wp_open, 1);
+ if (ret) {
+ printf("pmbus mps: WRITE_PROTECT clear failed (%d), chip refuses unlock\n",
+ ret);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ cfg_unlocked = cfg_orig | MPS_MFR_CFG_EXT_CLR_LAST_EN;
+ ret = pmbus_write_word(chip, MPS_MFR_CFG_EXT, cfg_unlocked);
+ if (ret) {
+ printf("pmbus mps: MFR_CFG_EXT <- 0x%04x failed (%d)\n",
+ cfg_unlocked, ret);
+ goto restore_wp;
+ }
+
+ last_rc = dm_i2c_write(chip, PMBUS_CLEAR_LAST_FAULT, NULL, 0);
+ if (last_rc)
+ printf("pmbus mps: CLEAR_LAST_FAULT (08h) write failed (%d) even with gate open\n",
+ last_rc);
+ else
+ printf("pmbus mps: CLEAR_LAST_FAULT (08h) issued with MFR_CFG_EXT bit[6]=1, PROTECTION_LAST should now read 0x0000\n");
+
+ rc = pmbus_write_word(chip, MPS_MFR_CFG_EXT, cfg_orig);
+ if (rc)
+ printf("pmbus mps: MFR_CFG_EXT restore failed (%d), gate may stay open until POR\n",
+ rc);
+
+restore_wp:
+ if (wp_orig != 0) {
+ rc = dm_i2c_write(chip, PMBUS_WRITE_PROTECT, &wp_orig, 1);
+ if (rc)
+ printf("pmbus mps: WRITE_PROTECT restore failed (%d), chip stays unlocked until POR\n",
+ rc);
+ }
+
+ return (ret || last_rc) ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+static int mps_vendor_handler(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *chip;
+ int rc;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ rc = mps_require_active(&chip);
+ if (rc)
+ return rc;
+
+ if (!strcmp(argv[1], "last") && argc == 2)
+ return mps_do_last(chip);
+ if (!strcmp(argv[1], "clear") && argc >= 3) {
+ if (!strcmp(argv[2], "last"))
+ return mps_do_clear_last(chip);
+ if (!strcmp(argv[2], "force"))
+ return mps_do_clear_force(chip);
+ }
+ return CMD_RET_USAGE;
+}
+
+static const struct pmbus_vendor_op mps_vendor_op = {
+ .vendor = "mps",
+ .handler = mps_vendor_handler,
+ .help = "pmbus mps last : read MPS PROTECTION_LAST (FBh)\n"
+ "pmbus mps clear last : issue MPS CLEAR_LAST_FAULT (08h) (DESTRUCTIVE)\n"
+ "pmbus mps clear force : force clear via MFR_CFG_EXT bit[6] (DESTRUCTIVE)\n",
+};
+
+static void mpq8785_identify_vout(struct udevice *i2c_dev)
+{
+ enum pmbus_data_format fmt;
+
+ /*
+ * Let the shared helper read VOUT_MODE and pick the base format
+ * (the single source of truth for the bit layout). The MPS quirk:
+ * this family encodes VOUT in DIRECT with m=64 R=1 whenever
+ * VOUT_MODE reports VID *or* DIRECT -- override the helper's
+ * generic DIRECT m=1 / VID-unwired result in those two modes.
+ * LINEAR and IEEE754 keep the helper's selection unchanged.
+ */
+ fmt = pmbus_regulator_identify_vout(i2c_dev, &mpq8785_info);
+ if (fmt == pmbus_fmt_vid || fmt == pmbus_fmt_direct) {
+ mpq8785_info.format[PSC_VOLTAGE_OUT] = pmbus_fmt_direct;
+ mpq8785_info.m[PSC_VOLTAGE_OUT] = 64;
+ mpq8785_info.b[PSC_VOLTAGE_OUT] = 0;
+ mpq8785_info.R[PSC_VOLTAGE_OUT] = 1;
+ }
+}
+
+/*
+ * The MPQ8785 datasheet revision letter changes which window the
+ * analog ADDR_VBOOT level resolves to. Boards have been observed at
+ * 0x10 (later die rev) versus the 0x20 the original driver assumed.
+ * If the DT declared address fails the MFR_ID probe at probe time,
+ * walk the three documented windows looking for an MPS responder.
+ *
+ * Each window covers 16 consecutive 7 bit I2C addresses; the low
+ * nibble selects the chip's MFR_ADDR_PMBUS slot within the window.
+ */
+#define MPS_ADDR_VBOOT_WINDOW_SIZE 16
+static const u8 mps_addr_window_starts[] = { 0x10, 0x20, 0x60 };
+
+static int mpq8785_probe_addr(struct udevice *bus, u8 addr,
+ struct udevice **chip_out)
+{
+ char id[PMBUS_MFR_STRING_MAX] = "";
+ struct udevice *chip;
+ int ret;
+
+ ret = i2c_get_chip(bus, addr, 1, &chip);
+ if (ret)
+ return ret;
+ ret = pmbus_read_string(chip, PMBUS_MFR_ID, id, sizeof(id), true);
+ if (ret < 0)
+ return ret;
+ if (strncmp(id, "MPS", 3) != 0)
+ return -ENODEV;
+ *chip_out = chip;
+ return 0;
+}
+
+static int mpq8785_scan_windows(struct udevice *bus, u8 *found_addr,
+ struct udevice **chip_out)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(mps_addr_window_starts); i++) {
+ for (j = 0; j < MPS_ADDR_VBOOT_WINDOW_SIZE; j++) {
+ u8 addr = mps_addr_window_starts[i] + j;
+
+ if (mpq8785_probe_addr(bus, addr, chip_out) == 0) {
+ *found_addr = addr;
+ return 0;
+ }
+ }
+ }
+ return -ENODEV;
+}
+
+static struct pmbus_driver_info *mpq8785_pick_info(enum mpq_chip_id chip_id)
+{
+ switch (chip_id) {
+ case MPQ_MPM3695:
+ case MPQ_MPM3695_25:
+ case MPQ_MPM82504:
+ return &mpm82504_info;
+ case MPQ_MPQ8785:
+ default:
+ return &mpq8785_info;
+ }
+}
+
+static int mpq8785_probe(struct udevice *dev)
+{
+ enum mpq_chip_id chip_id = (enum mpq_chip_id)dev_get_driver_data(dev);
+ struct pmbus_regulator_priv *priv = dev_get_priv(dev);
+ struct pmbus_driver_info *info = mpq8785_pick_info(chip_id);
+ static bool match_registered;
+ static bool vendor_registered;
+ u32 fb_div;
+ int ret;
+
+ ret = pmbus_regulator_probe_common(dev, info, 0);
+ if (ret)
+ return ret;
+
+ /*
+ * Verify the chip answers MFR_ID="MPS" at the DT declared
+ * address. If it doesn't, walk the documented ADDR_VBOOT windows
+ * looking for it (a die rev address shift). On a hit, replace
+ * priv->i2c_dev with the discovered chip handle and continue.
+ */
+ {
+ char id[PMBUS_MFR_STRING_MAX] = "";
+
+ ret = pmbus_read_string(priv->i2c_dev, PMBUS_MFR_ID, id,
+ sizeof(id), true);
+ if (ret < 0 || strncmp(id, "MPS", 3) != 0) {
+ struct udevice *bus = dev_get_parent(dev);
+ struct udevice *promoted;
+ u8 found = 0;
+
+ if (mpq8785_scan_windows(bus, &found, &promoted) == 0) {
+ printf("MPQ8785: DT addr 0x%02x silent, auto promoted to 0x%02x\n",
+ (unsigned int)dev_read_addr(dev), found);
+ priv->i2c_dev = promoted;
+ } else {
+ printf("MPQ8785: no MPS responder found in 0x10..0x1f / 0x20..0x2f / 0x60..0x6f\n");
+ return -ENODEV;
+ }
+ }
+ }
+
+ /* MPQ8785 specific: refine VOUT format from VOUT_MODE. */
+ if (chip_id == MPQ_MPQ8785)
+ mpq8785_identify_vout(priv->i2c_dev);
+
+ /* Apply mps,vout-fb-divider-ratio-permille if present in DT. */
+ fb_div = dev_read_u32_default(dev, "mps,vout-fb-divider-ratio-permille", 0);
+ if (fb_div) {
+ ret = pmbus_regulator_apply_voltage_scale(dev, fb_div);
+ if (ret) {
+ printf("MPQ8785: VOUT_SCALE_LOOP write failed (%d)\n", ret);
+ return ret;
+ }
+ }
+
+ /*
+ * Register the chip match and the MPS vendor handler exactly
+ * once across all bound MPS regulators (a board could legally
+ * carry several). Both registries are global and idempotent
+ * matches return -ENOSPC, so the static guards keep things
+ * tidy.
+ */
+ if (!match_registered) {
+ if (pmbus_register_chip(&mpq8785_match) == 0)
+ match_registered = true;
+ }
+ if (!vendor_registered) {
+ if (pmbus_register_vendor_handler(&mps_vendor_op) == 0)
+ vendor_registered = true;
+ }
+ return 0;
+}
+
+static const struct udevice_id mpq8785_ids[] = {
+ { .compatible = "mps,mpm3695", .data = MPQ_MPM3695 },
+ { .compatible = "mps,mpm3695-25", .data = MPQ_MPM3695_25 },
+ { .compatible = "mps,mpm82504", .data = MPQ_MPM82504 },
+ { .compatible = "mps,mpq8785", .data = MPQ_MPQ8785 },
+ { }
+};
+
+U_BOOT_DRIVER(mpq8785_regulator) = {
+ .name = "mpq8785_regulator",
+ .id = UCLASS_REGULATOR,
+ .of_match = mpq8785_ids,
+ .probe = mpq8785_probe,
+ .ops = &pmbus_regulator_ops,
+ .priv_auto = sizeof(struct pmbus_regulator_priv),
+};
diff --git a/drivers/power/regulator/pfuze100.c b/drivers/power/regulator/pfuze100.c
index 77c82a00b65..57af16cfbb9 100644
--- a/drivers/power/regulator/pfuze100.c
+++ b/drivers/power/regulator/pfuze100.c
@@ -550,6 +550,8 @@ static int pfuze100_regulator_val(struct udevice *dev, int op, int *uV)
return -EINVAL;
}
val = pmic_reg_read(dev->parent, desc->vsel_reg);
+ if (val < 0)
+ return val;
if (desc->high_volt_mask && (val & desc->high_volt_mask)) {
min_uV = desc->high_volt_desc->min_uV;
uV_step = desc->high_volt_desc->uV_step;
diff --git a/drivers/power/regulator/pmbus_generic.c b/drivers/power/regulator/pmbus_generic.c
new file mode 100644
index 00000000000..6ba50ce08f8
--- /dev/null
+++ b/drivers/power/regulator/pmbus_generic.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Free Mobile, Vincent Jardin
+ *
+ * Generic PMBus 1.x compatible voltage regulator driver.
+ *
+ * Catch all driver bound to compatible = "pmbus" for chips that have
+ * no per chip driver under drivers/power/regulator/. The probe path
+ * detects the VOUT numeric format from VOUT_MODE bits[7:5]:
+ *
+ * - 0 LINEAR16 with the exponent supplied via VOUT_MODE bits[4:0]
+ * - 1 VID; mapped to pmbus_fmt_vid (decoder returns 0 today; per
+ * chip driver still required to plug a VID table)
+ * - 2 DIRECT; default coefficients m=1, b=0, R=0 (per chip
+ * coefficients arrive via PMBUS_QUERY / PMBUS_COEFFICIENTS,
+ * not yet consumed by U-Boot; values may need a per chip
+ * driver if telemetry numbers are wrong)
+ * - 3 IEEE754; mapped to pmbus_fmt_ieee754 (decoder returns 0
+ * today; per chip driver required)
+ *
+ * Other sensor classes (VIN, IIN, IOUT, TEMPERATURE) default to
+ * LINEAR which is the spec baseline for compliant chips. If an
+ * operator sees wrong telemetry numbers on this driver, the answer
+ * is to write a per chip driver with the correct format[] / m / b / R.
+ *
+ * Adapted in spirit from linux/drivers/hwmon/pmbus/pmbus.c (the
+ * kernel's generic probe driver). The U-Boot version drops the
+ * page count auto detection (most generic compliant parts are
+ * single rail; multi rail chips are quirky enough to need a per
+ * chip driver) and the kernel hwmon publication layers.
+ */
+
+#include <dm.h>
+#include <i2c.h>
+#include <log.h>
+#include <pmbus.h>
+#include <power/regulator.h>
+
+#include "pmbus_helper.h"
+
+struct pmbus_generic_priv {
+ struct pmbus_regulator_priv base; /* must be first */
+ struct pmbus_driver_info info;
+};
+
+static int pmbus_generic_probe(struct udevice *dev)
+{
+ struct pmbus_generic_priv *gpriv = dev_get_priv(dev);
+ struct pmbus_driver_info *info = &gpriv->info;
+ enum pmbus_sensor_classes c;
+ int ret;
+
+ info->pages = 1;
+ for (c = 0; c < PSC_NUM_CLASSES; c++) {
+ info->format[c] = pmbus_fmt_linear;
+ info->m[c] = 0;
+ info->b[c] = 0;
+ info->R[c] = 0;
+ }
+
+ ret = pmbus_regulator_probe_common(dev, info, 0);
+ if (ret)
+ return ret;
+
+ /*
+ * Avoid reading non supported pages to avoid device's sticky
+ * status.
+ */
+ info->pages = dev_read_u32_default(dev, "pmbus,num-pages", 1);
+ if (info->pages < 1)
+ info->pages = 1;
+
+ pmbus_regulator_identify_vout(gpriv->base.i2c_dev, info);
+
+ return 0;
+}
+
+static const struct udevice_id pmbus_generic_ids[] = {
+ { .compatible = "pmbus" },
+ { }
+};
+
+U_BOOT_DRIVER(pmbus_generic_regulator) = {
+ .name = "pmbus_generic_regulator",
+ .id = UCLASS_REGULATOR,
+ .of_match = pmbus_generic_ids,
+ .probe = pmbus_generic_probe,
+ .ops = &pmbus_regulator_ops,
+ .priv_auto = sizeof(struct pmbus_generic_priv),
+};
diff --git a/drivers/power/regulator/pmbus_helper.c b/drivers/power/regulator/pmbus_helper.c
new file mode 100644
index 00000000000..4763470442d
--- /dev/null
+++ b/drivers/power/regulator/pmbus_helper.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Free Mobile, Vincent Jardin
+ *
+ * Shared UCLASS_REGULATOR operations over the PMBus 1.x framework.
+ * See pmbus_helper.h for the API surface and doc/develop/pmbus.rst
+ * for the porting guide.
+ *
+ * No code in this file may reference a specific chip family or
+ * board. Chip specific quirks (vendor registers, VID coercion,
+ * ADDR pin auto promotion, byte reversed MFR strings, etc.) belong
+ * in the per chip driver under drivers/power/regulator/<chip>.c.
+ */
+
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <i2c.h>
+#include <log.h>
+#include <pmbus.h>
+#include <vsprintf.h>
+#include <linux/types.h>
+#include <power/regulator.h>
+
+#include "pmbus_helper.h"
+
+static int pmbus_regulator_select_page(struct pmbus_regulator_priv *priv)
+{
+ u8 p;
+
+ if (priv->page <= 0)
+ return 0;
+ p = (u8)priv->page;
+ return dm_i2c_write(priv->i2c_dev, PMBUS_PAGE, &p, 1);
+}
+
+static int pmbus_regulator_get_value(struct udevice *dev)
+{
+ struct pmbus_regulator_priv *priv = dev_get_priv(dev);
+ u8 vout_mode = 0;
+ u16 raw = 0;
+ s64 uv;
+ int ret;
+
+ ret = pmbus_regulator_select_page(priv);
+ if (ret)
+ return ret;
+ pmbus_read_byte(priv->i2c_dev, PMBUS_VOUT_MODE, &vout_mode);
+ if (pmbus_read_word(priv->i2c_dev, PMBUS_READ_VOUT, &raw))
+ return -EIO;
+
+ if (priv->info)
+ uv = pmbus_reg2data(priv->info, PSC_VOLTAGE_OUT, raw, vout_mode);
+ else
+ uv = pmbus_reg2data_linear16(raw, vout_mode);
+
+ if (uv > INT_MAX)
+ uv = INT_MAX;
+ if (uv < INT_MIN)
+ uv = INT_MIN;
+ return (int)uv;
+}
+
+static int pmbus_regulator_set_value(struct udevice *dev, int uV)
+{
+ struct pmbus_regulator_priv *priv = dev_get_priv(dev);
+ u8 vout_mode = 0;
+ u8 buf[2];
+ u16 raw;
+ int ret;
+
+ ret = pmbus_regulator_select_page(priv);
+ if (ret)
+ return ret;
+ if (pmbus_read_byte(priv->i2c_dev, PMBUS_VOUT_MODE, &vout_mode))
+ return -EIO;
+
+ /*
+ * Dispatch on the chip's VOUT_MODE selector. LINEAR16 and DIRECT
+ * are wired today; VID and IEEE754 return -ENOSYS until their
+ * encoders land. For DIRECT, the m / b / R triple comes from the
+ * chip's pmbus_driver_info[PSC_VOLTAGE_OUT]; if the per chip
+ * driver did not populate them, the encoder cannot run.
+ */
+ switch (vout_mode & PB_VOUT_MODE_MODE_MASK) {
+ case PB_VOUT_MODE_LINEAR:
+ raw = pmbus_data2reg_linear16((s64)uV, vout_mode);
+ break;
+ case PB_VOUT_MODE_DIRECT:
+ if (!priv->info ||
+ priv->info->format[PSC_VOLTAGE_OUT] != pmbus_fmt_direct)
+ return -ENODATA;
+ raw = pmbus_data2reg_direct((s64)uV,
+ priv->info->m[PSC_VOLTAGE_OUT],
+ priv->info->b[PSC_VOLTAGE_OUT],
+ priv->info->R[PSC_VOLTAGE_OUT]);
+ break;
+ default:
+ return -ENOSYS;
+ }
+
+ buf[0] = (u8)(raw & 0xff);
+ buf[1] = (u8)((raw >> 8) & 0xff);
+ return dm_i2c_write(priv->i2c_dev, PMBUS_VOUT_COMMAND, buf, 2);
+}
+
+static int pmbus_regulator_get_enable(struct udevice *dev)
+{
+ struct pmbus_regulator_priv *priv = dev_get_priv(dev);
+ u8 op = 0;
+ int ret;
+
+ ret = pmbus_regulator_select_page(priv);
+ if (ret)
+ return ret;
+ if (pmbus_read_byte(priv->i2c_dev, PMBUS_OPERATION, &op))
+ return -EIO;
+ return (op & PB_OPERATION_ON) ? 1 : 0;
+}
+
+static int pmbus_regulator_set_enable(struct udevice *dev, bool enable)
+{
+ struct pmbus_regulator_priv *priv = dev_get_priv(dev);
+ u8 op = 0;
+ int ret;
+
+ ret = pmbus_regulator_select_page(priv);
+ if (ret)
+ return ret;
+ if (pmbus_read_byte(priv->i2c_dev, PMBUS_OPERATION, &op))
+ return -EIO;
+
+ if (enable)
+ op |= PB_OPERATION_ON;
+ else
+ op &= (u8)~PB_OPERATION_ON;
+ return dm_i2c_write(priv->i2c_dev, PMBUS_OPERATION, &op, 1);
+}
+
+const struct dm_regulator_ops pmbus_regulator_ops = {
+ .get_value = pmbus_regulator_get_value,
+ .set_value = pmbus_regulator_set_value,
+ .get_enable = pmbus_regulator_get_enable,
+ .set_enable = pmbus_regulator_set_enable,
+};
+
+int pmbus_regulator_read_temp(struct udevice *reg_dev, int *temp_mc)
+{
+ struct pmbus_regulator_priv *priv;
+ u16 raw = 0;
+ s64 udeg;
+ int ret;
+
+ if (!reg_dev || !temp_mc)
+ return -EINVAL;
+ priv = dev_get_priv(reg_dev);
+ if (!priv || !priv->i2c_dev)
+ return -ENODEV;
+
+ ret = pmbus_regulator_select_page(priv);
+ if (ret)
+ return ret;
+ if (pmbus_read_word(priv->i2c_dev, PMBUS_READ_TEMPERATURE_1, &raw))
+ return -EIO;
+
+ /*
+ * vout_mode is meaningless for the temperature class. With a
+ * chip info record the dispatcher honours its per-class format
+ * (DIRECT m/b/R for MPS, LINEAR11 for spec-compliant parts);
+ * without one, fall back to the PMBus 1.x standard LINEAR11.
+ */
+ if (priv->info)
+ udeg = pmbus_reg2data(priv->info, PSC_TEMPERATURE, raw, 0);
+ else
+ udeg = pmbus_reg2data_linear11(raw);
+
+ *temp_mc = (int)(udeg / 1000);
+ return 0;
+}
+
+enum pmbus_data_format
+pmbus_regulator_identify_vout(struct udevice *i2c_dev,
+ struct pmbus_driver_info *info)
+{
+ u8 vout_mode = 0;
+
+ if (pmbus_read_byte(i2c_dev, PMBUS_VOUT_MODE, &vout_mode))
+ return info->format[PSC_VOLTAGE_OUT];
+
+ switch (vout_mode & PB_VOUT_MODE_MODE_MASK) {
+ case PB_VOUT_MODE_LINEAR:
+ info->format[PSC_VOLTAGE_OUT] = pmbus_fmt_linear;
+ break;
+ case PB_VOUT_MODE_VID:
+ info->format[PSC_VOLTAGE_OUT] = pmbus_fmt_vid;
+ break;
+ case PB_VOUT_MODE_DIRECT:
+ info->format[PSC_VOLTAGE_OUT] = pmbus_fmt_direct;
+ info->m[PSC_VOLTAGE_OUT] = 1;
+ info->b[PSC_VOLTAGE_OUT] = 0;
+ info->R[PSC_VOLTAGE_OUT] = 0;
+ break;
+ case PB_VOUT_MODE_IEEE754:
+ info->format[PSC_VOLTAGE_OUT] = pmbus_fmt_ieee754;
+ break;
+ default:
+ break;
+ }
+ return info->format[PSC_VOLTAGE_OUT];
+}
+
+const struct pmbus_driver_info *pmbus_regulator_info_by_addr(int bus_seq,
+ u8 addr)
+{
+ struct uclass *uc;
+ struct udevice *r;
+
+ if (uclass_get(UCLASS_REGULATOR, &uc))
+ return NULL;
+
+ uclass_foreach_dev(r, uc) {
+ struct udevice *parent = dev_get_parent(r);
+ struct pmbus_regulator_priv *priv;
+ int ra;
+
+ if (!parent || device_get_uclass_id(parent) != UCLASS_I2C)
+ continue;
+ if (dev_seq(parent) != bus_seq)
+ continue;
+ ra = dev_read_addr(r);
+ if (ra < 0 || (u8)ra != addr)
+ continue;
+
+ /*
+ * Address matches. Only chips driven through this helper
+ * carry a pmbus_regulator_priv at the head of their priv;
+ * identify them by their shared ops vector so we never
+ * misread a foreign regulator's private layout.
+ */
+ if (!r->driver || r->driver->ops != &pmbus_regulator_ops)
+ return NULL;
+ if (device_probe(r))
+ return NULL;
+ priv = dev_get_priv(r);
+ return priv ? priv->info : NULL;
+ }
+ return NULL;
+}
+
+/*
+ * Spawn the generic UCLASS_THERMAL companion (drivers/thermal/
+ * pmbus_thermal.c) as a child of this regulator so READ_TEMPERATURE_1
+ * is reachable through the standard `temperature list` / `temperature
+ * get` interface. Named "<regulator-name>-temp" so several PMBus rails
+ * on one board produce distinct, descriptive device names. Failure is
+ * non-fatal: the chip still works as a UCLASS_REGULATOR.
+ */
+static void pmbus_regulator_bind_thermal(struct udevice *dev)
+{
+ struct udevice *therm;
+ const char *rname;
+ char name[48];
+
+ if (!IS_ENABLED(CONFIG_PMBUS_THERMAL))
+ return;
+ if (device_bind_driver(dev, "pmbus_thermal", "pmbus-temp", &therm))
+ return;
+ rname = dev_read_string(dev, "regulator-name");
+ snprintf(name, sizeof(name), "%s-temp", rname ? rname : dev->name);
+ device_set_name(therm, name);
+}
+
+int pmbus_regulator_probe_common(struct udevice *dev,
+ const struct pmbus_driver_info *info,
+ int page)
+{
+ struct pmbus_regulator_priv *priv = dev_get_priv(dev);
+ int chip_addr;
+ int ret;
+
+ chip_addr = dev_read_addr(dev);
+ if (chip_addr < 0)
+ return -EINVAL;
+
+ ret = i2c_get_chip(dev_get_parent(dev), (u32)chip_addr, 1, &priv->i2c_dev);
+ if (ret)
+ return ret;
+
+ priv->info = info;
+ priv->page = page;
+
+ if (page > 0) {
+ u8 p = (u8)page;
+
+ ret = dm_i2c_write(priv->i2c_dev, PMBUS_PAGE, &p, 1);
+ if (ret)
+ return ret;
+ }
+
+ pmbus_regulator_bind_thermal(dev);
+ return 0;
+}
+
+int pmbus_regulator_apply_voltage_scale(struct udevice *dev,
+ u32 fb_divider_permille)
+{
+ struct pmbus_regulator_priv *priv = dev_get_priv(dev);
+ u8 buf[2];
+
+ if (fb_divider_permille == 0)
+ return 0;
+ buf[0] = (u8)(fb_divider_permille & 0xff);
+ buf[1] = (u8)((fb_divider_permille >> 8) & 0xff);
+ return dm_i2c_write(priv->i2c_dev, PMBUS_VOUT_SCALE_LOOP, buf, 2);
+}
diff --git a/drivers/power/regulator/pmbus_helper.h b/drivers/power/regulator/pmbus_helper.h
new file mode 100644
index 00000000000..82f263cd513
--- /dev/null
+++ b/drivers/power/regulator/pmbus_helper.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2026 Free Mobile, Vincent Jardin
+ *
+ * Shared UCLASS_REGULATOR ops for PMBus 1.x voltage regulator chips.
+ *
+ * Per chip drivers under drivers/power/regulator/<chip>.c bind a
+ * vendor,chip compatible from DT and call pmbus_regulator_probe_common()
+ * in their .probe. They install pmbus_regulator_ops as the .ops vector;
+ * the helper handles VOUT_MODE / READ_VOUT / VOUT_COMMAND / OPERATION
+ * via the tree level <pmbus.h> framework.
+ *
+ * Per chip drivers retain control of identify hooks (VOUT_MODE based
+ * format selection), chip specific quirks (vendor registers, ADDR pin
+ * auto promotion), and DT property handling (e.g. MPS
+ * mps,vout-fb-divider-ratio-permille).
+ */
+
+#ifndef _DRIVERS_POWER_REGULATOR_PMBUS_HELPER_H_
+#define _DRIVERS_POWER_REGULATOR_PMBUS_HELPER_H_
+
+#include <linux/types.h>
+#include <pmbus.h>
+
+struct udevice;
+struct dm_regulator_ops;
+
+/*
+ * Per chip private state. The first field of every per chip driver's
+ * priv_auto must be (or contain at offset 0) a struct
+ * pmbus_regulator_priv so the shared ops vector can recover it via
+ * dev_get_priv(dev).
+ *
+ * i2c_dev chip handle obtained from dev->parent at probe time
+ * (the parent must be a UCLASS_I2C bus).
+ * page PMBUS_PAGE selector for multi rail chips. Single rail
+ * chips set page = 0; the helper writes PMBUS_PAGE only
+ * when page > 0 to avoid wasted bus traffic on single
+ * rail parts.
+ * info pointer to the chip's pmbus_driver_info; consumed by
+ * pmbus_reg2data() / pmbus_data2reg_linear16() to pick
+ * the right format[] / m / b / R coefficients.
+ */
+struct pmbus_regulator_priv {
+ struct udevice *i2c_dev;
+ int page;
+ const struct pmbus_driver_info *info;
+};
+
+extern const struct dm_regulator_ops pmbus_regulator_ops;
+
+/*
+ * Per chip probe glue. Reads `reg` from DT, gets the I2C chip handle
+ * from dev->parent, populates priv->i2c_dev / page / info, and writes
+ * PMBUS_PAGE if page > 0. Per chip drivers call this in their .probe
+ * before any chip specific identification.
+ */
+int pmbus_regulator_probe_common(struct udevice *dev,
+ const struct pmbus_driver_info *info,
+ int page);
+
+/*
+ * Optional helper for per chip drivers that honour an external
+ * feedback divider DT property (e.g. MPS mps,vout-fb-divider-ratio-
+ * permille). Writes the supplied ratio to PMBUS_VOUT_SCALE_LOOP at
+ * probe time. fb_divider_permille == 0 leaves the chip default.
+ */
+int pmbus_regulator_apply_voltage_scale(struct udevice *dev,
+ u32 fb_divider_permille);
+
+/*
+ * Read PMBUS_VOUT_MODE and set info->format[PSC_VOLTAGE_OUT] from its
+ * mode selector bits[7:5] per PMBus 1.3 Part II sec 8.3:
+ * LINEAR -> pmbus_fmt_linear
+ * VID -> pmbus_fmt_vid
+ * DIRECT -> pmbus_fmt_direct (default coefficients m=1, b=0, R=0)
+ * IEEE754 -> pmbus_fmt_ieee754
+ *
+ * The single place that knows the VOUT_MODE bit layout; both the
+ * generic regulator and per chip drivers call it so they never
+ * re-implement the switch. Returns the selected format so a chip
+ * driver can post-adjust a quirk (e.g. MPS encodes VOUT in DIRECT
+ * with m=64 R=1 even when VOUT_MODE reports VID). On a VOUT_MODE read
+ * failure the format is left unchanged and the prior value is returned.
+ */
+enum pmbus_data_format
+pmbus_regulator_identify_vout(struct udevice *i2c_dev,
+ struct pmbus_driver_info *info);
+
+#endif /* _DRIVERS_POWER_REGULATOR_PMBUS_HELPER_H_ */
diff --git a/drivers/power/regulator/qcom-rpmh-regulator.c b/drivers/power/regulator/qcom-rpmh-regulator.c
index 4d65aae1690..c458f227bed 100644
--- a/drivers/power/regulator/qcom-rpmh-regulator.c
+++ b/drivers/power/regulator/qcom-rpmh-regulator.c
@@ -5,6 +5,7 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/err.h>
+#include <dm.h>
#include <dm/device_compat.h>
#include <dm/device.h>
#include <dm/devres.h>
@@ -295,6 +296,56 @@ static int rpmh_regulator_vrm_get_value(struct udevice *rdev)
return vreg->uv;
}
+static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
+ unsigned int mode, bool bypassed)
+{
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
+ };
+ struct dm_regulator_mode *pmic_mode;
+ int i;
+
+ if (mode > REGULATOR_MODE_HPM)
+ return -EINVAL;
+
+ for (i = 0; i < vreg->hw_data->n_modes; i++) {
+ pmic_mode = &vreg->hw_data->pmic_mode_map[i];
+ if (pmic_mode->id == mode)
+ break;
+ }
+ if (pmic_mode->id != mode) {
+ printf("Invalid mode %d\n", mode);
+ return -EINVAL;
+ }
+
+ if (bypassed)
+ // XXX: should have a version check for PMIC4 but we don't have any yet
+ // and we don't use bypass mode
+ cmd.data = PMIC5_BOB_MODE_PASS;
+ else
+ cmd.data = pmic_mode->register_value;
+
+ return rpmh_regulator_send_request(vreg, &cmd, true);
+}
+
+static int rpmh_regulator_vrm_set_mode(struct udevice *rdev,
+ int mode)
+{
+ struct rpmh_vreg *vreg = dev_get_priv(rdev);
+ int ret;
+
+ debug("%s: set_mode %d (current %d)\n", rdev->name, mode, vreg->mode);
+
+ if (mode == vreg->mode)
+ return 0;
+
+ ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
+ if (!ret)
+ vreg->mode = mode;
+
+ return ret;
+}
+
static int rpmh_regulator_is_enabled(struct udevice *rdev)
{
struct rpmh_vreg *vreg = dev_get_priv(rdev);
@@ -331,6 +382,12 @@ static int rpmh_regulator_set_enable_state(struct udevice *rdev,
debug("%s: set_enable %d (current %d)\n", rdev->name, enable,
vreg->enabled);
+ if (vreg->mode != -EINVAL) {
+ ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, vreg->bypassed);
+ if (ret < 0)
+ return ret;
+ }
+
if (vreg->enabled == -EINVAL &&
vreg->uv != -ENOTRECOVERABLE) {
ret = _rpmh_regulator_vrm_set_value(rdev,
@@ -346,56 +403,6 @@ static int rpmh_regulator_set_enable_state(struct udevice *rdev,
return ret;
}
-static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
- unsigned int mode, bool bypassed)
-{
- struct tcs_cmd cmd = {
- .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
- };
- struct dm_regulator_mode *pmic_mode;
- int i;
-
- if (mode > REGULATOR_MODE_HPM)
- return -EINVAL;
-
- for (i = 0; i < vreg->hw_data->n_modes; i++) {
- pmic_mode = &vreg->hw_data->pmic_mode_map[i];
- if (pmic_mode->id == mode)
- break;
- }
- if (pmic_mode->id != mode) {
- printf("Invalid mode %d\n", mode);
- return -EINVAL;
- }
-
- if (bypassed)
- // XXX: should have a version check for PMIC4 but we don't have any yet
- // and we don't use bypass mode
- cmd.data = PMIC5_BOB_MODE_PASS;
- else
- cmd.data = pmic_mode->register_value;
-
- return rpmh_regulator_send_request(vreg, &cmd, true);
-}
-
-static int rpmh_regulator_vrm_set_mode(struct udevice *rdev,
- int mode)
-{
- struct rpmh_vreg *vreg = dev_get_priv(rdev);
- int ret;
-
- debug("%s: set_mode %d (current %d)\n", rdev->name, mode, vreg->mode);
-
- if (mode == vreg->mode)
- return 0;
-
- ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
- if (!ret)
- vreg->mode = mode;
-
- return ret;
-}
-
static int rpmh_regulator_vrm_get_pmic_mode(struct rpmh_vreg *vreg, int *pmic_mode)
{
struct tcs_cmd cmd = {
@@ -882,7 +889,7 @@ static int rpmh_regulator_probe(struct udevice *dev)
priv->hw_data = init_data->hw_data;
priv->enabled = -EINVAL;
priv->uv = -ENOTRECOVERABLE;
- if (ofnode_read_u32(dev_ofnode(dev), "regulator-initial-mode", &priv->mode))
+ if (dev_read_u32(dev, "regulator-initial-mode", &priv->mode))
priv->mode = -EINVAL;
plat_data->mode = priv->hw_data->pmic_mode_map;
@@ -933,7 +940,7 @@ static int rpmh_regulators_bind(struct udevice *dev)
return -ENODEV;
}
- pmic_id = ofnode_read_string(dev_ofnode(dev), "qcom,pmic-id");
+ pmic_id = dev_read_string(dev, "qcom,pmic-id");
if (!pmic_id) {
dev_err(dev, "No PMIC ID\n");
return -ENODEV;
@@ -941,7 +948,7 @@ static int rpmh_regulators_bind(struct udevice *dev)
drv = lists_driver_lookup_name("rpmh_regulator_drm");
- ofnode_for_each_subnode(node, dev_ofnode(dev)) {
+ dev_for_each_subnode(node, dev) {
data = vreg_get_init_data(init_data, node);
if (!data)
continue;
diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 1c7f75a9338..0f5ba51ad6c 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -111,6 +111,33 @@ int regulator_get_suspend_value(struct udevice *dev)
return ops->get_suspend_value(dev);
}
+int regulator_set_value_clamp(struct udevice *dev,
+ int min_uV, int target_uV, int max_uV)
+{
+ const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
+ struct dm_regulator_uclass_plat *uc_pdata;
+ int uV;
+
+ if (!ops || !ops->set_value)
+ return -ENOSYS;
+
+ uc_pdata = dev_get_uclass_plat(dev);
+ if (uc_pdata->min_uV != -ENODATA && max_uV < uc_pdata->min_uV)
+ return -EINVAL;
+ if (uc_pdata->max_uV != -ENODATA && min_uV > uc_pdata->max_uV)
+ return -EINVAL;
+ if (min_uV > max_uV)
+ return -EINVAL;
+
+ if (uc_pdata->min_uV != -ENODATA)
+ min_uV = max(min_uV, uc_pdata->min_uV);
+ if (uc_pdata->max_uV != -ENODATA)
+ max_uV = min(max_uV, uc_pdata->max_uV);
+ uV = clamp(target_uV, min_uV, max_uV);
+
+ return regulator_set_value(dev, uV);
+}
+
/*
* To be called with at most caution as there is no check
* before setting the actual voltage value.
diff --git a/drivers/power/regulator/regulator_common.c b/drivers/power/regulator/regulator_common.c
index 85af8d599ad..c0387eff4fc 100644
--- a/drivers/power/regulator/regulator_common.c
+++ b/drivers/power/regulator/regulator_common.c
@@ -87,6 +87,9 @@ int regulator_common_set_enable(const struct udevice *dev,
}
}
+ if (enable && plat->off_on_delay_us)
+ udelay(plat->off_on_delay_us);
+
ret = dm_gpio_set_value(&plat->gpio, enable);
if (ret) {
pr_err("Can't set regulator : %s gpio to: %d\n", dev->name,
@@ -97,9 +100,6 @@ int regulator_common_set_enable(const struct udevice *dev,
if (enable && plat->startup_delay_us)
udelay(plat->startup_delay_us);
- if (!enable && plat->off_on_delay_us)
- udelay(plat->off_on_delay_us);
-
if (enable)
plat->enable_count++;
else
diff --git a/drivers/power/regulator/sandbox.c b/drivers/power/regulator/sandbox.c
index 80a68f5a30d..813ee301e73 100644
--- a/drivers/power/regulator/sandbox.c
+++ b/drivers/power/regulator/sandbox.c
@@ -56,10 +56,11 @@ static struct dm_regulator_mode sandbox_buck_modes[] = {
MODE(BUCK_OM_PWM, OM2REG(BUCK_OM_PWM), "PWM"),
};
-/* LDO: 1,2 - voltage range */
+/* LDO: 1,2,3 - voltage range */
static struct output_range ldo_voltage_range[] = {
RANGE(OUT_LDO1_UV_MIN, OUT_LDO1_UV_MAX, OUT_LDO1_UV_STEP),
RANGE(OUT_LDO2_UV_MIN, OUT_LDO2_UV_MAX, OUT_LDO2_UV_STEP),
+ RANGE(OUT_LDO3_UV_MIN, OUT_LDO3_UV_MAX, OUT_LDO3_UV_STEP),
};
/* LDO: 1 - current range */
@@ -288,8 +289,8 @@ static int ldo_set_voltage(struct udevice *dev, int uV)
static int ldo_get_current(struct udevice *dev)
{
- /* LDO2 - unsupported */
- if (dev->driver_data == 2)
+ /* LDO: 2,3 - unsupported */
+ if (dev->driver_data >= 2)
return -ENOSYS;
return out_get_value(dev, SANDBOX_LDO_COUNT, OUT_REG_UA,
@@ -298,8 +299,8 @@ static int ldo_get_current(struct udevice *dev)
static int ldo_set_current(struct udevice *dev, int uA)
{
- /* LDO2 - unsupported */
- if (dev->driver_data == 2)
+ /* LDO: 2,3 - unsupported */
+ if (dev->driver_data >= 2)
return -ENOSYS;
return out_set_value(dev, SANDBOX_LDO_COUNT, OUT_REG_UA,
diff --git a/drivers/power/regulator/sandbox_pmbus.c b/drivers/power/regulator/sandbox_pmbus.c
new file mode 100644
index 00000000000..7b52d2ca293
--- /dev/null
+++ b/drivers/power/regulator/sandbox_pmbus.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Free Mobile - Vincent Jardin
+ *
+ * Sandbox PMBus 1.x chip stub (UCLASS_I2C_EMUL).
+ *
+ * Stub a DT i2c node so the PMBus framework, the generic pmbus
+ * regulator and the pmbus CLI command can be tested.
+ * The model is a flat per-command 16 bit
+ * register file combined with some fixed identification strings.
+ */
+
+#include <dm.h>
+#include <i2c.h>
+#include <pmbus.h>
+#include <linux/ctype.h>
+
+#define PMBUS_EMUL_NREG 256
+
+struct sandbox_pmbus_priv {
+ u16 reg[PMBUS_EMUL_NREG];
+ bool supported[PMBUS_EMUL_NREG];
+};
+
+/* Identification strings reported in the natural (forward) byte order. */
+static const char *pmbus_emul_string(u8 cmd)
+{
+ switch (cmd) {
+ case PMBUS_MFR_ID:
+ return "SANDBOX";
+ case PMBUS_MFR_MODEL:
+ return "PMBUS-EMUL";
+ case PMBUS_MFR_REVISION:
+ return "1.0";
+ default:
+ return NULL;
+ }
+}
+
+static int sandbox_pmbus_read(struct sandbox_pmbus_priv *priv, u8 cmd,
+ u8 *buf, int len)
+{
+ const char *str = pmbus_emul_string(cmd);
+ int i;
+
+ if (len < 1)
+ return -EINVAL;
+
+ if (str) {
+ int slen = strlen(str);
+
+ /*
+ * Block payload: [length][bytes...]. A one-byte read is
+ * the SMBus length probe and reports the true length (the
+ * master just NAKs early). Any longer read must have room
+ * for length + payload, otherwise the length byte would
+ * lie about the data actually returned.
+ */
+ if (len > 1 && len < slen + 1)
+ return -EREMOTEIO;
+ buf[0] = (u8)slen;
+ for (i = 1; i < len; i++)
+ buf[i] = (i - 1 < slen) ? (u8)str[i - 1] : 0;
+ return 0;
+ }
+
+ if (!priv->supported[cmd])
+ return -EREMOTEIO; /* chip NAKs an unimplemented command */
+
+ for (i = 0; i < len; i++)
+ buf[i] = (u8)(priv->reg[cmd] >> (8 * i));
+ return 0;
+}
+
+static int sandbox_pmbus_write(struct sandbox_pmbus_priv *priv, u8 cmd,
+ const u8 *buf, int len)
+{
+ if (len == 0)
+ return 0; /* send-byte (eg CLEAR_FAULTS): just ACK */
+ if (!priv->supported[cmd])
+ return -EREMOTEIO;
+ if (len == 1)
+ priv->reg[cmd] = buf[0];
+ else
+ priv->reg[cmd] = (u16)buf[0] | ((u16)buf[1] << 8);
+ return 0;
+}
+
+static int sandbox_pmbus_xfer(struct udevice *emul, struct i2c_msg *msg,
+ int nmsgs)
+{
+ struct sandbox_pmbus_priv *priv = dev_get_priv(emul);
+ u8 cmd;
+
+ if (nmsgs == 0)
+ return 0;
+ /* A PMBus transaction always opens with the command-code write. */
+ if (msg[0].flags & I2C_M_RD)
+ return -EIO;
+ if (msg[0].len == 0)
+ return 0; /* address-only probe */
+ cmd = msg[0].buf[0];
+
+ if (nmsgs >= 2 && (msg[1].flags & I2C_M_RD))
+ return sandbox_pmbus_read(priv, cmd, msg[1].buf, msg[1].len);
+
+ return sandbox_pmbus_write(priv, cmd, msg[0].buf + 1, msg[0].len - 1);
+}
+
+static void sandbox_pmbus_support(struct sandbox_pmbus_priv *priv, u8 cmd,
+ u16 val)
+{
+ priv->supported[cmd] = true;
+ priv->reg[cmd] = val;
+}
+
+static int sandbox_pmbus_probe(struct udevice *emul)
+{
+ struct sandbox_pmbus_priv *priv = dev_get_priv(emul);
+
+ /* Configuration / identification. */
+ sandbox_pmbus_support(priv, PMBUS_PAGE, 0);
+ sandbox_pmbus_support(priv, PMBUS_OPERATION, PB_OPERATION_ON);
+ sandbox_pmbus_support(priv, PMBUS_ON_OFF_CONFIG, 0);
+ sandbox_pmbus_support(priv, PMBUS_WRITE_PROTECT, 0);
+ sandbox_pmbus_support(priv, PMBUS_CAPABILITY, 0x30);
+ sandbox_pmbus_support(priv, PMBUS_VOUT_MODE, 0x18); /* LINEAR 2^-8 */
+ sandbox_pmbus_support(priv, PMBUS_VOUT_COMMAND, 0x0200);
+ sandbox_pmbus_support(priv, PMBUS_VOUT_TRIM, 0);
+ sandbox_pmbus_support(priv, PMBUS_VOUT_MAX, 0x0400);
+ sandbox_pmbus_support(priv, PMBUS_VOUT_SCALE_LOOP, 0);
+ sandbox_pmbus_support(priv, PMBUS_REVISION, PMBUS_REV_13);
+
+ /* Status registers, all clean. */
+ sandbox_pmbus_support(priv, PMBUS_STATUS_BYTE, 0);
+ sandbox_pmbus_support(priv, PMBUS_STATUS_WORD, 0);
+ sandbox_pmbus_support(priv, PMBUS_STATUS_VOUT, 0);
+ sandbox_pmbus_support(priv, PMBUS_STATUS_IOUT, 0);
+ sandbox_pmbus_support(priv, PMBUS_STATUS_INPUT, 0);
+ sandbox_pmbus_support(priv, PMBUS_STATUS_TEMPERATURE, 0);
+ sandbox_pmbus_support(priv, PMBUS_STATUS_CML, 0);
+
+ /*
+ * Telemetry the emulated chip implements. READ_IIN and READ_POUT
+ * are intentionally absent so callers see the unsupported path.
+ */
+ sandbox_pmbus_support(priv, PMBUS_READ_VIN, 0x0abc);
+ sandbox_pmbus_support(priv, PMBUS_READ_VOUT, 0x0200);
+ sandbox_pmbus_support(priv, PMBUS_READ_IOUT, 0x0123);
+ sandbox_pmbus_support(priv, PMBUS_READ_TEMPERATURE_1, 0x0019);
+
+ return 0;
+}
+
+static struct dm_i2c_ops sandbox_pmbus_emul_ops = {
+ .xfer = sandbox_pmbus_xfer,
+};
+
+static const struct udevice_id sandbox_pmbus_ids[] = {
+ { .compatible = "sandbox,i2c-pmbus" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_pmbus_emul) = {
+ .name = "sandbox_pmbus_emul",
+ .id = UCLASS_I2C_EMUL,
+ .of_match = sandbox_pmbus_ids,
+ .probe = sandbox_pmbus_probe,
+ .priv_auto = sizeof(struct sandbox_pmbus_priv),
+ .ops = &sandbox_pmbus_emul_ops,
+};
diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c
index 7d2db1e2bee..aa7b4278260 100644
--- a/drivers/power/regulator/scmi_regulator.c
+++ b/drivers/power/regulator/scmi_regulator.c
@@ -180,7 +180,7 @@ static int scmi_regulator_bind(struct udevice *dev)
ofnode node;
int ret;
- regul_node = ofnode_find_subnode(dev_ofnode(dev), "regulators");
+ regul_node = dev_read_subnode(dev, "regulators");
if (!ofnode_valid(regul_node)) {
dev_err(dev, "no regulators node\n");
return -ENXIO;
diff --git a/drivers/power/regulator/spacemit_p1_regulator.c b/drivers/power/regulator/spacemit_p1_regulator.c
new file mode 100644
index 00000000000..7b5eb710edf
--- /dev/null
+++ b/drivers/power/regulator/spacemit_p1_regulator.c
@@ -0,0 +1,464 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025-2026 RISCstar Ltd.
+ */
+
+#include <dm.h>
+#include <dm/lists.h>
+#include <errno.h>
+#include <log.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/spacemit_p1.h>
+
+struct p1_reg_info {
+ uint min_uv;
+ uint step_uv;
+ u8 vsel_reg;
+ u8 vsel_sleep_reg;
+ u8 config_reg;
+ u8 vsel_mask;
+ u8 min_sel;
+ u8 max_sel;
+};
+
+static const struct p1_reg_info p1_bucks[] = {
+ /* BUCK 1 */
+ { 500000, 5000, P1_BUCK_VSEL(1), P1_BUCK_SVSEL(1), P1_BUCK_CTRL(1),
+ BUCK_VSEL_MASK, 0x00, 0xaa },
+ { 1375000, 25000, P1_BUCK_VSEL(1), P1_BUCK_SVSEL(1), P1_BUCK_CTRL(1),
+ BUCK_VSEL_MASK, 0xab, 0xfe },
+ /* BUCK 2 */
+ { 500000, 5000, P1_BUCK_VSEL(2), P1_BUCK_SVSEL(2), P1_BUCK_CTRL(2),
+ BUCK_VSEL_MASK, 0x00, 0xaa },
+ { 1375000, 25000, P1_BUCK_VSEL(2), P1_BUCK_SVSEL(2), P1_BUCK_CTRL(2),
+ BUCK_VSEL_MASK, 0xab, 0xfe },
+ /* BUCK 3 */
+ { 500000, 5000, P1_BUCK_VSEL(3), P1_BUCK_SVSEL(3), P1_BUCK_CTRL(3),
+ BUCK_VSEL_MASK, 0x00, 0xaa },
+ { 1375000, 25000, P1_BUCK_VSEL(3), P1_BUCK_SVSEL(3), P1_BUCK_CTRL(3),
+ BUCK_VSEL_MASK, 0xab, 0xfe },
+ /* BUCK 4 */
+ { 500000, 5000, P1_BUCK_VSEL(4), P1_BUCK_SVSEL(4), P1_BUCK_CTRL(4),
+ BUCK_VSEL_MASK, 0x00, 0xaa },
+ { 1375000, 25000, P1_BUCK_VSEL(4), P1_BUCK_SVSEL(4), P1_BUCK_CTRL(4),
+ BUCK_VSEL_MASK, 0xab, 0xfe },
+ /* BUCK 5 */
+ { 500000, 5000, P1_BUCK_VSEL(5), P1_BUCK_SVSEL(5), P1_BUCK_CTRL(5),
+ BUCK_VSEL_MASK, 0x00, 0xaa },
+ { 1375000, 25000, P1_BUCK_VSEL(5), P1_BUCK_SVSEL(5), P1_BUCK_CTRL(5),
+ BUCK_VSEL_MASK, 0xab, 0xfe },
+ /* BUCK 6 */
+ { 500000, 5000, P1_BUCK_VSEL(6), P1_BUCK_SVSEL(6), P1_BUCK_CTRL(6),
+ BUCK_VSEL_MASK, 0x00, 0xaa },
+ { 1375000, 25000, P1_BUCK_VSEL(6), P1_BUCK_SVSEL(6), P1_BUCK_CTRL(6),
+ BUCK_VSEL_MASK, 0xab, 0xfe },
+};
+
+static const struct p1_reg_info p1_aldos[] = {
+ /* ALDO 1 */
+ { 500000, 25000, P1_ALDO_VOLT(1), P1_ALDO_SVOLT(1), P1_ALDO_CTRL(1),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* ALDO 2 */
+ { 500000, 25000, P1_ALDO_VOLT(2), P1_ALDO_SVOLT(2), P1_ALDO_CTRL(2),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* ALDO 3 */
+ { 500000, 25000, P1_ALDO_VOLT(3), P1_ALDO_SVOLT(3), P1_ALDO_CTRL(3),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* ALDO 4 */
+ { 500000, 25000, P1_ALDO_VOLT(4), P1_ALDO_SVOLT(4), P1_ALDO_CTRL(4),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+};
+
+static const struct p1_reg_info p1_dldos[] = {
+ /* DLDO 1 */
+ { 500000, 25000, P1_DLDO_VOLT(1), P1_DLDO_SVOLT(1), P1_DLDO_CTRL(1),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* DLDO 2 */
+ { 500000, 25000, P1_DLDO_VOLT(2), P1_DLDO_SVOLT(2), P1_DLDO_CTRL(2),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* DLDO 3 */
+ { 500000, 25000, P1_DLDO_VOLT(3), P1_DLDO_SVOLT(3), P1_DLDO_CTRL(3),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* DLDO 4 */
+ { 500000, 25000, P1_DLDO_VOLT(4), P1_DLDO_SVOLT(4), P1_DLDO_CTRL(4),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* DLDO 5 */
+ { 500000, 25000, P1_DLDO_VOLT(5), P1_DLDO_SVOLT(5), P1_DLDO_CTRL(5),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* DLDO 6 */
+ { 500000, 25000, P1_DLDO_VOLT(6), P1_DLDO_SVOLT(6), P1_DLDO_CTRL(6),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+ /* DLDO 7 */
+ { 500000, 25000, P1_DLDO_VOLT(7), P1_DLDO_SVOLT(7), P1_DLDO_CTRL(7),
+ ALDO_VSEL_MASK, 0x0b, 0x7f },
+};
+
+static const struct p1_reg_info *get_buck_reg(struct udevice *pmic,
+ int idx, int uvolt)
+{
+ if (idx < 0)
+ return NULL;
+ if (uvolt < 1375000)
+ return &p1_bucks[(idx - 1) * 2 + 0];
+ return &p1_bucks[(idx - 1) * 2 + 1];
+}
+
+static const struct p1_reg_info *get_aldo_reg(struct udevice *pmic,
+ int idx, int uvolt)
+{
+ if (idx < 1 || idx > ARRAY_SIZE(p1_aldos))
+ return NULL;
+ return &p1_aldos[idx - 1];
+}
+
+static const struct p1_reg_info *get_dldo_reg(struct udevice *pmic,
+ int idx, int uvolt)
+{
+ if (idx < 1 || idx > ARRAY_SIZE(p1_dldos))
+ return NULL;
+ return &p1_dldos[idx - 1];
+}
+
+static int buck_get_value(struct udevice *dev)
+{
+ const struct dm_pmic_ops *ops = device_get_ops(dev->parent);
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ if (!ops || !ops->read)
+ return -ENOSYS;
+
+ info = get_buck_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+ ret = pmic_reg_read(dev->parent, info->vsel_reg);
+ if (ret < 0)
+ return ret;
+ val = ret & info->vsel_mask;
+ while (val > info->max_sel)
+ info++;
+
+ return info->min_uv + (val - info->min_sel) * info->step_uv;
+}
+
+static int buck_set_value(struct udevice *dev, int uvolt)
+{
+ const struct dm_pmic_ops *ops = device_get_ops(dev->parent);
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ if (!ops || !ops->write)
+ return -ENOSYS;
+
+ info = get_buck_reg(dev->parent, dev->driver_data, uvolt);
+ if (!info)
+ return -ENOENT;
+ val = (uvolt - info->min_uv);
+ val = val / info->step_uv;
+ val += info->min_sel;
+ ret = pmic_reg_write(dev->parent, info->vsel_reg, val);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int buck_get_enable(struct udevice *dev)
+{
+ const struct p1_reg_info *info;
+ int ret;
+
+ info = get_buck_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->config_reg);
+ if (ret < 0)
+ return ret;
+ return ret & BUCK_EN_MASK;
+}
+
+static int buck_set_enable(struct udevice *dev, bool enable)
+{
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ info = get_buck_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->config_reg);
+ if (ret < 0)
+ return ret;
+ val = (unsigned int)ret;
+ val &= BUCK_EN_MASK;
+
+ if (enable == val)
+ return 0;
+
+ val = enable;
+ ret = pmic_clrsetbits(dev->parent, info->config_reg, BUCK_EN_MASK, val);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static const struct dm_regulator_ops p1_buck_ops = {
+ .get_value = buck_get_value,
+ .set_value = buck_set_value,
+ .get_enable = buck_get_enable,
+ .set_enable = buck_set_enable,
+};
+
+static int p1_buck_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_plat *uc_pdata;
+
+ uc_pdata = dev_get_uclass_plat(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_BUCK;
+ uc_pdata->mode_count = 0;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(p1_buck) = {
+ .name = P1_BUCK_DRIVER,
+ .id = UCLASS_REGULATOR,
+ .ops = &p1_buck_ops,
+ .probe = p1_buck_probe,
+};
+
+static int aldo_get_value(struct udevice *dev)
+{
+ const struct dm_pmic_ops *ops = device_get_ops(dev->parent);
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ if (!ops || !ops->read)
+ return -ENOSYS;
+
+ info = get_aldo_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->vsel_reg);
+ if (ret < 0)
+ return ret;
+
+ val = ret & info->vsel_mask;
+ while (val > info->max_sel)
+ info++;
+
+ return info->min_uv + (val - info->min_sel) * info->step_uv;
+}
+
+static int aldo_set_value(struct udevice *dev, int uvolt)
+{
+ const struct dm_pmic_ops *ops = device_get_ops(dev->parent);
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ if (!ops || !ops->write)
+ return -ENOSYS;
+
+ info = get_aldo_reg(dev->parent, dev->driver_data, uvolt);
+ if (!info)
+ return -ENOENT;
+ val = (uvolt - info->min_uv);
+ val = val / info->step_uv;
+ val += info->min_sel;
+ ret = pmic_reg_write(dev->parent, info->vsel_reg, val);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int aldo_get_enable(struct udevice *dev)
+{
+ const struct p1_reg_info *info;
+ int ret;
+
+ info = get_aldo_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->config_reg);
+ if (ret < 0)
+ return ret;
+ return ret & ALDO_EN_MASK;
+}
+
+static int aldo_set_enable(struct udevice *dev, bool enable)
+{
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ info = get_aldo_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->config_reg);
+ if (ret < 0)
+ return ret;
+ val = (unsigned int)ret;
+ val &= ALDO_EN_MASK;
+
+ if (enable == val)
+ return 0;
+
+ val = enable;
+ ret = pmic_clrsetbits(dev->parent, info->config_reg, ALDO_EN_MASK, val);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static const struct dm_regulator_ops p1_aldo_ops = {
+ .get_value = aldo_get_value,
+ .set_value = aldo_set_value,
+ .get_enable = aldo_get_enable,
+ .set_enable = aldo_set_enable,
+};
+
+static int p1_aldo_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_plat *uc_pdata;
+
+ uc_pdata = dev_get_uclass_plat(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_LDO;
+ uc_pdata->mode_count = 0;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(p1_aldo) = {
+ .name = P1_ALDO_DRIVER,
+ .id = UCLASS_REGULATOR,
+ .ops = &p1_aldo_ops,
+ .probe = p1_aldo_probe,
+};
+
+static int dldo_get_value(struct udevice *dev)
+{
+ const struct dm_pmic_ops *ops = device_get_ops(dev->parent);
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ if (!ops || !ops->read)
+ return -ENOSYS;
+
+ info = get_dldo_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->vsel_reg);
+ if (ret < 0)
+ return ret;
+
+ val = ret & info->vsel_mask;
+ while (val > info->max_sel)
+ info++;
+
+ return info->min_uv + (val - info->min_sel) * info->step_uv;
+}
+
+static int dldo_set_value(struct udevice *dev, int uvolt)
+{
+ const struct dm_pmic_ops *ops = device_get_ops(dev->parent);
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ if (!ops || !ops->write)
+ return -ENOSYS;
+
+ info = get_dldo_reg(dev->parent, dev->driver_data, uvolt);
+ if (!info)
+ return -ENOENT;
+ val = (uvolt - info->min_uv);
+ val = val / info->step_uv;
+ val += info->min_sel;
+ ret = pmic_reg_write(dev->parent, info->vsel_reg, val);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int dldo_get_enable(struct udevice *dev)
+{
+ const struct p1_reg_info *info;
+ int ret;
+
+ info = get_dldo_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->config_reg);
+ if (ret < 0)
+ return ret;
+ return ret & DLDO_EN_MASK;
+}
+
+static int dldo_set_enable(struct udevice *dev, bool enable)
+{
+ const struct p1_reg_info *info;
+ uint val;
+ int ret;
+
+ info = get_dldo_reg(dev->parent, dev->driver_data, 0);
+ if (!info)
+ return -ENOENT;
+
+ ret = pmic_reg_read(dev->parent, info->config_reg);
+ if (ret < 0)
+ return ret;
+ val = (unsigned int)ret;
+ val &= DLDO_EN_MASK;
+
+ if (enable == val)
+ return 0;
+
+ val = enable;
+ ret = pmic_clrsetbits(dev->parent, info->config_reg, DLDO_EN_MASK, val);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static const struct dm_regulator_ops p1_dldo_ops = {
+ .get_value = dldo_get_value,
+ .set_value = dldo_set_value,
+ .get_enable = dldo_get_enable,
+ .set_enable = dldo_set_enable,
+};
+
+static int p1_dldo_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_plat *uc_pdata;
+
+ uc_pdata = dev_get_uclass_plat(dev);
+
+ uc_pdata->type = REGULATOR_TYPE_LDO;
+ uc_pdata->mode_count = 0;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(p1_dldo) = {
+ .name = P1_DLDO_DRIVER,
+ .id = UCLASS_REGULATOR,
+ .ops = &p1_dldo_ops,
+ .probe = p1_dldo_probe,
+};
diff --git a/drivers/power/regulator/tps6287x_regulator.c b/drivers/power/regulator/tps6287x_regulator.c
index 6d185719199..2e6d85f677a 100644
--- a/drivers/power/regulator/tps6287x_regulator.c
+++ b/drivers/power/regulator/tps6287x_regulator.c
@@ -141,7 +141,7 @@ static int tps6287x_regulator_probe(struct udevice *dev)
pdata->config = (void *)dev_get_driver_data(dev);
- slave_id = devfdt_get_addr_index(dev, 0);
+ slave_id = dev_read_addr_index(dev, 0);
ret = i2c_get_chip(dev->parent, slave_id, 1, &pdata->i2c);
if (ret) {
diff --git a/drivers/ram/aspeed/Kconfig b/drivers/ram/aspeed/Kconfig
index e4918460de6..fa5c890bb7a 100644
--- a/drivers/ram/aspeed/Kconfig
+++ b/drivers/ram/aspeed/Kconfig
@@ -4,19 +4,19 @@ menuconfig ASPEED_RAM
depends on ARCH_ASPEED || TARGET_ASPEED_AST2700_IBEX
default ARCH_ASPEED
help
- Configuration options for DDR SDRAM on ASPEED systems.
+ Configuration options for DDR SDRAM on ASPEED systems.
- RAM initialisation is always built in for the platform. This menu
- allows customisation of the configuration used.
+ RAM initialisation is always built in for the platform. This menu
+ allows customisation of the configuration used.
config ASPEED_DDR4_DUALX8
bool "Enable Dual X8 DDR4 die"
depends on ASPEED_RAM
help
- Say Y if dual X8 DDR4 die is used on the board. The ASPEED DDRM
- SRAM controller needs to know if the memory chip mounted on the
- board is dual x8 die or not, otherwise it may get the wrong
- size of the memory space.
+ Say Y if dual X8 DDR4 die is used on the board. The ASPEED DDRM
+ SRAM controller needs to know if the memory chip mounted on the
+ board is dual x8 die or not, otherwise it may get the wrong
+ size of the memory space.
config ASPEED_BYPASS_SELFTEST
depends on ASPEED_RAM
@@ -77,7 +77,7 @@ choice
prompt "AST2700 DDR target date rate"
default ASPEED_DDR_3200
depends on ASPEED_RAM
- depends on TARGET_ASPEED_AST2700_IBEX
+ depends on ASPEED_AST2700 || TARGET_ASPEED_AST2700_IBEX
config ASPEED_DDR_1600
bool "1600 Mbps"
diff --git a/drivers/ram/aspeed/Makefile b/drivers/ram/aspeed/Makefile
index 1f0b22c8e9f..d29e2154ce9 100644
--- a/drivers/ram/aspeed/Makefile
+++ b/drivers/ram/aspeed/Makefile
@@ -2,4 +2,5 @@
#
obj-$(CONFIG_ASPEED_AST2500) += sdram_ast2500.o
obj-$(CONFIG_ASPEED_AST2600) += sdram_ast2600.o
+obj-$(CONFIG_ASPEED_AST2700) += sdram_ast2700.o
obj-$(CONFIG_TARGET_ASPEED_AST2700_IBEX) += sdram_ast2700.o
diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c
index 55e80fba3dc..2cf9296468d 100644
--- a/drivers/ram/aspeed/sdram_ast2600.c
+++ b/drivers/ram/aspeed/sdram_ast2600.c
@@ -1076,10 +1076,10 @@ static int ast2600_sdrammc_probe(struct udevice *dev)
return ret;
}
- priv->scu = devfdt_get_addr_ptr(clk_dev);
- if (IS_ERR(priv->scu)) {
+ priv->scu = dev_read_addr_ptr(clk_dev);
+ if (!priv->scu) {
debug("%s(): can't get SCU\n", __func__);
- return PTR_ERR(priv->scu);
+ return -ENODEV;
}
if (readl(&priv->scu->dram_hdshk) & SCU_DRAM_HDSHK_RDY) {
@@ -1136,12 +1136,11 @@ static int ast2600_sdrammc_of_to_plat(struct udevice *dev)
{
struct dram_info *priv = dev_get_priv(dev);
- priv->regs = (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
- priv->phy_setting = (void *)(uintptr_t)devfdt_get_addr_index(dev, 1);
- priv->phy_status = (void *)(uintptr_t)devfdt_get_addr_index(dev, 2);
+ priv->regs = (void *)(uintptr_t)dev_read_addr_index(dev, 0);
+ priv->phy_setting = (void *)(uintptr_t)dev_read_addr_index(dev, 1);
+ priv->phy_status = (void *)(uintptr_t)dev_read_addr_index(dev, 2);
- priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "clock-frequency", 0);
+ priv->clock_rate = ofnode_read_s32_default(dev_ofnode(dev), "clock-frequency", 0);
if (!priv->clock_rate) {
debug("DDR Clock Rate not defined\n");
return -EINVAL;
diff --git a/drivers/ram/aspeed/sdram_ast2700.c b/drivers/ram/aspeed/sdram_ast2700.c
index 4a019c4edb1..8605a92abb2 100644
--- a/drivers/ram/aspeed/sdram_ast2700.c
+++ b/drivers/ram/aspeed/sdram_ast2700.c
@@ -14,6 +14,11 @@
#include <linux/sizes.h>
#include <ram.h>
+__weak int fmc_hdr_get_prebuilt(u32 type, u32 *ofst, u32 *size)
+{
+ return -ENOSYS;
+}
+
enum ddr_type {
DDR4_1600 = 0x0,
DDR4_2400,
@@ -128,13 +133,13 @@ static size_t ast2700_sdrammc_get_vga_mem_size(struct sdrammc *sdrammc)
reg = readl(scu0 + SCU0_PCI_MISC70);
if (reg & SCU0_PCI_MISC70_EN_PCIEVGA0) {
- debug("VGA0:%dMB\n", vga_memsz[sel] / SZ_1M);
+ debug("VGA0:%zuMB\n", vga_memsz[sel] / SZ_1M);
dual++;
}
reg = readl(scu0 + SCU0_PCI_MISC80);
if (reg & SCU0_PCI_MISC80_EN_PCIEVGA1) {
- debug("VGA1:%dMB\n", vga_memsz[sel] / SZ_1M);
+ debug("VGA1:%zuMB\n", vga_memsz[sel] / SZ_1M);
dual++;
}
@@ -560,7 +565,7 @@ void dwc_get_mailbox(struct sdrammc *sdrammc, const int mode, u32 *mbox)
dwc_ddrphy_apb_wr(0xd0031, 1);
}
-uint32_t dwc_readMsgBlock(struct sdrammc *sdrammc, const u32 addr_half)
+u32 dwc_readMsgBlock(struct sdrammc *sdrammc, const u32 addr_half)
{
u32 data_word;
@@ -727,7 +732,7 @@ int dwc_ddrphy_phyinit_userCustom_D_loadIMEM(struct sdrammc *sdrammc, const int
fmc_hdr_get_prebuilt(pb_type, &imem_ofst, &imem_size);
memcpy(sdrammc->phy + (DWC_PHY_IMEM_OFST << 1),
- (void *)(0x20000000 + imem_ofst), imem_size);
+ (void *)(uintptr_t)(0x20000000 + imem_ofst), imem_size);
return 0;
}
@@ -746,7 +751,7 @@ int dwc_ddrphy_phyinit_userCustom_F_loadDMEM(struct sdrammc *sdrammc,
fmc_hdr_get_prebuilt(pb_type, &dmem_ofst, &dmem_size);
memcpy(sdrammc->phy + (DWC_PHY_DMEM_OFST << 1),
- (void *)(0x20000000 + dmem_ofst), dmem_size);
+ (void *)(uintptr_t)(0x20000000 + dmem_ofst), dmem_size);
return 0;
}
@@ -956,13 +961,13 @@ static int ast2700_sdrammc_of_to_plat(struct udevice *dev)
ofnode node;
int rc;
- sdrammc->regs = (struct sdrammc_regs *)devfdt_get_addr_index(dev, 0);
+ sdrammc->regs = (struct sdrammc_regs *)dev_read_addr_index(dev, 0);
if (sdrammc->regs == (void *)FDT_ADDR_T_NONE) {
debug("cannot map DRAM register\n");
return -ENODEV;
}
- sdrammc->phy = (void *)devfdt_get_addr_index(dev, 1);
+ sdrammc->phy = (void *)dev_read_addr_index(dev, 1);
if (sdrammc->phy == (void *)FDT_ADDR_T_NONE) {
debug("cannot map PHY memory\n");
return -ENODEV;
diff --git a/drivers/ram/octeon/Kconfig b/drivers/ram/octeon/Kconfig
index f19957293f9..37bf4851400 100644
--- a/drivers/ram/octeon/Kconfig
+++ b/drivers/ram/octeon/Kconfig
@@ -2,14 +2,14 @@ config RAM_OCTEON
bool "Ram drivers for Octeon SoCs"
depends on RAM && ARCH_OCTEON
help
- This enables support for RAM drivers for Octeon SoCs.
+ This enables support for RAM drivers for Octeon SoCs.
if RAM_OCTEON
config RAM_OCTEON_DDR4
bool "Octeon III DDR4 RAM support"
help
- This enables support for DDR4 RAM suppoort for Octeon III. This does
- not include support for Octeon CN70XX.
+ This enables support for DDR4 RAM suppoort for Octeon III. This does
+ not include support for Octeon CN70XX.
endif # RAM_OCTEON
diff --git a/drivers/ram/renesas/Kconfig b/drivers/ram/renesas/Kconfig
index 6a1ef2a0c63..8c3e5fab96f 100644
--- a/drivers/ram/renesas/Kconfig
+++ b/drivers/ram/renesas/Kconfig
@@ -1,7 +1,7 @@
config RAM_RENESAS_DBSC5
- bool "Renesas R-Car V4H/V4M DBSC5 controller driver"
- depends on SPL && RAM && (R8A779G0 || R8A779H0)
+ bool "Renesas R-Car V4H/V4M/X5H DBSC5 controller driver"
+ depends on RAM && (R8A78000 || (SPL && (R8A779G0 || R8A779H0)))
default n
help
Enable this to support the DBSC5 DRAM controller initialization
- on Renesas R8A779G0/R8A779H0 SoCs.
+ on Renesas R8A779G0/R8A779H0/R8A78000 SoCs.
diff --git a/drivers/ram/renesas/Makefile b/drivers/ram/renesas/Makefile
index 578d05622d7..699b726972b 100644
--- a/drivers/ram/renesas/Makefile
+++ b/drivers/ram/renesas/Makefile
@@ -1,6 +1,4 @@
# SPDX-License-Identifier: GPL-2.0+
-ifdef CONFIG_XPL_BUILD
obj-$(CONFIG_RAM_RENESAS_DBSC5) += dbsc5/
-endif
obj-$(CONFIG_RZN1) += rzn1/
diff --git a/drivers/ram/renesas/dbsc5/Makefile b/drivers/ram/renesas/dbsc5/Makefile
index 177be893e10..0ae2193e09b 100644
--- a/drivers/ram/renesas/dbsc5/Makefile
+++ b/drivers/ram/renesas/dbsc5/Makefile
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
-obj-y += dbsc5.o dram.o qos.o rtvram.o
+obj-$(CONFIG_R8A779G0) += r8a779g0-dbsc5.o r8a779g0-dram.o qos.o
+obj-$(CONFIG_R8A78000) += r8a78000-dbsc5.o r8a78000-dram.o ecc.o
+obj-y += rtvram.o
diff --git a/drivers/ram/renesas/dbsc5/ecc.c b/drivers/ram/renesas/dbsc5/ecc.c
new file mode 100644
index 00000000000..77295a696ab
--- /dev/null
+++ b/drivers/ram/renesas/dbsc5/ecc.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <ram.h>
+#include <linux/sizes.h>
+
+#define DBSC5_DBSC_CNT 8
+
+#define DBSC_D_BASE(n) (0xe9900000 + ((n) * 0x4000))
+#define DBSC_A_BASE(n) (0xe9800000 + ((n) * 0x8000))
+#define DBSYSCNT 0x100
+#define DBACEN 0x200
+#define DBFSINTENB02A 0x7088
+#define DBFSINTENB04A 0x7090
+#define DBFSCONFAXI0 0x7400
+#define DBFSDRAMECCAREA00 0x7450
+#define DBFSCTRL01A 0x7604
+#define DBFSCONF00A 0x7640
+#define DBFSCONF01A 0x7644
+#define DBFSCONF02A 0x7648
+#define DBFSSTAT00A 0x7680
+#define DBFSSTAT01A 0x7684
+
+#define DBSYSCNT_ENABLE 0x1234
+#define DBSYSCNT_DISABLE 0x0
+#define DBACEN_ACCESS_DISABLE 0
+#define DBACEN_ACCESS_ENABLE 1
+
+#define ECM_BASE 0xb89a0000
+#define ECMERRCTLR0 (ECM_BASE + 0x0)
+#define ECMERRINCR0 (ECM_BASE + 0x200)
+#define ECMERROMKR0 (ECM_BASE + 0x600)
+#define ECMERRCTLR6 (ECM_BASE + (0x4 * 6))
+#define ECMERRINCR6 (ECM_BASE + 0x200U + (0x4 * 6))
+#define ECMERROMKR6 (ECM_BASE + 0x600U + (0x4 * 6))
+#define ECMWPCNTR (ECM_BASE + 0xa00)
+#define ECMWACNTR (ECM_BASE + 0xa04)
+
+struct renesas_dbsc5_ecc_priv {
+ void __iomem *regs;
+};
+
+static void ecm_reg_unlock(void)
+{
+ writel(0xacce0001, ECMWPCNTR);
+}
+
+static void ecm_reg_lock(void)
+{
+ writel(0xacce0000, ECMWPCNTR);
+}
+
+static void ecm_reg_write(u32 adr, u32 val)
+{
+ writel(0xacce0000 | (adr & 0xffff), ECMWACNTR);
+ writel(val, adr);
+}
+
+static int renesas_dbsc5_ecc_probe(struct udevice *dev)
+{
+ int i;
+
+ ecm_reg_unlock();
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++) {
+ writel(DBSYSCNT_ENABLE, DBSC_D_BASE(i) + DBSYSCNT);
+ writel(DBSYSCNT_ENABLE, DBSC_A_BASE(i) + DBSYSCNT);
+ }
+
+ ecm_reg_write(ECMERRINCR0, readl(ECMERRINCR0) | 0xAAA);
+ ecm_reg_write(ECMERROMKR0, readl(ECMERROMKR0) | 0xAAA);
+ ecm_reg_write(ECMERRCTLR0, readl(ECMERRCTLR0) | 0xAAA);
+ ecm_reg_write(ECMERRINCR6, readl(ECMERRINCR6) | 0xA000);
+ ecm_reg_write(ECMERROMKR6, readl(ECMERROMKR6) | 0xA000);
+ ecm_reg_write(ECMERRCTLR6, readl(ECMERRCTLR6) | 0xA000);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(0xcccc, DBSC_A_BASE(i) + DBFSDRAMECCAREA00);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(DBACEN_ACCESS_DISABLE, DBSC_A_BASE(i) + DBACEN);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(0, DBSC_A_BASE(i) + DBFSCONF00A);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(0, DBSC_A_BASE(i) + DBFSCONF01A);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(0xcccb, DBSC_A_BASE(i) + DBFSCONF02A);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(0x1, DBSC_A_BASE(i) + DBFSCTRL01A);
+
+ u32 fsstat;
+ do {
+ fsstat = 0x1;
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ fsstat &= readl(DBSC_A_BASE(i) + DBFSSTAT01A);
+ } while (!(fsstat & 0x1));
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(DBACEN_ACCESS_ENABLE, DBSC_A_BASE(i) + DBACEN);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ setbits_le32(DBSC_A_BASE(i) + DBFSCONFAXI0, 0x100);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(0xff00ff00, DBSC_A_BASE(i) + DBFSINTENB02A);
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++)
+ writel(0xffffffff, DBSC_A_BASE(i) + DBFSINTENB04A);
+
+ ecm_reg_lock();
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++) {
+ writel(DBSYSCNT_DISABLE, DBSC_D_BASE(i) + DBSYSCNT);
+ writel(DBSYSCNT_DISABLE, DBSC_A_BASE(i) + DBSYSCNT);
+ }
+
+ return 0;
+}
+
+static int renesas_dbsc5_ecc_of_to_plat(struct udevice *dev)
+{
+ struct renesas_dbsc5_ecc_priv *priv = dev_get_priv(dev);
+
+ priv->regs = dev_read_addr_ptr(dev);
+ if (!priv->regs)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int renesas_dbsc5_ecc_get_info(struct udevice *dev,
+ struct ram_info *info)
+{
+ struct renesas_dbsc5_ecc_priv *priv = dev_get_priv(dev);
+
+ info->base = (phys_addr_t)priv->regs;
+ info->size = 32 * SZ_1M;
+
+ return 0;
+}
+
+static const struct ram_ops renesas_dbsc5_ecc_ops = {
+ .get_info = renesas_dbsc5_ecc_get_info,
+};
+
+static const struct udevice_id renesas_dbsc5_ecc_ids[] = {
+ { .compatible = "renesas,r8a78000-ecc" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(renesas_dbsc5_ecc) = {
+ .name = "dbsc5_ecc",
+ .id = UCLASS_RAM,
+ .of_match = renesas_dbsc5_ecc_ids,
+ .of_to_plat = renesas_dbsc5_ecc_of_to_plat,
+ .ops = &renesas_dbsc5_ecc_ops,
+ .probe = renesas_dbsc5_ecc_probe,
+ .priv_auto = sizeof(struct renesas_dbsc5_ecc_priv),
+};
diff --git a/drivers/ram/renesas/dbsc5/qos.c b/drivers/ram/renesas/dbsc5/qos.c
index 56a60b987af..a9fc0b1439a 100644
--- a/drivers/ram/renesas/dbsc5/qos.c
+++ b/drivers/ram/renesas/dbsc5/qos.c
@@ -9,7 +9,7 @@
#include <hang.h>
#include <linux/sizes.h>
#include <ram.h>
-#include "dbsc5.h"
+#include "r8a779g0-dbsc5.h"
/* AXMM */
#define AXMM_ADSPLCR0 0x4008
diff --git a/drivers/ram/renesas/dbsc5/dbsc5.c b/drivers/ram/renesas/dbsc5/r8a779g0-dbsc5.c
index 4cbc6aeda43..b57c885fc59 100644
--- a/drivers/ram/renesas/dbsc5/dbsc5.c
+++ b/drivers/ram/renesas/dbsc5/r8a779g0-dbsc5.c
@@ -10,7 +10,7 @@
#include <errno.h>
#include <linux/sizes.h>
#include <ram.h>
-#include "dbsc5.h"
+#include "r8a779g0-dbsc5.h"
static int renesas_dbsc5_probe(struct udevice *dev)
{
diff --git a/drivers/ram/renesas/dbsc5/dbsc5.h b/drivers/ram/renesas/dbsc5/r8a779g0-dbsc5.h
index bf22fcb8c11..592c9badbd7 100644
--- a/drivers/ram/renesas/dbsc5/dbsc5.h
+++ b/drivers/ram/renesas/dbsc5/r8a779g0-dbsc5.h
@@ -3,8 +3,8 @@
* Copyright (C) 2024 Renesas Electronics Corp.
*/
-#ifndef __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__
-#define __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__
+#ifndef __DRIVERS_RAM_RENESAS_DBSC5_R8A779G0_DBSC5_H__
+#define __DRIVERS_RAM_RENESAS_DBSC5_R8A779G0_DBSC5_H__
/*
* DBSC5 ... 0xe678_0000..0xe67fffff
@@ -26,4 +26,4 @@ struct renesas_dbsc5_data {
const char *otp_node;
};
-#endif /* __DRIVERS_RAM_RENESAS_DBSC5_DBSC5_H__ */
+#endif /* __DRIVERS_RAM_RENESAS_DBSC5_R8A779G0_DBSC5_H__ */
diff --git a/drivers/ram/renesas/dbsc5/dram.c b/drivers/ram/renesas/dbsc5/r8a779g0-dram.c
index 3ed02e11f9e..8dd4e321849 100644
--- a/drivers/ram/renesas/dbsc5/dram.c
+++ b/drivers/ram/renesas/dbsc5/r8a779g0-dram.c
@@ -4,14 +4,14 @@
*/
#include <asm/io.h>
-#include <dbsc5.h>
+#include <r8a779g0-dbsc5.h>
#include <dm.h>
#include <errno.h>
#include <hang.h>
#include <ram.h>
#include <linux/iopoll.h>
#include <linux/sizes.h>
-#include "dbsc5.h"
+#include "r8a779g0-dbsc5.h"
/* Number of array elements in Data Slice */
#define DDR_PHY_SLICE_REGSET_SIZE_V4H 0x100
diff --git a/drivers/ram/renesas/dbsc5/r8a78000-dbsc5.c b/drivers/ram/renesas/dbsc5/r8a78000-dbsc5.c
new file mode 100644
index 00000000000..b6b4ed8a5c0
--- /dev/null
+++ b/drivers/ram/renesas/dbsc5/r8a78000-dbsc5.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ *
+ * Portions Copyright (C) 2026 Synopsys, Inc. Used with permission. All rights reserved.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <errno.h>
+#include <linux/sizes.h>
+#include <ram.h>
+#include "r8a78000-dbsc5.h"
+
+static int renesas_dbsc5_probe(struct udevice *dev)
+{
+ struct udevice *ddev, *vdev, *edev;
+ int ret;
+
+ ret = uclass_get_device_by_name(UCLASS_RAM, "dbsc5_dram", &ddev);
+ if (ret)
+ return ret;
+
+ ret = uclass_get_device_by_name(UCLASS_RAM, "ram@b8940000", &vdev);
+ if (ret)
+ return ret;
+
+ ret = uclass_get_device_by_name(UCLASS_RAM, "dbsc5_ecc", &edev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int renesas_dbsc5_bind(struct udevice *dev)
+{
+ struct udevice *ramdev, *eccdev;
+ struct driver *ramdrv, *eccdrv;
+ int ret;
+
+ ramdrv = lists_driver_lookup_name("dbsc5_dram");
+ if (!ramdrv)
+ return -ENOENT;
+
+ eccdrv = lists_driver_lookup_name("dbsc5_ecc");
+ if (!eccdrv)
+ return -ENOENT;
+
+ ret = device_bind_with_driver_data(dev, ramdrv, "dbsc5_dram",
+ dev_get_driver_data(dev),
+ dev_ofnode(dev), &ramdev);
+ if (ret)
+ return ret;
+
+ ret = device_bind_with_driver_data(dev, eccdrv, "dbsc5_ecc", 0,
+ dev_ofnode(dev), &eccdev);
+ if (ret)
+ device_unbind(ramdev);
+
+ return ret;
+}
+
+static const struct udevice_id renesas_dbsc5_ids[] = {
+ { .compatible = "renesas,r8a78000-dbsc", },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(renesas_dbsc5) = {
+ .name = "dbsc5",
+ .id = UCLASS_NOP,
+ .of_match = renesas_dbsc5_ids,
+ .bind = renesas_dbsc5_bind,
+ .probe = renesas_dbsc5_probe,
+};
diff --git a/drivers/ram/renesas/dbsc5/r8a78000-dbsc5.h b/drivers/ram/renesas/dbsc5/r8a78000-dbsc5.h
new file mode 100644
index 00000000000..b8c9a6f81fa
--- /dev/null
+++ b/drivers/ram/renesas/dbsc5/r8a78000-dbsc5.h
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ *
+ * Portions Copyright (C) 2026 Synopsys, Inc. Used with permission. All rights reserved.
+ */
+
+#ifndef __DRIVERS_RAM_RENESAS_DBSC5_R8A78000_DBSC5_H__
+#define __DRIVERS_RAM_RENESAS_DBSC5_R8A78000_DBSC5_H__
+
+struct renesas_dbsc5_data {
+ const char *clock_node;
+ const char *reset_node;
+ const char *otp_node;
+};
+
+#endif /* __DRIVERS_RAM_RENESAS_DBSC5_R8A78000_DBSC5_H__ */
diff --git a/drivers/ram/renesas/dbsc5/r8a78000-dram.c b/drivers/ram/renesas/dbsc5/r8a78000-dram.c
new file mode 100644
index 00000000000..f1c12901d52
--- /dev/null
+++ b/drivers/ram/renesas/dbsc5/r8a78000-dram.c
@@ -0,0 +1,2795 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ *
+ * Portions Copyright (C) 2026 Synopsys, Inc. Used with permission. All rights reserved.
+ */
+
+#include <asm/io.h>
+#include <r8a78000-dbsc5.h>
+#include <dm.h>
+#include <errno.h>
+#include <hang.h>
+#include <ram.h>
+#include <linux/iopoll.h>
+#include <linux/sizes.h>
+#include "r8a78000-dbsc5.h"
+#include "r8a78000-dram.h"
+
+#define DBSC5_PHYNUM_CNT 8
+#define DBSC5_DBSC_CNT 8
+#define DBSC5_PLL3_CNT 4
+
+/* Minimum value table for JS1 configuration table that can be taken */
+#define JS1_USABLEC_SPEC_LO 5
+/* Maximum value table for JS1 configuration table that can be taken */
+#define JS1_USABLEC_SPEC_HI 14
+/* The number of JS1 setting table */
+#define JS1_FREQ_TBL_NUM 15
+/* Macro to set the value of MR1 */
+#define JS1_MR1(f) ((f) << 4) /* CK mode = 0B */
+/* Macro to set the value of MR2 */
+#define JS1_MR2(f) (((f) << 4) | (f))
+
+#define JS2_tSR 0 /* Element for self refresh */
+#define JS2_tXP 1 /* Exit power-down mode to first valid command */
+#define JS2_tRCD 2 /* Active to read or write delay */
+#define JS2_tRPpb 3 /* Minimum Row Precharge Delay Time */
+#define JS2_tRPab 4 /* Minimum Row Precharge Delay Time */
+#define JS2_tRAS 5 /* ACTIVE-to-PRECHARGE command */
+#define JS2_tWTR_S 6 /* Internal WRITE-to-READ command delay */
+#define JS2_tWTR_L 7 /* Internal WRITE-to-READ command delay */
+#define JS2_tRRD 8 /* Active bank a to active bank b command */
+#define JS2_tPPD 9 /* Precharge Power Down */
+#define JS2_tFAW 10 /* Four bank ACT window */
+#define JS2_tMRR 11 /* Mode Register Read */
+#define JS2_tMRW 12 /* Mode Register Write */
+#define JS2_tMRD 13 /* LOAD MODE REGISTER command cycle time */
+#define JS2_tZQCALns 14 /* ZQ Calibration */
+#define JS2_tZQLAT 15 /* ZQ Latency */
+#define JS2_tODTon_min 16 /* Minimum time on die termination */
+#define JS2_tPDN_DSM 17 /* Recommended minimum time for Deep Sleep Mode duration */
+#define JS2_tXSR_DSM 18 /* Required time to be fully re-powered up from Deep Sleep Mode */
+#define JS2_tXDSM_XP 19 /* Delay from Deep Sleep Mode Exit to Power-Down Exit */
+#define JS2_tWCK2DQI_HF 20 /* Setting value of DQ to WCK input offset */
+#define JS2_tWCK2DQO_HF 21 /* Setting value of WCK to DQ output offset */
+#define JS2_tWCK2DQI_LF 22 /* Setting value of DQ to WCK input offset */
+#define JS2_tWCK2DQO_LF 23 /* Setting value of WCK to DQ output offset */
+#define JS2_tOSCODQI 24 /* Delay time from Stop WCK2DQI Interval Oscillator command to Mode Register Readout */
+#define JS2_tOSCODQO 25
+#define JS2_tDQ72DQns 26 /* Reception time to change the value fof REF(CA) for Command Bus Training Mode2 */
+#define JS2_tCAENTns 27 /* Reception time to change the value fof REF(CA) for Command Bus Training Mode1 */
+#define JS2_tCSCAL 28 /* Minimum CA Low Duration time */
+#define JS2_tWCKSTOP 29
+#define JS2_tpbR2act 30
+#define JS2_TBLCNT 31 /* The number of table */
+
+#define JS2_tRCpb JS2_TBLCNT /* ACTIVATE-to-ACTIVATE command period with per bank precharge */
+#define JS2_tRCab (JS2_TBLCNT + 1) /* ACTIVATE-to-ACTIVATE command period with all bank precharge */
+#define JS2_tRFCab (JS2_TBLCNT + 2) /* Refresh Cycle Time with All Banks */
+#define JS2_tRBTP (JS2_TBLCNT + 3) /* READ Burst end to PRECHARGE command delay */
+#define JS2_tXSR (JS2_TBLCNT + 4) /* Exit Self Refresh to Valid commands */
+#define JS2_tPDN (JS2_TBLCNT + 5)
+#define JS2_tWLWCKOFF (JS2_TBLCNT + 6)
+#define JS2_tRFCpb (JS2_TBLCNT + 7)
+#define JS2_tpbR2pbR (JS2_TBLCNT + 8)
+#define JS2_tRFMab (JS2_TBLCNT + 9)
+#define JS2_tRFMpb (JS2_TBLCNT + 10)
+#define JS2_CNT (JS2_TBLCNT + 11)
+
+#define JS2_DERATE 0
+#define DBSC_REFINT 1920
+#define PERIODIC_TRAINING_INTERVAL 20000
+
+#define DBMEMCONF_REG(d3, row, BG, bank, col, dw) \
+ (((d3) << 30) | ((row) << 24) | ((BG) << 20) | \
+ ((bank) << 16) | ((col) << 8) | (dw))
+
+#define DBMEMCONF_REGD(density) \
+ (DBMEMCONF_REG(((density) % 2), (((density) + 1) / 2) + (28 - 2 - 2 - 10 - 1), \
+ 2, 2, 10, 1))
+
+struct jedec_spec1 {
+ u32 fx3;
+ u32 RLset0;
+ u32 RLset1;
+ u32 RLset2;
+ u32 WLsetA;
+ u32 WLsetB;
+ u32 nWR;
+ u32 nRBTP;
+ u32 ODTLon;
+ u32 MR1;
+ u32 MR2;
+ u32 WCKENLR0;
+ u32 WCKENLR1;
+ u32 WCKENLW;
+ u32 WCKENLF;
+ u32 WCKPRESTA;
+ u32 WCKPRETGLR;
+ u32 tRRD;
+ u32 tFAW;
+};
+
+static const struct jedec_spec1 js1[JS1_FREQ_TBL_NUM] = {
+ /* fx3,RL0,RL1,RL2,WLA.WLB.nWR.nRBTP,ODTLon */
+ { 800, 3, 3, 3, 2, 2, 3, 0, 1, JS1_MR1(0), JS1_MR2(0), 0, 0, 0, 0, 1, 3, 3750, 15000 }, /* 533.333Mbps */
+ { 1600, 4, 4, 4, 2, 3, 5, 0, 1, JS1_MR1(1), JS1_MR2(1), 0, 0, 0, 0, 1, 4, 3750, 15000 }, /* 1066.666Mbps */
+ { 2400, 5, 5, 6, 3, 4, 7, 0, 2, JS1_MR1(2), JS1_MR2(2), 1, 1, 1, 1, 1, 4, 3750, 15000 }, /* 1600.000Mbps */
+ { 3200, 6, 7, 7, 4, 5, 10, 0, 2, JS1_MR1(3), JS1_MR2(3), 1, 2, 1, 1, 2, 4, 3750, 15000 }, /* 2133.333Mbps */
+ { 4000, 8, 8, 9, 4, 7, 12, 1, 2, JS1_MR1(4), JS1_MR2(4), 2, 2, 1, 1, 2, 5, 3750, 15000 }, /* 2666.666Mbps */
+ { 4800, 9, 10, 10, 5, 8, 14, 1, 3, JS1_MR1(5), JS1_MR2(5), 3, 4, 2, 1, 2, 5, 3750, 15000 }, /* 3200.000Mbps */
+ { 5600, 10, 11, 12, 6, 9, 16, 2, 4, JS1_MR1(6), JS1_MR2(6), 3, 4, 2, 1, 3, 5, 3750, 15000 }, /* 3733.333Mbps */
+ { 6400, 12, 13, 14, 6, 11, 19, 2, 3, JS1_MR1(7), JS1_MR2(7), 4, 5, 2, 1, 3, 6, 3750, 15000 }, /* 4266.666Mbps */
+ { 7200, 13, 14, 15, 7, 12, 21, 3, 4, JS1_MR1(8), JS1_MR2(8), 5, 6, 3, 2, 3, 6, 3750, 15000 }, /* 4800.000Mbps */
+ { 8250, 15, 16, 17, 8, 14, 24, 4, 5, JS1_MR1(9), JS1_MR2(9), 6, 7, 3, 2, 4, 6, 3750, 15000 }, /* 5500.000Mbps */
+ { 9000, 16, 17, 19, 9, 15, 26, 4, 6, JS1_MR1(10), JS1_MR2(10), 6, 7, 4, 2, 4, 7, 3750, 15000 }, /* 6000.000Mbps */
+ { 9600, 17, 18, 20, 9, 16, 28, 4, 6, JS1_MR1(11), JS1_MR2(11), 7, 8, 4, 2, 4, 7, 3750, 15000 }, /* 6400.000Mbps */
+ { 11250, 20, 22, 24, 11, 19, 32, 6, 7, JS1_MR1(12), JS1_MR2(12), 7, 9, 5, 3, 5, 9, 3750, 15000 }, /* 7500.000Mbps */
+ { 12800, 23, 25, 26, 12, 22, 37, 6, 8, JS1_MR1(13), JS1_MR2(13), 8, 10, 5, 3, 6, 10, 3750, 15000 }, /* 8533.333Mbps */
+ { 14400, 25, 28, 29, 14, 24, 41, 7, 9, JS1_MR1(14), JS1_MR2(14), 8, 11, 6, 3, 7, 11, 3330, 13320 } /* 9600.000Mbps */
+};
+
+struct jedec_spec2 {
+ u32 ps;
+ u32 cyc;
+};
+
+static const struct jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = {
+ {
+ { 15000, 2 }, /* tSR */
+ { 7000, 3 }, /* tXP */
+ { 18000, 2 }, /* tRCD */
+ { 18000, 2 }, /* tRPpb */
+ { 21000, 2 }, /* tRPab */
+ { 42000, 3 }, /* tRAS */
+ { 6250, 4 }, /* tWTR_S */
+ { 12000, 4 }, /* tWTR_L */
+ { 0, 2 }, /* tRRD */
+ { 0, 2 }, /* tPPD */
+ { 0, 0 }, /* tFAW */
+ { 0, 4 }, /* tMRR */
+ { 10000, 5 }, /* tMRW */
+ { 14000, 5 }, /* tMRD */
+ { 1500, 0 }, /* tZQCALns */
+ { 30000, 4 }, /* tZQLAT */
+ { 1500, 0 }, /* tODTon_min */
+ { 4000, 0 }, /* tPDN_DSMus */
+ { 200, 0 }, /* tXSR_DSMus */
+ { 190, 0 }, /* tXDSM_XPus */
+ { 700, 0 }, /* tWCK2DQI_HF */
+ { 1600, 0 }, /* tWCK2DQO_HF */
+ { 900, 0 }, /* tWCK2DQI_LF */
+ { 1900, 0 }, /* tWCK2DQO_LF */
+ { 40000, 8 }, /* tOSCODQI */
+ { 40000, 8 }, /* tOSCODQO */
+ { 125, 0 }, /* tDQ72DQns */
+ { 250, 0 }, /* tCAENTns */
+ { 1750, 0 }, /* tCSCAL */
+ { 6000, 2 }, /* tWCKSTOP */
+ { 7500, 0 }, /* tpbR2act */
+ }, {
+ { 15000, 2 }, /* tSR */
+ { 7000, 3 }, /* tXP */
+ { 19875, 2 }, /* tRCD */
+ { 19875, 2 }, /* tRPpb */
+ { 22875, 2 }, /* tRPab */
+ { 43875, 3 }, /* tRAS */
+ { 6250, 4 }, /* tWTR_S */
+ { 12000, 4 }, /* tWTR_L */
+ { 0, 2 }, /* tRRD */
+ { 0, 2 }, /* tPPD */
+ { 0, 0 }, /* tFAW */
+ { 0, 4 }, /* tMRR */
+ { 10000, 5 }, /* tMRW */
+ { 14000, 5 }, /* tMRD */
+ { 1500, 0 }, /* tZQCALns */
+ { 30000, 4 }, /* tZQLAT */
+ { 1500, 0 }, /* tODTon_min */
+ { 4000, 0 }, /* tPDN_DSMus */
+ { 200, 0 }, /* tXSR_DSMus */
+ { 190, 0 }, /* tXDSM_XPus */
+ { 715, 0 }, /* tWCK2DQI_HF */
+ { 1635, 0 }, /* tWCK2DQO_HF */
+ { 920, 0 }, /* tWCK2DQI_LF */
+ { 1940, 0 }, /* tWCK2DQO_LF */
+ { 40000, 8 }, /* tOSCODQI */
+ { 40000, 8 }, /* tOSCODQO */
+ { 125, 0 }, /* tDQ72DQns */
+ { 250, 0 }, /* tCAENTns */
+ { 1750, 0 }, /* tCSCAL */
+ { 6000, 2 }, /* tWCKSTOP */
+ { 7500, 0 }, /* tpbR2act */
+ }
+};
+
+static const u32 jedec_spec2_tRFC_ab[9] = {
+ /* 2Gb, 3Gb, 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb, 32Gb */
+ 130, 180, 180, 210, 210, 280, 280, 380, 380
+};
+
+static const u32 jedec_spec2_tRFC_pb[9] = {
+ /* 2Gb, 3Gb, 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb, 32Gb */
+ 60, 90, 90, 120, 120, 140, 140, 190, 190
+};
+
+static const u32 jedec_spec2_tpbR2pbR[9] = {
+ /* 2Gb, 3Gb, 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb, 32Gb */
+ 60, 90, 90, 90, 90, 90, 90, 90, 90
+};
+
+static const u32 jedec_spec2_tRFM_ab[9] = {
+ /* 2Gb, 3Gb, 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb, 32Gb */
+ 0, 0, 0, 0, 210, 280, 280, 380, 380
+};
+
+static const u32 jedec_spec2_tRFM_pb[9] = {
+ /* 2Gb, 3Gb, 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb, 32Gb */
+ 0, 0, 0, 0, 170, 190, 190, 260, 260
+};
+
+/* System registers */
+#define SYSSS_TOP_BASE 0xc6480000
+#define SYSSS_ZB3CKCR0 (SYSSS_TOP_BASE + 0x10a0)
+#define SYSSS_ZB3CKCR1 (SYSSS_TOP_BASE + 0x10a4)
+#define SYSSS_ZB3CKCR_KICK BIT(31)
+#define SYSSS_ZB3CKCR_PHYx(ch) ((0x7 * ((ch) & 0x1)) + (0x8 * ((ch) & 0x2)))
+#define SYSSS_PLL1_1_CR0 (SYSSS_TOP_BASE + 0x1114)
+#define SYSSS_PLL1_1DCR (SYSSS_TOP_BASE + 0x127c)
+#define SYSSS_PLL3_x_CR0(ch) (SYSSS_TOP_BASE + 0x1180 + ((ch) * 0xc))
+#define SYSSS_PLL3_x_CR1(ch) (SYSSS_TOP_BASE + 0x1184 + ((ch) * 0xc))
+#define SYSSS_PLL3_x_CR2(ch) (SYSSS_TOP_BASE + 0x1188 + ((ch) * 0xc))
+#define SYSSS_PLL3_x_DCR(ch) (SYSSS_TOP_BASE + 0x12c4 + ((ch) * 0x8))
+#define SYSSS_PLL6_CR0 (SYSSS_TOP_BASE + 0x11c8)
+#define SYSSS_PLL3_xSCR(ch) (SYSSS_TOP_BASE + 0x12c0 + ((ch) * 0x8))
+#define SYSSS_CLKTOPPKCPROT0 (SYSSS_TOP_BASE + 0x1370)
+#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva)))
+
+/* MDLC registers */
+#define MODULE_CONTROL_DDRx_BASE(ch) (0xe8000000 + ((ch) * 0x80000))
+#define MODULE_CONTROL_DDRFI_BASE 0xc6480000
+#define MODULE_CONTROL_MDLC12PKCPROT1 (MODULE_CONTROL_DDRFI_BASE + 0xCF4)
+#define MODULE_CONTROL_MDLC0xPKCPROT1(ch) (MODULE_CONTROL_DDRx_BASE(ch) + 0xCF4)
+#define MODULE_CONTROL_MDLC15MSRES8 (MODULE_CONTROL_DDRFI_BASE + 0x920)
+#define MODULE_CONTROL_MDLC0xMSRES1(ch) (MODULE_CONTROL_DDRx_BASE(ch) + 0x904)
+#define MODULE_CONTROL_MDLC0xMSRES3(ch) (MODULE_CONTROL_DDRx_BASE(ch) + 0x90C)
+#define MODULE_CONTROL_MDLC15MSRESS8 (MODULE_CONTROL_DDRFI_BASE + 0x980)
+#define MODULE_CONTROL_MDLC0xMSRESS1(ch) (MODULE_CONTROL_DDRx_BASE(ch) + 0x964)
+#define MODULE_CONTROL_MDLC0xMSRESS3(ch) (MODULE_CONTROL_DDRx_BASE(ch) + 0x96C)
+#define MODULE_STANDBY 0
+#define MODULE_RUN 3
+
+/* DBSC5 registers */
+#define DBSC_A_BASE 0xE9800000
+#define DBSC_D_BASE 0xE9900000
+
+#define DBSC_DBSYSCONF0 (DBSC_A_BASE + 0x0)
+#define DBSC_DBSYSCONF1 (DBSC_D_BASE + 0x0)
+#define DBSC_DBSYSCONF1A (DBSC_A_BASE + 0x4)
+#define DBSC_DBSYSCONF2 (DBSC_D_BASE + 0x4)
+#define DBSC_DBPHYCONF0 (DBSC_D_BASE + 0x8)
+#define DBSC_DBSYSCONF2A (DBSC_A_BASE + 0x8)
+#define DBSC_DBMEMKIND (DBSC_D_BASE + 0x20)
+#define DBSC_DBMEMKINDA (DBSC_A_BASE + 0x20)
+#define DBSC_DBMEMCONF(ch, cs) \
+ (DBSC_D_BASE + 0x30 + (0x2000 * ((ch) & 0xE)) + (0x10 * ((ch) & 0x1)) + (0x4 * (cs)))
+#define DBSC_DBMEMCONFA(ch, cs) \
+ (DBSC_A_BASE + 0x30 + (0x4000 * ((ch) & 0xE)) + (0x10 * ((ch) & 0x1)) + (0x4 * (cs)))
+#define DBSC_DBSYSCNT0 (DBSC_D_BASE + 0x100)
+#define DBSC_DBSYSCNT0A (DBSC_A_BASE + 0x100)
+#define DBSC_DBSYSCNT1A (DBSC_A_BASE + 0x104)
+#define DBSC_DBACEN (DBSC_A_BASE + 0x200)
+#define DBSC_DBRFEN (DBSC_D_BASE + 0x204)
+#define DBSC_DBCMD (DBSC_D_BASE + 0x208)
+#define DBSC_DBWAIT (DBSC_D_BASE + 0x210)
+#define DBSC_DBTR(x) (DBSC_D_BASE + 0x300 + (0x4 * (x)))
+#define DBSC_DBBL (DBSC_D_BASE + 0x400)
+#define DBSC_DBBLA (DBSC_A_BASE + 0x400)
+#define DBSC_DBRFCNF1 (DBSC_D_BASE + 0x414)
+#define DBSC_DBRFCNF2 (DBSC_D_BASE + 0x418)
+#define DBSC_DBCALCNF (DBSC_D_BASE + 0x424)
+#define DBSC_DBSNOOPC (DBSC_D_BASE + 0x42C)
+#define DBSC_DBRNK(x) (DBSC_D_BASE + 0x430 + (0x4 * (x)))
+#define DBSC_DBDBICNT (DBSC_D_BASE + 0x518)
+#define DBSC_DBDFIPMSTRCNF (DBSC_D_BASE + 0x520)
+#define DBSC_DBDFICUPDCNF (DBSC_D_BASE + 0x540)
+#define DBSC_DBDFISTAT(ch) \
+ (DBSC_D_BASE + 0x600 + (0x2000 * ((ch) & 0xE)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBDFICNT(ch) \
+ (DBSC_D_BASE + 0x604 + (0x2000 * ((ch) & 0xE)) + (0x40 * ((ch) & 0x1)))
+#define DBSC_DBPDSTAT01(ch) (DBSC_D_BASE + 0x634 + (0x4000 * (ch)))
+#define DBSC_DBBUS0CNF1 (DBSC_A_BASE + 0x804)
+#define DBSC_DBBCAMDIS (DBSC_A_BASE + 0x9FC)
+#define DBSC_DBSCHRW(x) (DBSC_A_BASE + 0x1020 + (0x4 * (x)))
+#define DBSC_DBSCHTR0 (DBSC_A_BASE + 0x1030)
+#define DBSC_DBSCHFCTST(x) (DBSC_A_BASE + 0x1040 + (0x4 * (x)))
+
+/* DDR PHY registers */
+#define DDR_PHY_BASE(ch) (0xA0000000 + (0x1000000 * (ch)))
+#define DDR_PHY_DMA_TRANS_BASE(ch) (0xE0000000 + (0x1000000 * (ch)))
+
+#define PHY_HMAC_BASE(n) ((n) * 0x1000)
+#define PHY_HMAC_TXSLEWAC(n) (PHY_HMAC_BASE(n) + 0x6d)
+#define PHY_HMAC_TXIMPEDANCEAC(n) (PHY_HMAC_BASE(n) + 0x70)
+#define PHY_HMAC_ODTIMPEDANCEAC(n) (PHY_HMAC_BASE(n) + 0x79)
+
+#define PHY_DBYTE_BASE(n) (0x10000 + ((n) * 0x1000))
+#define PHY_DBYTE_ENABLEWRITELINKECC(n) (PHY_DBYTE_BASE(n) + 0x01)
+#define PHY_DBYTE_DQ0LNSEL(n) (PHY_DBYTE_BASE(n) + 0x80)
+#define PHY_DBYTE_DQ1LNSEL(n) (PHY_DBYTE_BASE(n) + 0x81)
+#define PHY_DBYTE_DQ2LNSEL(n) (PHY_DBYTE_BASE(n) + 0x82)
+#define PHY_DBYTE_DQ3LNSEL(n) (PHY_DBYTE_BASE(n) + 0x83)
+#define PHY_DBYTE_DQ4LNSEL(n) (PHY_DBYTE_BASE(n) + 0x84)
+#define PHY_DBYTE_DQ5LNSEL(n) (PHY_DBYTE_BASE(n) + 0x85)
+#define PHY_DBYTE_DQ6LNSEL(n) (PHY_DBYTE_BASE(n) + 0x86)
+#define PHY_DBYTE_DQ7LNSEL(n) (PHY_DBYTE_BASE(n) + 0x87)
+#define PHY_DBYTE_DQ8LNSEL(n) (PHY_DBYTE_BASE(n) + 0x88)
+#define PHY_DBYTE_PPTCTLSTATIC(n) (PHY_DBYTE_BASE(n) + 0xa3)
+
+#define PHY_AC_BASE(n) (0x30000 + ((n) * 0x1000))
+#define PHY_AC_MAPCA0TODFI(n) (PHY_AC_BASE(n) + 0x90)
+#define PHY_AC_MAPCA1TODFI(n) (PHY_AC_BASE(n) + 0x91)
+#define PHY_AC_MAPCA2TODFI(n) (PHY_AC_BASE(n) + 0x92)
+#define PHY_AC_MAPCA3TODFI(n) (PHY_AC_BASE(n) + 0x93)
+#define PHY_AC_MAPCA4TODFI(n) (PHY_AC_BASE(n) + 0x94)
+#define PHY_AC_MAPCA5TODFI(n) (PHY_AC_BASE(n) + 0x95)
+#define PHY_AC_MAPCA6TODFI(n) (PHY_AC_BASE(n) + 0x96)
+#define PHY_AC_ACLNDISABLE(n) (PHY_AC_BASE(n) + 0xac)
+#define PHY_AC_DFICLKACLNDIS(n) (PHY_AC_BASE(n) + 0xad)
+#define PHY_AC_PCLKACLNDIS(n) (PHY_AC_BASE(n) + 0xae)
+
+#define PHY_APB_BASE 0x58000
+#define PHY_APB_DRAMFREQ (PHY_APB_BASE + 0x01)
+#define PHY_APB_DCAOPTS (PHY_APB_BASE + 0x02)
+#define PHY_APB_SEQUENCECTRL (PHY_APB_BASE + 0x04)
+#define PHY_APB_HDTCTRL (PHY_APB_BASE + 0x04)
+#define PHY_APB_RXDFEOPT (PHY_APB_BASE + 0x07)
+#define PHY_APB_CSPRESENTCHA (PHY_APB_BASE + 0x09)
+#define PHY_APB_CSPRESENTCHB (PHY_APB_BASE + 0x10)
+#define PHY_APB_MR1_A0 (PHY_APB_BASE + 0x16)
+#define PHY_APB_MR1_A1 (PHY_APB_BASE + 0x16)
+#define PHY_APB_MR1_B0 (PHY_APB_BASE + 0x17)
+#define PHY_APB_MR1_B1 (PHY_APB_BASE + 0x17)
+#define PHY_APB_MR2_A0 (PHY_APB_BASE + 0x17)
+#define PHY_APB_MR2_A1 (PHY_APB_BASE + 0x17)
+#define PHY_APB_MR2_B0 (PHY_APB_BASE + 0x18)
+#define PHY_APB_MR2_B1 (PHY_APB_BASE + 0x18)
+#define PHY_APB_MR3_A0 (PHY_APB_BASE + 0x18)
+#define PHY_APB_MR3_A1 (PHY_APB_BASE + 0x18)
+#define PHY_APB_MR3_B0 (PHY_APB_BASE + 0x19)
+#define PHY_APB_MR3_B1 (PHY_APB_BASE + 0x19)
+#define PHY_APB_MR11_A0 (PHY_APB_BASE + 0x1A)
+#define PHY_APB_MR11_A1 (PHY_APB_BASE + 0x1A)
+#define PHY_APB_MR11_B0 (PHY_APB_BASE + 0x1B)
+#define PHY_APB_MR11_B1 (PHY_APB_BASE + 0x1B)
+#define PHY_APB_MR12_A0 (PHY_APB_BASE + 0x1B)
+#define PHY_APB_MR12_A1 (PHY_APB_BASE + 0x1B)
+#define PHY_APB_MR12_B0 (PHY_APB_BASE + 0x1C)
+#define PHY_APB_MR12_B1 (PHY_APB_BASE + 0x1C)
+#define PHY_APB_MR22_A0 (PHY_APB_BASE + 0x25)
+#define PHY_APB_MR22_A1 (PHY_APB_BASE + 0x25)
+#define PHY_APB_MR22_B0 (PHY_APB_BASE + 0x26)
+#define PHY_APB_MR22_B1 (PHY_APB_BASE + 0x26)
+#define PHY_APB_MR24_A0 (PHY_APB_BASE + 0x26)
+#define PHY_APB_MR24_A1 (PHY_APB_BASE + 0x26)
+#define PHY_APB_MR24_B0 (PHY_APB_BASE + 0x27)
+#define PHY_APB_MR24_B1 (PHY_APB_BASE + 0x27)
+#define PHY_APB_MR41_A0 (PHY_APB_BASE + 0x32)
+#define PHY_APB_MR41_A1 (PHY_APB_BASE + 0x32)
+#define PHY_APB_MR41_B0 (PHY_APB_BASE + 0x33)
+#define PHY_APB_MR41_B1 (PHY_APB_BASE + 0x33)
+#define PHY_APB_MR58_A0 (PHY_APB_BASE + 0x34)
+#define PHY_APB_MR58_A1 (PHY_APB_BASE + 0x34)
+#define PHY_APB_MR58_B0 (PHY_APB_BASE + 0x35)
+#define PHY_APB_MR58_B1 (PHY_APB_BASE + 0x35)
+#define PHY_APB_TXDFETRAINOPT (PHY_APB_BASE + 0x3E)
+#define PHY_APB_UPPERLOWERBYTE (PHY_APB_BASE + 0x48)
+#define PHY_APB_ALT_RL (PHY_APB_BASE + 0x48)
+#define PHY_APB_MAIN_RL (PHY_APB_BASE + 0x49)
+#define PHY_APB_RXVREFSTARTPAT (PHY_APB_BASE + 0x4E)
+#define PHY_APB_RXVREFSTARTPRBS (PHY_APB_BASE + 0x4E)
+#define PHY_APB_RXVREFENDPAT (PHY_APB_BASE + 0x4F)
+#define PHY_APB_RXVREFENDPRBS (PHY_APB_BASE + 0x4F)
+#define PHY_APB_RXVREFSTEPPAT (PHY_APB_BASE + 0x50)
+#define PHY_APB_TXVREFSTART (PHY_APB_BASE + 0x50)
+#define PHY_APB_TXVREFEND (PHY_APB_BASE + 0x50)
+#define PHY_APB_TXVREFSTEP (PHY_APB_BASE + 0x51)
+#define PHY_APB_RXVREFSTEPPRBS (PHY_APB_BASE + 0x51)
+#define PHY_APB_RXDFEBITTIMECONTROL (PHY_APB_BASE + 0x59)
+
+#define PHY_HMMAS_BASE 0x60000
+#define PHY_HMMAS_CPLLCTRL1 (PHY_HMMAS_BASE + 0x05)
+#define PHY_HMMAS_CPLLCTRL4 (PHY_HMMAS_BASE + 0x07)
+#define PHY_HMMAS_CPLLCTRL5 (PHY_HMMAS_BASE + 0x08)
+#define PHY_HMMAS_CPLLUPLLPROG0 (PHY_HMMAS_BASE + 0x0d)
+#define PHY_HMMAS_CPLLUPLLPROG1 (PHY_HMMAS_BASE + 0x0e)
+#define PHY_HMMAS_CPLLUPLLPROG2 (PHY_HMMAS_BASE + 0x0f)
+#define PHY_HMMAS_CPLLUPLLPROG3 (PHY_HMMAS_BASE + 0x10)
+
+#define PHY_PPGC_BASE 0x70000
+#define PHY_PPGC_ACSMDONE (PHY_PPGC_BASE + 0x121)
+#define PHY_PPGC_ACSMSTARTADDRXLATVAL0 (PHY_PPGC_BASE + 0x324)
+#define PHY_PPGC_ACSMSTOPADDRXLATVAL0 (PHY_PPGC_BASE + 0x38b)
+#define PHY_PPGC_HWTLPCSENA (PHY_PPGC_BASE + 0x072)
+#define PHY_PPGC_HWTLPCSENB (PHY_PPGC_BASE + 0x073)
+#define PHY_PPGC_HWTCONTROLVAL (PHY_PPGC_BASE + 0x07e)
+#define PHY_PPGC_ACSMRPTCNTOVERRIDE (PHY_PPGC_BASE + 0x145)
+#define PHY_PPGC_ACSMNOPADDR (PHY_PPGC_BASE + 0x18a)
+
+#define PHY_INITENG_BASE 0x90000
+#define PHY_INITENG_SEQ0BDISABLEFLAG0 (PHY_INITENG_BASE + 0x70c)
+#define PHY_INITENG_SEQ0BGPR1 (PHY_INITENG_BASE + 0x801)
+#define PHY_INITENG_SEQ0BDLY0 (PHY_INITENG_BASE + 0x8e0)
+#define PHY_INITENG_SEQ0BGPR14 (PHY_INITENG_BASE + 0x80e)
+#define PHY_INITENG_SEQ0BGPR15 (PHY_INITENG_BASE + 0x80f)
+
+#define PHY_DRTUB_BASE 0xc0000
+#define PHY_DRTUB_PIEINITVECSEL (PHY_DRTUB_BASE + 0x01)
+#define PHY_DRTUB_UCCLKHCLKENABLES (PHY_DRTUB_BASE + 0x80)
+#define PHY_DRTUB_STARTDCCMCLEAR (PHY_DRTUB_BASE + 0x88)
+
+#define PHY_APBONLY_BASE 0xd0000
+#define PHY_APBONLY_MICROCONTMUXSEL (PHY_APBONLY_BASE + 0x00)
+#define PHY_APBONLY_UCTSHADOWREGS (PHY_APBONLY_BASE + 0x04)
+#define PHY_APBONLY_DCTWRITEPROT (PHY_APBONLY_BASE + 0x31)
+#define PHY_APBONLY_UCTWRITEONLYSHADOW (PHY_APBONLY_BASE + 0x32)
+#define PHY_APBONLY_UCTDATWRITEONLYSHADOW (PHY_APBONLY_BASE + 0x34)
+#define PHY_APBONLY_MICRORESET (PHY_APBONLY_BASE + 0x99)
+#define PHY_APBONLY_SEQUENCEROVERRIDE (PHY_APBONLY_BASE + 0xe7)
+
+#define PHY_HMDBYTE_BASE(n) (0xe0000 + ((n) * 0x1000))
+#define PHY_HMDBYTE_VREGCTRL1DQ(n) (PHY_HMDBYTE_BASE(n) + 0x00)
+#define PHY_HMDBYTE_TXDQSLEW(n) (PHY_HMDBYTE_BASE(n) + 0x1c)
+#define PHY_HMDBYTE_TXIMPEDANCEDQ(n) (PHY_HMDBYTE_BASE(n) + 0x2c)
+#define PHY_HMDBYTE_TXIMPEDANCEDQS(n) (PHY_HMDBYTE_BASE(n) + 0x2d)
+#define PHY_HMDBYTE_ODTIMPEDANCEDQ(n) (PHY_HMDBYTE_BASE(n) + 0x2e)
+#define PHY_HMDBYTE_ODTIMPEDANCEDQS(n) (PHY_HMDBYTE_BASE(n) + 0x2f)
+
+/* RENESAS X5H Board (64Gb 1rank x 4pcs) */
+static const struct renesas_dbsc5_board_config renesas_x5h_dbsc5_board_config = {
+ .bdcfg_phyvalid = 0xffff,
+ .bdcfg_tx_drv = 0x77777,
+ .bdcfg_tx_ffc = 0x30000000,
+ .bdcfg_rx_odt = 0x33333,
+ .bdcfg_rx_dfe = 0x0,
+ .bdcfg_tx_odt = 0x43,
+ .bdcfg_tx_ntodt = 0x3,
+ .bdcfg_tx_dfe = 0x0,
+ .bdcfg_rx_dca = 0x1,
+ .bdcfg_rx_drv = 0x6,
+ .bdcfg_rx_emphasis = 0x0,
+ .bdcfg_tx_dca = 0x1,
+ .bdcfg_ca_vref = 0x2e,
+ .bdcfg_rx_vref = 0xff001e,
+ .bdcfg_rx_vref_step = 0xf,
+ .bdcfg_tx_vref = 0x56e0a,
+ .bdcfg_rfm_chk = 0x1,
+ .ch = {
+ [0] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x2641350,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x47583016, 0x85013247 },
+ .bdcfg_dm_swap = { 0x2, 0x6 },
+ },
+ [1] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x3265410,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x54263701, 0x84650312 },
+ .bdcfg_dm_swap = { 0x8, 0x7 },
+ },
+ [2] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x1240635,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x56420713, 0x57802134 },
+ .bdcfg_dm_swap = { 0x8, 0x6 },
+ },
+ [3] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x5462301,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x74560128, 0x58760312 },
+ .bdcfg_dm_swap = { 0x3, 0x4 },
+ },
+ [4] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x4215306,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x45760138, 0x75803124 },
+ .bdcfg_dm_swap = { 0x2, 0x6 },
+ },
+ [5] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x4065321,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x65420371, 0x78560213 },
+ .bdcfg_dm_swap = { 0x8, 0x4 },
+ },
+ [6] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x4612035,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x25481730, 0x56703128 },
+ .bdcfg_dm_swap = { 0x6, 0x4 },
+ },
+ [7] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x5023416,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x54783026, 0x41650238 },
+ .bdcfg_dm_swap = { 0x1, 0x7 },
+ },
+ [8] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x521463,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x76453012, 0x85430127 },
+ .bdcfg_dm_swap = { 0x8, 0x6 },
+ },
+ [9] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x5326041,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x43620781, 0x81653420 },
+ .bdcfg_dm_swap = { 0x5, 0x7 },
+ },
+ [10] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x2104635,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x54763210, 0x75831062 },
+ .bdcfg_dm_swap = { 0x8, 0x4 },
+ },
+ [11] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x3654021,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x74561082, 0x56473012 },
+ .bdcfg_dm_swap = { 0x3, 0x8 },
+ },
+ [12] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x514362,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x45761032, 0x74830126 },
+ .bdcfg_dm_swap = { 0x8, 0x5 },
+ },
+ [13] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x4523016,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x54763021, 0x58470312 },
+ .bdcfg_dm_swap = { 0x8, 0x6 },
+ },
+ [14] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x2315064,
+ .bdcfg_dqs_swap = 0x1,
+ .bdcfg_dq_swap = { 0x43620718, 0x68134207 },
+ .bdcfg_dm_swap = { 0x5, 0x5 },
+ },
+ [15] = {
+ .bdcfg_ddr_density = { 0x6, 0xff },
+ .bdcfg_ca_swap = 0x6315042,
+ .bdcfg_dqs_swap = 0x10,
+ .bdcfg_dq_swap = { 0x47653082, 0x64583012 },
+ .bdcfg_dm_swap = { 0x1, 0x7 },
+ }
+ }
+};
+
+struct renesas_dbsc5_dram_priv {
+ void __iomem *regs;
+
+ /* The board parameter structure of the board */
+ const struct renesas_dbsc5_board_config *dbsc5_board_config;
+
+ /* The board clock frequency */
+ u32 brd_clk;
+ u32 brd_clkdiv;
+ u32 brd_clkdiva;
+ /* The Mbps of DDR */
+ u32 ddr_mbps;
+ u32 ddr_mbpsdiv;
+ /* Value indicating the enabled channel */
+ u32 ddr_phyvalid;
+ u32 ddr_dramvalid;
+ /* Channels used for each memory rank */
+ u32 ch_have_this_cs[CS_CNT];
+ u32 upper_lower_byte[DBSC5_PHYNUM_CNT];
+ u32 link_ecc_en;
+ /* The maximum memory capacity */
+ u32 max_density;
+ /* Index of jedec spec1 setting table you use */
+ u32 js1_ind;
+};
+
+/**
+ * vch_nxt() - Macro for channel selection loop
+ * @dev: DBSC5 device
+ * @pos: Iterator position
+ *
+ * Return the ID of the channel to be used. Check for valid channels
+ * between the value of posn and the maximum number of CHs. If a valid
+ * channel is found, returns the value of that channel.
+ */
+static u32 vch_nxt(struct udevice *dev, u32 pos)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 posn;
+
+ for (posn = pos; posn < DRAM_CH_CNT; posn++)
+ if (priv->ddr_dramvalid & BIT(posn))
+ break;
+
+ return posn;
+}
+
+/**
+ * vphych_nxt() - Macro for PHY channel selection loop
+ * @dev: DBSC5 device
+ * @pos: Iterator position
+ *
+ * Return the ID of the channel to be used. Check for valid channels
+ * between the value of posn and the maximum number of CHs. If a valid
+ * channel is found, returns the value of that channel.
+ */
+static u32 vphych_nxt(struct udevice *dev, u32 pos)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 posn;
+
+ for (posn = pos; posn < DBSC5_PHYNUM_CNT; posn++)
+ if (priv->ddr_phyvalid & BIT(posn))
+ break;
+
+ return posn;
+}
+
+#define foreach_vch(dev, ch) \
+ for ((ch) = vch_nxt((dev), 0); (ch) < DRAM_CH_CNT; (ch) = vch_nxt((dev), (ch) + 1))
+
+#define foreach_vphych(dev, ch) \
+ for ((ch) = vphych_nxt((dev), 0); (ch) < DBSC5_PHYNUM_CNT; (ch) = vphych_nxt((dev), (ch) + 1))
+
+#define foreach_ech(ch) \
+ for (ch = 0; ch < DRAM_CH_CNT; ch++)
+
+/**
+ * dbsc5_soft_delay() - Wait loop number of CPU cycles
+ * @loop: Number of cycles to wait
+ *
+ * This is a cycle counting approximate delay loop, used in very
+ * early code to wait for near future events.
+ */
+static void dbsc5_soft_delay(const int loop)
+{
+ int i;
+
+ for (i = 0; i < loop; i++)
+ asm volatile("nop");
+}
+
+/**
+ * dbsc5_init_pll3() - Set PLL3
+ * @dev: DBSC5 device
+ */
+static void dbsc5_init_pll3(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 data_cr0, data_cr1, data_div, data_dcr_1st, data_dcr_2nd, data_dcr_3rd;
+ u32 ddr_mul, ddr_mul_div, ddr_mul_ni, ddr_mul_nf;
+ const int pll3_frac_mode_threshold = 9000;
+ u32 ssmode, pll3vco, pll3_valid = 0;
+ u32 ddr_zb3ckcr[DBSC5_PHYNUM_CNT];
+ u32 zb3ckcr0, zb3ckcr1;
+ u32 fvv, ch;
+
+ /* Calculate valid PLL3 channel */
+ for (ch = 0; ch < DBSC5_PHYNUM_CNT; ch++) {
+ pll3_valid |= (((priv->ddr_phyvalid >> (ch * 2)) |
+ (priv->ddr_phyvalid >> ((ch * 2) + 1))) & 0x1) << ch;
+ }
+
+ /* Calculate PLL3 settings */
+ if (priv->ddr_mbps < (pll3_frac_mode_threshold * priv->ddr_mbpsdiv))
+ ssmode = 4;
+ else
+ ssmode = 0;
+
+ ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2, priv->brd_clk,
+ priv->brd_clkdiv * (priv->brd_clkdiva + 1));
+
+ /* PLL3VCO = EXTAL * ddr_mul */
+ pll3vco = ddr_mul * priv->brd_clk / (priv->brd_clkdiv * (priv->brd_clkdiva + 1));
+
+ if (pll3vco < 3000) { /* div = 4 */
+ data_div = 2;
+ pll3vco = pll3vco * 2;
+ ddr_mul = ddr_mul * 2;
+ ddr_mul_div = 2;
+ } else { /* div = 2 */
+ data_div = 0;
+ ddr_mul_div = 1;
+ }
+
+ /*
+ * PLL3VCO FVV
+ * 3000 - 4000 0
+ * 3750 - 4900 1
+ * 4600 - 5800 2
+ * 5450 - 6200 3
+ */
+ if (pll3vco > 5800)
+ fvv = 3;
+ else if (pll3vco > 4900)
+ fvv = 2;
+ else if (pll3vco > 4000)
+ fvv = 1;
+ else
+ fvv = 0;
+
+ ddr_mul_ni = (ddr_mul / 2) - 1;
+ if (priv->ddr_mbps < (pll3_frac_mode_threshold * priv->ddr_mbpsdiv)) {
+ ddr_mul_nf = ((8 * priv->ddr_mbps * priv->brd_clkdiv * (priv->brd_clkdiva + 1) * ddr_mul_div) /
+ (priv->ddr_mbpsdiv * 2 * priv->brd_clk)) - (8 * (ddr_mul_ni + 1) * 2);
+ } else {
+ ddr_mul_nf = 0;
+ }
+
+ data_cr0 = (ddr_mul_ni << 20) | (ssmode << 16);
+ data_cr1 = (fvv << 26) | ddr_mul_nf;
+
+ /* Gradually frequency change settings */
+ data_dcr_1st = 0x18;
+ data_dcr_2nd = 0x10;
+ data_dcr_3rd = 0;
+
+ /* Disable write protection */
+ writel(0xa5a5a501, SYSSS_CLKTOPPKCPROT0);
+ while (!((readl(SYSSS_CLKTOPPKCPROT0)) & BIT(0)))
+ ;
+
+ /* Clock change & setting PLL3_x_CR0 and PLL3_x_CR1 */
+ for (ch = 0; ch < DBSC5_PLL3_CNT; ch++) {
+ if (!(pll3_valid & BIT(ch)))
+ continue;
+
+ /* 1. Confirm that the PLL3_x are stable with PLLCLKSTAB */
+ while (!(readl(SYSSS_PLL3_x_CR2(ch)) & BIT(31)))
+ ;
+
+ /* 2-1. Select PLL3_0SELID to CLK_IOSC1 */
+ writel(0x1, SYSSS_PLL3_xSCR(ch));
+ /* 2-2. Confirm PLL3_0SELACT register to ID equals CLK_IOSC1 */
+ while (((readl(SYSSS_PLL3_xSCR(ch))) & 0x10001) != 0x10001)
+ ;
+
+ /* 3. Stop the PLL3_x (PLLDISTRG = 1) */
+ writel(0x20000000, SYSSS_PLL3_x_CR2(ch));
+ /* 4. Confirm that the PLL3_0 has been stopped (PLLCLKSTAB = 0) */
+ while (readl(SYSSS_PLL3_x_CR2(ch)) & BIT(31))
+ ;
+
+ /* set PLL3_x_CR0 */
+ clrsetbits_le32(SYSSS_PLL3_x_CR0(ch), 0x1ff70000, data_cr0);
+ /* set PLL3_x_CR1 */
+ clrsetbits_le32(SYSSS_PLL3_x_CR1(ch), 0x0dffffff, data_cr1);
+ /* set PLL3_x_DCR */
+ writel(data_dcr_1st, SYSSS_PLL3_x_DCR(ch));
+ /* set PLL3_x_CR2 (PLLENTRG = 1) */
+ writel(BIT(28), SYSSS_PLL3_x_CR2(ch));
+ }
+
+ /* Clock change */
+ for (ch = 0; ch < DBSC5_PLL3_CNT; ch++) {
+ if (!(pll3_valid & BIT(ch)))
+ continue;
+
+ /* 1. Confirm that the PLL3_0 have been stable (PLLCLKSTAB = 1) */
+ while (!(readl(SYSSS_PLL3_x_CR2(ch)) & BIT(31)))
+ ;
+
+ /* 2-1. Select PLL input clock by PLLSELID register */
+ writel(0, SYSSS_PLL3_xSCR(ch));
+ /* 2-2. Confirm that PLL3_0SELACT register becomes same value with PLL3_0SELID */
+ while (readl(SYSSS_PLL3_xSCR(ch)) & 0x10001)
+ ;
+ }
+
+ /* Set PLL3_DCR gradually */
+ for (ch = 0; ch < DBSC5_PLL3_CNT; ch++) {
+ if (!(pll3_valid & BIT(ch)))
+ continue;
+
+ /* Set PLL3_x_DCR */
+ writel(data_dcr_2nd, SYSSS_PLL3_x_DCR(ch));
+ /* Wait PLL3DIVSYNC is changed from 0 to 1 */
+ while (!(readl(SYSSS_PLL3_x_DCR(ch)) & BIT(16)))
+ ;
+ }
+
+ /* Wait until the current stabilizes */
+ dbsc5_soft_delay(1000);
+
+ for (ch = 0; ch < DBSC5_PLL3_CNT; ch++) {
+ if (!(pll3_valid & BIT(ch)))
+ continue;
+
+ /* Set PLL3_x_DCR */
+ writel(data_dcr_3rd, SYSSS_PLL3_x_DCR(ch));
+ /* Wait PLL3DIVSYNC is changed from 0 to 1 */
+ while (((readl(SYSSS_PLL3_x_DCR(ch))) & 0x10000) != 0x10000)
+ ;
+ }
+
+ /* Wait until the current stabilizes */
+ dbsc5_soft_delay(1000);
+
+ /* Set PLL3 divider */
+ zb3ckcr0 = readl(SYSSS_ZB3CKCR0);
+ zb3ckcr1 = readl(SYSSS_ZB3CKCR1);
+ for (ch = 0; ch < DBSC5_PHYNUM_CNT; ch++) {
+ if (priv->ddr_phyvalid & BIT(ch)) {
+ /* set FC[3:0] = data_div */
+ ddr_zb3ckcr[ch] = data_div;
+ } else {
+ if (ch < 4)
+ ddr_zb3ckcr[ch] = (zb3ckcr0 >> SYSSS_ZB3CKCR_PHYx(ch)) & 0x1f;
+ else
+ ddr_zb3ckcr[ch] = (zb3ckcr1 >> SYSSS_ZB3CKCR_PHYx(ch)) & 0x1f;
+ }
+ }
+
+ zb3ckcr0 = (ddr_zb3ckcr[3] << 23) | (ddr_zb3ckcr[2] << 16) |
+ (ddr_zb3ckcr[1] << 7) | ddr_zb3ckcr[0];
+ zb3ckcr1 = (ddr_zb3ckcr[7] << 23) | (ddr_zb3ckcr[6] << 16) |
+ (ddr_zb3ckcr[5] << 7) | ddr_zb3ckcr[4];
+
+ /* Check ZB3CKCR0/1 KICK bit = 0 */
+ while (readl(SYSSS_ZB3CKCR0) & SYSSS_ZB3CKCR_KICK)
+ ;
+ while (readl(SYSSS_ZB3CKCR1) & SYSSS_ZB3CKCR_KICK)
+ ;
+
+ /* Set ZB3CKCR0/1 */
+ writel(zb3ckcr0, SYSSS_ZB3CKCR0);
+ writel(zb3ckcr1, SYSSS_ZB3CKCR1);
+
+ /* Set kickbit = 1 */
+ setbits_le32(SYSSS_ZB3CKCR0, SYSSS_ZB3CKCR_KICK);
+ setbits_le32(SYSSS_ZB3CKCR1, SYSSS_ZB3CKCR_KICK);
+
+ /* Wait ZB3CKCR0/1 KICK bit neg */
+ while (readl(SYSSS_ZB3CKCR0) & SYSSS_ZB3CKCR_KICK)
+ ;
+ while (readl(SYSSS_ZB3CKCR1) & SYSSS_ZB3CKCR_KICK)
+ ;
+}
+
+/**
+ * dbsc5_msres_sync_wait() - Wait for MSRES and MSRESS to synchronize
+ * @msres: MSRES register
+ * @msress: MSRESS register
+ */
+static void dbsc5_msres_sync_wait(u32 msres, u32 msress)
+{
+ while (readl(msres) != readl(msress))
+ ;
+}
+
+/**
+ * dbsc5_msres_status_set - Set DBSC5 into RUN or STANDBY mode
+ * @dev: DBSC5 device
+ * @status: RUN or STANDBY mode
+ */
+static void dbsc5_msres_status_set(struct udevice *dev, u32 status)
+{
+ u32 ch;
+
+ foreach_vphych(dev, ch) {
+ /*
+ * Enable write access of protected registers
+ * dbq_reset / ddr_reset_apb / ddr_reset_hard / ddr_reset
+ */
+ writel(0xa5a5a501, MODULE_CONTROL_MDLC0xPKCPROT1(ch));
+ /* ddrfi */
+ writel(0xa5a5a501, MODULE_CONTROL_MDLC12PKCPROT1);
+
+ /* Check MDLCnMSRESS[i] = MDLCnMSRES[i] */
+ /* dbq_reset */
+ dbsc5_msres_sync_wait(MODULE_CONTROL_MDLC0xMSRES1(ch),
+ MODULE_CONTROL_MDLC0xMSRESS1(ch));
+
+ /* ddr_reset_apb / ddr_reset_hard / ddr_reset */
+ dbsc5_msres_sync_wait(MODULE_CONTROL_MDLC0xMSRES3(ch),
+ MODULE_CONTROL_MDLC0xMSRESS3(ch));
+
+ /* ddrfi */
+ dbsc5_msres_sync_wait(MODULE_CONTROL_MDLC15MSRES8,
+ MODULE_CONTROL_MDLC15MSRESS8);
+
+ /* Set MDLCnMSRESx */
+ /* dbq_reset */
+ clrsetbits_le32(MODULE_CONTROL_MDLC0xMSRES1(ch), 0x3, status);
+
+ /* ddr_reset_apb / ddr_reset_hard / ddr_reset */
+ clrsetbits_le32(MODULE_CONTROL_MDLC0xMSRES3(ch), 0x3f,
+ (status << 4) | (status << 2) | status);
+
+ /* ddrfi */
+ clrsetbits_le32(MODULE_CONTROL_MDLC15MSRES8, 0x3 << (ch * 2),
+ status << (ch * 2));
+
+ /* Check MDLCnMSRESS[i] = MDLCnMSRES[i] */
+ /* dbq_reset */
+ dbsc5_msres_sync_wait(MODULE_CONTROL_MDLC0xMSRES1(ch),
+ MODULE_CONTROL_MDLC0xMSRESS1(ch));
+
+ /* ddr_reset_apb / ddr_reset_hard / ddr_reset */
+ dbsc5_msres_sync_wait(MODULE_CONTROL_MDLC0xMSRES3(ch),
+ MODULE_CONTROL_MDLC0xMSRESS3(ch));
+
+ /* ddrfi */
+ dbsc5_msres_sync_wait(MODULE_CONTROL_MDLC15MSRES8,
+ MODULE_CONTROL_MDLC15MSRESS8);
+
+ /* Disables write access of protected registers */
+ /* dbq_reset / ddr_reset_apb / ddr_reset_hard / ddr_reset */
+ writel(0xa5a5a500, MODULE_CONTROL_MDLC0xPKCPROT1(ch));
+ /* ddrfi */
+ writel(0xa5a5a500, MODULE_CONTROL_MDLC12PKCPROT1);
+ }
+}
+
+/**
+ * dbsc5_reg_write() - Write DBSC register
+ * @dev: DBSC5 device
+ * @addr: Destination address
+ * @data: Setting value to be written
+ *
+ * Write 32bit value @data to register at @addr .
+ */
+static void dbsc5_reg_write(struct udevice *dev, uintptr_t addr, u32 data)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < DBSC5_DBSC_CNT; i++) {
+ if (!(priv->ddr_phyvalid & BIT(i)))
+ continue;
+
+ if ((addr & 0xFFF00000) == 0xE9900000) /* clk_dbsc region */
+ writel(data, addr + (0x4000 * i));
+ else /* clk_axim region */
+ writel(data, addr + (0x8000 * i));
+ }
+}
+
+/**
+ * dbsc5_regset_unlock() - Unlock DBSC access
+ * @dev: DBSC5 device
+ */
+static void dbsc5_regset_unlock(struct udevice *dev)
+{
+ dbsc5_reg_write(dev, DBSC_DBSYSCNT0, 0x1234);
+ dbsc5_reg_write(dev, DBSC_DBSYSCNT0A, 0x1234);
+}
+
+/**
+ * dbsc5_regset_lock() - Lock DBSC access
+ * @dev: DBSC5 device
+ */
+static void dbsc5_regset_lock(struct udevice *dev)
+{
+ dbsc5_reg_write(dev, DBSC_DBSYSCNT0, 0);
+ dbsc5_reg_write(dev, DBSC_DBSYSCNT0A, 0);
+}
+
+/**
+ * dbsc5_send_dbcmd() - DRAM Command Write
+ * @dev: DBSC5 device
+ * @cmd: Command
+ */
+static void dbsc5_send_dbcmd(struct udevice *dev, u32 cmd)
+{
+ readl(DBSC_DBCMD); /* Dummy read */
+
+ while (readl(DBSC_DBWAIT) & BIT(0)) /* Wait for not busy */
+ ;
+
+ dbsc5_reg_write(dev, DBSC_DBCMD, cmd);
+}
+
+/**
+ * dbsc5_send_dbcmd_ch() - DRAM Command Write on channel
+ * @ch: DBSC5 channel
+ * @cmd: Command
+ */
+static void dbsc5_send_dbcmd_ch(u32 ch, u32 cmd)
+{
+ readl(DBSC_DBCMD); /* Dummy read */
+
+ while (readl(DBSC_DBWAIT) & BIT(0)) /* Wait for not busy */
+ ;
+
+ writel(cmd, DBSC_DBCMD + (0x4000 * ch));
+}
+
+/**
+ * dbsc5_f_scale_rate() - Calculate the best value for DBSC timing setting
+ * @priv: Driver private data
+ * @frac: Perform fractional rounding
+ * @ddr_mbps: DRAM Mbps
+ * @ddr_mbpsdiv: DRAM Mbps divider
+ * @ps: Optimal setting value in pico second
+ * @cyc: Optimal setting value in cycle count
+ *
+ * Convert the optimal value in pico second to in cycle count. Optionally, if @frac is true,
+ * perform fractional rounding. Compare the value of the result of the conversion with the
+ * value of the argument @cyc and return the larger value.
+ */
+static u32 dbsc5_f_scale_rate(struct renesas_dbsc5_dram_priv *priv, const bool frac,
+ u32 ddr_mbps, u32 ddr_mbpsdiv, u32 ps, u32 cyc)
+{
+ const u32 mul = frac ? 8 : 800000;
+ const u32 tmp = DIV_ROUND_UP(ps, 10UL) * ddr_mbps;
+ const u32 f_scale_div = DIV_ROUND_UP(tmp, mul * ddr_mbpsdiv);
+
+ return (f_scale_div > cyc) ? f_scale_div : cyc;
+}
+
+/**
+ * dbsc5_f_scale() - Calculate the best value for DBSC timing setting
+ * @priv: Driver private data
+ * @frac: Perform fractional rounding
+ * @ps: Optimal setting value in pico second
+ * @cyc: Optimal setting value in cycle count
+ *
+ * Convert the optimal value in pico second to in cycle count. Optionally, if @frac is true,
+ * perform fractional rounding. Compare the value of the result of the conversion with the
+ * value of the argument @cyc and return the larger value.
+ */
+static u32 dbsc5_f_scale(struct renesas_dbsc5_dram_priv *priv, const bool frac, u32 ps, u32 cyc)
+{
+ return dbsc5_f_scale_rate(priv, frac, priv->ddr_mbps, priv->ddr_mbpsdiv, ps, cyc);
+}
+
+/**
+ * dbsc5_f_scale_js2() - Select optimal settings based on jedec_spec2
+ * @priv: Driver private data
+ * @js2: Array of jedec spec2 setting table
+ *
+ * Calculate and assign each setting value of jedec_spec2 by "dbsc5_f_scale" function.
+ * Only the following array elements are calculated using different formulas from those
+ * described above -- JS2_tRRD/JS2_tFAW/JS2_tZQCALns/JS2_tRCpb/JS2_tRCab.
+ */
+static void dbsc5_f_scale_js2(struct renesas_dbsc5_dram_priv *priv, u32 *f_js2)
+{
+ int i;
+
+ for (i = 0; i < JS2_TBLCNT; i++) {
+ f_js2[i] = dbsc5_f_scale(priv, false,
+ jedec_spec2[JS2_DERATE][i].ps,
+ jedec_spec2[JS2_DERATE][i].cyc);
+ }
+
+ f_js2[JS2_tRRD] = dbsc5_f_scale(priv, false,
+ js1[priv->js1_ind].tRRD + jedec_spec2[JS2_DERATE][JS2_tRRD].ps,
+ jedec_spec2[JS2_DERATE][JS2_tRRD].cyc);
+ f_js2[JS2_tFAW] = dbsc5_f_scale(priv, false,
+ js1[priv->js1_ind].tFAW + jedec_spec2[JS2_DERATE][JS2_tFAW].ps,
+ jedec_spec2[JS2_DERATE][JS2_tFAW].cyc);
+ f_js2[JS2_tZQCALns] = dbsc5_f_scale(priv, false,
+ jedec_spec2[JS2_DERATE][JS2_tZQCALns].ps * 1000, 0);
+ f_js2[JS2_tDQ72DQns] = dbsc5_f_scale(priv, false,
+ jedec_spec2[JS2_DERATE][JS2_tDQ72DQns].ps * 1000, 0);
+ f_js2[JS2_tCAENTns] = dbsc5_f_scale(priv, false,
+ jedec_spec2[JS2_DERATE][JS2_tCAENTns].ps * 1000, 0);
+ f_js2[JS2_tRCpb] = f_js2[JS2_tRAS] + f_js2[JS2_tRPpb];
+ f_js2[JS2_tRCab] = f_js2[JS2_tRAS] + f_js2[JS2_tRPab];
+ f_js2[JS2_tRFCab] = dbsc5_f_scale(priv, false,
+ jedec_spec2_tRFC_ab[priv->max_density] * 1000, 0);
+ f_js2[JS2_tRFCpb] = dbsc5_f_scale(priv, false,
+ jedec_spec2_tRFC_pb[priv->max_density] * 1000, 0);
+ f_js2[JS2_tpbR2pbR] = dbsc5_f_scale(priv, false,
+ jedec_spec2_tpbR2pbR[priv->max_density] * 1000, 0);
+ f_js2[JS2_tRFMab] = dbsc5_f_scale(priv, false,
+ jedec_spec2_tRFM_ab[priv->max_density] * 1000, 0);
+ f_js2[JS2_tRFMpb] = dbsc5_f_scale(priv, false,
+ jedec_spec2_tRFM_pb[priv->max_density] * 1000, 0);
+
+ f_js2[JS2_tRBTP] = dbsc5_f_scale(priv, false, 7500, 2) - 2;
+ f_js2[JS2_tXSR] = f_js2[JS2_tRFCab] + dbsc5_f_scale(priv, false, 7500, 2);
+ f_js2[JS2_tPDN] = dbsc5_f_scale(priv, false, 10000, 0) + 1;
+ f_js2[JS2_tPDN_DSM] = dbsc5_f_scale(priv, true,
+ jedec_spec2[JS2_DERATE][JS2_tPDN_DSM].ps * 10, 0);
+ f_js2[JS2_tXSR_DSM] = dbsc5_f_scale(priv, true,
+ jedec_spec2[JS2_DERATE][JS2_tXSR_DSM].ps * 10, 0);
+ f_js2[JS2_tXDSM_XP] = dbsc5_f_scale(priv, true,
+ jedec_spec2[JS2_DERATE][JS2_tXDSM_XP].ps * 10, 0);
+ f_js2[JS2_tWLWCKOFF] = dbsc5_f_scale(priv, false, 14000, 5);
+}
+
+/**
+ * dbsc5_dbsc_regset_pre() - Configure primary DDR registers
+ * @dev: DBSC5 device
+ *
+ * Set SDRAM type, Burst length, and PHY type. Frequency mode setting.
+ * Write SDRAM configuration contents to registers.
+ */
+static void dbsc5_dbsc_regset_pre(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ddr_density[DRAM_CH_CNT][CS_CNT];
+ u32 RL, WL, WCKENLR;
+ u32 ch, cs, i, val;
+ u32 js2[JS2_CNT];
+ u32 param_trdwr;
+ u32 tmp[4];
+
+ /* Determine DBSC clock frequency (in MHz) */
+ const u32 ni = (readl(SYSSS_PLL1_1_CR0) >> 20) & 0x1FF;
+ const u32 cksel = (readl(SYSSS_PLL1_1_CR0) >> 7) & 0x1;
+ const u32 div = 0x20 - ((readl(SYSSS_PLL1_1DCR)) & 0x1F);
+ const u32 bus_clk = ((priv->brd_clk * (ni + 1) * 2) * div) / (cksel + 1) / 32 / 4;
+
+ /* Determine board density */
+ priv->max_density = 0;
+ for (ch = 0; ch < DRAM_CH_CNT; ch++) {
+ for (cs = 0; cs < CS_CNT; cs++) {
+ ddr_density[ch][cs] = priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs];
+ if (priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs] == 0xFF)
+ continue;
+
+ if (priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs] > priv->max_density)
+ priv->max_density = priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs];
+ }
+ }
+
+ /* Search jedec_spec1 index */
+ for (i = JS1_USABLEC_SPEC_LO; i < (JS1_FREQ_TBL_NUM - 1); i++)
+ if ((js1[i].fx3 * 2 * priv->ddr_mbpsdiv) >= (priv->ddr_mbps * 3))
+ break;
+
+ if (i > JS1_USABLEC_SPEC_HI)
+ priv->js1_ind = JS1_USABLEC_SPEC_HI;
+ else
+ priv->js1_ind = i;
+
+ RL = js1[priv->js1_ind].RLset0;
+ WL = js1[priv->js1_ind].WLsetA;
+ WCKENLR = js1[priv->js1_ind].WCKENLR0;
+
+ /* Calculate jedec_spec2 */
+ dbsc5_f_scale_js2(priv, js2);
+
+ /* LPDDR5, BL=16, DFI interface */
+ dbsc5_reg_write(dev, DBSC_DBMEMKIND, 0xC);
+ dbsc5_reg_write(dev, DBSC_DBMEMKINDA, 0xC);
+ dbsc5_reg_write(dev, DBSC_DBBL, 0x2);
+ dbsc5_reg_write(dev, DBSC_DBBLA, 0x2);
+
+ /* dcmpmd = 2 : bypass mode */
+ dbsc5_reg_write(dev, DBSC_DBSYSCNT1A, 0x2);
+ dbsc5_reg_write(dev, DBSC_DBPHYCONF0, 0x1);
+ dbsc5_reg_write(dev, DBSC_DBSYSCONF0, 0x1);
+
+ /* FREQRATIO=2 */
+ dbsc5_reg_write(dev, DBSC_DBSYSCONF1, 0x20000);
+ dbsc5_reg_write(dev, DBSC_DBSYSCONF1A, 0);
+ dbsc5_reg_write(dev, DBSC_DBSYSCONF2, 0x1);
+ dbsc5_reg_write(dev, DBSC_DBSYSCONF2A, 0x241);
+
+ for (ch = 0; ch < DRAM_CH_CNT; ch++) {
+ for (cs = 0; cs < CS_CNT; cs++) {
+ if (ddr_density[ch][cs] == 0xFF) {
+ writel(0, DBSC_DBMEMCONF(ch, cs));
+ writel(0, DBSC_DBMEMCONFA(ch, cs));
+ } else {
+ writel(DBMEMCONF_REGD(ddr_density[ch][cs]),
+ DBSC_DBMEMCONF(ch, cs));
+ writel(DBMEMCONF_REGD(ddr_density[ch][cs]),
+ DBSC_DBMEMCONFA(ch, cs));
+ }
+ }
+ }
+
+ /* DBTR0.cl : RL */
+ dbsc5_reg_write(dev, DBSC_DBTR(0), RL);
+
+ /* DBTR1.cwl : WL */
+ dbsc5_reg_write(dev, DBSC_DBTR(1), WL);
+
+ /* DBTR2.al = 0 */
+ dbsc5_reg_write(dev, DBSC_DBTR(2), 0);
+
+ /* DBTR3.trcd : tRCD */
+ dbsc5_reg_write(dev, DBSC_DBTR(3), js2[JS2_tRCD]);
+
+ /* DBTR4.trpa,trp : tRPab,tRPpb */
+ dbsc5_reg_write(dev, DBSC_DBTR(4), (js2[JS2_tRPab] << 16) | js2[JS2_tRPpb]);
+
+ /* DBTR5.trc : tRCpb */
+ dbsc5_reg_write(dev, DBSC_DBTR(5), js2[JS2_tRCpb]);
+
+ /* DBTR6.tras : tRAS */
+ dbsc5_reg_write(dev, DBSC_DBTR(6), js2[JS2_tRAS]);
+
+ /* DBTR7.trrd : tRRD */
+ dbsc5_reg_write(dev, DBSC_DBTR(7), (js2[JS2_tRRD] << 16) | js2[JS2_tRRD]);
+
+ /* DBTR8.tfaw : tFAW */
+ dbsc5_reg_write(dev, DBSC_DBTR(8), js2[JS2_tFAW]);
+
+ /* DBTR9.trdpr : nRBTP */
+ dbsc5_reg_write(dev, DBSC_DBTR(9), js1[priv->js1_ind].nRBTP);
+
+ /* DBTR10.twr : nWR */
+ dbsc5_reg_write(dev, DBSC_DBTR(10), js1[priv->js1_ind].nWR);
+
+ /*
+ * DBTR11.trdwr : RL + BL/n_max + RU(tWCK2DQO(max)/tCK) + RD(tRPST/tCK) -
+ * ODTLon - RD(tODTon(min)/tCK) + 1 + feature
+ */
+ param_trdwr = RL + 4 + js2[JS2_tWCK2DQO_HF] + 0 - js1[priv->js1_ind].ODTLon -
+ (js2[JS2_tODTon_min] - 1) + 1 + 0;
+ dbsc5_reg_write(dev, DBSC_DBTR(11), param_trdwr);
+
+ /* DBTR12.twrrd_s,twrrd : WL + BL/2 + tWTR_S,WL + BL + tWTR_L */
+ dbsc5_reg_write(dev, DBSC_DBTR(12), ((WL + 2 + js2[JS2_tWTR_S]) << 16) |
+ (WL + 4 + js2[JS2_tWTR_L]));
+
+ /* DBTR13.trfcpb,trfc : tRFCpb,tRFCab */
+ dbsc5_reg_write(dev, DBSC_DBTR(13), (js2[JS2_tRFCpb] << 16) | (js2[JS2_tRFCab]));
+
+ /* DBTR14.tcscal,tckehdll,tckeh : tCSCAL,tXP,tXP */
+ dbsc5_reg_write(dev, DBSC_DBTR(14), (js2[JS2_tCSCAL] << 24) | (js2[JS2_tXP] << 16) |
+ js2[JS2_tXP]);
+
+ /* DBTR15 */
+ /* tckel : tSR */
+ tmp[0] = js2[JS2_tSR];
+ /* tckesr : tSR */
+ tmp[1] = js2[JS2_tSR];
+ /* tespd : tESPD = 2 */
+ tmp[2] = 0x2;
+ dbsc5_reg_write(dev, DBSC_DBTR(15), (tmp[2] << 24) | (tmp[1] << 16) | tmp[0]);
+
+ /* DBTR16 */
+ /* wdql(tphy_wrlat + tphy_wrdata) */
+ tmp[0] = (WL * 4) - 5 + 2;
+ /* dqenltcy(tphy_wrlat) */
+ tmp[1] = (WL * 4) - 5;
+ /* dql(tphy_rdlat + trddata_en) : (6 + csrDFIMRL) * 4 + trddata_en */
+ tmp[2] = ((6 + 7) * 4) + ((RL * 4) - 13);
+ /* dqienltncy(trddata_en) : RL * 4 - 13 */
+ tmp[3] = (RL * 4) - 13;
+ dbsc5_reg_write(dev, DBSC_DBTR(16), (tmp[3] << 25) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
+
+ /* DBTR17.tmodrd,tmod : tMRR,tMRW */
+ dbsc5_reg_write(dev, DBSC_DBTR(17), (js2[JS2_tMRR] << 24) | (js2[JS2_tMRW] << 16));
+
+ /* DBTR18.rodtl,rodta = 0 */
+ dbsc5_reg_write(dev, DBSC_DBTR(18), 0);
+
+ /* DBTR19.tzqcl,tzqcs = 0 */
+ dbsc5_reg_write(dev, DBSC_DBTR(19), 0);
+
+ /* DBTR20.txsdll,txs : tXSR,tXSR */
+ dbsc5_reg_write(dev, DBSC_DBTR(20), (js2[JS2_tXSR] << 16) | js2[JS2_tXSR]);
+
+ /* DBTR21.tccdmw, tccd */
+ /* tccd(BL/2_max) */
+ tmp[0] = 0x4;
+ /* tccd_s(BL/2_min) */
+ tmp[1] = 0x2;
+ /* tccdmw */
+ if ((priv->ddr_mbps * 3) > (25600 * priv->ddr_mbpsdiv))
+ tmp[2] = 0x14;
+ else
+ tmp[2] = 0x10;
+ dbsc5_reg_write(dev, DBSC_DBTR(21), (tmp[2] << 24) | (tmp[1] << 16) | tmp[0]);
+
+ /* DBTR22.tzqcal,tzqlat : tZQCAL,tZQLAT */
+ dbsc5_reg_write(dev, DBSC_DBTR(22), (js2[JS2_tZQCALns] << 16) | js2[JS2_tZQLAT]);
+
+ /* DBTR23.rrspc = 0 */
+ dbsc5_reg_write(dev, DBSC_DBTR(23), 0);
+
+ /* DBTR24 */
+ /* wrcslat(tphy_wrcslat) */
+ tmp[0] = (WL * 4) - 5;
+ /* wrcsgap(tphy_wrcsgap) */
+ tmp[1] = 0x4;
+ /* rdcslat(tphy_rdcslat) */
+ tmp[2] = (RL * 4) - 13;
+ /* rdcsgap(tphy_rdcsgap) */
+ tmp[3] = 0x4;
+ dbsc5_reg_write(dev, DBSC_DBTR(24), (tmp[3] << 24) | (tmp[2] << 16) |
+ (tmp[1] << 8) | tmp[0]);
+
+ /* DBTR25 */
+ dbsc5_reg_write(dev, DBSC_DBTR(25), 0);
+
+ /* DBTR26 */
+ dbsc5_reg_write(dev, DBSC_DBTR(26), 0);
+
+ /* DBTR27.tpdn : tPDN */
+ dbsc5_reg_write(dev, DBSC_DBTR(27), js2[JS2_tPDN]);
+
+ /* DBTR28.txsrdsm : tXSR_DSM */
+ dbsc5_reg_write(dev, DBSC_DBTR(28), js2[JS2_tXSR_DSM]);
+
+ /* DBTR29.tdsmxp : tXDSM_XP */
+ dbsc5_reg_write(dev, DBSC_DBTR(29), js2[JS2_tXDSM_XP]);
+
+ /* DBTR30.tcmdpd : tCMDPD = 3 */
+ dbsc5_reg_write(dev, DBSC_DBTR(30), 0x3);
+
+ /* DBTR31.twck2dqomax,twck2dqimax : tWCK2DQO_HF/LF,tWCK2DQI_HF/LF */
+ dbsc5_reg_write(dev, DBSC_DBTR(31), (js2[JS2_tWCK2DQO_HF] << 4) | js2[JS2_tWCK2DQI_HF]);
+
+ /* DBTR32 */
+ /* twckenr */
+ tmp[0] = (WCKENLR * 4) - 4 - 1;
+ /* twckenw */
+ tmp[1] = (js1[priv->js1_ind].WCKENLW * 4) - 4 - 1;
+ /* twckenlf */
+ tmp[2] = (js1[priv->js1_ind].WCKENLF * 4) - 4;
+ /* twckpresta */
+ tmp[3] = js1[priv->js1_ind].WCKPRESTA * 4;
+ dbsc5_reg_write(dev, DBSC_DBTR(32), (tmp[3] << 24) | (tmp[2] << 16) |
+ (tmp[1] << 8) | tmp[0]);
+
+ /* DBTR33 */
+ /* twcktgl */
+ tmp[0] = 4;
+ /* twckdis : (RL+ bl/n_max) * 4 + RU(tWCKPST/tWCK),tWCKPST = MR10[3:2] = 2.5 */
+ tmp[1] = ((RL + 4) * 4) + 3;
+ dbsc5_reg_write(dev, DBSC_DBTR(33), (tmp[1] << 8) | tmp[0]);
+
+ /* DBTR34 */
+ /* twcksus = 4 */
+ tmp[0] = 4;
+ /* twckpst : RU(tWCKPST/tCK),tWCKPST = MR10[3:2] = 2.5 */
+ tmp[1] = 1;
+ dbsc5_reg_write(dev, DBSC_DBTR(34), (tmp[1] << 8) | tmp[0]);
+
+ /* DBTR35 */
+ /* trd2wckoff : RL + BL/n_max + RD(tWCKPST/tCK) + 1 */
+ tmp[0] = RL + 4 + 0 + 1;
+ /* twr2wckoff : WL + BL/n_max + RD(tWCKPST/tCK) + 1 */
+ tmp[1] = WL + 4 + 0 + 1;
+ dbsc5_reg_write(dev, DBSC_DBTR(35), (tmp[1] << 16) | tmp[0]);
+
+ /* DBTR36 */
+ /* twssuswrx : CAS(WCKSUS)WRX */
+ tmp[0] = 3;
+ /* twsoffwrx : CAS(WS_OFF)WRX */
+ tmp[1] = 3;
+ /* twsfswrx : CAS(WS_FS)WRX */
+ tmp[2] = 2;
+ dbsc5_reg_write(dev, DBSC_DBTR(36), (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
+
+ /* DBTR37 */
+ /* tosco : tOSCODQI */
+ tmp[0] = js2[JS2_tOSCODQI];
+ /* toscodqi : tOSCODQI */
+ tmp[1] = js2[JS2_tOSCODQI];
+ /* toscodqo : tOSCODQO */
+ tmp[2] = js2[JS2_tOSCODQO];
+ dbsc5_reg_write(dev, DBSC_DBTR(37), (tmp[2] << 24) | (tmp[1] << 16) | tmp[0]);
+
+ /* DBTR38.tpbr2act,tpbr2pbr : tpbR2act,tpbR2pbR */
+ dbsc5_reg_write(dev, DBSC_DBTR(38), (js2[JS2_tpbR2act] << 8) | js2[JS2_tpbR2pbR]);
+
+ /* DBTR39.trfmpb,trmbab : tRFMpb,tRFMab */
+ dbsc5_reg_write(dev, DBSC_DBTR(39), (js2[JS2_tRFMpb] << 16) | js2[JS2_tRFMab]);
+
+ /* DBRNK2 */
+ /* rnkrr = tphy_wckcsgap + tWCK2DQO_rank2rank_HF/tWCK */
+ val = dbsc5_f_scale_rate(priv, false, priv->ddr_mbps * 4, priv->ddr_mbpsdiv, 650, 0);
+ tmp[0] = (4 + val) / 4;
+ if ((tmp[0] * 4) == (4 + val))
+ val = tmp[0];
+ else
+ val = tmp[0] + 1;
+ dbsc5_reg_write(dev, DBSC_DBRNK(2), (val << 4) | val);
+
+ /* DBRNK3 */
+ /* rnkrw = tphy_wckcsgap + tWCK2DQO_rank2rank_HF/tWCK */
+ val = dbsc5_f_scale_rate(priv, false, priv->ddr_mbps * 4, priv->ddr_mbpsdiv, 650, 0);
+ tmp[0] = (4 + val) / 4;
+ if ((tmp[0] * 4) == (4 + val))
+ val = tmp[0];
+ else
+ val = (tmp[0] + 1);
+
+ /* trd2wckoff - trdwr */
+ tmp[0] = (RL + 4 + 0 + 1) - param_trdwr;
+ if (tmp[0] > val)
+ val = tmp[0];
+ dbsc5_reg_write(dev, DBSC_DBRNK(3), (val << 4) | val);
+
+ /* DBRNK4 */
+ /* rnkwr = tphy_wckcsgap */
+ dbsc5_reg_write(dev, DBSC_DBRNK(4), 0x11);
+
+ /* DBRNK5 */
+ /* rnkww = tphy_wckcsgap */
+ dbsc5_reg_write(dev, DBSC_DBRNK(5), 0x11);
+
+ /* DBRNK6 */
+ /* refmode = tphy_wckcsgap */
+ /* per_bank_refresh */
+ dbsc5_reg_write(dev, DBSC_DBRNK(6), 0x1);
+
+ /* SCFCTST0 */
+ /* scpreact */
+ tmp[0] = 1UL * js2[JS2_tRPpb] * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ /* scactrdwr */
+ tmp[1] = 1UL * (WL + 2 + 1 + js1[priv->js1_ind].nWR + js2[JS2_tRPpb]) *
+ bus_clk * priv->ddr_mbpsdiv * 8 / priv->ddr_mbps / priv->brd_clkdiv;
+ /* scrdacrt */
+ tmp[2] = 1UL * ((js1[priv->js1_ind].nRBTP + 2) + js2[JS2_tRPpb]) *
+ bus_clk * priv->ddr_mbpsdiv * 8 / priv->ddr_mbps / priv->brd_clkdiv;
+ /* scactact */
+ tmp[3] = 1UL * js2[JS2_tRCpb] * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ dbsc5_reg_write(dev, DBSC_DBSCHFCTST(0), (tmp[3] << 24) | (tmp[2] << 16) |
+ (tmp[1] << 8) | tmp[0]);
+
+ /* SCFCTST1 */
+ /* scasyncofs */
+ tmp[0] = 12;
+ /* scactrdwr */
+ tmp[1] = 1UL * js2[JS2_tRCD] * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ /* scwrrd */
+ tmp[2] = 1UL * (WL + 4 + js2[JS2_tWTR_L]) * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ /* scrdwr */
+ tmp[3] = 1UL * param_trdwr * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ dbsc5_reg_write(dev, DBSC_DBSCHFCTST(1), (tmp[3] << 24) | (tmp[2] << 16) |
+ (tmp[1] << 8) | tmp[0]);
+
+ /* DBSCHRW1 */
+ /* sctrfcab */
+ val = 1UL * (js2[JS2_tRFCab] + js2[JS2_tZQLAT]) * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ /* sctrfcab[7:0] = DBSCHRW1[7:0] */
+ tmp[0] = val & 0xFF;
+ /* sctrfcab[8] = DBSCHRW1[24] */
+ tmp[3] = val & 0x100;
+ /* sctrfcpb */
+ tmp[1] = 1UL * (js2[JS2_tRFCpb]) * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ /* sctrfcpb */
+ tmp[2] = 1UL * (js2[JS2_tpbR2pbR]) * bus_clk * priv->ddr_mbpsdiv * 8 /
+ priv->ddr_mbps / priv->brd_clkdiv;
+ dbsc5_reg_write(dev, DBSC_DBSCHRW(1), (tmp[3] << 24) | (tmp[2] << 16) |
+ (tmp[1] << 8) | tmp[0]);
+
+ /* DBSCHRW2 */
+ /* scrfpben */
+ tmp[0] = 1;
+ /* screfipb : tREFIpb */
+ tmp[1] = DBSC_REFINT * bus_clk / priv->brd_clkdiv / 1000 / 8;
+ dbsc5_reg_write(dev, DBSC_DBSCHRW(2), (tmp[1] << 16) | tmp[0]);
+
+ /* DBSCHTR0 */
+ /* scdt0 */
+ tmp[0] = (1UL * 4 * bus_clk * priv->ddr_mbpsdiv * 8 / priv->ddr_mbps / priv->brd_clkdiv) - 1;
+ /* scdt1 */
+ tmp[1] = (1UL * 8 * bus_clk * priv->ddr_mbpsdiv * 8 / priv->ddr_mbps / priv->brd_clkdiv) - 1;
+ /* scdt2 */
+ tmp[2] = (1UL * 12 * bus_clk * priv->ddr_mbpsdiv * 8 / priv->ddr_mbps / priv->brd_clkdiv) - 1;
+ /* scdt3 */
+ tmp[3] = (1UL * 16 * bus_clk * priv->ddr_mbpsdiv * 8 / priv->ddr_mbps / priv->brd_clkdiv) - 1;
+ dbsc5_reg_write(dev, DBSC_DBSCHTR0, (tmp[3] << 24) | (tmp[2] << 16) |
+ (tmp[1] << 8) | tmp[0]);
+
+ dbsc5_reg_write(dev, DBSC_DBBCAMDIS, 0x10);
+
+ /* Dummy PDE */
+ dbsc5_send_dbcmd(dev, 0x8840000);
+ /* Dummy PDX */
+ dbsc5_send_dbcmd(dev, 0x8840001);
+}
+
+/**
+ * dbsc5_dbsc_regset_post() - Set DBSC registers
+ * @dev: DBSC5 device
+ */
+static void dbsc5_dbsc_regset_post(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 val;
+ u32 tmp;
+
+ dbsc5_reg_write(dev, DBSC_DBBUS0CNF1, 0);
+
+ /* SRX */
+ dbsc5_send_dbcmd(dev, 0xA840001);
+
+ /* Write DBI ON */
+ dbsc5_reg_write(dev, DBSC_DBDBICNT, 0x1);
+
+ /* set REFCYCLE */
+ val = DBSC_REFINT * priv->ddr_mbps / 8000 / priv->ddr_mbpsdiv;
+ /* refpmax=8 */
+ dbsc5_reg_write(dev, DBSC_DBRFCNF1, 0x80000 | (val & 0xFFFF));
+ /* refpmin=1 */
+ dbsc5_reg_write(dev, DBSC_DBRFCNF2, 0x10000);
+
+ /* periodic dram zqcal enable */
+ dbsc5_reg_write(dev, DBSC_DBCALCNF, 0x1000010);
+
+ /* wtmode = 1, pmstrmd = 2(WA for WS1), pmstren = 1 */
+ dbsc5_reg_write(dev, DBSC_DBDFIPMSTRCNF, 0x15);
+
+ /* periodic phy ctrl update enable */
+ /* max = 80, min = 76, en = 1 */
+ dbsc5_reg_write(dev, DBSC_DBDFICUPDCNF, 0x504C0001);
+
+ /* set Auto Refresh */
+ dbsc5_reg_write(dev, DBSC_DBRFEN, 0x1);
+
+ /* dram access enable */
+ dbsc5_reg_write(dev, DBSC_DBACEN, 0x1);
+
+ tmp = (PERIODIC_TRAINING_INTERVAL * 1000) / DBSC_REFINT;
+ /* (ZQCalibration_interval + 1) / ZQCalibration_interval */
+ val = (tmp * (0x10 + 1)) / 0x10;
+ /* snoopen=1 */
+ dbsc5_reg_write(dev, DBSC_DBSNOOPC, BIT(24) | val);
+}
+
+#define RTMMAC_BASE 0xb8900000
+#define RTDMAC_RDMSAR_0(ch) (RTMMAC_BASE + 0x0 + ((ch) * 0x1000))
+#define RTDMAC_RDMDAR_0(ch) (RTMMAC_BASE + 0x4 + ((ch) * 0x1000))
+#define RTDMAC_RDMTCR_0(ch) (RTMMAC_BASE + 0x8 + ((ch) * 0x1000))
+#define RTDMAC_RDMCHCR_0(ch) (RTMMAC_BASE + 0xc + ((ch) * 0x1000))
+#define RTDMAC_RDMCHCLR(ch) (RTMMAC_BASE + 0x100 + ((ch) * 0x1000))
+#define RTDMAC_RDMOR 0xb9438060
+
+/**
+ * dbsc5_rtdmac_init() - Configure RTDMAC DMA controller
+ * @ch: DMA Channel
+ * @dst: Destination address
+ * @src: Source address
+ * @cnt: Byte count
+ */
+static void dbsc5_rtdmac_init(u32 ch, u32 dst, u32 src, u32 cnt)
+{
+ /* DMA Setting - 64Byte/AutoRequest mode */
+ writel(src, RTDMAC_RDMSAR_0(ch));
+ writel(dst, RTDMAC_RDMDAR_0(ch));
+ writel(cnt, RTDMAC_RDMTCR_0(ch));
+ writel(0x105409, RTDMAC_RDMCHCR_0(ch));
+}
+
+/**
+ * dbsc5_rtdmac_start() - Start RTDMAC DMA controller
+ */
+static void dbsc5_rtdmac_start(void)
+{
+ /* Start DMA */
+ writew(0x1, RTDMAC_RDMOR);
+}
+
+/**
+ * dbsc5_rtdmac_wait() - Wait for RTDMAC DMA completion
+ * @ch: DMA Channel
+ */
+static void dbsc5_rtdmac_wait(int ch)
+{
+ u32 val;
+
+ /* Wait for DMA completion */
+ for (;;) {
+ val = readl(RTDMAC_RDMCHCR_0(ch));
+ if (val & BIT(1)) { /* Clear TE */
+ writel(val & ~BIT(1), RTDMAC_RDMCHCR_0(ch));
+ break;
+ }
+
+ if (val & BIT(31)) { /* Clear CAE */
+ writel(val & ~BIT(31), RTDMAC_RDMCHCR_0(ch));
+ break;
+ }
+ }
+}
+
+/**
+ * dbsc5_rtdmac_stop() - Stop RTDMAC DMA controller
+ */
+static void dbsc5_rtdmac_stop(void)
+{
+ u32 ch;
+
+ /* Disable DMA */
+ writew(0, RTDMAC_RDMOR);
+ for (ch = 0; ch < 16; ch++)
+ writel(readl(RTDMAC_RDMCHCR_0(ch)) | BIT(0), RTDMAC_RDMCHCLR(ch));
+}
+
+/**
+ * dbsc5_rtdmac_phyinit_trans_ach() - Load PHY using RTDMAC
+ * @dev: DBSC5 device
+ * @dst: Destination address
+ * @src: Source address
+ * @size: Transfer size
+ */
+static void dbsc5_rtdmac_phyinit_trans_ach(struct udevice *dev, u32 dst, u32 src, u32 size)
+{
+ u32 ch;
+
+ foreach_vphych(dev, ch) {
+ dbsc5_rtdmac_init(ch, DDR_PHY_DMA_TRANS_BASE(ch) + (dst << 2),
+ src, (size + 0x3f) >> 6);
+ dbsc5_rtdmac_start();
+ }
+
+ foreach_vphych(dev, ch)
+ dbsc5_rtdmac_wait(ch);
+
+ dbsc5_rtdmac_stop();
+}
+
+/**
+ * dbsc5_phy_apb_wr() - Write PHY register
+ * @ch: PHY channel
+ * @addr: Register address
+ * @data: Register value
+ */
+static void dbsc5_phy_apb_wr(u32 ch, u32 addr, u32 data)
+{
+ writel(data, DDR_PHY_BASE(ch) + (addr << 2));
+}
+
+/**
+ * dbsc5_phy_apb_wr_ach() - Write PHY register on all channels
+ * @addr: Register address
+ * @data: Register value
+ */
+static void dbsc5_phy_apb_wr_ach(struct udevice *dev, u32 addr, u32 data)
+{
+ u32 ch;
+
+ foreach_vphych(dev, ch)
+ dbsc5_phy_apb_wr(ch, addr, data);
+}
+
+/**
+ * dbsc5_phy_apb_rd() - Read PHY register
+ * @ch: PHY channel
+ * @addr: Register address
+ */
+static u32 dbsc5_phy_apb_rd(u32 ch, u32 addr)
+{
+ return readl(DDR_PHY_BASE(ch) + (addr << 2));
+}
+
+/**
+ * ddrphy_apb_rd_mod_wr() - Read-modify-Write PHY register
+ * @ch: PHY channel
+ * @addr: Register address
+ * @len: Clearing bitmask length
+ * @lsb: Clearing bitmask shift
+ * @data: Register value
+ */
+static void ddrphy_apb_rd_mod_wr(u32 ch, u32 addr, u32 len, u32 lsb, u32 data)
+{
+ u32 msk = 0xffffffff;
+ u32 val;
+
+ if (len != 32)
+ msk = (BIT(len) - 1) << lsb;
+
+ val = dbsc5_phy_apb_rd(ch, addr);
+ val &= ~msk;
+ val |= data << lsb;
+ dbsc5_phy_apb_wr(ch, addr, val);
+}
+
+/**
+ * dbsc5_phy_apb_rd() - Read PHY message block
+ * @ch: PHY channel
+ */
+static u32 dbsc5_phy_apb_msg_rd(u32 ch)
+{
+ u32 ret;
+
+ while (dbsc5_phy_apb_rd(ch, PHY_APBONLY_UCTSHADOWREGS) & BIT(0))
+ ;
+
+ ret = dbsc5_phy_apb_rd(ch, PHY_APBONLY_UCTWRITEONLYSHADOW);
+ dbsc5_phy_apb_wr(ch, PHY_APBONLY_DCTWRITEPROT, 0);
+
+ while (!(dbsc5_phy_apb_rd(ch, PHY_APBONLY_UCTSHADOWREGS) & BIT(0)))
+ ;
+
+ dbsc5_phy_apb_wr(ch, PHY_APBONLY_DCTWRITEPROT, BIT(0));
+
+ return ret;
+}
+
+/**
+ * dbsc5_ddr_config_post() - Set DDR user configuration
+ * @dev: DBSC5 device
+ */
+static void dbsc5_ddr_config_post(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ch, tmp;
+
+ foreach_vphych(dev, ch) {
+ /* 2-Rank settings */
+ if (priv->ch_have_this_cs[1] & (0x3 << (ch * 2)))
+ dbsc5_phy_apb_wr(ch, PHY_PPGC_HWTCONTROLVAL, 0xc3);
+
+ /* Configure IO parameters */
+ /* DRAM Tx ODT for DQ */
+ ddrphy_apb_rd_mod_wr(ch, 0x41036, 3, 7,
+ (priv->dbsc5_board_config->bdcfg_tx_odt >> 4) & 0x7);
+
+ /* DRAM Tx ODT for CA */
+ ddrphy_apb_rd_mod_wr(ch, 0x41036, 3, 11,
+ (priv->dbsc5_board_config->bdcfg_tx_odt) & 0x7);
+
+ /* DRAM Tx NT DQ ODT */
+ tmp = (priv->dbsc5_board_config->bdcfg_tx_ntodt) & 0x7;
+ if (tmp < 0x4) {
+ ddrphy_apb_rd_mod_wr(ch, 0x4105A, 1, 6, 0x0);
+ tmp += 4;
+ }
+ ddrphy_apb_rd_mod_wr(ch, 0x4105A, 3, 12, tmp);
+
+ /* DRAM Tx NT ODT */
+ ddrphy_apb_rd_mod_wr(ch, 0x41036, 1, 10,
+ ((priv->dbsc5_board_config->bdcfg_tx_ntodt) >> 4) & 0x1);
+
+ /* DRAM Tx Per-pin DFE */
+ ddrphy_apb_rd_mod_wr(ch, 0x4105A, 1, 7,
+ (priv->dbsc5_board_config->bdcfg_tx_dfe) & 0x1);
+
+ /* DRAM Rx DRV */
+ ddrphy_apb_rd_mod_wr(ch, 0x41026, 3, 7,
+ (priv->dbsc5_board_config->bdcfg_rx_drv) & 0x7);
+
+ /* Link ECC setting */
+ if (priv->link_ecc_en) {
+ ddrphy_apb_rd_mod_wr(ch, 0x41052, 1, 11, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, 0x41052, 1, 13, 0x1);
+ }
+ }
+}
+
+/**
+ * dbsc5_ddr_smb_config() - Set user configuration
+ * @dev: DBSC5 device
+ */
+static void dbsc5_ddr_smb_config(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ch, val;
+
+ foreach_vphych(dev, ch) {
+ /* Frequency settings */
+ if (priv->ddr_mbps < (6401 * priv->ddr_mbpsdiv)) {
+ /* 5501 - 6400 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_DRAMFREQ, 16, 16, 0x1900);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_A0, 8, 16, 0xB0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_A1, 8, 24, 0xB0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_B0, 8, 0, 0xB0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_B1, 8, 8, 0xB0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_A0, 8, 16, 0xBB);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_A1, 8, 24, 0xBB);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_B0, 8, 0, 0xBB);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_B1, 8, 8, 0xBB);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_ALT_RL, 8, 24, 0x3B);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MAIN_RL, 8, 0, 0x37);
+ } else if (priv->ddr_mbps < (7501 * priv->ddr_mbpsdiv)) {
+ /* 6401 - 7500 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_DRAMFREQ, 16, 16, 0x1D48);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_A0, 8, 16, 0xC0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_A1, 8, 24, 0xC0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_B0, 8, 0, 0xC0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_B1, 8, 8, 0xC0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_A0, 8, 16, 0xCC);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_A1, 8, 24, 0xCC);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_B0, 8, 0, 0xCC);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_B1, 8, 8, 0xCC);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_ALT_RL, 8, 24, 0x4B);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MAIN_RL, 8, 0, 0x43);
+ } else if (priv->ddr_mbps < (8534 * priv->ddr_mbpsdiv)) {
+ /* 7501 - 8533 -- None */
+ } else {
+ /* 8534 - 9600 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_DRAMFREQ, 16, 16, 0x2580);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_DCAOPTS, 8, 8, 0x44);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_A0, 8, 16, 0xE0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_A1, 8, 24, 0xE0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_B0, 8, 0, 0xE0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR1_B1, 8, 8, 0xE0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_A0, 8, 16, 0xEE);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_A1, 8, 24, 0xEE);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_B0, 8, 0, 0xEE);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR2_B1, 8, 8, 0xEE);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_ALT_RL, 8, 24, 0x63);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MAIN_RL, 8, 0, 0x57);
+ }
+
+ /* 2Rank settings */
+ if (priv->ch_have_this_cs[1] & (0x3 << (ch * 2))) {
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_CSPRESENTCHA, 2, 8, 0x3);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_CSPRESENTCHB, 2, 0, 0x3);
+ }
+
+ /* Board settings, data byte swap */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_UPPERLOWERBYTE, 4, 8, priv->upper_lower_byte[ch]);
+
+ /* Configure Training settings */
+ /* SOC Rx DFE function */
+ if (!(priv->dbsc5_board_config->bdcfg_rx_dfe & BIT(0))) {
+ /* Rx DFE Disable */
+ /* RxDFEBitTimeControl[4] */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXDFEBITTIMECONTROL, 1, 4, 0x1);
+ } else {
+ /* Rx DFE DQ 1tap */
+ /* RxDFEOpt[6] */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXDFEOPT, 1, 30, 0);
+ /* RxClk scan skip */
+ /* RxDFEBitTimeControl[6] */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXDFEBITTIMECONTROL, 1, 6, 1);
+ }
+
+ /* DRAM Tx DFE function */
+ val = priv->dbsc5_board_config->bdcfg_tx_dfe & 0x7;
+ if (val == 0x0) {
+ /* Tx DFE Disable */
+ /* PHY_APB_SEQUENCECTRL[10] */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_SEQUENCECTRL, 1, 10, 0x0);
+ } else {
+ /* Select Tx DFE step */
+ /* DRAM Tx DFE for Upper */
+ /* PHY_APB_MR24_A0, PHY_APB_MR24_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_A0, 3, 20, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_A1, 3, 28, val);
+ /* PHY_APB_MR24_B0, PHY_APB_MR24_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_B0, 3, 4, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_B1, 3, 12, val);
+
+ /* DRAM Tx DFE for Lower */
+ /* PHY_APB_MR24_A0, PHY_APB_MR24_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_A0, 3, 16, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_A1, 3, 24, val);
+ /* PHY_APB_MR24_B0, PHY_APB_MR24_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_B0, 3, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR24_B1, 3, 8, val);
+ }
+
+ /* DRAM Tx Per-pin DFE */
+ val = (priv->dbsc5_board_config->bdcfg_tx_dfe >> 4) & 0x1;
+ /* PHY_APB_MR41_A0, PHY_APB_MR41_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_A0, 1, 16, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_A1, 1, 24, val);
+ /* PHY_APB_MR41_B0, PHY_APB_MR41_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_B0, 1, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_B1, 1, 8, val);
+ /* TxDFETrainOpt[0] */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_TXDFETRAINOPT, val, 1, 0);
+
+ /* DRAM Rx DCA function */
+ /* PHY_APB_SEQUENCECTRL[7] */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_SEQUENCECTRL, 1, 7,
+ priv->dbsc5_board_config->bdcfg_rx_dca & 0x1);
+
+ /* DRAM Tx DCA function */
+ /* PHY_APB_SEQUENCECTRL[6] */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_SEQUENCECTRL, 1, 6,
+ priv->dbsc5_board_config->bdcfg_tx_dca & 0x1);
+
+ /* CA Vref training initial value */
+ val = priv->dbsc5_board_config->bdcfg_ca_vref & 0x7F;
+ /* PHY_APB_MR12_A0, PHY_APB_MR12_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR12_A0, 7, 16, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR12_A1, 7, 24, val);
+ /* PHY_APB_MR12_B0, PHY_APB_MR12_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR12_B0, 7, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR12_B1, 7, 8, val);
+
+ /* Rx Vref training range */
+ /* RxVrefStartPat, RxVrefStartPrbs */
+ val = priv->dbsc5_board_config->bdcfg_rx_vref & 0xFFFF;
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXVREFSTARTPAT, 16, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXVREFSTARTPRBS, 16, 16, val);
+ /* RxVrefEndPat, RxVrefEndPrbs */
+ val = (priv->dbsc5_board_config->bdcfg_rx_vref >> 16) & 0xFFFF;
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXVREFENDPAT, 16, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXVREFENDPRBS, 16, 16, val);
+ /* RxVrefStepPat, RxVrefStepPrbs */
+ val = priv->dbsc5_board_config->bdcfg_rx_vref_step & 0xFFFF;
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXVREFSTEPPAT, 16, 16, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_RXVREFSTEPPRBS, 16, 0, val);
+
+ /* Tx Vref training range */
+ /* TxVrefStart */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_TXVREFSTART, 8, 0,
+ priv->dbsc5_board_config->bdcfg_tx_vref & 0xFF);
+ /* TxVrefEnd */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_TXVREFEND, 8, 8,
+ (priv->dbsc5_board_config->bdcfg_tx_vref >> 8) & 0xFF);
+ /* TxVrefStep */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_TXVREFSTEP, 8, 16,
+ (priv->dbsc5_board_config->bdcfg_tx_vref >> 16) & 0xFF);
+
+ /* FW message setting */
+ /* HdtCtrl */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_HDTCTRL, 8, 16, 0xff);
+
+ /* Configure IO parameters */
+ /* DRAM Tx ODT for DQ */
+ val = (priv->dbsc5_board_config->bdcfg_tx_odt >> 4) & 0x7;
+ /* PHY_APB_MR11_A0, PHY_APB_MR11_B0 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_A0, 3, 16, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_A1, 3, 24, val);
+ /* PHY_APB_MR11_A1, PHY_APB_MR11_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_B0, 3, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_B1, 3, 8, val);
+
+ /* DRAM Tx ODT for CA */
+ val = priv->dbsc5_board_config->bdcfg_tx_odt & 0x7;
+ /* PHY_APB_MR11_A0, PHY_APB_MR11_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_A0, 3, 20, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_A1, 3, 28, val);
+ /* PHY_APB_MR11_B0, PHY_APB_MR11_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_B0, 3, 4, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_B1, 3, 12, val);
+
+ /* DRAM Tx NT DQ ODT */
+ val = priv->dbsc5_board_config->bdcfg_tx_ntodt & 0x7;
+ /* PHY_APB_MR41_A0, PHY_APB_MR41_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_A0, 3, 21, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_A1, 3, 29, val);
+ /* PHY_APB_MR41_B0, PHY_APB_MR41_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_B0, 3, 5, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR41_B1, 3, 13, val);
+
+ /* DRAM Tx NT ODT */
+ val = (priv->dbsc5_board_config->bdcfg_tx_ntodt >> 4) & 0x1;
+ /* PHY_APB_MR11_A0, PHY_APB_MR11_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_A0, 1, 19, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_A1, 1, 27, val);
+ /* PHY_APB_MR11_B0, PHY_APB_MR11_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_B0, 1, 3, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR11_B1, 1, 11, val);
+
+ /* DRAM Rx DRV */
+ val = priv->dbsc5_board_config->bdcfg_rx_drv & 0x7;
+ /* PHY_APB_MR3_A0, PHY_APB_MR3_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR3_A0, 3, 16, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR3_A1, 3, 24, val);
+ /* PHY_APB_MR3_B0, PHY_APB_MR3_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR3_B0, 3, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR3_B1, 3, 8, val);
+
+ /* DRAM Rx Pre-emphasis */
+ val = ((priv->dbsc5_board_config->bdcfg_rx_emphasis >> 12) & 0x3);
+ val |= ((priv->dbsc5_board_config->bdcfg_rx_emphasis >> 8) & 0x3) << 2;
+ val |= ((priv->dbsc5_board_config->bdcfg_rx_emphasis >> 4) & 0x3) << 4;
+ val |= (priv->dbsc5_board_config->bdcfg_rx_emphasis & 0x3) << 6;
+ /* PHY_APB_MR58_A0, PHY_APB_MR58_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR58_A0, 8, 16, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR58_A1, 8, 24, val);
+ /* PHY_APB_MR58_B0, PHY_APB_MR58_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR58_B0, 8, 0, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR58_B1, 8, 8, val);
+
+ /* Link ECC setting */
+ if (priv->link_ecc_en) {
+ /* PHY_APB_MR22_A0, PHY_APB_MR22_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_A0, 1, 20, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_A1, 1, 28, 0x1);
+ /* PHY_APB_MR22_B0, PHY_APB_MR22_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_B0, 1, 4, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_B1, 1, 12, 0x1);
+ /* PHY_APB_MR22_A0, PHY_APB_MR22_A1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_A0, 1, 22, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_A1, 1, 30, 0x1);
+ /* PHY_APB_MR22_B0, PHY_APB_MR22_B1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_B0, 1, 6, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MR22_B1, 1, 14, 0x1);
+ /* PHY_APB_ALT_RL, PHY_APB_MAIN_RL */
+ if (priv->ddr_mbps < (7501 * priv->ddr_mbpsdiv)) {
+ /* 6401 - 7500 */
+ val = 0x5B;
+ } else {
+ /* 7501 - 8533 */
+ val = 0x4F;
+ }
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_ALT_RL, 8, 24, val);
+ ddrphy_apb_rd_mod_wr(ch, PHY_APB_MAIN_RL, 8, 0, val);
+ }
+ }
+}
+
+/**
+ * dbsc5_phy_data_load() - Load PHY data memory
+ * @dev: DBSC5 device
+ */
+static void dbsc5_phy_data_load(struct udevice *dev)
+{
+ dbsc5_phy_apb_wr_ach(dev, PHY_DRTUB_STARTDCCMCLEAR, 0x0);
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICROCONTMUXSEL, 0x0);
+ dbsc5_rtdmac_phyinit_trans_ach(dev, DDR_PHY_DCCM_OFS,
+ (uintptr_t)DMAC_TRANS_DCCM,
+ ARRAY_SIZE(DMAC_TRANS_DCCM) * 4);
+ dbsc5_ddr_smb_config(dev);
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICROCONTMUXSEL, 0x1);
+}
+
+/**
+ * dbsc5_phy_init_load() - Load PHY init memory
+ * @dev: DBSC5 device
+ */
+static void dbsc5_phy_init_load(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ch, i;
+
+ foreach_vphych(dev, ch)
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab4); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab4[i].addr, cpu_trans_tab4[i].data);
+
+ if (priv->ddr_mbps < (6401 * priv->ddr_mbpsdiv)) /* 5501 - 6400 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL5, 0x2d56);
+
+ foreach_vphych(dev, ch) {
+ if ((priv->ch_have_this_cs[1] & (0x3 << (ch * 2))) != 0x0) {
+ dbsc5_phy_apb_wr(ch, PHY_PPGC_HWTLPCSENA, 0x3);
+ dbsc5_phy_apb_wr(ch, PHY_INITENG_SEQ0BGPR14, 0x3);
+ dbsc5_phy_apb_wr(ch, PHY_PPGC_HWTLPCSENB, 0x3);
+ dbsc5_phy_apb_wr(ch, PHY_INITENG_SEQ0BGPR15, 0x3);
+ }
+ }
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICROCONTMUXSEL, 0);
+ dbsc5_phy_apb_wr_ach(dev, 0x41000, 0);
+ dbsc5_phy_apb_wr_ach(dev, 0x41001, 0);
+ dbsc5_phy_apb_wr_ach(dev, 0x41002, 0);
+ dbsc5_phy_apb_wr_ach(dev, 0x41003, 0);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, DDR_PHY_ACSM_OFS,
+ (uintptr_t)DMAC_TRANS_ACSM,
+ ARRAY_SIZE(DMAC_TRANS_ACSM) * 4);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, DDR_PHY_PIE_OFS,
+ (uintptr_t)DMAC_TRANS_PIE,
+ ARRAY_SIZE(DMAC_TRANS_PIE) * 4);
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_SEQUENCEROVERRIDE, 0x600);
+ dbsc5_phy_apb_wr_ach(dev, PHY_PPGC_ACSMNOPADDR, 0x0);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_PPGC_ACSMSTARTADDRXLATVAL0,
+ (uintptr_t)DATA_A, 64);
+
+ foreach_vphych(dev, ch)
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab5); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab5[i].addr, cpu_trans_tab5[i].data);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_PPGC_ACSMSTOPADDRXLATVAL0,
+ (uintptr_t)DATA_B, 64);
+
+ foreach_vphych(dev, ch)
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab6); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab6[i].addr, cpu_trans_tab6[i].data);
+
+ if (priv->ddr_mbps < (6401 * priv->ddr_mbpsdiv)) /* 5501 - 6400 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_PPGC_ACSMRPTCNTOVERRIDE, 0x2);
+ else if (priv->ddr_mbps < (7501 * priv->ddr_mbpsdiv)) /* 6401 - 7500 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_PPGC_ACSMRPTCNTOVERRIDE, 0x3);
+ else if (priv->ddr_mbps < (8534 * priv->ddr_mbpsdiv)) { /* 7501 - 8533 */
+ } else /* 8534 - 9600 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_PPGC_ACSMRPTCNTOVERRIDE, 0x5);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, 0x41004, (uintptr_t)ACSM_0, 384);
+
+ if (priv->ddr_mbps < (6401 * priv->ddr_mbpsdiv)) { /* 5501 - 6400 */
+ dbsc5_phy_apb_wr_ach(dev, 0x41009, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41011, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41016, 0xD848);
+ dbsc5_phy_apb_wr_ach(dev, 0x41019, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x4101E, 0xDDC8);
+ dbsc5_phy_apb_wr_ach(dev, 0x41021, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41029, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41031, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41039, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41045, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x4104D, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41055, 0x4B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x4105D, 0x4B000000);
+ } else if (priv->ddr_mbps < (7501 * priv->ddr_mbpsdiv)) { /* 6401 - 7500 */
+ dbsc5_phy_apb_wr_ach(dev, 0x41016, 0xE048);
+ dbsc5_phy_apb_wr_ach(dev, 0x4101E, 0xE648);
+ } else if (priv->ddr_mbps < (8534 * priv->ddr_mbpsdiv)) { /* 7501 - 8533 */
+ /* Nothing */
+ } else { /* 8534 - 9600 */
+ dbsc5_phy_apb_wr_ach(dev, 0x41009, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41011, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41016, 0xF048);
+ dbsc5_phy_apb_wr_ach(dev, 0x41019, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x4101E, 0xF748);
+ dbsc5_phy_apb_wr_ach(dev, 0x41021, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41029, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41031, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41039, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41045, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x4104D, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x41055, 0x6B000000);
+ dbsc5_phy_apb_wr_ach(dev, 0x4105D, 0x6B000000);
+ }
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, 0x4110C, (uintptr_t)ACSM_123, 384);
+ dbsc5_rtdmac_phyinit_trans_ach(dev, 0x41214, (uintptr_t)ACSM_123, 384);
+ dbsc5_rtdmac_phyinit_trans_ach(dev, 0x4131C, (uintptr_t)ACSM_123, 384);
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_SEQUENCEROVERRIDE, 0x400);
+ dbsc5_phy_apb_wr_ach(dev, PHY_DRTUB_PIEINITVECSEL, 0x5821);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_INITENG_SEQ0BDISABLEFLAG0,
+ (uintptr_t)DATA_C, 64);
+
+ foreach_vphych(dev, ch)
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab7); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab7[i].addr, cpu_trans_tab7[i].data);
+
+ dbsc5_ddr_config_post(dev);
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_DRTUB_UCCLKHCLKENABLES, 0x6);
+
+ if (priv->ddr_mbps < (6481 * priv->ddr_mbpsdiv)) { /* 5401 - 6480 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL1, 0x1C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL4, 0x1C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL5, 0x2D56);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG0, 0x1009);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG1, 0x5060);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG2, 0x6B01);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG3, 0x423);
+ } else if (priv->ddr_mbps < (8537 * priv->ddr_mbpsdiv)) { /* 6481 - 8536 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL1, 0x2C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL4, 0x2C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL5, 0x1956);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG0, 0x1009);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG1, 0x5060);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG2, 0x6B01);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG3, 0x423);
+ } else { /* 8537 - 9600 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL1, 0x2C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL4, 0x2C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL5, 0x1956);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG0, 0x1009);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG1, 0x5060);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG2, 0x6B01);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG3, 0x423);
+ }
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICROCONTMUXSEL, 0x1);
+}
+
+/**
+ * dbsc5_phy_training() - Perform PHY training and read message block back
+ * @dev: DBSC5 device
+ */
+static u32 dbsc5_phy_training(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 phytrainingok = 0;
+ u32 fail_flag = 0;
+ u32 ch, val;
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICROCONTMUXSEL, 0x1);
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICRORESET, 0x9);
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICRORESET, 0x1);
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICRORESET, 0x0);
+
+ while ((phytrainingok != priv->ddr_phyvalid) && !fail_flag) {
+ foreach_vphych(dev, ch) {
+ val = dbsc5_phy_apb_msg_rd(ch);
+ if (val == 0x7) /* Training complete */
+ phytrainingok |= BIT(ch);
+ else if (val == 0xFF) /* Training FAIL */
+ fail_flag = 1;
+ }
+ }
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICRORESET, 1);
+ dbsc5_phy_apb_wr_ach(dev, PHY_APBONLY_MICROCONTMUXSEL, 0);
+
+ return phytrainingok;
+}
+
+/**
+ * dbsc5_ddr_config() - Configure DBSC5 registers
+ * @dev: DBSC5 device
+ */
+static void dbsc5_ddr_config(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ch, ddr_ch, i, tmp, val;
+
+ foreach_vphych(dev, ch) {
+ /* Frequency settings */
+ if (priv->ddr_mbps < (6401 * priv->ddr_mbpsdiv)) { /* 5501 - 6400 */
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab3_6400); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab3_6400[i].addr, cpu_trans_tab3_6400[i].data);
+ } else if (priv->ddr_mbps < (7501 * priv->ddr_mbpsdiv)) { /* 6401 - 7500 */
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab3_7500); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab3_7500[i].addr, cpu_trans_tab3_7500[i].data);
+ } else if (priv->ddr_mbps < (8534 * priv->ddr_mbpsdiv)) { /* 7501 - 8533 */
+ /* Nothing */
+ } else { /* 8534 - 9600 */
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab3_9600); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab3_9600[i].addr, cpu_trans_tab3_9600[i].data);
+ }
+
+ /* 2-Rank settings */
+ if (priv->ch_have_this_cs[1] & (0x3 << (ch * 2))) {
+ /* PHY_ACx_P0_PCLKACLNDIS[9] : Tx SEC lane1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_AC_PCLKACLNDIS(0), 1, 9, 0x0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_AC_PCLKACLNDIS(1), 1, 9, 0x0);
+ /* PHY_ACx_P0_DFICLKACLNDIS[9] : Tx SEC lane1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_AC_DFICLKACLNDIS(0), 1, 9, 0x0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_AC_DFICLKACLNDIS(1), 1, 9, 0x0);
+ /* PHY_ACx_P0_ACLNDISABLE[9] : Tx SEC lane1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_AC_ACLNDISABLE(0), 1, 9, 0x0);
+ ddrphy_apb_rd_mod_wr(ch, PHY_AC_ACLNDISABLE(1), 1, 9, 0x0);
+ /* PHY_DBYTEx_P0_PPTCTLSTATIC[1] : PptEnDqs2DqTg1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(0), 1, 1, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(1), 1, 1, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(2), 1, 1, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(3), 1, 1, 0x1);
+ /* PHY_DBYTEx_P0_PPTCTLSTATIC[5] : PptEnWck2DqoTg1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(0), 1, 5, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(1), 1, 5, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(2), 1, 5, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(3), 1, 5, 0x1);
+ /* PHY_DBYTEx_P0_PPTCTLSTATIC[9] : PptEnRxEnDlyTg1 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(0), 1, 9, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(1), 1, 9, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(2), 1, 9, 0x1);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(3), 1, 9, 0x1);
+ }
+
+ /* BOARD SETTINGS (CA, DQ, DMI) */
+ /* CA_SWAP_CHA */
+ ddr_ch = (ch * 2);
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_ca_swap & 0xfffffff;
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA0TODFI(0), val & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA1TODFI(0), (val >> 4) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA2TODFI(0), (val >> 8) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA3TODFI(0), (val >> 12) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA4TODFI(0), (val >> 16) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA5TODFI(0), (val >> 20) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA6TODFI(0), (val >> 24) & 0xf);
+
+ /* DQ_SWAP_CHA_SLICE0 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dq_swap[0] & 0xffffffff;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ0LNSEL(0), val & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ1LNSEL(0), (val >> 4) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ2LNSEL(0), (val >> 8) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ3LNSEL(0), (val >> 12) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ4LNSEL(0), (val >> 16) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ5LNSEL(0), (val >> 20) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ6LNSEL(0), (val >> 24) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ7LNSEL(0), (val >> 28) & 0xf);
+
+ /* DM_SWAP_CHA_SLICE0 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dm_swap[0] & 0xf;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ8LNSEL(0), val & 0xf);
+
+ /* DQ_SWAP_CHA_SLICE1 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dq_swap[1] & 0xffffffff;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ0LNSEL(1), val & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ1LNSEL(1), (val >> 4) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ2LNSEL(1), (val >> 8) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ3LNSEL(1), (val >> 12) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ4LNSEL(1), (val >> 16) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ5LNSEL(1), (val >> 20) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ6LNSEL(1), (val >> 24) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ7LNSEL(1), (val >> 28) & 0xf);
+
+ /* DM_SWAP_CHA_SLICE1 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dm_swap[1] & 0xf;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ8LNSEL(1), val & 0xf);
+
+ /* CA_SWAP_CHB */
+ ddr_ch = ((ch * 2) + 1);
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_ca_swap & 0xfffffff;
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA0TODFI(1), val & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA1TODFI(1), (val >> 4) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA2TODFI(1), (val >> 8) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA3TODFI(1), (val >> 12) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA4TODFI(1), (val >> 16) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA5TODFI(1), (val >> 20) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_AC_MAPCA6TODFI(1), (val >> 24) & 0xf);
+
+ /* DQ_SWAP_CHB_SLICE0 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dq_swap[0] & 0xffffffff;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ0LNSEL(2), val & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ1LNSEL(2), (val >> 4) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ2LNSEL(2), (val >> 8) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ3LNSEL(2), (val >> 12) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ4LNSEL(2), (val >> 16) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ5LNSEL(2), (val >> 20) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ6LNSEL(2), (val >> 24) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ7LNSEL(2), (val >> 28) & 0xf);
+
+ /* DM_SWAP_CHB_SLICE0 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dm_swap[0] & 0xf;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ8LNSEL(2), val & 0xf);
+
+ /* DQ_SWAP_CHB_SLICE1 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dq_swap[1] & 0xffffffff;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ0LNSEL(3), val & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ1LNSEL(3), (val >> 4) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ2LNSEL(3), (val >> 8) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ3LNSEL(3), (val >> 12) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ4LNSEL(3), (val >> 16) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ5LNSEL(3), (val >> 20) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ6LNSEL(3), (val >> 24) & 0xf);
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ7LNSEL(3), (val >> 28) & 0xf);
+
+ /* DM_SWAP_CHB_SLICE1 */
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dm_swap[1] & 0xf;
+ dbsc5_phy_apb_wr(ch, PHY_DBYTE_DQ8LNSEL(3), val & 0xf);
+
+ /* BOARD SETTINGS (DATA_BYTE_SWAP) */
+ priv->upper_lower_byte[ch] = 0x0;
+ ddr_ch = ch * 2;
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dqs_swap;
+ if ((val & 0xff) == 0x1) {
+ /* PHY_DBYTEx_P0_PPTCTLSTATIC[3][2] : DOCByteSelTg1/0 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(0), 2, 2, 0x3);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(1), 2, 2, 0x0);
+ priv->upper_lower_byte[ch] |= 0x3;
+ }
+
+ ddr_ch = (ch * 2) + 1;
+ val = priv->dbsc5_board_config->ch[ddr_ch].bdcfg_dqs_swap;
+ if ((val & 0xFF) == 0x1) {
+ /* PHY_DBYTEx_P0_PPTCTLSTATIC[3][2] : DOCByteSelTg1/0 */
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(2), 2, 2, 0x3);
+ ddrphy_apb_rd_mod_wr(ch, PHY_DBYTE_PPTCTLSTATIC(3), 2, 2, 0x0);
+ priv->upper_lower_byte[ch] |= 0xc;
+ }
+ }
+
+ /* Configure IO parameters */
+ /* SOC Tx DRV for DQ */
+ val = priv->dbsc5_board_config->bdcfg_tx_drv & 0xf;
+ tmp = (val << 4) | val;
+ for (i = 0; i < 8; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMDBYTE_TXIMPEDANCEDQ(i), tmp);
+
+ /* SOC Tx DRV for DQS */
+ val = (priv->dbsc5_board_config->bdcfg_tx_drv >> 4) & 0xF;
+ tmp = (val << 8) | val;
+ for (i = 0; i < 8; i += 2)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMDBYTE_TXIMPEDANCEDQS(i), tmp);
+
+ /* SOC Tx DRV for WCK */
+ val = (priv->dbsc5_board_config->bdcfg_tx_drv >> 8) & 0xF;
+ tmp = (val << 12) | (val << 8) | (val << 4) | val;
+ for (i = 0; i < 8; i += 2)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMDBYTE_TXIMPEDANCEDQS(i + 1), tmp);
+
+ /* SOC Tx DRV for CK */
+ val = (priv->dbsc5_board_config->bdcfg_tx_drv >> 12) & 0xF;
+ tmp = (val << 4) | val;
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXIMPEDANCEAC(5), tmp);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXIMPEDANCEAC(12), tmp);
+
+ /* SOC Tx DRV for AC */
+ val = (priv->dbsc5_board_config->bdcfg_tx_drv >> 16) & 0xF;
+ tmp = (val << 4) | val;
+ for (i = 0; i < 4; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXIMPEDANCEAC(i), tmp);
+ for (i = 0; i < 4; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXIMPEDANCEAC(i + 7), tmp);
+
+ /* SOC Tx FFC for DQ */
+ /* Rise */
+ val = (priv->dbsc5_board_config->bdcfg_tx_ffc >> 28) & 0xF;
+ tmp = val;
+ /* Fall */
+ val = (priv->dbsc5_board_config->bdcfg_tx_ffc >> 24) & 0xF;
+ tmp |= (val << 4);
+ for (i = 0; i < 8; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMDBYTE_TXDQSLEW(i), tmp);
+
+ /* SOC Tx FFC for CA */
+ /* Rise */
+ val = (priv->dbsc5_board_config->bdcfg_tx_ffc >> 20) & 0xF;
+ tmp = val;
+ /* Fall */
+ val = (priv->dbsc5_board_config->bdcfg_tx_ffc >> 16) & 0xF;
+ tmp |= (val << 4);
+ for (i = 0; i < 4; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXSLEWAC(i), tmp);
+ for (i = 0; i < 4; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXSLEWAC(i + 7), tmp);
+
+ /* SOC Tx FFC for CK */
+ /* Rise */
+ val = (priv->dbsc5_board_config->bdcfg_tx_ffc >> 12) & 0xF;
+ tmp = val;
+ /* Fall */
+ val = (priv->dbsc5_board_config->bdcfg_tx_ffc >> 8) & 0xF;
+ tmp |= (val << 4);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXSLEWAC(5), tmp);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_TXSLEWAC(12), tmp);
+
+ /* SOC Rx ODT for DQ */
+ val = priv->dbsc5_board_config->bdcfg_rx_odt & 0xF;
+ tmp = val << 4;
+ for (i = 0; i < 8; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMDBYTE_ODTIMPEDANCEDQ(i), tmp);
+
+ /* SOC Rx ODT for DQS */
+ val = (priv->dbsc5_board_config->bdcfg_rx_odt >> 4) & 0xF;
+ tmp = (val << 12) | (val << 8);
+ for (i = 0; i < 8; i += 2)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMDBYTE_ODTIMPEDANCEDQS(i), tmp);
+
+ /* SOC Rx ODT for WCK */
+ val = (priv->dbsc5_board_config->bdcfg_rx_odt >> 8) & 0xF;
+ tmp = (val << 12) | (val << 8);
+ for (i = 0; i < 8; i += 2)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMDBYTE_ODTIMPEDANCEDQS(i + 1), tmp);
+
+ /* SOC Rx ODT for CK */
+ val = (priv->dbsc5_board_config->bdcfg_rx_odt >> 12) & 0xF;
+ tmp = val << 4;
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_ODTIMPEDANCEAC(5), tmp);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_ODTIMPEDANCEAC(12), tmp);
+
+ /* SOC Rx ODT for AC */
+ val = (priv->dbsc5_board_config->bdcfg_rx_odt >> 16) & 0xF;
+ tmp = val << 4;
+ for (i = 0; i < 5; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_ODTIMPEDANCEAC(i), tmp);
+ for (i = 0; i < 5; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMAC_ODTIMPEDANCEAC(i + 7), tmp);
+
+ /* Link ECC setting */
+ if (priv->link_ecc_en)
+ for (i = 0; i < 4; i++)
+ dbsc5_phy_apb_wr_ach(dev, PHY_DBYTE_ENABLEWRITELINKECC(i), 0x1);
+}
+
+/**
+ * dbsc5_phy_init() - Initialize DBSC5 PHY
+ * @dev: DBSC5 device
+ */
+static void dbsc5_phy_init(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ch, i;
+
+ /* Initialize PHY Configuration */
+ foreach_vphych(dev, ch)
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab1); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab1[i].addr, cpu_trans_tab1[i].data);
+ foreach_vphych(dev, ch)
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab2); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab2[i].addr, cpu_trans_tab2[i].data);
+
+ if (priv->ddr_mbps < (6481 * priv->ddr_mbpsdiv)) { /* 5401 - 6480 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL1, 0x808);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL4, 0x1C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL5, 0x2E9A);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG0, 0x1009);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG1, 0x5060);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG2, 0x6B01);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG3, 0x423);
+ } else if (priv->ddr_mbps < (8537 * priv->ddr_mbpsdiv)) { /* 6481 - 8536 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL1, 0x1008);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL4, 0x2C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL5, 0x1A9A);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG0, 0x1009);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG1, 0x5060);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG2, 0x6B01);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG3, 0x423);
+ } else {
+ /* 8537 - 9600 */
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL1, 0x1008);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL4, 0x2C7F);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLCTRL5, 0x1A9A);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG0, 0x1009);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG1, 0x5060);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG2, 0x6B01);
+ dbsc5_phy_apb_wr_ach(dev, PHY_HMMAS_CPLLUPLLPROG3, 0x423);
+ }
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_DRTUB_UCCLKHCLKENABLES, 0x5);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, DDR_PHY_ICCM_OFS,
+ (uintptr_t)DMAC_TRANS_ICCM,
+ ARRAY_SIZE(DMAC_TRANS_ICCM) * 4);
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_DRTUB_UCCLKHCLKENABLES, 0x7);
+
+ foreach_vphych(dev, ch)
+ for (i = 0; i < ARRAY_SIZE(cpu_trans_tab3); i++)
+ dbsc5_phy_apb_wr(ch, cpu_trans_tab3[i].addr, cpu_trans_tab3[i].data);
+
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_PPGC_ACSMDONE, ((uintptr_t)DATA_3_1), 128);
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_INITENG_SEQ0BGPR1, ((uintptr_t)DATA_3_2), 128);
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_INITENG_SEQ0BDLY0, ((uintptr_t)DATA_3_3), 64);
+ for (i = 0; i < 8; i += 2) {
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_HMDBYTE_VREGCTRL1DQ(i),
+ (uintptr_t)DATA_3_4, 256);
+ dbsc5_rtdmac_phyinit_trans_ach(dev, PHY_HMDBYTE_VREGCTRL1DQ(i + i),
+ (uintptr_t)DATA_3_5, 256);
+ }
+
+ dbsc5_ddr_config(dev);
+
+ dbsc5_phy_apb_wr_ach(dev, PHY_DRTUB_STARTDCCMCLEAR, 0x1);
+}
+
+/**
+ * dbsc5_dfi_wait_init_complete() - Wait DFI init completion
+ * @dev: DBSC5 device
+ */
+static void dbsc5_dfi_wait_init_complete(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 retry = 0, phytrainingok = 0;
+ const u32 RETRY_MAX = 0x10000;
+ u32 ch, val;
+
+ while (retry < RETRY_MAX) {
+ foreach_vch(dev, ch) {
+ val = readl(DBSC_DBDFISTAT(ch));
+ if (val & 0x1)
+ phytrainingok |= BIT(ch);
+ }
+
+ if (phytrainingok == priv->ddr_dramvalid)
+ break;
+
+ retry++;
+ }
+}
+
+/**
+ * dbsc5_dfi_init_start() - Start DFI initialization
+ * @dev: DBSC5 device
+ */
+static void dbsc5_dfi_init_start(struct udevice *dev)
+{
+ u32 ch;
+
+ foreach_vch(dev, ch)
+ writel(0x21, DBSC_DBDFICNT(ch));
+
+ dbsc5_dfi_wait_init_complete(dev);
+
+ foreach_vch(dev, ch)
+ writel(0x20, DBSC_DBDFICNT(ch));
+}
+
+/**
+ * dbsc5_ddr_mode_register_set() - Set DDR mode registers
+ * @dev: DBSC5 device
+ */
+static void dbsc5_ddr_mode_register_set(struct udevice *dev)
+{
+ dbsc5_send_dbcmd(dev, 0xE841C24); /* MR28 */
+ dbsc5_send_dbcmd(dev, 0xE842540);
+ dbsc5_send_dbcmd(dev, 0xE842840);
+}
+
+/**
+ * dbsc5_ddr_mode_register_read() - Read DDR mode registers
+ * @dev: DBSC5 device
+ */
+static void dbsc5_ddr_mode_register_read(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ch, val;
+
+ val = priv->dbsc5_board_config->bdcfg_rfm_chk;
+ if (!val)
+ return;
+
+ dbsc5_send_dbcmd(dev, 0xF801B00); /* MR27:0 */
+ dbsc5_send_dbcmd(dev, 0xF803900); /* MR57:0 */
+
+ foreach_vphych(dev, ch) {
+ if ((priv->ch_have_this_cs[1] & (0x3 << (ch * 2)))) {
+ dbsc5_send_dbcmd_ch(ch, 0xF811B00); /* MR27:1 */
+ dbsc5_send_dbcmd_ch(ch, 0xF813900); /* MR57:1 */
+ }
+ }
+}
+
+/**
+ * dbsc5_phy_pll_lock_status_read() - Read PHY PLL lock status
+ * @dev: DBSC5 device
+ */
+static u32 dbsc5_phy_pll_lock_status_read(struct udevice *dev)
+{
+ u32 ch, ret = 0;
+
+ foreach_vphych(dev, ch)
+ ret |= (readl(DBSC_DBPDSTAT01(ch)) & BIT(0)) << ch;
+
+ return ret;
+}
+
+/**
+ * dbsc5_ddr_initialize() - Initialize DDR
+ * @dev: DBSC5 device
+ */
+static int dbsc5_ddr_initialize(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ddrphy_pll_lock_ok, phytrainingok;
+
+ dbsc5_regset_unlock(dev);
+ dbsc5_msres_status_set(dev, MODULE_STANDBY);
+ dbsc5_init_pll3(dev);
+ dbsc5_msres_status_set(dev, MODULE_RUN);
+ dbsc5_phy_init(dev);
+ dbsc5_dbsc_regset_pre(dev);
+ dbsc5_phy_data_load(dev);
+ phytrainingok = dbsc5_phy_training(dev);
+ if (phytrainingok != priv->ddr_phyvalid)
+ return -EINVAL;
+
+ dbsc5_phy_init_load(dev);
+ dbsc5_dfi_init_start(dev);
+ ddrphy_pll_lock_ok = dbsc5_phy_pll_lock_status_read(dev);
+ if (ddrphy_pll_lock_ok != priv->ddr_phyvalid)
+ return -EINVAL;
+
+ dbsc5_ddr_mode_register_set(dev);
+ dbsc5_ddr_mode_register_read(dev);
+
+ dbsc5_dbsc_regset_post(dev);
+ dbsc5_regset_lock(dev);
+
+ return 0;
+}
+
+/**
+ * dbsc5_get_board_data() - Obtain board specific DRAM configuration
+ * @dev: DBSC5 device
+ *
+ * Return board specific DRAM configuration structure pointer.
+ */
+__weak const struct renesas_dbsc5_board_config *
+dbsc5_get_board_data(struct udevice *dev)
+{
+ return &renesas_x5h_dbsc5_board_config;
+}
+
+/**
+ * renesas_dbsc5_dram_probe() - DDR Initialize entry
+ * @dev: DBSC5 device
+ *
+ * Remove write protection on DBSC register. Read DDR configuration
+ * information from driver data. Calculate board clock frequency and
+ * operating frequency from DDR configuration information. Call the
+ * main function of DDR initialization. Perform DBSC write protection
+ * after initialization is complete.
+ */
+static int renesas_dbsc5_dram_probe(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+ u32 ch, cs, i;
+
+ priv->dbsc5_board_config = dbsc5_get_board_data(dev);
+
+ /* Link ECC only on SoC > 1.0 */
+ if (renesas_get_cpu_rev_integer() == 1 && renesas_get_cpu_rev_fraction() == 0)
+ priv->link_ecc_en = 0;
+ else
+ priv->link_ecc_en = 1;
+
+ priv->ddr_dramvalid = (u32)(priv->dbsc5_board_config->bdcfg_phyvalid);
+ priv->ddr_phyvalid = 0x0;
+ for (i = 0; i < DBSC5_PHYNUM_CNT; i++) {
+ priv->ddr_phyvalid |= ((((priv->ddr_dramvalid >> (i * 2)) |
+ (priv->ddr_dramvalid >> ((i * 2) + 1))) & 0x1) << i);
+ }
+
+ for (cs = 0; cs < CS_CNT; cs++)
+ priv->ch_have_this_cs[cs] = 0;
+
+ foreach_vch(dev, ch)
+ for (cs = 0; cs < CS_CNT; cs++)
+ if (priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs] != 0xff)
+ priv->ch_have_this_cs[cs] |= BIT(ch);
+
+ /* Determine board clock frequency (in MHz) */
+ priv->brd_clkdiv = 3;
+ switch (readl(SYSSS_PLL6_CR0)) {
+ case 0xa700000: /* 50 / 3 = 16.66MHz */
+ priv->brd_clk = 50;
+ break;
+ case 0x8b00000: /* 60 / 3 = 20.00MHz */
+ priv->brd_clk = 60;
+ break;
+ case 0xa700080: /* 100 / 3 = 33.33MHz */
+ priv->brd_clk = 100;
+ break;
+ default: /* 50 / 3 = 16.66MHz */
+ priv->brd_clk = 50;
+ break;
+ }
+
+ priv->brd_clkdiva = !!(readl(SYSSS_PLL6_CR0) & BIT(7));
+
+ /* Determine DDR operating frequency clock (in Mbps) */
+ priv->ddr_mbps = 6400;
+ priv->ddr_mbpsdiv = 1;
+
+ /* Initialize DDR */
+ return dbsc5_ddr_initialize(dev);
+}
+
+/**
+ * renesas_dbsc5_dram_of_to_plat() - Convert OF data to plat data
+ * @dev: DBSC5 device
+ *
+ * Extract DBSC5 address from DT and store it in driver data.
+ */
+static int renesas_dbsc5_dram_of_to_plat(struct udevice *dev)
+{
+ struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
+
+ priv->regs = dev_read_addr_ptr(dev);
+ if (!priv->regs)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * renesas_dbsc5_dram_get_info() - Return RAM size
+ * @dev: DBSC5 device
+ * @info: Output RAM info
+ *
+ * Return size of the RAM managed by this RAM driver.
+ */
+static int renesas_dbsc5_dram_get_info(struct udevice *dev,
+ struct ram_info *info)
+{
+ info->base = 0x40000000;
+ info->size = 0;
+
+ return 0;
+}
+
+static const struct ram_ops renesas_dbsc5_dram_ops = {
+ .get_info = renesas_dbsc5_dram_get_info,
+};
+
+U_BOOT_DRIVER(renesas_dbsc5_dram) = {
+ .name = "dbsc5_dram",
+ .id = UCLASS_RAM,
+ .of_to_plat = renesas_dbsc5_dram_of_to_plat,
+ .ops = &renesas_dbsc5_dram_ops,
+ .probe = renesas_dbsc5_dram_probe,
+ .priv_auto = sizeof(struct renesas_dbsc5_dram_priv),
+};
diff --git a/drivers/ram/renesas/dbsc5/r8a78000-dram.h b/drivers/ram/renesas/dbsc5/r8a78000-dram.h
new file mode 100644
index 00000000000..ec810cd54bb
--- /dev/null
+++ b/drivers/ram/renesas/dbsc5/r8a78000-dram.h
@@ -0,0 +1,7385 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ *
+ * Portions Copyright (C) 2026 Synopsys, Inc. Used with permission. All rights reserved.
+ */
+
+#ifndef __DRIVERS_RAM_RENESAS_DBSC5_R8A78000_DRAM_H__
+#define __DRIVERS_RAM_RENESAS_DBSC5_R8A78000_DRAM_H__
+
+#define DDR_PHY_ICCM_OFS 0x00050000U
+#define DDR_PHY_DCCM_OFS 0x00058000U
+#define DDR_PHY_ACSM_OFS 0x00041454U
+#define DDR_PHY_PIE_OFS 0x00044000U
+
+struct phyinitdata {
+ u32 addr;
+ u32 data;
+};
+
+static const struct phyinitdata cpu_trans_tab1[] = {
+ { 0x00030022, 0x00000002 },
+ { 0x00031022, 0x00000002 },
+ { 0x00004070, 0x000000FF },
+ { 0x00005070, 0x00000077 },
+ { 0x0000B070, 0x000000FF },
+ { 0x0000C070, 0x00000077 },
+ { 0x00104070, 0x000000FF },
+ { 0x00105070, 0x00000077 },
+ { 0x0010B070, 0x000000FF },
+ { 0x0010C070, 0x00000077 },
+ { 0x00204070, 0x000000FF },
+ { 0x00205070, 0x00000077 },
+ { 0x0020B070, 0x000000FF },
+ { 0x0020C070, 0x00000077 },
+ { 0x00304070, 0x000000FF },
+ { 0x00305070, 0x00000077 },
+ { 0x0030B070, 0x000000FF },
+ { 0x0030C070, 0x00000077 },
+ { 0x00000005, 0x00000003 },
+ { 0x00001005, 0x00000003 },
+ { 0x00002005, 0x00000003 },
+ { 0x00003005, 0x00000003 },
+ { 0x00004005, 0x00000003 },
+ { 0x00005005, 0x00000003 },
+ { 0x00007005, 0x00000003 },
+ { 0x00008005, 0x00000003 },
+ { 0x00009005, 0x00000003 },
+ { 0x0000A005, 0x00000003 },
+ { 0x0000B005, 0x00000003 },
+ { 0x0000C005, 0x00000003 },
+ { 0x000A0308, 0x00000002 },
+ { 0x000A0002, 0x00000001 },
+ { 0x000E0046, 0x00000006 },
+ { 0x000E0047, 0x00000006 },
+ { 0x000E0048, 0x00000006 },
+ { 0x000E0049, 0x00000006 },
+ { 0x000E1046, 0x00000006 },
+ { 0x000E1047, 0x00000006 },
+ { 0x000E1048, 0x00000006 },
+ { 0x000E1049, 0x00000006 },
+ { 0x000E104A, 0x00000006 },
+ { 0x000E004B, 0x00000006 },
+ { 0x000E104B, 0x00000006 },
+ { 0x000E2046, 0x00000006 },
+ { 0x000E2047, 0x00000006 },
+ { 0x000E2048, 0x00000006 },
+ { 0x000E2049, 0x00000006 },
+ { 0x000E3046, 0x00000006 },
+ { 0x000E3047, 0x00000006 },
+ { 0x000E3048, 0x00000006 },
+ { 0x000E3049, 0x00000006 },
+ { 0x000E304A, 0x00000006 },
+ { 0x000E204B, 0x00000006 },
+ { 0x000E304B, 0x00000006 },
+ { 0x000E4046, 0x00000006 },
+ { 0x000E4047, 0x00000006 },
+ { 0x000E4048, 0x00000006 },
+ { 0x000E4049, 0x00000006 },
+ { 0x000E5046, 0x00000006 },
+ { 0x000E5047, 0x00000006 },
+ { 0x000E5048, 0x00000006 },
+ { 0x000E5049, 0x00000006 },
+ { 0x000E504A, 0x00000006 },
+ { 0x000E404B, 0x00000006 },
+ { 0x000E504B, 0x00000006 },
+ { 0x000E6046, 0x00000006 },
+ { 0x000E6047, 0x00000006 },
+ { 0x000E6048, 0x00000006 },
+ { 0x000E6049, 0x00000006 },
+ { 0x000E7046, 0x00000006 },
+ { 0x000E7047, 0x00000006 },
+ { 0x000E7048, 0x00000006 },
+ { 0x000E7049, 0x00000006 },
+ { 0x000E704A, 0x00000006 },
+ { 0x000E604B, 0x00000006 },
+ { 0x000E704B, 0x00000006 },
+ { 0x00030020, 0x00000001 },
+ { 0x00031020, 0x00000001 }
+};
+
+static const struct phyinitdata cpu_trans_tab2[] = {
+ { 0x00000005, 0x00000003 },
+ { 0x00001005, 0x00000003 },
+ { 0x00002005, 0x00000003 },
+ { 0x00003005, 0x00000003 },
+ { 0x00004005, 0x00000003 },
+ { 0x00005005, 0x00000003 },
+ { 0x00007005, 0x00000003 },
+ { 0x00008005, 0x00000003 },
+ { 0x00009005, 0x00000003 },
+ { 0x0000A005, 0x00000003 },
+ { 0x0000B005, 0x00000003 },
+ { 0x0000C005, 0x00000003 },
+ { 0x000A0308, 0x00000000 },
+ { 0x000A0002, 0x00000001 },
+ { 0x000E0046, 0x00000000 },
+ { 0x000E0047, 0x00000000 },
+ { 0x000E0048, 0x00000000 },
+ { 0x000E0049, 0x00000000 },
+ { 0x000E1046, 0x00000000 },
+ { 0x000E1047, 0x00000000 },
+ { 0x000E1048, 0x00000000 },
+ { 0x000E1049, 0x00000000 },
+ { 0x000E104A, 0x00000000 },
+ { 0x000E004B, 0x00000002 },
+ { 0x000E104B, 0x00000004 },
+ { 0x000E2046, 0x00000000 },
+ { 0x000E2047, 0x00000000 },
+ { 0x000E2048, 0x00000000 },
+ { 0x000E2049, 0x00000000 },
+ { 0x000E3046, 0x00000000 },
+ { 0x000E3047, 0x00000000 },
+ { 0x000E3048, 0x00000000 },
+ { 0x000E3049, 0x00000000 },
+ { 0x000E304A, 0x00000000 },
+ { 0x000E204B, 0x00000002 },
+ { 0x000E304B, 0x00000004 },
+ { 0x000E4046, 0x00000000 },
+ { 0x000E4047, 0x00000000 },
+ { 0x000E4048, 0x00000000 },
+ { 0x000E4049, 0x00000000 },
+ { 0x000E5046, 0x00000000 },
+ { 0x000E5047, 0x00000000 },
+ { 0x000E5048, 0x00000000 },
+ { 0x000E5049, 0x00000000 },
+ { 0x000E504A, 0x00000000 },
+ { 0x000E404B, 0x00000002 },
+ { 0x000E504B, 0x00000004 },
+ { 0x000E6046, 0x00000000 },
+ { 0x000E6047, 0x00000000 },
+ { 0x000E6048, 0x00000000 },
+ { 0x000E6049, 0x00000000 },
+ { 0x000E7046, 0x00000000 },
+ { 0x000E7047, 0x00000000 },
+ { 0x000E7048, 0x00000000 },
+ { 0x000E7049, 0x00000000 },
+ { 0x000E704A, 0x00000000 },
+ { 0x000E604B, 0x00000002 },
+ { 0x000E704B, 0x00000004 },
+ { 0x000200A5, 0x00000001 },
+ { 0x00010097, 0x000007FF },
+ { 0x00011097, 0x000007FF },
+ { 0x00012097, 0x000007FF },
+ { 0x00013097, 0x000007FF },
+ { 0x0001003F, 0x00000001 },
+ { 0x0001003F, 0x00000000 },
+ { 0x0001103F, 0x00000001 },
+ { 0x0001103F, 0x00000000 },
+ { 0x0001203F, 0x00000001 },
+ { 0x0001203F, 0x00000000 },
+ { 0x0001303F, 0x00000001 },
+ { 0x0001303F, 0x00000000 },
+ { 0x000B0303, 0x00000009 },
+ { 0x000A0302, 0x00000026 },
+ { 0x000B0301, 0x00000000 },
+ { 0x000B030F, 0x0000001D },
+ { 0x00070067, 0x00000000 },
+ { 0x000700E7, 0x00000000 },
+ { 0x000300AE, 0x00001A80 },
+ { 0x000300AD, 0x00001A80 },
+ { 0x000300AC, 0x00001A80 },
+ { 0x000310AE, 0x00001A80 },
+ { 0x000310AD, 0x00001A80 },
+ { 0x000310AC, 0x00001A80 },
+ { 0x000100A3, 0x00000911 },
+ { 0x000110A3, 0x0000091D },
+ { 0x000120A3, 0x00000911 },
+ { 0x000130A3, 0x0000091D },
+ { 0x000C00F0, 0x00000001 },
+ { 0x000C00F1, 0x00000002 },
+ { 0x000C00F2, 0x00000007 },
+ { 0x000C00F3, 0x00000034 },
+ { 0x00090733, 0x0000002D },
+ { 0x000C00F4, 0x00000005 },
+ { 0x000C00F7, 0x0000F000 },
+ { 0x00090737, 0x00000A00 },
+ { 0x0009071F, 0x00000004 },
+ { 0x00090829, 0x0000000F },
+ { 0x00020007, 0x00000000 },
+ { 0x000E007A, 0x00000000 },
+ { 0x000E107A, 0x00000001 },
+ { 0x000E207A, 0x00000000 },
+ { 0x000E307A, 0x00000001 },
+ { 0x000E407A, 0x00000000 },
+ { 0x000E507A, 0x00000001 },
+ { 0x000E607A, 0x00000000 },
+ { 0x000E707A, 0x00000001 },
+ { 0x0000061E, 0x00000000 },
+ { 0x0000E61E, 0x00000000 },
+ { 0x0000161E, 0x00000000 },
+ { 0x0000261E, 0x00000000 },
+ { 0x0000361E, 0x00000000 },
+ { 0x0000461E, 0x00000000 },
+ { 0x0000561E, 0x00000000 },
+ { 0x0000761E, 0x00000000 },
+ { 0x0000861E, 0x00000000 },
+ { 0x0000961E, 0x00000000 },
+ { 0x0000A61E, 0x00000000 },
+ { 0x0000B61E, 0x00000000 },
+ { 0x0000C61E, 0x00000000 },
+ { 0x00010E1F, 0x00000000 },
+ { 0x00011E1F, 0x00000000 },
+ { 0x00012E1F, 0x00000000 },
+ { 0x00013E1F, 0x00000000 },
+ { 0x00030807, 0x0000EE66 },
+ { 0x00031807, 0x0000EE66 },
+ { 0x00010807, 0x0000EE66 },
+ { 0x00011807, 0x0000EE66 },
+ { 0x00012807, 0x0000EE66 },
+ { 0x00013807, 0x0000EE66 },
+ { 0x000300A0, 0x00003FFF },
+ { 0x000310A0, 0x00003FFF },
+ { 0x00010089, 0x00001FFF },
+ { 0x0001008A, 0x000007FF },
+ { 0x00011089, 0x00001FFF },
+ { 0x0001108A, 0x000007FF },
+ { 0x00012089, 0x00001FFF },
+ { 0x0001208A, 0x000007FF },
+ { 0x00013089, 0x00001FFF },
+ { 0x0001308A, 0x000007FF },
+ { 0x00020006, 0x0000000F },
+ { 0x0002000C, 0x00000000 },
+ { 0x000E000D, 0x00000001 },
+ { 0x000E100D, 0x00000001 },
+ { 0x000E200D, 0x00000001 },
+ { 0x000E300D, 0x00000001 },
+ { 0x000E400D, 0x00000001 },
+ { 0x000E500D, 0x00000001 },
+ { 0x000E600D, 0x00000001 },
+ { 0x000E700D, 0x00000001 },
+ { 0x00030027, 0x00000001 },
+ { 0x0000003F, 0x00000001 },
+ { 0x0000103F, 0x00000001 },
+ { 0x0000203F, 0x00000001 },
+ { 0x0000303F, 0x00000001 },
+ { 0x0000403F, 0x00000001 },
+ { 0x0000503F, 0x00000001 },
+ { 0x00031027, 0x00000001 },
+ { 0x0000703F, 0x00000001 },
+ { 0x0000803F, 0x00000001 },
+ { 0x0000903F, 0x00000001 },
+ { 0x0000A03F, 0x00000001 },
+ { 0x0000B03F, 0x00000001 },
+ { 0x0000C03F, 0x00000001 }
+};
+
+static const struct phyinitdata cpu_trans_tab3[] = {
+ { 0x0002008B, 0x00000000 },
+ { 0x000A03FF, 0x00004101 },
+ { 0x000A030B, 0x00000000 },
+ { 0x00060008, 0x00000E9A },
+ { 0x00020002, 0x00000007 },
+ { 0x00060040, 0x00000007 },
+ { 0x00020000, 0x00000002 },
+ { 0x000100FB, 0x00000000 },
+ { 0x000110FB, 0x00000000 },
+ { 0x000120FB, 0x00000000 },
+ { 0x000130FB, 0x00000000 },
+ { 0x00010024, 0x00000200 },
+ { 0x00011024, 0x00000200 },
+ { 0x00012024, 0x00000200 },
+ { 0x00013024, 0x00000200 },
+ { 0x00010025, 0x0000002C },
+ { 0x00011025, 0x0000002C },
+ { 0x00012025, 0x0000002C },
+ { 0x00013025, 0x0000002C },
+ { 0x00010004, 0x00000000 },
+ { 0x00010003, 0x00000000 },
+ { 0x00011004, 0x00000000 },
+ { 0x00011003, 0x00000000 },
+ { 0x00012004, 0x00000000 },
+ { 0x00012003, 0x00000000 },
+ { 0x00013004, 0x00000000 },
+ { 0x00013003, 0x00000000 },
+ { 0x000B0004, 0x0000042A },
+ { 0x000A030C, 0x00000000 },
+ { 0x0001003E, 0x00000005 },
+ { 0x0001103E, 0x00000005 },
+ { 0x0001203E, 0x00000005 },
+ { 0x0001303E, 0x00000005 },
+ { 0x00020003, 0x00000001 },
+ { 0x0002000B, 0x00001111 },
+ { 0x00010108, 0x00000000 },
+ { 0x00011108, 0x00000000 },
+ { 0x00012108, 0x00000000 },
+ { 0x00013108, 0x00000000 },
+ { 0x00070005, 0x00000003 },
+ { 0x0007000F, 0x00000000 },
+ { 0x0001000E, 0x00001301 },
+ { 0x0001100E, 0x00001301 },
+ { 0x0001200E, 0x00001301 },
+ { 0x0001300E, 0x00001301 },
+ { 0x00020019, 0x00000004 },
+ { 0x00000070, 0x00000077 },
+ { 0x00001070, 0x00000077 },
+ { 0x00002070, 0x00000077 },
+ { 0x00003070, 0x00000077 },
+ { 0x00004070, 0x000000FF },
+ { 0x00005070, 0x00000077 },
+ { 0x00007070, 0x00000077 },
+ { 0x00008070, 0x00000077 },
+ { 0x00009070, 0x00000077 },
+ { 0x0000A070, 0x00000077 },
+ { 0x0000B070, 0x000000FF },
+ { 0x0000C070, 0x00000077 },
+ { 0x00000079, 0x00000030 },
+ { 0x00001079, 0x00000030 },
+ { 0x00002079, 0x00000030 },
+ { 0x00003079, 0x00000030 },
+ { 0x00004079, 0x00000030 },
+ { 0x00005079, 0x00000030 },
+ { 0x00007079, 0x00000030 },
+ { 0x00008079, 0x00000030 },
+ { 0x00009079, 0x00000030 },
+ { 0x0000A079, 0x00000030 },
+ { 0x0000B079, 0x00000030 },
+ { 0x0000C079, 0x00000030 },
+ { 0x0000006D, 0x00000000 },
+ { 0x0000106D, 0x00000000 },
+ { 0x0000206D, 0x00000000 },
+ { 0x0000306D, 0x00000000 },
+ { 0x0000406D, 0x00000000 },
+ { 0x0000506D, 0x00000000 },
+ { 0x0000706D, 0x00000000 },
+ { 0x0000806D, 0x00000000 },
+ { 0x0000906D, 0x00000000 },
+ { 0x0000A06D, 0x00000000 },
+ { 0x0000B06D, 0x00000000 },
+ { 0x0000C06D, 0x00000000 },
+ { 0x00010001, 0x00000000 },
+ { 0x00011001, 0x00000000 },
+ { 0x00012001, 0x00000000 },
+ { 0x00013001, 0x00000000 },
+ { 0x00070040, 0x00000050 },
+ { 0x00070041, 0x0000000F },
+ { 0x000100A5, 0x00000001 },
+ { 0x000110A5, 0x00000001 },
+ { 0x000120A5, 0x00000001 },
+ { 0x000130A5, 0x00000001 },
+ { 0x00010209, 0x00003232 },
+ { 0x00011209, 0x00003232 },
+ { 0x00012209, 0x00003232 },
+ { 0x00013209, 0x00003232 },
+ { 0x0001020F, 0x00000006 },
+ { 0x0001120F, 0x00000006 },
+ { 0x0001220F, 0x00000006 },
+ { 0x0001320F, 0x00000006 },
+ { 0x00020005, 0x00001111 },
+ { 0x00010008, 0x00000001 },
+ { 0x00011008, 0x00000001 },
+ { 0x00012008, 0x00000001 },
+ { 0x00013008, 0x00000001 },
+ { 0x0007006B, 0x00000111 },
+ { 0x00070066, 0x00000A10 },
+ { 0x000700EB, 0x00000111 },
+ { 0x000700E6, 0x00000A10 },
+ { 0x00030008, 0x00000000 },
+ { 0x00031008, 0x00000000 },
+ { 0x000005E3, 0x00000004 },
+ { 0x000015E3, 0x00000004 },
+ { 0x000025E3, 0x00000004 },
+ { 0x000035E3, 0x00000004 },
+ { 0x000045E3, 0x00000004 },
+ { 0x000055E3, 0x00000004 },
+ { 0x000075E3, 0x00000004 },
+ { 0x000085E3, 0x00000004 },
+ { 0x000095E3, 0x00000004 },
+ { 0x0000A5E3, 0x00000004 },
+ { 0x0000B5E3, 0x00000004 },
+ { 0x0000C5E3, 0x00000004 },
+ { 0x000E05E3, 0x00000004 },
+ { 0x000E15E3, 0x00000004 },
+ { 0x000E25E3, 0x00000004 },
+ { 0x000E35E3, 0x00000004 },
+ { 0x000E45E3, 0x00000004 },
+ { 0x000E55E3, 0x00000004 },
+ { 0x000E65E3, 0x00000004 },
+ { 0x000E75E3, 0x00000004 },
+ { 0x0000050A, 0x00000001 },
+ { 0x0000150A, 0x00000001 },
+ { 0x0000250A, 0x00000001 },
+ { 0x0000350A, 0x00000001 },
+ { 0x0000450A, 0x00000001 },
+ { 0x0000550A, 0x00000001 },
+ { 0x0000750A, 0x00000001 },
+ { 0x0000850A, 0x00000001 },
+ { 0x0000950A, 0x00000001 },
+ { 0x0000A50A, 0x00000001 },
+ { 0x0000B50A, 0x00000001 },
+ { 0x0000C50A, 0x00000001 },
+ { 0x0001080B, 0x00000001 },
+ { 0x0001180B, 0x00000001 },
+ { 0x0001280B, 0x00000001 },
+ { 0x0001380B, 0x00000001 },
+ { 0x00030803, 0x0000108A },
+ { 0x00031803, 0x0000108A },
+ { 0x00010803, 0x0000108A },
+ { 0x00011803, 0x0000108A },
+ { 0x00012803, 0x0000108A },
+ { 0x00013803, 0x0000108A },
+ { 0x00000503, 0x0000002B },
+ { 0x00001503, 0x0000002B },
+ { 0x00002503, 0x0000002B },
+ { 0x00003503, 0x0000002B },
+ { 0x00004503, 0x0000002B },
+ { 0x00005503, 0x0000002B },
+ { 0x00007503, 0x0000002B },
+ { 0x00008503, 0x0000002B },
+ { 0x00009503, 0x0000002B },
+ { 0x0000A503, 0x0000002B },
+ { 0x0000B503, 0x0000002B },
+ { 0x0000C503, 0x0000002B },
+ { 0x00010C03, 0x0000002B },
+ { 0x00011C03, 0x0000002B },
+ { 0x00012C03, 0x0000002B },
+ { 0x00013C03, 0x0000002B },
+ { 0x00000110, 0x0000001F },
+ { 0x00001110, 0x0000001F },
+ { 0x00002110, 0x0000001F },
+ { 0x00003110, 0x0000001F },
+ { 0x00004110, 0x0000001F },
+ { 0x00005110, 0x0000001F },
+ { 0x00007110, 0x0000001F },
+ { 0x00008110, 0x0000001F },
+ { 0x00009110, 0x0000001F },
+ { 0x0000A110, 0x0000001F },
+ { 0x0000B110, 0x0000001F },
+ { 0x0000C110, 0x0000001F },
+ { 0x000E0110, 0x0000001F },
+ { 0x000E1110, 0x0000001F },
+ { 0x000E2110, 0x0000001F },
+ { 0x000E3110, 0x0000001F },
+ { 0x000E4110, 0x0000001F },
+ { 0x000E5110, 0x0000001F },
+ { 0x000E6110, 0x0000001F },
+ { 0x000E7110, 0x0000001F },
+ { 0x0001010B, 0x00000003 },
+ { 0x0001110B, 0x00000003 },
+ { 0x0001210B, 0x00000003 },
+ { 0x0001310B, 0x00000003 },
+ { 0x00000063, 0x0000004E },
+ { 0x00001063, 0x0000004E },
+ { 0x00002063, 0x0000004E },
+ { 0x00003063, 0x0000004E },
+ { 0x00004063, 0x0000004E },
+ { 0x00005063, 0x0000004E },
+ { 0x00007063, 0x0000004E },
+ { 0x00008063, 0x0000004E },
+ { 0x00009063, 0x0000004E },
+ { 0x0000A063, 0x0000004E },
+ { 0x0000B063, 0x0000004E },
+ { 0x0000C063, 0x0000004E },
+ { 0x000E0063, 0x0000004E },
+ { 0x000E0064, 0x0000004E },
+ { 0x000E0087, 0x0000004E },
+ { 0x000E1063, 0x0000004E },
+ { 0x000E1064, 0x0000004E },
+ { 0x000E1087, 0x0000004E },
+ { 0x000E2063, 0x0000004E },
+ { 0x000E2064, 0x0000004E },
+ { 0x000E2087, 0x0000004E },
+ { 0x000E3063, 0x0000004E },
+ { 0x000E3064, 0x0000004E },
+ { 0x000E3087, 0x0000004E },
+ { 0x000E4063, 0x0000004E },
+ { 0x000E4064, 0x0000004E },
+ { 0x000E4087, 0x0000004E },
+ { 0x000E5063, 0x0000004E },
+ { 0x000E5064, 0x0000004E },
+ { 0x000E5087, 0x0000004E },
+ { 0x000E6063, 0x0000004E },
+ { 0x000E6064, 0x0000004E },
+ { 0x000E6087, 0x0000004E },
+ { 0x000E7063, 0x0000004E },
+ { 0x000E7064, 0x0000004E },
+ { 0x000E7087, 0x0000004E },
+ { 0x000C0080, 0x00000007 },
+ { 0x000300EB, 0x00000000 },
+ { 0x000310EB, 0x00000000 }
+};
+
+static const struct phyinitdata cpu_trans_tab4[] = {
+ { 0x000B0310, 0x00000001 },
+ { 0x000B0311, 0x00000001 },
+ { 0x00060008, 0x00000D56 },
+ { 0x00060006, 0x000003F0 },
+ { 0x00010075, 0x00000001 },
+ { 0x00011075, 0x00000001 },
+ { 0x00012075, 0x00000001 },
+ { 0x00013075, 0x00000001 },
+ { 0x00030015, 0x00000000 },
+ { 0x00031015, 0x00000000 },
+ { 0x0001007C, 0x00000000 },
+ { 0x0001107C, 0x00000000 },
+ { 0x0001207C, 0x00000000 },
+ { 0x0001307C, 0x00000000 },
+ { 0x00070141, 0x00000000 },
+ { 0x000B0001, 0x00000003 },
+ { 0x0009080C, 0x00000003 },
+ { 0x00010027, 0x00000001 },
+ { 0x00011027, 0x00000001 },
+ { 0x00012027, 0x00000001 },
+ { 0x00013027, 0x00000001 },
+ { 0x0001020F, 0x00000009 },
+ { 0x0001120F, 0x00000009 },
+ { 0x0001220F, 0x00000009 },
+ { 0x0001320F, 0x00000009 },
+ { 0x000E003F, 0x00000001 },
+ { 0x000E008D, 0x00000001 },
+ { 0x000E103F, 0x00000001 },
+ { 0x000E108D, 0x00000001 },
+ { 0x000E203F, 0x00000001 },
+ { 0x000E208D, 0x00000001 },
+ { 0x000E303F, 0x00000001 },
+ { 0x000E308D, 0x00000001 },
+ { 0x000E403F, 0x00000001 },
+ { 0x000E408D, 0x00000001 },
+ { 0x000E503F, 0x00000001 },
+ { 0x000E508D, 0x00000001 },
+ { 0x000E603F, 0x00000001 },
+ { 0x000E608D, 0x00000001 },
+ { 0x000E703F, 0x00000001 },
+ { 0x000E708D, 0x00000001 },
+ { 0x00090903, 0x00000000 },
+ { 0x00070072, 0x00000001 },
+ { 0x0009080E, 0x00000001 },
+ { 0x00070073, 0x00000001 },
+ { 0x0009080F, 0x00000001 }
+};
+
+static const struct phyinitdata cpu_trans_tab5[] = {
+ { 0x00070334, 0x0000011B },
+ { 0x00070335, 0x0000011F },
+ { 0x00070336, 0x00000121 },
+ { 0x00070337, 0x00000122 },
+ { 0x00070339, 0x00000123 },
+ { 0x0007033A, 0x00000124 },
+ { 0x0007033C, 0x00000125 },
+ { 0x0007033D, 0x0000013E },
+ { 0x0007033E, 0x00000148 },
+ { 0x0007033F, 0x00000160 },
+ { 0x00070350, 0x00000170 },
+ { 0x00070351, 0x00000188 },
+ { 0x00070352, 0x00000191 },
+ { 0x00070353, 0x000001A3 }
+};
+
+static const struct phyinitdata cpu_trans_tab6[] = {
+ { 0x0007039B, 0x0000011E },
+ { 0x0007039C, 0x00000120 },
+ { 0x0007039D, 0x00000121 },
+ { 0x0007039E, 0x00000122 },
+ { 0x000703A0, 0x00000123 },
+ { 0x000703A1, 0x00000124 },
+ { 0x000703A3, 0x0000013D },
+ { 0x000703A4, 0x00000147 },
+ { 0x000703A5, 0x0000015F },
+ { 0x000703A6, 0x0000016F },
+ { 0x000703B7, 0x00000187 },
+ { 0x000703B8, 0x00000190 },
+ { 0x000703B9, 0x000001A2 },
+ { 0x000703BA, 0x000001B3 },
+ { 0x00070200, 0x0000040E },
+ { 0x00070202, 0x0000044F },
+ { 0x00070204, 0x000000C0 },
+ { 0x00070205, 0x00000246 },
+ { 0x00070206, 0x00000101 },
+ { 0x00070207, 0x00000287 },
+ { 0x00070208, 0x00000142 },
+ { 0x00070209, 0x000002C8 },
+ { 0x0007020A, 0x00000012 },
+ { 0x0007020B, 0x0000034C },
+ { 0x0007020C, 0x00000015 },
+ { 0x0007020E, 0x00000016 },
+ { 0x00070212, 0x0000002C },
+ { 0x00070213, 0x00000018 },
+ { 0x00070214, 0x0000002D },
+ { 0x00070215, 0x00000019 },
+ { 0x00070216, 0x0000002E },
+ { 0x00070217, 0x0000001A },
+ { 0x00070218, 0x0000002F },
+ { 0x00070219, 0x0000001B },
+ { 0x0007021A, 0x00000013 },
+ { 0x0009001C, 0x00000267 },
+ { 0x0009001D, 0x00000267 },
+ { 0x0009001E, 0x00000267 },
+ { 0x0009001F, 0x00000267 },
+ { 0x00090020, 0x000002A0 },
+ { 0x00090021, 0x00000267 },
+ { 0x00090022, 0x00000000 },
+ { 0x00090023, 0x00000000 },
+ { 0x00090024, 0x00000000 },
+ { 0x00090025, 0x00000000 },
+ { 0x00090026, 0x00000000 },
+ { 0x00090027, 0x00000000 },
+ { 0x0009002B, 0x0000029D },
+ { 0x00070145, 0x00000004 }
+};
+
+static const struct phyinitdata cpu_trans_tab7[] = {
+ { 0x000700F0, 0x00000B6D },
+ { 0x000100B9, 0x00000001 },
+ { 0x000100B1, 0x00000180 },
+ { 0x000100BA, 0x00000001 },
+ { 0x000100A2, 0x00000000 },
+ { 0x000100B5, 0x00000001 },
+ { 0x00010E2B, 0x00005A3C },
+ { 0x00010E2A, 0x00005A3C },
+ { 0x00010E20, 0x00000002 },
+ { 0x000110B9, 0x00000001 },
+ { 0x000110B1, 0x00000180 },
+ { 0x000110BA, 0x00000001 },
+ { 0x000110A2, 0x00000000 },
+ { 0x000110B5, 0x00000001 },
+ { 0x00011E2B, 0x00005A3C },
+ { 0x00011E2A, 0x00005A3C },
+ { 0x00011E20, 0x00000002 },
+ { 0x000120B9, 0x00000001 },
+ { 0x000120B1, 0x00000180 },
+ { 0x000120BA, 0x00000001 },
+ { 0x000120A2, 0x00000000 },
+ { 0x000120B5, 0x00000001 },
+ { 0x00012E2B, 0x00005A3C },
+ { 0x00012E2A, 0x00005A3C },
+ { 0x00012E20, 0x00000002 },
+ { 0x000130B9, 0x00000001 },
+ { 0x000130B1, 0x00000180 },
+ { 0x000130BA, 0x00000001 },
+ { 0x000130A2, 0x00000000 },
+ { 0x000130B5, 0x00000001 },
+ { 0x00013E2B, 0x00005A3C },
+ { 0x00013E2A, 0x00005A3C },
+ { 0x00013E20, 0x00000002 },
+ { 0x0007001C, 0x00005A3C },
+ { 0x0007001B, 0x00005A3C },
+ { 0x00070010, 0x00000002 },
+ { 0x0007007E, 0x00000041 },
+ { 0x000701EF, 0x00007FFF },
+ { 0x000300A6, 0x00000001 },
+ { 0x000310A6, 0x00000001 },
+ { 0x000701A8, 0x00000000 },
+ { 0x00070128, 0x00000000 },
+ { 0x00070131, 0x00000000 },
+ { 0x00070132, 0x00000000 },
+ { 0x00070133, 0x00000000 },
+ { 0x00070134, 0x00000000 },
+ { 0x00070142, 0x00000000 },
+ { 0x00070144, 0x00000000 }
+};
+
+static const struct phyinitdata cpu_trans_tab3_7500[] = {
+ { 0x000908E0, 0x00000076 },
+ { 0x000908E1, 0x00000160 },
+ { 0x000908E2, 0x00000927 },
+ { 0x000908E4, 0x00000018 },
+ { 0x000908EA, 0x00000005 },
+ { 0x000908EB, 0x00000005 },
+ { 0x000908EC, 0x0000000C },
+ { 0x000908ED, 0x0000005B },
+ { 0x000B0004, 0x000003A9 },
+ { 0x00070066, 0x00000910 },
+ { 0x000700E6, 0x00000910 },
+ { 0x00070135, 0x00001410 },
+ { 0x00070136, 0x00001410 },
+ { 0x00070137, 0x00000424 },
+ { 0x00070138, 0x00001928 },
+ { 0x00070139, 0x00001418 },
+ { 0x0007013A, 0x00001418 },
+ { 0x0007013B, 0x0000042C },
+ { 0x0007013C, 0x00003530 },
+ { 0x0007013D, 0x00001408 },
+ { 0x0007013E, 0x00001408 },
+ { 0x0007013F, 0x0000041C },
+ { 0x00070140, 0x00001120 },
+ { 0x0007012C, 0x00000843 },
+ { 0x0007012D, 0x00000843 },
+ { 0x00070130, 0x00000843 },
+ { 0x0007012E, 0x00000827 },
+ { 0x0007012F, 0x00000827 },
+ { 0x00030803, 0x0000107A },
+ { 0x00031803, 0x0000107A },
+ { 0x00010803, 0x0000107A },
+ { 0x00011803, 0x0000107A },
+ { 0x00012803, 0x0000107A },
+ { 0x00013803, 0x0000107A },
+ { 0x00000503, 0x00000027 },
+ { 0x00001503, 0x00000027 },
+ { 0x00002503, 0x00000027 },
+ { 0x00003503, 0x00000027 },
+ { 0x00004503, 0x00000027 },
+ { 0x00005503, 0x00000027 },
+ { 0x00007503, 0x00000027 },
+ { 0x00008503, 0x00000027 },
+ { 0x00009503, 0x00000027 },
+ { 0x0000A503, 0x00000027 },
+ { 0x0000B503, 0x00000027 },
+ { 0x0000C503, 0x00000027 },
+ { 0x00010C03, 0x00000027 },
+ { 0x00011C03, 0x00000027 },
+ { 0x00012C03, 0x00000027 },
+ { 0x00013C03, 0x00000027 },
+ { 0x000908E8, 0x00000015 },
+ { 0x000908E9, 0x00000048 },
+ { 0x00000063, 0x00000058 },
+ { 0x00001063, 0x00000058 },
+ { 0x00002063, 0x00000058 },
+ { 0x00003063, 0x00000058 },
+ { 0x00004063, 0x00000058 },
+ { 0x00005063, 0x00000058 },
+ { 0x00007063, 0x00000058 },
+ { 0x00008063, 0x00000058 },
+ { 0x00009063, 0x00000058 },
+ { 0x0000A063, 0x00000058 },
+ { 0x0000B063, 0x00000058 },
+ { 0x0000C063, 0x00000058 },
+ { 0x0009080A, 0x00000258 },
+ { 0x0009080B, 0x00000058 },
+ { 0x00090815, 0x00000258 },
+ { 0x00090816, 0x00000058 },
+ { 0x000E0063, 0x00000058 },
+ { 0x000E0064, 0x00000058 },
+ { 0x000E0087, 0x00000058 },
+ { 0x000E1063, 0x00000058 },
+ { 0x000E1064, 0x00000058 },
+ { 0x000E1087, 0x00000058 },
+ { 0x000E2063, 0x00000058 },
+ { 0x000E2064, 0x00000058 },
+ { 0x000E2087, 0x00000058 },
+ { 0x000E3063, 0x00000058 },
+ { 0x000E3064, 0x00000058 },
+ { 0x000E3087, 0x00000058 },
+ { 0x000E4063, 0x00000058 },
+ { 0x000E4064, 0x00000058 },
+ { 0x000E4087, 0x00000058 },
+ { 0x000E5063, 0x00000058 },
+ { 0x000E5064, 0x00000058 },
+ { 0x000E5087, 0x00000058 },
+ { 0x000E6063, 0x00000058 },
+ { 0x000E6064, 0x00000058 },
+ { 0x000E6087, 0x00000058 },
+ { 0x000E7063, 0x00000058 },
+ { 0x000E7064, 0x00000058 },
+ { 0x000E7087, 0x00000058 },
+ { 0x00090817, 0x00000061 }
+};
+
+static const struct phyinitdata cpu_trans_tab3_9600[] = {
+ { 0x000908E0, 0x00000096 },
+ { 0x000908E1, 0x000001C2 },
+ { 0x000908E2, 0x00000BB8 },
+ { 0x000908E4, 0x0000001E },
+ { 0x000908EC, 0x0000000F },
+ { 0x000908ED, 0x00000075 },
+ { 0x000B0004, 0x000004B0 },
+ { 0x00070066, 0x00000B10 },
+ { 0x000700E6, 0x00000B10 },
+ { 0x00070135, 0x00001C14 },
+ { 0x00070136, 0x00001C14 },
+ { 0x00070137, 0x00000430 },
+ { 0x00070138, 0x00001934 },
+ { 0x00070139, 0x00001C1C },
+ { 0x0007013A, 0x00001C1C },
+ { 0x0007013B, 0x00000438 },
+ { 0x0007013C, 0x00003D3C },
+ { 0x0007013D, 0x00001C08 },
+ { 0x0007013E, 0x00001C08 },
+ { 0x0007013F, 0x00000424 },
+ { 0x00070140, 0x00001128 },
+ { 0x0007012C, 0x00000857 },
+ { 0x0007012D, 0x00000857 },
+ { 0x00070130, 0x00000857 },
+ { 0x0007012E, 0x00000833 },
+ { 0x0007012F, 0x00000833 },
+ { 0x00030803, 0x0000109A },
+ { 0x00031803, 0x0000109A },
+ { 0x00010803, 0x0000109A },
+ { 0x00011803, 0x0000109A },
+ { 0x00012803, 0x0000109A },
+ { 0x00013803, 0x0000109A },
+ { 0x00000503, 0x0000002F },
+ { 0x00001503, 0x0000002F },
+ { 0x00002503, 0x0000002F },
+ { 0x00003503, 0x0000002F },
+ { 0x00004503, 0x0000002F },
+ { 0x00005503, 0x0000002F },
+ { 0x00007503, 0x0000002F },
+ { 0x00008503, 0x0000002F },
+ { 0x00009503, 0x0000002F },
+ { 0x0000A503, 0x0000002F },
+ { 0x0000B503, 0x0000002F },
+ { 0x0000C503, 0x0000002F },
+ { 0x00010C03, 0x0000002F },
+ { 0x00011C03, 0x0000002F },
+ { 0x00012C03, 0x0000002F },
+ { 0x00013C03, 0x0000002F },
+ { 0x000908E8, 0x00000019 },
+ { 0x000908E9, 0x00000056 },
+ { 0x00000063, 0x00000045 },
+ { 0x00001063, 0x00000045 },
+ { 0x00002063, 0x00000045 },
+ { 0x00003063, 0x00000045 },
+ { 0x00004063, 0x00000045 },
+ { 0x00005063, 0x00000045 },
+ { 0x00007063, 0x00000045 },
+ { 0x00008063, 0x00000045 },
+ { 0x00009063, 0x00000045 },
+ { 0x0000A063, 0x00000045 },
+ { 0x0000B063, 0x00000045 },
+ { 0x0000C063, 0x00000045 },
+ { 0x0009080A, 0x00000245 },
+ { 0x0009080B, 0x00000045 },
+ { 0x00090815, 0x00000245 },
+ { 0x00090816, 0x00000045 },
+ { 0x000E0063, 0x00000045 },
+ { 0x000E0064, 0x00000045 },
+ { 0x000E0087, 0x00000045 },
+ { 0x000E1063, 0x00000045 },
+ { 0x000E1064, 0x00000045 },
+ { 0x000E1087, 0x00000045 },
+ { 0x000E2063, 0x00000045 },
+ { 0x000E2064, 0x00000045 },
+ { 0x000E2087, 0x00000045 },
+ { 0x000E3063, 0x00000045 },
+ { 0x000E3064, 0x00000045 },
+ { 0x000E3087, 0x00000045 },
+ { 0x000E4063, 0x00000045 },
+ { 0x000E4064, 0x00000045 },
+ { 0x000E4087, 0x00000045 },
+ { 0x000E5063, 0x00000045 },
+ { 0x000E5064, 0x00000045 },
+ { 0x000E5087, 0x00000045 },
+ { 0x000E6063, 0x00000045 },
+ { 0x000E6064, 0x00000045 },
+ { 0x000E6087, 0x00000045 },
+ { 0x000E7063, 0x00000045 },
+ { 0x000E7064, 0x00000045 },
+ { 0x000E7087, 0x00000045 },
+ { 0x00090817, 0x0000007D }
+};
+
+static const struct phyinitdata cpu_trans_tab3_6400[] = {
+ { 0x00060008, 0x00002E9A },
+ { 0x000908E0, 0x00000064 },
+ { 0x000908E1, 0x0000012C },
+ { 0x000908E2, 0x000007D0 },
+ { 0x000908E4, 0x00000014 },
+ { 0x000908EA, 0x00000004 },
+ { 0x000908EB, 0x00000004 },
+ { 0x000908EC, 0x0000000A },
+ { 0x000908ED, 0x0000004E },
+ { 0x000B0004, 0x00000320 },
+ { 0x00070066, 0x00000810 },
+ { 0x000700E6, 0x00000810 },
+ { 0x00070135, 0x0000100C },
+ { 0x00070136, 0x0000100C },
+ { 0x00070137, 0x0000041C },
+ { 0x00070138, 0x00001920 },
+ { 0x00070139, 0x00001018 },
+ { 0x0007013A, 0x00001018 },
+ { 0x0007013B, 0x00000428 },
+ { 0x0007013C, 0x00002D2C },
+ { 0x0007013D, 0x00001004 },
+ { 0x0007013E, 0x00001004 },
+ { 0x0007013F, 0x00000414 },
+ { 0x00070140, 0x00001118 },
+ { 0x0007012C, 0x00000837 },
+ { 0x0007012D, 0x00000837 },
+ { 0x00070130, 0x00000837 },
+ { 0x0007012E, 0x0000081F },
+ { 0x0007012F, 0x0000081F },
+ { 0x00030803, 0x0000107A },
+ { 0x00031803, 0x0000107A },
+ { 0x00010803, 0x0000107A },
+ { 0x00011803, 0x0000107A },
+ { 0x00012803, 0x0000107A },
+ { 0x00013803, 0x0000107A },
+ { 0x00000503, 0x00000023 },
+ { 0x00001503, 0x00000023 },
+ { 0x00002503, 0x00000023 },
+ { 0x00003503, 0x00000023 },
+ { 0x00004503, 0x00000023 },
+ { 0x00005503, 0x00000023 },
+ { 0x00007503, 0x00000023 },
+ { 0x00008503, 0x00000023 },
+ { 0x00009503, 0x00000023 },
+ { 0x0000A503, 0x00000023 },
+ { 0x0000B503, 0x00000023 },
+ { 0x0000C503, 0x00000023 },
+ { 0x00010C03, 0x00000023 },
+ { 0x00011C03, 0x00000023 },
+ { 0x00012C03, 0x00000023 },
+ { 0x00013C03, 0x00000023 },
+ { 0x000908E8, 0x00000015 },
+ { 0x000908E9, 0x00000048 },
+ { 0x00000063, 0x00000068 },
+ { 0x00001063, 0x00000068 },
+ { 0x00002063, 0x00000068 },
+ { 0x00003063, 0x00000068 },
+ { 0x00004063, 0x00000068 },
+ { 0x00005063, 0x00000068 },
+ { 0x00007063, 0x00000068 },
+ { 0x00008063, 0x00000068 },
+ { 0x00009063, 0x00000068 },
+ { 0x0000A063, 0x00000068 },
+ { 0x0000B063, 0x00000068 },
+ { 0x0000C063, 0x00000068 },
+ { 0x0009080A, 0x00000268 },
+ { 0x0009080B, 0x00000068 },
+ { 0x00090815, 0x00000268 },
+ { 0x00090816, 0x00000068 },
+ { 0x000E0063, 0x00000068 },
+ { 0x000E0064, 0x00000068 },
+ { 0x000E0087, 0x00000068 },
+ { 0x000E1063, 0x00000068 },
+ { 0x000E1064, 0x00000068 },
+ { 0x000E1087, 0x00000068 },
+ { 0x000E2063, 0x00000068 },
+ { 0x000E2064, 0x00000068 },
+ { 0x000E2087, 0x00000068 },
+ { 0x000E3063, 0x00000068 },
+ { 0x000E3064, 0x00000068 },
+ { 0x000E3087, 0x00000068 },
+ { 0x000E4063, 0x00000068 },
+ { 0x000E4064, 0x00000068 },
+ { 0x000E4087, 0x00000068 },
+ { 0x000E5063, 0x00000068 },
+ { 0x000E5064, 0x00000068 },
+ { 0x000E5087, 0x00000068 },
+ { 0x000E6063, 0x00000068 },
+ { 0x000E6064, 0x00000068 },
+ { 0x000E6087, 0x00000068 },
+ { 0x000E7063, 0x00000068 },
+ { 0x000E7064, 0x00000068 },
+ { 0x000E7087, 0x00000068 },
+ { 0x00090817, 0x00000053 }
+};
+
+static const u32 DMAC_TRANS_ICCM[] = {
+ 0x0000058C, 0x00000090, 0x00000090, 0x00000090,
+ 0x00000090, 0x00000090, 0x00000090, 0x00000090,
+ 0x00000090, 0x00000090, 0x00000090, 0x00000090,
+ 0x00000090, 0x00000090, 0x00000090, 0x00000090,
+ 0x00000050, 0x00000050, 0x00000050, 0x00000050,
+ 0x7000264A, 0x7000264A, 0x7000264A, 0x7000264A,
+ 0x00402069, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xC0D1C0F1, 0x00007EE0, 0xC0D1C0F1, 0x00007EE0,
+ 0x0F80220A, 0x00008000, 0x0F80230A, 0xDEAD1234,
+ 0x00C01A00, 0x23AA7444, 0x1A000010, 0x744400C0,
+ 0x00D023AA, 0x00C01A00, 0x1A007444, 0x74440000,
+ 0x00401A00, 0x1A007444, 0x74440700, 0x06C01A00,
+ 0x230A7444, 0xABCD0F80, 0x1A00DEAD, 0x206900C0,
+ 0x78E00040, 0x803C2242, 0x42007CE0, 0x018020A8,
+ 0x04831101, 0x00D21A01, 0x78E07EE0, 0x803C2242,
+ 0x42007CE0, 0x010020A8, 0x00521A01, 0x78E07EE0,
+ 0xB6881CFC, 0xB6481CFC, 0xB6081CFC, 0xB5C81CFC,
+ 0xB5881CFC, 0xB5481CFC, 0xB5081CFC, 0xB4C81CFC,
+ 0xB4881CFC, 0xB4481CFC, 0xB4081CFC, 0xB3C81CFC,
+ 0xB3881CFC, 0x1CFC7FE0, 0x78E0B348, 0x78E07EE0,
+ 0xDD38748D, 0x78E0F038, 0xDD34748D, 0x78E0F036,
+ 0xDD30748D, 0x78E0F034, 0xDD2C748D, 0x78E0F032,
+ 0xDD28748D, 0x78E0F030, 0xDD24748D, 0x78E0F02E,
+ 0xDD20748D, 0x78E0F02C, 0xDD1C748D, 0x78E0F02A,
+ 0xDD18748D, 0x78E0F028, 0xDD14748D, 0x78E0F026,
+ 0xDD10748D, 0x78E0F024, 0xDD0C748D, 0x78E0F022,
+ 0xDD08748D, 0x78E0F01F, 0x74AD748D, 0x78E0F01C,
+ 0xF01C748D, 0x301A1434, 0x30191430, 0x3018142C,
+ 0x30171428, 0x30161424, 0x30151420, 0x3014141C,
+ 0x30131418, 0x30121414, 0x30111410, 0x3010140C,
+ 0xC601C702, 0x334D24B0, 0x331F24B0, 0x78E07EE0,
+ 0x1CFCC4C1, 0x1CFCB1C8, 0x1CFCB188, 0x1CFCB148,
+ 0xC3E1B108, 0xC1E1C2E1, 0xC4E1C0E1, 0xC0017FE0,
+ 0x0A11C2F0, 0x42300032, 0x0081292F, 0xF00369E1,
+ 0x280070ED, 0x274E03D1, 0x2A011800, 0x70F52000,
+ 0x03D02A00, 0x200921C5, 0x240E2841, 0x0AB24022,
+ 0x41C10020, 0x23C22A00, 0x000042D3, 0x4508FFFF,
+ 0xBA307F50, 0x2408232F, 0x20542240, 0x23640A13,
+ 0x04002940, 0x14C3251A, 0x080F6058, 0x61D900C5,
+ 0x852409ED, 0x294077A5, 0x251A2411, 0x72221400,
+ 0x0A6E4A10, 0x41C10020, 0x0A154300, 0x294020E4,
+ 0x231A0400, 0x60F804C2, 0x0085080D, 0x09EF61D9,
+ 0x77648524, 0x14002D40, 0x2000BD30, 0x254180C0,
+ 0xC6D09001, 0xEB884408, 0x00A5090D, 0x07554020,
+ 0x4181FFEF, 0x00200071, 0x78E04081, 0x4548C2E8,
+ 0x44084220, 0x41407034, 0x700CF646, 0x900C240E,
+ 0x80812003, 0x00330B11, 0x700C4668, 0x900D250E,
+ 0x80CE2003, 0x07CF2B41, 0x07D02A41, 0x0917EE8B,
+ 0x40200365, 0x42A14181, 0x2007FFC2, 0xF40EA3FE,
+ 0x4081C6C8, 0x082242A1, 0x43C10020, 0xA3FE2007,
+ 0x2505F3F8, 0xF3F693BE, 0x200E704C, 0x22038080,
+ 0xC6C88041, 0x00200031, 0x78E0708C, 0x00C42107,
+ 0xF040262F, 0x001270AC, 0x242F0026, 0x200E0104,
+ 0x25038140, 0x70740041, 0x0003000C, 0x8142220E,
+ 0x00C32503, 0x80852305, 0x00010116, 0x44484368,
+ 0x43204200, 0x82C0250A, 0x001A704D, 0x22C00004,
+ 0x25CA1821, 0x2F2F8301, 0x22C00141, 0x22C01063,
+ 0x70EC11C3, 0x80C0250A, 0x082127C0, 0x00040014,
+ 0x808125CA, 0x0141282F, 0x006327C0, 0x000327C0,
+ 0x8287270E, 0x002427CA, 0x45E071E4, 0x8800274C,
+ 0x0012702C, 0x700C0024, 0x42604140, 0x2742706C,
+ 0x240A8807, 0x002A7140, 0x274E0001, 0x007C880A,
+ 0x29000001, 0x29010280, 0x2A0001C1, 0x71A00285,
+ 0x01C22A01, 0x02852B00, 0x01C32B01, 0x224C72A0,
+ 0x00629800, 0x20A80009, 0x200005C0, 0x21018000,
+ 0x22018041, 0x23018082, 0x220200C3, 0x23038302,
+ 0x000E82C3, 0x22000006, 0x23018302, 0x20C082C3,
+ 0x70940066, 0x002270AC, 0x000E0001, 0x220E000A,
+ 0x25038142, 0x242F00C3, 0x000E8100, 0x200E0003,
+ 0x25038140, 0x7EE00041, 0x41404020, 0x706C4260,
+ 0x20A8F1CF, 0x20000380, 0x21018000, 0x22018041,
+ 0x72918082, 0x030622C2, 0x006620C5, 0x704CF1DB,
+ 0x706C6A09, 0x0002212F, 0x78E0F1E7, 0x81422253,
+ 0x224E7CE0, 0x00168803, 0x2801000C, 0x290000CC,
+ 0x28000081, 0x7FE00080, 0x234E7985, 0x28000003,
+ 0x7FE000C1, 0x78E07802, 0x81422253, 0x224E7CE0,
+ 0x00168803, 0x2900000C, 0x290100CC, 0x28010081,
+ 0x7FE00080, 0x234E7885, 0x29010003, 0x7FE000C0,
+ 0x78E07922, 0x00402069, 0xF1FE78E0, 0x0020001D,
+ 0x78E0700D, 0x87C82941, 0x002221CE, 0x87C32842,
+ 0x002220CE, 0x10C82007, 0x8040220A, 0x00210050,
+ 0x700C4100, 0x2D2F6869, 0x25CA8041, 0x2E2F00C4,
+ 0x26CA8081, 0x260200C4, 0x23CA8143, 0x23400024,
+ 0x2AC0007C, 0x20A800C3, 0x210202C0, 0x20CF8081,
+ 0x21C00F06, 0x222F0085, 0x202F0082, 0x202F9202,
+ 0x20CE0003, 0x7FE00025, 0x002221CE, 0x0F802020,
+ 0x05740000, 0xF000260A, 0x0FBF208A, 0x006420CA,
+ 0x202F7FE0, 0x7FE00003, 0x78E0770C, 0x704C702C,
+ 0x708C706C, 0x70CC70AC, 0x700D70EC, 0x704D702D,
+ 0x708D706D, 0x70CD70AD, 0x700E70ED, 0x704E702E,
+ 0x708E706E, 0x70CE70AE, 0x700F70EE, 0x706F702F,
+ 0x3000254A, 0x3000264A, 0x800144DB, 0x42DB8000,
+ 0x04008000, 0xFFCF0AB6, 0x05400E52, 0x0719D830,
+ 0xF1FEFFCF, 0x0C1EC0F1, 0xC1A1FFCF, 0x7487E805,
+ 0x7FE0C0D1, 0x40C3C0A8, 0x12218000, 0x206F8840,
+ 0xA84007C3, 0x208C8803, 0xF20D8FC3, 0xC040C084,
+ 0x08524020, 0xC18409A0, 0xD8FFD911, 0x02600AC2,
+ 0x0EF6B911, 0xD8FF0960, 0x20AB700C, 0x7FFF00C4,
+ 0x78E0F1FF, 0x47CBC2F8, 0x11DA8000, 0x10951746,
+ 0x23784310, 0x40580000, 0x4130781B, 0x2040704E,
+ 0x23140057, 0x19002556, 0x252F0001, 0x0FAF1487,
+ 0x72B52364, 0x2FC1208A, 0x20542244, 0x352E089B,
+ 0x202620CA, 0x70801600, 0x001B8000, 0x800146CB,
+ 0x08214D64, 0x40C3009E, 0x04868000, 0xE88A8800,
+ 0x20300B1F, 0x09E67EB4, 0x961200E0, 0xF00D961E,
+ 0x00E009DA, 0x134026F4, 0x96067EB4, 0x09CEF005,
+ 0x960C00E0, 0x09D69618, 0x700C00C0, 0x00A00D56,
+ 0x2C40712C, 0x70AD20CE, 0x23C02632, 0x10250D3B,
+ 0x21002D40, 0x04C02016, 0xE02460B8, 0x294060E9,
+ 0x20050380, 0x90040F80, 0x90000234, 0x02600AE6,
+ 0xB8C6B8C8, 0x200771A5, 0x40260401, 0x782579D8,
+ 0x20001900, 0x7146F1E2, 0xC6D8F1A9, 0xC1B4C3F6,
+ 0x16004110, 0x80007080, 0x4750000C, 0x800046CB,
+ 0x081B11DA, 0x4728003F, 0xF483B8E1, 0x41E14022,
+ 0x0F0642E2, 0x4380FFEF, 0x1F00C7D6, 0xC0801001,
+ 0x10951646, 0x800041C3, 0xDA4E0F12, 0xFFEF099A,
+ 0x700C708E, 0x704C702C, 0x04600B26, 0x42C3706C,
+ 0xFFFF0000, 0x722C700C, 0x44404340, 0x04600A8A,
+ 0xC0804540, 0x09E009F6, 0x2114D94E, 0x43D32552,
+ 0xF8049007, 0x21051B00, 0x208A7296, 0x24442FC1,
+ 0x0F8B2056, 0x20CA25AE, 0x45CB2026, 0x4D648001,
+ 0x07800AE2, 0x00E008D6, 0x150025F4, 0x15002514,
+ 0x00E008DA, 0x218A9006, 0x40C30FCF, 0xC2EC9007,
+ 0x712CB020, 0x00051800, 0x0C4A700C, 0x70AD00A0,
+ 0x23802232, 0x2E40E823, 0x2D4020D6, 0x20162100,
+ 0x60B80440, 0x60C9E024, 0x03802940, 0x0F802005,
+ 0x26FC9004, 0x208A9040, 0x09DA0FC7, 0x78460260,
+ 0x71A5B8C6, 0x04002007, 0x05812800, 0x78258700,
+ 0x2232A700, 0x0DC72380, 0x71869004, 0xA1140C6D,
+ 0x70051E00, 0x0004901C, 0x20051B00, 0x1F00C7D6,
+ 0x708E1001, 0x10931646, 0x24D22114, 0x208A7296,
+ 0x24442FC1, 0x0F692055, 0x20CA256E, 0x45CB2026,
+ 0x4D648001, 0x07800A2E, 0x00E00822, 0x150025F4,
+ 0x150D2514, 0x00E00826, 0x700C9506, 0x00A00BA6,
+ 0x2232712C, 0xE81C2380, 0x20D52D40, 0x2B4070AD,
+ 0x41222100, 0x04402016, 0xE02460B8, 0x076008DA,
+ 0xB8C660C8, 0x200771A5, 0x28000400, 0x87000541,
+ 0xA7007825, 0x23802232, 0x90040DD7, 0x0C917186,
+ 0xF144A114, 0x1CFCC2FA, 0x2482B6C8, 0x710C3E07,
+ 0x0FDF218A, 0x056008D6, 0xC808704C, 0x3643236F,
+ 0x685270AD, 0x0F802205, 0x00949004, 0xC0449000,
+ 0x30801300, 0x80BE2053, 0xC004F20B, 0x0F812205,
+ 0xC0949007, 0x0080206C, 0x00C02045, 0x2205B100,
+ 0x90080F80, 0x9040002C, 0x2443276F, 0x17004040,
+ 0x20842081, 0x217800CC, 0x20B80103, 0x41C30084,
+ 0x00020190, 0x40C37B04, 0x12DA8000, 0x0FB2A860,
+ 0x740C0220, 0x702CC08E, 0xFFAF0FC6, 0x0007228A,
+ 0xA08017F9, 0x019141C3, 0x20440000, 0x1C0C0200,
+ 0x20783344, 0xC5420000, 0xC540C541, 0xFFEF0C8A,
+ 0x1713C54B, 0x47CB2081, 0x04848000, 0x01002941,
+ 0x00DF0815, 0x009F0819, 0x007F081D, 0x1F00710C,
+ 0xF00D1043, 0x1F00D808, 0xF0091203, 0x1F00740C,
+ 0xF0051103, 0x1F00720C, 0xB9E21083, 0x800041C3,
+ 0x20CA0F0C, 0x764C0062, 0x0F3EAF01, 0xC08CFFAF,
+ 0x712CC08C, 0x07E00822, 0x0E1E714C, 0xC08003A0,
+ 0x050009A6, 0x46CB700E, 0x12208000, 0x30031C17,
+ 0x0408202F, 0x2440C187, 0x0B6E3AC2, 0x244003E0,
+ 0x08C535C3, 0x40C30011, 0x11388000, 0x00431800,
+ 0x30801417, 0x02E00A56, 0x0F2A4210, 0x142B0400,
+ 0x17133091, 0xB8E22080, 0x1F024022, 0xF42B1003,
+ 0x0C1A712C, 0xC28E0820, 0xC18B8E40, 0x3093141C,
+ 0x019645CB, 0x23140002, 0x61792083, 0xA9004362,
+ 0x0EAE740C, 0x41A10220, 0x0FFA4042, 0xC18E0260,
+ 0x702C4022, 0x08200BE6, 0x8E40C28E, 0x1401254F,
+ 0x0E8E740C, 0x43620220, 0x0FDA4042, 0xC18E0260,
+ 0xC18EF022, 0x706C714C, 0x0FC1248A, 0x00200C8E,
+ 0x8E2070AC, 0x2514C527, 0xC18B1042, 0xA9006159,
+ 0x088E4022, 0xC18E03A0, 0x740C8E40, 0x019441C3,
+ 0x0E4E0002, 0x43A10220, 0x0F9A4042, 0xC18E0260,
+ 0x10431F02, 0x202F7106, 0x08290408, 0xC8088114,
+ 0xDD07708D, 0x20057885, 0x00030F80, 0x0DB6F0D8,
+ 0x702C0960, 0x258DC808, 0x24561E3F, 0xB802180C,
+ 0x2005700F, 0x900F0F80, 0x0AF6C364, 0x18000720,
+ 0x14170604, 0x44D33080, 0x01668000, 0x30192440,
+ 0x1C00700E, 0x1CFF2FC3, 0xC046AFC3, 0x200CC006,
+ 0x02A2A000, 0xD9690026, 0x20801713, 0x00FF0821,
+ 0x0F52D840, 0x43000780, 0x41C3740C, 0x00020199,
+ 0x02200DBE, 0x228A4202, 0xF00E2001, 0x07A00F36,
+ 0x4300700C, 0x41C3740C, 0x00020198, 0x02200DA2,
+ 0x704E4202, 0x28152255, 0x2480260A, 0x203E2680,
+ 0x7676706E, 0x002D014A, 0x2FC3218A, 0x70AD70CD,
+ 0x708D706C, 0xC18E4002, 0x0803209A, 0x2B406038,
+ 0x61192141, 0x1F802604, 0xFFF80000, 0x610AB823,
+ 0x78C6D807, 0x7918712C, 0x0448202F, 0x8FC3208C,
+ 0x794BF408, 0xD8FF41A1, 0x41D170AD, 0xF02BF429,
+ 0xF224794B, 0x218C79D0, 0xF79D8042, 0x79707AB0,
+ 0x00850933, 0x07800EAE, 0x8F014300, 0x0EA64E10,
+ 0x781007A0, 0x0E9E4400, 0x404007A0, 0x740C4500,
+ 0x019B41C3, 0x0D0A0004, 0x42620220, 0x442A8F61,
+ 0x41A163BB, 0xF005D8FF, 0x40228F21, 0x452861B9,
+ 0x8F014110, 0x79D0661E, 0x8004218C, 0xFFC50768,
+ 0x262F7970, 0x2179F348, 0x651D0001, 0x006121C5,
+ 0x3082120B, 0x80412144, 0x78B0757C, 0x00A5081D,
+ 0x41C3D80A, 0x0001019F, 0x02000CB6, 0x702C7BAE,
+ 0x00832B44, 0xF01F710F, 0x70347BAE, 0x00832B44,
+ 0x144124CA, 0x23002600, 0x262F6078, 0x0016F006,
+ 0x704C0024, 0x0D137910, 0x25022065, 0x42A22001,
+ 0x4100F005, 0x702CF003, 0xC0874200, 0x04C02014,
+ 0x6179B040, 0x2048782E, 0x08170000, 0x780F2030,
+ 0x20811400, 0x00402009, 0x20021C00, 0x14FFF007,
+ 0x2009A081, 0x1CFF0040, 0x7166A002, 0x2840F15B,
+ 0x2440230D, 0xDE073713, 0x2640250A, 0x25001302,
+ 0x24831501, 0x07A00DAE, 0x44004610, 0x07A00DA6,
+ 0x45004042, 0x4202750C, 0x01A041C3, 0x0C120004,
+ 0x41700220, 0x22012940, 0x79A5C808, 0x20057825,
+ 0x00030F80, 0x0B8E00D8, 0x41C20960, 0x183F268D,
+ 0x3B112440, 0x24112114, 0x20C01100, 0x20487042,
+ 0x7E100000, 0x07A00D5E, 0x430040C1, 0x07A00D56,
+ 0x44004042, 0x41C3750C, 0x000301A1, 0x02200BC2,
+ 0xC8084202, 0x200578A5, 0x00030F80, 0x0B4608D8,
+ 0x41C10960, 0x20C01101, 0x20487042, 0x7E100000,
+ 0x07A00D22, 0x430040C1, 0x07A00D1A, 0x44004042,
+ 0x41C3750C, 0x000301A2, 0x02200B86, 0xC8084202,
+ 0x200578A5, 0x00030F80, 0x0B0A09D8, 0x41C10960,
+ 0x07A00CF2, 0x43004042, 0x41C3750C, 0x000201A3,
+ 0x02200B5E, 0xC8084202, 0x200578A5, 0x00030F80,
+ 0x0AE200D9, 0x41420960, 0x31D92140, 0xFFEF0561,
+ 0x20787106, 0x08423000, 0xB912FFEF, 0x07000822,
+ 0x07400CD2, 0x20801713, 0x003E0815, 0xB88D700C,
+ 0x70041E00, 0x00148000, 0x05000EBA, 0x30801300,
+ 0x80BE2053, 0x0CAEF20B, 0xC8080740, 0x2005B802,
+ 0x90070F81, 0xC004C094, 0xC08CB100, 0x0BEA712C,
+ 0x704C07A0, 0x702C700C, 0x05200BA2, 0x2480704C,
+ 0x14043E07, 0xC6DA341B, 0x47CBC2F4, 0x11DA8000,
+ 0x10921746, 0x46304550, 0x07600C6A, 0x40C24410,
+ 0x428241A2, 0x09A00B0A, 0x40C3706C, 0x27100000,
+ 0x05A00ED2, 0x2453702C, 0x702E2040, 0x00902078,
+ 0x201470CD, 0x70AD2493, 0x23C02332, 0x10250D4B,
+ 0x21002A40, 0x04002016, 0xE02460B8, 0x160060E9,
+ 0x80007080, 0x2053000C, 0xF20780BE, 0x0AFA4020,
+ 0x41020720, 0x2940F00B, 0x20050380, 0x90040F80,
+ 0x90000234, 0x02200B4E, 0x2053B8C8, 0x71A581BE,
+ 0x106226C5, 0x0BEEF1DA, 0x40C20740, 0x428241A2,
+ 0x09A00A8E, 0x2332DB7F, 0x094D23C0, 0x2A402025,
+ 0x20162100, 0x70220400, 0x60E9E024, 0x70801600,
+ 0x000C8000, 0x80BE2053, 0x4020F206, 0x07200A9A,
+ 0xF00C4102, 0x03802940, 0x0F802005, 0x02349004,
+ 0x0AF29000, 0xB8C80220, 0x7126B8C6, 0x0FC120B9,
+ 0xF1DB7E05, 0xC6D478CF, 0xC1A1C3FA, 0xD8404210,
+ 0x210AB89F, 0x250A3140, 0x47682100, 0x00901000,
+ 0x10E54350, 0x46308097, 0x800041D3, 0xEA081138,
+ 0x0F2A4042, 0x712C02A0, 0x20031900, 0x70801600,
+ 0x001B8000, 0x800045CB, 0x08291220, 0x708E007E,
+ 0x20300B21, 0x0A724042, 0x8D4004C0, 0x750C4410,
+ 0x018741C3, 0x43420003, 0x02200986, 0x0500240A,
+ 0x740C8D40, 0x41C34342, 0x0005018A, 0x04C0240A,
+ 0x260A45E1, 0x096A0540, 0x22530220, 0x46CB2058,
+ 0x04878000, 0xE8128E00, 0x201F0F09, 0x201E080B,
+ 0x04200E7A, 0x0F0B710C, 0x080D205F, 0x0E6E205E,
+ 0x720C0420, 0x10031E00, 0x41C37156, 0x08D80003,
+ 0x2078C808, 0x21D63097, 0x78250822, 0xB90C8D20,
+ 0x08B27825, 0xD9400960, 0x710E7076, 0x24A220CA,
+ 0x0DA57EF0, 0x740C23A4, 0x234A708D, 0xC80811C0,
+ 0x03012005, 0xB80C8D00, 0x20057825, 0x00030F80,
+ 0x088200D8, 0x41C10960, 0x1CFF238D, 0x180C2456,
+ 0x06C00DCE, 0xC18040E2, 0x716C734C, 0xFFAF0F02,
+ 0x1400718C, 0x26553009, 0xD8071801, 0x10C82E41,
+ 0x2006B923, 0x244A038B, 0x708D71C0, 0x088020A8,
+ 0x13002901, 0xB8C06C75, 0x02C62800, 0x209F8D00,
+ 0x70C20803, 0x70016078, 0x22058840, 0xA8400182,
+ 0x29014C18, 0x71851000, 0x2800B8C0, 0x8D0002C2,
+ 0x0803209F, 0x631B70C2, 0x88606338, 0xA8407A65,
+ 0xF1B07702, 0x43428D40, 0x018C41C3, 0x08620003,
+ 0x240A0220, 0x70AD04C0, 0xC808DC07, 0x200578A5,
+ 0x00030F80, 0x0FDEF0D8, 0x702C0920, 0x1DFF248D,
+ 0x180D2556, 0x06C00D2A, 0x30100915, 0x20310B11,
+ 0x702C4042, 0x02E00F1E, 0x20431900, 0xC7DA4082,
+ 0x41C3C2E2, 0x12208000, 0x89208941, 0x02C1229F,
+ 0x0582219F, 0x621A6038, 0xB8C38A02, 0x002009D6,
+ 0x068D205F, 0x00802079, 0x0186209F, 0x2534651D,
+ 0x80001F80, 0xC6C20A7C, 0x0AEEC0F1, 0x716C0100,
+ 0xDA62E89D, 0x800140C3, 0xBA9F4E77, 0x8A208800,
+ 0x262F7825, 0x0026F005, 0x12340004, 0x208B0080,
+ 0xF40D8401, 0x01000A7A, 0x0AA2E889, 0xE8870100,
+ 0x00801230, 0x04032044, 0xC0D1BB24, 0x40607FE0,
+ 0x4508C2EA, 0xD8FA4110, 0x46284748, 0x05200B1E,
+ 0x22C1219F, 0x0020096A, 0x40C34010, 0x12208000,
+ 0x762C8800, 0x0582209F, 0x244ADA22, 0x70CC0400,
+ 0x20327022, 0x80010F83, 0x710C4E84, 0xB80278B8,
+ 0x0340200F, 0x7D0FBB86, 0x0AB2700C, 0x45A10060,
+ 0x0402202F, 0x0F33E008, 0x202F103E, 0x700C2007,
+ 0x724CD907, 0x708C706C, 0x0A9270AC, 0x260A0060,
+ 0x700C0400, 0xDA22762C, 0x244A43C1, 0x45A10380,
+ 0x00600A7A, 0x0F2F70CC, 0x700C107E, 0x724CD907,
+ 0x708C706C, 0x0A6670AC, 0x260A0060, 0x700C0400,
+ 0xDA22762C, 0x244A43C1, 0x45A103C0, 0x00600A4E,
+ 0x700C70CC, 0x724CD907, 0x708C706C, 0x0A3E70AC,
+ 0x260A0060, 0x700C0400, 0x724CD907, 0x708C706C,
+ 0x0A2A70AC, 0x264A0060, 0x700C0A00, 0x006009CE,
+ 0xC6CA712C, 0x800040C3, 0x7FE00462, 0x00051800,
+ 0x1E00700C, 0x901C7004, 0x7EE00480, 0xE08E4100,
+ 0xF707710C, 0x704E0E0B, 0x40410000, 0xE1A87EE0,
+ 0x7FE07CE0, 0x78E0700C, 0x45CBC2E4, 0x1A108000,
+ 0xE8049511, 0x10451D28, 0x00200872, 0x460840A1,
+ 0x800040C3, 0xB0C00462, 0x702C40A1, 0xFF6F0E82,
+ 0x700CDA20, 0xB513B514, 0xB511B512, 0xC6C440C1,
+ 0x800041C3, 0x91030462, 0x71109120, 0x7CE0700C,
+ 0xFFCF07B9, 0x800040C3, 0x90000462, 0xB8227FE0,
+ 0x800040C3, 0x7FE0046E, 0x78E08800, 0x0DBEC0F1,
+ 0x700C0060, 0x00600DC6, 0x0C12700C, 0x700C0060,
+ 0xFFCF0F56, 0x7EE0C0D1, 0xC1A4C3F6, 0x800043C3,
+ 0x8B280462, 0xE90770CD, 0x71C56949, 0x80812104,
+ 0x904FF5FC, 0x100E8BA3, 0xB0B30115, 0x01171004,
+ 0x01161002, 0x1028BD0A, 0x1000010B, 0x10240109,
+ 0x10120108, 0x10140107, 0x2B400106, 0x101012CB,
+ 0x90910104, 0x01051020, 0x011E100A, 0x011F1006,
+ 0x01101008, 0x01131016, 0x0111101A, 0x0114100C,
+ 0x01121018, 0x226D902E, 0x1C0C0300, 0xB9C33004,
+ 0xDA7F6A14, 0x24537825, 0x1C0A20C1, 0x256D3004,
+ 0x1C042300, 0x2D403004, 0x78252100, 0x1C02BA07,
+ 0x2A403004, 0x235321C0, 0x78442181, 0x29407905,
+ 0x78252380, 0x31812753, 0x30041C08, 0x21C02840,
+ 0x93E37844, 0x2E407905, 0x78253380, 0x02012D40,
+ 0x30041C00, 0x21846C17, 0x2004000C, 0x00000F80,
+ 0x78257C00, 0x01012C40, 0x04012144, 0x7905BC0C,
+ 0x01402F40, 0x08012084, 0x79058B4A, 0x01C02E40,
+ 0x7825780F, 0x12012840, 0x30041C0E, 0x1F802404,
+ 0x70000000, 0x000C2184, 0x782578A5, 0x1F812304,
+ 0x08000000, 0x29407825, 0x21441101, 0x79050401,
+ 0x21402E40, 0x08012084, 0x2F407905, 0x780F21C0,
+ 0x79FD7825, 0x30041C06, 0x0A6DEA08, 0x7CCF0071,
+ 0x641C8B09, 0x12140C57, 0x244A6912, 0x20057100,
+ 0x00100F81, 0xC0804000, 0x03C020A8, 0x050B1002,
+ 0x0F8D2105, 0x00009000, 0x050C1002, 0xBC107424,
+ 0x12CC2405, 0x4F98A580, 0x907E2053, 0xB323B9A0,
+ 0x710CF205, 0x02002006, 0x40C3AB0B, 0x1A308000,
+ 0x00710A15, 0x00051800, 0x60D88B09, 0x00031B08,
+ 0xAB09B8C2, 0xC7D67830, 0x4350C2EE, 0x09D74130,
+ 0x47080030, 0x2FC3208A, 0x800045CB, 0x70CD1A10,
+ 0x2448222F, 0x21140A1D, 0x20300B19, 0x90BE2753,
+ 0x700CF219, 0xA5077726, 0xA505A506, 0xF02EA504,
+ 0x90BE2753, 0x0A69F21F, 0x74E52070, 0xA5C6A5C7,
+ 0x0D8AA5C5, 0xA5C4FFEF, 0x20B00A49, 0x77264708,
+ 0x40A1F1E0, 0x0C1A702C, 0xDA20FF6F, 0xA048228C,
+ 0x00250046, 0x1D22732C, 0x21801404, 0xB5322038,
+ 0x0A21F00C, 0x40A12070, 0x0BF6702C, 0xDA20FF6F,
+ 0x20B00A3B, 0x20912142, 0xFFCF0D42, 0xF1C24708,
+ 0x74E5A5C3, 0xA5C1A5C2, 0xF01DA5C0, 0xA5C6A5C7,
+ 0xA5C4A5C5, 0x2104F017, 0x00002F80, 0x781DFFFE,
+ 0x203F090F, 0xB5327704, 0xE708B511, 0xB532F00B,
+ 0xFFEF0D0A, 0x702CB511, 0xA52068E4, 0xA522A521,
+ 0x78F0A523, 0x78E0C6CE, 0x4508C2E2, 0x0060096E,
+ 0x080C208A, 0x752CD809, 0xDA0CB813, 0x0008238A,
+ 0x45A1708C, 0x00200EB6, 0x700C70CC, 0x724C762C,
+ 0x244A736C, 0x45A10680, 0x00200EA2, 0x0EF270CC,
+ 0x700C03C0, 0x724C762C, 0x244A716C, 0x45A10680,
+ 0x00200E8A, 0x0EDA70CC, 0x700C03C0, 0x724C762C,
+ 0x244A706C, 0x45A10680, 0x00200E72, 0x700C70CC,
+ 0x095ED922, 0x704C0060, 0x752C700C, 0x238A744C,
+ 0x708C000E, 0x0E5645A1, 0x70CC0020, 0xD907D880,
+ 0x744CB893, 0x708C706C, 0x0E4270AC, 0x70CC0020,
+ 0xFFCF0CA6, 0x78107704, 0x78E0C6C2, 0x4508C2EA,
+ 0x70801600, 0x00088000, 0x00B1080D, 0x2280204A,
+ 0xF00574CD, 0x2240204A, 0x0C9672CD, 0x08AEFFCF,
+ 0x208A0060, 0x08B2080C, 0x706C0040, 0x4768D907,
+ 0xBF8F724C, 0x40E1708C, 0x0DF270AC, 0x70CC0020,
+ 0xD907700C, 0x706C704C, 0x70AC708C, 0x00200DDE,
+ 0x6F1570CC, 0x704C752C, 0x708CDB80, 0x0DCE45A1,
+ 0x70CC0020, 0x12002F40, 0x42C1D929, 0x708C706C,
+ 0x70CC45A1, 0x00200DB6, 0x40224110, 0x42C1D929,
+ 0x708C706C, 0x0DA645A1, 0x70CC0020, 0x30821204,
+ 0xD907700C, 0x708C706C, 0x0D9270AC, 0x70CC0020,
+ 0xD907700C, 0x706C704C, 0x70AC708C, 0x00200D7E,
+ 0x6F1670CC, 0x704C752C, 0x0004238A, 0x45A1708C,
+ 0x00200D6A, 0xD80870CC, 0xB898D92A, 0x706C42C1,
+ 0x45A1708C, 0x00200D56, 0xD84170CC, 0xB812D92A,
+ 0x706C42C1, 0x45A1708C, 0x00200D42, 0x700C70CC,
+ 0x744CD907, 0x708C706C, 0x0D3270AC, 0x260A0020,
+ 0x0FBE0400, 0x700C0000, 0x704CD907, 0x708C706C,
+ 0x0D1A70AC, 0x70CC0020, 0xD907D880, 0x706C704C,
+ 0x70AC708C, 0x00200D06, 0x0B6E70CC, 0x7704FFCF,
+ 0xC6CA7810, 0x40C3C0F1, 0x61A80000, 0x0000080E,
+ 0xFFCF0AE2, 0x7EE0C0D1, 0x0072081D, 0x1600714C,
+ 0x901C7101, 0xE9850484, 0x71447210, 0x2179F6B9,
+ 0xF0030000, 0xD90B700C, 0xFF6F066D, 0x78E0B912,
+ 0x082DC2E2, 0x43200072, 0x800045CB, 0x8D420462,
+ 0x28057810, 0x0B110081, 0x9500027F, 0xEA848D4B,
+ 0xF003714C, 0x0CE6704C, 0xB500FFCF, 0x78E0C6C2,
+ 0x70ADC0E6, 0xB0A2E2B3, 0xB0A7B0A1, 0x0302B0A6,
+ 0xB0A0002D, 0x24AD4468, 0x20241203, 0x00F50080,
+ 0x01090000, 0x01310000, 0x015B0000, 0x01850000,
+ 0x01A50000, 0x01B30000, 0x00B70000, 0x00BB0000,
+ 0x02CF0000, 0x00BD0000, 0x01AB0000, 0x01B30000,
+ 0x02BF0000, 0x01AF0000, 0x01C10000, 0x01C70000,
+ 0x00A10000, 0x02AB0000, 0x02A70000, 0x02A30000,
+ 0x029F0000, 0x029B0000, 0x02970000, 0x02930000,
+ 0x01AD0000, 0x01BB0000, 0x006F0000, 0x01C10000,
+ 0x01E90000, 0x01E90000, 0x01EB0000, 0x006F0000,
+ 0x017D0000, 0x01E90000, 0x01E90000, 0x01F10000,
+ 0x01F30000, 0x00570000, 0x00370000, 0x01F30000,
+ 0x01F70000, 0x01F70000, 0x01F70000, 0x01F90000,
+ 0x01F90000, 0x01FD0000, 0x020B0000, 0x02210000,
+ 0x000F0000, 0x021D0000, 0x021D0000, 0xB0A40000,
+ 0x0020021F, 0xDB78B0A3, 0x2453B063, 0xF0A600C3,
+ 0xB063DB38, 0x00832453, 0x0203F0A0, 0xBBC60020,
+ 0x02F270D4, 0x23530021, 0xBB24018C, 0x0E012384,
+ 0x2345B084, 0xF0F400C3, 0x2C406BF3, 0x2453008C,
+ 0x274400C4, 0x24841C0E, 0x24051001, 0x24050384,
+ 0x7B7B110C, 0x2384B084, 0x27440C01, 0x7B85120C,
+ 0xF0DEBB80, 0x2C406BF3, 0x2453008C, 0x274400C4,
+ 0x24841C0E, 0x24051001, 0x24050384, 0x7B7B110C,
+ 0x2384B084, 0x27440C01, 0x7B85120C, 0x01432345,
+ 0x6BF3F0C6, 0x008C2C40, 0x00C42453, 0x1C0E2744,
+ 0x10012484, 0x03842405, 0x110C2405, 0xB0847B7B,
+ 0x0C012384, 0x120C2744, 0x23457B85, 0xF0B00183,
+ 0xBB037C7B, 0x1C012484, 0x0C032344, 0xB083BC82,
+ 0x008C2C40, 0x00C42453, 0x10012484, 0x01032305,
+ 0xF03C7B85, 0x2453BB23, 0x2384018C, 0xB0840C01,
+ 0x03032345, 0x0E25F094, 0x02370011, 0x18080020,
+ 0xBB050104, 0x2384DC68, 0xB0830801, 0xDB28F026,
+ 0x70D4F060, 0x00010218, 0x018C2353, 0x23847B7D,
+ 0xB0840001, 0xF07CBB83, 0x01041808, 0x06051806,
+ 0xDB38F077, 0x2453B063, 0xF00F0083, 0x018C2353,
+ 0x23847B7D, 0xB0840001, 0x0C032345, 0xDB78F068,
+ 0x2453B063, 0xBB8600C3, 0xF063B064, 0x2C406BF3,
+ 0x2453008C, 0x274400C4, 0x24841C0E, 0x24051001,
+ 0x24050384, 0x7B7B110C, 0x2384B084, 0x27440C01,
+ 0x7B85120C, 0xF04CBB81, 0xF049DB58, 0xB083B084,
+ 0x7B7DF047, 0x00012384, 0xF041BB83, 0xF041B084,
+ 0x2384BB23, 0x23450C01, 0xF0390303, 0x01832453,
+ 0x7B7DF035, 0x00012384, 0x0C032345, 0x70D4F02F,
+ 0xDB40F51F, 0xDB60F006, 0xDB20F004, 0xDB50F002,
+ 0xF026B0A4, 0xF023DB38, 0x00832453, 0xF01FBB86,
+ 0xBB037C7B, 0x1C012484, 0x02032344, 0xBB807B85,
+ 0xBB03F015, 0x008C2C40, 0x00C42453, 0x0C032344,
+ 0x10012484, 0x01032305, 0xF0097B85, 0xF007DB40,
+ 0xF005DB68, 0x2384BB05, 0xB0640801, 0x091DB063,
+ 0x0A19041F, 0x22780C70, 0x230B0A03, 0xF4068180,
+ 0x00432553, 0xF003B065, 0x0939B0A5, 0xDB0D053F,
+ 0x057F0937, 0x0939DBD0, 0xDB0D05BF, 0x05FF0937,
+ 0x0939DB08, 0xDB80063F, 0x067F09B3, 0x0010238A,
+ 0x06BF09D3, 0x0004238A, 0x06FF09D3, 0xF010706C,
+ 0x0345180E, 0xB067F00C, 0xF00ADBD0, 0xB067BB08,
+ 0x180EF006, 0xF0040205, 0xDB80B067, 0x0909BB8C,
+ 0xB06704DE, 0x07550A13, 0x708F0E21, 0x00181000,
+ 0x0B21766C, 0x2242008F, 0x0B190843, 0x0A150094,
+ 0xE2A90AF0, 0xF414704C, 0x180C744C, 0xF0100105,
+ 0x00832941, 0x7A66724C, 0x01032144, 0x21447074,
+ 0x0B0D0303, 0x22CF0330, 0xB0460021, 0x049E090B,
+ 0x00C22245, 0x262FB046, 0x000AF046, 0x18040003,
+ 0x090B0045, 0xBA83033E, 0x090DB046, 0x0D09019F,
+ 0xC4C6005F, 0x00451800, 0xB067C4C6, 0xBB0A756C,
+ 0x2B41F1BF, 0xBB2B01CC, 0x1C012484, 0x0E012384,
+ 0x110E2405, 0x01C32345, 0xF17AB0C4, 0xDB58B084,
+ 0xB067F176, 0xBB08DB11, 0x238AF1AB, 0xB0670008,
+ 0xBB09DB09, 0x78E0F1A5, 0x0C1AC2E2, 0x45280020,
+ 0x05600886, 0x0EB2760C, 0x7704FF8F, 0x00200C8E,
+ 0x0C6E7810, 0x70B50000, 0xFFC20B3C, 0x78E0C6C2,
+ 0x0BF2C2E2, 0x45280020, 0x0560085E, 0x0C52760C,
+ 0x70B50000, 0xFFC20B20, 0x78E0C6C2, 0x800040C3,
+ 0x7FE0046F, 0x00431800, 0x46CBC2F4, 0x04628000,
+ 0x8E4D4050, 0x2180260A, 0x2140240A, 0x2100250A,
+ 0x43304270, 0x01B1092D, 0xEA144110, 0x8E008EA2,
+ 0x80BE2053, 0x7DBBF402, 0x0487212F, 0x0A8640A2,
+ 0x42820020, 0x23402002, 0xFFEF0B0A, 0xF0C94122,
+ 0x081D8E0A, 0x40620071, 0xFFAF0DB6, 0x20788E68,
+ 0xBB240000, 0xB870B806, 0xAE086078, 0x47CB7054,
+ 0x1A108000, 0x223E090F, 0x206120C0, 0xB8819710,
+ 0x090DB710, 0x9710235E, 0xB710B880, 0x0E699620,
+ 0x21532030, 0x08190080, 0x700C0131, 0xA706A707,
+ 0xA704A705, 0x0D866904, 0xB600FFAF, 0x42628E23,
+ 0x43428E04, 0x41227825, 0x00002079, 0x0540240A,
+ 0x40E1AE03, 0x0500250A, 0x0ABA70CC, 0x70ADFFEF,
+ 0xFFAF0D3E, 0x08C54062, 0x4FA80030, 0x41224020,
+ 0x43424262, 0x0540240A, 0x0500250A, 0xFFEF0A96,
+ 0xF05871CC, 0x01110829, 0x225F0911, 0x8E438E04,
+ 0x00010A09, 0xE80C9712, 0xA704700C, 0xA706A705,
+ 0x6904A707, 0xFFAF0D16, 0x9620B600, 0x09CBB9C2,
+ 0x40620130, 0x003109C1, 0x8E23700C, 0x8E044262,
+ 0x78254342, 0x20794122, 0x240A0000, 0xAE030540,
+ 0x250A40E1, 0x0A3E0500, 0x70CCFFEF, 0x96008E22,
+ 0x090F7404, 0xB600227E, 0xB8819712, 0x4062B712,
+ 0xFFAF0CAE, 0x204D2002, 0x4F28E813, 0x42624122,
+ 0x240A4342, 0x250A0540, 0x0A0A0500, 0x71CCFFEF,
+ 0x74049600, 0xFFAF0CDE, 0x8E02B600, 0x40A17D02,
+ 0xFFEF09C2, 0xF0234122, 0xA1A2A1A3, 0xA1A0A1A1,
+ 0x96008EA2, 0xB600E008, 0x23402017, 0x0072082B,
+ 0x15841F22, 0x1F2460B8, 0x77041085, 0xFFAF0C6E,
+ 0x2F057F10, 0x96001341, 0xFFAF0E92, 0xB600704C,
+ 0x22D1214F, 0x1F24F003, 0x8E0410C5, 0x0E32AE03,
+ 0x40220620, 0x0C2AC6D4, 0x4308FF8F, 0x41224F28,
+ 0x43424262, 0x0540240A, 0x0500250A, 0xFFEF0986,
+ 0x960070CC, 0x0B357404, 0xB6001030, 0xFF8F0C1E,
+ 0x40E18EA2, 0x42624122, 0x240A4342, 0x250A0540,
+ 0x09620500, 0x71CCFFEF, 0x20029600, 0x74042341,
+ 0x8E02B600, 0xF10A4910, 0x20028E02, 0x0D13200D,
+ 0x0BEA1052, 0x40A1FF8F, 0xFFEF090A, 0x09934122,
+ 0x9712A2DE, 0xB712B880, 0x78E0F1C3, 0xC1ABC3E6,
+ 0x45284748, 0xC0804608, 0x0A66702C, 0xDA2AFF2F,
+ 0x41838E00, 0x8E01B103, 0x8E02B104, 0x8E03B10B,
+ 0x103E0F0B, 0x1C0AB10C, 0x0F0B3344, 0x1C1A105E,
+ 0x0C1A3344, 0xC080FFAF, 0x78E0C7C6, 0x800040C3,
+ 0x7FE00466, 0x00031800, 0x800041C3, 0xB1000462,
+ 0xB1037FE0, 0x800040C3, 0x7FE00466, 0x00431800,
+ 0x800043C3, 0xB30419E4, 0xB303D858, 0x01802153,
+ 0x2253B30C, 0xB30D0040, 0x800044CB, 0xB3050462,
+ 0xB308781D, 0x783DB300, 0x0140206C, 0xB8839440,
+ 0xB30BE208, 0x03B54060, 0xB440FFAF, 0xC1A4C3E8,
+ 0x800046CB, 0x47480462, 0x45289640, 0x00812253,
+ 0x700C4010, 0xC042C043, 0x091FC041, 0xC0400131,
+ 0x800041C3, 0xA1001A20, 0xA102A101, 0x6A04A103,
+ 0xFFAF0AFA, 0x8E02B600, 0x781B70F5, 0x080F780F,
+ 0x20CA2031, 0x0D090062, 0x45081005, 0x100E2D05,
+ 0x781078C9, 0x26C27510, 0x78D01061, 0x8004208C,
+ 0xD908F792, 0xB80AD81F, 0xB2074283, 0x08002059,
+ 0x0892B203, 0xC0800920, 0x107C2680, 0x208C78D0,
+ 0xF7328FC3, 0xF388262F, 0x2E40F212, 0x20041300,
+ 0x00000F80, 0xB8887000, 0xB88BB889, 0x30041C06,
+ 0x20046E17, 0x00000F80, 0xF0057C00, 0x1C06700C,
+ 0x1C0E3005, 0xC0803004, 0x0920084A, 0xC7C8D908,
+ 0x800041C3, 0x19020462, 0x7FE00043, 0x78E0A90C,
+ 0x70041E00, 0x049C901C, 0x78E07EE0, 0xC1A8C3E6,
+ 0x47284648, 0x24404508, 0x702C3080, 0xFF2F08E2,
+ 0x6E13DA1E, 0x2044BE0E, 0x42830400, 0xB203B20B,
+ 0x1F802605, 0x2C580000, 0x2753B200, 0x68371180,
+ 0xB20C7825, 0x11802553, 0x78256837, 0x78FDB204,
+ 0x0140206C, 0x2605B883, 0xB8071001, 0xC0807905,
+ 0x0FD2B228, 0xD91008E0, 0x78E0C7C6, 0x1E00710C,
+ 0x901C7004, 0x7EE00480, 0xB9025020, 0x0F812105,
+ 0x0488901C, 0xB1007FE0, 0xB9025020, 0x0F812105,
+ 0x048C901C, 0xB1007FE0, 0x4708C2E8, 0x20846A15,
+ 0x204F0001, 0x204F06D0, 0x2148068E, 0x77040040,
+ 0x68A17810, 0x400270F5, 0x038120CA, 0x704CD907,
+ 0x708C706C, 0x0B7670AC, 0x70CCFFEF, 0x1D3F258C,
+ 0x78E0C6C8, 0x256FC2E8, 0x46081743, 0x10D01500,
+ 0x20402040, 0x7314780F, 0x002500F0, 0x0D1E70ED,
+ 0x42C10880, 0x00842280, 0xE8188A60, 0x10C21500,
+ 0x780F6A01, 0x00F408D5, 0x2A446B01, 0xB8220081,
+ 0x0FC02049, 0x10002615, 0x0A999081, 0x242F00B2,
+ 0x90200045, 0xF0497180, 0x20B2082D, 0x20812844,
+ 0x170B1682, 0x240A6B01, 0x20A87000, 0x26150300,
+ 0x908110C0, 0x12C40C41, 0x0B3D9000, 0x77641004,
+ 0xF01B700C, 0x700CE3BF, 0x1682F717, 0xDC40170B,
+ 0x240A7C62, 0x20A87300, 0x261503C0, 0x94A110CC,
+ 0x12C40D15, 0x0B119480, 0xE3BF1324, 0x20CA7164,
+ 0xF0030FE1, 0x60384060, 0x7B0FAA00, 0x17021682,
+ 0xF749E3C0, 0x96017E75, 0x0084080B, 0x0A3D9600,
+ 0x242F0005, 0xD8C80045, 0x022041C3, 0xF0130003,
+ 0x792D7933, 0x1E824C31, 0x9000105C, 0x10240C0F,
+ 0x0C0B7A30, 0x0A151084, 0xD8C80005, 0x021F41C3,
+ 0x0F0E0003, 0xDF070140, 0xC6C840E1, 0x0DA2C2F2,
+ 0x451001A0, 0x704E4410, 0x800047CB, 0x0AA91222,
+ 0xD82520B5, 0x8820B89F, 0x7825881B, 0x048E0895,
+ 0x1A0D8FC0, 0x7DCF3482, 0x08898F01, 0x40C30344,
+ 0x12D98000, 0x08798800, 0x40A2036E, 0x085641A1,
+ 0x1A0B0760, 0x43103358, 0x0865700E, 0x0B5D2295,
+ 0x210A242E, 0x1A0C2500, 0x40C33418, 0x28F00000,
+ 0x221A7A1B, 0x211A2001, 0xB8222082, 0x623A78AA,
+ 0x40026219, 0x0184209A, 0x70C36038, 0x1A3C8000,
+ 0xFFEF0E76, 0x34581A0D, 0x3082120D, 0x00002078,
+ 0x3603120B, 0x021E41C3, 0x0B6E0003, 0x120CFF2F,
+ 0x71363604, 0xF5DB712E, 0xF1D17106, 0xF1BD71C5,
+ 0xF1AF7146, 0x78E0C6D2, 0x1CFCC2FA, 0xC1A8B6C8,
+ 0xD8254318, 0x1600B89F, 0x80007091, 0x44D31222,
+ 0x00489004, 0x24428820, 0x881B2210, 0x20787825,
+ 0x204000C0, 0x16000055, 0x80007080, 0x08E11223,
+ 0x40C30444, 0x12D98000, 0x08D18800, 0x212F046E,
+ 0x0F920447, 0x40630720, 0x23182940, 0x706E4118,
+ 0x34EE09B3, 0x22002B40, 0x200570AD, 0xC8080601,
+ 0x69127905, 0x20054230, 0x90040F96, 0x215A0320,
+ 0xC7802A00, 0x800041C3, 0x7FB4C004, 0x04C02015,
+ 0x603278B4, 0x11A06119, 0x20340101, 0x80000F80,
+ 0xB740BEC4, 0x1C08B722, 0x25053004, 0x68D21480,
+ 0x15002605, 0x00E009D6, 0xB7059000, 0x140E2605,
+ 0x00E009CA, 0xB7079600, 0x160071A5, 0x0DB32100,
+ 0x1C129564, 0x40A23004, 0x062009E6, 0x706CC180,
+ 0x2305C485, 0x14020480, 0xB8021501, 0x20057164,
+ 0xB2200502, 0x04012005, 0x0BEB9401, 0xB1008564,
+ 0x70801600, 0x00EE8000, 0x141CE885, 0x1E003100,
+ 0x71662004, 0xA2540B4D, 0xF18F7126, 0x1404C0A8,
+ 0xC6DA341B, 0xC1A3C3F8, 0xD8254018, 0x1600B89F,
+ 0x8000708D, 0x16001222, 0x80007092, 0x88200187,
+ 0x881B7056, 0x242122CA, 0x20787825, 0x204000C0,
+ 0x16000053, 0x80007080, 0x08DB1223, 0x40C30344,
+ 0x12D98000, 0x08CB8800, 0x79AF036E, 0x07200E76,
+ 0x2D404003, 0x47101316, 0x0FB1700E, 0x2840242E,
+ 0x702E2200, 0x05812005, 0x2105C808, 0x25050015,
+ 0xC1812440, 0x260568D2, 0x90041F8F, 0x0B960048,
+ 0x97000260, 0x1F8E2605, 0x00409004, 0x0B869600,
+ 0xC1820260, 0x30821409, 0x30811405, 0x0483223D,
+ 0x0480213D, 0xC022786B, 0xE810F410, 0x08022254,
+ 0x2154C321, 0x77040801, 0x1C097764, 0xC0623082,
+ 0x1C05C361, 0xF0033042, 0x792FC321, 0x0007252F,
+ 0x262FC140, 0x272F0087, 0x740C00C7, 0x41C34222,
+ 0x0007025A, 0x0C4A43A1, 0x240A0160, 0x0CF60400,
+ 0xC0810160, 0x0CEEB700, 0xC0820160, 0x2140B600,
+ 0x086F2040, 0x712E84E4, 0x08537106, 0x71A5A254,
+ 0xC7D8F191, 0x88606038, 0xA8607B44, 0x0083104B,
+ 0x184B7B44, 0x109600C2, 0x7B440083, 0x00C21896,
+ 0x008310E1, 0x7FE07A64, 0x008218E1, 0x2482C3F4,
+ 0x250A3306, 0x230A2180, 0x40702100, 0x45284650,
+ 0x248A4410, 0x24407001, 0x218A3011, 0xC0800FC7,
+ 0x014020A8, 0x1804B021, 0x18000015, 0xD8FF0005,
+ 0x301C1C82, 0x38002456, 0x000042D3, 0x47CB0A3C,
+ 0x1A3C8000, 0x00300D89, 0x07C31802, 0x1481251F,
+ 0x0184228A, 0x2F80241F, 0x28F00000, 0x2184209F,
+ 0x70026038, 0x0B9260F9, 0xC080FEEF, 0x088008AE,
+ 0x003008DB, 0x1600DD3F, 0x80007080, 0x080F0001,
+ 0x1600009F, 0x8000708D, 0x08920120, 0x24560880,
+ 0x24003843, 0x00003F81, 0xA901010C, 0x712C40A1,
+ 0x02E00EBE, 0x148A704C, 0x248A370D, 0x708D7001,
+ 0x20A8C080, 0x10020340, 0x10020503, 0x4A710502,
+ 0x71247270, 0x24C079AC, 0xF0501046, 0x20842180,
+ 0xA3440E9D, 0x20900B0F, 0x20510B13, 0x101F0D0B,
+ 0x0D0BF005, 0x71A5101F, 0x70CDF1F4, 0x94050EFB,
+ 0x20310D11, 0x16802500, 0x0080101C, 0x10000E4B,
+ 0x0880081A, 0x1482251A, 0x241F7014, 0x00002F81,
+ 0x708D28F0, 0x800040C3, 0x61591B3E, 0x229A42C1,
+ 0x623A0184, 0x6059F206, 0x14829161, 0x4B343701,
+ 0x620A62F9, 0x20801100, 0x0306242F, 0xC0804A13,
+ 0x00600F96, 0x71C5C280, 0x248AF1D2, 0x708D7001,
+ 0x20A8C080, 0x10020300, 0x10020502, 0x49530501,
+ 0x71647150, 0x10C624C0, 0xC7D47890, 0x4008C0E6,
+ 0x7001248A, 0x70CD70ED, 0x07C020A8, 0x000044CB,
+ 0x7D9B28F0, 0x1300201F, 0xBC227D6A, 0x60B87C2A,
+ 0x4448609D, 0x1184249F, 0x44CB659D, 0x1A3C8000,
+ 0x71E57DF5, 0x64BC6590, 0x4C159481, 0x25407410,
+ 0x26C0104B, 0x78D012C6, 0x78E0C4C6, 0x78E07EE0,
+ 0x70851E00, 0x0088900C, 0x78E07EE0, 0x0921C0F1,
+ 0x271400A5, 0x0ACE000C, 0x40A00160, 0x0AC6B40A,
+ 0x40C00160, 0x2740B40C, 0xF00C0200, 0x01600AB6,
+ 0xB40A4060, 0x01600AAE, 0xB40C4080, 0x04802740,
+ 0xC0D19000, 0x1F1C7FE0, 0x78E00004, 0x08EDC3F4,
+ 0xC1A40071, 0x47CB712E, 0x12228000, 0x20F509D3,
+ 0x0447202F, 0x00900813, 0x0051081B, 0x70811600,
+ 0x00258000, 0x1600F005, 0x80007081, 0x09AF0040,
+ 0x0D1A00D1, 0x0EEE01C0, 0x706E0600, 0x20B50B9F,
+ 0x0DB64062, 0x702C00A0, 0x20408FA0, 0x8F010A94,
+ 0x03440887, 0x13122D40, 0x2205C808, 0xC1802510,
+ 0x04002005, 0x04C22116, 0x46CBB802, 0x00009004,
+ 0x78C57AB4, 0x0B5F9000, 0xB2002071, 0x034021F4,
+ 0x422279B4, 0x9124716C, 0x603844A1, 0x042241C3,
+ 0x78100006, 0x0002252F, 0x01D62841, 0x01552553,
+ 0x260A740C, 0x093A0580, 0x270A0160, 0x2E400540,
+ 0x20052180, 0xC8080541, 0x04822005, 0x04002005,
+ 0xB802BA02, 0x22057E05, 0x90040F82, 0xB22000A8,
+ 0x71A5B620, 0x7166F1BD, 0x7126F1B2, 0x0E46F198,
+ 0x0C6A0600, 0x730C01E0, 0x78E0C7D4, 0x41C3C2F0,
+ 0x000001CF, 0x016008EA, 0x43D3740C, 0x12228000,
+ 0x208E1300, 0x800142D3, 0x22164D44, 0x1301238D,
+ 0x76102080, 0x002D0120, 0x23802216, 0xCC2290E0,
+ 0x702EE819, 0x40F144B1, 0x21041400, 0x42C1740C,
+ 0x01D041C3, 0x08AA0003, 0x43220160, 0x25001402,
+ 0x20087126, 0x27092010, 0xCC22100F, 0xA00409DD,
+ 0x40F1F002, 0x41C3740C, 0x000201D1, 0x088242E1,
+ 0x43020160, 0x740C7702, 0x41C37FFD, 0x000201D2,
+ 0x1310274E, 0x232F42E1, 0x08660408, 0x41700160,
+ 0x2E406F14, 0x20051343, 0x29402010, 0x20052100,
+ 0xC80803DF, 0x2300718C, 0x00000F8C, 0x726D1000,
+ 0x903842C3, 0x0C0F0000, 0x208A0031, 0x208A1C15,
+ 0x20051415, 0xB9021001, 0x1016218A, 0x0C0D7945,
+ 0x91200031, 0x1815218A, 0x000C2184, 0x2105708C,
+ 0x210507CF, 0xB9021001, 0x794572AC, 0x912070CC,
+ 0x000C2184, 0x20472005, 0x02012600, 0x001E2105,
+ 0x30C12605, 0x7945B902, 0x2605B1E0, 0xB9023301,
+ 0xB1E07945, 0x02412600, 0x00062105, 0x00C12605,
+ 0x7945B902, 0x01C41900, 0x03012605, 0x71CCB902,
+ 0x258D7945, 0x1900093F, 0x238C01C4, 0xE5081FFE,
+ 0xF16F71C5, 0x06000CEE, 0x78E0C6D0, 0x014422AA,
+ 0x010421AA, 0x800040C3, 0xA0410450, 0xA0207FE0,
+ 0x700026F4, 0x0F608000, 0x78E07EE0, 0x803C2042,
+ 0x012220E8, 0x0040212F, 0x7FE06909, 0x78E07810,
+ 0x4010C2E8, 0x4568730C, 0x0AD24648, 0x472801E0,
+ 0x800040C3, 0x88001138, 0x1600E810, 0x80007080,
+ 0x08190001, 0xD80F00FF, 0x42E14102, 0x708C43C1,
+ 0x08A00C16, 0xC6C845A1, 0x4102D80F, 0x43C142E1,
+ 0x08A00A6A, 0xC6C844A1, 0xEA06C0E6, 0x248A76AD,
+ 0xF005100F, 0x248ADD07, 0x2278100E, 0xBA060002,
+ 0x2204E23F, 0x7984004F, 0x7C0479B9, 0x2C0169D6,
+ 0x66FE1340, 0x0E176836, 0x61581064, 0x76107810,
+ 0x108D24C0, 0x6698F703, 0xC8084834, 0xB8027865,
+ 0x0F802005, 0x3C009004, 0xC4C6B080, 0x093EC2E2,
+ 0x099E02C0, 0x450802E0, 0x02A00D66, 0x609860BC,
+ 0x00412044, 0x780F6038, 0x07012089, 0x30021A04,
+ 0x78E0C6C2, 0x4008C2E6, 0x800040C3, 0x08151221,
+ 0x88401071, 0x70831600, 0x00408000, 0xF2957074,
+ 0x1030080D, 0x100C2078, 0xF0038865, 0xEC848863,
+ 0xF0038886, 0xC8088884, 0xDD787034, 0x0C0F706D,
+ 0x25CA10E5, 0x70CD1822, 0x2178F01F, 0x655D0001,
+ 0x70CDB903, 0x00462140, 0x03012B40, 0x7180240A,
+ 0x702D61B9, 0x69F27905, 0x030020A8, 0x13C12105,
+ 0x10102180, 0xB99CB992, 0x9120B99F, 0x038E2108,
+ 0x71647391, 0xB802F7AA, 0x0343236F, 0x0F802005,
+ 0x00209004, 0x730C9080, 0x05091302, 0x100C2479,
+ 0x210C8B20, 0x00009F80, 0x20CA0C7F, 0x723400AD,
+ 0x23CA7C9B, 0x718510E1, 0x2300DDFF, 0x7C3D130B,
+ 0x2E01E407, 0x7461130C, 0x208A641C, 0x20CA0FC7,
+ 0x78C40341, 0x00002079, 0x2356641C, 0x10000940,
+ 0x609800C0, 0x2048780E, 0xCA070003, 0x0813E80F,
+ 0x12210231, 0x0C17370C, 0x00001F80, 0x08176815,
+ 0x0C130251, 0x00001F81, 0x09177196, 0xBB620111,
+ 0x210CF007, 0x00009F80, 0x23C22156, 0x202F0066,
+ 0x242F0200, 0x785500C8, 0x007541C3, 0x70C30003,
+ 0x04588000, 0x6B09B060, 0x43017810, 0xFEEF0A7A,
+ 0x03C0207C, 0x40C3C6C6, 0x04588000, 0x90207855,
+ 0xC6C6B021, 0xC80843E3, 0x2005B802, 0x90080F80,
+ 0x90000014, 0x02A00F96, 0x2044B8C3, 0x781D0041,
+ 0x7B006038, 0x1CFCC2FA, 0x2482B6C8, 0xD98E3805,
+ 0xB99F70AD, 0xC551DA80, 0x11F88900, 0xC552808E,
+ 0x8908C047, 0xC553702C, 0xC044C554, 0xFEAF0D32,
+ 0x3E002455, 0x702CC098, 0x0D26DA80, 0xC557FEAF,
+ 0x14002644, 0xC54D720E, 0xC54FC54E, 0xC549C550,
+ 0xC54BC54A, 0xC556C54C, 0xC007C046, 0x807E2053,
+ 0x4DC8F212, 0x7825C808, 0x79B6C191, 0x06200BAE,
+ 0x1600714C, 0x8000708B, 0x16001223, 0x80007082,
+ 0xF02D1222, 0x708B1600, 0x12238000, 0x70821600,
+ 0x12228000, 0x10A40B47, 0x1F012554, 0x7825C808,
+ 0x68324448, 0x13832C40, 0x7200244A, 0x70CD7B25,
+ 0x048020A8, 0x24556D16, 0x671F3E0F, 0x671F6C14,
+ 0x12802E40, 0x7FD47865, 0x71C5B892, 0xB89FB89C,
+ 0xB7009000, 0x71857471, 0x0B47F7A6, 0x6D3610A4,
+ 0x611B6A14, 0x1F412554, 0x7825C808, 0x2A4068D2,
+ 0xC098038F, 0x244A7FC5, 0x60797200, 0x20A8700C,
+ 0x27050340, 0x2080100C, 0xBC920010, 0xBC9FBC9C,
+ 0x19029480, 0xE3100314, 0x71447271, 0xC006F7A9,
+ 0x4DDAE889, 0x7825C808, 0x79B6C189, 0x06200AEE,
+ 0xC004714C, 0x013E0815, 0xC8084DD8, 0xC18D7825,
+ 0x0ADA79B6, 0x714C0620, 0x227E208D, 0xC09871AD,
+ 0x3B1B2440, 0x08002054, 0xC042700F, 0x3E002455,
+ 0x30191408, 0x08002054, 0xC045C043, 0x30161408,
+ 0x140CC696, 0x24543013, 0x7EB43B92, 0x23522214,
+ 0x3B172440, 0x77B171ED, 0x1600F2F6, 0x80007085,
+ 0x16001223, 0x8000708C, 0xC0061222, 0x700DE8B8,
+ 0x03240D67, 0x2454702D, 0x25023B0B, 0x23140300,
+ 0x231413CB, 0x27143307, 0x20402304, 0x702D0046,
+ 0x1702700D, 0x762C0500, 0x01200C56, 0x4408DA40,
+ 0x1402B600, 0x762C0500, 0x01200C46, 0x1B00DA40,
+ 0x222F1004, 0x9E200206, 0x1B00B680, 0x780E1004,
+ 0x22087902, 0x9E200048, 0x212F4910, 0x268D0246,
+ 0x210808FF, 0x202F0009, 0xF0910206, 0xC0056C34,
+ 0x00482000, 0x2014C096, 0xC09703D0, 0x03DE2014,
+ 0x20442600, 0x30472100, 0x20462300, 0x702D706D,
+ 0x03240DF9, 0x11802B40, 0x2053C007, 0xF218807E,
+ 0x2016C091, 0x78F60341, 0x030121F4, 0x030020F4,
+ 0xB826B926, 0x20441A00, 0x30041E00, 0x21411200,
+ 0x212F4910, 0x210802C6, 0xF019000B, 0x7200244A,
+ 0x420143C0, 0x04C020A8, 0x05001202, 0x1A00B826,
+ 0x13022004, 0xB8260500, 0x30041E00, 0x21411200,
+ 0x212F4910, 0x210802C6, 0x214A000B, 0x250A2200,
+ 0x240A2100, 0x140221C0, 0x762C2500, 0x01200B72,
+ 0xB600DA40, 0x1502762C, 0x0B662500, 0xDA400120,
+ 0x20041800, 0x9E00790E, 0x212F7822, 0x218D0246,
+ 0x21082B7F, 0xC0040009, 0x013E083D, 0x3D112440,
+ 0x2116762C, 0xDA402340, 0x01200B36, 0x030020F4,
+ 0x2116B600, 0x762C23C0, 0x0B26DA40, 0x20F40120,
+ 0x18000300, 0x790E2004, 0x78229E00, 0x0246212F,
+ 0x00092108, 0x04042440, 0x04072740, 0x04062640,
+ 0x14082040, 0xF1867185, 0x0B66780E, 0x44000000,
+ 0x00200B5E, 0x0246202F, 0x202F4110, 0xC1880607,
+ 0x611942A1, 0x190043E1, 0xC1950442, 0x41C36038,
+ 0x0003038E, 0x01021800, 0x09E6740C, 0x40300120,
+ 0x2401204F, 0x42A1740C, 0x09D643E1, 0x240A0120,
+ 0x71070440, 0x203F2680, 0x203F2380, 0x22172742,
+ 0x77E570F5, 0xC005F501, 0x303F2180, 0x003F2080,
+ 0x321B2342, 0x77A570B5, 0xFFE205D4, 0xC135C045,
+ 0x70801600, 0x12208000, 0xD841E803, 0xD826F002,
+ 0x1408B89F, 0x700E3015, 0x1801712E, 0x14550052,
+ 0xA8203081, 0xA829C128, 0x30811421, 0xC006A82A,
+ 0x00172079, 0x34001C04, 0x34001C00, 0x30141408,
+ 0x3B182454, 0x3B962454, 0x34532014, 0x24562614,
+ 0x273971ED, 0x704E1440, 0x05C02006, 0xB8E070CD,
+ 0x1600F4CB, 0x8000708C, 0x16001222, 0x80007092,
+ 0x20141223, 0xC00333CE, 0x700D70AD, 0x25006C34,
+ 0x24002044, 0x20002049, 0x74520046, 0x002D015A,
+ 0xC00778AE, 0x807E2053, 0xC091F23F, 0x2016762C,
+ 0xDA400440, 0x012009DA, 0x030020F4, 0x43CB4700,
+ 0xFFFF0000, 0x3000264A, 0x0200254A, 0x20041E00,
+ 0xC1986F16, 0x6C146119, 0x762C6038, 0x078020F4,
+ 0x012009AE, 0x212FDA40, 0x264002C8, 0x258D305E,
+ 0x21090CBF, 0xB600000B, 0x081DC004, 0xC08D013E,
+ 0x78F6762C, 0x098ADA40, 0x20F40120, 0x23090300,
+ 0xB600100B, 0x02C6212F, 0x01C6202F, 0x79AE7822,
+ 0x000D2108, 0x274AF020, 0x260A0200, 0x250A3240,
+ 0x15020180, 0x762C0500, 0x01200956, 0x4308DA40,
+ 0x35001602, 0x094A762C, 0xDA400120, 0x02C6222F,
+ 0x4A31790E, 0x278D7AAE, 0x22080BFF, 0xB600004D,
+ 0x22C41E00, 0x14600F83, 0x1200234A, 0x0240250A,
+ 0x0100270A, 0x05001702, 0x0916762C, 0xDA400120,
+ 0x20041B00, 0x1502762C, 0x09060500, 0xDA400120,
+ 0x790EB600, 0x21401300, 0x212F7822, 0x238D0206,
+ 0x21081B3F, 0xC0040008, 0x013E083F, 0x3D0B2440,
+ 0x2316762C, 0xDA401440, 0x012008D6, 0x030020F4,
+ 0x13CB2316, 0x20041B00, 0xDA40762C, 0x012008C2,
+ 0x130023F4, 0x790EB600, 0x21401300, 0x212F7822,
+ 0x21080206, 0x24400008, 0x21400404, 0x26401409,
+ 0x71850406, 0x090AF153, 0x42100000, 0x00200902,
+ 0x0206202F, 0x202F4608, 0xC1800407, 0x45CB6119,
+ 0x00030392, 0xC181A9C0, 0x41A16038, 0x04821800,
+ 0x4222740C, 0x0F8A43E1, 0x240A00E0, 0x254F0480,
+ 0x740C1401, 0x43E14222, 0x00E00F76, 0x248044C1,
+ 0x7106203F, 0x77E570F5, 0xC003F50D, 0x203F2580,
+ 0x003F2080, 0x77267036, 0xFFE205F4, 0xC221C043,
+ 0x70801600, 0x12208000, 0xD943E803, 0xD928F002,
+ 0x1405B99F, 0x19013080, 0x19010092, 0x14060012,
+ 0x19013080, 0x19010012, 0xC0200492, 0x00121901,
+ 0x30801401, 0x1402A900, 0xA9013080, 0x2480A9C2,
+ 0x14043805, 0xC6DA341B, 0x40D3C2EA, 0x0C0C902C,
+ 0x21111000, 0x2D0D2040, 0x214F71ED, 0xB5E02100,
+ 0x180070CD, 0x40C32004, 0xA48007BF, 0x10151D04,
+ 0x1DF0702C, 0x1DF093C4, 0x0AFA9384, 0xB5E004A0,
+ 0xE8069502, 0x04A00A62, 0xF1FCD80A, 0xB5DEB5C0,
+ 0xB5DEB5FE, 0x24441800, 0x78E0C6CA, 0x70811600,
+ 0x00088000, 0x00720813, 0x7810B907, 0x77046038,
+ 0x00412804, 0x7813F006, 0x28057810, 0x79130040,
+ 0x782E7FE0, 0x0B32C2E6, 0x45080820, 0x16007014,
+ 0x80007080, 0x74CD0160, 0x11E226CA, 0x0EF2E805,
+ 0x712CFFAF, 0x1600F009, 0x80007080, 0xB8E20001,
+ 0x20CA700C, 0x7F1003E1, 0x40E141C1, 0x716C42A1,
+ 0x70AC708C, 0x00600A9E, 0x700C71CC, 0x42A1702C,
+ 0x0DCE716C, 0x708C08E0, 0x41C140E1, 0x706C42A1,
+ 0x70AC708C, 0x00600A7E, 0x710C71CC, 0x42A1702C,
+ 0x0DAE716C, 0x708C08E0, 0x78E0C6C6, 0x40D3C2F4,
+ 0x12228000, 0x20911000, 0x46304550, 0x0A942040,
+ 0x23122940, 0x20801001, 0x046408AF, 0x25132205,
+ 0x2005C808, 0x47CB04C0, 0x00009004, 0x41C3B802,
+ 0x000303EC, 0x422278E5, 0x740C90C0, 0x265343C1,
+ 0x0DCE1144, 0x23AD00E0, 0x0D230982, 0x740C2030,
+ 0x03ED41C3, 0x0DBA0000, 0x160000C0, 0x80007080,
+ 0xB8060008, 0x100D2E09, 0x0E0DF00B, 0x26402030,
+ 0xF007180D, 0x18340E0B, 0x264270AD, 0x2553180D,
+ 0x25AD114E, 0x0D111982, 0x740C2030, 0x03EE41C3,
+ 0xF00B0002, 0x20100E0D, 0x03EF41C3, 0xF0050002,
+ 0x03F041C3, 0x42A10002, 0x00E00D66, 0x6D1643C1,
+ 0x20082296, 0xC8087E05, 0x04C02005, 0xB8027126,
+ 0xB7C07F05, 0x0A8EF1A8, 0xC6D405C0, 0x800140C3,
+ 0x88204E81, 0x70801600, 0x00728000, 0x20447824,
+ 0x7FE00800, 0x00002078, 0x70801600, 0x008A8000,
+ 0x7FE0B8C1, 0x00402078, 0x800141C3, 0x89204E89,
+ 0x70801600, 0x00928000, 0x20447825, 0x7FE00800,
+ 0x78E0B825, 0x800141C3, 0x89204E77, 0x70801600,
+ 0x00628000, 0x20847825, 0x7FE00001, 0x78E0B826,
+ 0x70801600, 0x008E8000, 0x7FE0B8C1, 0x00002078,
+ 0x70801600, 0x00968000, 0x04002044, 0xB8247FE0,
+ 0xB7C81CF4, 0x087F4200, 0x1C040065, 0x78523001,
+ 0x6038700D, 0xB8224340, 0x71044140, 0x7000240A,
+ 0x20A84308, 0x810005C0, 0xC0427104, 0xC001C402,
+ 0xC0416098, 0x236FA160, 0x8100003F, 0x00210B0D,
+ 0xC002718D, 0xA1004409, 0x74247464, 0x240A4089,
+ 0x20A872C0, 0x82000340, 0xC102C042, 0x7822C001,
+ 0xC002C041, 0x1A047704, 0xEC0D0010, 0x031041C3,
+ 0x0C4E0001, 0xD80A00E0, 0x41C3700C, 0x00000311,
+ 0xC001F00E, 0xC201E810, 0x031241C3, 0x0C320001,
+ 0xD80A00E0, 0x41C3700C, 0x00000313, 0xFE8F092A,
+ 0xF008710C, 0xD80AD9C5, 0x00E00C16, 0x700CB912,
+ 0x341F140C, 0x78E07EE0, 0xB7C81CF4, 0x087F4200,
+ 0x1C040065, 0x78523001, 0x6038700D, 0xB8224340,
+ 0x71044140, 0x7000240A, 0x20A84308, 0x810005C0,
+ 0xC0427104, 0xC001C402, 0xC0416098, 0x236FA160,
+ 0x8100003F, 0x00210B0D, 0xC002718D, 0xA1004409,
+ 0x74247464, 0x240A4089, 0x20A872C0, 0x82000340,
+ 0xC102C042, 0x7822C001, 0xC002C041, 0x1A047704,
+ 0xEC0D0010, 0x031541C3, 0x0B960001, 0xD80A00E0,
+ 0x41C3700C, 0x00000316, 0xC001F00D, 0xC201E80F,
+ 0x031741C3, 0x0B7A0001, 0xD80A00E0, 0x700CD963,
+ 0x0876B913, 0x710CFE8F, 0x41C3F008, 0x00000319,
+ 0x00E00B5E, 0x700CD80A, 0x341F140C, 0x78E07EE0,
+ 0xE18F714C, 0x0FC7238A, 0x22CA7A38, 0xB80E00C1,
+ 0x0F812005, 0x02EC9004, 0x0240224F, 0x00051900,
+ 0xB100B140, 0x7FE0B140, 0x00051900, 0x7FE0720C,
+ 0x00C420AB, 0x2482C3EC, 0x41303204, 0x740C4210,
+ 0x021241C3, 0x45880000, 0x0B064668, 0x474800E0,
+ 0x3605120C, 0x120B740C, 0x41C33604, 0x00040213,
+ 0x3603120D, 0x00E00AEA, 0x3082120D, 0x71001600,
+ 0x000A8000, 0x007E0815, 0x41C3D8C8, 0x00020214,
+ 0x0ACE42C1, 0x43A100E0, 0x24407752, 0x27CC3010,
+ 0xF2039442, 0x0FE640F1, 0x701407C0, 0x7EC0706D,
+ 0x1FC7208A, 0x9FC0234C, 0x002D006C, 0xE0BF78D0,
+ 0x002D0052, 0x22C12215, 0xEC259181, 0x211578CE,
+ 0x90612000, 0x9000EB1F, 0x994078A2, 0x2048780E,
+ 0x79100000, 0x20157230, 0x20CA22C1, 0x4BB2008A,
+ 0x7B8E7A4E, 0x0FC72289, 0x2209B100, 0x781000C2,
+ 0x7A50B141, 0x00A4081B, 0x1902D8FF, 0xB1000005,
+ 0x2015F007, 0x180222C0, 0x18000005, 0x71650204,
+ 0xF1CA71C5, 0xA3C0200C, 0x7001248A, 0x02A220E8,
+ 0x25001002, 0x10141F02, 0x25001002, 0x10141F02,
+ 0xC7CC700C, 0x1CFCC2FA, 0xC1A8B6C8, 0x31401C04,
+ 0x41C34520, 0x28F00000, 0x42504078, 0x0042201F,
+ 0xC0177B3B, 0x009B2D41, 0x1C1C786C, 0x44C33100,
+ 0x1A3C8000, 0x00962440, 0x31C01C00, 0x31801C14,
+ 0x00972000, 0x30191460, 0x25802700, 0xC000C042,
+ 0xD8406849, 0x00952801, 0x800040C3, 0x10B71222,
+ 0x43500081, 0x00861000, 0x8821C143, 0x222FC144,
+ 0xC0040187, 0x01DC7210, 0xC003000D, 0x80802011,
+ 0x221FF2E6, 0x00000F90, 0x225F0A3C, 0xC0020281,
+ 0x029E265E, 0x2700700D, 0x20002414, 0xC0012010,
+ 0x21112400, 0xC0467834, 0x9240204C, 0x002D01A0,
+ 0x3787272F, 0x702D700C, 0x702C706C, 0x436870CD,
+ 0xF005262F, 0x800043C3, 0x0044C444, 0x44EB0024,
+ 0x100E249F, 0x092B641C, 0x646B1030, 0x68A9EB95,
+ 0x12C7242F, 0x4B977BAF, 0x7BCF7C2F, 0x7B7B7B82,
+ 0x03E50B17, 0x706C702D, 0x46A94161, 0xEB05F006,
+ 0x4300712D, 0x4361F002, 0xF1DB7104, 0x1030091F,
+ 0x7ECF782F, 0x12C7242F, 0x7E02DD7F, 0x7EDB7D82,
+ 0x20CA75D1, 0x21CA030D, 0x70A202CD, 0x8002208C,
+ 0x41A2F784, 0x0FC12187, 0x7D2F4709, 0x1184279A,
+ 0x7D0AC000, 0x308021F4, 0x7782702D, 0x03CC2400,
+ 0x1C8060B8, 0xC005101C, 0x248AE824, 0x27007001,
+ 0x80001F8B, 0x20A81B40, 0x40E30740, 0x14CC2901,
+ 0x000E209F, 0x7C8F643C, 0x609845A8, 0xB8816068,
+ 0x700C7314, 0x40A0F203, 0x271570AD, 0x7125124C,
+ 0x110E2400, 0xB60074C2, 0x1B00B4A0, 0xF05016C4,
+ 0x7001248A, 0x0400270A, 0x1440230A, 0x020120A8,
+ 0x290145EB, 0x259F14C0, 0x6038100E, 0x708D7F0F,
+ 0x606E65F8, 0xEE2540A0, 0x1180275F, 0x40C3651D,
+ 0xC1448000, 0x10B00E11, 0x0E1760BC, 0x444A1071,
+ 0xF0176510, 0x94816510, 0x160C2402, 0x60BEF011,
+ 0x96816515, 0x160C2402, 0x7F104CB0, 0x22029602,
+ 0x7ED0200E, 0x20CA76F1, 0x24CA034E, 0x7D90148D,
+ 0x10040D23, 0xED07C507, 0x25F4C506, 0x60B8120D,
+ 0x7E1064BC, 0x7DC27D90, 0x0D0B71A5, 0x708D1155,
+ 0x1B0440A0, 0x71251014, 0x03141F04, 0x21842180,
+ 0x21842080, 0x26407105, 0xF130305E, 0xF11171C4,
+ 0x1404C0A8, 0xC6DA341B, 0x4130C2EA, 0xFFEF0AE6,
+ 0x0D154508, 0x401011F5, 0x203278AD, 0x80000F89,
+ 0xF00A0D80, 0x41C3700C, 0x00010087, 0xFE6F0CAA,
+ 0x702D42A1, 0x900446CB, 0x6D0A02D4, 0x01750821,
+ 0x294096E0, 0x27041289, 0x00001F80, 0x2005C3FF,
+ 0x1E000240, 0x90077004, 0xC6CAFED4, 0x800040C3,
+ 0x10B71222, 0x21540086, 0x88612F08, 0x240B2140,
+ 0x45CB8880, 0x00009004, 0x36071208, 0x83040BDF,
+ 0x032E0E59, 0x13042C40, 0x7240244A, 0x20A870AC,
+ 0x25050980, 0x20050100, 0x220501C2, 0xB90202C1,
+ 0x912079A5, 0x20300817, 0x2205B927, 0xBA020202,
+ 0x92407AA5, 0x0182226D, 0xB9E06159, 0x21C74121,
+ 0xB90A03E2, 0x1F8F2704, 0xC3FFFFFF, 0x2556B802,
+ 0x7F250805, 0xB0E078C5, 0xF1D27185, 0x226FC2E2,
+ 0x44CB0443, 0x04988000, 0x8A6084A7, 0x7D6C8406,
+ 0x0001231C, 0x810212FE, 0x231A61B9, 0x219A000D,
+ 0x40A1041F, 0x141F259A, 0x041F209C, 0x61197BBD,
+ 0x20798C10, 0x2447004C, 0x799817C0, 0x00002B01,
+ 0x7905706C, 0xFE6F0892, 0x13002D00, 0x78E0C6C2,
+ 0xC1A1C3E6, 0x000F2315, 0x260A4008, 0x97013080,
+ 0x703070AD, 0x002E0120, 0x97204328, 0x21CC7171,
+ 0x01148005, 0x2B400026, 0x258A1407, 0x27050FC3,
+ 0x772D0207, 0x334E2616, 0x9E609E01, 0x00E2082B,
+ 0x0240260A, 0x7A7079AF, 0x40E07B10, 0x00E00C6A,
+ 0x30C42440, 0x210C4600, 0x14039000, 0x26CA3080,
+ 0x25090245, 0x9E030005, 0x082D9E62, 0x210A00E2,
+ 0x79AF1180, 0x7B107A70, 0x0C3E40E0, 0x244000E0,
+ 0x410830C4, 0x8000260C, 0x30801403, 0x118521CA,
+ 0x00052509, 0xE5C071A5, 0xFFC5079C, 0x45CB9720,
+ 0xFFFF0000, 0x02C5091B, 0x0B179701, 0x20021025,
+ 0x7A1002C0, 0x10402302, 0x20097810, 0xD840008D,
+ 0x3703121D, 0x02002002, 0x201A780C, 0x204000C1,
+ 0x780A1040, 0x2509786C, 0x210C0203, 0x20CA9000,
+ 0x70300245, 0x000521CA, 0x0008208A, 0x02C22002,
+ 0x7A4CCC1C, 0x71507A0C, 0x004522CA, 0x1FC1204E,
+ 0x2309792F, 0x16000043, 0x80007081, 0xB9E0000E,
+ 0xF409705C, 0x10412340, 0x782C792C, 0x20CA7210,
+ 0x41C30085, 0xFFFF00FF, 0x657D7030, 0x000521CA,
+ 0x7D25B908, 0xC7C640A1, 0x1200C0E6, 0x70AD3087,
+ 0x47CB706C, 0x113A8000, 0x0B69710D, 0x2B4001E5,
+ 0x235A0386, 0x702D0A0E, 0x704C706D, 0xB0A167D8,
+ 0x0A47B0A0, 0x26050255, 0x21050241, 0x90040F81,
+ 0x91200200, 0x0A157C2F, 0x28000321, 0x9020130C,
+ 0x0081210F, 0xF00DB020, 0x71249021, 0xB902B021,
+ 0x0F0F2184, 0x61F961D9, 0x02C41902, 0x7425B180,
+ 0x71447165, 0x9020F1DF, 0xB9897164, 0xF1CFB020,
+ 0x78E0C4C6, 0xC1A1C3E6, 0x16004608, 0x80007100,
+ 0x4528000A, 0x0980206D, 0x0817E808, 0x080D0050,
+ 0x1A0000D1, 0xF00700C3, 0x00831A00, 0x1A00F003,
+ 0x24400043, 0x244030C0, 0x0E123081, 0x42C101E0,
+ 0xC7C6E802, 0x30821402, 0x308C1403, 0x7B3D6459,
+ 0x10C12615, 0x91E0AD60, 0x61F99121, 0xB521793D,
+ 0x7C3D6399, 0x13012615, 0x91E0AD84, 0x61F99121,
+ 0xB523793D, 0x793D6359, 0xAD287E35, 0x96219640,
+ 0x793D6159, 0xC7C6B525, 0xC1A2C3E4, 0x45084628,
+ 0x30011C04, 0xFEAF0E3A, 0x30011C00, 0xD907D841,
+ 0xDA08B813, 0x708C706C, 0x0FA270AC, 0x70CCFEEF,
+ 0x742C700C, 0xFF2F0A8A, 0xC080714C, 0x09E241A1,
+ 0x734CFF2F, 0x700C4508, 0x0A76742C, 0x714CFF2F,
+ 0xD907706C, 0x744C4060, 0x708CB892, 0x0F6E70AC,
+ 0x70CCFEEF, 0xD907D880, 0xDA08B893, 0x708C706C,
+ 0x0F5A70AC, 0x70CCFEEF, 0xFE8F0DBE, 0xB600B802,
+ 0xC7C440A1, 0x2044781B, 0xD8E40181, 0x7FE07839,
+ 0x78E0B8C1, 0x01422053, 0x206DA941, 0x20AD0182,
+ 0x605801C1, 0xA9007FE0, 0x43E3C1A1, 0xFFEF0FEA,
+ 0xC020C180, 0x30811401, 0x6038B806, 0x74877B20,
+ 0x1CFCC2FA, 0x2482B6C8, 0x1CC83B06, 0x40383080,
+ 0x30001CC0, 0x1CC4700C, 0x1C403000, 0x1CFC3018,
+ 0x1CF83000, 0x1CF43000, 0x14C83000, 0x1CA03000,
+ 0x20843000, 0x1CA00004, 0x14A03000, 0x1C8C3010,
+ 0x148C30C0, 0x1CE43001, 0x28413180, 0x1CE02200,
+ 0x1CAC3140, 0x09AA3100, 0x401000E0, 0x70911600,
+ 0x000D8000, 0x30001CEC, 0x02A00FBA, 0x46084003,
+ 0x702CC808, 0x2005B802, 0x90380F80, 0x90E00008,
+ 0x3F802400, 0x01040000, 0xFE2F0B46, 0x148CDA50,
+ 0xB8A03000, 0x30001C98, 0x22002144, 0x000D2078,
+ 0x30001498, 0x00910811, 0xFF8F0E3A, 0x30001CC4,
+ 0xF004710C, 0x00C00986, 0x30001CBC, 0x40037DC4,
+ 0x02A00F62, 0x33401CD4, 0x30011498, 0x00B1092D,
+ 0x24012144, 0x71001600, 0x00148000, 0x04110819,
+ 0x07800F86, 0x0832E888, 0x701407C0, 0x1CA4710C,
+ 0xF40B3000, 0xF007700C, 0x00002052, 0x00012178,
+ 0x1CA47824, 0x148C3000, 0xBFC13000, 0x00002078,
+ 0x07A00F56, 0x30001C9C, 0x300214C0, 0x024541C3,
+ 0x148C0005, 0x240A3003, 0x1CD80600, 0x740C3000,
+ 0x300614AC, 0x00A00A7A, 0x0400250A, 0x300014D4,
+ 0x00102079, 0x30402042, 0x081B7D0F, 0x1CB001F5,
+ 0x14B03000, 0xB8C63000, 0x0050080B, 0x300014A0,
+ 0x1600E88A, 0x80007080, 0xB8E00107, 0x1C94700C,
+ 0xF2073000, 0x05800B96, 0x1C94710C, 0x27793000,
+ 0xDA7D1000, 0x30001CB4, 0x148C708E, 0x41DB3000,
+ 0xC1448000, 0x0080207C, 0x30001CB8, 0x20402040,
+ 0x30001CCC, 0x3000149C, 0x0F80201F, 0x51E00000,
+ 0x30001CF0, 0x800070C3, 0x1CD01B3C, 0x14B03000,
+ 0xB8C63000, 0x00012A01, 0x11C0257C, 0x1CE87824,
+ 0x2A013000, 0xB8C00340, 0x800045CB, 0x1CDC1221,
+ 0x14983000, 0x20783000, 0x1CA80080, 0x72963000,
+ 0x00260702, 0xB89FD825, 0x881B8820, 0x710C7905,
+ 0x05002800, 0x200FB802, 0x7E2B050E, 0x002106D4,
+ 0x0D0A730C, 0x1D000120, 0x148C1502, 0x24553001,
+ 0x14E03F42, 0x24553004, 0x14A43FC3, 0x202F3005,
+ 0x43180507, 0x01600CB2, 0x300614D4, 0x300014A0,
+ 0x00002079, 0x100115BB, 0x30001C90, 0x14904063,
+ 0x0A623002, 0x14900320, 0x14D83003, 0x7FCF3000,
+ 0x3003148C, 0x3F452455, 0x30061490, 0x14CCC182,
+ 0x42033007, 0x093E44E1, 0x43F10060, 0x300014AC,
+ 0x14A870AE, 0xC3823001, 0x35441C0A, 0x300214E8,
+ 0x02200C8E, 0x30431C0C, 0x300014A4, 0xC808E839,
+ 0x15B8700D, 0x15021086, 0x8DE11089, 0x78EF68D2,
+ 0x1004095F, 0x002E0E57, 0x038C2840, 0x7240244A,
+ 0x70EC7CC5, 0x20A8706C, 0x205F0600, 0x24000501,
+ 0x00003F82, 0x623A015C, 0x02812F40, 0x22147985,
+ 0x210501CB, 0x90040F81, 0x91200320, 0x633B71E4,
+ 0x10441B00, 0x3F812400, 0x01540000, 0x78707914,
+ 0x02402845, 0x02041A12, 0x71E5B100, 0x14B0F1D1,
+ 0x08173000, 0x14A801D5, 0x14DC3001, 0x20053000,
+ 0xF207807E, 0x1498F00D, 0x08173000, 0x16000090,
+ 0x80007080, 0x2044000B, 0x2D410815, 0x0C9B2155,
+ 0x0D972011, 0x70ED2030, 0x310B1412, 0x3108140E,
+ 0x12C02002, 0x31071410, 0x00072700, 0x15B8C808,
+ 0x15021085, 0x8DC11084, 0x00862840, 0x0C6B7BCF,
+ 0x0D6300C4, 0x2B4000EE, 0x704C0389, 0x11892105,
+ 0x0501235F, 0x3F802400, 0x015C0000, 0x02750A45,
+ 0x20146038, 0x2A400081, 0x20050280, 0x20050240,
+ 0x90040F80, 0x90000320, 0x02CC2000, 0x1325080D,
+ 0x1900B100, 0xF00C01C4, 0x710C1600, 0x013A8000,
+ 0x0325080B, 0xB1E07882, 0xB100F002, 0xF1DA7144,
+ 0x71C5B0E9, 0x14B8F1CC, 0x14B43001, 0x790B3000,
+ 0x8DE1F233, 0x8D027EEF, 0x0384085F, 0x800040C3,
+ 0x880012D9, 0x03AE084F, 0x094A41C1, 0x14C80660,
+ 0x43083000, 0x13002E40, 0x244AC107, 0x79057280,
+ 0x7825C808, 0x6872702C, 0x054020A8, 0x104E0B25,
+ 0x150C265F, 0x3F822400, 0x01040000, 0x2940645C,
+ 0x7A650282, 0xBA927C34, 0xBA9FBA9C, 0xB4409240,
+ 0x71E57124, 0xDA23F1D0, 0xBA0A4023, 0xFDEF0F82,
+ 0x14D8702C, 0xE8093000, 0x40C3702C, 0xBE248000,
+ 0xFDEF0F6E, 0x1412DAA0, 0x14103112, 0x0A4D310E,
+ 0x210A23A5, 0x140D2500, 0x70143080, 0x000102E4,
+ 0x108B15B8, 0x8D218D42, 0x31031410, 0x7050782F,
+ 0x000D03C2, 0x102E0B21, 0x7240244A, 0x0F80201F,
+ 0x0A3C0000, 0x020020A8, 0x300C14D0, 0x2080641C,
+ 0xB4600184, 0xF1EC7124, 0x31171414, 0x20162479,
+ 0x2E812185, 0x2A162640, 0x900740D3, 0x14ACC29C,
+ 0x08A13000, 0x14980010, 0x08133000, 0x79CF00B1,
+ 0x0F324063, 0x734CFE6F, 0xC808F044, 0x108815B8,
+ 0x108B1502, 0x8D016852, 0x0B55790F, 0x084D1044,
+ 0x2940106E, 0x0D3B038C, 0x7C452030, 0x0501215F,
+ 0x3F832400, 0x015C0000, 0x7240244A, 0x633B702D,
+ 0x038020A8, 0x12812940, 0x024F23F4, 0x67DF7985,
+ 0x21057125, 0x90040F81, 0xB1E00320, 0x2405F006,
+ 0x90041F81, 0xB1C03F20, 0xF1D87104, 0x000440C3,
+ 0x0A8293E0, 0x702C0420, 0x300114B8, 0x300014B4,
+ 0xF208790B, 0x70801600, 0x001D8000, 0xF4D0B8E0,
+ 0x1C0AC808, 0xB8023384, 0x0F802005, 0xC0049007,
+ 0x00051800, 0x7014C022, 0xF217C082, 0x3101140E,
+ 0x3F432455, 0x30051490, 0x3FC42455, 0x300614A8,
+ 0xC1404263, 0x3001148C, 0x4003C041, 0x02200ED2,
+ 0x3007149C, 0x148CF012, 0x24553001, 0x14C03F45,
+ 0x704C3003, 0x300414BC, 0x30061490, 0x30071494,
+ 0x09C6C040, 0x40030060, 0x300014C4, 0xF2917014,
+ 0x30001494, 0x0F247014, 0x1C1C0561, 0x710C3580,
+ 0x012009D6, 0x40034162, 0x0FC24162, 0x704C0020,
+ 0x08C1C022, 0xC0820030, 0x24051800, 0xE81CCA00,
+ 0x2940702C, 0x228A0380, 0x20050004, 0x90040F80,
+ 0xB04002F8, 0x7200244A, 0x0010228A, 0x020020A8,
+ 0x00832005, 0x00102280, 0x00051B00, 0xCA007124,
+ 0x800409D3, 0x3101140E, 0x1490C082, 0x24553005,
+ 0x14A83F43, 0x24553006, 0x149C3FC4, 0x42633007,
+ 0x4003C041, 0x0E1AC140, 0x732C0220, 0x43C3702C,
+ 0x4FA08001, 0x0945CA00, 0x29400025, 0x700D038B,
+ 0x0833700C, 0x71ED0255, 0x30021494, 0x70547F18,
+ 0x900442C3, 0xF20702F8, 0xBC0A630C, 0x12CC2405,
+ 0x2305F003, 0x7A85120C, 0x10102080, 0x7104B2E0,
+ 0xE309F1E9, 0xF1E07124, 0x1800D820, 0xF0102004,
+ 0x300314C0, 0x300414BC, 0x3F452455, 0x4003C040,
+ 0x704C732C, 0x08C270CC, 0x71EC0060, 0x30001494,
+ 0x0AB87014, 0x14EC05C1, 0x40033002, 0x00200ECE,
+ 0x700C4162, 0x012008D2, 0x1C1C4162, 0x76E23440,
+ 0x705278D0, 0xFFCE05CA, 0xFFCF056F, 0x108B15B8,
+ 0x8D827FD0, 0x796F8D61, 0x06587191, 0x0B41FFCD,
+ 0x2400104E, 0x00003F80, 0x20F40154, 0x16000042,
+ 0x80007080, 0x6058011B, 0xD81170F1, 0x1600F7CA,
+ 0x80007080, 0x4A10011C, 0xD89170F1, 0x006B20CA,
+ 0x2105B90E, 0x90040F81, 0xB1003ED4, 0xF1DD7164,
+ 0x08C1C022, 0x140E0030, 0x8DE13113, 0x8D0279EF,
+ 0x006408E3, 0x40C34030, 0x12D98000, 0x08A18800,
+ 0x70CD042E, 0x1291275E, 0x0447202F, 0x01A00DE2,
+ 0x205F4210, 0x14CC2502, 0xC182300C, 0x248A7C09,
+ 0x623A7001, 0x923A7AD4, 0x41C3643C, 0x28F00000,
+ 0x2043241A, 0x201FB922, 0x14F02041, 0x627A3002,
+ 0x41C1623A, 0x0184219A, 0x2300623B, 0x80000F81,
+ 0x43681B3C, 0x708DB180, 0x078020A8, 0x300114D4,
+ 0x43627A8F, 0x62197A39, 0x218C704C, 0xF74C8002,
+ 0x215A4242, 0x229F0181, 0x623A000E, 0x06432234,
+ 0x92417223, 0x13012315, 0x71C37185, 0x1A3C8000,
+ 0xB141B160, 0x0E7571C5, 0x712692B4, 0xF1A871E5,
+ 0x3FC02455, 0x916A4183, 0x41629149, 0x240AC041,
+ 0x149C0540, 0x24003000, 0x00003F85, 0x14CC015C,
+ 0xC0403007, 0x300014AC, 0x00062078, 0xFFAF094A,
+ 0x149C4063, 0x40633001, 0x30021490, 0x300314C4,
+ 0x01A00A06, 0x300414E4, 0x300114B8, 0x300014B4,
+ 0xF234790B, 0x7EEF8DE1, 0x08618D02, 0x40C30384,
+ 0x12D98000, 0x08518800, 0x41C103AE, 0x06200CB6,
+ 0x300014C8, 0x2E404408, 0xC1071300, 0x7280244A,
+ 0xC8087905, 0x700C7905, 0x20A86952, 0x0C270580,
+ 0x265F100E, 0x24001503, 0x00003F81, 0x61790104,
+ 0x000321F4, 0x02812840, 0xB9927945, 0xB99FB99C,
+ 0x7104B160, 0xF1D171E5, 0x0A9EC082, 0x702C0020,
+ 0x300014D0, 0x20967186, 0x01070794, 0x1CD0FFEF,
+ 0x14943000, 0x70143000, 0x05C208A0, 0x3B062480,
+ 0x341B1404, 0x78E0C6DA, 0x4110C2EA, 0x70801600,
+ 0x00088000, 0x08114548, 0x462800B1, 0x2280204A,
+ 0xF00574ED, 0x2240204A, 0x088272ED, 0x208AFEEF,
+ 0x0EC1080C, 0x208A1275, 0x08B90144, 0x0923038E,
+ 0x706C2030, 0xFECF0872, 0xD907706C, 0x724C4060,
+ 0x708CB88F, 0x0DB670AC, 0x70CCFEAF, 0xD907F00C,
+ 0xDA184060, 0x708CB88F, 0x0DA270AC, 0x70CCFEAF,
+ 0xFECF0846, 0xD907700C, 0x706C704C, 0x45A1708C,
+ 0xFEAF0D8A, 0x704C70CC, 0x4648752C, 0xBE94DB80,
+ 0x40C1708C, 0x0D7645A1, 0x70CCFEAF, 0xD9296E13,
+ 0x706C42E1, 0x45A1708C, 0xFEAF0D62, 0x01C0264A,
+ 0x30821204, 0xD907700C, 0x708C706C, 0x0D4E45A1,
+ 0x70CCFEAF, 0xD907700C, 0x706C704C, 0x45A1708C,
+ 0xFEAF0D3A, 0x78DB70CC, 0x704C752C, 0x0004238A,
+ 0x45A1708C, 0xFEAF0D26, 0xD84170CC, 0xF03CD92A,
+ 0x20300921, 0x0FC2706C, 0x706CFE8F, 0x4060D907,
+ 0xB88F724C, 0x70AC708C, 0xFEAF0D02, 0xF00D70CC,
+ 0x4060D907, 0xB88FDA28, 0x70AC708C, 0xFEAF0CEE,
+ 0x0F9670CC, 0x700CFE8F, 0xDA08D907, 0x708C706C,
+ 0x0CDA45A1, 0x70CCFEAF, 0xD907700C, 0x706C704C,
+ 0x45A1708C, 0xFEAF0CC6, 0x704C70CC, 0x4040752C,
+ 0x0004238A, 0x708CB895, 0x0CB245A1, 0x70CCFEAF,
+ 0xD92BD841, 0x42E1B812, 0x708C706C, 0x0C9E45A1,
+ 0x264AFEAF, 0x700C01C0, 0x744CD907, 0x708C706C,
+ 0x0C8A45A1, 0x260AFEAF, 0x0F160400, 0x700CFE8F,
+ 0x704CD907, 0x708C706C, 0x0C7270AC, 0x70CCFEAF,
+ 0xD907700C, 0x706C704C, 0x70AC708C, 0xFEAF0C5E,
+ 0x0AC670CC, 0x7704FE4F, 0x78E0C6CA, 0x88A0C0E6,
+ 0x900743C3, 0xED07C2CC, 0x00051B00, 0x00051B04,
+ 0x248AF005, 0xB3801FC7, 0x1600B382, 0x80007083,
+ 0x23780008, 0x6B920103, 0x900743C3, 0xED16C2C0,
+ 0x1B04B380, 0x09130085, 0xDB1000F5, 0x26F47B2D,
+ 0x800070C3, 0x908810BC, 0x23CF7295, 0x1E000361,
+ 0x900770C4, 0xF007C29C, 0x1C0C2445, 0x1B04B380,
+ 0x43C30045, 0x12228000, 0x008B13B7, 0x8BC08BE1,
+ 0x0F417BCF, 0x0B3910C4, 0x201410EE, 0x091300CC,
+ 0xDD0A0070, 0x1C24E988, 0x75AD1285, 0x1C24F007,
+ 0xF0051145, 0x1C24DD0F, 0x09151005, 0x221400B5,
+ 0x130000C3, 0x0B0900C3, 0xB4B20013, 0xF1E271C5,
+ 0x78E0C4C6, 0x702CC0F1, 0x900742C3, 0x1E00C2C0,
+ 0x90077044, 0xB220FED4, 0x1E00B222, 0x90087044,
+ 0x800801E4, 0x2005B802, 0x90070F80, 0xB020C000,
+ 0x002009E2, 0x80441ADC, 0x01800C2A, 0x7EE0C0D1,
+ 0x46C8C2F2, 0x47084528, 0x416040C1, 0x21C0250A,
+ 0x2140220A, 0x2100200A, 0x0E364170, 0x43500060,
+ 0x40E14410, 0x704C41A1, 0x240A4322, 0x250A0400,
+ 0x46C10480, 0x0020085E, 0x0540270A, 0xEF0870CD,
+ 0x000040C3, 0x0C32FFFF, 0x712C05E0, 0x4102D840,
+ 0x70041E00, 0x01E49008, 0x42828508, 0x2005B802,
+ 0x90070F80, 0x1800C000, 0x1E000045, 0x90077384,
+ 0x099AC29C, 0x40620020, 0x41628D00, 0xFFEF0CDE,
+ 0xA5074202, 0x412240A1, 0xFFEF0E86, 0xC6D24242,
+ 0xC1A1C3F0, 0xD8314608, 0x4528A108, 0x210AC808,
+ 0xA9C02180, 0xAD24702C, 0x2140230A, 0x200AA526,
+ 0xB8022100, 0x20054270, 0x90380F80, 0x90E00008,
+ 0xA522B521, 0x07600C66, 0x11C41D10, 0x20F00A2B,
+ 0x0A31AD05, 0x204B2070, 0x0A35A140, 0x204B20B0,
+ 0x0A33A140, 0x204B2031, 0xF21DA140, 0x14811D18,
+ 0x14011D14, 0x204BF025, 0xF21AA140, 0xF020D828,
+ 0x1D18F218, 0x1D141401, 0xF01B1481, 0xD87AF217,
+ 0x700CF016, 0x022541C3, 0x0BEE0001, 0x4242FDEF,
+ 0x1D18F00F, 0x1D1414C1, 0xF00B1441, 0xF008D829,
+ 0x14411D18, 0x14C11D14, 0xD87BF003, 0x0A91A505,
+ 0x275320B5, 0xF244907E, 0x10310E85, 0x20112179,
+ 0x800047CB, 0x8FC01222, 0x0402202F, 0x22112140,
+ 0x20522279, 0x00542044, 0x08658F01, 0x40C30384,
+ 0x12D98000, 0x08558800, 0x7ACF03AE, 0x41424022,
+ 0x01600EBA, 0x089E4382, 0xC18001A0, 0x23802314,
+ 0x00C11000, 0x09C2C080, 0x21BF0360, 0x0CEE0FFF,
+ 0xE80D0040, 0x30801401, 0xF789E0C0, 0x003F2080,
+ 0x30021C01, 0x7104C020, 0xC080C060, 0x00200EF6,
+ 0x13902514, 0x2004182C, 0xF1D071C5, 0x78E0C7D0,
+ 0x42C3700C, 0x0000901C, 0x900741C3, 0xB200F800,
+ 0x00151984, 0x00041A44, 0x80151980, 0x191CB202,
+ 0x19040015, 0x19040015, 0x19080015, 0xB1000015,
+ 0x7FE0B102, 0x78E0B104, 0x4050C2EA, 0x082D4130,
+ 0x45080275, 0x000046CB, 0x2025FFFF, 0xF0310340,
+ 0xF008F015, 0xF006F016, 0xF01CF018, 0xF026F01E,
+ 0x000046CB, 0xF025A536, 0x41C3700C, 0x00010224,
+ 0xFDEF0AC6, 0x70CD42A1, 0xDEFFF01B, 0xF019BE08,
+ 0x000046CB, 0xF015AAAA, 0x000046CB, 0xF011B2B2,
+ 0x000046CB, 0xF00D8241, 0x800040C3, 0x88C10104,
+ 0xBE088820, 0xF0057E25, 0x000046CB, 0x70165A3C,
+ 0x0A26DFAA, 0x27CA0760, 0xE8061021, 0x708F1600,
+ 0x01068000, 0x08E96D0B, 0x26040155, 0x00001F81,
+ 0xB928FF00, 0x42E178CF, 0x0B8A43E1, 0x240A05E0,
+ 0x16000440, 0x80007080, 0x72140008, 0x901C41C3,
+ 0x40C30000, 0xF8009007, 0x1900F406, 0x18000005,
+ 0xF0060005, 0x00451900, 0x00451800, 0x12300DA7,
+ 0x0D59D8FF, 0x0D551110, 0x0DF111D0, 0xD9441031,
+ 0x901C40C3, 0x45CB0044, 0xF8849007, 0x00851800,
+ 0x90951D80, 0x804418C0, 0x0EC64002, 0x1D0005E0,
+ 0x700C1105, 0x901F41C3, 0x7AD0C00C, 0xB518B516,
+ 0xB51A4340, 0xB1004440, 0xB1024540, 0xB504712C,
+ 0x02200DE6, 0xC6CAB506, 0x900745CB, 0x1D04F830,
+ 0x704C13D4, 0x0FC7208A, 0x0388242F, 0x722CB540,
+ 0x700CB502, 0x250A706C, 0x0DBE0100, 0x47480220,
+ 0x1C012542, 0x901F40C3, 0x1900C00C, 0x1D500085,
+ 0xB0E013C4, 0xB1E4B0E2, 0xC6CAB1E6, 0x90500D1F,
+ 0x45CBF199, 0xF8209007, 0x13D41D04, 0x10151D04,
+ 0x1D08700E, 0x7AD01014, 0x13D41D04, 0x901F47CB,
+ 0x1D00C004, 0x25421404, 0xB5021C11, 0xB700D844,
+ 0x722C700C, 0x44404340, 0x0D5E4540, 0x19000220,
+ 0x1D502105, 0x1F081404, 0x1F0C1404, 0x19081404,
+ 0x190C2404, 0xC6CA2404, 0x70051E00, 0xF8049007,
+ 0x78E0C6CA, 0x1CFCC2FA, 0xC1BFB6C8, 0x47084338,
+ 0xC08B70CE, 0xDA50702C, 0x31C01C00, 0x2140200A,
+ 0x31801C08, 0x31001C04, 0x1C28C348, 0x0C123580,
+ 0x1C24FDAF, 0xC8083580, 0x308D237C, 0x2005B802,
+ 0x90380F80, 0x90000008, 0x2079B8C1, 0x6F0B000E,
+ 0x039C7514, 0x71F50026, 0x00400A66, 0x25044610,
+ 0x0B0F1395, 0x712F3070, 0x21CA70D6, 0x47CB3541,
+ 0x12228000, 0x25802504, 0x300E14B8, 0x71148F60,
+ 0x202F8F41, 0x223C058A, 0x25CA00C1, 0x78252021,
+ 0x003F081B, 0x40614368, 0x7104790F, 0x10412614,
+ 0x00051924, 0x0AF5790F, 0x23788045, 0x737730C0,
+ 0x1618E009, 0xC0431017, 0xC044700C, 0x026120CA,
+ 0x8605C044, 0x9608C045, 0x30300969, 0xC808C047,
+ 0x12C0200A, 0x108717B7, 0x05C02005, 0x10861701,
+ 0x212F6892, 0x0E4D0207, 0x0F450044, 0x2940006E,
+ 0x215F0383, 0x7B850289, 0xC203700C, 0x00850831,
+ 0xEA88C202, 0x06822100, 0x0082121C, 0x0080081D,
+ 0x02422000, 0x7D54C58B, 0x02822840, 0xBA927A65,
+ 0xBA9FBA9C, 0xB5409240, 0xF1E97104, 0xF1DB7105,
+ 0x40CB7377, 0x0F000000, 0x20002552, 0x102120CA,
+ 0x800040DB, 0xC04612D9, 0x02C7222F, 0x08678F01,
+ 0x10000084, 0x085B3080, 0x2A4000AE, 0xC0050303,
+ 0x02012305, 0x900444CB, 0x79050000, 0x7905C808,
+ 0x208D20F4, 0x7985B902, 0xC106B1A0, 0xB040210B,
+ 0x2305F20B, 0x210505C1, 0x78250201, 0x7C05B802,
+ 0x208020F4, 0x0D1BB400, 0x26142030, 0x23051080,
+ 0x903605C3, 0x208020F4, 0xFEEF0B52, 0x7165C201,
+ 0x0C12F1CC, 0x8F610540, 0x0B458F20, 0x7A2F0044,
+ 0x2A407124, 0x2614038B, 0x2305108C, 0x90041F80,
+ 0x900002D4, 0x20849492, 0xBC0A040E, 0x204F7885,
+ 0x2305000C, 0x90041F80, 0xB0803ED4, 0x7854C089,
+ 0x208220F4, 0x782FB040, 0x80050BC7, 0xFEAF09BE,
+ 0x09CAD8C8, 0x960EFEAF, 0x248A702E, 0xC0082002,
+ 0xFE6F0D42, 0x1700712C, 0x8F211093, 0x24C7202F,
+ 0xA040200C, 0x002D0152, 0x0FCF228A, 0x30801000,
+ 0x84002011, 0x2440F29F, 0xC507390B, 0x140123F4,
+ 0x140B2314, 0x30B50B37, 0xB9C6653D, 0x6038C007,
+ 0x8002208C, 0x2555F796, 0x0D2D180D, 0x1B002030,
+ 0x26141344, 0xC2011400, 0x23032840, 0x23059036,
+ 0x0A8A05C3, 0x78B0FEEF, 0x1B00F006, 0xF0351344,
+ 0x13441B00, 0x119E0D63, 0xE82FC001, 0x180D2554,
+ 0x20300D1F, 0x13441B00, 0x14002614, 0x23032840,
+ 0x05C32305, 0x9036714C, 0xFEEF0A52, 0x0E3B78B0,
+ 0x28402031, 0xD90F238C, 0x1F802405, 0x02D49004,
+ 0x26149060, 0x90521400, 0xB0327946, 0x0F802304,
+ 0xC3FF0000, 0x7905B90A, 0x1F802405, 0x3ED49004,
+ 0x1300B020, 0x2840110D, 0xC8082302, 0xC0057A05,
+ 0x41C37845, 0x3C009004, 0x7825B802, 0xC006B0A0,
+ 0xB000210B, 0x2205F208, 0x6A1205C2, 0x13007825,
+ 0xB0201101, 0x23802840, 0x0F802005, 0x26FC9004,
+ 0x01121000, 0xC002C504, 0xE88E7AAF, 0x02110A09,
+ 0xE89CC000, 0xE888C000, 0x26802000, 0x0080101C,
+ 0x00000A29, 0xE8098E04, 0x11041602, 0x0447232F,
+ 0x4102C000, 0xC000F006, 0x0448242F, 0x706C4102,
+ 0x04A00C7A, 0x0480250A, 0xC00371A5, 0x09BB79AF,
+ 0x71668004, 0x40C3F153, 0xC2EC9007, 0xB0407126,
+ 0x21FD248D, 0x00051800, 0x3010095D, 0x108B17B7,
+ 0x7C4F8F40, 0x03040951, 0x132E0B49, 0x13002C40,
+ 0x128D245F, 0x05C32005, 0x7865C808, 0x68D2706C,
+ 0x0B31C003, 0xC0020005, 0x2400E887, 0x101C1680,
+ 0x0B1D0080, 0x63BF0000, 0x20F4C08B, 0x2B4003CF,
+ 0x78C50280, 0xB89CB892, 0xB0E0B89F, 0xF1EA7164,
+ 0xF1D97144, 0x1404C0BF, 0xC6DA341B, 0xFFC1046C,
+ 0xFFCF046F, 0x0F812032, 0x0E9C8000, 0x02150809,
+ 0xF0037933, 0x7FE0B9C2, 0x78E0782D, 0x78E07EE0,
+ 0x70C51E00, 0x0088900C, 0x78E07EE0, 0x0926C0F1,
+ 0x0862FD8F, 0x4608FD8F, 0x4528CA09, 0x09807014,
+ 0xC1A10361, 0xC040C086, 0x70801600, 0x00128000,
+ 0x10240E0D, 0x0D5E40A1, 0xC1000720, 0x7014CA09,
+ 0x07010A10, 0xDC247487, 0xFD8F009B, 0xC1A2C3E8,
+ 0x45284050, 0x41C34200, 0x00010361, 0xFFEF0FB2,
+ 0xED23750C, 0x70CD704C, 0x7100244A, 0x4040702C,
+ 0x024020A8, 0x20F4C380, 0x7B34200C, 0x712460B8,
+ 0x1406B380, 0x750C3106, 0x31041402, 0x036241C3,
+ 0x14040005, 0x0F7A3105, 0x1400FFEF, 0x71C53103,
+ 0x0AC97AD0, 0xC7C88344, 0x02550A15, 0x215FE808,
+ 0x621A0240, 0x0F822232, 0x4FA08001, 0x40407FE0,
+ 0x88008821, 0x7FE0B807, 0x78E06038, 0x88008821,
+ 0x7FE0B806, 0x78E06038, 0x216C791D, 0x20530142,
+ 0x20840141, 0x60380001, 0x60587FE0, 0x00432801,
+ 0x2B007A69, 0x78220041, 0x7FE0621A, 0x78E07850,
+ 0x215FC0E4, 0x44CB0A03, 0x113A8000, 0x647970CD,
+ 0x639291A1, 0x0E257A04, 0x23151365, 0x61990381,
+ 0x790B9122, 0x79DBF208, 0x00412314, 0x91236199,
+ 0x0042220F, 0xF1F171C5, 0xC4C47850, 0xC1A4C3F2,
+ 0x70931600, 0x00048000, 0x02E341C3, 0x0EC20000,
+ 0x740CFFEF, 0x800145CB, 0x6DCB4E77, 0x19152554,
+ 0x02200CC6, 0x40C140C1, 0x05600F66, 0x40C1D90B,
+ 0x05600F5E, 0x40C1D911, 0x0A7ED912, 0xDAEFFEAF,
+ 0x0F4E40C1, 0xD9120560, 0x0F4640C1, 0xD9290560,
+ 0x05600BEA, 0x0BE640C1, 0x40A20560, 0x800140C3,
+ 0x0BDA4F0A, 0x42100560, 0x800140C3, 0x0BCE4F55,
+ 0x41100560, 0x10C01603, 0x8E3670ED, 0x800040D3,
+ 0x8E4D1220, 0x23C218B8, 0x23C41800, 0x017E0A11,
+ 0x238018BC, 0x00120809, 0x011E0933, 0x092F7905,
+ 0xB88601BF, 0x154BAD00, 0xB8861080, 0x10021D4B,
+ 0x10801596, 0x1D96B886, 0x15E11002, 0xB8861080,
+ 0x10021DE1, 0x07200862, 0xC808710C, 0x40C36832,
+ 0x0504901C, 0xB1E07905, 0x10C3276F, 0x804518A4,
+ 0x773541C3, 0x8F009400, 0x80822044, 0x001E40C3,
+ 0x45088480, 0x104125CA, 0xE9098F38, 0x02E541C3,
+ 0x0DCE0000, 0xD80AFFEF, 0x7054F047, 0x0BEB41C3,
+ 0x20CAC200, 0x09DE0041, 0x702C03A0, 0x70801600,
+ 0x000D8000, 0x00BE080B, 0x09DED840, 0x0D960700,
+ 0x40C3FFCF, 0x019B8000, 0x10FF8820, 0x20058080,
+ 0xF21A807E, 0x201A782A, 0x000F0F80, 0x09CA4240,
+ 0x702C03A0, 0xC8094200, 0x010421AA, 0x09237912,
+ 0x23AA0085, 0x08FF0104, 0x20AA80C4, 0x50320144,
+ 0xF0097A22, 0x097E40A1, 0x702C03A0, 0x621AF00D,
+ 0x21AAC80A, 0x090F0104, 0x23AA00A5, 0x08F70144,
+ 0x20AA80C0, 0x16000104, 0x80007080, 0xB8E0000D,
+ 0x06C20F78, 0x03C008CE, 0x800045CB, 0x8D001138,
+ 0x0010088B, 0x08878F00, 0x0DE200DF, 0x0EF20080,
+ 0x8D00FDCF, 0x704C708E, 0x8F00E806, 0x02002044,
+ 0x00022078, 0x0B4A700C, 0xD908FE6F, 0x081F8D01,
+ 0x704C00B4, 0xE8078D00, 0x20448F00, 0x20780200,
+ 0x700C0002, 0xFE6F0B2A, 0x8D00702C, 0xE807704C,
+ 0x20448F00, 0x20780200, 0x700C0002, 0xFE6F0B12,
+ 0x8D00D90A, 0x8F00E806, 0x02002044, 0x00142078,
+ 0x702CD808, 0xFE6F0AFA, 0x8D004282, 0x8F00E80E,
+ 0x02002044, 0x00022078, 0x40C3F009, 0x8480001E,
+ 0x03A008B2, 0xF00F702C, 0x700C704C, 0xFE6F0AD2,
+ 0x0C42D996, 0x700C0580, 0xFE2F0F82, 0x0CC2712C,
+ 0x160000C0, 0x80007080, 0x081502FE, 0xD95D003E,
+ 0x0C5ED80A, 0xB913FFEF, 0x07400AFA, 0x0BE2C080,
+ 0x235305A0, 0xC08020D3, 0x00A008BE, 0x40C1D91C,
+ 0xC280702C, 0x708CDBFF, 0x07600BD2, 0x0B5A70AD,
+ 0x0BBE0000, 0xC08005A0, 0x089EC080, 0xD91000A0,
+ 0x0896C080, 0xD91C00A0, 0x712C40C1, 0xDBFFC280,
+ 0x07600BAA, 0x40C1708C, 0x04E00E4E, 0x40C1D90B,
+ 0x04E00E46, 0x40C1D911, 0x04E00E3E, 0x40C1D912,
+ 0x04E00E36, 0xCA0ED929, 0x10050D2F, 0x2B02235F,
+ 0x1F812532, 0x04788000, 0x7AB561CB, 0x720271A5,
+ 0x2132AA68, 0xAA6A0483, 0x05432132, 0x04412132,
+ 0xAA2BAA69, 0x0CEAF1EA, 0xD96EFE8F, 0x11C5B99F,
+ 0x19018480, 0x21400012, 0x21400EC2, 0x12010683,
+ 0xA9000480, 0x04801201, 0x00121B01, 0x04801205,
+ 0x1201AB00, 0xA9010480, 0x04801201, 0x1201A902,
+ 0xAB010480, 0x04801201, 0x1276AB02, 0x1A8B0480,
+ 0x12018012, 0x43400480, 0x000A1B79, 0x04801201,
+ 0xAC006B85, 0x121D6C25, 0x19010480, 0x12010012,
+ 0x1A560480, 0x12010002, 0xAB010480, 0x04801201,
+ 0x1211AC01, 0x19010480, 0x12010012, 0x1A430480,
+ 0x8A000002, 0x8A01AB02, 0x8A02AC02, 0x197CE227,
+ 0x12010012, 0x19010480, 0x12010012, 0x19010480,
+ 0x12010012, 0x19010480, 0x12010012, 0x19E70480,
+ 0x12018012, 0x19050480, 0x12010012, 0x19050480,
+ 0x12010012, 0x19050480, 0x12010012, 0x19010480,
+ 0x12010012, 0x21420480, 0xAB0003C3, 0x028C2142,
+ 0x04801201, 0xAC0069AD, 0x04801201, 0x1201AD00,
+ 0x19010480, 0x12010012, 0xAB010480, 0x04801201,
+ 0x1201AC01, 0xAD010480, 0x04801201, 0x1201A900,
+ 0xAB020480, 0x04801201, 0x1201AC02, 0xAD020480,
+ 0x04801201, 0x1201A901, 0x19F30480, 0x8A008002,
+ 0x800219F8, 0x19FD8A01, 0x8A028002, 0x1600A902,
+ 0x90387101, 0x12260034, 0x080D8080, 0x704C01BF,
+ 0xF011B9A0, 0x70801600, 0x01648000, 0x013F0817,
+ 0x1600B980, 0x80007080, 0xB8E6001F, 0x22CA724C,
+ 0x1E000061, 0x903B7044, 0xC808C034, 0x2005B802,
+ 0x903B0F80, 0xB040C008, 0x78E0C7D2, 0x40C3C5E1,
+ 0x12228000, 0x706C88A1, 0x704C8880, 0xCA00702C,
+ 0x00050921, 0x03040909, 0x10450D0F, 0x0F802205,
+ 0x3ED49004, 0x7124B060, 0x000072C3, 0xF1F14000,
+ 0x78E0C4C2, 0x1C00DC3F, 0x7C0F0302, 0x080DB830,
+ 0x4C3100A5, 0xF00A4852, 0x00250B09, 0xF0064872,
+ 0x704C7831, 0x00021C00, 0xCC1D792C, 0x0003211A,
+ 0x221ACC1C, 0x782C0081, 0x60787FE0, 0x44CBC0F1,
+ 0x01078000, 0x42008C60, 0x003F0B2D, 0x0B29710C,
+ 0x700C007F, 0x7234B9A0, 0xFEC20C9C, 0x40C3F40B,
+ 0x4E778001, 0x9081145B, 0x78258800, 0x207A780D,
+ 0x78440000, 0x7EE0C0D1, 0x71001600, 0x00068000,
+ 0x0F80203C, 0x0C800000, 0x78E07EE0, 0x06C3216F,
+ 0xB8E68900, 0x7CE0700C, 0x20448907, 0x7FE00200,
+ 0x78E0B823, 0x4528C2E4, 0xFDEF0B26, 0xEE1E4608,
+ 0x05800926, 0xD925700C, 0xDB86704C, 0x45A1708C,
+ 0xFE2F0C8A, 0x700C70CC, 0x704CD926, 0x708CDB86,
+ 0x0C7A70AC, 0x70CCFE2F, 0xD910700C, 0xFE2F0F62,
+ 0x08D2714C, 0xF00C0580, 0x10452553, 0xD919D880,
+ 0xDB86744C, 0x0C56708C, 0x70CCFE2F, 0x0BFE700C,
+ 0x712CFE2F, 0x40C3EE87, 0x75300000, 0x03600D06,
+ 0xC6C4D91E, 0x0C46C0F1, 0x730C0060, 0x800040C3,
+ 0x88001138, 0x1600E810, 0x80007080, 0x08190001,
+ 0x098A00DF, 0x710C0080, 0xFFEF0F6E, 0x0902D90F,
+ 0xF00600C0, 0x0F62700C, 0xD90FFFEF, 0x7EE0C0D1,
+ 0x4430C2F0, 0xFEEF0BA2, 0x46CB4110, 0x12DC8000,
+ 0x43108620, 0x800140C3, 0x88E04E77, 0x0442202F,
+ 0x70901600, 0x00628000, 0x704CB8C0, 0x0976706C,
+ 0x42100260, 0x900745CB, 0x0A0AC17C, 0x1D000520,
+ 0x0A3E1005, 0x708CFDCF, 0x4080752C, 0xB895714C,
+ 0x0004238A, 0x0440250A, 0xFE2F0BA2, 0xD88070CC,
+ 0xB892D90F, 0x706CDA20, 0x0500240A, 0x0440250A,
+ 0xFE2F0B8A, 0x700C70CC, 0xFE2F0B32, 0x2705712C,
+ 0x78ED140F, 0x20310B0F, 0x10451D00, 0x00120807,
+ 0x8620C6D0, 0x00022084, 0x01C32841, 0x09064042,
+ 0x42620260, 0x78E0C6D0, 0x0B62C2E6, 0x730C0060,
+ 0x72ED70CD, 0xB89FD825, 0x881B8820, 0x710C7905,
+ 0xB80278D8, 0x0380200F, 0xF259782B, 0x712C7D0F,
+ 0x056009EE, 0x09AA40A1, 0x0AF2FDCF, 0xE00C0140,
+ 0x7A0F752C, 0xB813D809, 0x0008238A, 0x45A1708C,
+ 0xFE2F0B0A, 0x269F70CC, 0x700C12C1, 0xDA22762C,
+ 0x03C0244A, 0x70CC45A1, 0x1F8E2632, 0x4E838001,
+ 0xFE2F0AEA, 0x11C3264F, 0x002D40C3, 0x0BB6C6C0,
+ 0x712C0360, 0x700C7910, 0xFE2F0DC6, 0x700C704C,
+ 0xDA22762C, 0x244A43C1, 0x45A103C0, 0xFE2F0ABE,
+ 0x700C70CC, 0xDA08752C, 0x000E238A, 0x45A1708C,
+ 0xFE2F0AAA, 0xD88070CC, 0xB893D907, 0x706C744C,
+ 0x70AC708C, 0xFE2F0A96, 0x700C70CC, 0xFE2F0A3E,
+ 0x40A1712C, 0x0560094A, 0x278D702C, 0x71CD17BE,
+ 0x78E0C6C6, 0xB7C81CF4, 0xC181C808, 0x1C08714C,
+ 0x0DEA3001, 0x1C0404A0, 0x41C33001, 0x0000036B,
+ 0xFFAF0EFE, 0x700C750C, 0x0F36712C, 0xC281FFAF,
+ 0x341F140C, 0x78E07EE0, 0xB7C81CF4, 0x70C3C181,
+ 0x00400100, 0x1C08714C, 0x0DB23001, 0x1C0404A0,
+ 0x41C33001, 0x0000036A, 0xFFAF0EC6, 0x700C750C,
+ 0x0EFE712C, 0xC281FFAF, 0x341F140C, 0x78E07EE0,
+ 0x4030C2EA, 0x70AD4110, 0x00FA76B5, 0x097B000D,
+ 0x740C203E, 0x00E541C3, 0x0E960001, 0x42A1FFAF,
+ 0xDF0770CD, 0x800040C3, 0x88600485, 0x800040C3,
+ 0x10001220, 0x244A008B, 0x708D7200, 0x20A8DA07,
+ 0x40610540, 0x209F6D35, 0x27060803, 0x70021388,
+ 0x2E416119, 0x667E10C0, 0x28016108, 0xB8C00200,
+ 0x77447858, 0x7A8F7C05, 0x00E641C3, 0x0E420001,
+ 0x740CFFAF, 0x9004268C, 0xFFC507AC, 0x740CD9E7,
+ 0xFFAF0E2E, 0x097BB910, 0x740C207E, 0x00E841C3,
+ 0x0E1E0001, 0x42A1FFAF, 0xDF0770CD, 0x800040C3,
+ 0x88600485, 0x800040C3, 0x10001220, 0x244A008B,
+ 0xDA077200, 0x20A8708D, 0x40610540, 0x209F6D35,
+ 0x27060803, 0x70021388, 0x2E416119, 0x667E10C0,
+ 0x28016108, 0xB8C00200, 0x77447858, 0x7A8F7C05,
+ 0x00E941C3, 0x0DCA0001, 0x740CFFAF, 0x9004268C,
+ 0xFFC507AC, 0x740CD975, 0xFFAF0DB6, 0x71A5B911,
+ 0xC6CAF184, 0xC1A2C3F6, 0x46504170, 0xC1814730,
+ 0x30C22440, 0x01600A82, 0x30832440, 0x000040C3,
+ 0x211A28F0, 0x14022011, 0x232F3094, 0x46CB2000,
+ 0x1B3C8000, 0x308D1403, 0x23640C9F, 0x0F0679AF,
+ 0x40E20560, 0x704E4510, 0x24AE0D85, 0x261F474A,
+ 0x251A24C1, 0x00001F80, 0x279A0A3C, 0x71221184,
+ 0x671F6038, 0x06E00A76, 0x13D02600, 0x20851002,
+ 0x13842734, 0x21061004, 0x2D41E808, 0x740C0085,
+ 0x00A741C3, 0xF0060005, 0x41C3740C, 0x000500A8,
+ 0x0D1E42A1, 0x4342FFAF, 0x18002659, 0x1600671F,
+ 0x80007080, 0x0819000B, 0x40E1007F, 0x00200BCA,
+ 0x40E1712C, 0x00200BC2, 0xF00A702C, 0x090240E1,
+ 0x712C0020, 0x08FA40E1, 0x702C0020, 0x0A7D7146,
+ 0x71A5A294, 0xC7D6F1B2, 0xC1BFC3EA, 0x47084548,
+ 0x702CC08B, 0x0CEADA50, 0x4668FD2F, 0x10B10F29,
+ 0x41C3750C, 0x00010365, 0xFFAF0CB6, 0xC08B42C1,
+ 0x0D9E702C, 0x704C04A0, 0xD909700C, 0xFFAF0CE2,
+ 0xC7CAC28B, 0xC046700C, 0xC044C045, 0x30041C28,
+ 0x750CC049, 0x41C3EF12, 0x00010368, 0xFFAF0C82,
+ 0x255442C1, 0x25001F42, 0x01001F8C, 0x25400020,
+ 0x4D5A1A03, 0xF00F712C, 0x036641C3, 0x0C620001,
+ 0x42C1FFAF, 0x148C2540, 0x14022540, 0xD9094D48,
+ 0xC040DBC8, 0x000940C3, 0x70AD0001, 0x37102440,
+ 0x30112440, 0xC047C241, 0x4083C442, 0xC343B030,
+ 0xC08BB031, 0x0C4A702C, 0xDA50FD2F, 0x24011104,
+ 0x1002C808, 0x7825250E, 0x0AF2C18B, 0x42C104A0,
+ 0x41C140A1, 0xFFAF0C4A, 0x71A5C28B, 0x91140DD7,
+ 0x90110F63, 0x00000CF2, 0x78E0C7CA, 0x1CFCC2FA,
+ 0x2482B6C8, 0x20143F05, 0x22550042, 0x922A0800,
+ 0x30401CE8, 0x1CEC9228, 0x92263040, 0x30401CF0,
+ 0x1CF49224, 0x92223040, 0x30401CF8, 0x1CFC9220,
+ 0x922C3040, 0x30581C40, 0x1C41922E, 0x92303058,
+ 0x30581C42, 0x1C439232, 0x92343058, 0x30581C44,
+ 0x1C459236, 0x92383058, 0x30581C46, 0x1C47923A,
+ 0x923C3058, 0x30581C48, 0x1C49923E, 0x12403058,
+ 0x1C4A0101, 0x12443058, 0x1C4B0101, 0x12483058,
+ 0x1C4C0101, 0x124C3058, 0x1C4D0101, 0x12503058,
+ 0x1C4E0101, 0x12543058, 0x1C4F0101, 0x12583058,
+ 0x1C500101, 0x125C3058, 0x1C510101, 0x12603058,
+ 0x1C520101, 0x12643058, 0x1C530101, 0x12683058,
+ 0x1C540101, 0x126C3058, 0x1C550101, 0x12703058,
+ 0x1C560101, 0x12743058, 0x1C570101, 0x12783058,
+ 0x1C580101, 0x127C3058, 0x1C590101, 0x90203058,
+ 0x30581C5A, 0x1C5B9022, 0x90243058, 0x30581C5C,
+ 0x1C5D9026, 0x90283058, 0x30581C5E, 0x01061014,
+ 0x01091018, 0x0108101C, 0x010B1020, 0x90F490D2,
+ 0x909890B6, 0x905C907A, 0x1040903E, 0x10440119,
+ 0x10480118, 0x104C0117, 0x10500116, 0x10540115,
+ 0x10580114, 0x105C0113, 0x10600112, 0x10640111,
+ 0x10680110, 0x106C011F, 0x1070011E, 0x10740105,
+ 0x10780104, 0x107C0107, 0x2455011B, 0x18643800,
+ 0x186006C0, 0x185C01C0, 0x18580100, 0x18540140,
+ 0x18500780, 0x184C07C0, 0x18480400, 0x18440440,
+ 0x18400480, 0x183C04C0, 0x18380500, 0x18340540,
+ 0x18300580, 0x182C05C0, 0x18280600, 0xA0290640,
+ 0x00A541C3, 0xA0480040, 0xA086A067, 0xA0E4A0A5,
+ 0x1808A0C3, 0x180402C0, 0x18000200, 0x145E0240,
+ 0x1C7C3600, 0x14FC3180, 0xC05E3002, 0x3600145D,
+ 0x300314F8, 0x300414F4, 0x145CC05D, 0x14EC3600,
+ 0x14F03006, 0xC05C3005, 0x3600145B, 0x300714E8,
+ 0x145AC05B, 0xC05A3600, 0x36001459, 0x1458C059,
+ 0xC0583600, 0x36001457, 0x1456C057, 0xC0563600,
+ 0x36001455, 0x1454C055, 0xC0543600, 0x36001453,
+ 0x1452C053, 0xC0523600, 0x36001451, 0x1450C051,
+ 0xC0503600, 0x3600144F, 0x144EC04F, 0xC04E3600,
+ 0x3600144D, 0x144CC04D, 0xC04C3600, 0x3600144B,
+ 0x144AC04B, 0xC04A3600, 0x36001449, 0x1448C049,
+ 0xC0483600, 0x36001447, 0x1446C047, 0xC0463600,
+ 0x36001445, 0x1444C045, 0xC0443600, 0x36001443,
+ 0x1442C043, 0xC0423600, 0x36001441, 0x1440C041,
+ 0xC0403600, 0xFFAF094A, 0x2480740C, 0x14043F05,
+ 0xC6DA341B, 0x1CFCC2FA, 0xC1BCB6C8, 0x20557834,
+ 0x90580801, 0x01051158, 0x01071160, 0x9054C259,
+ 0x01061168, 0x01041018, 0x9050C25A, 0x01161010,
+ 0x01171008, 0x1038C25B, 0x10400108, 0x10480119,
+ 0x10500118, 0x10580115, 0x10600114, 0x10680113,
+ 0x10700112, 0x10780111, 0x1100011B, 0x9164010B,
+ 0x91EC9148, 0x91B491D0, 0x911C9198, 0x01101140,
+ 0x011F1148, 0x011E1150, 0x01091170, 0x01011178,
+ 0x31801C58, 0x31C01C54, 0x31401C50, 0x3005146C,
+ 0x30061468, 0x30071464, 0x41C3C158, 0x001F00A6,
+ 0x740CC050, 0x42E2C24B, 0x43C2C34A, 0x32401C5C,
+ 0x37801C4C, 0x37C01C48, 0x34001C44, 0xC54EC44F,
+ 0xC74CC64D, 0x32C01C24, 0x36C01C20, 0x34401C1C,
+ 0x34801C18, 0x34C01C14, 0x35001C10, 0x35401C0C,
+ 0x36001C08, 0x36401C04, 0xFFAF0856, 0x32001C00,
+ 0x1404C0BC, 0xC6DA341B, 0xC1A2C2F2, 0x70901600,
+ 0x00048000, 0x20D02053, 0x710C702E, 0x70AE724E,
+ 0x1600E807, 0x80007080, 0xE8890025, 0x1600F040,
+ 0x80007080, 0x08810040, 0x251F0010, 0x00002F8D,
+ 0x706E7000, 0x23002B40, 0x60BE70AC, 0xC808728E,
+ 0x03812005, 0x0300255F, 0x0F802030, 0x05B88000,
+ 0xB8027825, 0xB89FB89C, 0x20539000, 0x205300C6,
+ 0x274C0107, 0x26CE8400, 0xB8250026, 0x00C12053,
+ 0x02340909, 0x7813B8C2, 0x41C3C141, 0x0008006A,
+ 0x750CC040, 0x43A24202, 0xFF6F0FB6, 0x04C0240A,
+ 0x25FF248D, 0x716671AC, 0xA1940B9D, 0x228D700C,
+ 0x71AE2EBE, 0x800040C3, 0x880012D9, 0x046E087D,
+ 0x724E708E, 0x2414710C, 0x2800244E, 0xBE0C050F,
+ 0x45CB706E, 0x05D08000, 0x7F0B8D04, 0xC808F227,
+ 0x03812005, 0x78258500, 0xB89CB802, 0x9000B89F,
+ 0x00C62053, 0x01072053, 0x8400274C, 0x002626CE,
+ 0x2053B825, 0x090B00C1, 0xB8C20234, 0xC1417813,
+ 0x006B41C3, 0xC0400008, 0x4202750C, 0x240A4322,
+ 0x0F2E0500, 0x250AFF6F, 0x716604C0, 0xA1B40BAD,
+ 0x228DE50C, 0x718E22BF, 0x097D7126, 0xC0A2A114,
+ 0x78E0C6D2, 0xC1B7C3EC, 0x41C3D840, 0x0000036D,
+ 0x88A0B89F, 0x809110E5, 0xFF6F0EF6, 0x2105750C,
+ 0x700E2351, 0xE58770AD, 0x00260162, 0x20C02178,
+ 0x10B50D0D, 0x1208704E, 0xF009360E, 0x0D0F704E,
+ 0x70CD10B0, 0x360E1208, 0xC083744E, 0x0EE2702C,
+ 0xDA50FCEF, 0x800041C3, 0x89011222, 0x08E38980,
+ 0x742C0324, 0x29007882, 0x732C048F, 0x049F2900,
+ 0x2900722C, 0x712C049E, 0x04852900, 0x40C36821,
+ 0x12D98000, 0x00841000, 0x7040240A, 0x903843C3,
+ 0x20A80000, 0x0CA905C1, 0x2C40032E, 0x26F01347,
+ 0x8000734B, 0x270510F8, 0xC2830387, 0x11C02305,
+ 0x03012215, 0x2300B802, 0x78651146, 0x17892300,
+ 0x23009000, 0xB10017C8, 0x01C02605, 0x7865B802,
+ 0xB1089000, 0x11C02105, 0x7865B802, 0xB1109000,
+ 0x11C02005, 0x7865B802, 0xB1189000, 0x7894710C,
+ 0x00012214, 0x2005B80C, 0x23050382, 0x23001080,
+ 0xB80213CB, 0x90007865, 0x2605B100, 0xB8020080,
+ 0x90007865, 0x2105B108, 0xB8021080, 0x90007865,
+ 0x2005B110, 0xB8021080, 0x02C22205, 0x90007865,
+ 0x6A12B118, 0x90007865, 0x00041940, 0x750C7185,
+ 0x036E41C3, 0x42A10001, 0xFF6F0DC6, 0x6E3470CD,
+ 0x6038C083, 0x01071008, 0x01061006, 0x01041002,
+ 0x01051004, 0x90459060, 0x90079026, 0x42C1C240,
+ 0x41C3C141, 0x0009036F, 0x0D96C042, 0x750CFF6F,
+ 0x0ECF71C5, 0x71A59154, 0x68C1F14F, 0x41C3750C,
+ 0x00010370, 0xFF6F0D7A, 0x70AD4202, 0x209F4002,
+ 0x20140401, 0x40C30341, 0xBF648000, 0x6113603A,
+ 0x123C750C, 0x41C30106, 0x00050371, 0x01051228,
+ 0x01041214, 0xFF6F0D4A, 0x71A542A1, 0x92540DD1,
+ 0x20402040, 0x83A408B9, 0xC7CC710E, 0x094AC2E6,
+ 0x702CFEEF, 0x800046CB, 0x8EE01222, 0x09418E21,
+ 0x204003E4, 0xC8080A8D, 0x78A57AEF, 0x2A406832,
+ 0x78250380, 0x03F141C3, 0xB8920004, 0xB89FB89C,
+ 0x750C9060, 0x23534460, 0x0CF60145, 0x24ADFF6F,
+ 0x71E50982, 0x79EF8E01, 0x804508CF, 0x78E0C6C6,
+ 0xC1B4C3E2, 0x360D1208, 0x702CC080, 0xFCEF0CF2,
+ 0xD9DBDA50, 0x0CCA750C, 0xB912FF6F, 0x12032585,
+ 0x40A1C180, 0x04600B96, 0x700CDA09, 0x0CF2D909,
+ 0xC280FF6F, 0x78E0C7C2, 0x78E07EE0, 0xA023702C,
+ 0xA021A022, 0xA0207FE0, 0x4200C2E8, 0x780F7704,
+ 0x004C41C3, 0x207C0001, 0x098E00C0, 0x4050FD2F,
+ 0x901C41C3, 0x42C301C8, 0x12228000, 0x20B00821,
+ 0xDC25706C, 0x0831BC9F, 0x8C002071, 0xB162B100,
+ 0x9201B178, 0xD83FB200, 0xF00CB806, 0x1600B160,
+ 0x80007080, 0xB1020040, 0x9202B178, 0xD83FB200,
+ 0xF011B110, 0x8C1BB100, 0xB178B102, 0x20049110,
+ 0x00000F80, 0xB110FFBE, 0xAA008A02, 0xAA018A05,
+ 0x0F16B170, 0x400204E0, 0x78E0C6C8, 0x40C37014,
+ 0x048A8000, 0x1600F207, 0x90387101, 0xB9800030,
+ 0x9020F003, 0x1E00B9A0, 0x903B7044, 0x7FE0C030,
+ 0x78E0B020, 0x4528C2E4, 0xFD6F0DC6, 0xEE154608,
+ 0x762CC808, 0x746CDA22, 0x0B80244A, 0x70CC45A1,
+ 0x2005B802, 0x90070F80, 0x1800C004, 0x0F1E0045,
+ 0x700CFDAF, 0x700CF013, 0xDA22762C, 0x244A706C,
+ 0x45A10B80, 0xFDAF0F06, 0xC80870CC, 0x2005B802,
+ 0x90070F80, 0x1800C004, 0x700C0005, 0xFDAF0E9E,
+ 0xC6C4712C, 0x4628C2E4, 0x21534508, 0x710C0142,
+ 0xFCEF0F3E, 0xBE23702C, 0x16022644, 0x8540655D,
+ 0x85017A06, 0xA5407826, 0xC6C4A501, 0x70801600,
+ 0x00018000, 0x7CE0B8E0, 0x900F41C3, 0x704CC068,
+ 0x04C02150, 0xB040B140, 0x900840C3, 0xB0400068,
+ 0x804519D8, 0x804518A8, 0x18007FE0, 0x78E000C5,
+ 0x03C32841, 0x03C12840, 0x28417B25, 0x21440341,
+ 0x28410081, 0x7B2500C2, 0x02C12841, 0x01012144,
+ 0x00012284, 0x28417B25, 0x21440241, 0x7B250201,
+ 0x01C12841, 0x04012144, 0x28417B25, 0x21440141,
+ 0x79650801, 0x79456875, 0x22847A1D, 0x23840002,
+ 0x79450010, 0x22847A1B, 0x79450004, 0x22846853,
+ 0x79450008, 0x7B25704C, 0xBA8B6837, 0x23057944,
+ 0x2840004C, 0x795B0243, 0x28407964, 0x7C2502C3,
+ 0x79646A32, 0x10432405, 0x03412840, 0x78246A13,
+ 0x7FE07B05, 0x78E07870, 0xC1A4C3FA, 0x00582053,
+ 0x800045CB, 0x207811DA, 0x4138308F, 0x15464510,
+ 0x40E11081, 0x219F4030, 0x42D30582, 0x4E748001,
+ 0x02C1209F, 0x140E2714, 0x46D3706E, 0x02249004,
+ 0x2FC7248A, 0x41C36038, 0x0504901C, 0x100C7042,
+ 0xC8080097, 0x2005B802, 0x1A000042, 0x19A40045,
+ 0x20058045, 0x90070F81, 0x2005C090, 0x90040F80,
+ 0x90000090, 0xB100B888, 0x0B3F66A8, 0x28402025,
+ 0x78F62100, 0xE0247062, 0x294060A9, 0x21050391,
+ 0x18002580, 0x0E060504, 0x740C02E0, 0x22012640,
+ 0x21057166, 0x18002040, 0x69040504, 0x04402005,
+ 0x00051800, 0x2D40F1E2, 0xD9102080, 0x05512005,
+ 0x303009AF, 0x0A9A4042, 0x404204C0, 0x0FA6D910,
+ 0xDA410260, 0xD9104042, 0xFDEF0DAE, 0x0FBEDAF3,
+ 0x208AFDAF, 0x0D820C12, 0x700C0160, 0xFD4F0B7A,
+ 0x40C36829, 0x04888000, 0x0520099A, 0x40C3B020,
+ 0x13880000, 0x02E00DBE, 0x09C2D90C, 0x40420500,
+ 0x0F62D90D, 0xDA400260, 0x05200916, 0xC080C080,
+ 0xFFEF0DF6, 0xC080D910, 0xFFEF0DEE, 0x41E1D90D,
+ 0x219F4002, 0x704C02C1, 0x0582209F, 0x708CC380,
+ 0x611970AC, 0x0447202F, 0x06A00E2E, 0x40427142,
+ 0x0D36D910, 0xDAF3FDEF, 0xD9104042, 0x02600F16,
+ 0x4042DA61, 0x0D22D910, 0xDA7FFDEF, 0x0D1AF00E,
+ 0xDAF3FDEF, 0xD9104042, 0x02600EFA, 0x4042DA61,
+ 0x0EF2D910, 0xDA800260, 0x70451E00, 0x04C4901C,
+ 0x800040C3, 0x88001220, 0xDA40E803, 0xDA25F002,
+ 0x209F41E1, 0x219F0582, 0xBA9F02C1, 0x00931200,
+ 0x70426038, 0xFD6F0ACA, 0x00941010, 0x000009AE,
+ 0x050008C6, 0x0447222F, 0x0806D810, 0x4182FDEF,
+ 0x742C700C, 0xFDAF0F1A, 0x0B27714C, 0x710C20F1,
+ 0x30812079, 0x24847838, 0xB8022282, 0x21412485,
+ 0x0040200F, 0x7A0F4182, 0xFDAF0FD6, 0x700CD810,
+ 0x0EEED920, 0x714CFDAF, 0x0BA2700C, 0x712CFDAF,
+ 0xFD4F0A6E, 0x01600C52, 0x084A700C, 0x700C0500,
+ 0xFDAF0B8A, 0xD914702C, 0x000040C3, 0x0C961388,
+ 0x441002E0, 0xE81866A8, 0x2840706E, 0x78F62100,
+ 0xE0247062, 0xD88060A9, 0x052009EA, 0x29404130,
+ 0x71662391, 0x2F812105, 0x02309004, 0x66A8B100,
+ 0xA0040BDB, 0x0C5E4082, 0xD90C02E0, 0x00400882,
+ 0x0500085A, 0x000340C3, 0x0C4AD090, 0x702C02E0,
+ 0x05200812, 0x21D5274F, 0xE81866A8, 0x2840706E,
+ 0x78F62100, 0xE0247062, 0x40A260A9, 0x05200996,
+ 0x29404130, 0x71662391, 0x2F812105, 0x02309004,
+ 0x66A8B100, 0xA0040BDB, 0x40C3D90C, 0x13880000,
+ 0x02E00C02, 0x66A84410, 0x254FE819, 0x706E2215,
+ 0x21002840, 0x706278F6, 0x60A9E024, 0x095640A2,
+ 0x41300520, 0x23912940, 0x21057166, 0x90042F81,
+ 0xB1000230, 0x0BDD66A8, 0x4082A004, 0x02E00BC6,
+ 0x66A8D90C, 0x702EE825, 0x21002840, 0x702278F6,
+ 0x60A9E024, 0x0006208A, 0x0520091A, 0x2B404330,
+ 0x24052394, 0x90042F81, 0xB1000224, 0x02E00B6E,
+ 0x208A740C, 0x08FE0006, 0x41620520, 0x2F812405,
+ 0x022C9004, 0x7126B100, 0x09C166A8, 0x40C3A004,
+ 0xD0900003, 0x02E00B6E, 0x4042702C, 0x0460098A,
+ 0x0F6AD910, 0xC7DA04C0, 0x40D3C2F8, 0x01E8901C,
+ 0x000040C3, 0x10000FFF, 0x10102112, 0x18102111,
+ 0x18002005, 0xC8082004, 0x2005B802, 0x900C0F80,
+ 0x90400020, 0x800040C3, 0x8800121E, 0x0201204F,
+ 0x1E006058, 0x901C7044, 0x20420508, 0x160000D5,
+ 0x80007080, 0x70140114, 0xD93DF281, 0xB910750C,
+ 0xFF2F0EDE, 0x47CB70CD, 0x01188000, 0x45CB8F40,
+ 0x0001003E, 0x0ECA750C, 0x41A1FF2F, 0x10562740,
+ 0x1401254F, 0x20821600, 0xFF2F0EB6, 0x2640750C,
+ 0x71AD2057, 0x20821700, 0x750CBD96, 0xFF2F0EA2,
+ 0x274241A1, 0x254F10D4, 0x14001401, 0x0E922082,
+ 0x750CFF2F, 0x20532440, 0x1441254F, 0x20821300,
+ 0x0E7E750C, 0x4038FF2F, 0x204F6FA9, 0x8D403401,
+ 0xFF2F0E6E, 0x710C750C, 0xE808722D, 0x70801600,
+ 0x00258000, 0xF037E887, 0x70801600, 0x00408000,
+ 0xC808E835, 0x13812E40, 0x7180244A, 0x008B2840,
+ 0x0A4020A8, 0x03DE208A, 0x201143E2, 0x40A18380,
+ 0x4062F40F, 0x11300E1B, 0x0E1343C2, 0x40621330,
+ 0x12F00E0F, 0x0E2743C2, 0x40821151, 0x210543E1,
+ 0x884002C8, 0x20058B00, 0x90001F8C, 0xB40001C0,
+ 0x1F802005, 0x01B49000, 0x71C5B040, 0x000071C3,
+ 0xDE074000, 0x10FF218D, 0x45CB700C, 0x11388000,
+ 0x108015E6, 0x27C12D42, 0x7824B802, 0x1E0070A2,
+ 0x901C7004, 0x40C30510, 0x2AF80000, 0x02E009E6,
+ 0x1800702C, 0x18102484, 0x15E62444, 0x781D1080,
+ 0x7704B8A0, 0xC6D8AD01, 0x0AC2C2E8, 0x40100640,
+ 0x700C71ED, 0x900F45CB, 0xD940C298, 0x73C41E00,
+ 0xC028900F, 0x02E009AE, 0x1E00B5E0, 0x902F73C4,
+ 0x0A62CC40, 0x700C03A0, 0x02E0090E, 0x1D00D810,
+ 0x16001005, 0x9018710E, 0x08150018, 0x26842030,
+ 0x1E001C07, 0x901B73C4, 0xF02EC000, 0x901B45CB,
+ 0x264FC018, 0x702C1280, 0x096AB500, 0x208A02E0,
+ 0x702C0A0F, 0x000F40C3, 0x095A4240, 0x1DEC02E0,
+ 0x160093C4, 0x90187101, 0x1DE8004C, 0xB9C493C4,
+ 0x90051DEC, 0x70801600, 0x00048000, 0x08002044,
+ 0x78C5B804, 0xC808B500, 0x2005B802, 0x90180F80,
+ 0xB0200024, 0x800041C3, 0x89001220, 0x0582209F,
+ 0x000111BC, 0x88216038, 0x00DF090D, 0x21538834,
+ 0xF20480FE, 0x04C00E2A, 0x70451E00, 0xC0B49027,
+ 0x78E0C6C8, 0xC1A3C3FA, 0x2140260A, 0x3100210A,
+ 0x40584770, 0x71344530, 0x002D0136, 0xC8084210,
+ 0x800047CB, 0xB8021222, 0x0F802005, 0x01909038,
+ 0x08159000, 0x1600025E, 0x80007080, 0x701400F3,
+ 0x0001024E, 0x208A70D4, 0x218A003E, 0x0C9E2001,
+ 0x21CAFD2F, 0x8FA02002, 0x00132079, 0x22132340,
+ 0x75308F21, 0x000D01A6, 0x800040C3, 0x880012D9,
+ 0x036E08CB, 0x0E137AAF, 0x40622030, 0x0C8E41A2,
+ 0x43420060, 0x0A92F004, 0x40400020, 0x234E2714,
+ 0x20700A25, 0x0A4FB600, 0x212F2031, 0xF2138348,
+ 0x0050099F, 0x009009A3, 0x00D1093B, 0x800041C3,
+ 0xF01C014A, 0x8348222F, 0x41C3F209, 0x014C8000,
+ 0x41C3F008, 0x01478000, 0x41C3F010, 0x014B8000,
+ 0x0083227C, 0x21CA7074, 0x80000F81, 0x0A0D014D,
+ 0x41C300D4, 0x014E8000, 0x00901100, 0x70811600,
+ 0x000D8000, 0x017E0937, 0x0DFAC182, 0x22140040,
+ 0x20002340, 0x80000F94, 0x0D6A0470, 0x140904A0,
+ 0x08133080, 0xC1220874, 0x001E090F, 0x20431C00,
+ 0x09FDF005, 0x1C00801E, 0x96202003, 0x24402000,
+ 0x2108780F, 0x49100001, 0x71A5B600, 0x41C3F192,
+ 0x01488000, 0x41C3F1D2, 0x01498000, 0x2550F1CE,
+ 0x08BF2000, 0x708D00B1, 0x800045CB, 0x0EC31222,
+ 0x73B62030, 0x20C82578, 0x126124CA, 0x12482040,
+ 0xFD2F0B7A, 0x12892C40, 0x108615B7, 0x15014700,
+ 0x8D60108B, 0x018C7371, 0x0E7F000D, 0x2B4000EE,
+ 0xC8080301, 0x47CB7905, 0xFFFF0000, 0x04812105,
+ 0x69B270CD, 0x42814021, 0x02050A43, 0x00310F11,
+ 0x06812300, 0x0081111C, 0x00400A2B, 0x20B10D13,
+ 0x03412005, 0x0F812105, 0x01E89004, 0x2505F005,
+ 0x90041F81, 0x912000A8, 0x210871F1, 0x27CA038E,
+ 0x20801045, 0x71440010, 0x66FEF1E0, 0x20C22714,
+ 0x268C79DD, 0x21809002, 0x21CA003F, 0xB2200025,
+ 0x30C22014, 0x7164B220, 0x8FA0F1BE, 0x700CF080,
+ 0x03A341C3, 0x0FC20001, 0x42A2FCAF, 0x4042F07A,
+ 0x714CC180, 0xC441716C, 0x00A009EA, 0x4042C440,
+ 0x714CC180, 0x00A009DE, 0x8D01706C, 0x08D58D40,
+ 0x784200A4, 0x2A922240, 0xC8086821, 0x7040240A,
+ 0x078020A8, 0x03012A40, 0x79057142, 0xB992B902,
+ 0xB99FB99C, 0xC1809180, 0x008321F4, 0x6479BCC5,
+ 0x08032142, 0x7930E120, 0x2714E1C0, 0x23CA2081,
+ 0xB1600025, 0x30812014, 0xB1607144, 0x8F21F042,
+ 0x097D8FA0, 0x49B00364, 0x40C36841, 0x12D98000,
+ 0x240A8880, 0x40A17080, 0x20A8DAC1, 0x0C0D0240,
+ 0x2714102E, 0xB3402003, 0xF02A7104, 0x800040C3,
+ 0x880012D9, 0x034E0847, 0x234027F4, 0x00600C26,
+ 0xCA05C182, 0xC082E805, 0x02200D4E, 0x16004123,
+ 0x80007080, 0x0819000D, 0x2214017E, 0x20322340,
+ 0x80000F81, 0x0D320470, 0xC0820220, 0x0A86C082,
+ 0x2014FF2F, 0x8F21334E, 0x71A5B600, 0x834509B1,
+ 0x78E0C7DA, 0x2840C2E2, 0x4200038C, 0x1F812405,
+ 0x0AB09004, 0x70EC9100, 0x0003204F, 0xB8A0B160,
+ 0x2A40B100, 0xC8080301, 0x69127905, 0x0F802005,
+ 0x0AB49004, 0x0B1D9060, 0x46600175, 0x208040C0,
+ 0x7825080A, 0xB892B802, 0xB89FB89C, 0x01071000,
+ 0x1F802405, 0x03549004, 0x16009000, 0x80007101,
+ 0x090D0006, 0x00000F84, 0x781D0A6B, 0x211F7910,
+ 0x20020180, 0xB80601C0, 0x00402805, 0x0804218A,
+ 0x0008252F, 0x7D104910, 0x01442053, 0x11832D41,
+ 0x039D41C3, 0x092A0006, 0x740CFF2F, 0xC6C240A1,
+ 0x01822053, 0x01C120AD, 0x7FE0A941, 0x78E0A900,
+ 0xC1A4C3F0, 0x40C34410, 0x12208000, 0x202F8820,
+ 0x41300502, 0xD940E903, 0xD925F002, 0x2044B99F,
+ 0x89000053, 0x00F1080F, 0x20002352, 0x04E0092E,
+ 0x09AA712C, 0x40C3FFCF, 0xC3500000, 0x02A00CF6,
+ 0x46CB732C, 0x11DA8000, 0x04E008BA, 0x244F2314,
+ 0x21122940, 0x67C870AD, 0x10250D2B, 0x24C02216,
+ 0xE02460B8, 0x208A60C9, 0x0A3A0004, 0x403004E0,
+ 0x23902840, 0x200571A5, 0x90042F81, 0xB1000230,
+ 0x45CBF1EB, 0x13880000, 0x0CAA40A1, 0xD90C02A0,
+ 0x04C008AA, 0x702CC808, 0xB802700E, 0x0F802005,
+ 0x0504901C, 0x00051800, 0x02A00C8A, 0x45CB40A1,
+ 0x4E748001, 0x091A40A1, 0xD91004A0, 0xD91040A1,
+ 0xFDAF0C36, 0x40A1DACF, 0x0C2ED910, 0xDAFFFDAF,
+ 0x04A00FCE, 0xC080C080, 0xFFAF0CAE, 0x4062D910,
+ 0x2582219F, 0x02C1209F, 0xC380704C, 0x70AC718C,
+ 0x60B97022, 0x06600CF2, 0x40C34082, 0x36B00000,
+ 0x02A00C32, 0x67C8D90A, 0x2216E812, 0x700224C0,
+ 0xE0247106, 0xB80E60C8, 0x0F812005, 0x02309004,
+ 0xB88C700C, 0x67C8B100, 0xA00408E3, 0x0A2A40A1,
+ 0xD9100420, 0x6832C808, 0x0F802105, 0xC0909007,
+ 0x0F812105, 0x00909004, 0x21049120, 0x00000F81,
+ 0xB020FEFF, 0x02A00B52, 0xC7D0D814, 0x46CBC2E8,
+ 0x01E8901C, 0x96A89620, 0x25464030, 0xB6081C00,
+ 0x0F802105, 0x0C300000, 0x1600B600, 0x80007080,
+ 0xE8360114, 0x750CD945, 0xFEEF0F86, 0xC808B910,
+ 0x726D702C, 0x710C68F2, 0x1600E807, 0x80007080,
+ 0xE8880025, 0x1600F020, 0x80007080, 0xE8200040,
+ 0x7180244A, 0x060020A8, 0x03802940, 0x800042C3,
+ 0x78E519AC, 0x004C22F4, 0x0F832005, 0x01C09000,
+ 0xE21CB380, 0x0F832005, 0x01B49000, 0x004022F4,
+ 0xB3007124, 0x238DD907, 0x700C16BF, 0x901C40C3,
+ 0x18000508, 0x18080005, 0x40C30005, 0x2AF80000,
+ 0x02A00B32, 0x1E00702C, 0xB6A81404, 0x78E0C6C8,
+ 0x1CFCC2FA, 0xC1A7B6C8, 0xD9894528, 0x4608B910,
+ 0xC344D8C8, 0xFEEF0EEA, 0xD8C8C243, 0xD98BED04,
+ 0xF004B910, 0xB911D945, 0xFECF0ED6, 0xC18640A1,
+ 0x35C22440, 0x00A00BB2, 0x35832440, 0xEE05D8C8,
+ 0xB910D98D, 0xD923F003, 0x0EB6B912, 0xC006FECF,
+ 0x008E45CB, 0x41A10001, 0xD8C8C041, 0xFEEF0EA2,
+ 0x1417C201, 0x254F3080, 0xC0401401, 0x0E92D8C8,
+ 0xC200FEEF, 0x30801416, 0x009046CB, 0x41C10001,
+ 0xD8C8C042, 0xFEEF0E7A, 0xC203C202, 0x1401264F,
+ 0xFEEF0E6E, 0xDD20D8C8, 0x144F264F, 0xD8C8BD9F,
+ 0x0E5E41E1, 0x1501FEEF, 0x8D401482, 0x1401274F,
+ 0xFEEF0E4E, 0x15F6D8C8, 0x264F9082, 0xD8C8148F,
+ 0xFEEF0E3E, 0x15F741E1, 0x274F9082, 0x0E321401,
+ 0xD8C8FEEF, 0xBF918D44, 0x0E26D8C8, 0x41E1FEEF,
+ 0x274F8D5F, 0x0E1A1401, 0xD8C8FEEF, 0xD8C8BE93,
+ 0x0E0E41C1, 0xDA0AFEEF, 0x1401264F, 0x0E02D8C8,
+ 0x744CFEEF, 0xD8C8D94D, 0xFEEF0DF6, 0xC001B911,
+ 0x01427014, 0x704E002C, 0x47D3C000, 0x0A3C0000,
+ 0x05C2201F, 0x20C12F40, 0x46D3C004, 0x1A3C8000,
+ 0x0059201F, 0x20902640, 0x22007223, 0x20000595,
+ 0xC1002090, 0x7110C002, 0x002D00F0, 0x2540230A,
+ 0x240AC600, 0xC0032400, 0x04A00F3A, 0x431879CF,
+ 0x0BC1702E, 0xD8C8346E, 0x4342C204, 0x009B41C3,
+ 0x44C10004, 0xFEEF0D8A, 0x0440250A, 0xD8C8D927,
+ 0xFEEF0D7E, 0x70ADB912, 0x34C0200A, 0x1704478A,
+ 0xD8C81503, 0x35021004, 0x009D41C3, 0x0D620003,
+ 0x44A1FEEF, 0xE5C071A5, 0xDD4FF7B3, 0xBD11D8C8,
+ 0xFEEF0D4E, 0x254F41A1, 0x0D461401, 0xD8C8FEEF,
+ 0xD8C8752C, 0xFEEF0D3A, 0x221AB915, 0x00002F81,
+ 0x261A28F0, 0x452A15C0, 0x1184259A, 0x800047CB,
+ 0x71231B3E, 0x0A466038, 0x651D0620, 0x260065EB,
+ 0x65FD2341, 0x07021180, 0x11041502, 0xBB22E807,
+ 0x41C3D8C8, 0x000300A1, 0xD8C8F005, 0x00A241C3,
+ 0x0CEE0003, 0xD9A3FECF, 0x0CE6D8C8, 0xB910FEEF,
+ 0x23807126, 0x093F2184, 0x2480A2B4, 0xC0022184,
+ 0x07267610, 0x71C5FFE5, 0x000040C3, 0x250028F0,
+ 0x20002015, 0x71462010, 0x220CC001, 0x06F6A000,
+ 0xD929FFCB, 0x0CAAD8C8, 0xB912FEEF, 0x1404C0A7,
+ 0xC6DA341B, 0xC1A2C3F0, 0x40C34310, 0x12258000,
+ 0x800041D3, 0x88000025, 0x11004748, 0x4628208C,
+ 0x30021C03, 0xC181710C, 0x30C22440, 0x00A0095A,
+ 0x30C32440, 0x30121404, 0x10C02478, 0x20087104,
+ 0x084F0490, 0x44102072, 0x0B1170AD, 0x740C2030,
+ 0x00AA41C3, 0xF0050003, 0x00A941C3, 0x42A10003,
+ 0x0C3E43A1, 0x44C1FEEF, 0x15250D11, 0x41C1700C,
+ 0x0E8642E1, 0x43A1FF2F, 0x14A30D11, 0x41C1710C,
+ 0x0E7642E1, 0x43A1FF2F, 0x0DC371A5, 0x11E59404,
+ 0x081FA080, 0x4062003E, 0x42C1702C, 0xFFEF0D06,
+ 0x406243E1, 0x42C1712C, 0xFFEF0CFA, 0xC7D043E1,
+ 0x2482C3F2, 0x42203608, 0x740C4210, 0x021741C3,
+ 0x0BDE0001, 0x4450FEEF, 0xC1804042, 0xFE2F0EEA,
+ 0x35C22440, 0x003108B5, 0xC0864708, 0x00200902,
+ 0xC0204142, 0xC2864182, 0x0D1A4342, 0x4110FE2F,
+ 0x70CD4510, 0x70ED454A, 0x200A706E, 0xE7C02440,
+ 0x9500F755, 0x0505081F, 0x0C1B9501, 0x78CF2025,
+ 0xC2864182, 0xFE2F0CEE, 0x0B0B4342, 0x43102005,
+ 0xE60840D1, 0xE708E520, 0x74EDF1EB, 0x2000740C,
+ 0x4508200E, 0xE0BF78CF, 0x4182F70A, 0x0CC6C286,
+ 0x4342FE2F, 0x20050B09, 0x40D14310, 0x234E2002,
+ 0xE0BF78CF, 0x4182F70A, 0x0CAAC286, 0x4342FE2F,
+ 0x20050B09, 0x40D14310, 0x91350DC7, 0x0B1D78BD,
+ 0x230C2030, 0x1A82A540, 0x21CA251C, 0x22802402,
+ 0x70ED2084, 0x24421A00, 0xC7D240E1, 0x4010C2E8,
+ 0xB8226901, 0x20494528, 0x46CB0FCF, 0x00020218,
+ 0x41C1740C, 0x0AFA42A1, 0x43E1FEEF, 0x23C02015,
+ 0x90419060, 0x00E50A13, 0x1401264F, 0x0AE2740C,
+ 0x74ADFEEF, 0x4002F00A, 0x2080627A, 0xA8A00084,
+ 0x70AD785D, 0x201C1882, 0xC6C840A1, 0x2155C0E6,
+ 0x248A0F8E, 0x708D7001, 0x238A704C, 0x20A80FC7,
+ 0x20160280, 0x7144008F, 0xB762B783, 0xB760B781,
+ 0x2115716D, 0x234002CC, 0x94401048, 0x0D3794A1,
+ 0x211510A5, 0x93A00203, 0x0A119341, 0x20160364,
+ 0xB2A002C2, 0xB2619361, 0x910214FC, 0x910314FE,
+ 0x00A40B65, 0x02C32016, 0x14FEB340, 0xB3419102,
+ 0x2016F02A, 0x774402CD, 0x9340B541, 0x232F7144,
+ 0x14FC1088, 0x71449102, 0x22097A50, 0xB54002C2,
+ 0x1086232F, 0x23099C40, 0x77441082, 0x9441B540,
+ 0xB5427144, 0x77449341, 0x14FE7B50, 0x77449102,
+ 0x22087A50, 0xB54300C2, 0x9C417B4E, 0x00822308,
+ 0xB5437144, 0x9FF4086F, 0x1200230A, 0x91619140,
+ 0x00A50B17, 0x91427744, 0x0B3B9163, 0xB0400084,
+ 0xB0419143, 0xB041F017, 0x71449142, 0x7B4EB040,
+ 0x23099940, 0x77440082, 0x9141B040, 0xB0427144,
+ 0x77449143, 0x7B4EB043, 0x23089941, 0x71440082,
+ 0x9642B043, 0x010311FE, 0x00A50B1B, 0x96407744,
+ 0x010311FA, 0x00840B41, 0x11FAB740, 0xB7210101,
+ 0xB741F01A, 0x71449640, 0x7B4EB740, 0x23099E42,
+ 0x77440082, 0x11FEB740, 0x71440102, 0x11FAB742,
+ 0x77440102, 0x7A4EB743, 0x014111FE, 0x00412208,
+ 0xB7237124, 0x7F80244A, 0x034020A8, 0x09159024,
+ 0x00000F81, 0x218AFFFF, 0x180A0FC7, 0xB0240005,
+ 0xC4C6E008, 0x1CFCC2FA, 0x1600B6C8, 0x8000708F,
+ 0x46CB1222, 0x1A3E8000, 0x2100270A, 0x41584078,
+ 0x46104338, 0x10912642, 0x70801600, 0x12238000,
+ 0x01507710, 0x40C3000D, 0x12D98000, 0x20118800,
+ 0xF29E83C0, 0x091370AD, 0x27003031, 0x101C1680,
+ 0x75100080, 0x0D0BF290, 0x70171271, 0x248AF28C,
+ 0x70EC7001, 0x706D700D, 0x70CC702D, 0x20A8706C,
+ 0x40C30D00, 0x28F00000, 0x261F791B, 0x231F2002,
+ 0xB8223041, 0x615978EC, 0x40A1611A, 0x0184209A,
+ 0x20156058, 0x213401C0, 0x60D0200C, 0x03250829,
+ 0xEB174050, 0x02C7222F, 0x0207212F, 0x222F4953,
+ 0x212F0187, 0x79420247, 0x23CA7170, 0x20CA1189,
+ 0xF0071249, 0x26CA7074, 0x210A01C1, 0x203D11C0,
+ 0x71E40303, 0x02C7212F, 0x0207202F, 0x212F4832,
+ 0x202F0187, 0x78220247, 0x23CA7050, 0x20CA118A,
+ 0x222F124A, 0x232F22C7, 0x23002207, 0x0F472480,
+ 0x242F2030, 0x0D762002, 0xE80D05C0, 0x209A40A1,
+ 0x70020184, 0x05002015, 0x20012134, 0x782260D0,
+ 0x2302F003, 0x120B2480, 0x252F3086, 0x253F0006,
+ 0x41C30180, 0x00050237, 0x43E142C2, 0xFC6F0D1A,
+ 0x40A144A1, 0x0184209A, 0x20102000, 0x18002656,
+ 0x0D2A7002, 0x180005E0, 0xE80E0502, 0x25002015,
+ 0x213460D1, 0x60382000, 0x2000791D, 0x80002F80,
+ 0xB0201B40, 0xE58A71A5, 0xFFC506CE, 0xF15671E5,
+ 0x341B1404, 0x78E0C6DA, 0x7034C2E6, 0x03012A40,
+ 0x79654608, 0x47CBC808, 0x00409004, 0x27C07825,
+ 0x28401222, 0xE688008B, 0x404846C1, 0x026126CA,
+ 0x000045CB, 0x702DFFFF, 0x706C708D, 0x01A50B37,
+ 0x0E137890, 0x20001275, 0x101C1680, 0x0B1F0080,
+ 0x21050000, 0x78E512C0, 0xFEEF0842, 0x79B09000,
+ 0x004D2009, 0x20087990, 0x2180004C, 0x71641010,
+ 0x79B0F1E6, 0x781D6038, 0x78E0C6C6, 0x44CBC0E6,
+ 0x12228000, 0x108814B7, 0x14008CE1, 0x0F9B1086,
+ 0x08931184, 0x244A11AE, 0x265A7280, 0x20A8028B,
+ 0x446900C1, 0x800045CB, 0x249AC144, 0x2432100E,
+ 0x80001F89, 0x0927C444, 0x659E10F0, 0x10B00915,
+ 0x7135659E, 0x702D70EC, 0x2434F417, 0xF0131347,
+ 0x13472434, 0x11091602, 0x2434F00F, 0x16021347,
+ 0xDD801109, 0x21029682, 0x7D8211C4, 0x03450C0B,
+ 0x218A4781, 0x21001002, 0x211411CC, 0x7E9D02CD,
+ 0x018C20F4, 0xB58064DC, 0x02CD2214, 0x018C20F4,
+ 0xB58074E0, 0x02CD2314, 0x018C20F4, 0x74217165,
+ 0x71C4B580, 0xC4C6F1B5, 0x706CC0F1, 0x2240DC3F,
+ 0x248A008B, 0x18007001, 0xA9800003, 0x01C020A8,
+ 0x15081304, 0x10110809, 0xF0037164, 0x2280A860,
+ 0x248A0F83, 0x20A87001, 0x12FC01C0, 0xEB858503,
+ 0x89807785, 0xA980F002, 0x7B8F8840, 0xCA0B4B51,
+ 0x44207110, 0xF649700C, 0x021D41C3, 0x0E520003,
+ 0xD8C9FEAF, 0xC0D1760C, 0x78E07EE0, 0x7002248A,
+ 0x20A8706C, 0x41000480, 0x0182235A, 0x000E219A,
+ 0x41C3623A, 0xC1448000, 0x61596234, 0x090D9121,
+ 0x71640305, 0xD8807FE0, 0x786F7FE0, 0xF717E1FF,
+ 0x7A22DA80, 0x7080240A, 0x044020A8, 0x215A4200,
+ 0x229A0183, 0x635B000E, 0x800042C3, 0x6354C144,
+ 0x9241627A, 0x03040A09, 0xD9807124, 0x78307FE0,
+ 0x01422053, 0xA941B826, 0xA9007FE0, 0xC1A3C3EC,
+ 0x700C4210, 0x458B4130, 0xB504B505, 0x018D41C3,
+ 0xB5030000, 0x0DBAB502, 0x740CFEAF, 0x4122710C,
+ 0x32822440, 0x00200F26, 0x31832440, 0x4122700C,
+ 0x0F1AC282, 0xC3810020, 0x3140140A, 0x2042D980,
+ 0x40C38443, 0x12208000, 0x23CA9582, 0x8840002C,
+ 0xE411E4EE, 0x24CA95E4, 0x1406104D, 0x7E703110,
+ 0x740C7D90, 0x018E41C3, 0x43420007, 0x45C1718C,
+ 0x0400260A, 0x0D5A47E1, 0xC540FEAF, 0x13840D1B,
+ 0x23E40817, 0x27CC7512, 0xF7599385, 0x41224042,
+ 0x43E1704C, 0x4042F00D, 0x704C4122, 0x44A143E1,
+ 0xFCAF0B4A, 0x404270AC, 0x704C4122, 0x240A43C1,
+ 0x0B3A0400, 0x71ACFCAF, 0x0E15C7CC, 0x0DEB13C5,
+ 0x40429424, 0x704C4122, 0xF00F43C1, 0x14250D13,
+ 0x41C3740C, 0x0000018F, 0xFE8F0CF6, 0x4042C7CC,
+ 0x704C4122, 0x44A143E1, 0x78E0F1E5, 0x800042C3,
+ 0x24AA0450, 0x21AA1144, 0x82610104, 0x200E8200,
+ 0xA2008040, 0x90C12403, 0xA2217FE0, 0x1CFCC2FA,
+ 0xC1B6B6C8, 0x800046CB, 0x8EA01222, 0x780F4310,
+ 0x714CC180, 0x1C04706C, 0x24403001, 0x0BE63019,
+ 0x1C000020, 0x23403001, 0x23402A18, 0x09D62A9B,
+ 0x255F03A0, 0x16001251, 0x272F1092, 0x8E011487,
+ 0x03E40885, 0x2F412354, 0x33CD21F4, 0x41C3740C,
+ 0x000103EA, 0xFEAF0C6A, 0x2F4042A1, 0xC8081315,
+ 0x26C12505, 0x900447CB, 0x78250000, 0xB802708E,
+ 0x2440270A, 0x902078E5, 0x01502153, 0xE5207502,
+ 0x2348262F, 0x05C7222F, 0x7854C082, 0x03EB41C3,
+ 0x43020004, 0xB0A04440, 0x0C26740C, 0x250AFEAF,
+ 0x71860580, 0x0507202F, 0x827408DD, 0x250571E6,
+ 0xC8082601, 0x21007825, 0xB8022511, 0x78E57146,
+ 0xF1BDB0A0, 0x7825C808, 0x714CC182, 0x708C706C,
+ 0x06200D7E, 0xC0B670AC, 0x341B1404, 0x78E0C6DA,
+ 0xD820C2E2, 0x900745CB, 0x1D00C40C, 0x0F6A1045,
+ 0x1D000220, 0xD8201005, 0x02200F5E, 0x10451D00,
+ 0x10051D00, 0x78E0C6C2, 0x803C2042, 0x42C3F208,
+ 0x12EA8000, 0x010020A8, 0x00521A14, 0x06200475,
+ 0x78E0712C, 0x2482C3EA, 0x45083212, 0x38802455,
+ 0x0BAE702C, 0x228AFC2F, 0x710C0010, 0xB80278B8,
+ 0x00200E42, 0x0350200F, 0x00200E46, 0x07912040,
+ 0x8E82208C, 0xDEFE70ED, 0x0E36F705, 0x20540000,
+ 0x740C088E, 0x040841C3, 0x714C0002, 0xFEAF0B52,
+ 0x120843A1, 0xC084360D, 0x800041C3, 0x0B4A1042,
+ 0xDA78FC2F, 0x0BC6C084, 0xD9780620, 0x1E00D80F,
+ 0x900773C4, 0x0FDEC29C, 0xD90FFDAF, 0x212F78CF,
+ 0x0FA60447, 0x222F0160, 0x25050407, 0x00011F90,
+ 0x45CB002A, 0x12228000, 0x8D208D01, 0x00640829,
+ 0xB90E7822, 0x28407104, 0x240A2082, 0x20A87000,
+ 0x22050300, 0x71C30040, 0x40000000, 0xB89FB89C,
+ 0x00051800, 0xD80F70CD, 0xFDAF0F8A, 0x700CD90F,
+ 0xFCEF0DDA, 0x8D01712C, 0x77108DE0, 0x002D006C,
+ 0x106D26C0, 0x712C78E2, 0x26046861, 0x00001F82,
+ 0x2653FFF8, 0xBA231080, 0x71C57918, 0x70C0240A,
+ 0x090020A8, 0x13032F40, 0x73C026F4, 0x048C8000,
+ 0x2F407865, 0xB802120C, 0x0F802005, 0x02DC9004,
+ 0x010B1000, 0x38802455, 0x70756098, 0x8C00605C,
+ 0x004220C5, 0x7826F402, 0x04032305, 0x6B12AC00,
+ 0xB89C71E5, 0xB0C0B89F, 0x03400F9A, 0x087B78D0,
+ 0x00008F84, 0x8DC00800, 0x8D01700E, 0x03A408DD,
+ 0x41C3740C, 0x00010409, 0xFEAF0A36, 0x702E42C1,
+ 0xAFDF218C, 0x002D00B6, 0x218B740C, 0x1C0CA803,
+ 0x1C083400, 0xF4123400, 0x28002156, 0x21822941,
+ 0x0F802004, 0xFFC00000, 0x41C3B826, 0x0002040A,
+ 0x09FE6869, 0x740CFEAF, 0x70CCDF08, 0xC282706C,
+ 0x627A708D, 0x00892653, 0x7100244A, 0x200A736D,
+ 0x1A001440, 0x20A80003, 0x2E400500, 0x24551200,
+ 0x61193881, 0x10C02841, 0x61087105, 0x02402801,
+ 0xB8C07125, 0x02C02800, 0x7C057765, 0x00862652,
+ 0x71647426, 0x177F278D, 0x140DAA80, 0x140B3087,
+ 0x140C3085, 0x140A3086, 0xC2223084, 0x30831409,
+ 0x3081140E, 0x3080140F, 0x41C3C140, 0x0008040B,
+ 0x097EC041, 0x740CFEAF, 0x41C3F1A4, 0x0000040C,
+ 0xFE8F096E, 0xF19371C5, 0x78E0C7CA, 0x082E43E3,
+ 0x20780000, 0x16000001, 0x80007080, 0x08110008,
+ 0x217800B1, 0xB8020000, 0x7B007404, 0x00002178,
+ 0x7204781B, 0x78E07B00, 0x800040C3, 0x88201220,
+ 0x219F8841, 0x229F0582, 0x10BC02C1, 0x60380000,
+ 0x8A03621A, 0x86002044, 0x02002078, 0x20CA7FE0,
+ 0x78E000A1, 0x244AC5E1, 0x706C71C0, 0x702C704C,
+ 0x900C44CB, 0x20A80240, 0x21050280, 0x7424030D,
+ 0x651D95A0, 0x7144AD40, 0x70811600, 0x00408000,
+ 0x244AE90E, 0x704C71C0, 0x028020A8, 0x1381244F,
+ 0x74447945, 0x61199120, 0x7164A967, 0x78E0C4C2,
+ 0x4310C2F2, 0x4570710C, 0x42304450, 0xFCAF0A92,
+ 0x04CD2800, 0x10512553, 0xD90B700C, 0x706C704C,
+ 0x250A708C, 0x0BF60440, 0x70CCFCEF, 0xD9FF700C,
+ 0xFCEF0EDE, 0x6D12704C, 0x200F762C, 0xDA2204C0,
+ 0x700C7E0F, 0x20300D1D, 0x244ADB40, 0x45C10A00,
+ 0xFCEF0BCA, 0xD88070CC, 0x744CD919, 0xF00CDB83,
+ 0x0940244A, 0x0BB645C1, 0x70CCFCEF, 0xD919D880,
+ 0xDB81744C, 0x250A708C, 0x0BA20440, 0x70CCFCEF,
+ 0x0B4A700C, 0x712CFCEF, 0x0BCE700C, 0xB88B0220,
+ 0x000040C3, 0x0C4E9C40, 0xD9080220, 0x20300D0B,
+ 0xD92640C1, 0xD923F002, 0xFE8F0F7A, 0x800047CB,
+ 0x8FA01222, 0x082B8F01, 0x79AF0344, 0x0C4E4062,
+ 0x403000A0, 0x4002E809, 0x0F9A742C, 0x42620360,
+ 0x23412214, 0x8F01B100, 0x71A57510, 0x0D0DF7AF,
+ 0x40C12030, 0xF003D927, 0x0F3AD924, 0x8FA0FE8F,
+ 0x0B7D8F61, 0x7EAF0364, 0x0C124062, 0x41C100A0,
+ 0x40C1E834, 0x0F5E742C, 0x42620360, 0x22F4B808,
+ 0x22142341, 0x78252342, 0x1600B200, 0x80007101,
+ 0x218C0006, 0xF70581C3, 0x00451A00, 0x7810F004,
+ 0x0095080D, 0x000040C3, 0xF009FFFF, 0x70811600,
+ 0x00088000, 0x2905B911, 0xB2000000, 0x0D117B10,
+ 0x740C2030, 0x035941C3, 0xF0050002, 0x035A41C3,
+ 0x0F5E0002, 0x42A1FE6F, 0xF1C471A5, 0x0B298FA0,
+ 0x79AF0364, 0x00A00B96, 0xE88B4062, 0x103F0D0D,
+ 0x23402214, 0xF0049021, 0x810110FE, 0x8F61B020,
+ 0xF1EF71A5, 0x0B438F40, 0x0C3F0084, 0x23782030,
+ 0x0D0F2000, 0x20782030, 0x48AC0000, 0x489CF002,
+ 0x68614B50, 0x7825C808, 0x70C0240A, 0x20A86892,
+ 0x2A400340, 0x22F40380, 0x78852081, 0xB8927144,
+ 0xB89FB89C, 0x08CAB020, 0x700CFC8F, 0x744CD90C,
+ 0x708C706C, 0x0440250A, 0xFCEF0A32, 0x700C70CC,
+ 0x764CD907, 0x708C706C, 0x0A2270AC, 0x268AFCEF,
+ 0x700C0FC3, 0x744CD910, 0x708C706C, 0x0440250A,
+ 0xFCEF0A0A, 0xD88070CC, 0x764CD907, 0x708C706C,
+ 0x09FA70AC, 0x268AFCEF, 0x700C0FC3, 0xFCEF099E,
+ 0x0832712C, 0xC6D203C0, 0xC1A4C3EA, 0x45484668,
+ 0x41104030, 0x0F9770ED, 0x244A11F5, 0x40C37200,
+ 0x12208000, 0x20300935, 0x704C8820, 0x20A8706C,
+ 0x40200540, 0x209F6F95, 0x70020803, 0x2B41641C,
+ 0x640C00C0, 0x01802344, 0x01C02047, 0x102E0C3B,
+ 0xE212C080, 0xF029E312, 0xDA7EDBFE, 0x050020A8,
+ 0x6F954020, 0x0803209F, 0x641C7002, 0x00C02B41,
+ 0x2344640C, 0x20470180, 0x0C1901C0, 0xC080102E,
+ 0xBB72BA72, 0x41C3F011, 0x00020183, 0xF00878F4,
+ 0x003E2380, 0x41C378F4, 0x00020184, 0x740CB040,
+ 0xFE6F0DEE, 0x71E542E1, 0x1400F1B7, 0x244A3100,
+ 0xC28071C0, 0xB600B500, 0x038020A8, 0x05011202,
+ 0x090B9560, 0xB52000C5, 0x080B9600, 0x40200045,
+ 0x78E0B620, 0x78E0C7CA, 0xE808702C, 0x8002222F,
+ 0x6119B8C0, 0xF5FC4040, 0x78307FE0, 0x71001600,
+ 0x02909008, 0x78E07EE0, 0x0872C2E2, 0x08C6FD8F,
+ 0x4508FDAF, 0x70811600, 0x001C8000, 0xE80CE906,
+ 0xD87DED8B, 0xF019B807, 0xED8CE80B, 0x000040C3,
+ 0xF0134650, 0x40C3ED0A, 0x4A380000, 0xED0AF00D,
+ 0x000040C3, 0xF0095208, 0x000040C3, 0xF0052EE0,
+ 0x000040C3, 0x097E36B0, 0x742C0220, 0xC6C2780F,
+ 0x800040C3, 0x051D12DC, 0x8000FC6F, 0x45CBC2E4,
+ 0x12208000, 0x8D218D00, 0x0582209F, 0x02C1219F,
+ 0x100215BC, 0x60386058, 0xB8248801, 0xFC6F0EE6,
+ 0x058E205F, 0x00832079, 0x8D418D00, 0x0582209F,
+ 0x02C1229F, 0x100115BC, 0x0285239F, 0x60586038,
+ 0x63DB8803, 0xD80AB8E5, 0x022120CA, 0x2332631B,
+ 0x80000F80, 0xC6C407E0, 0x40C3C2E2, 0x12208000,
+ 0x88418820, 0x0582219F, 0x02C1229F, 0x000010BC,
+ 0x621A6038, 0xB8C38A02, 0xFC6F0E8A, 0x038D205F,
+ 0x00812079, 0x800040C3, 0x219F0646, 0x61B90483,
+ 0x60386112, 0x621A9001, 0xC6C27850, 0x4568C2E8,
+ 0x4050DB7F, 0x44604220, 0x248AE983, 0x8D850FC7,
+ 0x11041D06, 0xEA14E80E, 0x70811600, 0x01468000,
+ 0x40C3E91E, 0x01408000, 0xB5268861, 0xF0158820,
+ 0x1D08710C, 0xB8901001, 0xC6C8A503, 0x20100831,
+ 0x71011600, 0x01428000, 0x40C3E92E, 0x01388000,
+ 0xB5269062, 0xB5249020, 0xF031B565, 0x11041D0A,
+ 0x10051D08, 0x1D0CEC2A, 0xF0291085, 0x71011600,
+ 0x01448000, 0x40C3E918, 0x013E8000, 0x10FC9060,
+ 0xB5268100, 0xB504B565, 0x70801600, 0x000B8000,
+ 0x017E082B, 0x8008238C, 0x10051D08, 0x238AF78F,
+ 0xF1DC0FC7, 0x0FC7238A, 0x11041D0A, 0x10051D08,
+ 0x1D0CEC04, 0xF0031205, 0x41C3B506, 0x00030227,
+ 0xFC2F08D6, 0x00C0243D, 0x1104150C, 0x0400250A,
+ 0x95059544, 0x1D0E4851, 0x29081104, 0x78220101,
+ 0x022841C3, 0xB5050004, 0x0BA67B10, 0x740CFE6F,
+ 0x78E0C6C8, 0x084BC5E1, 0x712D00B5, 0x2078DD25,
+ 0xBD9F0008, 0x8D8D700C, 0x10F00C0F, 0x2444716D,
+ 0x20521040, 0x7015000B, 0x20CA8D80, 0xA90002C1,
+ 0x10002900, 0x7C0BAA00, 0x700C712C, 0xAB20F207,
+ 0x800041C3, 0x702D1220, 0x4021A900, 0xDD40C4C2,
+ 0x00882078, 0x700CBD9F, 0x0C118D8D, 0x716D10F0,
+ 0x10402444, 0x000B2052, 0x8D807015, 0x02C120CA,
+ 0x2900A900, 0xAA001000, 0x722C7C0B, 0xF5E1710C,
+ 0x78E0F1E5, 0x00700821, 0x7DE07014, 0x70801600,
+ 0x00258000, 0x00C02078, 0xA1007104, 0x800040C3,
+ 0xF0151224, 0x70801600, 0x00408000, 0x0050080F,
+ 0x00D10811, 0x00811900, 0x1900F006, 0xF0040041,
+ 0x00011900, 0x800040C3, 0x88201226, 0x8801AA20,
+ 0xAB007FE0, 0x0883C2E2, 0x45080030, 0x71021600,
+ 0x00148000, 0x00CF41C3, 0x0AB60001, 0xD8FFFE6F,
+ 0x08676D09, 0x120D01D5, 0x120B3083, 0x120C3604,
+ 0x20253605, 0xF0080000, 0xF010F00B, 0xF018F013,
+ 0xF024F01B, 0x41C3700C, 0x000300D0, 0x700CF022,
+ 0x00D141C3, 0xF01E0003, 0x41C3700C, 0x000300D2,
+ 0x700CF018, 0x00D341C3, 0xF0140003, 0x41C3700C,
+ 0x000300D4, 0x120BF00E, 0x41C33082, 0x000400D5,
+ 0xFBEF0F56, 0xC6C2700C, 0x41C3700C, 0x000300D6,
+ 0x43804260, 0xFBEF0F42, 0x0140240A, 0x78E0C6C2,
+ 0x000043CB, 0x242F28F0, 0x201F12C0, 0x7B8A02C0,
+ 0x108B2B41, 0x02C1211F, 0x0184229F, 0x60386078,
+ 0x42C36058, 0x1A3E8000, 0x08012256, 0x78356029,
+ 0x61116A2A, 0x48326050, 0x71447030, 0x002522CA,
+ 0x78507FE0, 0x1CFCC2FA, 0xC1A6B6C8, 0x16004608,
+ 0x80007100, 0x4528000A, 0xC3414358, 0x781DC043,
+ 0x87812044, 0xC045710C, 0xC042D810, 0x090DF207,
+ 0x700C00B1, 0xF003C045, 0x208AC142, 0xB6010004,
+ 0xAE00D820, 0x081FC003, 0xD8C8007E, 0x8D409561,
+ 0x021A41C3, 0x121C0004, 0x09963705, 0x121DFE6F,
+ 0x8D003704, 0xC2014363, 0x95E14210, 0x0AE641E1,
+ 0x41F1FDAF, 0xC0034010, 0x007E081D, 0x9561D8C8,
+ 0x41C38D40, 0x0004021B, 0x0400240A, 0xFE6F0962,
+ 0x0400250A, 0x7014C002, 0x7216F2BC, 0x00250174,
+ 0xC002746E, 0x70CE8DE0, 0xB82295A1, 0x1410C044,
+ 0x22003015, 0x240A24C0, 0x210A2440, 0x20533400,
+ 0x22020150, 0x0D1124C0, 0x20531521, 0x0F1B0151,
+ 0x70EE1460, 0x4022C201, 0x0A7A4182, 0x4363FDAF,
+ 0x15210D0B, 0x0F254710, 0xC2011400, 0x41824002,
+ 0xFDAF0A62, 0x0F154363, 0x081F2005, 0x47100664,
+ 0x220A474A, 0xF00B2400, 0xA640270C, 0x148627CA,
+ 0x244622CA, 0x270AF743, 0x24002640, 0x240224C0,
+ 0x205324D1, 0x21530218, 0x77522211, 0x944125CC,
+ 0x0D21F405, 0x700E1621, 0xC201F01B, 0x41224042,
+ 0xFDAF0A12, 0x40104363, 0x25CC7752, 0xF2119601,
+ 0x4042C201, 0x09FE4103, 0x4363FDAF, 0x20050813,
+ 0x05E40819, 0x2600210A, 0x4010458A, 0x200CF00A,
+ 0x25CAA5C0, 0xF7461506, 0x2500210A, 0x25C0200A,
+ 0x26610817, 0x30141410, 0xF547262F, 0x2542F204,
+ 0xF0032054, 0xC003708E, 0x007E082D, 0x2507252F,
+ 0x41C3D8C8, 0x0007021C, 0x434242C2, 0x0440240A,
+ 0x0400250A, 0x0400260A, 0x04C0270A, 0xFE6F0832,
+ 0x35401C00, 0x08178E00, 0x0D170481, 0x96012010,
+ 0x0440080F, 0x2500250A, 0x0DFDF012, 0x1410A011,
+ 0x202F3015, 0x431084C2, 0x716EF404, 0x2500250A,
+ 0x00012079, 0x2005C005, 0xF20C807E, 0xC00271C6,
+ 0xA000260C, 0x14441E02, 0xFFE506AA, 0x14821E00,
+ 0xC0A64002, 0x341B1404, 0x78E0C6DA, 0x44CBC0E6,
+ 0x12D98000, 0x8C204028, 0x7100244A, 0x70AD70CD,
+ 0x20A8708D, 0x091B0240, 0x7185030F, 0x000075C3,
+ 0x702C8000, 0x900345CB, 0x706DC000, 0x6892F015,
+ 0x10812800, 0x79647D85, 0x1F8C2505, 0x00009038,
+ 0x25059480, 0x903B1F8D, 0x2406C000, 0x7C6410CF,
+ 0x2C0179E5, 0x0C43108B, 0xB5200031, 0x708C1600,
+ 0x00258000, 0x1600EC88, 0x8000708C, 0xEC140040,
+ 0xBE0CDE07, 0x28007E05, 0x6E52108C, 0x22057C64,
+ 0x90000F81, 0x91200000, 0x0F8D2205, 0xC0009003,
+ 0x79857966, 0x4061B520, 0x78E0C4C6, 0x1CFCC2FA,
+ 0xC1ADB6C8, 0x4210C71D, 0x70801600, 0x00148000,
+ 0x21C0200A, 0x41384150, 0x700F70EE, 0x31801C2C,
+ 0x31401C04, 0x31001C28, 0x013E081B, 0x1600C349,
+ 0x80007080, 0x080F001E, 0x710F003F, 0x05400C5A,
+ 0x97C44018, 0x20C02242, 0x0175082F, 0x0D8297A1,
+ 0xE815FE4F, 0x800040C3, 0x88411222, 0x0A1F8800,
+ 0x790F0004, 0x27147104, 0x19241041, 0x790F05C4,
+ 0x80450AF3, 0x0ADBF003, 0x2178A050, 0xD80930D2,
+ 0x30F10911, 0xD80AC040, 0x3240234A, 0xF003C040,
+ 0x0842706F, 0x0E360380, 0xD8C8FCAF, 0xFCAF0E3E,
+ 0x7056970E, 0x900446D3, 0x40C33DD0, 0x01D09004,
+ 0x200226CA, 0x3031080D, 0x2004258A, 0x2002258A,
+ 0x2538C01C, 0x704E1393, 0x800044D3, 0xC04C1222,
+ 0x30002150, 0x40C3C045, 0x28F00000, 0x2001211F,
+ 0x201F781B, 0x60382000, 0x4063C043, 0x0184209F,
+ 0x6038C103, 0x0F812000, 0x1A3C8000, 0x800070C3,
+ 0xC0481A3E, 0xC042720C, 0x30802178, 0xC1477204,
+ 0x710CC046, 0x45CBC044, 0xC2CC9007, 0x20300A1D,
+ 0x0FC7208A, 0x732EB500, 0x15C41D04, 0x0819C005,
+ 0x97C800B1, 0xF009BE07, 0x712E70CD, 0x15C41D00,
+ 0xF003B502, 0x1400BE08, 0x14012090, 0x202F208B,
+ 0x0B930407, 0x43A21024, 0x70811600, 0x12D98000,
+ 0x002E097F, 0x10012714, 0x038B2840, 0x1F822305,
+ 0x3ED49004, 0xB90A9132, 0x04412105, 0xC109B220,
+ 0x000021F4, 0x30300829, 0x0A1960D8, 0x79102030,
+ 0x08002155, 0x0FCF218A, 0x8FCF208C, 0xF009F7C8,
+ 0x8002218C, 0xF785702C, 0x003E2080, 0x23054100,
+ 0xB0201580, 0xE815CC20, 0x712CD840, 0x15C41D00,
+ 0x03E009E6, 0x15C41D04, 0x70801600, 0x00088000,
+ 0xD8407414, 0x20CAD944, 0x1DF40041, 0x71069004,
+ 0xCC20F1B5, 0xC106E827, 0x20032D01, 0x00412800,
+ 0x1400633B, 0x0B3F2081, 0x16001044, 0x80007088,
+ 0x782F12D9, 0x102E0827, 0x2005B80E, 0x90040F82,
+ 0x9200029C, 0x05C41A00, 0x0F8C2004, 0x1FFE0000,
+ 0xB80DCC20, 0xBC807C05, 0x7124B280, 0x0BD7782F,
+ 0x78709005, 0xFCAF082E, 0x7076702C, 0x14B7F26F,
+ 0x14012088, 0x8F05208B, 0x208E1400, 0x268AE82E,
+ 0x7BCF0FC7, 0x10C40BC5, 0x10CE084D, 0x0F82231F,
+ 0x0A3C0000, 0xC008C407, 0x621A645C, 0xC1004063,
+ 0x00450835, 0xE988C101, 0x06812300, 0x0081111C,
+ 0x00400819, 0x7001248A, 0x41404189, 0x018020A8,
+ 0x00151904, 0x11941904, 0x11842480, 0x01842280,
+ 0xF1E77104, 0xF1D771C5, 0x128D265F, 0x7ACF7563,
+ 0x10840B69, 0x10AE085F, 0x416344A9, 0x0957C000,
+ 0xC0010005, 0x2200E887, 0x101C0680, 0x09410080,
+ 0x788F0000, 0x7002248A, 0x000E209F, 0x0F832000,
+ 0xC1448000, 0x20A8C00C, 0x1B0201C0, 0x1B040014,
+ 0x225F0015, 0x60F80500, 0x3030080D, 0x18347834,
+ 0xF0060FC5, 0x23F4C30A, 0xB07A0083, 0x71247185,
+ 0xE50AF1D6, 0xF1CD71C5, 0x0A7E706E, 0x1400FC4F,
+ 0x14012090, 0x262F2080, 0x08771407, 0x714E03A4,
+ 0x70801600, 0x12D98000, 0x03AE0863, 0x13912E40,
+ 0xC000456B, 0x10050D57, 0xE888C001, 0x16802600,
+ 0x0080101C, 0x10000D43, 0x12802D40, 0x20CA7337,
+ 0x20050021, 0x20050440, 0x90040F80, 0xC10B01D0,
+ 0x0FF87034, 0x9000FD61, 0x1502265F, 0x7034C104,
+ 0x800041C3, 0x7AB4BE24, 0x6159F204, 0xF005B100,
+ 0x19506159, 0x71A50004, 0x7106F1D5, 0xC102F1C3,
+ 0xC1427724, 0x702C7034, 0xFFE2056E, 0x1400C144,
+ 0x202F2091, 0x200C2447, 0x012EA000, 0x1600000D,
+ 0x80007081, 0x211112D9, 0xF28D8400, 0x2295215E,
+ 0xC000466B, 0x010A7610, 0xC0010006, 0x2000E887,
+ 0x101C2680, 0x0EA10080, 0x205F1000, 0x40C32501,
+ 0xBE248000, 0x03832114, 0x6315607A, 0x01121250,
+ 0xE82E8F05, 0xDB3F9724, 0x48319701, 0x29049707,
+ 0x78300001, 0x023E41C3, 0x42000002, 0x000120BC,
+ 0xFBEF0816, 0x201F4350, 0x00002F81, 0xC0030A3C,
+ 0x40C16119, 0x0184209A, 0x21156119, 0x200004C0,
+ 0x80000F81, 0x70C31A3C, 0x1A3E8000, 0x23650A33,
+ 0x0FC7228A, 0x05C41800, 0xF016B140, 0x23640A29,
+ 0x79D461F9, 0x082D911A, 0x00000F81, 0x2200FFFF,
+ 0xE0FF2340, 0x1934F70A, 0x700C05C4, 0xB1A0F00A,
+ 0x04841800, 0xF1A771C5, 0x2080781D, 0xB11A003F,
+ 0x78109728, 0x75104D12, 0x0480200E, 0x23832500,
+ 0x004B2A04, 0x28047C6F, 0x23CA0040, 0x7A101025,
+ 0x02C8212F, 0x80640AD1, 0x215F4081, 0x209F0181,
+ 0x6119000E, 0x800040C3, 0x6038C144, 0xB0219721,
+ 0x90609721, 0x00C50907, 0x7165B020, 0x1401F1EA,
+ 0x71262080, 0xC0ADF167, 0x341B1404, 0x78E0C6DA,
+ 0x47CBC2FA, 0x12228000, 0x240A8FC0, 0x250A2180,
+ 0x260A2140, 0x47702100, 0x41384058, 0x8F014110,
+ 0x03840899, 0x800040C3, 0x880012D9, 0x03AE0889,
+ 0x1105704E, 0x700E2080, 0x27F4E883, 0x265A2390,
+ 0x11051293, 0xE81D2080, 0x000040C3, 0x791B28F0,
+ 0x3002211F, 0x3041201F, 0x78CCB822, 0x611A6159,
+ 0x209A4042, 0x621A0184, 0x800040C3, 0x60591A3C,
+ 0x91016215, 0x0345081B, 0x700C70AD, 0x0B82F009,
+ 0x4062FF6F, 0x40624508, 0xFF6F0BA6, 0x60B941A1,
+ 0x24C22614, 0x7502793D, 0x71467102, 0x2514B220,
+ 0xB1A024C1, 0x04012000, 0x24C02414, 0x0A977166,
+ 0xB020A2B4, 0xF1B571C5, 0x78E0C6DA, 0x800041C3,
+ 0x89011222, 0x71108920, 0x07CD20E0, 0x29407822,
+ 0x71040382, 0x7000240A, 0x030020A8, 0x0F812205,
+ 0x01D09004, 0x72C39100, 0x40000000, 0xB100E020,
+ 0x78E07EE0, 0x0343236F, 0x800041C3, 0x93000458,
+ 0x208CDA08, 0xD8088059, 0x02A520CA, 0x9300B100,
+ 0x8059208C, 0x20CAD808, 0xB10102A5, 0x208C9300,
+ 0xD8088059, 0x02A520CA, 0x9300B102, 0x8059208C,
+ 0x02A522CA, 0xB1437FE0, 0xC1A2C3EE, 0x42104728,
+ 0x0C0D2055, 0x0D124020, 0x702CFD6F, 0x40424010,
+ 0x090E702C, 0xDACAFBAF, 0x208A71CD, 0xB5C20016,
+ 0x20041AC2, 0x0C15208A, 0x1600B500, 0x80007080,
+ 0x20440009, 0x710C8091, 0x00A120CA, 0x22431AC6,
+ 0x03200A1A, 0x20021AC9, 0x22408D24, 0xADC82403,
+ 0x200D2178, 0x424240E1, 0x71AC708C, 0xFEEF0BDA,
+ 0x12C546A1, 0x22402081, 0x22402202, 0x40E12603,
+ 0x71AC708C, 0xFEEF0BC2, 0x47CB46A1, 0x12228000,
+ 0x8F018FC0, 0x03840841, 0x238D2214, 0x0C9AC180,
+ 0x9500FD6F, 0x0C929504, 0xC181FD6F, 0x0BBAC080,
+ 0x712C0120, 0xFE2F090E, 0xB500C080, 0x0BAAC081,
+ 0x712C0120, 0xFE2F08FE, 0xB504C081, 0x76108F01,
+ 0xF7A471C5, 0x05000CE2, 0x70148FC0, 0x2040740C,
+ 0x20CA2413, 0x204001E2, 0x1AC72491, 0x8F012002,
+ 0x03A4085F, 0x13102E40, 0x265A70AD, 0x2D401503,
+ 0x22051202, 0xC8080402, 0x41C37A05, 0x00009004,
+ 0x04402205, 0x04C22205, 0xB8027342, 0x78257BB4,
+ 0x01051000, 0x1B206A12, 0x78250144, 0x01041000,
+ 0x1B70740C, 0x41C30104, 0x000401C7, 0x0FD242C1,
+ 0x43A1FDEF, 0x0DB771A5, 0x71C59254, 0xC7CEF1D1,
+ 0x40C3C0F1, 0x12208000, 0xC8088880, 0x7885BC0C,
+ 0x0F802005, 0x0FD80003, 0x05200F3A, 0xC808702C,
+ 0x6C127C05, 0x0F802005, 0x0364900C, 0x7FE0C0D1,
+ 0x00051800, 0xD9FFD838, 0x1803B89F, 0x18FC0052,
+ 0x18018042, 0x18160052, 0x18010052, 0xA8200052,
+ 0x7FE0A823, 0x78E0A824, 0xD9FFD83A, 0x1803B89F,
+ 0x18FC0052, 0x18018042, 0x18160052, 0x18010052,
+ 0xA8200052, 0x7FE0A823, 0x78E0A824, 0x200AC2E8,
+ 0x47682100, 0x45284648, 0x0135080B, 0xBA0E4200,
+ 0x0A0FF00D, 0x700C03F1, 0xBA0EDA1F, 0x41C3F008,
+ 0x00010030, 0xFB8F0C22, 0xBA92704C, 0x900040C3,
+ 0x22053A90, 0x74040001, 0x2205B1A0, 0x74040001,
+ 0x2205B1C0, 0x74040001, 0xB1E07845, 0x04041800,
+ 0x78E0C6C8, 0x4110C2EE, 0x230A4040, 0x220A2140,
+ 0x45682100, 0xFEAF0BAE, 0x46084030, 0xFEAF0BA6,
+ 0x470840A1, 0xFEAF0B9E, 0x45084042, 0xFEAF0B96,
+ 0x09214062, 0x092D2090, 0x09472050, 0x42222031,
+ 0x901C42C3, 0x41C3006C, 0xF8A89007, 0xF011B2C0,
+ 0x901C42C3, 0xB2C000EC, 0x900741C3, 0xF009F928,
+ 0x901C42C3, 0xB2C000AC, 0x900741C3, 0xB2E2F8E8,
+ 0xB102B1A0, 0x84041AD4, 0x840419D8, 0x41C3C6CE,
+ 0x0001002F, 0xFBAF0B72, 0xC6CE700C, 0x45CBC5E1,
+ 0x006C901C, 0x10141D04, 0x900744CB, 0x1D3CF8A8,
+ 0x1C041054, 0x1C3C1094, 0x1D0410D4, 0xB5201014,
+ 0x10941C04, 0xB51EB460, 0x10441D40, 0x1C40B45E,
+ 0xC4C210C4, 0x1600C2E2, 0x90307100, 0x45CB0200,
+ 0x4FC48001, 0x1A11DAB0, 0x206D3003, 0x40C30081,
+ 0x04A88000, 0x40A1A820, 0xFB6F0E26, 0x42C3702C,
+ 0xFFFC7FFF, 0x10802504, 0x2000B822, 0x00050F81,
+ 0x12688000, 0x20790600, 0x1A680000, 0x1A090058,
+ 0xC6C23002, 0x0FBAC3EC, 0xC1A1FBEF, 0x800040D3,
+ 0x205410D4, 0x70CD280F, 0x254270AD, 0x08111700,
+ 0x160001D5, 0x80007080, 0xE8130131, 0x14032532,
+ 0x1700700C, 0x762C1084, 0x254A704C, 0x08FE03C0,
+ 0x70CCFC6F, 0xD922700C, 0xFC6F0BE6, 0x71A5704C,
+ 0x98F40DCB, 0x700C71E5, 0xFC6F0892, 0xDD25712C,
+ 0xBD9F714E, 0x702C722E, 0x8D40720E, 0x7A058D1B,
+ 0x20402A00, 0x200FB802, 0x7F4B004F, 0x0E6AF21B,
+ 0x40C10060, 0x0F3AE817, 0x252FFBCF, 0x700C03C7,
+ 0x704C762C, 0x244ADBD0, 0x08A20300, 0x70CCFC6F,
+ 0xD922700C, 0xFC6F0B8A, 0x700C704C, 0xFC6F083E,
+ 0x208D712C, 0x712C277F, 0x25FF218D, 0xD98271CD,
+ 0xB99F70CD, 0x800047CB, 0x712E1220, 0x04801101,
+ 0x0140206C, 0x0E002045, 0x8900C060, 0x0140206C,
+ 0x0E002045, 0x30021C01, 0x206C8901, 0x20450140,
+ 0x1C020E00, 0x89023002, 0x0140206C, 0x0E002045,
+ 0x30021C03, 0x790F700C, 0x00B50979, 0xE906AF00,
+ 0xE8888D1B, 0xF034710C, 0x70148D00, 0xF230700C,
+ 0x20402900, 0xFEAF0826, 0x0E96780F, 0x702CFBCF,
+ 0x8D60720E, 0x7B058D1B, 0x20402900, 0x200FB802,
+ 0x7A6B0042, 0x8F60F20F, 0x252FC080, 0x704C0087,
+ 0x0440244A, 0x787470CC, 0x700C602B, 0xFC2F0FDE,
+ 0x208D762C, 0x712C2A7F, 0xD922700C, 0xFC6F0AC2,
+ 0x700C704C, 0xFC2F0F76, 0x8F00712C, 0xF1C57104,
+ 0xFE6F0FCA, 0xB7C0730C, 0x78E0C7CC, 0x0FDEC0F1,
+ 0x208A00E0, 0x7910041F, 0x0A96700C, 0x704CFC6F,
+ 0x7EE0C0D1, 0x4508C2E2, 0xB813D841, 0x744CD907,
+ 0x708C706C, 0x0F8670AC, 0x70CCFC2F, 0xFC4F0A2A,
+ 0xD90740A1, 0x706C744C, 0x70AC708C, 0xFC2F0F6E,
+ 0x09FE70CC, 0x40A1FC4F, 0x744CD907, 0x708C706C,
+ 0x0F5A70AC, 0x70CCFC2F, 0xD907D880, 0x744CB893,
+ 0x708C706C, 0x0F4670AC, 0x70CCFC2F, 0x78E0C6C2,
+ 0x800042C3, 0x8A401225, 0x0042223C, 0x16007854,
+ 0x80007082, 0x22110121, 0x21448000, 0x20F90040,
+ 0x7FE00022, 0x002120F8, 0x4608C2E4, 0x800040C3,
+ 0x88001225, 0x203C4528, 0x0CAE0040, 0x41C10060,
+ 0x710C7014, 0x038120CA, 0xFFE10FB8, 0xC6C441A1,
+ 0x0927682B, 0x71140175, 0x71011600, 0x00148000,
+ 0x210B710C, 0x00008F80, 0xF2034008, 0x782D7EE0,
+ 0x207A7FE0, 0x700C0000, 0xF1FAF3F0, 0x4220C0F1,
+ 0x2144B923, 0xBAC50601, 0x81006119, 0xFB6F0F3E,
+ 0xB8C08121, 0x7FE0C0D1, 0x00002078, 0x2482C3EC,
+ 0x45083708, 0x087AC087, 0x41A1FF2F, 0xC18240A1,
+ 0xFD2F0E46, 0x31C22440, 0xC7CCE802, 0x30801407,
+ 0x00B00811, 0x080F72CD, 0x704E00F0, 0xF00370CD,
+ 0x702E714E, 0xC080C182, 0x42A179D5, 0xFFAF091A,
+ 0x080FC387, 0xC7200444, 0x14024110, 0x76523110,
+ 0xF63277C5, 0xA03009C7, 0x1D82750C, 0x2580141C,
+ 0x700C1084, 0xC7CCADE0, 0xC1A2C3E6, 0x70AD4708,
+ 0x800146CB, 0xC5414D7C, 0x0071080D, 0xD864C540,
+ 0xF066B600, 0xB606D8C8, 0x080FF062, 0xE8890050,
+ 0xB808D87F, 0xD87FF003, 0xC040B810, 0xD9FFF006,
+ 0x0FA6700C, 0xB910FB6F, 0x10710F0D, 0x26F44E1C,
+ 0xF0041340, 0x034020F4, 0x0882B802, 0x7810FC6F,
+ 0xD907D841, 0xDA08B813, 0x708C706C, 0x0DCE70AC,
+ 0x70CCFC2F, 0x742C700C, 0xFC6F08B6, 0xC080714C,
+ 0x080E41E1, 0x724CFC6F, 0xD914700C, 0xFC6F08A2,
+ 0x706C714C, 0x4060D907, 0xB892744C, 0x70AC708C,
+ 0xFC2F0D9A, 0x160070CC, 0x80007080, 0x0811000C,
+ 0x700C003E, 0x087AD914, 0x714CFC6F, 0xD907D880,
+ 0xDA08B893, 0x708C706C, 0x0D7270AC, 0x70CCFC2F,
+ 0xFBCF0BD6, 0x13412614, 0x10710F0F, 0xB1016849,
+ 0xB14C71A5, 0xB107F004, 0xB15271A5, 0x90B40D3F,
+ 0xC7C678B0, 0x702CC2E4, 0x4508DA4B, 0xFB6F0A02,
+ 0x090E2055, 0x704CD95A, 0x1104B99F, 0xAD010480,
+ 0x04801104, 0x1104AD02, 0xAD030480, 0x04801104,
+ 0x1104AD0A, 0xAD0B0480, 0x04801104, 0x1104AD0C,
+ 0xAD0D0480, 0x04801104, 0x1104AD0E, 0xAD0F0480,
+ 0x04801104, 0x1104AD10, 0xAD110480, 0x04801104,
+ 0x1104AD12, 0xAD130480, 0x04801104, 0x1104AD14,
+ 0xAD150480, 0x04801104, 0x1104AD16, 0xAD180480,
+ 0x04801104, 0x1104AD19, 0xAD1A0480, 0x04801104,
+ 0x1104AD1B, 0xAD1C0480, 0x04801104, 0x1104AD1E,
+ 0xAD1F0480, 0x04801104, 0x10021D20, 0x04801104,
+ 0x10021D21, 0x04801104, 0x10021D22, 0x04801104,
+ 0x10021D25, 0x04801104, 0x10021D28, 0x04801108,
+ 0x10021D29, 0x10821D2E, 0x04801104, 0x10021D3A,
+ 0x04801104, 0x10021D45, 0x04801104, 0x10021D46,
+ 0x04801104, 0x10021D47, 0x84801179, 0x10021D48,
+ 0x0080118B, 0x10021D49, 0x0080118F, 0x10021D4A,
+ 0x04801104, 0x10021D4C, 0x04801104, 0x10021D4D,
+ 0x04801104, 0x10021D4E, 0x04801104, 0x10021D55,
+ 0x04801104, 0x10021D56, 0x04801104, 0x10021D57,
+ 0x04801104, 0x10021D58, 0x04801104, 0x10021D59,
+ 0x04801104, 0x10021D5A, 0x04801104, 0x10021D5B,
+ 0x04801104, 0x10021D5C, 0x04801104, 0x10021D5D,
+ 0x04801104, 0x10021D5E, 0x04801104, 0x10021D5F,
+ 0x04801104, 0x10021D60, 0x04801104, 0x10021D61,
+ 0x04801104, 0x10021D63, 0x04801104, 0x10021D64,
+ 0x04801104, 0x10021D65, 0x04801104, 0x10021D66,
+ 0x04801104, 0x10021D67, 0x04801104, 0x10021D69,
+ 0x04801104, 0x10021D6A, 0x04801104, 0x10021D6B,
+ 0x04801104, 0x10021D6C, 0x04801104, 0x10021D6D,
+ 0x04801104, 0x10021D70, 0x04801104, 0x10021D73,
+ 0x04801108, 0x10021D74, 0x10821D79, 0x04801104,
+ 0x10021D85, 0x04801104, 0x1104AE00, 0x1D910480,
+ 0x11041002, 0x1D920480, 0x11791002, 0x1D938480,
+ 0x118B1002, 0xAE040080, 0x0080118F, 0x10021D95,
+ 0x04801104, 0x10021D97, 0x04801104, 0x1104AE08,
+ 0x1D990480, 0x11041002, 0xAE100480, 0x04801104,
+ 0x10021DA1, 0x04801104, 0x10021DA2, 0x04801104,
+ 0x10021DA3, 0x04801104, 0x1104AE14, 0x1DA50480,
+ 0x11041002, 0x1DA60480, 0x11041002, 0x1DA70480,
+ 0x11041002, 0xAE180480, 0x04801104, 0x10021DA9,
+ 0x04801104, 0x10021DAA, 0x04801104, 0x10021DAB,
+ 0x04801104, 0x1104AE1C, 0x1DAE0480, 0x11041002,
+ 0x1DAF0480, 0x11041002, 0x1E200480, 0x11041002,
+ 0x1DB10480, 0x11041002, 0x1DB20480, 0x11041002,
+ 0x1E240480, 0x11041002, 0x1DB50480, 0x11041002,
+ 0x1DB60480, 0x11041002, 0x1DB70480, 0x11041002,
+ 0x1E280480, 0x11041002, 0x1DBB0480, 0x11041002,
+ 0x1DBE0480, 0x11081002, 0x1DBF0480, 0x1E341002,
+ 0x11041082, 0x1E400480, 0x11041002, 0x1DDB0480,
+ 0x11041002, 0x1E4C0480, 0x11041002, 0x1DDD0480,
+ 0x11791002, 0x1DDE8480, 0x118B1002, 0x1DDF0080,
+ 0x118F1002, 0x1E500080, 0x11041002, 0x1DE20480,
+ 0x11041002, 0x1DE30480, 0x11041002, 0x1E540480,
+ 0x11041002, 0x1DEB0480, 0x11041002, 0x1E5C0480,
+ 0x11041002, 0x1DED0480, 0x11041002, 0x1DEE0480,
+ 0x11041002, 0x1DEF0480, 0x11041002, 0x1E600480,
+ 0x11041002, 0x1DF10480, 0x11041002, 0x1DF20480,
+ 0x11041002, 0x1DF30480, 0x11041002, 0x1E640480,
+ 0x11041002, 0x1DF50480, 0x11041002, 0x1DF60480,
+ 0x11041002, 0x1DF70480, 0x11041002, 0x1DF90480,
+ 0x11041002, 0x1DFA0480, 0x11041002, 0x1DFB0480,
+ 0x11041002, 0x1E6C0480, 0x11041002, 0x1DFD0480,
+ 0x11041002, 0x1DFF0480, 0x25561002, 0x11041800,
+ 0xA8600483, 0x238043A1, 0x11040044, 0xAB000480,
+ 0x04801104, 0x1104AB01, 0xAB020480, 0x04801104,
+ 0x1104AB05, 0xAB080480, 0x04801108, 0xAB4EAB09,
+ 0x04801104, 0x1104AB1A, 0x1B250480, 0x11040002,
+ 0x1B260480, 0x25560002, 0x11041940, 0xA8400482,
+ 0x1B288900, 0x89040002, 0x00021B29, 0x1B2A8908,
+ 0xC6C40002, 0x1CFCC2FA, 0x256FB6C8, 0x8D001243,
+ 0x017E084F, 0x42C3C1AE, 0x00349018, 0x05001204,
+ 0x800041C3, 0x1902018C, 0x12040014, 0x19020500,
+ 0x12040014, 0x19020500, 0x12E00014, 0xB1008500,
+ 0x6872C808, 0x00802305, 0xB1039000, 0x03002242,
+ 0x90007865, 0x6A0CB101, 0x90007865, 0xC08CB102,
+ 0x800041C3, 0x0D320635, 0x764CFB2F, 0x0DAEC08C,
+ 0x762C0520, 0xD9258D00, 0xB99FB8C3, 0x70041E00,
+ 0x022C9008, 0x42C38900, 0x01C8901C, 0x891BB200,
+ 0x11F4B202, 0xE8968080, 0x03000C56, 0x2042C805,
+ 0xF210803C, 0x20A8700C, 0x20050380, 0x90040F82,
+ 0x9220028C, 0x000070C3, 0x21444000, 0xB2200301,
+ 0x902C41C3, 0x91000C98, 0x78259122, 0x001E0815,
+ 0x71001600, 0x00068000, 0x0F84080D, 0x0C810000,
+ 0xFC8F0DAA, 0x00000BB6, 0x70801600, 0x011D8000,
+ 0x0AFAE807, 0xC0AE0300, 0x341B1404, 0x1600C6DA,
+ 0x80007080, 0x701400F3, 0x00010370, 0x702E700C,
+ 0x1E00B88C, 0x90077444, 0x43DBC3E8, 0xC83C9007,
+ 0x70041E00, 0xC3649007, 0x40DBC808, 0x00009000,
+ 0x20056892, 0x00010F80, 0x24050027, 0x90041F83,
+ 0x9340083C, 0x16C12405, 0x0F822204, 0xFF780000,
+ 0x01822285, 0x2405B140, 0x90071F82, 0xC04BC09C,
+ 0x2005B802, 0xC2450600, 0x9040C048, 0xBAA0C005,
+ 0x1600B040, 0x90047100, 0xB8A00AB0, 0x70041E00,
+ 0xCAB09007, 0x20459300, 0xB1A0014D, 0x70801600,
+ 0x00088000, 0x01002079, 0x2040B802, 0x2B40030B,
+ 0x0F861240, 0x20960120, 0xC8080208, 0x47CBBDA0,
+ 0x12228000, 0x22056852, 0xB1A006C1, 0xB7209721,
+ 0x0F812205, 0x08249004, 0x34401C0C, 0x34401C08,
+ 0x34401C04, 0x793B9120, 0x0F872184, 0x231F7124,
+ 0x21551041, 0xC1460DC1, 0x0F812205, 0x01909038,
+ 0xC14A9120, 0xB962C181, 0x702CC149, 0x202FC144,
+ 0x28402447, 0x20052312, 0x68520480, 0x900440C3,
+ 0x22050A80, 0x74040001, 0x43839120, 0x2205B322,
+ 0x91200001, 0xB3237404, 0x00012205, 0x74049120,
+ 0x2205B324, 0x91200001, 0xB3257404, 0x208A7A05,
+ 0x92200FCF, 0x2840B307, 0xB3262380, 0x0F8E2005,
+ 0x0AB09004, 0x9600C047, 0x0001204F, 0xB8A0B620,
+ 0xC007B600, 0x0F802005, 0x03549004, 0x090BC10A,
+ 0x9000027F, 0x140C781D, 0x7D103107, 0x3106140A,
+ 0x1404740C, 0x41C33103, 0x0007005A, 0x31051408,
+ 0x14064202, 0x240A3117, 0x0AF605C0, 0xC540FDAF,
+ 0x16D5255F, 0x30141424, 0x702F706E, 0x29012D85,
+ 0x15562502, 0x23552500, 0x21001402, 0x71021600,
+ 0x00068000, 0x0A11791B, 0x00000F85, 0x0D2D0C80,
+ 0xF0201045, 0x03440925, 0x30100915, 0x21011400,
+ 0x0D197822, 0x08152002, 0xF0140582, 0x05C0200E,
+ 0x20020D09, 0x058308EF, 0x2179D95D, 0x0F9A3100,
+ 0xB910FB2F, 0x72867127, 0xB17409B1, 0x756E7166,
+ 0x2205C808, 0x00012F86, 0x2005020F, 0x20050481,
+ 0xB9020180, 0x2105B802, 0x90040F81, 0x19000AB4,
+ 0xD99C04C4, 0x70441E00, 0xC3649007, 0x2005C10B,
+ 0x21050600, 0xB9020481, 0x060B2105, 0x11091300,
+ 0x1001214F, 0x10441B00, 0x256C90A0, 0xB9801041,
+ 0x0DC6B020, 0xC0060120, 0x10002150, 0x1B00BDA0,
+ 0xC8081004, 0x01812005, 0x2105B902, 0xB1A00601,
+ 0x214F9620, 0xB6400002, 0xB620B9A0, 0x04812005,
+ 0x2105B902, 0x90040F82, 0xC1070ABC, 0x0F812105,
+ 0x03589004, 0xB2209120, 0x080D8F23, 0x218C2065,
+ 0xF4118FC3, 0x20610815, 0x8F258F44, 0x72304150,
+ 0x21CAC104, 0xF00A006D, 0x2084080F, 0x080B8F25,
+ 0x71262045, 0x712CF003, 0xC104C144, 0xF3117034,
+ 0x706EF003, 0xC108F196, 0x91A0B802, 0x254FC105,
+ 0xB1401002, 0x06C12005, 0x0F802005, 0x083C9004,
+ 0x266C90C0, 0xB8801040, 0x0D1EB100, 0xC0060120,
+ 0xBDA0C005, 0xB0A0BEA0, 0xB802C808, 0x06C12005,
+ 0x8FA0B1C0, 0x8F017AAF, 0x04CA7210, 0x40C3FFCD,
+ 0x12D98000, 0x08418800, 0x2A4000AE, 0x2405038C,
+ 0x90041F80, 0x90600354, 0x2353C808, 0xB8020201,
+ 0x20057885, 0x90380F8C, 0x9400021C, 0x0F802004,
+ 0xFE000000, 0x41C37825, 0x00020062, 0x0922B400,
+ 0x740CFDAF, 0xF1D871A5, 0x800041C3, 0x9100018A,
+ 0x8701113E, 0xF7877110, 0xFC8F0C2A, 0x04807014,
+ 0x0463FFC1, 0x78E0FFCF, 0xC808C2E6, 0x21056832,
+ 0x90070F80, 0x2105C83C, 0x90040F81, 0x9120083C,
+ 0x0F812104, 0xFF780000, 0x01812145, 0x1600B020,
+ 0x80007087, 0x0E5A0005, 0x710C0320, 0x47CB712D,
+ 0x0084900C, 0x0F9574CC, 0x1F000030, 0x700C1244,
+ 0x01200CD2, 0x702C742C, 0x901840C3, 0xB7200008,
+ 0x02441800, 0x824418FC, 0x70441E00, 0x0C40902C,
+ 0x804418F8, 0x009840C3, 0x0CAA9680, 0x46280120,
+ 0x47CBD833, 0x08009008, 0x45CBB700, 0x02889008,
+ 0x0C06D820, 0xB5C00120, 0x900743CB, 0x1D58C11C,
+ 0x208A9244, 0x1B000010, 0x1B001145, 0x234F1184,
+ 0x1B0014CB, 0x1B001145, 0x1D001184, 0x0BDA1085,
+ 0x1D580120, 0x700C9384, 0xB5C0D920, 0x01200C56,
+ 0x1B0CB7C0, 0xF0659244, 0x01200BBE, 0x46CB740C,
+ 0x00189018, 0x950016F0, 0x2004702C, 0x00000F80,
+ 0x1E00FDFF, 0x901B7004, 0x40C3C018, 0x4240000F,
+ 0xB7204528, 0x4708B620, 0x70441E00, 0x0C40902C,
+ 0x90441EFC, 0x90441EF8, 0x01200C0A, 0x10C51E04,
+ 0x78FD720D, 0x0BFE702C, 0x1E040120, 0x702C1204,
+ 0x009840C3, 0x0BEE9680, 0xB6A20120, 0x900843CB,
+ 0x47C301E0, 0xC11C9007, 0x12441B00, 0x1F00D833,
+ 0x47CB0145, 0x08009008, 0x01841F00, 0x04C7274F,
+ 0x1A8E2355, 0x01451F00, 0x01841F00, 0x760CB700,
+ 0x01200B26, 0x700CB6A0, 0x000041C3, 0x1B002710,
+ 0x0BA21204, 0x1E000120, 0x700C1204, 0x1B00D920,
+ 0xB6A01344, 0x01200B8E, 0x1F0CB7A0, 0x0CB68244,
+ 0x710C01E0, 0x01200AF2, 0x46CBD878, 0xC11C900F,
+ 0x14CF2650, 0x1E00710C, 0x1E001185, 0x1F001105,
+ 0x08D61185, 0x1F0000E0, 0x0EF21105, 0x208AFDCF,
+ 0x45CB0D07, 0x03E09008, 0x0B4AD920, 0x1D000120,
+ 0x700C1045, 0x1EB2B88C, 0xD820101C, 0x101D1F84,
+ 0x01200AA6, 0x10051D00, 0x78E0C6C6, 0x78E07EE0,
+ 0x78E07EE0, 0x16007A1B, 0x80007080, 0x7859001C,
+ 0x7FE07839, 0x78E0B8C0, 0x2079C2F0, 0x43500050,
+ 0x45CB4728, 0x11DA8000, 0x03200ECA, 0x204E2014,
+ 0x66A8704E, 0x20250A2B, 0x20166F14, 0x70420400,
+ 0x60A9E024, 0x084ED880, 0x41300360, 0x23912940,
+ 0x21057146, 0x90042F81, 0xB1000230, 0x40C3F1EB,
+ 0x4E200000, 0x01200ABE, 0x66A8702C, 0x21D3234F,
+ 0x702EE82B, 0x20166F14, 0x70220400, 0x60A9E024,
+ 0x08124062, 0x42300360, 0x23942A40, 0x2F812405,
+ 0x02309004, 0x0A66B100, 0x740C0120, 0x2FC7228A,
+ 0x2F802405, 0x02249004, 0x04841800, 0x01200A4E,
+ 0x2405740C, 0x90042F80, 0x1800022C, 0x71260484,
+ 0x09B566A8, 0xD90CA004, 0x000040C3, 0x0A561388,
+ 0x44100120, 0xE81A66A8, 0x2213234F, 0x6F14704E,
+ 0x04002016, 0xE0247042, 0x406260A9, 0x03200FA6,
+ 0x29404130, 0x71462391, 0x2F812105, 0x02309004,
+ 0x66A8B100, 0xA0040ADB, 0x0A1A4082, 0xD90C0120,
+ 0xE82666A8, 0x6F14702E, 0x04002016, 0xE0247022,
+ 0x208A60A9, 0x0F6E0006, 0x42300320, 0x23932A40,
+ 0x2F812305, 0x02249004, 0x09C2B100, 0x740C0120,
+ 0x0006208A, 0x03200F4E, 0x23054142, 0x90042F81,
+ 0xB100022C, 0x66A87126, 0xA00409BF, 0x000340C3,
+ 0x09C2D090, 0x702C0120, 0x03000DC2, 0x78E0C6D0,
+ 0x1CFCC2FA, 0x2482B6C8, 0x702C3211, 0xFCEF099A,
+ 0x1207C045, 0xC0443091, 0xC051700C, 0xC04FC050,
+ 0xC04DC04E, 0xFF2F082E, 0x47CBC04C, 0x12228000,
+ 0x40108F61, 0x0B338F20, 0x750C0064, 0x70801600,
+ 0x000C8000, 0x700CB8E3, 0x2100F208, 0x101C0680,
+ 0x20780080, 0xB8080000, 0x70422614, 0x048C8000,
+ 0xB2007124, 0xC205F1E9, 0x03F246CB, 0x0D220001,
+ 0x41C1FD6F, 0xFDEF0FEA, 0x45CBC005, 0x01268000,
+ 0x264F8D40, 0x0D0A1401, 0x740CFD6F, 0x214A7036,
+ 0x8D003480, 0x33E121CA, 0xF491B8E0, 0x712EC005,
+ 0x41C3C204, 0x000103F5, 0x20002900, 0x0CE268D2,
+ 0x740CFD6F, 0x712CC004, 0xFC6F0EC6, 0x0D9E704C,
+ 0x0EAEFE0F, 0x0CB2FB4F, 0x0C8A0300, 0x700C0300,
+ 0xFBAF0FCA, 0x1600712C, 0x80007082, 0x22780008,
+ 0x68210080, 0x71001600, 0x0510901C, 0x2044C047,
+ 0x20002040, 0x1E002003, 0x901C7044, 0x0A0F0510,
+ 0x218A00B0, 0x218A0048, 0xC0050090, 0x1010260F,
+ 0x2340C808, 0xB802078E, 0x0F822005, 0x04F8901C,
+ 0x0F802005, 0x04F4901C, 0x714CB220, 0x712CB020,
+ 0x71001600, 0x0508901C, 0xB887C048, 0x70041E00,
+ 0x0508901C, 0xFC6F0E3A, 0x0C62C004, 0x4210FB4F,
+ 0x000040C3, 0x08B2FFFF, 0x41000320, 0x208A7056,
+ 0xD9FF0FC7, 0x0EA6711C, 0x710C02E0, 0x70801600,
+ 0x000C8000, 0x00DF080D, 0x74441E00, 0xC2D49007,
+ 0x1E00D80F, 0x901F7085, 0x1E00C040, 0x90077085,
+ 0x08B2F880, 0xD90FFCAF, 0x0240093A, 0x0A9278CF,
+ 0x212F0060, 0x8D000407, 0x00FF0821, 0x1410C092,
+ 0x0205301B, 0x23400020, 0xD9FD3A9B, 0x0BD2D80A,
+ 0xB912FD6F, 0x00000425, 0x0BE6702C, 0x228AFAEF,
+ 0xC3050010, 0x714C740C, 0x03F941C3, 0x1C2C0002,
+ 0x0BAE3FC1, 0x1C28FD6F, 0x8FA03FC1, 0x1410700E,
+ 0x2340301B, 0x232F3A9B, 0x238C0408, 0x00A68FDF,
+ 0xC808000D, 0x20058FC1, 0x689206C0, 0x13640E23,
+ 0x13802D40, 0xB8927885, 0xB89FB89C, 0xC28AEB85,
+ 0x7AB49020, 0x1800B220, 0x71A50404, 0x08A6F1F0,
+ 0xD80F0240, 0xFCAF080E, 0x700CD90F, 0xFBAF0E5E,
+ 0x8F01712C, 0x085B8FA0, 0x78A20364, 0x6821714C,
+ 0x2F832004, 0xFFF80000, 0x20802053, 0x7A18BB23,
+ 0x7040240A, 0x20A843A9, 0x26F40740, 0x800072C0,
+ 0x6832048C, 0x13802B40, 0x2B407825, 0x20051201,
+ 0x90040F80, 0x908002DC, 0x6038C092, 0x60797095,
+ 0x20C58900, 0xF4030082, 0x71657846, 0x7106A900,
+ 0x700EF1AB, 0x08DD8F01, 0x42A10364, 0x03FA41C3,
+ 0x0ADE0001, 0x740CFD6F, 0x09B9702E, 0x00002F85,
+ 0x218B0800, 0x1C0CA803, 0x1C083400, 0xF4123400,
+ 0x28002156, 0x21822941, 0x0F802004, 0xFFC00000,
+ 0x41C3B826, 0x000203FB, 0x0AA66869, 0x740CFD6F,
+ 0x70CCDB08, 0xC48270CD, 0x64DC700C, 0x00892653,
+ 0x7100244A, 0x200A736D, 0x1C001440, 0x20A81003,
+ 0x2D4004C0, 0xC2921201, 0x2841623A, 0x710510C1,
+ 0x29016229, 0x71250241, 0x2900B9C0, 0x776502C1,
+ 0x26527825, 0x74260086, 0x238D71C5, 0xAC0007FF,
+ 0x3087140D, 0x3085140B, 0x3086140C, 0x3084140A,
+ 0x1409C222, 0x140E3083, 0x140F3081, 0xC1403080,
+ 0x03FC41C3, 0xC0410008, 0xFD6F0A26, 0xF1A7740C,
+ 0x03FD41C3, 0x0A1A0000, 0x740CFD6F, 0xF19471A5,
+ 0x08318F20, 0x78220064, 0xC8086861, 0x06C02005,
+ 0x70C0240A, 0x20A86852, 0xC08A0380, 0x004320F4,
+ 0x03802940, 0x71247845, 0xB89CB892, 0xB060B89F,
+ 0x02000F22, 0x03FE41C3, 0x09D60000, 0x740CFD6F,
+ 0x42D3700C, 0x00009000, 0x202FC046, 0xC0498648,
+ 0x1600F2F2, 0x80007080, 0x0817000C, 0x700C00FE,
+ 0xFBAF0CBA, 0xD80F712C, 0xFC6F0E5A, 0x700CD90F,
+ 0xFBAF0CAA, 0x8FC0712C, 0x76108F01, 0x002D01AA,
+ 0x2440D80F, 0x27143C17, 0x17002397, 0x70142100,
+ 0x2614F4C9, 0x80007395, 0x2E40048C, 0x24401301,
+ 0x15003E11, 0x21052100, 0x00010F98, 0x200500B7,
+ 0x21050600, 0xB80206C1, 0x23912114, 0x04802005,
+ 0x2490224F, 0xC8089040, 0x78254350, 0x20841900,
+ 0x2005B802, 0xC0902010, 0x21141000, 0x03962014,
+ 0x21001600, 0x0B3FE80E, 0x740C2031, 0x03FF41C3,
+ 0x42C10002, 0x091A4382, 0x1F00FD6F, 0xF0932045,
+ 0x20110B23, 0x7014CA07, 0x20CAD812, 0xC10903E1,
+ 0x00610813, 0x740C702C, 0xFD6F08F6, 0x710CB99A,
+ 0x2453C046, 0x24AD214D, 0x740C2982, 0x040141C3,
+ 0x42C10004, 0x44A14382, 0xFD6F08D6, 0x04C0250A,
+ 0x20812440, 0x20056916, 0xCA070353, 0xD8227014,
+ 0x072120CA, 0x004508C3, 0x08B3C006, 0x16000010,
+ 0x80007080, 0x29090008, 0xF2518014, 0x040241C3,
+ 0x089E0000, 0x740CFD6F, 0xD90FD80F, 0xFC6F0D46,
+ 0x23441800, 0x02000DCE, 0x41C3740C, 0x00030403,
+ 0x706C42C1, 0xFD6F087A, 0x160044A1, 0x80007080,
+ 0x0817000C, 0x700C00FE, 0xFBAF0B72, 0xD80F712C,
+ 0xFC6F0D12, 0x700CD90F, 0xFBAF0B62, 0x1500712C,
+ 0x20052100, 0xB8020600, 0x04802005, 0x19009000,
+ 0xE8132004, 0x21842C40, 0x2405740C, 0x41C30344,
+ 0x00030404, 0x438242C1, 0xFD6F0826, 0x21041800,
+ 0x20451F00, 0x740CF017, 0x040541C3, 0x42C10003,
+ 0x080E706C, 0x44A1FD6F, 0x41C343B1, 0x00000406,
+ 0xFAEF0D06, 0x1800700C, 0x110024C4, 0x1E002100,
+ 0x71C52004, 0x0C9EF12A, 0xD90FFC6F, 0x02200D26,
+ 0xF10D7727, 0x1E00C007, 0x901C7004, 0xC0080510,
+ 0x70041E00, 0x0508901C, 0xFE4F0816, 0x702CC004,
+ 0xFC6F09AE, 0x41C3704C, 0x00000407, 0xFD2F0FB2,
+ 0x0A7E750C, 0xC005FDEF, 0x32112480, 0x341B1404,
+ 0x78E0C6DA, 0xC1A4C3E8, 0x800046CB, 0x8EA11220,
+ 0x40D371ED, 0x4E748001, 0x40027014, 0x7FB8D912,
+ 0x083EF209, 0x400202C0, 0x0D4AD912, 0xDA800060,
+ 0x09B6F003, 0x0EFA0240, 0xC08002E0, 0x0BDAC080,
+ 0xD912FDEF, 0x259F8E00, 0x209F12C1, 0x704C0582,
+ 0x708CC380, 0x6F12651D, 0x250078E5, 0x0A7E1401,
+ 0x780F04A0, 0x000040C3, 0x0B5A4E20, 0x702C00E0,
+ 0x78E0C7C8, 0x2482C3F2, 0x44103104, 0x702CC081,
+ 0xFAAF0F3E, 0x0004228A, 0x800045CB, 0x8D401220,
+ 0x20502479, 0x22102040, 0xA0432442, 0x41C3750C,
+ 0x00030150, 0xFD2F0EFA, 0x0400240A, 0x24408DA0,
+ 0xC8083081, 0x7D05BD0C, 0xFCAF0A82, 0x46084082,
+ 0x1F802505, 0x00D90003, 0x0E6AD940, 0x43100460,
+ 0x02200BBE, 0x1402BE68, 0x7FD03102, 0x41E14082,
+ 0x0BEA41F1, 0x4250FB2F, 0xD955E806, 0x0BBA700C,
+ 0xB912FAEF, 0x22002840, 0x7D0570CD, 0x800047CB,
+ 0x25050484, 0x00031F95, 0x7DD000D8, 0x9FC3258C,
+ 0x40A2F712, 0x04600E1E, 0x0B7641A1, 0x40820200,
+ 0x0BAA4122, 0x4242FB2F, 0x61B9C181, 0x8F00A900,
+ 0xF1ED661E, 0x0DFE40A2, 0x702C0460, 0x20802B40,
+ 0xB89C70AD, 0x0B4AB89F, 0xB0A00220, 0x015741C3,
+ 0x0E4E0000, 0x740CFD2F, 0x21C22042, 0x41C3740C,
+ 0x00020158, 0xFD2F0E3A, 0x8F804302, 0x7200244A,
+ 0x706C704C, 0x030020A8, 0x659EC081, 0x224E60A9,
+ 0x714401C0, 0x290045C9, 0x7B050000, 0x41C37A6F,
+ 0x00010159, 0xFD2F0E0A, 0x268C740C, 0x45C99004,
+ 0xD9ADF6A5, 0x0DFA740C, 0xB911FD2F, 0x700C8F40,
+ 0x8FC3208C, 0xC181F707, 0x70346109, 0x008120C0,
+ 0x2080F3F8, 0x7E0E003F, 0x9004268C, 0x41C3F688,
+ 0x0000015B, 0xFAEF0AD2, 0xF009700C, 0x41C3740C,
+ 0x0001015C, 0xFD2F0DBA, 0x40C342C1, 0x01258000,
+ 0x6D2988A0, 0x0114090B, 0x180074AD, 0x740C0103,
+ 0x015D41C3, 0x0D9A0001, 0x42A1FD2F, 0x740CBD05,
+ 0x015E41C3, 0x0D8A0001, 0x42A1FD2F, 0x780E4EB0,
+ 0x78E0C7D2, 0xC1A4C3E2, 0x800145CB, 0x40A14E74,
+ 0x02A00E2E, 0x40A1D910, 0x0B3AD910, 0xDA410060,
+ 0xD91040A1, 0xFBEF0942, 0x40A1DAF3, 0x02A00E12,
+ 0x40A1D929, 0x0932D929, 0xDA1FFBEF, 0x0E0240A1,
+ 0xD90B02A0, 0xD90B40A1, 0xFBEF091E, 0x40A1DAF0,
+ 0x02A00DEE, 0x40A1D912, 0x0AFAD912, 0xDA080060,
+ 0xD91240A1, 0xFBEF0902, 0x0CA6DAF8, 0xC08002E0,
+ 0x0986C080, 0xD910FDEF, 0x097EC080, 0xD929FDEF,
+ 0x0976C080, 0xD90BFDEF, 0x096EC080, 0xD912FDEF,
+ 0x0966C080, 0x732CFDEF, 0x095EC080, 0xD911FDEF,
+ 0x0956C080, 0xD912FDEF, 0x70801600, 0x01318000,
+ 0x0071080D, 0x0942C080, 0xD913FDEF, 0x702C40A1,
+ 0xDBFFC280, 0x04A00C56, 0x40C3708C, 0x4E200000,
+ 0x00E008D2, 0x40A1702C, 0x02200EEE, 0x40A1D929,
+ 0x02200EE6, 0x40A1D90B, 0x02200EDE, 0xC7C2D912,
+ 0xC1A2C3EC, 0x800145CB, 0x41304D64, 0xD8644010,
+ 0x254070CD, 0xB5001312, 0xC640C641, 0x731478CF,
+ 0x000D00F0, 0x20100919, 0x00D00829, 0x0050081F,
+ 0x00900829, 0xD87FE896, 0xF01EB808, 0x00D0082D,
+ 0x00500831, 0x0090080D, 0xD87FE898, 0xF014B810,
+ 0x7F0040C3, 0xF0107F7F, 0x7F7F40C3, 0xF00C007F,
+ 0x700CD989, 0xF00EB911, 0x007F40C3, 0xF0047F7F,
+ 0xB818D87F, 0xF008C040, 0x41C3700C, 0x00000119,
+ 0xFACF0916, 0x15001502, 0x0A02B802, 0x7810FBAF,
+ 0xD907D841, 0xDA08B813, 0x708C706C, 0x0F4E70AC,
+ 0x70CCFB6F, 0x742C700C, 0xFBAF0A36, 0xC080714C,
+ 0x098E4102, 0x724CFBAF, 0xD914700C, 0xFBAF0A22,
+ 0x706C714C, 0x4060D907, 0xB892744C, 0x70AC708C,
+ 0xFB6F0F1A, 0x160070CC, 0x80007080, 0x0811000C,
+ 0x700C003E, 0x09FAD914, 0x714CFBAF, 0xD907D880,
+ 0xDA08B893, 0x708C706C, 0x0EF270AC, 0x70CCFB6F,
+ 0xFB0F0D56, 0x7704B500, 0x20141A02, 0xF18871C5,
+ 0x78E0C7CC, 0x4608C2E8, 0x70801600, 0x000C8000,
+ 0x47284050, 0x8E00204B, 0x40C3F2B7, 0x12208000,
+ 0x20812078, 0x219F8800, 0x209F02C1, 0x61190582,
+ 0x0F8F2132, 0x4E868001, 0xFB0F0D26, 0xD907706C,
+ 0x744C4568, 0x708CBD9A, 0x70AC40A1, 0xFB6F0E8E,
+ 0x43E170CC, 0x238540A1, 0x762C0201, 0x244A744C,
+ 0x250A0480, 0x0E760400, 0x70CCFB6F, 0xD90740A1,
+ 0x706C744C, 0x70AC708C, 0xFB6F0E62, 0x0FC1268A,
+ 0xFB8F0906, 0x13C0254F, 0x744CD907, 0x708C706C,
+ 0x0E4A70AC, 0x70CCFB6F, 0xD90740A1, 0x706C744C,
+ 0x70AC708C, 0xFB6F0E36, 0x03C0264A, 0xD9077EBD,
+ 0x744C40C1, 0x708C706C, 0x0E2270AC, 0x70CCFB6F,
+ 0xD90740A1, 0x706C744C, 0x70AC708C, 0xFB6F0E0E,
+ 0x0FC3268A, 0xD90740C1, 0x706C744C, 0x70AC708C,
+ 0xFB6F0DFA, 0x40A170CC, 0x744CD907, 0x708C706C,
+ 0x0DEA70AC, 0x268AFB6F, 0x40C10FC3, 0x744CD907,
+ 0x708C706C, 0x0DD670AC, 0x70CCFB6F, 0xD90740A1,
+ 0x706C744C, 0x70AC708C, 0xFB6F0DC2, 0x0FC3268A,
+ 0x1480254F, 0x744CD907, 0x708C706C, 0x0DAE70AC,
+ 0x71CCFB6F, 0xFB8F083A, 0xD90740A1, 0x706C744C,
+ 0x70AC708C, 0xFB6F0D96, 0x40A173CC, 0x744CD907,
+ 0x708C706C, 0x0D8670AC, 0x268AFB6F, 0x40A10FC1,
+ 0x744C762C, 0x244A43E1, 0x250A0480, 0x0D6E0400,
+ 0x70CCFB6F, 0xD90740A1, 0x706C744C, 0x70AC708C,
+ 0x0FC0264A, 0x0BDAF03F, 0x700CFB0F, 0x744CD907,
+ 0x708C706C, 0x0D4670AC, 0x70CCFB6F, 0xFB4F0FEA,
+ 0xD907706C, 0x724C4568, 0x708CBD99, 0x70AC40A1,
+ 0xFB6F0D2A, 0x700C70CC, 0x42C1D907, 0x708C706C,
+ 0x0D1A70AC, 0x70CCFB6F, 0xBD2D740C, 0x712CB892,
+ 0x43A142E1, 0x70AC708C, 0xFB6F0D02, 0x6D1370CC,
+ 0xDA0CD907, 0x708C706C, 0x0CF270AC, 0x71CCFB6F,
+ 0xFB4F0F7E, 0xD907700C, 0x706CDA10, 0x70AC708C,
+ 0x0CDA70CC, 0xD880FB4F, 0x744CD907, 0x708C706C,
+ 0x0CCA70AC, 0x70CCFB6F, 0x78E0C6C8, 0x4510C2F4,
+ 0x71001600, 0x0508901C, 0x20534330, 0xF4098196,
+ 0x03E641C3, 0x094A0000, 0x740CFD2F, 0x265F71CE,
+ 0x2E4020CF, 0x710C2094, 0x200E241F, 0x93A50FFD,
+ 0x0B0E7104, 0x740CFB0F, 0x03E741C3, 0x09220001,
+ 0x42C2FD2F, 0xFB4F0F22, 0x2280265F, 0x704CD907,
+ 0x708C706C, 0x770470AC, 0x2007212F, 0x0C5E700C,
+ 0x260AFB6F, 0x6F010440, 0x7B0F702C, 0x0986D807,
+ 0x704C0020, 0x000045CB, 0x232F12C8, 0xD81D0580,
+ 0x426241A1, 0x0020096E, 0xD81E4270, 0x426241A1,
+ 0x00200962, 0xD81F4342, 0x426241A1, 0x00200956,
+ 0xD8204342, 0x704C41A1, 0x0020094A, 0x78F24342,
+ 0x661E702C, 0x7BCFD807, 0x093A704C, 0x40700020,
+ 0xD907700C, 0x706C704C, 0x70AC708C, 0xFB6F0BEE,
+ 0x0440260A, 0x20402242, 0x262FD907, 0x700C0007,
+ 0x706C744C, 0x0BD6708C, 0x70ACFB6F, 0x710CDD08,
+ 0x082A41C2, 0x4262FBAF, 0x41C2700C, 0xFBAF081E,
+ 0x258C4262, 0x700C1DFF, 0xDA5CD907, 0x708C706C,
+ 0x70CC70AC, 0xFB6F0BA6, 0x708C71CE, 0x458874CD,
+ 0xBD8CBE92, 0xD92E40C1, 0x43A142A2, 0x0B8E70AC,
+ 0x70CCFB6F, 0xD92F40C1, 0x43A142A2, 0x70AC708C,
+ 0xFB6F0B7A, 0x6D1370CC, 0x744CD907, 0x708C706C,
+ 0x0B6A70AC, 0x71CCFB6F, 0x0540202F, 0x0C8D2054,
+ 0x2580241F, 0x08FD46CA, 0x71C68364, 0xD907700C,
+ 0x706C704C, 0x70AC708C, 0xFB6F0B42, 0x0440260A,
+ 0x1500261E, 0x704C702C, 0x671F78A2, 0x7B0F6F01,
+ 0x00200862, 0xDD25D807, 0xBD07D81D, 0x41A14262,
+ 0x00200852, 0xD81E4342, 0x426241A1, 0x00200846,
+ 0xD81F4342, 0x426241A1, 0x0020083A, 0xD8204342,
+ 0x704C41A1, 0x0020082E, 0xD8074342, 0x704C702C,
+ 0x00200822, 0x700C4302, 0x704CD907, 0x708C706C,
+ 0x0ADA70AC, 0x260AFB6F, 0x0D660440, 0xC6D4FB4F,
+ 0x4648C2E8, 0x40104728, 0x6B09EB0F, 0x68A1780F,
+ 0x4102700C, 0x43E1704C, 0x45C1708C, 0xFB6F0AAE,
+ 0x258C70CC, 0xC6C81E3F, 0x4050C2E8, 0x47CB4528,
+ 0x04988000, 0x8703E81B, 0xE8877104, 0x71001600,
+ 0x025C9004, 0x720CA703, 0x900746CB, 0x0B1EC25C,
+ 0x1E0000A0, 0x16001005, 0x80007080, 0x2053000C,
+ 0xF223817E, 0x90051ECC, 0xC808F021, 0x46CB70AD,
+ 0xC3EC9007, 0x21056832, 0x903B0F80, 0xB0A0C02C,
+ 0x268079C5, 0xD8141939, 0x0A7EB1A0, 0xB6A000A0,
+ 0x90451E2C, 0x93441ED8, 0x93441ED4, 0xB6068703,
+ 0x93441EE0, 0x1ECCC6C8, 0x740C9344, 0x900746CB,
+ 0x0ABAC224, 0xB6A000A0, 0x10051E08, 0x20300819,
+ 0x90051E58, 0x20710823, 0x1E00700C, 0x90077285,
+ 0xF010C254, 0xB802C808, 0x0F802005, 0xC3EC9007,
+ 0x00451800, 0x41C3F006, 0x0000034D, 0xFA8F0B8A,
+ 0x74041E00, 0xC2509007, 0xB802C808, 0x0F802005,
+ 0xC02C903B, 0x00851800, 0x78E0C6C8, 0xC1A2C3F2,
+ 0xB99FD925, 0x1C068900, 0x891B3002, 0x30021C07,
+ 0x800040C3, 0x88201224, 0x8822C161, 0x30421C05,
+ 0x88038821, 0x30421C02, 0xFEAF0896, 0x30021C03,
+ 0x70ED4110, 0x218121AD, 0x0FA9714E, 0x2A001465,
+ 0x70CD23D5, 0x0E99C806, 0x24401005, 0x60C83180,
+ 0xA000250B, 0x2714F242, 0x700E1380, 0x20142A00,
+ 0x30802440, 0x03932032, 0x60CDC081, 0x0B6D78AF,
+ 0x78CF2024, 0xFF6F0EF2, 0x6E3479EF, 0x800042C3,
+ 0xE81311DE, 0x20402040, 0x03C32116, 0x6D817910,
+ 0x61596179, 0x03021920, 0x0408212F, 0x61596179,
+ 0x03421920, 0x232FF016, 0x79F60408, 0x16006179,
+ 0x80007080, 0x240B0121, 0x6D01A000, 0xF2066159,
+ 0x00021920, 0xF005A9A0, 0x1920A900, 0x40020342,
+ 0x204072A5, 0xF1CC0050, 0xF1B671C5, 0xF1AF71E5,
+ 0x78E0C7D2, 0xDB24C2E6, 0x800042C3, 0xBB9F1224,
+ 0x00031A00, 0xE0078B00, 0x00C12841, 0x69898B1C,
+ 0xE80FAA81, 0x791DC805, 0x70801600, 0x003F8000,
+ 0xB9C6E007, 0xAA22B823, 0x68C96038, 0x4689F003,
+ 0x12B5AA22, 0x788F008D, 0xAAC37104, 0x7000240A,
+ 0x20A8770C, 0x71040180, 0x100D250F, 0x42C378CF,
+ 0x12D98000, 0x0064081B, 0x7822AAA0, 0x240A7104,
+ 0x20A87000, 0x250F0180, 0x7124104D, 0x70ADAAA0,
+ 0x800044CB, 0x0D4311DA, 0x408910B5, 0x706D70CD,
+ 0x0B3179AF, 0x70751095, 0x20CA4060, 0x80000F82,
+ 0x88E0003F, 0xFF6F0DE2, 0xE80578CF, 0xB8236F07,
+ 0x4F1FF003, 0x1802B824, 0x71C51012, 0xF1EB7165,
+ 0x71A57185, 0xC6C6F1E1, 0x0A22C0F1, 0xC0D10100,
+ 0x700C7FE0, 0xE9058840, 0x001F0A0B, 0xBAE07EE0,
+ 0x88217DE0, 0xF78AE1C0, 0x20E07354, 0x218007CD,
+ 0xA821003F, 0xF0086A21, 0x7CE07054, 0x08012154,
+ 0x6A29A821, 0xA8207FE0, 0x0443216F, 0x11FE8940,
+ 0x229F8101, 0x790C041F, 0x00802905, 0x71047FE0,
+ 0x2482C3F4, 0x16003302, 0x80007080, 0xB8C30004,
+ 0x800047CB, 0x205F1220, 0x41C30B16, 0x0000013F,
+ 0x2700702E, 0x18081580, 0x0C360001, 0xD80AFCEF,
+ 0xFF8F0EB6, 0x800042D3, 0x202F1138, 0x24400448,
+ 0x24403181, 0x08823142, 0x2440FEAF, 0x701431C3,
+ 0x1407F4E3, 0x0F763080, 0x1A00FD6F, 0x14052043,
+ 0x712C3080, 0xFDAF0966, 0x70AD4310, 0x712C4062,
+ 0x0F62704C, 0x1A00FFAF, 0x14062342, 0xC1823080,
+ 0x716C724C, 0x0A0A708C, 0x4010FAAF, 0x702CC083,
+ 0xFA6F0BEE, 0x258ADA80, 0x708E2002, 0x8F2070CD,
+ 0x0507222F, 0x0CD64062, 0xC540FF6F, 0xC1804002,
+ 0x716C724C, 0xFAAF09DA, 0x1401708C, 0x20533080,
+ 0xF20681BE, 0x60D8C083, 0x00431800, 0x258D7186,
+ 0x71C52A7F, 0x740C8F60, 0x014141C3, 0x0B820002,
+ 0x4202FCEF, 0xDE8070AD, 0x41C3C083, 0x00010142,
+ 0x0B6E60AA, 0x740CFCEF, 0x1E3F268D, 0x41C371A5,
+ 0x00000143, 0xFCEF0B5A, 0x248A740C, 0x77AD7002,
+ 0x776D700C, 0x20A8776C, 0xC1830740, 0x610977B5,
+ 0xE0FFF207, 0xE914F202, 0x6829E906, 0xE98FF005,
+ 0xF00E4508, 0x2302D97F, 0x49B210CC, 0x25CA7291,
+ 0x21CA10CC, 0x43A102CC, 0x77AD4328, 0x77747104,
+ 0x77B5F404, 0xF404DE7F, 0x46694568, 0x41A18F60,
+ 0x21B94EB0, 0x207F0FFF, 0x78240100, 0x014541C3,
+ 0x0FF60002, 0x4202FA6F, 0x41C366B8, 0x00030146,
+ 0x00942844, 0x42A1740C, 0x0AD643C1, 0x240AFCEF,
+ 0x8F200500, 0x843E2105, 0x26144620, 0x70022040,
+ 0x180860F8, 0xF20B0502, 0x2011081D, 0x00510E19,
+ 0x75021E00, 0x004E8000, 0x1E00F013, 0x80007502,
+ 0xF00F0033, 0x20510813, 0x00110E0F, 0x75021E00,
+ 0x00348000, 0x1E00F005, 0x80007502, 0x242F004F,
+ 0x250A0507, 0x245F0400, 0x20540140, 0x78300C81,
+ 0x02822845, 0x209E4040, 0x60380DBF, 0x014741C3,
+ 0x7B100005, 0xFCEF0A5A, 0x4062750C, 0x0946702C,
+ 0x1A00FDEF, 0x71262043, 0x0448202F, 0x061E7414,
+ 0x40C3FFC5, 0x12D88000, 0x00431800, 0x78E0C7D4,
+ 0x88606038, 0xA8607B45, 0x0083104B, 0x184B7B45,
+ 0x109600C2, 0x7B450083, 0x00C21896, 0x008310E1,
+ 0x7FE07A65, 0x008218E1, 0x2482C3EA, 0x266F3206,
+ 0xC0801243, 0xFF2F0812, 0x10901600, 0x800140C3,
+ 0x88404E77, 0x7A058813, 0x30811403, 0x30801416,
+ 0x78477825, 0x01BE080B, 0x0C2E700C, 0x256F03C0,
+ 0x150016C3, 0x081110C0, 0xC0800032, 0x0DAAD913,
+ 0xDAF3FB6F, 0x3BC02456, 0xFD6F0D16, 0x20D02053,
+ 0x3BC02456, 0x02A00946, 0xC080D90B, 0xDA45D910,
+ 0xFFEF0F72, 0x30112440, 0x3BC02456, 0x02A0092E,
+ 0x2456D946, 0x09263BC0, 0xD94702A0, 0x3BC02456,
+ 0x02A0091A, 0x2456D948, 0x09123BC0, 0xD94902A0,
+ 0x3BC02456, 0x02A00906, 0xCA0ED94A, 0x47CB704C,
+ 0x12208000, 0x00050A31, 0x2B01205F, 0x0F832232,
+ 0x04788000, 0x79557322, 0x673F7144, 0xAB208F28,
+ 0x1B968F2A, 0x8F290042, 0x00421B4B, 0x1BE18F2B,
+ 0xF1E70042, 0x3BC22456, 0x712CC080, 0x08BEDBFF,
+ 0x708C0460, 0xD910C080, 0xFB6F0CFE, 0x8D00DABC,
+ 0x005E0815, 0x08118E00, 0xC080017F, 0x0ED6D910,
+ 0xDA40FFEF, 0x02A0088A, 0x3BC02456, 0x3BC02456,
+ 0xFD6F0D66, 0xC027D910, 0x017F0819, 0xD91CC080,
+ 0xFFEF0EB2, 0x2456724C, 0x0D4E3BC0, 0xD91CFD6F,
+ 0x3BC22456, 0x702CC080, 0x0862DBFF, 0x708C0460,
+ 0x080F8D00, 0x8E00005E, 0x0ADCB8E5, 0x08A2FEC1,
+ 0x0A8EFCCF, 0x8D00FACF, 0xF29EB8E1, 0xB8E58E00,
+ 0x096AF49A, 0x0882FD8F, 0xD8100280, 0x0FC2D940,
+ 0xDA0FFB2F, 0x762C700C, 0xFB2F0ED6, 0x8F20714C,
+ 0x0582219F, 0x100017BC, 0x88216038, 0x00DF090D,
+ 0x20538814, 0xF23580FE, 0x2400702C, 0x00003F80,
+ 0x087E012C, 0xDA4BFA6F, 0x3A002456, 0x02A00816,
+ 0x00831800, 0x0B56700C, 0x712CFB2F, 0xFACF0A22,
+ 0x02800826, 0x752C700C, 0xFB2F0E86, 0x40C3714C,
+ 0x3A980000, 0x00600C4E, 0x0D0A742C, 0x710C0120,
+ 0x3F802400, 0x012C0000, 0x02800966, 0x000340C3,
+ 0x0C320D40, 0xD9080060, 0x01200D5A, 0xD810710C,
+ 0x0F2E702C, 0xDA0FFB2F, 0x762C700C, 0xFB2F0E42,
+ 0x700C714C, 0x704CD932, 0x708C706C, 0x0B3E73AC,
+ 0x70CCFB2F, 0xD933700C, 0x706CDA20, 0x73AC708C,
+ 0xFB2F0B2A, 0x700C70CC, 0x0E16762C, 0x714CFB2F,
+ 0xD938D811, 0xFB2F0EEA, 0x700CDA0F, 0x0E02D907,
+ 0x714CFB2F, 0xD930700C, 0x706C704C, 0x73AC708C,
+ 0xFB2F0AFA, 0x700C70CC, 0x704CD931, 0x708C706C,
+ 0x0AEA73AC, 0x70CCFB2F, 0x762C700C, 0xFB2F0DD2,
+ 0x0F42714C, 0x700C0240, 0xFB2F0A82, 0x0FC2712C,
+ 0xF027FD8F, 0xDA20D825, 0x706CB89F, 0x70CC708C,
+ 0x881B8820, 0xD90B7825, 0x00452053, 0xFB2F0AAE,
+ 0x700C700C, 0x724CD928, 0x708C706C, 0x0A9E73AC,
+ 0x70CCFB2F, 0xD907700C, 0x706CDA1E, 0x70AC708C,
+ 0xFB2F0A8A, 0x700C70CC, 0xFB2F0A32, 0x702C712C,
+ 0x70441E00, 0xC200901F, 0x70801600, 0x00968000,
+ 0x011E0815, 0xB802C808, 0x0F802005, 0xC0049007,
+ 0x00451800, 0x900840C3, 0xB02001B8, 0x1CC3266F,
+ 0x8E00B036, 0xF01AE89E, 0x1600E908, 0x80007080,
+ 0xE88B0040, 0xF011710C, 0x70801600, 0x00258000,
+ 0x700C7014, 0x710CF209, 0x0A327838, 0x780FFD6F,
+ 0xFB8F0986, 0x68218F00, 0x792FAF20, 0x809409CD,
+ 0xFD6F0A1A, 0x70AD730C, 0x8E20B7A0, 0x0C82E984,
+ 0x8E200240, 0x900740C3, 0xB0A0C2CC, 0xE989B0A2,
+ 0x71001600, 0x00108000, 0x09F07114, 0x0F820242,
+ 0x08DAFF0F, 0xC7CAFD8F, 0x78E07EE0, 0x7FE0700C,
+ 0x00C420AB, 0x1CFCC2FA, 0xC1A2B6C8, 0xC8084608,
+ 0x006E41C3, 0xB8020002, 0x0F802005, 0x200C900C,
+ 0x78BD90A0, 0x70901600, 0x00048000, 0x004F2044,
+ 0x10432544, 0x42E1D80A, 0xFCAF0E36, 0x20534078,
+ 0xC04020C0, 0xC200EF8A, 0x006F41C3, 0x0E220001,
+ 0xD80AFCAF, 0x000003E5, 0xB802C808, 0x0F802005,
+ 0x140C9000, 0x30310821, 0x01131000, 0x10C02D41,
+ 0x1AC125AD, 0x0F832084, 0x60B8742C, 0x0380205A,
+ 0xF004E038, 0x732CD870, 0x6038710E, 0x1E007017,
+ 0x90037404, 0x1E00D878, 0x90077404, 0x02F4F87C,
+ 0xC0410022, 0x02EC70D5, 0x710C0021, 0x01000AA6,
+ 0x45CBC808, 0xC400900F, 0x14CE2550, 0xB802726D,
+ 0x03412005, 0x190078C5, 0x180002C4, 0x099E02C4,
+ 0xD81E0060, 0x36091208, 0x702E700D, 0x70CC71EC,
+ 0x00100F11, 0x70801600, 0x00258000, 0xF053E888,
+ 0x70801600, 0x00408000, 0x001008A7, 0x00052752,
+ 0x3000264A, 0x33002E40, 0x70C0704C, 0x200572EF,
+ 0x0E090244, 0xEAB830D1, 0x31310E17, 0x8080270B,
+ 0x1600F207, 0x80007081, 0x095D0025, 0x0E1B0050,
+ 0x220B3131, 0xF2098140, 0x70811600, 0x00408000,
+ 0x0051090F, 0x2678F020, 0x794B3141, 0x215AF41C,
+ 0x41C32503, 0x12E08000, 0x71266A94, 0x43C36179,
+ 0x0FF10000, 0x43C3B166, 0x05248000, 0x1908639A,
+ 0x82E30003, 0x22058241, 0xA1E40102, 0x6462A141,
+ 0xA1407A05, 0x31FF278D, 0x2640714C, 0x0E79305E,
+ 0x46C3B194, 0x70000000, 0x193E238D, 0x40C370EC,
+ 0x12D98000, 0x00841000, 0x43C371CC, 0x05448000,
+ 0x022E0C6B, 0x72AC700C, 0x00072E00, 0x02002014,
+ 0x244AB80C, 0x20057180, 0x4308025F, 0x3000264A,
+ 0x088020A8, 0x310C2E40, 0x89086399, 0x8000270B,
+ 0x215AF218, 0x40C32502, 0x12E08000, 0x60587126,
+ 0x000042C3, 0xB0460FF1, 0x81218143, 0x07C12105,
+ 0x01821808, 0x6461A021, 0x02C12105, 0xA020A044,
+ 0x305E2640, 0x04BF258D, 0x7105710C, 0x91140895,
+ 0x41C34022, 0x00010069, 0x024120BC, 0xFA6F094A,
+ 0x21424222, 0x42D3A03C, 0x12E48000, 0x2344F20B,
+ 0x22402042, 0xD9F12140, 0x014020A8, 0x1814A822,
+ 0x706D0092, 0x79EDDFF1, 0xFE2F0862, 0x71654022,
+ 0x14310B11, 0x702C4022, 0x01A00A56, 0x706DDA10,
+ 0x7F0D6F01, 0x94120FE3, 0x702C4022, 0x01A00A42,
+ 0x21424261, 0xF20DA03C, 0x2006710C, 0x224004C1,
+ 0x20A82140, 0x180201C0, 0x181403C3, 0x706D0052,
+ 0x4022DF0F, 0xFE2F0816, 0x716541E1, 0x14310B11,
+ 0x712C4022, 0x01A00A0A, 0x706DDA10, 0x7F0D6F09,
+ 0x9C3F278C, 0x4022F62F, 0x09F6712C, 0x426101A0,
+ 0x2030098F, 0x230A708E, 0x702F3440, 0x350F215A,
+ 0x23D32200, 0x20D51308, 0x23F10D1F, 0x20D61309,
+ 0x14822730, 0xDB0F740C, 0x006441C3, 0x0B720003,
+ 0x240AFCAF, 0x268C0580, 0xF40DAC7F, 0x14822730,
+ 0x43A2740C, 0x006541C3, 0x0B560003, 0x248AFCAF,
+ 0x26000C7F, 0x27302540, 0x28441482, 0x13040097,
+ 0x252F2080, 0xE80705C5, 0x41C3740C, 0x00040066,
+ 0x740CF005, 0x006741C3, 0x43A20004, 0xFCAF0B22,
+ 0x0580240A, 0x238D7127, 0x1B06313F, 0x402225C2,
+ 0x04200BE2, 0xC808702C, 0x2005B802, 0x78C50341,
+ 0x05041900, 0x05041800, 0x0120084A, 0xC808710C,
+ 0x7D05B802, 0x1D007E05, 0x1E001045, 0xF0061045,
+ 0x74041E00, 0xC02C9003, 0x0260083E, 0x4008710C,
+ 0x00200ECA, 0x45CBD80D, 0xE008900F, 0x255070CD,
+ 0xB5C014CB, 0x13841B00, 0x00200E4E, 0x1D00C001,
+ 0x08231404, 0x1B003031, 0xC8081404, 0x40C36832,
+ 0xC400900F, 0x00022105, 0x7825B8B3, 0xB0C0B2C0,
+ 0x40C3F00C, 0xC02C9003, 0xB8AFB0C0, 0x70451E00,
+ 0x802C9001, 0x00451800, 0x1E0070CD, 0x90037384,
+ 0x1E00D878, 0x90077384, 0x0FCEF87C, 0x40010220,
+ 0x45CBD820, 0x03E09008, 0x00200DEE, 0x10451D00,
+ 0x0DE6D820, 0xB5C00020, 0xD80AC200, 0x007041C3,
+ 0x0A3E0002, 0x4303FCAF, 0x1404C0A2, 0xC6DA341B,
+ 0x1CFCC2F8, 0x2482B6C8, 0x44303902, 0xB910D9AB,
+ 0x30001C84, 0x4670740C, 0xFCAF0A16, 0xD9204550,
+ 0x89A0B99F, 0x11002553, 0x8961A900, 0x01002353,
+ 0xA9017BA5, 0x813E2353, 0x808C11F7, 0x11002453,
+ 0x800219F7, 0x808211F8, 0x01002253, 0x800219F8,
+ 0x1901F405, 0x19000043, 0x7A850043, 0x813E2253,
+ 0x19F8F405, 0x19F78043, 0x0E1D8043, 0x740C2030,
+ 0x20710E23, 0x09BAD92B, 0xB912FCAF, 0x712E700F,
+ 0xF01070EE, 0x09AAD9AD, 0xB910FCAF, 0x710F70EE,
+ 0xD957F007, 0xFCAF099A, 0x71EEB911, 0x722E700F,
+ 0xBD9FDDEE, 0x15328DC0, 0x70D5109B, 0x0ECA40D1,
+ 0x23CA03A0, 0x1C8C3022, 0xE8123000, 0x740CD9AF,
+ 0xFCAF096E, 0xD825B910, 0x8840B89F, 0x00412244,
+ 0xA8204250, 0x274488FB, 0xA83B1041, 0x740CD90B,
+ 0xFCAF094E, 0x8D00B914, 0x120C4182, 0x20793085,
+ 0x14840006, 0x42A23000, 0x0D8A43C2, 0x240AFBEF,
+ 0x160006C0, 0x80007080, 0x081B000B, 0xD9B1003E,
+ 0x091E740C, 0xB910FCAF, 0x41A240E2, 0xFDAF0C7A,
+ 0x20054203, 0x148C35C0, 0x1C883001, 0x78253000,
+ 0x0051085F, 0xE8AD8D00, 0x740CD959, 0xFCAF08F2,
+ 0x2479B911, 0x40E22003, 0x42A2702C, 0x0440240A,
+ 0x01200EBE, 0x46084370, 0x40E2E88A, 0x42A2712C,
+ 0x0EAE4362, 0x240A0120, 0x46080440, 0x740CD9B3,
+ 0xFCAF08BE, 0x40E2B910, 0x0C1E41A2, 0x4203FDAF,
+ 0xFE2F0DE6, 0x709640C1, 0xFB2209A4, 0x0F1740A2,
+ 0x740C2030, 0x089AD92D, 0xB912FCAF, 0x04800AE6,
+ 0xD9B5F057, 0xFCAF088A, 0x120CB910, 0x24793081,
+ 0x20782003, 0x40032004, 0x04A00806, 0xCA0C42A2,
+ 0x060A212F, 0x00002078, 0x084D7825, 0xD840003F,
+ 0xB89F700E, 0x88C0722E, 0x808010E5, 0x0E237E05,
+ 0x4002142E, 0x70931600, 0x00048000, 0xFBEF0C5A,
+ 0x4200712C, 0x4162700C, 0xFCEF0B62, 0x218D4302,
+ 0x710E2C7F, 0x740CD95B, 0xFCAF0826, 0x09DEB911,
+ 0x40A2FB2F, 0x0343206F, 0x10C29020, 0x09330700,
+ 0x0C2F0004, 0x16002011, 0x80007100, 0x09230188,
+ 0x0E9E0005, 0x2005FC8F, 0x08170600, 0xD9B70071,
+ 0x0FEE740C, 0xB910FC6F, 0xFB2F0ABE, 0x8D0040A2,
+ 0xF47C7114, 0x7014CA06, 0x700CF278, 0x20300C15,
+ 0x30001C90, 0xFC8F0E6A, 0x710CE804, 0x30001C90,
+ 0x708E1600, 0x12228000, 0x16007DCF, 0x80007080,
+ 0x08C51223, 0x40C30344, 0x12D98000, 0x08B58800,
+ 0x40A2036E, 0x0260092E, 0x702E41A1, 0x30001CA0,
+ 0x300014A0, 0x046E0897, 0x706E720C, 0x30001C94,
+ 0xB89FD825, 0x881B8820, 0x710C7905, 0x04C02800,
+ 0x200FB802, 0x782B04C0, 0x1490F231, 0x40C33010,
+ 0x28F00000, 0x231F791B, 0x201F2002, 0xB8222041,
+ 0x436278AA, 0x6219623A, 0x209A4022, 0x704C0184,
+ 0x41E26038, 0x800070C3, 0x1C981A3C, 0x24793000,
+ 0x1C9C2000, 0x14983000, 0x0B623000, 0x149C0460,
+ 0x14983004, 0x41E23000, 0x3004149C, 0x0B4E714C,
+ 0x43620460, 0x710E7016, 0x1494F3D3, 0x716E3000,
+ 0x08817704, 0x1C948031, 0x71263000, 0xA2940965,
+ 0xF19C71C5, 0x0100099A, 0x3000148C, 0x026E7014,
+ 0x0C0A0001, 0x24790380, 0x1C05200E, 0x40633002,
+ 0x42C141E2, 0xFE2F0A3A, 0xD917C380, 0x0EC2740C,
+ 0xB913FC6F, 0x30001488, 0x256FE81A, 0x700C1243,
+ 0x10901500, 0xFBEF0AC2, 0x4200712C, 0x4102700C,
+ 0xFCEF09CA, 0x8DA0706C, 0x0AAE710C, 0x712CFBEF,
+ 0x700C4200, 0x09B641A1, 0x716CFCEF, 0x2744DD40,
+ 0xBD9F1080, 0xAD0070F6, 0x20802244, 0x90021DE5,
+ 0x09DAF27E, 0x710CFD2F, 0x800046CB, 0x8E221B3C,
+ 0x140C714C, 0x782A3100, 0x61199620, 0x0EB6710C,
+ 0x21ADFA6F, 0x40C30883, 0x25788000, 0x140C8842,
+ 0x7A2A3101, 0x710C9020, 0x724C6159, 0xFA6F0E96,
+ 0x088321AD, 0xFD2F0996, 0x40C3720C, 0x2FB48000,
+ 0x140C8842, 0x7A2A3101, 0x710C9020, 0x714C6159,
+ 0xFA6F0E72, 0x088321AD, 0x800040C3, 0x884239F0,
+ 0x3101140C, 0x90207A2A, 0x6159710C, 0x0E56724C,
+ 0x21ADFA6F, 0x09560883, 0x730CFD2F, 0x3085120C,
+ 0x14844182, 0x42A23000, 0x708C43C2, 0xFBEF0A26,
+ 0xD9B971CC, 0xB910740C, 0x0DC6ADE0, 0x1DE5FC6F,
+ 0x40C39482, 0x12228000, 0x008810B7, 0x88608841,
+ 0x01007350, 0x0835000D, 0x244A10EE, 0x700C7280,
+ 0x050020A8, 0x209A68A1, 0x231A0184, 0x00000F81,
+ 0x60380A3C, 0x800041C3, 0x603C442C, 0x60D860D1,
+ 0x8802B420, 0x40A1AC02, 0xF1E47164, 0x3085120C,
+ 0x14844182, 0x42A23000, 0x708C43C2, 0x09B671CC,
+ 0x700EFBEF, 0x740CD95D, 0xADE0B911, 0xFC6F0D52,
+ 0x94821DE5, 0x3081120C, 0x42A24003, 0x0CD243C1,
+ 0x708C0460, 0x212FCA0C, 0x2078060A, 0x78250000,
+ 0x001F0845, 0x15E58DE0, 0x72AD9080, 0x0F237F05,
+ 0x4002142E, 0x708E1600, 0x00048000, 0xFBEF092A,
+ 0x4200712C, 0x41C1700C, 0xFCEF0832, 0x258D4302,
+ 0x710E1C7F, 0x740CD9BB, 0xFC6F0CF6, 0x0EAEB910,
+ 0x40A2FAEF, 0x0343206F, 0x10C29020, 0x09390700,
+ 0x0C350004, 0x16002011, 0x80007100, 0x09290188,
+ 0x0B6E0005, 0x2005FC8F, 0x081D0600, 0xD92F0071,
+ 0x0CBE740C, 0xB912FC6F, 0xFAEF0F8E, 0xF00440A2,
+ 0x04400F02, 0x30001488, 0x256FE819, 0x700C1243,
+ 0x08B68DC0, 0x712CFBEF, 0x710C4200, 0x0FBE41C1,
+ 0x706CFCAF, 0x710C8DA0, 0xFBEF089E, 0x4200712C,
+ 0x41A1710C, 0xFCAF0FA6, 0x2480716C, 0x14043902,
+ 0xC6D8341B, 0x68614200, 0x7054CA08, 0x20AA7B19,
+ 0x081700C4, 0x23CA003F, 0x720C0021, 0x00C420AB,
+ 0x20AB710C, 0x0B1100C4, 0x16000415, 0x901C7100,
+ 0xF01B0490, 0x010420AA, 0x0A1B7A12, 0x24AA00E5,
+ 0x21AA1144, 0x08FF0104, 0x4B508044, 0x114424AA,
+ 0x6078F002, 0x010421AA, 0x20E17110, 0x22AA07C6,
+ 0x0CF50144, 0x7EE09080, 0x0443226F, 0x8A004300,
+ 0x0A0F239A, 0x00802079, 0x12FE6822, 0x78398100,
+ 0x70002E05, 0x4240000F, 0xFFEF077D, 0x00002B05,
+ 0x0826C0F1, 0x0F720000, 0xC0D1FFCF, 0x78E07EE0,
+ 0x4328C0F1, 0x00200812, 0x7071702C, 0x7FE0C0D1,
+ 0x02C520CA, 0x0343226F, 0x000370D3, 0x92600D41,
+ 0x0F8628C5, 0x86A00001, 0x00C620DA, 0x052628C5,
+ 0x00C520DA, 0x0F8528C5, 0x8480001E, 0x69818A62,
+ 0x71046078, 0x00C02805, 0x800043C3, 0x8B601138,
+ 0x12FBEB0D, 0x0A178082, 0x43C300DF, 0x121E8000,
+ 0xEA058B40, 0x8B817A2C, 0x74107C4C, 0x20CA7FE0,
+ 0x78E0030D, 0x0DBAC2EE, 0x2053FDCF, 0x206D00C1,
+ 0x50160900, 0x43D3782A, 0x003F8000, 0x13005015,
+ 0x13012080, 0xE9112081, 0x029741C3, 0x083A0000,
+ 0x2079FA2F, 0xCA140000, 0x20811300, 0x206CB802,
+ 0x61190080, 0xD953F011, 0x00002078, 0xFA2F081A,
+ 0x1600B913, 0x80007081, 0xC8060024, 0x0091080B,
+ 0x781DC805, 0x7A2F5015, 0x807E2153, 0x00832A41,
+ 0x23C0BA23, 0x21530062, 0x1A028080, 0x22C03002,
+ 0xD80A0062, 0x029941C3, 0x1A010002, 0x0AD230C2,
+ 0x1A00FC6F, 0x226F3082, 0x41C320C3, 0x0006029B,
+ 0x20801200, 0xD87FB8E2, 0x01E220CA, 0x30021A03,
+ 0x1205D80A, 0x12002486, 0x120C2107, 0x120A2085,
+ 0x13012104, 0x0A9A2083, 0x121FFC6F, 0x121F2082,
+ 0xB8E02080, 0xDE66F2AB, 0x02A447CB, 0xBE9F0005,
+ 0x41E1D80A, 0x948616FC, 0x948516FC, 0x10841600,
+ 0x908316FC, 0x908216A6, 0xFC6F0A66, 0x2640BAC3,
+ 0x8E6C160D, 0x10861500, 0x1401274F, 0x908515FC,
+ 0x15F8D80A, 0x16A69084, 0x0A469082, 0xBAC3FC6F,
+ 0x14102540, 0x10008D64, 0x274F2086, 0x10FC144D,
+ 0xD80AA085, 0xA08410F8, 0x16A641A1, 0x0A229082,
+ 0xBAC3FC6F, 0x240F2040, 0x20831004, 0x14861710,
+ 0x1401254F, 0x908517EC, 0x17E8D80A, 0x16A69084,
+ 0x09FE9082, 0xBAC3FC6F, 0x948617FC, 0x1700D80A,
+ 0x41C31085, 0x000502A8, 0x908417FC, 0x17F84030,
+ 0x16A69083, 0x09DA9082, 0xBAC3FC6F, 0x150D2740,
+ 0x15008F68, 0x204F1086, 0x15FC2401, 0xD80A9085,
+ 0x908415F8, 0x908216A6, 0xFC6F09B6, 0x2540BAC3,
+ 0x8D64140F, 0x10861700, 0x2441204F, 0x908517FC,
+ 0x17F8D80A, 0x16A69084, 0x09969082, 0xBAC3FC6F,
+ 0x120D2740, 0x15008F64, 0xD80A1084, 0x908216A6,
+ 0x02AB41C3, 0x097A0003, 0xBAC3FC6F, 0x10861510,
+ 0x2481204F, 0x1085150C, 0x1508D80A, 0x8D641084,
+ 0x908216A6, 0xFC6F095A, 0x151CBAC3, 0xD80A1085,
+ 0x10841518, 0x02AD41C3, 0x8D740004, 0x908216A6,
+ 0xFC6F093E, 0x121FBAC3, 0xB8E12080, 0xDE67F2A8,
+ 0x02AE45CB, 0xBE9F0005, 0x41A1D80A, 0x948616FC,
+ 0x948516FC, 0x14841618, 0x908316E4, 0x9082168D,
+ 0xFC6F090E, 0x16FCBAC3, 0x254F9486, 0x16001401,
+ 0xD80A1085, 0x908416FC, 0x908316F8, 0x90821691,
+ 0xFC6F08EE, 0x2640BAC3, 0x8E68150D, 0x10861500,
+ 0x15FCD80A, 0x41C39085, 0x000502B0, 0x908415F8,
+ 0x16914030, 0x08CA9082, 0xBAC3FC6F, 0x140F2540,
+ 0x17008D64, 0x204F1086, 0x17FC2401, 0xD80A9085,
+ 0x908417F8, 0x90821691, 0xFC6F08A6, 0x2740BAC3,
+ 0x8F64140D, 0x10861500, 0x2441204F, 0x908515FC,
+ 0x15F8D80A, 0x41309084, 0x90821691, 0xFC6F0882,
+ 0x2540BAC3, 0x8D64140F, 0x10861700, 0x2401214F,
+ 0x908517FC, 0x17F8D80A, 0x16919084, 0x08629082,
+ 0xBAC3FC6F, 0x140D2740, 0x15088F64, 0x204F1486,
+ 0x15F4248F, 0xD80A9085, 0x908415F0, 0x169141E1,
+ 0x083E9082, 0xBAC3FC6F, 0x10841500, 0x15FCD80A,
+ 0x41C39083, 0x000302B5, 0x90821691, 0xFC6F0822,
+ 0x1510BAC3, 0x274F1086, 0x150C1441, 0xD80A1085,
+ 0x10841508, 0x16918D64, 0x08069082, 0xBAC3FC6F,
+ 0x1085151C, 0x1518D80A, 0x41C31084, 0x000402B7,
+ 0x16918D74, 0x0FEA9082, 0xBAC3FC2F, 0x20801301,
+ 0xF2ABB8E0, 0xD80ADE68, 0x41C3BE9F, 0x000502B8,
+ 0x16FC4030, 0x16FC9486, 0x16009485, 0x16FC1084,
+ 0x16A49083, 0x0FBA9082, 0xBAC3FC2F, 0x160F2640,
+ 0x17008E6C, 0x204F1086, 0x17FC2401, 0xD80A9085,
+ 0x908417F8, 0x908216A4, 0xFC2F0F96, 0x2740BAC3,
+ 0x8F64140D, 0x10861500, 0x2441204F, 0x908515FC,
+ 0x15F8D80A, 0x41309084, 0x908216A4, 0xFC2F0F72,
+ 0x2540BAC3, 0x8D64140F, 0x14861710, 0x2401214F,
+ 0x908517EC, 0x17E8D80A, 0x16A49084, 0x0F529082,
+ 0xBAC3FC2F, 0x948617FC, 0x2481204F, 0x10851700,
+ 0x17FCD80A, 0x40309084, 0x908317F8, 0x908216A4,
+ 0xFC2F0F2E, 0x2740BAC3, 0x8F68150D, 0x10861500,
+ 0x2401204F, 0x908515FC, 0x15F8D80A, 0x16A49084,
+ 0x0F0E9082, 0xBAC3FC2F, 0x140F2540, 0x17008D64,
+ 0x204F1086, 0x17FC2441, 0xD80A9085, 0x908417F8,
+ 0x908216A4, 0xFC2F0EEA, 0x2740BAC3, 0x8F64120D,
+ 0x10841500, 0x16A4D80A, 0x41C39082, 0x000302BF,
+ 0xFC2F0ECE, 0x1510BAC3, 0xD80A1086, 0x1085150C,
+ 0x02C041C3, 0x15080005, 0x8D641084, 0x908216A4,
+ 0xFC2F0EAE, 0x151CBAC3, 0xD80A1085, 0x10841518,
+ 0x02C141C3, 0x8D740004, 0x908216A4, 0xFC2F0E92,
+ 0x1301BAC3, 0xB8E12080, 0xDE69F2AA, 0x02C245CB,
+ 0xBE9F0005, 0x41A1D80A, 0x948616FC, 0x948516FC,
+ 0x14841618, 0x908316E4, 0x9082168B, 0xFC2F0E62,
+ 0x16FCBAC3, 0x254F9486, 0x16001401, 0xD80A1085,
+ 0x908416FC, 0x908316F8, 0x9082168F, 0xFC2F0E42,
+ 0x2640BAC3, 0x8E68150D, 0x10861500, 0x02C447CB,
+ 0x15FC0005, 0xD80A9085, 0x908415F8, 0x168F41E1,
+ 0x0E1E9082, 0xBAC3FC2F, 0x14102540, 0x10008D64,
+ 0x274F2086, 0x10FC1401, 0xD80AA085, 0xA08410F8,
+ 0x9082168F, 0xFC2F0DFA, 0x2040BAC3, 0x10042411,
+ 0x11002083, 0xBF912086, 0xA08511FC, 0x11F8D80A,
+ 0x41E1A084, 0x9082168F, 0xFC2F0DD6, 0x2140BAC3,
+ 0x1104240D, 0x15002083, 0x274F1086, 0x15FC1401,
+ 0xD80A9085, 0x908415F8, 0x9082168F, 0xFC2F0DB2,
+ 0x2540BAC3, 0x8D64140F, 0x14861708, 0x02C845CB,
+ 0x17F40005, 0xD80A9085, 0x908417F0, 0x168F41A1,
+ 0x0D8E9082, 0xBAC3FC2F, 0x10841700, 0x17FCD80A,
+ 0x41C39083, 0x000302C9, 0x9082168F, 0xFC2F0D72,
+ 0x1710BAC3, 0x254F1086, 0x170C1441, 0xD80A1085,
+ 0x10841708, 0x168F8F64, 0x0D569082, 0xBAC3FC2F,
+ 0x1085171C, 0x1718D80A, 0x41C31084, 0x000402CB,
+ 0x168F8F74, 0x0D3A9082, 0xBAC3FC2F, 0x71001600,
+ 0x02009030, 0xB82271ED, 0x10002706, 0x30021A08,
+ 0x21001200, 0x0F85082B, 0x0A6B0000, 0x244AC808,
+ 0x68527200, 0x20A8700C, 0x22050340, 0x70C30001,
+ 0x40000000, 0x0F812105, 0x004C9038, 0x0BAAB1E0,
+ 0x46CBFE0F, 0xC1DC901F, 0x1443256F, 0x73C41E00,
+ 0x04A0901C, 0x73C41E00, 0xC294900B, 0x10051E00,
+ 0x41C3740C, 0x000102CE, 0xFC2F0CC6, 0x0BD68D40,
+ 0x8D00FAAF, 0x02CF41C3, 0x0CB60000, 0x750CFC2F,
+ 0x120AB6F2, 0x08152100, 0x16000050, 0x80007080,
+ 0xB8E40004, 0x010109F4, 0x70801600, 0x01148000,
+ 0x0CEC7014, 0x16000182, 0x80007080, 0x205300F4,
+ 0xF20B80FE, 0x813E206C, 0x208CF207, 0xF7068FC2,
+ 0x1A20B825, 0xC6CE301C, 0x301D1A20, 0x78E0C6CE,
+ 0x0E3EC2E2, 0x40C3FA0F, 0x0BB80000, 0xFFEF0886,
+ 0x252F702C, 0xF20D9007, 0xD907700C, 0x706C704C,
+ 0x73AC708C, 0xFA6F0F96, 0x258C70CC, 0xD8801E3F,
+ 0x704CD907, 0x708C706C, 0x0F8273AC, 0x70CCFA6F,
+ 0x0F2A700C, 0x712CFA6F, 0x78E0C6C2, 0x1CFCC2FA,
+ 0x2482B6C8, 0xC0413C09, 0x70C01600, 0x001F8000,
+ 0x00320817, 0x0E06DE51, 0xC0010020, 0x3C092480,
+ 0x341B1404, 0x740CC6DA, 0x0BE6BE13, 0x41C1FC2F,
+ 0x3F002456, 0x70901600, 0x12238000, 0x708D1600,
+ 0x12228000, 0x0BEA702C, 0xDA90F9AF, 0x3A802456,
+ 0x0BDE702C, 0xDA90F9AF, 0x70921600, 0x001F8000,
+ 0x21402244, 0x1401264F, 0xF9EF08AE, 0x01402079,
+ 0x20402244, 0x20912244, 0x2244C044, 0xC0432100,
+ 0x0442242F, 0x740CC303, 0x41C3C204, 0x0003028A,
+ 0xFC2F0B7E, 0xC808BB22, 0x2005B802, 0x90380F80,
+ 0x90000008, 0xB8C2C049, 0x0050080D, 0x80B10871,
+ 0xF003720C, 0xC045710C, 0xC04278BB, 0x2014710C,
+ 0x226D0400, 0x41C32902, 0x0001028B, 0x740CC048,
+ 0x0B3E70ED, 0x4450FC2F, 0x01A00B2E, 0xC001C001,
+ 0x01E00CC2, 0x2F4079EF, 0x45101310, 0x0DCB70AD,
+ 0x2D40236E, 0x275A120E, 0x26051500, 0x726E140E,
+ 0x78B4704E, 0x800170C3, 0x18004DAC, 0x43420405,
+ 0x238C2200, 0x0201239F, 0xC8084CAA, 0x1488275A,
+ 0x42C37905, 0x00009004, 0x2455B902, 0x79453C0B,
+ 0x10CB2300, 0x01061100, 0x2300C18C, 0x6179120B,
+ 0x14032440, 0x134B2314, 0x71017865, 0x1B00B802,
+ 0x78451184, 0x100079B4, 0x740C0105, 0x01441900,
+ 0x028C41C3, 0x42420005, 0x0AA643E1, 0x44A1FC2F,
+ 0x20510C41, 0x000040C3, 0x271A0A3C, 0xB8021001,
+ 0x2000221F, 0x40A16119, 0x0184209A, 0xC8086119,
+ 0x210078C5, 0x80000F82, 0xB8021B40, 0x800071C3,
+ 0x20056D20, 0x90040F80, 0x90000320, 0xB100B200,
+ 0x2BFE238D, 0x71A5714E, 0x92540D37, 0x0F2371E5,
+ 0x244A9114, 0xD8987140, 0x903B43DB, 0x20A8C000,
+ 0x20050200, 0x740406C1, 0x00C51900, 0x20B10C11,
+ 0x20412478, 0x000047CB, 0xF00586B0, 0x000047CB,
+ 0x2940265C, 0xE90520C0, 0x000147CB, 0x20523694,
+ 0xC04A0100, 0xFCAF0DFA, 0xDE25700C, 0xBE9F716E,
+ 0x029040DB, 0xC8080005, 0x2005B802, 0x903B0F80,
+ 0x0B11C008, 0x228A2071, 0x18002802, 0xF0060045,
+ 0x2902228A, 0x01451800, 0x30171428, 0xC808708E,
+ 0x7140244A, 0x20A84242, 0x22050440, 0xE2100001,
+ 0x2105B902, 0x210506C3, 0x903B0F81, 0x1B00C004,
+ 0x190005C4, 0x160005C4, 0x80007080, 0x08110001,
+ 0xDD6400BF, 0x708D1600, 0x01208000, 0xE88BC003,
+ 0xD80FC201, 0x716C742C, 0x70AC44A1, 0xFB6F0DD6,
+ 0xC00470CC, 0xC201E88A, 0x742CD80F, 0x44A1706C,
+ 0x0DC270AC, 0x70CCFB6F, 0x70AE720C, 0xC047C046,
+ 0x8E3B8E00, 0x710C7905, 0x05402800, 0x200FB802,
+ 0x782B0540, 0x740CF2A6, 0x028D41C3, 0x42620003,
+ 0x093E43E2, 0x240AFC2F, 0x16000540, 0x80007091,
+ 0x16001222, 0x80007080, 0x210C1223, 0x0124A000,
+ 0x40C3000D, 0x12D98000, 0x20118800, 0xF2888440,
+ 0x0AA2C001, 0x212F01E0, 0x700E0447, 0x2448262F,
+ 0xC00BC04B, 0x042E08F3, 0x1408252F, 0xE8ABC004,
+ 0xE8B4C003, 0x41C240A2, 0x7F6042A1, 0x4118706C,
+ 0x4103740C, 0x43A24222, 0x0400240A, 0x05C0250A,
+ 0xFC2F08CE, 0x0640260A, 0x41C240A2, 0x7F6042A1,
+ 0x4508716C, 0x3401204F, 0x4222740C, 0x240A43A2,
+ 0x250A0400, 0x08AA05C0, 0x46A1FC2F, 0x164D2509,
+ 0x40A2F01F, 0x42A141C2, 0x706C7F60, 0x740C4508,
+ 0x028E41C3, 0xF00C0005, 0x41C240A2, 0x7F6042A1,
+ 0x4508716C, 0x41C3740C, 0x0005028F, 0x43A24222,
+ 0x0400240A, 0x05C0250A, 0xFC2F0866, 0x43A246A1,
+ 0x248C215A, 0x0201239F, 0x3A802456, 0x60986078,
+ 0x04012014, 0x3F002456, 0x91406078, 0x03650A17,
+ 0x20146098, 0x42A10400, 0x1800B1A0, 0x40E205C4,
+ 0x20F4F003, 0xC2400400, 0x0008272F, 0x41C3740C,
+ 0x00070292, 0x432242A2, 0x0400240A, 0x05C0250A,
+ 0xFC2F080E, 0x710646A1, 0xA254080B, 0xF16B7126,
+ 0x71AEC007, 0x70147704, 0xF54CC047, 0x274C71E6,
+ 0x061EA800, 0x8E00FFC5, 0x79058E3B, 0x2800710C,
+ 0xB8020500, 0x0500200F, 0xF24C782B, 0x70901600,
+ 0x12228000, 0x70801600, 0x12238000, 0x04240877,
+ 0x40C34082, 0x12D98000, 0x08678800, 0x212F042E,
+ 0x09420407, 0xC00101E0, 0x2495205A, 0x70AD4610,
+ 0x236E0E49, 0x2500210A, 0x3A802456, 0x2201219F,
+ 0x70A27022, 0x034020F4, 0x700CE88A, 0x029341C3,
+ 0x42820003, 0x0C824302, 0x44A1F9AF, 0x2500205A,
+ 0x200078B4, 0x80010F81, 0x24564DAC, 0x70223F00,
+ 0x20F470A2, 0xB1000340, 0x0DB971A5, 0x71069254,
+ 0xC301F1C2, 0x000042C3, 0x0D9EBA68, 0x414203E0,
+ 0x718EC006, 0x08537704, 0xC0468031, 0x230CC005,
+ 0x0536A000, 0x7166FFE5, 0xC00170CD, 0x01E008B6,
+ 0x2E4079CF, 0x43101311, 0x0B7970AD, 0x2D40236E,
+ 0x704C1210, 0x24502005, 0x4340724E, 0x148C265A,
+ 0x0201239F, 0x3C002455, 0x04082200, 0x900447CB,
+ 0x20400000, 0x44A11481, 0x20006078, 0xC808030B,
+ 0x23F47905, 0xB9021349, 0x190079E5, 0x20400244,
+ 0x78251401, 0x029441C3, 0xB8020005, 0xC08C7F05,
+ 0x43C16078, 0x24F4641C, 0xB7001340, 0x24F4740C,
+ 0x0EAE1345, 0x23F4FBEF, 0x228D1346, 0x714C247F,
+ 0x0D8B71A5, 0x71C59254, 0x91140E73, 0x0882C001,
+ 0x712C03A0, 0x7A0FC008, 0x780FC002, 0x00040A29,
+ 0x6832C808, 0xB8C4C002, 0x7825B80E, 0x0F832005,
+ 0x00089038, 0xB300C009, 0x7104C002, 0x780FC042,
+ 0x80050AE5, 0x70801600, 0x01648000, 0xF42BB8E6,
+ 0x70801600, 0x001F8000, 0x00FF0839, 0x41C3740C,
+ 0x00000295, 0xFBCF0E3A, 0x256FC201, 0xD80F1A43,
+ 0x716C742C, 0xFF6F0BFE, 0x12051D00, 0xD80FC201,
+ 0x0BF2742C, 0x706CFF6F, 0xB88FD808, 0xF00BB500,
+ 0x029641C3, 0x0E0A0000, 0x740CFBEF, 0xFAEF0F7A,
+ 0x020DC001, 0x78E0FFCF, 0x1CFCC2FA, 0xC1BFB6C8,
+ 0xC8084410, 0x2005B802, 0x90380F80, 0x90000008,
+ 0x1600C043, 0x80007080, 0xC1030164, 0xC046B9C2,
+ 0x800040C3, 0x88601222, 0x00700911, 0x72348841,
+ 0x00220320, 0xF003720C, 0xC044710C, 0xC00671AD,
+ 0x780D7D54, 0xC0497F7B, 0x88002044, 0xF40EC047,
+ 0x7140244A, 0x20A8D898, 0x20050280, 0x903B0F81,
+ 0x7404C000, 0x00C51900, 0x01600D7E, 0xD8254082,
+ 0x33C7232F, 0x712FB89F, 0x881B8820, 0x20787825,
+ 0x710400C0, 0x78AFC048, 0x202FC041, 0xC0043647,
+ 0x02347013, 0x40820025, 0x752CC808, 0x2005B802,
+ 0x903B0F80, 0x0815C008, 0xC1453071, 0xDEA0712C,
+ 0x730CB020, 0xF009C040, 0x01451800, 0xDEA4740C,
+ 0x760CC040, 0x70ADC045, 0x7510C008, 0x000601F2,
+ 0x2578C007, 0x20791017, 0x27040000, 0x20782017,
+ 0x27043040, 0x0F1F2017, 0x244A2071, 0xD8987140,
+ 0x024020A8, 0x0F812005, 0xC000903B, 0x19007404,
+ 0x08DE0005, 0x710CFCAF, 0x30041400, 0x2347262F,
+ 0x218AD8C8, 0x43820004, 0x000042C3, 0x250ABA68,
+ 0x70CC0580, 0x02A0083E, 0xC0064250, 0x800140D3,
+ 0x08434DAC, 0x244000FF, 0x74AE3B13, 0x2400210A,
+ 0x41224062, 0xF96F0CB2, 0x2340DA14, 0x258D2513,
+ 0x21402EBF, 0x14142511, 0xD8C83004, 0x0004218A,
+ 0x43824242, 0x0580250A, 0x02600FFA, 0xC28B70CC,
+ 0x42C3F004, 0xBF648000, 0x244A746C, 0x20A87280,
+ 0x100002C0, 0x12022101, 0x60380500, 0x1802781D,
+ 0x238C2014, 0x084A0D7F, 0x700CFCAF, 0x0E424082,
+ 0x702C0360, 0x706E70F6, 0xF28570AE, 0x7140244A,
+ 0x20A8D998, 0x21050280, 0x903B0F80, 0x7424C000,
+ 0x04C41800, 0xF07773AE, 0x244AC808, 0x20057140,
+ 0x41C10342, 0x038020A8, 0x00402205, 0xB802E110,
+ 0x0F832005, 0xC000903B, 0xC042700C, 0x00051B00,
+ 0x30041400, 0x142440C1, 0xD9103006, 0x0FFF26BF,
+ 0x000042C3, 0x43822950, 0x02600F5A, 0x0580250A,
+ 0x2540203C, 0x26C0200A, 0xC001C04A, 0x04040895,
+ 0x212FC002, 0x20790402, 0xB9C60000, 0x00922840,
+ 0x0D524082, 0x702E01A0, 0x230C2840, 0x24055020,
+ 0x43C11342, 0x00482205, 0x20412044, 0x010B2140,
+ 0x22C50955, 0x04AE0849, 0x10C12005, 0x903842C3,
+ 0xB9020000, 0x00892105, 0x11061100, 0x270BC10A,
+ 0xF216A040, 0x29812140, 0xB9027985, 0x26537A25,
+ 0x091D00C1, 0x120003F1, 0x0F150107, 0x274000F0,
+ 0x19000041, 0xB2201184, 0x10051900, 0x7126E310,
+ 0xF1D87146, 0x7106C002, 0x00002052, 0xF1B7C042,
+ 0x202F7166, 0x0D1524C7, 0x71A5A405, 0x05CFF106,
+ 0x7127FFEF, 0x03600D1A, 0xC001712C, 0x06C40827,
+ 0x6852C808, 0x11002753, 0xB80E71E5, 0x20057845,
+ 0x90380F81, 0xC0030008, 0x79EFB100, 0x08E9C001,
+ 0x16008045, 0x80007080, 0x08590164, 0x1600019F,
+ 0x80007080, 0x083B001F, 0x740C00FF, 0x028641C3,
+ 0x0ADE0000, 0x256FFBCF, 0xD80F1A43, 0x4282742C,
+ 0x08A2716C, 0x1D00FF6F, 0xD80F1205, 0x4282742C,
+ 0xFF6F0892, 0xD808706C, 0xB500B88F, 0x41C3F00A,
+ 0x00000287, 0xFBEF0AAA, 0x0C1E740C, 0x4082FAEF,
+ 0x1404C0BF, 0xC6DA341B, 0x200AC2F6, 0x80010F80,
+ 0x20A78000, 0x200A0849, 0x80010F80, 0x20A78000,
+ 0x200A0949, 0x80010F80, 0x20A77000, 0x200A0809,
+ 0x80010F80, 0x20A77000, 0x200A0909, 0x00080F80,
+ 0x20296000, 0x206F0000, 0x100020C3, 0x701420C0,
+ 0x000B072C, 0x800047CB, 0x8F00019A, 0x1600E886,
+ 0x80007080, 0xE812019B, 0x00C420AA, 0x003F0811,
+ 0x20AB720C, 0x710C00C4, 0x00C420AB, 0x010420AA,
+ 0x20AA5031, 0x50320144, 0x19C3266F, 0x70451E00,
+ 0x0080900C, 0x903045CB, 0x16EF03B8, 0x0D4E9481,
+ 0x950002E0, 0x000041D3, 0x0E962503, 0x1E00FC6F,
+ 0x0E961444, 0x41C30080, 0x00000325, 0xFBEF09E2,
+ 0x0D2ED80A, 0x40C3FA0F, 0xA6350000, 0x902446CB,
+ 0xB60020A8, 0x0304208A, 0xD80AB602, 0x032741C3,
+ 0x09BE0001, 0x4222FBEF, 0xD80A9542, 0x41C39560,
+ 0x00050328, 0x910415FC, 0x71051600, 0x03B89008,
+ 0xFBEF099E, 0x910615F8, 0xFDCF0B6E, 0xB802C808,
+ 0x0F802005, 0x002C9008, 0xCA079020, 0x01B5081B,
+ 0x00CC2184, 0x8084218C, 0x41C3F407, 0x00000329,
+ 0xF96F0E76, 0xCC1E700C, 0x08139620, 0x700C0060,
+ 0x032A41C3, 0x0E620000, 0xCC1FF94F, 0x08139622,
+ 0x700C0060, 0x032B41C3, 0x0E4E0000, 0x1600F94F,
+ 0x80007080, 0xB8E00185, 0x00C20C54, 0x1243256F,
+ 0x800042D3, 0x8D001138, 0x9566B8C3, 0x1A00B814,
+ 0x0B1A2043, 0x50300160, 0xFDCF098E, 0xFDCF09AE,
+ 0xBBE0C808, 0xB8024170, 0x0F802005, 0x003C900C,
+ 0x01141000, 0x1E00F28D, 0x90087045, 0x0DD60288,
+ 0x710C0020, 0x70801600, 0x00198000, 0x1600E893,
+ 0x80007080, 0x080D000D, 0x8D00005E, 0x011E0817,
+ 0xE8898F00, 0x70801600, 0x019B8000, 0x0E947014,
+ 0x0D66FA41, 0x0B42FF4F, 0xD933FECF, 0x08B2740C,
+ 0xB914FBEF, 0xFE0F0B22, 0xF9CF0A86, 0x742C700C,
+ 0xFA2F0EEE, 0x700C704C, 0xFA2F0BA2, 0x0DE6712C,
+ 0x700C0020, 0x70801600, 0x000D8000, 0x005E080D,
+ 0xB8E48D00, 0x01410F30, 0x1A43266F, 0xFBEF09A2,
+ 0x10451E00, 0xFB0F0B06, 0xFECF0A06, 0x01000E4E,
+ 0x233E0939, 0xD80A70ED, 0x033341C3, 0x08520000,
+ 0xBF8CFBEF, 0x70801600, 0x01848000, 0x20CA7014,
+ 0x1A0B0321, 0x08123002, 0xB6E0F9AF, 0xB80CD809,
+ 0x0DCAB600, 0xD80D0020, 0x03400C2E, 0xF9CF0A02,
+ 0x000040C3, 0x0C4E3A98, 0x702CFF6F, 0xD907780F,
+ 0x02022048, 0x706C700C, 0x70AC708C, 0xFA2F0B5E,
+ 0x700C70CC, 0xFA2F0B06, 0x0DC6712C, 0x710CFA4F,
+ 0x20031A00, 0xB600B88F, 0x00200D82, 0x0B3E700C,
+ 0x710CFC6F, 0x207E092B, 0x41C3D80A, 0x000002F1,
+ 0xFB8F0FCE, 0x1A43266F, 0x0A2E710C, 0x1E0001A0,
+ 0x720C1085, 0xB600B88F, 0x00200D52, 0x095D710C,
+ 0xD9BB20BE, 0x0FAAD80A, 0xB912FBAF, 0xFBCF0FAE,
+ 0x1A43266F, 0xFAEF0ABE, 0x11051E00, 0x41C3E80F,
+ 0x000002ED, 0xFBAF0F8A, 0x09EED80A, 0xD80901A0,
+ 0xB88F740C, 0x750CB600, 0x41C3F00E, 0x000002EE,
+ 0xFBAF0F6E, 0x09D2D80A, 0x700C01A0, 0xB88F740C,
+ 0x720CB600, 0x00000CF6, 0x000042D3, 0x21044000,
+ 0xF215A495, 0x02EF41C3, 0x0F460000, 0xD80AFBAF,
+ 0x1A43266F, 0x09A2D80C, 0x1E0001A0, 0x730C1484,
+ 0xB600B80E, 0x00200CC6, 0x2144D814, 0xF205A216,
+ 0x02E008EA, 0x0939710C, 0xD80A21BE, 0x02F741C3,
+ 0x0F0E0000, 0xDF40FBAF, 0xFD8F0FA2, 0x1A43266F,
+ 0xB6E0D80B, 0x01A00962, 0x30431A06, 0xB88FD840,
+ 0x0C8AB600, 0x760C0020, 0x30031A06, 0xF445262F,
+ 0x00030096, 0xF98F0EF6, 0xFAEF09FA, 0xE8094710,
+ 0x02F941C3, 0x0ECA0000, 0xD80AFBAF, 0x266FF03D,
+ 0xD95F14C3, 0x10931600, 0x0EB6B913, 0xD80AFBAF,
+ 0x12CF2640, 0xB700D880, 0xA0002351, 0x090AD80D,
+ 0x20CA01A0, 0x8E0002A1, 0x00BF0843, 0x218A70F6,
+ 0xD8FF0FC7, 0xFAEF0802, 0xCA0A703C, 0xD825E897,
+ 0xB89F706E, 0x88C072EE, 0x7E05881B, 0x14EE0E19,
+ 0x0A864062, 0x712CFB2F, 0x42008D20, 0x098E700C,
+ 0x4362FC2F, 0x2D3F278D, 0xD880716E, 0xB700B88F,
+ 0x00200BEA, 0x0D67D80A, 0x16002010, 0x80007080,
+ 0x08510164, 0xD92F013F, 0x0E36D80A, 0xB914FBAF,
+ 0x1A43266F, 0xF9AF0E46, 0x14841E00, 0x218A7014,
+ 0xD8FF0FC7, 0xFFAF0A0A, 0x730C703C, 0xB600B80E,
+ 0x00200BAA, 0x8D20D814, 0x704C700C, 0xFC2F092E,
+ 0x8D20706C, 0x714C700C, 0xFC2F0922, 0xF007716C,
+ 0xD80AD9CD, 0xFBAF0DEA, 0x096DB912, 0xD80A22BE,
+ 0x02FA41C3, 0x0DDA0000, 0x278AFBAF, 0x0DEE1010,
+ 0x4210F98F, 0x70801600, 0x01638000, 0xFA6F0E42,
+ 0x266F712C, 0x41421A43, 0x02600EFA, 0xD821B6E0,
+ 0xB600B80A, 0xE895CA0A, 0x70EDD825, 0x724EB89F,
+ 0x88DB8820, 0x0E157E25, 0x40E113EE, 0xFB2F09AA,
+ 0x0EAA712C, 0x41E1FBEF, 0x2DFF228D, 0x0B1E71ED,
+ 0xD80E0020, 0x2051092D, 0x70801600, 0x00198000,
+ 0x1600E897, 0x80007080, 0xE893011D, 0x033541C3,
+ 0x0D5E0000, 0xD80AFBAF, 0x01600FBE, 0xF009D808,
+ 0x213F0909, 0xF003710C, 0x0F3E700C, 0x09710140,
+ 0x704E213E, 0x20801000, 0x370E1223, 0x0D4EB8E2,
+ 0x22CAF9AF, 0x278A23E1, 0xE8831FC7, 0x0E51DFFF,
+ 0xD80A117E, 0x02FD41C3, 0x0D160000, 0x208AFB8F,
+ 0x266F0404, 0xB6001A43, 0x4142720C, 0x00200AEA,
+ 0x083242E1, 0xE80DFACF, 0x02FE41C3, 0x0CF20000,
+ 0x740CFBAF, 0x4142730C, 0x00200ACE, 0x40C342E1,
+ 0x81100000, 0x0A76B600, 0xD8160020, 0x20300EAD,
+ 0x40C3704E, 0x01888000, 0x103F9020, 0x70308700,
+ 0xF786700C, 0x00000F5A, 0x00002052, 0x30021A05,
+ 0x0E7A700C, 0x1A0C02A0, 0xCA053482, 0x700CE806,
+ 0x02A00E6A, 0x30431A0C, 0x20801000, 0x370E1223,
+ 0x0CAAB8E2, 0x22CAF9AF, 0x278A23E1, 0xE8831FC7,
+ 0x0E0DDFFF, 0x0F9E119E, 0xE808FA8F, 0xD80A732C,
+ 0xFBAF0C6E, 0xF022B918, 0x02FF41C3, 0x0C620000,
+ 0xD80AFBAF, 0x0204208A, 0x1A43266F, 0x710CB600,
+ 0x0A364142, 0x42E10020, 0x000040C3, 0xB6000908,
+ 0x4142700C, 0x00200A22, 0x40C342E1, 0x81080000,
+ 0x09CAB600, 0xD8180020, 0x227E0951, 0x41C3D80A,
+ 0x00000301, 0xFBAF0C1A, 0x2008228A, 0xF9AF0C2E,
+ 0x208F1000, 0x0F764010, 0x730CFC2F, 0x700CBFE2,
+ 0x1A43266F, 0x03E120CA, 0x0CE24102, 0x1E000220,
+ 0xD8411484, 0xB600B809, 0xE885CA0A, 0xFBEF0CCA,
+ 0x097A8D00, 0xD8090020, 0xE829CA0A, 0x70EDD825,
+ 0x720EB89F, 0x88DB8820, 0x0E297E25, 0x40E113EE,
+ 0xFAEF0FD6, 0x8D20712C, 0x710C4200, 0x0EDE43E1,
+ 0x4250FBEF, 0x700C8D20, 0x0ED24242, 0x43E1FBEF,
+ 0x2B7F208D, 0x0C8271ED, 0x8D00FBEF, 0x70801600,
+ 0x00008000, 0x0EACB8E5, 0x0982FC02, 0x0923FECF,
+ 0x8D002050, 0x0C012044, 0x0C100913, 0x017F0809,
+ 0xF003700C, 0x0C4A710C, 0x0ED202C0, 0x0CBE0100,
+ 0xC8080080, 0x2005B802, 0x900F0F80, 0x1800C03C,
+ 0x08DE0504, 0x700C0160, 0x00000DF6, 0xD80AD967,
+ 0xFBAF0B3E, 0x0E96B913, 0x700CFC2F, 0x02A00F6A,
+ 0x700CD807, 0x00C420AB, 0xF0007FFF, 0x02800C82,
+ 0x4308C2E6, 0x730C71AD, 0x900F46CB, 0x0EAAC028,
+ 0xB6A0FF2F, 0x900847CB, 0x97000288, 0x0B3DB8A1,
+ 0xB7001031, 0x900F41C3, 0x40C3C298, 0x3FFF0000,
+ 0x19E8B1A0, 0x20508004, 0x40C30341, 0xC2249007,
+ 0x1600B020, 0x80007082, 0x2253000C, 0xF205817E,
+ 0x00051804, 0xB022F002, 0xFF2F0E5E, 0xD81FD80D,
+ 0x135C1FAC, 0xFF2F0E52, 0x10051E00, 0x78E0C6C6,
+ 0x4308C2E4, 0xFF2F0E42, 0x70ADD81F, 0x900846CB,
+ 0x740C03E0, 0xFF2F0E32, 0x1654B6A0, 0x206C9700,
+ 0xB8810040, 0x10300B0B, 0x901C1E54, 0x700CC6C4,
+ 0x900F41C3, 0xB88CC280, 0x40C3B100, 0xC2249007,
+ 0xB0A2B0A0, 0xC6C4B1AC, 0x4608C2E4, 0x70801600,
+ 0x00128000, 0x8203208C, 0x02AE0E8C, 0x0EFA40C1,
+ 0x0BDE0040, 0x0B26FECF, 0xCA110080, 0x800145CB,
+ 0x25164FC4, 0x0B4A1000, 0xB0C0FAEF, 0x30821211,
+ 0xA5017D56, 0x0F0A6A01, 0x1A11FAAF, 0x0C663002,
+ 0xC6C40280, 0x1CFCC2FA, 0x2482B6C8, 0x41583304,
+ 0x4310C141, 0x702CC08E, 0xF92F0A26, 0x708EDA50,
+ 0x35001C34, 0x35001C30, 0x35001C2C, 0xFBEF087E,
+ 0x35001C28, 0x21350B27, 0x2353C042, 0x730C20C1,
+ 0x21787839, 0xB8C000DB, 0x202FC043, 0x26F004C5,
+ 0x80007000, 0xC04410C4, 0x700CF007, 0xB890706F,
+ 0x4063C044, 0x2350C043, 0x21842000, 0xC0473004,
+ 0x46D3720C, 0x12218000, 0x800047D3, 0xC045C144,
+ 0x458AD825, 0x718EB89F, 0x881B8820, 0x2C007905,
+ 0xB8022340, 0x0350200F, 0xA040200B, 0x00210408,
+ 0x0CEA730C, 0x1E00FC2F, 0xC0042342, 0x0E2A78A5,
+ 0xC04602A0, 0xC8084110, 0x7825C106, 0x208916B8,
+ 0x20881602, 0x008B2840, 0x20811601, 0x1064086D,
+ 0x096540A1, 0x2940106E, 0x215A0380, 0x2005050C,
+ 0xC78E02C0, 0x7280244A, 0x0F832005, 0x00009000,
+ 0x679F700C, 0x080020A8, 0x30310911, 0x06822100,
+ 0x0082121C, 0x0080082F, 0x30300B0B, 0x02422079,
+ 0x2078F003, 0xEA8F0242, 0x0271080D, 0x9340C68E,
+ 0xF009B749, 0x02822840, 0x7A65669E, 0x92407E14,
+ 0x7104B640, 0xF1CC7124, 0x3005140C, 0xC28C4162,
+ 0x708CC38A, 0xFC6F0C12, 0x40C370CC, 0x12DC8000,
+ 0x21798020, 0x40A13002, 0x09CA4340, 0x4250FE2F,
+ 0x30300B73, 0x1407262F, 0x0CCE710C, 0x41C1FC2F,
+ 0x00800A0A, 0x38812455, 0xDA084022, 0x44C14362,
+ 0x3C052440, 0x0480260A, 0x089A71EC, 0x2455FB6F,
+ 0xDA23388F, 0xBA0A40E2, 0xF92F08A6, 0xC301702C,
+ 0x1408D808, 0x41623004, 0x2440704C, 0x260A3C05,
+ 0x70EC0480, 0xFB6F0C52, 0x2455C740, 0x082A3880,
+ 0x702CFB6F, 0x0C72700C, 0x41C1FC2F, 0x00C00E3E,
+ 0x2455F029, 0x40223881, 0x4362DA08, 0x244044C1,
+ 0x260A3C05, 0x71EC0480, 0xFB6F083A, 0x388F2455,
+ 0x40E2DA23, 0x084ABA0A, 0x702CF92F, 0xD808C301,
+ 0x30041408, 0x704C4162, 0x3C052440, 0x0480260A,
+ 0x0BF670EC, 0xC740FB6F, 0x38802455, 0xFB2F0FCA,
+ 0x1601702C, 0x16022091, 0x210C2080, 0x025CA000,
+ 0x40C3000D, 0x12D98000, 0x20118800, 0x02468440,
+ 0x29400021, 0xC0062315, 0x05402005, 0xC049700E,
+ 0x2280215A, 0x0917C048, 0x21003031, 0x101C2680,
+ 0x200C0080, 0x0214A000, 0x0B0D0001, 0x20793030,
+ 0xF0042240, 0x22402078, 0x02007014, 0xC2080002,
+ 0x229A7202, 0x2232000E, 0x80000F83, 0xEB14C444,
+ 0x00700B2B, 0x05C02234, 0x0B1772E2, 0x922100F1,
+ 0xDE809282, 0x4E924913, 0x00A20B17, 0x42104291,
+ 0xF0074628, 0x70CD704E, 0xDE80F003, 0x215A4210,
+ 0xC08E2501, 0xC007603A, 0x040F22F4, 0x00B1080F,
+ 0xC08C4058, 0x044020F4, 0x0812F00A, 0x40E1FBAF,
+ 0xC08C4708, 0xFBAF0806, 0x044020F4, 0x4F10661E,
+ 0x20024EF1, 0x72760480, 0x20CA4608, 0x26CA0045,
+ 0x0B411046, 0x12082030, 0x0BB73609, 0x28402071,
+ 0x47CB220B, 0x00009000, 0x154B2305, 0x124B2305,
+ 0x1F812305, 0x006A0001, 0xB90261B9, 0x03C82105,
+ 0x1F812305, 0x00680001, 0xB90261B9, 0xF0787F25,
+ 0x220B2840, 0x900042C3, 0x23050000, 0x7BD0154B,
+ 0x124B2305, 0x23057810, 0x00011F81, 0x61B90068,
+ 0x7F4569F2, 0x21099720, 0x230500CE, 0x00011F81,
+ 0x61B9006A, 0x2105B902, 0x10000088, 0x21091101,
+ 0x23050000, 0xB9021341, 0x0F822105, 0x00489004,
+ 0x0F812105, 0x00409004, 0x16009240, 0x80007083,
+ 0x0B8D00EF, 0x91200030, 0xB9C6BAC6, 0x21CC72D1,
+ 0x005E838D, 0x0A59000D, 0x4A760065, 0x0B2DF029,
+ 0x210520B1, 0x28401541, 0x43C32202, 0x00009000,
+ 0x21057945, 0x00010F82, 0x62BA0060, 0x0F812105,
+ 0x00630001, 0xF00EBA02, 0x0F822105, 0x00190001,
+ 0x7AB4B981, 0xBA02B985, 0x43C3B990, 0x00009000,
+ 0xB2C07A65, 0xB90261B9, 0xF0277965, 0x621C4976,
+ 0xF705E4FE, 0xE4FF611C, 0x090FF78A, 0x228700A5,
+ 0x4A700FC1, 0x2187F004, 0x49700FC1, 0x1F812305,
+ 0x006C0001, 0x42C361B9, 0x00009000, 0xB7C0B902,
+ 0xB1C07945, 0x1F812305, 0x006E0001, 0x180061B9,
+ 0xB9021004, 0xB1007945, 0x41C3C009, 0x00009000,
+ 0x340320F4, 0x02402005, 0x2270080D, 0x2840B802,
+ 0x78452282, 0xB0607825, 0x204C7106, 0x05DAA280,
+ 0x05A7FFC5, 0x7126FFEF, 0x20110B1D, 0x71001600,
+ 0x00C49004, 0x0002204F, 0x900741C3, 0xB140C0C4,
+ 0xB100B8A0, 0x7704C005, 0x03D87014, 0xC045FFE2,
+ 0x33042480, 0x341B1404, 0x78E0C6DA, 0x70801600,
+ 0x000D8000, 0x08002044, 0xB8257FE0, 0xC1A4C3E4,
+ 0x70CDDD37, 0x1501BD9F, 0xC0621480, 0x14801501,
+ 0x30021C09, 0x14801501, 0x30021C0A, 0x14801501,
+ 0x30021C0B, 0x14801501, 0x1501C063, 0x1C0D1480,
+ 0x15013002, 0x1C0E1480, 0x15143002, 0x1C0F1480,
+ 0xC0823002, 0x022141C3, 0x60CB0002, 0x0D02740C,
+ 0x42C1FB6F, 0x0EEF71C5, 0x15019214, 0xC0601480,
+ 0x14801501, 0x30021C01, 0x14801501, 0x30021C02,
+ 0x14801501, 0x30021C03, 0x14801501, 0x8D00C061,
+ 0x30021C05, 0x1C068D01, 0x8D023002, 0x1C0770AD,
+ 0xC0803002, 0x022241C3, 0x60AB0002, 0x0CB2740C,
+ 0x42A1FB6F, 0x0DEF71A5, 0xC7C49214, 0x46CBC2E6,
+ 0x04628000, 0x800045CB, 0x08131A20, 0x470802FF,
+ 0x20539600, 0xF41180BE, 0x950AF00D, 0xB50AB880,
+ 0x20538E00, 0xF20780BE, 0xA503700C, 0xA501A502,
+ 0x0E22A500, 0x262FF94F, 0x0008F3C5, 0xC6C60004,
+ 0x20538E00, 0xF20780BE, 0xA503700C, 0xA501A502,
+ 0x0E02A500, 0xC6C6F94F, 0x46A8C2EA, 0x40704788,
+ 0x0CDA4548, 0x4130FB6F, 0x2281215F, 0x25CAE589,
+ 0x60381221, 0x229F7A0F, 0x2200000E, 0x20000400,
+ 0x80000F81, 0x8960C444, 0x0B1D710C, 0x78B800F0,
+ 0x00700B3F, 0x0B5178CB, 0x78CB00B0, 0x78CBEB83,
+ 0xC6CAF22C, 0xF3FF78CB, 0x2180205F, 0x40C3621A,
+ 0xC1448000, 0x9340621B, 0x78429301, 0x93027C10,
+ 0x7A504F12, 0x10850C1B, 0xB300B3E1, 0xF3EBF009,
+ 0x2180205F, 0x70C36058, 0xC1468000, 0x1900B0E0,
+ 0xC6CA0083, 0x205FF5DF, 0x19002180, 0x605800C3,
+ 0x800070C3, 0xF00AC148, 0x2180205F, 0x00431900,
+ 0x70C36058, 0xC1448000, 0xC6CAB0E0, 0xC1A6C3F2,
+ 0x44104530, 0xF2B27014, 0x230A70ED, 0x25142500,
+ 0x244023D2, 0x21143511, 0x120023D1, 0x20532100,
+ 0x19010141, 0x702C2042, 0x1900B826, 0x0EBA2002,
+ 0x4022FE6F, 0x21001204, 0x34102440, 0x23D02014,
+ 0x01412053, 0x20421801, 0xB826702C, 0x20021800,
+ 0xFE6F0E96, 0x40224002, 0x0DB24102, 0x724C0060,
+ 0x2100120A, 0x7EF4C683, 0x01412053, 0x712CAE21,
+ 0xAE00B826, 0xFE6F0E72, 0x120E40C1, 0xC5822100,
+ 0x20537DF4, 0xAD210141, 0xB826712C, 0x0E5AAD00,
+ 0x40A1FE6F, 0x41A140C1, 0x00600D72, 0x1101724C,
+ 0xE0C02080, 0xD940F704, 0xF0044910, 0x003F2080,
+ 0x31812440, 0xA90061F9, 0x20801001, 0xF705E0C0,
+ 0x4910D940, 0x2080F003, 0xC181003F, 0xA90061F9,
+ 0xE0C08E01, 0xD940F704, 0xF0044910, 0x003F2080,
+ 0x30812440, 0xA90061F9, 0xE0C08D01, 0xD940F704,
+ 0xF0044910, 0x003F2080, 0x63F9C380, 0x238D71E5,
+ 0xA900227E, 0x7500240A, 0x708D70AD, 0x704C706D,
+ 0x054020A8, 0x30802440, 0x22086088, 0x13010001,
+ 0x21080480, 0x24400002, 0x60883180, 0x10012308,
+ 0x6088C081, 0x21087185, 0x270A000B, 0xC3830540,
+ 0x32042440, 0x35052440, 0x34062440, 0x24147BB4,
+ 0x25140344, 0x26140345, 0x78AF0346, 0xFA2F0812,
+ 0x71A54161, 0x95040DDB, 0x78E0C7D2, 0x1CFCC2FA,
+ 0x2482B6C8, 0x1C473D08, 0xC0413058, 0x36001447,
+ 0x30981C48, 0x800042C3, 0x1C081224, 0x08293100,
+ 0x1C490070, 0x144730D8, 0xE89F3600, 0x70801600,
+ 0x00258000, 0x00C02078, 0x00971200, 0xC0407104,
+ 0xF0118A01, 0x70801600, 0x00408000, 0x00412078,
+ 0x00971202, 0x7314C140, 0x20CAC000, 0xC04000A1,
+ 0x1C468A03, 0xC2013018, 0x41C3740C, 0x000200BD,
+ 0xFB6F09AE, 0xC001C300, 0x02D07014, 0xD9200021,
+ 0x0BC3216F, 0x780A8900, 0x301C1A1C, 0x780A8901,
+ 0x301C1A1D, 0x7014C000, 0x0021052C, 0x40DB708E,
+ 0x0A3C0000, 0x2619271F, 0x394F2456, 0x33102440,
+ 0x800043DB, 0x27801A3C, 0x20801084, 0x706E2084,
+ 0x36D92100, 0x30181C45, 0x7001248A, 0x218AC083,
+ 0x1A0D0FC7, 0x20A834C2, 0xB0210180, 0x00151804,
+ 0x39402456, 0x248AD9FF, 0x228A7001, 0x18000FC7,
+ 0x1C8627C3, 0x1C88351C, 0x20A8305C, 0xB0410180,
+ 0x00151804, 0x25C0210A, 0x3F802400, 0x02280000,
+ 0x17C31F00, 0x00051800, 0x1446B022, 0x08CF3600,
+ 0xC0830464, 0x36001448, 0x0447212F, 0x01200A86,
+ 0x34581A0B, 0xC04270AE, 0x08A9C002, 0x211A054E,
+ 0x1A0C2600, 0x231A3558, 0x00002F92, 0x220028F0,
+ 0x40A22012, 0x0184209A, 0x20007042, 0x0ED606CD,
+ 0x40A10260, 0xF4E47014, 0x41C3740C, 0x000200CA,
+ 0x08AE4222, 0x43A2FB6F, 0x0CCA4062, 0x4122FD6F,
+ 0x24404608, 0xE8843316, 0x39562456, 0x02400DBE,
+ 0x700C7014, 0x800042C3, 0xF2101B3E, 0xC083EE03,
+ 0x2456F003, 0x10823940, 0x40A20701, 0x0184209A,
+ 0x60587042, 0x78229001, 0x219A41A2, 0x71420184,
+ 0xEE05614A, 0x20811000, 0x8F20F002, 0x242F4A33,
+ 0x40C20006, 0x0D3241A1, 0x42C2FA6F, 0xF4A87014,
+ 0x0D5971A6, 0x7126A294, 0x0D16F199, 0xC1010060,
+ 0x70CE7014, 0xC101F49D, 0x00600D06, 0x39402456,
+ 0xF4977014, 0x20821000, 0x41C3740C, 0x000200CB,
+ 0xFB6F080E, 0x37031488, 0x24348F40, 0x00003F83,
+ 0x41C3022C, 0x000200CC, 0xFB2F0FF6, 0x1446740C,
+ 0x080F3600, 0x71CE05E5, 0x36001445, 0x462BF079,
+ 0x25C0210A, 0x36001448, 0x0447212F, 0x01200966,
+ 0x34581A0B, 0x02600CF6, 0x4508C042, 0x0BE64062,
+ 0x4122FD6F, 0xE808ED05, 0x208D1000, 0xE806F00A,
+ 0xF006C083, 0xF0068FA0, 0x39402456, 0x070D1082,
+ 0x45D1704E, 0x0867C002, 0x740C04AE, 0x00CD41C3,
+ 0x42220002, 0x0F8A4342, 0x1A0CFB2F, 0x0CAE3498,
+ 0xE8070240, 0x0C6A40A2, 0x41A1FC6F, 0x40A2F005,
+ 0xFC6F0B82, 0xE8BC41A1, 0x0084208A, 0x00CE41C3,
+ 0x25320004, 0x740C2005, 0x43224262, 0xFB2F0F52,
+ 0x0480240A, 0xE80BCA06, 0x40A2C101, 0x36021447,
+ 0x0B7A4362, 0x14490320, 0x71463604, 0xA2B40A99,
+ 0x21842580, 0x02400C56, 0x2602211A, 0x231A7014,
+ 0x00002F81, 0x40C328F0, 0x1B3E8000, 0xF2056159,
+ 0xA8A06038, 0x6038F003, 0x1446B0A1, 0x76033600,
+ 0xA000210C, 0xFFE50720, 0xF1887126, 0x70D670CE,
+ 0x00210292, 0xC1007166, 0xA040230C, 0xFFE50588,
+ 0x37942196, 0x00000281, 0xB99F700E, 0x780A8900,
+ 0x301C1A1C, 0x780A8901, 0x301C1A1D, 0x36001449,
+ 0x0D5EE805, 0xE803FB4F, 0x41D3710E, 0x51E00000,
+ 0x20D82941, 0x2440201F, 0x2619271F, 0x800043DB,
+ 0xC7831A3C, 0x10842780, 0x20007023, 0x144606D9,
+ 0x270C3600, 0x0230A000, 0x708E002D, 0x36001448,
+ 0x05C7212F, 0x080E706E, 0x1A0B0120, 0x1C8C35D8,
+ 0x1C453018, 0x148C3658, 0x20113600, 0xF2ED84C0,
+ 0x7001248A, 0x218AC083, 0x704E0FC7, 0x34D81A0C,
+ 0x014020A8, 0x1804B021, 0xD8FF0015, 0x17C31F00,
+ 0x301C1C88, 0x08BDC000, 0x1C860030, 0x1445349C,
+ 0xC002360E, 0x2025082B, 0x34821A0D, 0x250A70AD,
+ 0x66B82400, 0x0AFA702C, 0x1A0D0060, 0x44103558,
+ 0xF4BF7014, 0xC00271A6, 0xA0240DEB, 0x71467522,
+ 0x000045D3, 0xC00028F0, 0xA0240ACB, 0x70AD76A2,
+ 0x0869C002, 0x1A0D2025, 0x220A3342, 0x0B0E2400,
+ 0x1A0D0260, 0x251A3498, 0x70141542, 0x2441221A,
+ 0x800040C3, 0x271A1B3E, 0x708D2603, 0x42626159,
+ 0x0184229A, 0x627A633B, 0x6059F206, 0x14889161,
+ 0x4B343701, 0x06C12200, 0x8F00620A, 0x0306242F,
+ 0xC0834A13, 0xFA6F0A82, 0x4410C283, 0xF4817014,
+ 0xC0027146, 0xA0040AAB, 0xC00071A5, 0x90040D95,
+ 0x740CD95F, 0xFB2F0D7A, 0x8F40B911, 0x41C3740C,
+ 0x000200BF, 0xFB2F0D6A, 0x37031488, 0x0A42C083,
+ 0x702C0060, 0x08CD4410, 0x70CE0031, 0x740C8F40,
+ 0x00C041C3, 0x0D4A0002, 0x1488FB2F, 0xD9C13703,
+ 0x0D3E740C, 0xB910FB2F, 0x08A1C000, 0x71CE0030,
+ 0x220A70AE, 0x1A0D2400, 0xC0023542, 0x20250A85,
+ 0x0487202F, 0x2F81251A, 0x28F00000, 0x221A5035,
+ 0x271A2440, 0x6038260E, 0x4062661E, 0x0184209A,
+ 0x0A2A661D, 0x75630260, 0x8F20E806, 0xFC6F09E2,
+ 0xF00740A1, 0x37011488, 0xFC6F08FA, 0x441040A1,
+ 0x4062E8A7, 0x00C241C3, 0x209A0004, 0x42A20184,
+ 0x240A43E2, 0x60D804C0, 0x0F852032, 0x1B3E8000,
+ 0xFB2F0CBE, 0xCA06740C, 0x1447E80A, 0x40A13602,
+ 0x36041449, 0x08E6702C, 0x43A20320, 0xF1BF7146,
+ 0xC00071A6, 0xA0040D6F, 0x30141404, 0x70CEF002,
+ 0x20110E0B, 0x1404F018, 0x14453014, 0x71663600,
+ 0x01842080, 0xA280234C, 0x30181C45, 0xFFE5060A,
+ 0x35001C04, 0x36192100, 0x05D771E6, 0x1C04FFEF,
+ 0x44103500, 0x0507202F, 0x3D082480, 0x341B1404,
+ 0x78E0C6DA, 0x1600C2EA, 0x8000708D, 0x40500008,
+ 0x0E1E4130, 0x4608F92F, 0xD907706C, 0xDA284768,
+ 0x708CBF8F, 0x70AC40E1, 0xF96F0F82, 0x0A2A70CC,
+ 0x700CF98F, 0xDA08D907, 0x708C706C, 0x0F6E70AC,
+ 0x70CCF96F, 0xD907700C, 0x706C704C, 0x70AC708C,
+ 0xF96F0F5A, 0x6F1670CC, 0x704C752C, 0x0004238A,
+ 0x45C1708C, 0xF96F0F46, 0x257870CC, 0x781B1080,
+ 0x20300845, 0xD92B68A2, 0x010040C3, 0x42A1000C,
+ 0x708C706C, 0x70CC45C1, 0xF96F0F22, 0x2F404010,
+ 0xD92B1240, 0x706C42A1, 0x45C1708C, 0xF96F0F0E,
+ 0x0440260A, 0xD92B4002, 0x706C42A1, 0x45C1708C,
+ 0xF00B70CC, 0x12402F40, 0x42A1D92B, 0x708C706C,
+ 0x260A45C1, 0x0EE60440, 0x700CF94F, 0x744CD907,
+ 0x708C706C, 0x0ED670AC, 0x70CCF96F, 0xF98F0962,
+ 0xD907700C, 0x706CDA30, 0x70AC708C, 0xF96F0EBE,
+ 0xC6CA70CC, 0x1600C2E2, 0x80007080, 0x083F0001,
+ 0x45CB001E, 0xC148900B, 0x10451D00, 0x800042C3,
+ 0x12FF0203, 0x8A008481, 0xB810B918, 0x12FF7825,
+ 0xB9088081, 0x12FE7905, 0x20058080, 0x0F1E8040,
+ 0x20CAFEAF, 0x1D0002A1, 0xC6C21005, 0x1600C2E4,
+ 0x80007080, 0x45CB001A, 0xC40C900F, 0x00510821,
+ 0x900F40C3, 0x1D00C1E4, 0x1D001045, 0x18001005,
+ 0x18000185, 0x0E820005, 0xD820FEAF, 0x0E7A750C,
+ 0x1D00FEAF, 0xD8201045, 0x900F46CB, 0x0E6AC1E4,
+ 0x1E00FEAF, 0x1D001185, 0x1E001005, 0xC6C41005,
+ 0xD841C2E2, 0x900845CB, 0xB50001E4, 0xFEAF0E4A,
+ 0xD840750C, 0xC6C2B500, 0xC1A4C3F4, 0x800045CB,
+ 0x15020150, 0xD97B1500, 0xB2004283, 0x1502B910,
+ 0xB2011500, 0x15001502, 0x1502B202, 0xB2031500,
+ 0x15001502, 0x9500B204, 0x9501B205, 0x9502B206,
+ 0x0A6EB207, 0x740CFB2F, 0x908015D7, 0x1210E804,
+ 0xF0043092, 0x3092120F, 0x710C702E, 0xE80872CE,
+ 0x70801600, 0x00258000, 0xF045E888, 0x70801600,
+ 0x00408000, 0x00100887, 0xC08070AD, 0x78B5700E,
+ 0x70ED728E, 0x044020F4, 0x2005781B, 0x00040F93,
+ 0x0A571000, 0x250A2030, 0x70CD2480, 0x1B00255A,
+ 0x1F852632, 0x04788000, 0x430242A1, 0x0440240A,
+ 0x201478D5, 0x70020440, 0x0F812000, 0x12288000,
+ 0x706278EF, 0xB89CB802, 0x8000B89F, 0x262FA900,
+ 0x41C30007, 0x0005007C, 0xFB2F09D6, 0x71C5740C,
+ 0x27BF258D, 0x248D71E5, 0x710E25FF, 0x0D8F71A5,
+ 0x700C9114, 0x2D7E268D, 0xC7D4712E, 0x4350C2F8,
+ 0x08854630, 0x44100030, 0x20002678, 0x220A70D6,
+ 0x781B24C0, 0x202222CE, 0x70AE68E9, 0x250D255A,
+ 0x800041C3, 0x652012E0, 0xB89CB802, 0x0B53B89F,
+ 0x10002030, 0x653D0118, 0x8D29702E, 0x20008D0B,
+ 0x40100497, 0x044A222F, 0x72624628, 0x0D4E4003,
+ 0x702CF8AF, 0x00412044, 0x10400E17, 0x20300E11,
+ 0x20402042, 0x20402040, 0xF003AD0D, 0x7126AD0C,
+ 0xA4E409D5, 0x23D02000, 0x15C21D0B, 0x248DAD29,
+ 0x71A6243F, 0x78E0C6D8, 0x47CBC2EE, 0x12228000,
+ 0x42508FA0, 0x1090251F, 0x70911600, 0x00048000,
+ 0x46084330, 0x20D12153, 0x08A58F01, 0x0E390344,
+ 0x0A99161F, 0x2D402030, 0x6E321380, 0x704C7905,
+ 0x0408202F, 0x20032314, 0xB80A784F, 0x78257144,
+ 0xB89CB892, 0x9000B89F, 0x784FB300, 0x84A408E5,
+ 0xF0347106, 0x7E06C808, 0x1F802604, 0xFFFE0FFF,
+ 0xFEFF70C3, 0x2843FFF0, 0xF2118100, 0x00D00823,
+ 0x00900817, 0x0071081F, 0x0CCA40C1, 0x41A1FD2F,
+ 0x710C7014, 0x720CF408, 0x700CF006, 0x730CF004,
+ 0x740CF002, 0x2B01215F, 0x8F037915, 0x0340203C,
+ 0x26447914, 0x60381040, 0x882660F8, 0x0408202F,
+ 0x20002314, 0xB0207106, 0xF1B071A5, 0x78E0C6CE,
+ 0x4410C2F8, 0x03952840, 0x1600785B, 0x80007096,
+ 0x2044008E, 0xD8E40182, 0x2C407859, 0xB8C12318,
+ 0x2F8E2505, 0x01C89004, 0x0F112054, 0x040F2040,
+ 0x01972140, 0x704E706E, 0x700E70AD, 0x26012205,
+ 0x7825C808, 0xA07E2653, 0x900441C3, 0xF20D0000,
+ 0xB80278E5, 0x90007825, 0x01C120AD, 0xB8647314,
+ 0x002D20CA, 0x2005F00C, 0xB8020440, 0x218A7825,
+ 0x90000FBF, 0x770CB8E6, 0x004120CA, 0x20022700,
+ 0xE810CA07, 0x02310811, 0x37011221, 0x0F800915,
+ 0x68150000, 0x02510811, 0x0F81090D, 0x71960000,
+ 0xF003BA86, 0xD808BA87, 0xFEAF0B4E, 0x2505B640,
+ 0x225624C0, 0x20052812, 0x90040F80, 0x900001CC,
+ 0x20102380, 0x2800B8C0, 0x71060400, 0xA2740871,
+ 0x78B07D05, 0x087E4182, 0x1E00FB2F, 0x780F1005,
+ 0x78E0C6D8, 0x2840C2E6, 0x4708038E, 0x2605D889,
+ 0x90041F8D, 0xB50001C8, 0xFEAF0AFE, 0x244AD808,
+ 0x708D7240, 0x702C704C, 0x20A8706C, 0x26050400,
+ 0x22801080, 0x20050010, 0x90040F80, 0x900001CC,
+ 0x7838B8C0, 0x7B057124, 0x41E17870, 0xFB2F0826,
+ 0x780FB580, 0x78E0C6C6, 0x014422AA, 0x010421AA,
+ 0x800040C3, 0xA04104B0, 0xA0207FE0, 0x45CBC0E6,
+ 0x12228000, 0x46008D60, 0x0A1B718D, 0x700C00B0,
+ 0x0241235F, 0x00710A13, 0xE108DE08, 0xD808DC09,
+ 0x4160F003, 0x150170CD, 0x4E12108B, 0x00492240,
+ 0x0B377D6F, 0x0E2F1344, 0xBD0E1024, 0x7240240A,
+ 0x20A84008, 0x7A2F0440, 0x26146199, 0x2840008F,
+ 0x7AA51282, 0x22057105, 0x90040F82, 0x924001D0,
+ 0x7164B740, 0xC4C6F1E6, 0x40C3C5E1, 0x04988000,
+ 0xE9AE8820, 0x00431800, 0xE82ACA00, 0x70AD712D,
+ 0x800144CB, 0x2D404FA0, 0x244A1381, 0x42817240,
+ 0x706D700D, 0x05C020A8, 0x02002105, 0x20057405,
+ 0x90040F83, 0x8A000200, 0x2900B300, 0x120112C3,
+ 0x71650480, 0x7825B80A, 0x0F802005, 0x02F89004,
+ 0x71A5B060, 0x0DC3CA00, 0xE4099024, 0x78E0C4C2,
+ 0xDC25C808, 0x43C3BC9F, 0x12248000, 0x2005B802,
+ 0x90070F81, 0xCC23C408, 0x8C00B100, 0x8B01E818,
+ 0x082D8B20, 0x78220064, 0x240A7104, 0x20A87000,
+ 0x40C30400, 0x049C8000, 0x004220F4, 0x03802940,
+ 0x20057124, 0x90040F80, 0xB040028C, 0x70148C1B,
+ 0x8B037CE0, 0x72108B42, 0x07CD20E0, 0x71047842,
+ 0x7000240A, 0x03C020A8, 0x800040C3, 0x20F4049C,
+ 0x2A400081, 0x71440380, 0x0F802005, 0x028C9004,
+ 0x7EE0B020, 0x21326038, 0x80000F82, 0xA8401880,
+ 0x0F822132, 0x18CB8000, 0x0082184B, 0x0F822132,
+ 0x19168000, 0x00821896, 0x0F812132, 0x19618000,
+ 0x18E17FE0, 0x78E00042, 0x4748C2E6, 0x00851101,
+ 0x46288861, 0x00841100, 0x88404508, 0x41C3740C,
+ 0x000500D7, 0xFAEF0D6A, 0x8E0046E1, 0x71108D20,
+ 0xF7C7F233, 0x03E50915, 0xAD006909, 0x0835F00F,
+ 0x770403C5, 0xF01FAE00, 0x0F1349F0, 0xAD001070,
+ 0x10900F1B, 0x10C01501, 0x8D01F005, 0x08002054,
+ 0x262FAD01, 0x0032F005, 0xD87F0003, 0xF015AD01,
+ 0x0F1378E2, 0xAE001070, 0x10900F1B, 0x10C01601,
+ 0x8E01F005, 0x08002054, 0x262FAE01, 0x000AF005,
+ 0xD87F0003, 0x8E60AE01, 0x00D841C3, 0x8D400003,
+ 0x09F644E1, 0x2238F8AF, 0xC6C600C0, 0x41C3C2E4,
+ 0x0000031A, 0xFAEF0CDA, 0x086ED80A, 0xD80AFEAF,
+ 0xF98F0D2E, 0x800141C3, 0x080A6800, 0x206FFA2F,
+ 0xE8880043, 0x031B41C3, 0x0CB60000, 0xD80AFAEF,
+ 0xFC0F0FCE, 0x43204200, 0x031C41C3, 0x0CA20001,
+ 0xD80AFAEF, 0xF98F0CFA, 0x000046CB, 0x45CB3420,
+ 0x34D80000, 0x13650E37, 0x41C3D80A, 0x0001031D,
+ 0xFAEF0C7E, 0x700C42A1, 0xFA2F0872, 0x460841A1,
+ 0x031E41C3, 0x0C6A0000, 0xD80AFAEF, 0x40A1D941,
+ 0xF9EF0FA2, 0x60DDB90A, 0x41C3F017, 0x0001031F,
+ 0xFAEF0C4E, 0x700C42C1, 0xF9EF0F8A, 0xD91941C1,
+ 0xB9154508, 0xFAEF0C3A, 0xD941D80A, 0x082E40C1,
+ 0xB90AFA2F, 0xED88651D, 0x032141C3, 0x0C220000,
+ 0xD80AFAEF, 0xFC0F0F3A, 0x800045CB, 0x85400448,
+ 0x0003223D, 0x223D8541, 0x71500040, 0x00C120CA,
+ 0x0F1EE885, 0xA521FC0F, 0x0F16A500, 0x4200FC0F,
+ 0x41C34320, 0x00010322, 0xFAEF0BE6, 0x1600D80A,
+ 0x80007080, 0x082F0004, 0x8501015E, 0x70148520,
+ 0x0F81213C, 0xF42C0001, 0xE98D79C0, 0x032341C3,
+ 0x0BBE0000, 0xD80AFAEF, 0x700CD9C9, 0xF8AF08BA,
+ 0xC6C4B912, 0x4010C2E8, 0x085AD80F, 0xD90FFA2F,
+ 0x0EAAD80F, 0x712CF92F, 0x800046CB, 0x8EA01222,
+ 0x1280255F, 0x0F8F2000, 0x4DFC8001, 0x085F8E01,
+ 0x40C30344, 0x12D98000, 0x084D8800, 0x79AF036E,
+ 0x00A00D02, 0x2D404002, 0x244A138B, 0x708D7280,
+ 0x20A8706C, 0x082B0680, 0x240500EE, 0x210512C1,
+ 0x90040F82, 0x210502DC, 0x90040F81, 0x924002E0,
+ 0x213D9120, 0x793B0081, 0x67796949, 0x2480A940,
+ 0x71641010, 0x71A5E70A, 0xC6C8F1D2, 0x084EC2E2,
+ 0x45080220, 0x1600E888, 0x80007080, 0x0811000B,
+ 0x40A100BF, 0x0220091E, 0xC6C240A1, 0xFCEF0FC2,
+ 0xC6C2702C, 0x1600C2E6, 0x8000708E, 0x47280008,
+ 0xF8EF0CCE, 0x700C4508, 0x744CD907, 0x708C706C,
+ 0x0E3A70AC, 0x70CCF92F, 0x10802678, 0x08DA781B,
+ 0x68C2F96F, 0x700CEF11, 0x724CD907, 0x708C706C,
+ 0x0E1A70AC, 0x74CCF92F, 0x752C704C, 0x238A4040,
+ 0xB8950004, 0x704CF01B, 0x4040752C, 0x0004238A,
+ 0x708CB895, 0x0DF645A1, 0x70CCF92F, 0xD92B74ED,
+ 0x42C1BF98, 0x706C40E1, 0x45A1708C, 0xF92F0DDE,
+ 0x40E170CC, 0x42C1D92B, 0x708C706C, 0x0DCE45A1,
+ 0x70CCF92F, 0xD92BD841, 0x42C1B812, 0x708C706C,
+ 0x0DBA45A1, 0x70CCF92F, 0xD907700C, 0x706C744C,
+ 0x70AC708C, 0xF92F0DA6, 0x0280264A, 0xD907706C,
+ 0x744C4060, 0x708CB88F, 0x0D9270AC, 0x70CCF92F,
+ 0xD907700C, 0x706CDA08, 0x70AC708C, 0xF92F0D7E,
+ 0x080E70CC, 0x700CF94F, 0x744CD907, 0x708C706C,
+ 0x0D6A70AC, 0x70CCF92F, 0x78E0C6C6, 0x2482C3F0,
+ 0x42103403, 0x38002455, 0x702C4330, 0xF86F0A12,
+ 0x40C3DA50, 0xF0B00000, 0xB415448B, 0x73044899,
+ 0xB409B42F, 0x0A812057, 0x000040C3, 0x1C66FF74,
+ 0x21573004, 0x1C5A09C0, 0xB86E3004, 0x30041C42,
+ 0xB41BB863, 0x000140C3, 0xC049F0BA, 0x710C686E,
+ 0xB88EDA07, 0x30841C5C, 0x30841C44, 0xB45C71AD,
+ 0x03422342, 0x40C3B408, 0xFFB50001, 0x2080C043,
+ 0xC2400339, 0x1C6ADA40, 0x20403084, 0xC05B0802,
+ 0x6843C258, 0xB4237704, 0x41C3C04F, 0xFE030000,
+ 0x70801600, 0x00088000, 0x00802079, 0x30441C4E,
+ 0x30041C40, 0xB41D702C, 0xC255B802, 0x000742C3,
+ 0xB417F004, 0xB42EC808, 0xB425B42B, 0x30441C70,
+ 0x30441C64, 0x30441C5E, 0x30441C58, 0x30441C52,
+ 0x30441C4C, 0x6B4BC252, 0x30441C46, 0x2005B43A,
+ 0x000E0F81, 0xC15EF00B, 0x09412254, 0xC3467825,
+ 0x30041C72, 0xC24CB830, 0x1C74702C, 0x700C3004,
+ 0x706C704C, 0xB4B0B4B6, 0xB4A4B4AA, 0x33441C68,
+ 0x33441C50, 0xB4B1B4B4, 0x30851C04, 0x30851C7C,
+ 0xFCEF0A7E, 0x33441C76, 0x000042C3, 0x700C5555,
+ 0x4340722C, 0x09E24440, 0x4540FCEF, 0x094EC080,
+ 0xD97E0260, 0x0D6ED80F, 0xD90FF9EF, 0x900741D3,
+ 0x1900F804, 0x47CB2105, 0x12228000, 0x6832C808,
+ 0x2105D880, 0x90070F82, 0xB200FC48, 0x0F822105,
+ 0xFC4C9007, 0x2105B200, 0x90070F82, 0xB200FC40,
+ 0x0F822105, 0xFC449007, 0x2D00B200, 0xB8021480,
+ 0x200F8F40, 0x8F01048E, 0x00A4082B, 0xBA0E7842,
+ 0x240A7104, 0x20A87000, 0x210503C0, 0x72C30080,
+ 0x40000000, 0x0F802005, 0x057C9004, 0xBB8A9060,
+ 0x0C62B060, 0x09DEFC0F, 0x242F0000, 0xD8552387,
+ 0x704CD955, 0x0E5E706C, 0x240A0060, 0x40820500,
+ 0xFFEF0D26, 0xD860702C, 0xF92F0B22, 0x208A712C,
+ 0x40D30FC7, 0xC2CC9007, 0x20041800, 0x20041804,
+ 0x71001600, 0x02C09004, 0x0C002045, 0xA00418F4,
+ 0xA34418F8, 0x8F008F81, 0x10240C43, 0x2840D9AC,
+ 0x244A0388, 0x706D7240, 0x20A8704C, 0x0B1305C0,
+ 0x20002031, 0x111C0681, 0x0A190081, 0x20050040,
+ 0x210512C1, 0x90040F81, 0x916001D0, 0xB160E320,
+ 0x10102380, 0x71047144, 0x46CBF1E0, 0x01068000,
+ 0xD8538E40, 0x0DCE4340, 0x240A0060, 0x8E000500,
+ 0x8FA0E81C, 0x08258F01, 0x8E000344, 0x00A00916,
+ 0x2D4079AF, 0x21051381, 0x90040F81, 0xB1003830,
+ 0x75108F01, 0xF7B371A5, 0x0FC7218A, 0x900740C3,
+ 0x1800F834, 0xB0220005, 0x0C5E4082, 0x712CFFEF,
+ 0x000042C3, 0x700CAC53, 0x4340722C, 0x085A4440,
+ 0x4540FCEF, 0x0BEED80F, 0xD90FF9EF, 0xDD2870CD,
+ 0x0A3AD808, 0x712CF92F, 0x108B1701, 0x0B578F00,
+ 0xD90F1024, 0x03892840, 0x7240244A, 0x708D700D,
+ 0x07C020A8, 0x20310B11, 0x06812000, 0x0081111C,
+ 0x10400C29, 0x12412005, 0x210570CD, 0x90040F82,
+ 0x210502DC, 0x90040F81, 0x924001D0, 0xEA069160,
+ 0x08032354, 0xB1604648, 0x10102080, 0x71047185,
+ 0x0B82F1D7, 0xD80FF9EF, 0x133F258C, 0x10002678,
+ 0x02DD41C3, 0x0BC20001, 0x4242F86F, 0x38002455,
+ 0x0F9E712C, 0x704CFFAF, 0x0ABE4042, 0x712CFA2F,
+ 0x0F002054, 0x38012455, 0x706C714C, 0x70AC708C,
+ 0x0260081E, 0x40C34588, 0xF8309007, 0x73441E00,
+ 0xC29C9007, 0xA34418F8, 0x73441E00, 0x0004901C,
+ 0x23441900, 0xB0A2B0A0, 0x0020080A, 0xC7D0B0A4,
+ 0xD820C2E2, 0x900B45CB, 0x09EEC280, 0x1D00FE6F,
+ 0x1D001045, 0xC6C21005, 0x1CFCC2FA, 0x2482B6C8,
+ 0x41DB3002, 0xC17C9007, 0x901C43D3, 0x190004A8,
+ 0x42103005, 0x20551B5C, 0xC8084338, 0x800041C3,
+ 0xDA6C04B8, 0x71AD702E, 0x2005B802, 0x180004C0,
+ 0x0E160045, 0xC085F82F, 0x702C700C, 0x0FA2704C,
+ 0x706CFCAF, 0x722C700C, 0x706C704C, 0x0F0A708C,
+ 0x70ACFCAF, 0x0E76C085, 0xD96C0220, 0xFACF0BC2,
+ 0x0A92D80F, 0xD90FF9EF, 0xFF8F0B1A, 0x40C3D90A,
+ 0x4E748001, 0x00200E8A, 0x40024010, 0x09AAD90A,
+ 0x704CF96F, 0xD90A4002, 0xFDEF0B8A, 0x4002DA59,
+ 0x00200E6E, 0x4002D92E, 0x098ED92E, 0x704CF96F,
+ 0x0E5E4002, 0xD9120020, 0xD9124002, 0xF96F097A,
+ 0x0D1EDAEF, 0xC0810060, 0x09FEC081, 0xD90AFB6F,
+ 0x09F6C081, 0xD92EFB6F, 0x09EEC081, 0xD912FB6F,
+ 0x800047CB, 0x41421220, 0x219F8F00, 0x704C02C1,
+ 0x0582209F, 0x708CC381, 0x2D006119, 0xB8021480,
+ 0x200F7102, 0x6D12048D, 0x7E0F78A5, 0x087E40C1,
+ 0x40D90220, 0x0F824002, 0xD90AFFAF, 0x0F7A4002,
+ 0xD912FFAF, 0x0F724002, 0xD92EFFAF, 0x700C7DAF,
+ 0x704C702C, 0x0B4E706C, 0x44A10060, 0x098A710C,
+ 0x712C0060, 0x0CB640A1, 0x702C01E0, 0x02D341C3,
+ 0x0CFE0000, 0x740CFAAF, 0x0802D860, 0x712CF92F,
+ 0xFC8F0B6E, 0x8F228F03, 0x00640829, 0x68417822,
+ 0x03802940, 0x7080240A, 0x030020A8, 0x0F812005,
+ 0x01D09004, 0x70C39140, 0x40000000, 0xB140BAC5,
+ 0x712C700C, 0xF8EF0FC6, 0x3FC11C00, 0x0966D80F,
+ 0xD90FF9EF, 0x0C5640A1, 0x712C01E0, 0x0FC7208A,
+ 0x900746CB, 0xB600C2CC, 0xB602D9B5, 0x1EF8D881,
+ 0xD8309004, 0x1EF4B912, 0x0C869004, 0x740CFAAF,
+ 0x40A1DDFF, 0x461045B1, 0x700C44B1, 0xF8EF0F7E,
+ 0x8F03712C, 0x08618F22, 0x70EE0064, 0x29407822,
+ 0x7104038C, 0x7000240A, 0x07C020A8, 0x2405C280,
+ 0x90041F80, 0x900002DC, 0x2079623A, 0x8A000003,
+ 0x7865781B, 0x2053AA00, 0x240580BE, 0x90041F80,
+ 0x904001D0, 0x2254F205, 0x71EE0802, 0x7124B040,
+ 0x000074C3, 0x14034000, 0xC5203096, 0x30951402,
+ 0x30941401, 0x08BED80F, 0xD90FF9EF, 0x41C3740C,
+ 0x000402D5, 0x438242A1, 0x0540240A, 0xFAAF0BF2,
+ 0x0580250A, 0x090B7126, 0x0F732E15, 0x41C3A011,
+ 0x000002D7, 0xF86F08E2, 0x20002778, 0x740CD95B,
+ 0xFAAF0BCE, 0x8F03B913, 0x082D8F22, 0x78220064,
+ 0x29406841, 0x240A0380, 0x20A87080, 0x20050380,
+ 0x90040F81, 0x914001D0, 0x000070C3, 0x22554000,
+ 0xB1400802, 0xB6A070AD, 0x0A16B6A2, 0x1EF4FCAF,
+ 0x700C9344, 0x00200D42, 0xD881712C, 0x02D941C3,
+ 0x1EF80000, 0x0B7A9004, 0x740CFAAF, 0x0E7ED840,
+ 0x712CF8EF, 0x712C4063, 0xFFAF0C56, 0x8F23724C,
+ 0x09238F02, 0x79020024, 0x240A7124, 0x20A87040,
+ 0x23F402C0, 0x23143001, 0x21803002, 0x7104003E,
+ 0x4042B220, 0xF9EF0F52, 0x48C8712C, 0x7825C808,
+ 0x714C4163, 0x708C706C, 0x02200CB6, 0xD92071AC,
+ 0x900740C3, 0xB0A0C29C, 0x22C1229F, 0x804418EC,
+ 0x834418EC, 0x73441E00, 0xC164900B, 0x93441EF8,
+ 0x30451900, 0xB802C808, 0x04C12005, 0xFFEF0C96,
+ 0x8F00B1A0, 0x209F704C, 0xC3810582, 0x7042708C,
+ 0x04012000, 0x01E00E16, 0xCA004003, 0x10250D31,
+ 0x138C2D40, 0x7240244A, 0x702C704C, 0x038020A8,
+ 0x2405716C, 0x7B381080, 0x0F802005, 0x02F89004,
+ 0x00102280, 0xB0607124, 0xF1E971A5, 0x30022480,
+ 0x341B1404, 0x78E0C6DA, 0x4408C0F1, 0x2084880B,
+ 0xAC0B01C2, 0xB8A38C01, 0x1600AC01, 0x800070C0,
+ 0x080F000D, 0x8C130012, 0x03002046, 0x0A8EAC13,
+ 0xE808F88F, 0xB8858C0D, 0x8C03AC0D, 0xAC03B887,
+ 0xF98F0D4A, 0x8C15E807, 0xAC15B8A5, 0xB8868C03,
+ 0xD840AC03, 0x10831C14, 0x8C0DAC10, 0xAC0DB8A4,
+ 0x20458C11, 0xAC110E00, 0x206C8C12, 0xAC120080,
+ 0x20448C1C, 0xAC1C0300, 0x10801429, 0xC0D1B8C4,
+ 0x1C297FE0, 0x78E01002, 0x40C3C5E1, 0x04988000,
+ 0xE9328820, 0xA840704C, 0x0A5DCA00, 0x2A400025,
+ 0x244A0381, 0x706C7240, 0x090020A8, 0x00802216,
+ 0x20006078, 0x80010F8D, 0x6B124FA0, 0x20057825,
+ 0x90040F80, 0x90800200, 0x0B13AD80, 0xB0600231,
+ 0x22008D80, 0x181C0680, 0x2B400302, 0x718D0280,
+ 0x7C787825, 0x20057164, 0x90040F80, 0xB08002F8,
+ 0xF1D47144, 0x78E0C4C2, 0xC1A2C3E6, 0x900042C3,
+ 0x92800184, 0x903841C3, 0x246C0184, 0x91601140,
+ 0x236CB200, 0xB1000140, 0x9202722D, 0xB8C891A2,
+ 0x704CB280, 0x44CBBDC8, 0x05A48000, 0xC241B160,
+ 0xB1014183, 0xC808B1A0, 0x10832415, 0x30062440,
+ 0x70AD720D, 0xF41C7AAB, 0x13412415, 0x7E0583C1,
+ 0x79C58123, 0x2105B902, 0x90030F8E, 0xB99CC000,
+ 0x91E0B99F, 0x134124F4, 0xC1817F26, 0x034B21F4,
+ 0x008126F4, 0x02C12900, 0xB62079E5, 0x193F208D,
+ 0x218D71AD, 0x714C16FF, 0x2042C805, 0xF20E803C,
+ 0xD99C700C, 0x028020A8, 0x0F822005, 0x03649004,
+ 0x000070C3, 0xB2204000, 0x9661468B, 0x41C3740C,
+ 0x00020071, 0x08EA96A0, 0x42A1FAAF, 0xDC7FC808,
+ 0x2553BC09, 0x68321202, 0x0F832105, 0x20289024,
+ 0x21059300, 0x90240F81, 0x7884202C, 0x008D2005,
+ 0x78849100, 0x7845B3A0, 0x740CB100, 0x007241C3,
+ 0x08AE0001, 0x9640FAAF, 0x78E0C7C6, 0xDC25C808,
+ 0x43C3BC9F, 0x12248000, 0x21056832, 0x90070F80,
+ 0x2105C408, 0x90040F81, 0x91200408, 0x305C1A23,
+ 0x0F812104, 0xFF9F0000, 0x8C00B020, 0x8B01E818,
+ 0x082D8B20, 0x78220064, 0x240A7104, 0x20A87000,
+ 0x29400400, 0x26140380, 0x80007042, 0x2005049C,
+ 0x90040F80, 0x9000028C, 0xB2007124, 0x70148C1B,
+ 0x8B037CE0, 0x71108B22, 0x07CD20E0, 0x71047822,
+ 0x7000240A, 0x03C020A8, 0x03802940, 0x70422614,
+ 0x049C8000, 0x0F802005, 0x028C9004, 0x71249000,
+ 0x7EE0B200, 0x45CBC2E8, 0x12228000, 0x40108DC0,
+ 0x085B8D01, 0x40C30384, 0x12D98000, 0x084B8800,
+ 0x79CF03AE, 0x0060097E, 0x44084002, 0x2E40C808,
+ 0x244A1382, 0x68327280, 0x702C7A25, 0x054020A8,
+ 0x104E0C25, 0x1500265A, 0x20007834, 0x80010F83,
+ 0x29404E24, 0x78450280, 0x0F802005, 0x03209004,
+ 0xB3009000, 0x71C57124, 0xC6C8F1D4, 0x706CC808,
+ 0x6852726D, 0xE808710C, 0x70801600, 0x00258000,
+ 0xF020E888, 0x70801600, 0x00408000, 0x7CE07014,
+ 0x7180244A, 0x058020A8, 0x03802B40, 0x800044CB,
+ 0x784519AC, 0x20057C74, 0x90000F81, 0x912001C0,
+ 0x0F802005, 0x01B49000, 0x7164B420, 0xB40E9000,
+ 0x238DDB07, 0x700C16FF, 0x78E07EE0, 0x21006038,
+ 0x80000F83, 0x88401880, 0x2100AB40, 0x80000F83,
+ 0x104B18CB, 0xAB400082, 0x0F832100, 0x19168000,
+ 0x00821096, 0x800071C3, 0xAB401961, 0x008010E1,
+ 0xA9007FE0, 0x2142EA1E, 0x7CE0803C, 0x064020A8,
+ 0x04831001, 0x04811001, 0x04821001, 0x7B25B908,
+ 0x04811001, 0x7945B908, 0x7965B910, 0xB99CB902,
+ 0x9120B99F, 0x00521801, 0x1801B928, 0xF0200052,
+ 0x803C2142, 0x072220E8, 0x04831001, 0x04811001,
+ 0x04821001, 0x7B25B908, 0x04811001, 0x7945B908,
+ 0x04821001, 0x7965B910, 0x2105B902, 0x90030F83,
+ 0x1001C000, 0xB9080481, 0xB3207945, 0x78E07EE0,
+ 0x7915793B, 0x0F802100, 0x04588000, 0xB0407FE0,
+ 0x40C34100, 0x12DA8000, 0xE8898800, 0x70801600,
+ 0x00088000, 0x01110807, 0x7FE0793B, 0x78E07830,
+ 0xE0C04100, 0xD840F704, 0xF0044831, 0x003F2180,
+ 0x782F7FE0, 0x24056892, 0x90071F80, 0x1800C2D4,
+ 0x40C30005, 0x12228000, 0x88608841, 0x20E07350,
+ 0x4A7007CD, 0x7104BB0E, 0x7000240A, 0x030020A8,
+ 0x10C02405, 0x000073C3, 0x20054000, 0x90040F80,
+ 0xB02002D4, 0x78E07EE0, 0x0443206F, 0x800042C3,
+ 0x8820121E, 0x0703219F, 0x810010FE, 0x01031A01,
+ 0x77046038, 0x00402805, 0xAA007FE0, 0xC1A4C3E4,
+ 0x800145CB, 0x46084E74, 0x40A17034, 0xF20BD912,
+ 0xFFCF0E8E, 0xD91240A1, 0xFDAF0B9A, 0x714CDA10,
+ 0x0806F004, 0x704CFF8F, 0x41C3C808, 0x0504901C,
+ 0x7825B802, 0xC080B040, 0x00200D36, 0x804519A4,
+ 0x0A16C080, 0xD912FB2F, 0x702C40A1, 0x43C1C280,
+ 0x01E00D2A, 0xC7C4708C, 0x70CDC0E6, 0x800042C3,
+ 0x1E001222, 0x90077384, 0x8AE1FED4, 0x1047232F,
+ 0x0F638A60, 0x2B4010E4, 0x238C038D, 0xF4169FC3,
+ 0x1F822505, 0x3ED49004, 0x023F091D, 0x2300B200,
+ 0x121C0682, 0xBA0A0082, 0x25057D45, 0x90041F82,
+ 0xB2C002D4, 0xF1E77164, 0x4028702D, 0x08F9704C,
+ 0x0AF59010, 0x202F8275, 0xF7499202, 0x124C2505,
+ 0x1F8C2405, 0x02D49004, 0x2180B400, 0x71441010,
+ 0xC4C6F1EF, 0x0FB2C2E2, 0x4408F92F, 0x1843256F,
+ 0x09679520, 0x41C30050, 0x12218000, 0x800043C3,
+ 0x0C1B0458, 0x894010F1, 0x15307B55, 0x93401081,
+ 0x9321E909, 0x00422208, 0x2450F005, 0x79551001,
+ 0x621B6172, 0x6852C808, 0x0F802205, 0x0034901C,
+ 0xC805B060, 0x803C2042, 0x700CF20D, 0x02C020A8,
+ 0x00012205, 0x000070C3, 0xB9924000, 0xB99FB99C,
+ 0x0E42B160, 0xC6C2FF8F, 0xC808C2E6, 0x120570AD,
+ 0x706C3608, 0x1202212F, 0x800046CB, 0x68920458,
+ 0x02250B51, 0x233DD940, 0xB99F024B, 0x20798900,
+ 0x23040002, 0x26F4908F, 0xF20613C2, 0x00D10817,
+ 0xF0079623, 0x808111E5, 0x00D1090B, 0x22089622,
+ 0x26140042, 0x716413C1, 0xB142B140, 0x13412405,
+ 0x75C3B992, 0x40000000, 0xB99FB99C, 0xF1DAB140,
+ 0x96219600, 0xF92F0ED2, 0x000C2108, 0x60985020,
+ 0x2105B902, 0x901C0F81, 0xB1000034, 0x78E0C6C6,
+ 0xC1A4C3E6, 0xC0804708, 0x00200B96, 0xC0804528,
+ 0xFB2F0876, 0x46CBD918, 0x4E748001, 0xD91840C1,
+ 0x0020096A, 0x78BD42E1, 0x800041C3, 0xB8C01220,
+ 0x209F8920, 0x704C02C1, 0x0582219F, 0x708CC380,
+ 0x6D126119, 0x61D978A5, 0x01A00F02, 0xC7C6780F,
+ 0x4528C2E4, 0xF86F0D9A, 0x700C4608, 0x724C762C,
+ 0x244A43C1, 0x45A10780, 0xF8AF0F02, 0x700C70CC,
+ 0x09EED922, 0x704CF8EF, 0x0EA2700C, 0x712CF8AF,
+ 0x78E0C6C4, 0x900742C3, 0xB200C2E4, 0xB2227FE0,
+ 0xC1A4C3E8, 0xC0804010, 0x0B064548, 0x47280020,
+ 0xAFC3208C, 0x800146CB, 0xF20C4E74, 0x28C02054,
+ 0xC080790F, 0xFAEF0FD2, 0x40C14030, 0xF02C4102,
+ 0x0FC6C080, 0xD946FAEF, 0x0FBEC080, 0xD947FAEF,
+ 0x0FB6C080, 0xD948FAEF, 0x0FAEC080, 0xD949FAEF,
+ 0x0FA6C080, 0xD94AFAEF, 0xD94640C1, 0x0020089E,
+ 0x40C142E1, 0x0896D947, 0x42E10020, 0xD94840C1,
+ 0x0020088A, 0x40C142E1, 0x0882D949, 0x42E10020,
+ 0xD94A40C1, 0x00200876, 0x79BD42E1, 0x800040C3,
+ 0x88001220, 0x209FB9C0, 0x704C0582, 0x02C1219F,
+ 0x708CC380, 0x6D126119, 0x61D978A5, 0x01A00E0E,
+ 0xC7C8780F, 0xDB1FC0F1, 0xC8084100, 0x2085BB0B,
+ 0xDA0B08C1, 0x0AEA708C, 0x4128FC2F, 0xC8084600,
+ 0x09012085, 0xDA0B4121, 0xFC2F0AD6, 0xC0D1718C,
+ 0x40C07FE0, 0xC8084100, 0x08C12085, 0x238ADA09,
+ 0x02BD0008, 0x708CFC2F, 0x184B6038, 0xA8400082,
+ 0x00821896, 0x18E17FE0, 0x78E00082, 0x45CBC2E2,
+ 0x04588000, 0x0FA2E806, 0x700CFFEF, 0xC6C2B504,
+ 0xFFEF0F96, 0xC6C29504, 0x4528C2E4, 0xF86F0C32,
+ 0x700C4608, 0x724C762C, 0x248A43C1, 0x45A10141,
+ 0xF8AF0D9A, 0x700C70CC, 0x0886D922, 0x704CF8EF,
+ 0x0D3A700C, 0x712CF8AF, 0x78E0C6C4, 0xDD25C2E2,
+ 0x901C41C3, 0xBD9F01C8, 0x1480151B, 0x15C6B100,
+ 0x0BD29480, 0xB102FF6F, 0x08359500, 0x00000F84,
+ 0xC8080C81, 0x40C36852, 0x0C50902C, 0x22059020,
+ 0x90240F8C, 0x9062201C, 0x71046917, 0xB4006B37,
+ 0x0F802205, 0x20209024, 0xB0207124, 0x78E0C6C2,
+ 0x4588C2EA, 0x47484668, 0x0BA64030, 0x4110F86F,
+ 0x800140C3, 0x88604E88, 0xBBC5700C, 0xDA22762C,
+ 0x0500244A, 0x0D0645A1, 0x70CCF8AF, 0x762C700C,
+ 0x4322DA22, 0x0840244A, 0x0CF245A1, 0x70CCF8AF,
+ 0x700CDA22, 0x4302762C, 0x45A14440, 0xF8AF0CDE,
+ 0x700C70CC, 0xDA22762C, 0x244A43E1, 0x45A107C0,
+ 0xF8AF0CCA, 0x700C70CC, 0xDA22762C, 0x244A43C1,
+ 0x45A10800, 0xF8AF0CB6, 0x700C70CC, 0xF8AF0C5E,
+ 0xC6CA712C, 0xD925C2E6, 0x8900B99F, 0x7F0589FB,
+ 0x000540C3, 0x0D6ECC60, 0x752CFDEF, 0xFE2F0CD6,
+ 0x0B0E4608, 0xBFC1F84F, 0xD90C700C, 0x706CDA20,
+ 0x45E1708C, 0xF8AF0C76, 0x40C370CC, 0x1D4C0000,
+ 0xFDEF0D42, 0x60DD722C, 0x262F700C, 0xD9070347,
+ 0x706C704C, 0x0C56708C, 0x70ACF8AF, 0x920D2D41,
+ 0x700CF20D, 0x704CD907, 0x708C706C, 0x0C3E70AC,
+ 0x268AF8AF, 0x258C0FC3, 0x700C1DFF, 0x744CD910,
+ 0x708C706C, 0x0C2645E1, 0x70CCF8AF, 0x0387262F,
+ 0xD907700C, 0x706C704C, 0x0C12708C, 0x70ACF8AF,
+ 0x920D2E41, 0x700CF20D, 0x704CD907, 0x708C706C,
+ 0x0BFA70AC, 0x268AF8AF, 0x258C0FC3, 0xD8801DFF,
+ 0x704CD907, 0x708C706C, 0x0BE270AC, 0x70CCF8AF,
+ 0x0B8A700C, 0x712CF8AF, 0x78E0C6C6, 0xA023772C,
+ 0xA021A022, 0xA0207FE0, 0x4628C2E4, 0x21534508,
+ 0x710C0142, 0xF7EF0C1A, 0xBE23702C, 0x16022644,
+ 0x8540655D, 0xA5007845, 0x78258501, 0xC6C4A501,
+ 0x700CC0F1, 0x0E8AD910, 0x714CF8AF, 0x702CD810,
+ 0xF8AF0E7E, 0x700C714C, 0x0E76D90A, 0x714CF8AF,
+ 0x7EE0C0D1, 0x752C700C, 0xF8AF0665, 0x78E0714C,
+ 0x0FAAC0F1, 0x208AF8AF, 0x40C30B04, 0x04888000,
+ 0xF8AF0FAA, 0x710C9000, 0x1E00702C, 0x901C7004,
+ 0x0B2204C4, 0x700CF8AF, 0x000040C3, 0x0C06C350,
+ 0xD90FFDEF, 0x7EE0C0D1, 0x901C41C3, 0x190004C4,
+ 0x11C00005, 0xE87F8100, 0x800519BC, 0x000040C3,
+ 0x03E11388, 0x702CFDEF, 0x4030C2F0, 0x41004508,
+ 0x800040C3, 0x88C01220, 0x02C1219F, 0x47CB40C1,
+ 0x4E758001, 0x0582209F, 0x67386119, 0x710C882F,
+ 0x080F78B8, 0xB8022030, 0x00D4216C, 0x2145F003,
+ 0x095E0154, 0x200FF86F, 0x087B0351, 0x40822030,
+ 0x12C1259F, 0x1582269F, 0x01012085, 0x2447222F,
+ 0x700C7B0F, 0xDA22762C, 0x0400244A, 0x250A65DD,
+ 0x67BE0480, 0x13D32532, 0x10901613, 0xF8AF0A9E,
+ 0x234470CC, 0xF20CA213, 0x700C65EB, 0xDA22762C,
+ 0x250A718C, 0x0A860480, 0x70CCF8AF, 0x20D02053,
+ 0x20B1080D, 0x08F87076, 0xF00DF841, 0x700C8E73,
+ 0xDA22762C, 0x0500244A, 0x0480250A, 0xF8AF0A5E,
+ 0x244F70CC, 0x252F2183, 0x7B6F0447, 0x762CD880,
+ 0x244ADA22, 0x0A460400, 0x70CCF8AF, 0x09EE700C,
+ 0x712CF8AF, 0x71001600, 0x00068000, 0x000070D3,
+ 0x41C3257F, 0x57300005, 0x000340C3, 0x20CAD090,
+ 0x0AE2004D, 0x702CFDEF, 0x78E0C6D0, 0x88945020,
+ 0x69528801, 0x0F812205, 0xC054900F, 0x00C0206D,
+ 0x0F832205, 0xC02C903B, 0x2205B100, 0x90070F81,
+ 0x2444C1F0, 0xBCC11300, 0x2478B100, 0x783B1001,
+ 0x2205B300, 0x90070F80, 0x7FE0C3EC, 0x78E0B020,
+ 0x215FC0E4, 0x44CB0A03, 0x113A8000, 0x647970CD,
+ 0x63959141, 0x0E237D04, 0x231510A5, 0x61990381,
+ 0x08139123, 0x79DB006E, 0x00412314, 0x91226199,
+ 0x71C57D25, 0x40A1F1F1, 0x78E0C4C4, 0x901C44CB,
+ 0x16000004, 0x90047102, 0x94203804, 0x900743C3,
+ 0xBAA0F804, 0x7A05B9A0, 0xB3407825, 0x7FE0B400,
+ 0x00051B04, 0xE81EC2E2, 0x740CD9BF, 0xFA2F0E02,
+ 0x700CB912, 0xD92572AD, 0x8940B99F, 0x7A25893B,
+ 0x7918712C, 0x210FB902, 0x794B0001, 0x09FAF206,
+ 0x712CF9AF, 0xFB8F091A, 0x1BFF258D, 0xC6C2710C,
+ 0x02FB41C3, 0x0DCA0000, 0xD80AFA2F, 0x1A43256F,
+ 0xFC2F0E5A, 0x14051D00, 0x081ED807, 0x1A060020,
+ 0xD8103043, 0x30031A06, 0xB500B88F, 0xFEAF0B3E,
+ 0xC6C2740C, 0xC1B6C3F6, 0xD8404608, 0x1000B89F,
+ 0x0ABA0095, 0x10E50160, 0x70148092, 0x20CAD80C,
+ 0x267C01A2, 0x1A0B1393, 0x2E013002, 0x00007380,
+ 0x20443679, 0x0E150051, 0x230411F1, 0x16002453,
+ 0x80007080, 0xE88D0161, 0x73146E0B, 0x000D0212,
+ 0x70801600, 0x01608000, 0x02067014, 0x0DC20001,
+ 0x712CF8EF, 0x23524708, 0x26792001, 0x782B11C0,
+ 0x708EDDFF, 0x0D46F407, 0xE805F80F, 0x1FC7258A,
+ 0x088A718E, 0x730CFAEF, 0x08336E0B, 0x26790135,
+ 0x26791141, 0x200410C0, 0x6E0D0050, 0x00B5082D,
+ 0x09A6702C, 0x70140140, 0x70801600, 0x01818000,
+ 0x21CA742C, 0xE88F01E2, 0xE687F00F, 0xE68CF2E5,
+ 0x00E10B50, 0xF00E40A1, 0x70801600, 0x01828000,
+ 0x1A0BE803, 0x78F03002, 0x430242A1, 0xFD8F0A96,
+ 0x1381267D, 0x20002178, 0x24952505, 0x00122105,
+ 0x70EE70AD, 0x800040D3, 0x72F61220, 0x00260124,
+ 0xA5C02511, 0x40E2F28B, 0x08AE4162, 0x1801F9AF,
+ 0x08B22342, 0x4610FBAF, 0x702CC082, 0xF7AF0CA2,
+ 0x0FEADA50, 0x730CFAAF, 0x13950ED3, 0x03802025,
+ 0xF024F019, 0xF063F027, 0xF061F061, 0xF05FF05F,
+ 0xF037F025, 0xF042F004, 0xF002F059, 0x79F078AF,
+ 0x0AF64282, 0x43C10020, 0x13500E9B, 0x12D00E8B,
+ 0x78AFF04D, 0xFF6F0DF6, 0x700CC182, 0xF8EF0D8A,
+ 0x710C712C, 0xF027712C, 0x08EE78AF, 0xC18201E0,
+ 0x08E2F03D, 0x78AF01E0, 0x78AFF039, 0x714CC180,
+ 0x0B52706C, 0x4110FBAF, 0xC1804022, 0x716C714C,
+ 0x30011C04, 0xFBAF0B3E, 0x30011C00, 0x78AFF027,
+ 0xFF6F09EE, 0x700C4182, 0xF8EF0D3E, 0x710C702C,
+ 0x0D36702C, 0xF01BF8CF, 0x70801600, 0x00098000,
+ 0x78AFB8E3, 0x0CFEF404, 0xF0070040, 0x428279F0,
+ 0x00200A66, 0x1600DB0B, 0x80007080, 0x080F017C,
+ 0xCC22001E, 0x1A227104, 0x730C301C, 0xFAAF0F0E,
+ 0x20031800, 0xE88BCA0A, 0x70811600, 0x00048000,
+ 0x40427BAF, 0xFA6F0EB6, 0x71A542C2, 0xF16F71E6,
+ 0x12D00E0B, 0x13500E13, 0x1600F00E, 0x80007080,
+ 0x0815017C, 0x1600001E, 0x80007080, 0xB8E60001,
+ 0xF8C20A6C, 0x70801600, 0x00018000, 0x0970B8E6,
+ 0x40C1F8E2, 0x70031E00, 0x000F8000, 0x1600C7D6,
+ 0x80007080, 0xE8070163, 0xF203E68D, 0x05F2E68A,
+ 0x1600FFC1, 0x80007080, 0xB8E20001, 0x05EB70ED,
+ 0x27CAFFEF, 0x0E4E13E1, 0x2079F90F, 0x28400000,
+ 0x16000256, 0x80007080, 0xE8040183, 0x30021A0B,
+ 0x23562605, 0xBD9FDDF4, 0x08338D00, 0x085A005F,
+ 0xE8150140, 0x02DF41C3, 0x0AE60000, 0x740CFA2F,
+ 0x10901500, 0x204F702C, 0x42C22040, 0x78F0AD00,
+ 0xFDAF08A2, 0x1D00726C, 0x78F01402, 0x42C2702C,
+ 0xFFEF05FD, 0x78E0726C, 0xC1A1C3F4, 0x43304550,
+ 0xFAEF081A, 0x70CD4210, 0x800040D3, 0x22531138,
+ 0x708E204D, 0x800047CB, 0x0B351220, 0x18002030,
+ 0x16002382, 0x80007080, 0x0825001B, 0x708E007E,
+ 0xFCEF0B56, 0x8F404042, 0x750C4410, 0x017741C3,
+ 0x43420003, 0xFA2F0A6A, 0x0500240A, 0x41624042,
+ 0x0DD2704C, 0x2578FCEF, 0x71561096, 0x000341C3,
+ 0xC80808D8, 0x082221D6, 0x8F207825, 0x7825B90C,
+ 0x016009D2, 0x7DD0D940, 0xE5FF708D, 0x002D00A8,
+ 0x11C0234A, 0x2005C808, 0x8F000301, 0x7825B80C,
+ 0x0F802005, 0x00D80003, 0x016009AA, 0x238D41A1,
+ 0x24561D3F, 0x0EFA180C, 0x40C2FECF, 0x734CC180,
+ 0x708C4362, 0xF7EF082A, 0x1400702E, 0x25553009,
+ 0xD8071803, 0x10C82D41, 0x2006BB23, 0x244A034B,
+ 0x20A871C0, 0x29010900, 0x29401440, 0xB8C02142,
+ 0x02CC2800, 0x209F8F00, 0x70A20803, 0x70016058,
+ 0x79858820, 0x2140A820, 0x29012200, 0x71261000,
+ 0x2800B8C0, 0x8F0002C1, 0x0803209F, 0x621A70A2,
+ 0x88406278, 0xA8207945, 0x800040C3, 0x88000484,
+ 0xF1AB661E, 0x7885C808, 0x0F802005, 0xF0D80003,
+ 0x01600912, 0x238D702C, 0x24561E3F, 0x0E62180C,
+ 0x4042FECF, 0x085E702C, 0x1800FB2F, 0x40822043,
+ 0x78E0C7D4, 0x2482C3F8, 0x46503617, 0x47104130,
+ 0x3F802400, 0x03800000, 0xDA78702C, 0xF7AF0962,
+ 0x30C01CD4, 0x2400702C, 0x00003F80, 0x09520308,
+ 0xDA78F7AF, 0x2400702C, 0x00003F80, 0x09420290,
+ 0xDA78F7AF, 0x300014D4, 0x0819704E, 0x700F02B1,
+ 0x70981600, 0x000C8000, 0x30012084, 0x31982841,
+ 0x300514D4, 0x42E2740C, 0x01D641C3, 0x43220005,
+ 0x0580240A, 0xFA2F08EA, 0x0600260A, 0x702C710C,
+ 0x05D32800, 0xF96F0CF2, 0x084B40E2, 0x1CD83031,
+ 0xC0823000, 0xFBEF0FC6, 0x14C841E2, 0x42C33101,
+ 0x00009038, 0x7905C808, 0x7945B902, 0x216D9120,
+ 0x14CA0A10, 0x78253101, 0x01D741C3, 0xB8020002,
+ 0x92007A05, 0x206D4202, 0x740C0A0D, 0xFA2F0892,
+ 0x14D443A1, 0x2B403000, 0x0F122093, 0x2079FA2F,
+ 0x1C5A034E, 0x16003018, 0x80007080, 0x206D0009,
+ 0x70140940, 0x30001CE0, 0x006120CA, 0x30001CE0,
+ 0x300014D4, 0x03510815, 0xB802C808, 0x0F802005,
+ 0xC234903B, 0x00451800, 0x0CFE7FDB, 0x230F0120,
+ 0x1CDC25D4, 0x24003000, 0x00003F80, 0x702C0218,
+ 0xF7AF084E, 0x45D3DA78, 0x12228000, 0x303008BD,
+ 0x1E00DA60, 0x90077484, 0x1E00C17C, 0x901C7045,
+ 0xC80804A8, 0x800041C3, 0xB8020EAB, 0x0F802005,
+ 0x0504901C, 0x00451800, 0x70C51E00, 0xC164900B,
+ 0xF76F0FF6, 0x3E402455, 0x3E402455, 0x01A0086E,
+ 0x710CD960, 0xFFAF0C52, 0x212F712C, 0x700C0507,
+ 0x09DA704C, 0x4330F9EF, 0xF82F0CF6, 0x43104062,
+ 0x20801501, 0x20821500, 0x00A408C3, 0x27407842,
+ 0x6821280C, 0x240AC808, 0x20A87040, 0x2A4007C0,
+ 0x24000301, 0x00003F83, 0x61990210, 0x79057B54,
+ 0xB992B902, 0xB99FB99C, 0xB3209120, 0x8005218C,
+ 0x003C238A, 0x00CD21C0, 0x3F832400, 0x02080000,
+ 0x71447B54, 0xF03BB320, 0x308714D1, 0x2507232F,
+ 0x308314CC, 0x3E412455, 0x04C0240A, 0x32052440,
+ 0x308214CF, 0x0580260A, 0xF9AF0F4A, 0x300014DC,
+ 0x308714D1, 0x3F812400, 0x01840000, 0x308314CD,
+ 0x04C0240A, 0x34052440, 0x0580260A, 0x308214CF,
+ 0xF9AF0FB2, 0x300014DC, 0x36001440, 0x30181C68,
+ 0x308014E9, 0x710CE80B, 0x34801CEC, 0x1C63B890,
+ 0x1CF03498, 0x1C643000, 0xBD083018, 0xE70D6E06,
+ 0x2447212F, 0x33581C5B, 0x22102840, 0x1C5D70AD,
+ 0x1C5E3018, 0x1C5C33D8, 0x145E3418, 0x75103600,
+ 0x000604A0, 0x3600145D, 0x790E78A2, 0x300014E0,
+ 0x00012908, 0xF048262F, 0x7017F4AD, 0x40C3F2AD,
+ 0x0E9C8000, 0x68346508, 0x212F7825, 0x0C4E0507,
+ 0x780FFFAF, 0xF86F0E36, 0x0E42D8C8, 0x202FF86F,
+ 0x150104C8, 0x1C602081, 0x15003498, 0x09352080,
+ 0x1C5F0024, 0x79023498, 0x240A7124, 0x20A87040,
+ 0x28400480, 0x21050381, 0x90040F82, 0x24003DD0,
+ 0x00003F81, 0x21F40208, 0x71040001, 0xB220E120,
+ 0xFECF0B92, 0x0AFED80F, 0xD90FF92F, 0x0086208A,
+ 0x900746CB, 0xB600C2C4, 0x096AD840, 0x712CF86F,
+ 0x20811501, 0x20801500, 0x00240931, 0x71247902,
+ 0x7040240A, 0x048020A8, 0x03812840, 0x3F832400,
+ 0x017C0000, 0x21057B14, 0x90040F82, 0x922001D0,
+ 0xB3207104, 0xB220E120, 0xFECF0B3A, 0x0AA6D80F,
+ 0xD90FF92F, 0x712CD882, 0x091AB600, 0xD840F86F,
+ 0x208E1500, 0x20801501, 0x03A40877, 0x0DAA78AF,
+ 0x4010F9CF, 0x13802E40, 0x0F8F2005, 0x01D09004,
+ 0x3F802400, 0x017C0000, 0x20F49720, 0x78220380,
+ 0x88012054, 0x0023000E, 0x26024420, 0x00007001,
+ 0xD840FFC0, 0x483142C1, 0x3F802400, 0x02180000,
+ 0x430278B6, 0xB02078D4, 0x01DC41C3, 0x0D820003,
+ 0x740CF9EF, 0x3F802400, 0x02100000, 0x038020F4,
+ 0x1501B700, 0x76102080, 0xFFE5079C, 0x0AA671C5,
+ 0x71A5FECF, 0x702CF143, 0x3F802400, 0x05880000,
+ 0xF76F0D6E, 0x702CDA50, 0x3F802400, 0x05380000,
+ 0xF76F0D5E, 0x702CDA50, 0x3F802400, 0x04E80000,
+ 0xF76F0D4E, 0x702CDA50, 0x3F802400, 0x04980000,
+ 0xF76F0D3E, 0x702CDA50, 0x3F802400, 0x04480000,
+ 0xF76F0D2E, 0x702CDA50, 0x3F802400, 0x03F80000,
+ 0xF76F0D1E, 0x14D4DA50, 0x08773000, 0x6D340371,
+ 0x3600145B, 0x254E7905, 0x20051300, 0x145C004B,
+ 0x78103601, 0xB80479A5, 0x36091208, 0x15007825,
+ 0x7E3B2081, 0x43C3710D, 0x00009038, 0x034F2940,
+ 0x20811501, 0x10482014, 0x13A40857, 0x124C2705,
+ 0x310214C8, 0x10082796, 0x14D871C5, 0x61593001,
+ 0xB9027985, 0xB1007965, 0x310214CA, 0x300114D8,
+ 0x79856159, 0x7965B902, 0x02C41900, 0x40C3F1E6,
+ 0x0E9C8000, 0x14D46508, 0x68343002, 0x212F7825,
+ 0x0A190507, 0x780F02B1, 0xFF8F0A12, 0x0886F003,
+ 0x268AFB4F, 0xF0051FC7, 0xFF8F089A, 0x14CCDE7F,
+ 0x24553081, 0xC2823E40, 0xF9AF0B56, 0x3E4F2455,
+ 0x300014DC, 0x14CCE825, 0x42E23081, 0x2440C382,
+ 0x14CF3604, 0x250A3080, 0x70CC0580, 0xC74170EC,
+ 0xFBAF0CEE, 0x2455C640, 0x41E23E40, 0x2400704C,
+ 0x00003F84, 0x24000588, 0x00003F85, 0x24000538,
+ 0x00003F86, 0x09BE04E8, 0xC386FBEF, 0x081AF024,
+ 0x14D00200, 0x222F3087, 0x14CC0507, 0x43223081,
+ 0x3604145A, 0x32052440, 0x308014CF, 0x0580260A,
+ 0xF9AF0FB6, 0x2400C740, 0x00003F81, 0x24000588,
+ 0x00003F82, 0x24000538, 0x00003F83, 0x0C6204E8,
+ 0xC086FB2F, 0x308114CD, 0x3F802400, 0x01840000,
+ 0x3F8F2400, 0x01840000, 0xF9AF0AA6, 0x14DCC284,
+ 0xE8283000, 0x308114CD, 0xC38442E2, 0x38042440,
+ 0x308014CF, 0x0580250A, 0x71EC70CC, 0x0C42C741,
+ 0xC640FBAF, 0x240041E2, 0x00003F80, 0x714C0184,
+ 0x3F842400, 0x04980000, 0x3F852400, 0x04480000,
+ 0x3F862400, 0x03F80000, 0xFBEF090A, 0xF025C388,
+ 0x01C00F66, 0x308714D0, 0x0507222F, 0x308114CD,
+ 0x145A4322, 0x24403604, 0x14CF3405, 0x260A3080,
+ 0x0F060580, 0xC740F9AF, 0x3F812400, 0x04980000,
+ 0x3F822400, 0x04480000, 0x3F832400, 0x03F80000,
+ 0xFB2F0BAE, 0x1501C088, 0x14CE2087, 0x15003084,
+ 0x74F0208C, 0xFFED058E, 0x245A706D, 0x24001286,
+ 0x00003F8F, 0x24000308, 0x00003F8E, 0x7FB60380,
+ 0x7F947EB6, 0x218A7E94, 0xD97F1FC1, 0x11250B6D,
+ 0x9040210C, 0x20310E11, 0x16802400, 0x0080101C,
+ 0x10000B55, 0x11882300, 0x3F802400, 0x05380000,
+ 0x020220F4, 0x3F802400, 0x04E80000, 0x020020F4,
+ 0x96004853, 0xB6006078, 0x3F802400, 0x04480000,
+ 0x020220F4, 0x3F802400, 0x03F80000, 0x020020F4,
+ 0x97407842, 0x7810621A, 0x02492009, 0x20097870,
+ 0xB7400041, 0xF1CC7165, 0x9700F745, 0x4121B600,
+ 0xF407F007, 0x96209700, 0x804408F5, 0x2400F1F9,
+ 0x00003F80, 0x78B60290, 0x71857894, 0xF1A3B020,
+ 0x30300847, 0x3E402455, 0x74841E00, 0xC164900B,
+ 0x6832C808, 0x901C40C3, 0x79050504, 0x04841900,
+ 0x18A4D920, 0x40C38484, 0xC17C9007, 0x00451800,
+ 0x74841E00, 0xFED49007, 0x005C1886, 0xFF2F0B96,
+ 0x049C1886, 0x09B2F005, 0x14CCF9AF, 0x15003081,
+ 0x40C3208F, 0x07070707, 0x30181C5F, 0x20801501,
+ 0x3F8E2400, 0x017C0000, 0x02507710, 0x41E2002D,
+ 0x70AD66FE, 0x708E714E, 0x70CE706E, 0x3600145D,
+ 0x790E78A2, 0x300014E0, 0x00012908, 0xF048262F,
+ 0x081DF434, 0x42E13030, 0x3F802400, 0x02180000,
+ 0x20F478B6, 0x210A03D0, 0xF01B2400, 0x3F802400,
+ 0x03800000, 0x41C378B6, 0x000401E5, 0x20F443A1,
+ 0x240003D1, 0x00003F80, 0x78B60290, 0x0440250A,
+ 0x03D020F4, 0x095A740C, 0x240AF9EF, 0x200C0400,
+ 0xF705A580, 0x0B21F410, 0xAEA02445, 0x260A718E,
+ 0x230A2400, 0x714E2440, 0x145E71A5, 0x0D813600,
+ 0xF00D9004, 0x20300C13, 0xA580200C, 0xA4C121CC,
+ 0x206122C0, 0x708EF3F2, 0x202FF1F0, 0x68290487,
+ 0x300014E0, 0x8E00790C, 0x783D7914, 0x7D0FAE00,
+ 0x300014D4, 0xF48AE08D, 0x41C3740C, 0x000301E6,
+ 0x43A142E1, 0xF9EF08EA, 0x04C0240A, 0x41C3740C,
+ 0x000201E7, 0x08DA42E1, 0x43A1F9EF, 0x37041222,
+ 0x01E841C3, 0x202F0003, 0x42E10100, 0x43A178F6,
+ 0x800170C3, 0xB0A04D44, 0xF9EF08B6, 0x14C8740C,
+ 0x2F403101, 0x12081348, 0x254E360B, 0x14D81306,
+ 0x23053000, 0x60381203, 0x3601145C, 0x46CB7865,
+ 0x00009038, 0x79A5B802, 0x01022E40, 0x7A2578C5,
+ 0x1F892000, 0x10000000, 0x2305B040, 0x14C8124C,
+ 0x14D83100, 0x60383001, 0xB8027885, 0xB04078C5,
+ 0x310014CA, 0x300114D8, 0x6D346038, 0x145B7865,
+ 0xB8023603, 0x01832305, 0x7B2578C5, 0x14CAB060,
+ 0x14D83101, 0x60383000, 0xB8027885, 0xB06078C5,
+ 0x70801600, 0x017C8000, 0x001F08AB, 0x70801600,
+ 0x00098000, 0x013F089F, 0x15CB2305, 0x903840C3,
+ 0x23051540, 0xBC02120C, 0x10012405, 0x2305B140,
+ 0xB9021241, 0x000D2105, 0x08002054, 0x79057C05,
+ 0xB460B540, 0xF037B160, 0xF9AF0FBE, 0x460840A1,
+ 0x300014D4, 0x02B1081F, 0x0837740C, 0xD8403030,
+ 0x01E941C3, 0x20020003, 0x740C04C4, 0x43A142E1,
+ 0x41C3F017, 0x000301EC, 0x43A142E1, 0xF9AF0FB2,
+ 0x04C0240A, 0x41C3740C, 0x000201ED, 0x740CF00F,
+ 0x01EA41C3, 0x42E10003, 0x240A43A1, 0x0F9204C0,
+ 0x740CF98F, 0x01EB41C3, 0x42E10002, 0xF9AF0F82,
+ 0x05AD43C1, 0x71E5FFEF, 0x3F802400, 0x017C0000,
+ 0x016009D2, 0x300214D4, 0x30310897, 0x0B7A40E2,
+ 0x702CF92F, 0x4210D939, 0x0F56B913, 0x740CF9AF,
+ 0x20901500, 0x24132240, 0x24922240, 0x1407272F,
+ 0x20801501, 0x03E40863, 0x13112F40, 0x275F70AD,
+ 0xC0821501, 0x43A142E1, 0x740C603E, 0x41C37EB4,
+ 0x000401C9, 0x11051620, 0xF9AF0F16, 0x11041670,
+ 0x12012D40, 0x2105C808, 0x43C30441, 0x00009004,
+ 0x71A57825, 0x04812005, 0x04C02005, 0x96306952,
+ 0xB8027A65, 0x7865B220, 0x11011670, 0x92740DB3,
+ 0x7106B020, 0x0C1EF1CC, 0x0CC2FE8F, 0xC7D8FF0F,
+ 0x1CFCC2FA, 0x2482B6C8, 0x40103D06, 0xDA78702C,
+ 0x3F802400, 0x013C0000, 0xC1504528, 0xC14EC14F,
+ 0xC14CC14D, 0xC14AC14B, 0xF72F0EC6, 0x2455C149,
+ 0x702C3C40, 0xF72F0EBA, 0x2455DA78, 0x702C3880,
+ 0xC548DA3C, 0xF72F0EAA, 0xC093C547, 0x0EA2702C,
+ 0xDA3CF72F, 0xC552712C, 0x70441E00, 0x04A8901C,
+ 0xC546C808, 0x6852C545, 0x0F802205, 0x0504901C,
+ 0x2205B020, 0x90040F80, 0x90000090, 0x0F832205,
+ 0xC0909007, 0xB888C042, 0x1600B300, 0x80007083,
+ 0x16000004, 0x80007080, 0x0811017C, 0x2205001E,
+ 0x903B0F80, 0xB020C234, 0x040E2900, 0x7FCFBBC3,
+ 0x40E1752C, 0xF9EF0D7E, 0x44D3C343, 0x12228000,
+ 0x208D1400, 0x35112440, 0x20801401, 0x03640841,
+ 0x160040E1, 0x80007080, 0x083112D9, 0x4002036E,
+ 0xFBEF0A12, 0xE81241A1, 0x742C78AF, 0xFEAF0D86,
+ 0x42004202, 0x23402114, 0x41C343A1, 0x000201A7,
+ 0x0DCEB040, 0x750CF9AF, 0xF1E071A5, 0xF9EF0D26,
+ 0x1400762C, 0x706F208D, 0x20801401, 0x0364084D,
+ 0x16006E12, 0x80007080, 0x083D12D9, 0x4002036E,
+ 0xFBEF09C2, 0xE81841A1, 0x20F4C085, 0x08290340,
+ 0x78AF0071, 0x0D2E742C, 0x4202FEAF, 0x750C4708,
+ 0x41C342E1, 0x000201A8, 0xF9AF0D76, 0x0F0943A1,
+ 0x716F11D1, 0xF1DA71A5, 0x78CF7E05, 0xF7EF09EE,
+ 0xC044C040, 0x060640C3, 0xC0510606, 0x2005C808,
+ 0x14B70400, 0xB8022097, 0x0F802005, 0x15409038,
+ 0x01181000, 0x1401D80D, 0x2084208F, 0xC041300C,
+ 0x20831400, 0x35C7212F, 0xDEC0C808, 0x040B2005,
+ 0x10C40F9B, 0x30EE0993, 0x2B40C591, 0x65690342,
+ 0x06002105, 0x4E31B904, 0x22057905, 0x284002C0,
+ 0x22960088, 0x20050008, 0x90381F80, 0xB0201540,
+ 0x20056568, 0xB8040601, 0x79054E10, 0x02C02205,
+ 0x42C36892, 0x15809038, 0x1F802405, 0x15409038,
+ 0x6568B020, 0x06012005, 0x4E10B804, 0x20057905,
+ 0xB0201080, 0x65687A85, 0x06012005, 0x4E10B804,
+ 0x702C7825, 0xC08DB200, 0xB0207874, 0x7874C08F,
+ 0xC08BB020, 0xB0207874, 0x7874C089, 0x30300B0B,
+ 0x1800B020, 0x71640045, 0x70CDF1B4, 0x1F802632,
+ 0x0E9C8000, 0x78256834, 0x08BAC100, 0x780FFF6F,
+ 0xF82F0C0A, 0x0C16D8C8, 0xC004F82F, 0x0F96700C,
+ 0x712CF7EF, 0x089EC100, 0x700CFF6F, 0x0BB6C000,
+ 0xD91AF9EF, 0x704E72AE, 0x20100A0F, 0x70801600,
+ 0x00408000, 0x212FE827, 0x40020480, 0xFBEF0856,
+ 0x46104130, 0x20532140, 0x41227014, 0x04C121CA,
+ 0x742C782F, 0xFEAF0BBE, 0xC5924202, 0x75224708,
+ 0xB5004102, 0xFC2F0D12, 0xE80D4042, 0x23CA70D6,
+ 0x202F2441, 0x742C04C7, 0xFEAF0B9A, 0x78E54202,
+ 0x258DB500, 0x714E253F, 0xF9AF0BBE, 0x140078CF,
+ 0x4110208D, 0x20801401, 0x01347510, 0x2111002D,
+ 0xF294B340, 0x208F1403, 0x0FEA4002, 0x41A1FBAF,
+ 0x1342273C, 0x21F4C192, 0x2078008C, 0x781B0000,
+ 0x38822455, 0x73046862, 0x10C12C01, 0x21447C19,
+ 0x255A0043, 0xC09313C1, 0x6119623A, 0x61D862DA,
+ 0x2444AA60, 0xA8401042, 0x78B4C08B, 0x09299020,
+ 0x438900E0, 0xC08FB060, 0x902078B4, 0xB0806981,
+ 0x178C255A, 0x3F802400, 0x013C0000, 0x78346098,
+ 0x04441800, 0x78B4C089, 0x09239020, 0xB0400080,
+ 0x78B4C08D, 0x69819020, 0x255AB080, 0x2455178C,
+ 0x60983C40, 0x18007834, 0x0E910444, 0xC18F13B1,
+ 0x910079B4, 0x0050083D, 0x7074E88F, 0x1783255A,
+ 0x0E7F208A, 0x3F812400, 0x013C0000, 0x01E120CA,
+ 0xB1006179, 0xEB8EF00E, 0xB1606861, 0x1783255A,
+ 0x3F812400, 0x013C0000, 0x79146179, 0x01C51900,
+ 0x78B4C08D, 0xE9179020, 0x32C22305, 0x16CB2304,
+ 0x10032378, 0xF41A7A6B, 0x00700931, 0xB0406941,
+ 0x1782255A, 0x3C402455, 0x78346058, 0x01C51800,
+ 0x7054F00C, 0x1782255A, 0x0E7F208A, 0x3C412455,
+ 0x01E120CA, 0xB1006159, 0xF16671A5, 0xE68F71C5,
+ 0xFFC5061C, 0x41C3750C, 0x000101B4, 0xF9AF0A92,
+ 0x41C34202, 0x000001B5, 0xF9AF0A86, 0x70AD740C,
+ 0x0A56DE0F, 0x78AFF9AF, 0x41C34200, 0x000101B6,
+ 0xF9AF0A6E, 0x268D740C, 0x71A51DFF, 0x01B741C3,
+ 0x0A5E0000, 0x740CF9AF, 0x20911400, 0x215FC693,
+ 0x245523CD, 0x66BE3880, 0x1401651D, 0x0F71208F,
+ 0x740C1464, 0x01B841C3, 0x0A360001, 0x4222F9AF,
+ 0x42B1DF0F, 0x24821201, 0x01B941C3, 0x0A220001,
+ 0x740CF9AF, 0x1E3F278C, 0x740CD9DD, 0xF9AF0A12,
+ 0x740CB911, 0x01BB41C3, 0x0A060001, 0x4222F9AF,
+ 0x42D1DF0F, 0x24821201, 0x01BC41C3, 0x09F20001,
+ 0x740CF9AF, 0x1E3F278D, 0x41C3740C, 0x000001BD,
+ 0xF98F09DE, 0xE50FE60F, 0xF1C97126, 0x208D1400,
+ 0x13640FAB, 0x42A14FB0, 0x240A7104, 0x20A87000,
+ 0x096D0E40, 0xC08F30AE, 0x008120F4, 0x00B40925,
+ 0x0783225A, 0x3F802400, 0x013C0000, 0x20146078,
+ 0x98800041, 0x814111FE, 0x2C44643C, 0xB0201081,
+ 0x20F4C08D, 0x2455008C, 0x60783C40, 0x10B40C17,
+ 0x20149820, 0x14FE030C, 0x6199914C, 0x00812944,
+ 0x2400B020, 0x00003F8C, 0xC087013C, 0x10C32435,
+ 0x7854792E, 0x2B44633B, 0xB0200081, 0xC6877144,
+ 0x091F7EB4, 0x740C336E, 0x11441600, 0x41C34202,
+ 0x000301C1, 0xF9AF093A, 0x140143A1, 0x72C5208F,
+ 0x71A575F1, 0x1400F7AF, 0x0F99208D, 0xC1871364,
+ 0x79B44FB0, 0x240A7104, 0x42A17000, 0x034020A8,
+ 0x308E0913, 0x080B9900, 0xB8830052, 0x7813F002,
+ 0x7224B100, 0xF0367144, 0x270479B8, 0x262F2040,
+ 0xF22DF007, 0x70801600, 0x017C8000, 0xC08FE809,
+ 0x034020F4, 0xC08DE808, 0x034020F4, 0x2706E804,
+ 0xF01D2057, 0xC287C191, 0x22F561B9, 0x0A190342,
+ 0x890001F2, 0x03310815, 0x700C7104, 0x01C241C3,
+ 0xF00A0001, 0x7704E804, 0xF009A900, 0x41C3700C,
+ 0x000101C3, 0xF72F0DA2, 0x140142A1, 0x71A5208F,
+ 0x93650F99, 0xC001712C, 0x262F7704, 0xC041F007,
+ 0x262FF205, 0x034CF5C7, 0x1600FFC2, 0x80007080,
+ 0x0895017C, 0x1400001E, 0x0F8D2081, 0xC8081044,
+ 0x903841CB, 0x160015C0, 0x80007088, 0x200512D9,
+ 0x4F30040B, 0x240A7104, 0x20A87000, 0x08670D80,
+ 0xC491106E, 0x034D2940, 0x2205642A, 0x6A740600,
+ 0x4A76DAC0, 0x25057E05, 0x687212C0, 0x10082596,
+ 0x02402305, 0x6428B0C0, 0x060E2005, 0x4A10B804,
+ 0x25057E05, 0x68B212C0, 0x12402505, 0x6428B0C0,
+ 0x060E2005, 0x4A10B804, 0x21547E05, 0x7B051800,
+ 0xB3C078A5, 0x2305642B, 0xBB04060C, 0x7A857A62,
+ 0x7124B040, 0x716E70ED, 0xEF08724E, 0x70801600,
+ 0x00408000, 0x00100879, 0x40027EFB, 0xFBAF0BE6,
+ 0xC18741C1, 0x894079D4, 0xE8058922, 0x7D4569B4,
+ 0x6AB4F003, 0x710C7D25, 0x0B1278F8, 0x780FFA2F,
+ 0x2347212F, 0x4202750C, 0x01C541C3, 0x43E10003,
+ 0xF96F0F8E, 0x0440240A, 0x0BCAC100, 0x4022FF2F,
+ 0x205FC003, 0x60D80B00, 0x70827002, 0x20300815,
+ 0x0B27A8B6, 0x1E002010, 0x80007342, 0xF00800F7,
+ 0x20100B21, 0x73421E00, 0x00F28000, 0x228D71ED,
+ 0x706E2FFE, 0x1E00F00A, 0x80007342, 0xF0060101,
+ 0x73421E00, 0x00FC8000, 0xFA2F0AA2, 0xC808730C,
+ 0x2005B802, 0x90070F81, 0xC002C090, 0x2480B100,
+ 0x14043D06, 0xC6DA341B, 0x1CFCC2FA, 0xC1A5B6C8,
+ 0x702CC140, 0x0D5AC044, 0xC000F9AF, 0x1443256F,
+ 0x8D00C043, 0x900747CB, 0x2078C2C0, 0xD90F0100,
+ 0xE030B802, 0x0B9EB700, 0xD80FF8AF, 0x71AED9FF,
+ 0x208A700E, 0xB7320FC7, 0x15441F28, 0x94041FDC,
+ 0xB708B706, 0x15441F04, 0x7054C200, 0x093E711C,
+ 0x710CFF2F, 0xFACF0ADE, 0x1097150E, 0x720C776E,
+ 0x800046CB, 0x46D31220, 0x12D98000, 0x34041C0A,
+ 0x34041C08, 0x8E00C041, 0xD840E803, 0xD825F002,
+ 0x2D00B89F, 0xB9022401, 0x040D210F, 0x7D0B8800,
+ 0x40C3F2A1, 0x12DC8000, 0x40028020, 0x0F76C200,
+ 0xC300FBEF, 0x7DAFC203, 0x0872700C, 0x41A1F96F,
+ 0xF78F083E, 0x702C700C, 0xF92F0BB2, 0x450842A1,
+ 0xF7EF0DEA, 0x0DF6D8C8, 0x78B0F7EF, 0x329B2440,
+ 0x32192440, 0x341B2300, 0x34192100, 0x70AD700F,
+ 0x6892C808, 0x1F802405, 0xC034901F, 0x8E23B0A0,
+ 0x09338E02, 0x79020024, 0x20831600, 0x28406941,
+ 0x240A0381, 0x20A87080, 0x0B1303C0, 0x2405002E,
+ 0xBA921042, 0xBA9FBA9C, 0x7104B2A0, 0x000071C3,
+ 0x09864000, 0xD814FD2F, 0xFE8F0F8A, 0x712CC004,
+ 0xF7EF08EA, 0x8E027810, 0x4110704E, 0x03942840,
+ 0x083F8E03, 0xD80F0464, 0x20801600, 0x044E0827,
+ 0x2F802405, 0x02F49004, 0x22059000, 0xE88B2012,
+ 0x41C3740C, 0x0003024B, 0x43224202, 0xF96F0DA2,
+ 0x712644A1, 0x2F942400, 0x40000000, 0x0A46F1E2,
+ 0xD90FF8AF, 0x3011082D, 0x20310A33, 0x15C02500,
+ 0x7A10702C, 0x0EEE4002, 0x4150FEEF, 0x712C4002,
+ 0xFEEF0EE2, 0x1B004222, 0x23083342, 0xF0062353,
+ 0x20110A0B, 0x33421900, 0x71A5710F, 0x98D40D25,
+ 0x41C34003, 0x00010250, 0xF72F0A4E, 0x0F164202,
+ 0xC001F90F, 0x7704710E, 0xC0417014, 0x202FF54D,
+ 0x41C304CA, 0x00000252, 0xF72F0A2E, 0x202FB83F,
+ 0x43C304C7, 0x01328000, 0x140B70E2, 0x2049308D,
+ 0xC0220881, 0x140A4832, 0x49103080, 0x00802009,
+ 0xAB02AB00, 0x6852C808, 0x30801409, 0x0F8C2205,
+ 0xC034901F, 0x4834B420, 0x200949B0, 0xAB010300,
+ 0x8E03AB03, 0x08378E62, 0x786200E4, 0x038D2B40,
+ 0x40C36881, 0x12D98000, 0x240A88C0, 0x20A87300,
+ 0x0E1303C0, 0x220510EE, 0xB8920340, 0xB89FB89C,
+ 0x7164B020, 0x000075C3, 0x0E4A4000, 0x700CFE8F,
+ 0xB708B706, 0xC0A5B702, 0x341B1404, 0x78E0C6DA,
+ 0x1CFCC2FA, 0xC1BBB6C8, 0x710C4018, 0x01402800,
+ 0x2140250A, 0x160068B2, 0x80007080, 0x260A0162,
+ 0x44702100, 0x47304158, 0xB203208C, 0x31801C68,
+ 0xE899F403, 0xE809F009, 0xBD41208C, 0xBF8220CC,
+ 0x00700000, 0x2050F20F, 0x204A3080, 0x208C21C0,
+ 0xF40D8802, 0x70801600, 0x01648000, 0x80802053,
+ 0x0CAEF205, 0x712CF82F, 0x26424010, 0x250F20C0,
+ 0x212F1553, 0x08232007, 0x706F0135, 0x40C3790D,
+ 0x0FA08000, 0x02022040, 0x004D20F4, 0x005222F4,
+ 0xBB8E736C, 0x736CF006, 0x000045CB, 0x704EFFFF,
+ 0x44CB710C, 0xFE030000, 0xB60A468B, 0x000041C3,
+ 0xB604F0B0, 0x1C5C6943, 0x276F3004, 0x1C441443,
+ 0xB61C3004, 0x6C0AB610, 0x40C3B60F, 0xFFB50001,
+ 0xB969B629, 0x2258B643, 0xC0400B02, 0x000140C3,
+ 0x1C4EFE04, 0x24403084, 0xB63B1282, 0xB662489A,
+ 0x000743C3, 0xC058F004, 0x1C42B864, 0x42C33084,
+ 0xF0B40001, 0x6B0BC04C, 0x6A0BC049, 0x8F00C046,
+ 0x01002078, 0xB61AC152, 0xB617B962, 0xE030B802,
+ 0xB60BC14F, 0xD966C080, 0x33041C5A, 0x31C51C50,
+ 0x31C51C2C, 0x36C41C2A, 0x36C41C10, 0x1C0AC243,
+ 0x1C6436C4, 0x1C5E36C4, 0x1C5836C4, 0xC35536C4,
+ 0x36C41C52, 0x36C41C4C, 0x36C41C46, 0x36C41C40,
+ 0x36C41C3A, 0x31851C28, 0x30851C22, 0x00E00BAE,
+ 0x30C51C1C, 0x4142D80F, 0x43424242, 0xFB6F0BD2,
+ 0x0480240A, 0x722C700C, 0x706C704C, 0x0C1A44A1,
+ 0x45A1FB6F, 0x14C7262F, 0x12012D41, 0x704C78AF,
+ 0x0922706C, 0x44C1FF2F, 0x2102217D, 0x0407212F,
+ 0xFE2F0E96, 0x40C240C1, 0xF8AF0B12, 0x45CB41A2,
+ 0x4DAC8001, 0x0B2B43B1, 0x212F3135, 0x0C5606C7,
+ 0x4082FF2F, 0x7280244A, 0x20A8702C, 0x080B0240,
+ 0x1D00004E, 0x72A515C4, 0x71677124, 0x0F9FF1ED,
+ 0x46EA2030, 0xB203208C, 0x4082F406, 0x00E00C82,
+ 0xF010702C, 0xBC01208C, 0x40C2F406, 0x01600846,
+ 0xF0084182, 0x410340A2, 0x08CE4223, 0x706C0160,
+ 0xBC01208C, 0x76F2F205, 0xFE610EBC, 0x0EBA4082,
+ 0x4082FE6F, 0x2A102354, 0x2382222F, 0x456A702E,
+ 0x21350945, 0x0447212F, 0xFF2F0BDA, 0x704C4082,
+ 0x02950A2D, 0x008E081D, 0x20832033, 0xE90DC11A,
+ 0x00520B0B, 0x79C29520, 0x9520B520, 0xB5207142,
+ 0x714472A5, 0x0BF7F1EE, 0xF1F68013, 0x22902040,
+ 0xF1E07126, 0xA0310A71, 0x208C464A, 0xF407B203,
+ 0x0BEE4082, 0x702C00E0, 0x208CF00F, 0xF407BC01,
+ 0x0FB240C2, 0x41820120, 0x40A2F007, 0x42234103,
+ 0x01600836, 0x704C706C, 0x900741C3, 0x1924C29C,
+ 0x706C0015, 0x70841E00, 0xFED49007, 0x708C8F00,
+ 0x01002078, 0x1904B802, 0xD80F0014, 0xB144B140,
+ 0x1E00B146, 0x90077084, 0x1E00F804, 0x901F7084,
+ 0x0A5EC004, 0x702CFB6F, 0x1404C0BB, 0xC6DA341B,
+ 0x1CFCC2FA, 0xC1BAB6C8, 0x41C34510, 0x000003DD,
+ 0xF96F097E, 0x730C740C, 0x900741DB, 0x70EEC17C,
+ 0xF9EF0CDA, 0x30051900, 0xFEEF095E, 0x0D5240A2,
+ 0x710CF9EF, 0x45CBD840, 0x4E748001, 0xD90BB89F,
+ 0x10E588E0, 0x0A0A8090, 0x40A1FEEF, 0x0A0240A1,
+ 0xD911FEEF, 0xD90BC808, 0xB802DAF7, 0x0F802005,
+ 0x00B89038, 0xC0409000, 0xF7EF0D0E, 0x40A140A1,
+ 0x0D06D911, 0xDAF8F7EF, 0xD91140A1, 0xFC6F0EE6,
+ 0x089E724C, 0xC096FF2F, 0x0D7EC096, 0xD90BF9EF,
+ 0x0D76C096, 0xD911F9EF, 0x800046CB, 0x8E001220,
+ 0x209F704C, 0xC3960582, 0x60B9708C, 0x00A00C1E,
+ 0x2705750C, 0x40DB141B, 0x4EBF8001, 0x30F10B1F,
+ 0x30CF2378, 0x704C8E00, 0x0582209F, 0x708CC396,
+ 0x06012000, 0x00A00BF6, 0x6F01D80A, 0x903B46D3,
+ 0xC041C0B8, 0x000042C3, 0xC808BA68, 0x718C43A2,
+ 0x70CC70AC, 0x68324350, 0x2105D870, 0xB1000581,
+ 0x0C02D8C8, 0x218AFFEF, 0x44D30004, 0x4DAC8001,
+ 0x32112440, 0x800047CB, 0x220A12D9, 0x24402500,
+ 0x0F413210, 0xD8C82135, 0x082D8F00, 0x212F05EE,
+ 0x09F205C7, 0x40A2FF2F, 0x7280244A, 0x4342708D,
+ 0x20A84202, 0x080B0280, 0x9320030E, 0x7264B220,
+ 0x71857244, 0x25122240, 0x25102040, 0xF1E371E6,
+ 0x0004218A, 0x43A24262, 0x70AC708C, 0x0B9670CC,
+ 0x704EFFEF, 0x2500200A, 0x21350A45, 0x8F0040A2,
+ 0x04AE0831, 0x0487212F, 0xFF2F099A, 0x244A40A2,
+ 0x706D7280, 0x442A4302, 0x030020A8, 0x02CE080F,
+ 0x94209340, 0x793D6159, 0x7264B320, 0x71657285,
+ 0x25102040, 0x25112140, 0xF1E07146, 0x00E009C2,
+ 0xD870702C, 0x43A2D910, 0x000042C3, 0x718C2950,
+ 0x70CC70AC, 0xFFEF0B2E, 0xD8704050, 0x4202D910,
+ 0x708C43A2, 0x0B1E70AC, 0x70CCFFEF, 0xB802C808,
+ 0x05812005, 0xB100C000, 0x09DE40A1, 0xD90BFE6F,
+ 0x09D640A1, 0xD911FE6F, 0xFEEF0F16, 0xC096C096,
+ 0xF9EF0BF6, 0xC096D90B, 0xF9EF0BEE, 0x8E00D911,
+ 0x209F704C, 0xC3960582, 0x60B9708C, 0x00A00A9E,
+ 0x0B1D750C, 0x704C30F1, 0x209F8E00, 0xC3960582,
+ 0x2000708C, 0x0A860601, 0xD80A00A0, 0x45CB70CD,
+ 0xBF648000, 0x0E61C001, 0x252F1025, 0xD8C80387,
+ 0x0004218A, 0x43A24262, 0x0A9A728C, 0x70CCFFEF,
+ 0x2500200A, 0x093D702E, 0x8F002115, 0x046E082B,
+ 0x0447212F, 0xFF2F089E, 0x244A40A2, 0x708D7280,
+ 0x41A14302, 0x024020A8, 0x030E0809, 0xB1409340,
+ 0x72247264, 0x20407185, 0xE5142510, 0xF1E57126,
+ 0xF1D271C5, 0x08CA40A2, 0x712C00E0, 0xF9EF0AC2,
+ 0x1900700C, 0xC0BA3045, 0x341B1404, 0x78E0C6DA,
+ 0x1CFCC2FA, 0x2482B6C8, 0xC1443F17, 0xC08D4318,
+ 0x0ECE702C, 0xDA14F6AF, 0x0E0A750C, 0xD918F96F,
+ 0x800041DB, 0x11001222, 0x0ABA3081, 0x700CFB6F,
+ 0x00012052, 0x30801100, 0x742C6038, 0x704C7E0F,
+ 0xFE2F0E22, 0x206D40C1, 0x740C01CD, 0x41C342A1,
+ 0x0002033B, 0xF92F0E6A, 0xED8A43C1, 0x033D41C3,
+ 0x0E5E0000, 0xD80AF92F, 0x000007A9, 0x1243266F,
+ 0xF86F0982, 0x148F16F4, 0x750CC04C, 0xF96F0DA6,
+ 0x1100702C, 0x0A5E3081, 0x700CFB6F, 0x00012052,
+ 0x30801100, 0x742C6038, 0x704C7D0F, 0xFE2F0DC6,
+ 0x206D40A1, 0x41C301C0, 0x0002033C, 0xC04243A1,
+ 0x0E0E740C, 0xC202F92F, 0xB802C808, 0x0F812005,
+ 0xC0909007, 0x0F802005, 0x00909004, 0xB8899000,
+ 0xC004B100, 0x00002079, 0xC045E008, 0x7014C00C,
+ 0x20CAC005, 0xC04502A2, 0xC0438E00, 0x10801639,
+ 0x730C7014, 0xF219C046, 0xC003C102, 0x700C790B,
+ 0x20CAC048, 0xC04800E2, 0x70801600, 0x017B8000,
+ 0x001E081B, 0xC003C102, 0xD807790B, 0x20CAC046,
+ 0xC0460122, 0x700CF003, 0xC004C048, 0x2FC3268A,
+ 0x208A7014, 0xDE250FC7, 0x200226CA, 0xBE9FC106,
+ 0xBFC3C008, 0x700E6038, 0xC74A702E, 0xC007C047,
+ 0xA000210C, 0x002D0210, 0xC10272AE, 0x2440220A,
+ 0x790BC003, 0xF20E700C, 0x220AC006, 0x210C2440,
+ 0x700CA000, 0x1418F7C6, 0xC0063012, 0x0440200E,
+ 0x21012A40, 0x22056852, 0x7A052052, 0x68B66834,
+ 0x728E7945, 0x706E7D25, 0x8E204262, 0x716E8E1B,
+ 0x2B007825, 0xB9022081, 0x0081210F, 0xF211790B,
+ 0x202F7F2F, 0x08FE0487, 0x41E1FEEF, 0xC003C102,
+ 0xF207790B, 0xD8FF79AF, 0xFEEF097A, 0x248C42E1,
+ 0x160029BF, 0x80007080, 0x08130001, 0x244A00BF,
+ 0x16000FC0, 0x80007084, 0x40630120, 0x42C2702C,
+ 0x70AC726C, 0x091E70CC, 0x70EEF8AF, 0x230A720F,
+ 0x8E2025C0, 0x71EE8E1B, 0x2F007905, 0xB80224C0,
+ 0x04C0200F, 0xF2A3782B, 0x000045D3, 0x231F28F0,
+ 0x11022540, 0x2D41308D, 0x251F2095, 0x671F154F,
+ 0x30801105, 0x03640839, 0x44D3704E, 0x1A3C8000,
+ 0x0A27C005, 0xC0042005, 0x2500E887, 0x101C1680,
+ 0x0A0F0080, 0x0A7E2000, 0x24000060, 0x248023C0,
+ 0x71462184, 0x77A2F1EE, 0xF1E471A5, 0xC103C202,
+ 0xF2397A2B, 0x308D1102, 0x036408E3, 0x10522544,
+ 0x30801103, 0x0354203C, 0xC00570ED, 0x10050F4F,
+ 0xE888C004, 0x16802500, 0x0080101C, 0x10000F3B,
+ 0x30061410, 0x7BF079B0, 0x704C4062, 0x0822718C,
+ 0x71ACF7EF, 0x42624122, 0x0802219A, 0x229FC393,
+ 0x61790401, 0x245F6159, 0x623A2A02, 0x2501225F,
+ 0x7AF4623A, 0x71E5B200, 0x1105F1D9, 0x71A53080,
+ 0x708EF1CC, 0x20950C77, 0x20100C09, 0xF0038E1B,
+ 0xE8338E00, 0x20100C0B, 0x30921104, 0x1102F003,
+ 0x24783092, 0xE8852000, 0x308F1105, 0x1103F003,
+ 0xC305308F, 0x14104062, 0x41423006, 0x718C42E1,
+ 0xF7AF0FAE, 0x412270AC, 0x219A4262, 0xC3930802,
+ 0x0401229F, 0x30061410, 0x2A0D245A, 0x70AC728C,
+ 0xC3056179, 0x4142623A, 0x42E1655D, 0x0F82B500,
+ 0x4062F7AF, 0x7186B50A, 0x208CF1C6, 0x05F334FD,
+ 0x7126FFEF, 0x242FC005, 0x40A22000, 0x800043DB,
+ 0xC04B0025, 0x30811300, 0x3080131B, 0x710C7905,
+ 0x04002800, 0x200FB802, 0x782B0400, 0x702EF2AB,
+ 0x01527136, 0x090D000D, 0x131B2010, 0xF0043080,
+ 0x30801300, 0xF29D7014, 0x2214704E, 0x7156244F,
+ 0x002D012E, 0x702CC08D, 0xF6AF0B26, 0x24004282,
+ 0x00003F93, 0x231605EC, 0x70CD2413, 0x24532315,
+ 0x24932314, 0xC003C102, 0xF236790B, 0x79EF70AD,
+ 0x0B7A7AAF, 0x710CF92F, 0xE988C104, 0x16812700,
+ 0x0081111C, 0x10400D47, 0x230A41C1, 0x219A1400,
+ 0xC2930802, 0x1401239F, 0x2A0C215A, 0x2503225A,
+ 0x7261623A, 0x61796299, 0x000121F4, 0x78B4C08D,
+ 0x0A1B9040, 0xB0200045, 0x3F802400, 0x054C0000,
+ 0x60987061, 0x7BB4631B, 0x71A5B3C0, 0x0DA3C005,
+ 0xF0199004, 0x410240C1, 0x0802209A, 0x219FC293,
+ 0x60580401, 0x215A6038, 0x61192A01, 0x2500225A,
+ 0x14346110, 0x090F3101, 0x1B000005, 0x1C342384,
+ 0xC0073004, 0x07607610, 0x71C5FFE5, 0xC003C102,
+ 0xF21F790B, 0xC68D70AD, 0xE888C004, 0x16802700,
+ 0x0080101C, 0x10000D1F, 0xE88D9600, 0x41C3700C,
+ 0x00040343, 0x43224202, 0x0480240A, 0xF6AF0F1A,
+ 0x71A545A1, 0x0DD5C005, 0x72C59024, 0x1434F00E,
+ 0xE88C3100, 0x41C3700C, 0x00030344, 0x43224202,
+ 0xF6AF0EF6, 0x0480240A, 0x71E57146, 0x7126F169,
+ 0x258DF158, 0x710E22BD, 0x710C704E, 0x1300C049,
+ 0x131B3081, 0x79053080, 0x2800710C, 0xB8020480,
+ 0x0480200F, 0x02F4782B, 0xC0470021, 0xD9504042,
+ 0xF72F0A12, 0x200A734C, 0x24003480, 0x00003F80,
+ 0x209F054C, 0x70AE3401, 0x30182000, 0x02CC71B6,
+ 0x0D0D000D, 0x131B2010, 0xF0043080, 0x30801300,
+ 0x02AE7014, 0x710C0021, 0x05402800, 0xF9AF0CDE,
+ 0x252F780F, 0x40421540, 0xFB2F0D8A, 0x471041A1,
+ 0xC003C102, 0xF2C0790B, 0x20002752, 0x700E708E,
+ 0x23512200, 0x08FBC052, 0xDB0820B5, 0x2007C012,
+ 0x790F0400, 0x215F700C, 0x653E0502, 0x43484330,
+ 0x082BC105, 0x796F0065, 0xE988C104, 0x16812600,
+ 0x0081111C, 0x00400811, 0x30812034, 0x71917C6F,
+ 0x004523CA, 0x71047244, 0xC006F1EC, 0x708DC208,
+ 0x00032109, 0x3F802400, 0x05EC0000, 0x04802016,
+ 0x05402015, 0x04C02014, 0xC005B060, 0x7000240A,
+ 0x050020A8, 0xE888C004, 0x16802600, 0x0080101C,
+ 0x10000C15, 0x32C02000, 0x79629020, 0x00820907,
+ 0xB020C108, 0x71857265, 0x72CE70ED, 0x244A6F72,
+ 0x702C7100, 0x20A870CD, 0x40420640, 0x3F822400,
+ 0x054C0000, 0x0401209F, 0x255A6058, 0x621A2A02,
+ 0x2500235F, 0x20F46058, 0x783B00C2, 0x71647124,
+ 0x00002A00, 0x27147E05, 0xC207140F, 0x79CF78EF,
+ 0xFEAF0CF2, 0xC00A7A4F, 0x0B00205F, 0x71ED78F5,
+ 0x70237022, 0x253F268D, 0x7106A8DE, 0x4042F185,
+ 0x2A02255A, 0x0401209F, 0x3F812400, 0x054C0000,
+ 0x621A6038, 0xE886C004, 0x05041A24, 0x05041A10,
+ 0xE886C00C, 0x05041A26, 0x05041A12, 0x0F1B8A30,
+ 0x12242030, 0xB8020080, 0x8A127905, 0x7825B804,
+ 0x00811226, 0xB902F008, 0x12267905, 0xB8040080,
+ 0x8A327825, 0x7E0569D6, 0x79CFC007, 0x0C767A0F,
+ 0x740CFEAF, 0x205FC00A, 0x60B80B00, 0x70237042,
+ 0x0382182E, 0x3F802400, 0x05EC0000, 0x04802016,
+ 0x05402015, 0x20300F0D, 0x880290E0, 0xF004B804,
+ 0xBF049001, 0xC0077F05, 0x23C7242F, 0x0BA6790F,
+ 0x4082FEAF, 0x2140C00A, 0x205F3890, 0x21400B00,
+ 0x21403991, 0x42A23B93, 0x240A4342, 0x651D0500,
+ 0x21007542, 0x2032334E, 0xAEF22346, 0x3A8F2140,
+ 0x1085161E, 0x23472132, 0x233267A9, 0xC1402340,
+ 0x034541C3, 0xC0410008, 0xF8EF0F66, 0x0D27740C,
+ 0x8E322030, 0xE81EC009, 0x1E00C003, 0x80007042,
+ 0xC10200FB, 0xF23D790B, 0x40C38E3E, 0x01718000,
+ 0xC009F029, 0xC003E81B, 0x70421E00, 0x00F18000,
+ 0x790BC102, 0x8E3EF22D, 0x800040C3, 0xF01B0167,
+ 0x1E00C003, 0x80007042, 0xC1020100, 0xF221790B,
+ 0x40C38E3E, 0x01768000, 0xC003F00D, 0x70421E00,
+ 0x00F68000, 0x790BC102, 0x8E3EF213, 0x800040C3,
+ 0x1801016C, 0x20320052, 0x18012341, 0x21320052,
+ 0xA8202341, 0xA82167A9, 0x23412332, 0x2040A822,
+ 0x053D3A18, 0x71A6FFEF, 0x714EC00B, 0xC04B7704,
+ 0x700C7014, 0xFFE204EA, 0x0A22C049, 0x730CF9AF,
+ 0x3F172480, 0x341B1404, 0x78E0C6DA, 0x09FEC0F1,
+ 0x710CF9AF, 0x030541C3, 0x0E960000, 0xD80AF8EF,
+ 0x030641C3, 0x42C30001, 0x25030000, 0xF8EF0E82,
+ 0x740CD80A, 0x030741C3, 0x714C0004, 0x738C726C,
+ 0xF8EF0E6E, 0x740C74AC, 0x030841C3, 0x704C0004,
+ 0x123444C3, 0x45C3ABCD, 0xEF12ABCD, 0xF8EF0E52,
+ 0x09AADB07, 0x700CF9AF, 0x00200A7E, 0x700CD807,
+ 0x00C420AB, 0xF0007FFF, 0x2079C2E6, 0x4708000E,
+ 0x256F4E18, 0xB5001A43, 0x10002752, 0xF82F0946,
+ 0x30021A06, 0x41C3E808, 0x000002F6, 0xF8EF0E12,
+ 0xF018D80A, 0xEF05D80A, 0xB912D9BD, 0x41C3F004,
+ 0x000002F5, 0xF8CF0DFA, 0xF90F0C96, 0xEF86E802,
+ 0x085678DB, 0x7404FEEF, 0x084E78DB, 0x7304FEEF,
+ 0x40C370F5, 0x8009FFFF, 0x006120C2, 0x30031A06,
+ 0xD8FDB500, 0xFD6F0B66, 0x00E120CA, 0x78E0C6C6,
+ 0x7FE0710C, 0x00C420AB, 0x1E00710C, 0x900C7004,
+ 0x7EE00088, 0x7014C2F6, 0x42C3C808, 0x01238000,
+ 0x901C43C3, 0x404804B0, 0x0F8122CA, 0x01248000,
+ 0x008B2840, 0x23056BA4, 0xDF3F10C1, 0x23058A40,
+ 0x91001343, 0xBF08E50C, 0x12CD2505, 0x938078E4,
+ 0x784595C0, 0x2404B100, 0x7EE413C0, 0x7AC57845,
+ 0xB540B300, 0x901C41D3, 0x100004E4, 0x21401080,
+ 0x16002215, 0x80007081, 0x48350124, 0x14402305,
+ 0x254090C0, 0x25CE2116, 0x26531021, 0x23051181,
+ 0x23051542, 0x25001583, 0x92209057, 0x01131300,
+ 0x01902153, 0x001A4230, 0x23530024, 0x25002194,
+ 0x000E943E, 0x25000024, 0x0022953E, 0x752C0003,
+ 0x0A06700C, 0xB913F6AF, 0x6832C808, 0x05832105,
+ 0x05422105, 0x04402105, 0x7EE44328, 0x23D22204,
+ 0x15C12605, 0x23502000, 0x2305B020, 0x901C1F80,
+ 0x270404E8, 0x758214CF, 0x2005B020, 0x7DE52480,
+ 0xB3A0B200, 0x78E0C6D6, 0x4628C2E4, 0x16004508,
+ 0x90307100, 0x1A2103BC, 0xE909301C, 0x10710E3D,
+ 0x724C700C, 0x30831A07, 0x258CF020, 0x004E9804,
+ 0x258C0029, 0x00629FC3, 0x258C002C, 0x258C9002,
+ 0xF23D9004, 0x9404258C, 0x258CF23D, 0xF44F9804,
+ 0x1A07754C, 0xF00A3143, 0x030241C3, 0x096A0001,
+ 0x42C1F6AF, 0x30821207, 0x41C3D80A, 0x00030303,
+ 0x0C4E43A1, 0x44C1F8EF, 0x258CC6C4, 0xF6D597C8,
+ 0x9808258C, 0x258CF223, 0xF2259848, 0x9F800D97,
+ 0xE9010000, 0xF223F02B, 0x9402258C, 0x714CF427,
+ 0x30431A07, 0x258CF1E2, 0xF21D9844, 0x9408258C,
+ 0xDA07F41D, 0x31C31A07, 0x734CF1D8, 0x30C31A07,
+ 0x744CF1D4, 0x31031A07, 0xDA08F1D0, 0x32031A07,
+ 0xDA09F1CC, 0x32431A07, 0x704CF1C8, 0x30031A07,
+ 0x764CF1C4, 0x31831A07, 0xDA0AF1C0, 0x32831A07,
+ 0x78E0F1BC, 0x8FC3208C, 0x0821F209, 0x41C301D1,
+ 0x0470901C, 0x00451900, 0x41C3F006, 0x0470901C,
+ 0x01051900, 0x00051900, 0x903041C3, 0xB10000C8,
+ 0x0020001D, 0x00051904, 0x903041C3, 0xB10000C8,
+ 0xB104B830, 0x00200009, 0x00051904, 0x903041C3,
+ 0x91000010, 0x801F08FF, 0x0B822155, 0x080F9200,
+ 0x1A0408B1, 0x1ACE0045, 0x9100005D, 0x801E08FF,
+ 0x78E07EE0, 0x70801600, 0x01078000, 0x01002044,
+ 0xB8227FE0, 0x0343226F, 0x0500120E, 0x000070D3,
+ 0x700C0C80, 0x07C520E0, 0x050112E0, 0xF60BE1FF,
+ 0x02032142, 0x00940B23, 0x0430092B, 0xF20FE1C0,
+ 0x218CF014, 0xF20B8002, 0x8010218C, 0x091DF211,
+ 0x00000F81, 0x8A004000, 0x8A00F007, 0x0080206D,
+ 0x8A00F004, 0xB8C0781D, 0x20797FE0, 0x8A000000,
+ 0x00C0206D, 0x78E0F1FA, 0x70801600, 0x00058000,
+ 0x20797FE0, 0x78E00000, 0x0F8EC0F1, 0xE809FFCF,
+ 0x70801600, 0x00F48000, 0x710CB8E4, 0x700CF402,
+ 0x7EE0C0D1, 0x216FC0F1, 0x890005C3, 0x700CB8E6,
+ 0x895AF208, 0x00811135, 0x73347945, 0xFFC10FCC,
+ 0x7EE0C0D1, 0x0F43216F, 0xB8E18900, 0x7CE0700C,
+ 0x810011E8, 0x7000263C, 0x0C7F0000, 0x78E07EE0,
+ 0x4300C0F1, 0x70801600, 0x00018000, 0x013F0825,
+ 0x0EA64428, 0xD808FFEF, 0xFFEF0ED2, 0x232F4060,
+ 0xF20880C8, 0xFFEF0EC6, 0x14001404, 0x0F3F238C,
+ 0x7EE0C0D1, 0x44CBC5E1, 0x28F00000, 0x030D201F,
+ 0x786A789B, 0x0184229F, 0x2C4160BB, 0x782A1080,
+ 0x605C6078, 0x800042C3, 0x22561A3E, 0x64080800,
+ 0x10012415, 0x60336A0A, 0x0A256152, 0x700C00E4,
+ 0x1F812434, 0x1B408000, 0x21CC7230, 0xF78880C6,
+ 0x4A314970, 0x79307810, 0x00002109, 0x78E0C4C2,
+ 0x1600C2E8, 0x80007101, 0x47C3000A, 0x18000000,
+ 0x21044010, 0x248A01C1, 0x27507001, 0x700D0307,
+ 0x70CC702D, 0x70CD70ED, 0x706D704C, 0x20A8708D,
+ 0x20150101, 0x906023C0, 0x087B9001, 0x631D00E4,
+ 0x6B014873, 0x7D0C73C0, 0x00462340, 0x21007034,
+ 0x20DA1349, 0x20D503C1, 0xF22D1001, 0x01E10915,
+ 0x8C07208B, 0x271A780C, 0x621A1003, 0xF0237E75,
+ 0x083BF20D, 0xDB08023F, 0x8003208B, 0x262FF213,
+ 0xDB07F005, 0x01A323CA, 0x204BF011, 0xF2078300,
+ 0x736CB8E3, 0x00A123CA, 0x781DF009, 0x00432044,
+ 0xB8E5F005, 0x23CA756C, 0x647C0121, 0x23157BEC,
+ 0x71E510CB, 0x00300E4B, 0x2905D8C9, 0x21781180,
+ 0x71F00003, 0x767D729D, 0x26CA7074, 0x20CA0081,
+ 0x71041381, 0x118D2805, 0xFFEF0E42, 0xE8897E1D,
+ 0xBD2271A5, 0x1FC0257C, 0x25CA7014, 0x18821FE1,
+ 0x2080239C, 0x18002084, 0x700C2342, 0x41C3C6C8,
+ 0x00020215, 0x08EA4201, 0x4321F8EF, 0x021641C3,
+ 0x08DE0000, 0xD8C9F8EF, 0xC6C8730C, 0x42C3C2E4,
+ 0x12208000, 0x8A404300, 0x02C1239F, 0x0582229F,
+ 0x2232627A, 0x80010F8D, 0x714C4E86, 0xE9047A18,
+ 0x12012585, 0x0A8A6A12, 0x2005F6EF, 0x252F008E,
+ 0x700C0387, 0xDA22762C, 0x244A43A1, 0x0BEE0480,
+ 0x70CCF72F, 0xD907D880, 0x706C724C, 0x70AC708C,
+ 0xF72F0BDA, 0x700C70CC, 0xF72F0B82, 0xC6C4712C,
+ 0xB80243E3, 0x0F822005, 0x00009000, 0xFE6F09E6,
+ 0x7B204020, 0x78E0B200, 0x4608C2E6, 0x70801600,
+ 0x00088000, 0x72AD7214, 0x0A264728, 0x25CAF6EF,
+ 0x0E461161, 0x0A02F70F, 0x0819F6CF, 0x700C003F,
+ 0x704CD907, 0x708C706C, 0x0B8270AC, 0x70CCF72F,
+ 0x752CD809, 0x704CB813, 0x0008238A, 0x45C1708C,
+ 0xF72F0B6A, 0xD80C70CC, 0x42A1D92B, 0x708C706C,
+ 0x0B5A45C1, 0x70CCF72F, 0xD92BD80C, 0x706C42A1,
+ 0x45C1708C, 0xF72F0B46, 0xEF0670CC, 0xD80C6D41,
+ 0xF005D92B, 0xD92BD80C, 0x706C42A1, 0x45C1708C,
+ 0xF72F0B2A, 0x708C70CC, 0x4788D92B, 0xBF9242A1,
+ 0x40E1726C, 0x0B1645C1, 0x70CCF72F, 0xD92BD80C,
+ 0x726C42A1, 0x45C1708C, 0xF72F0B02, 0x700C70CC,
+ 0x744CD907, 0x708C706C, 0x0AF270AC, 0x264AF72F,
+ 0x7DFB0280, 0x40A1D907, 0x706CDA10, 0x45C1708C,
+ 0xF72F0ADA, 0x2F4170CC, 0xD90710C0, 0x706C744C,
+ 0x70AC708C, 0xF72F0AC6, 0x700C70CC, 0x744CD907,
+ 0x708C706C, 0x0AB670AC, 0x264AF72F, 0x0D420BC0,
+ 0x700CF70F, 0x744CD907, 0x708C706C, 0x0A9E70AC,
+ 0x70CCF72F, 0x18002555, 0x704CD907, 0x708C706C,
+ 0x0A8A45C1, 0x70CCF72F, 0x78E0C6C6, 0xC1A6C3FA,
+ 0xC045D977, 0x0F1AB910, 0x740CF8AF, 0x800040C3,
+ 0x10020150, 0x42830501, 0x1002B220, 0xB2210501,
+ 0x05011002, 0x1002B222, 0xB2230501, 0x05011002,
+ 0x9020B224, 0x9021B225, 0x9022B226, 0x808010D7,
+ 0xE805B227, 0x30961210, 0x120FF003, 0x700E3096,
+ 0x800040C3, 0xC0441228, 0x01F07216, 0x702C0026,
+ 0x20510811, 0x70801600, 0x003F8000, 0xF2E97014,
+ 0x2800710C, 0x0A160400, 0x780FF96F, 0x702EC005,
+ 0xF29C7014, 0x202FC704, 0xC0803407, 0x04402015,
+ 0x040020F4, 0xF6EF086A, 0x0C8268B2, 0x78B0F72F,
+ 0x70AD45F1, 0x010875D2, 0x704E0026, 0x3540210A,
+ 0x0BF7706E, 0x11012095, 0x740C3494, 0x1F8E2532,
+ 0x04788000, 0x41C34222, 0x00050078, 0x240A4362,
+ 0x45C10400, 0xF8AF0E4A, 0x0500260A, 0x13310E1B,
+ 0x3083120E, 0x0407202F, 0xFB2F0F3E, 0x0487212F,
+ 0xDA22E803, 0x6B09F00A, 0x2538DA22, 0x23781001,
+ 0x20052000, 0x7AC0807E, 0x4382710C, 0x04C02800,
+ 0x683244C1, 0x782570CC, 0x272F762C, 0x700C2007,
+ 0xF72F095A, 0x05C0250A, 0x13310E79, 0x1487262F,
+ 0x0EF64003, 0x41C1FB2F, 0x244FE823, 0x740C21D4,
+ 0x41C34222, 0x00050079, 0x240A4362, 0x254A0400,
+ 0x0DCE0300, 0x260AF8AF, 0x0B130500, 0x704C2030,
+ 0x7704CA0E, 0x10000D07, 0x700CDA22, 0x4382762C,
+ 0x0300244A, 0x05C0250A, 0xF72F0902, 0x400370CC,
+ 0xFB2F0EA6, 0xE88E41C1, 0x742C700C, 0xF72F0BE2,
+ 0x0B11704C, 0x700C2030, 0x0BD6702C, 0x704CF72F,
+ 0x71667146, 0x74A6F187, 0xF17E71A5, 0x74367126,
+ 0xFFE506DA, 0xF045E72C, 0x704E740F, 0x72EEC080,
+ 0x04802015, 0x70AD70AE, 0x040020F4, 0x2005781B,
+ 0x00040F93, 0x0E4D1000, 0x240A2030, 0x25002580,
+ 0x80002F95, 0x70ED1228, 0x2B00225A, 0x1F822732,
+ 0x04788000, 0x007A41C3, 0x78F50002, 0x04002014,
+ 0x200E2532, 0x0D1A740C, 0x43C1F8AF, 0x71E578AF,
+ 0x71A57062, 0xB89CB802, 0x248DB89F, 0xA0C02A3F,
+ 0x26FF278D, 0x0D1571AE, 0x78AF103E, 0xB8027062,
+ 0xB89FB89C, 0x04441800, 0x30BF208D, 0xC0047146,
+ 0x72047106, 0xF10AC044, 0x901C40C3, 0xB02001F8,
+ 0x804418F0, 0x78E0C7DA, 0x716EC2F4, 0x23064010,
+ 0x16002013, 0x80007080, 0x70140131, 0x2740224A,
+ 0x2100240A, 0x46504570, 0x0E864628, 0x22CAF6AF,
+ 0x70AD25A1, 0x011C7552, 0x40A20026, 0x1F912532,
+ 0x06188000, 0x092A4122, 0x2632FAEF, 0x08BD144F,
+ 0x0D1B0010, 0x700C1131, 0x744CD910, 0x708C706C,
+ 0x0400250A, 0xF6EF0FC6, 0x700C70CC, 0x704C762C,
+ 0x240A43E1, 0x250A0440, 0x0FB20400, 0x70CCF6EF,
+ 0xD922700C, 0xF72F0A9A, 0x0D85704C, 0x0E191755,
+ 0x1F08734E, 0x16000000, 0x80007080, 0x085D00CA,
+ 0xF034001F, 0x734F0E55, 0x00000006, 0x14110D61,
+ 0x800040C3, 0x88201222, 0x203C8803, 0x0D1A0040,
+ 0x4162FB2F, 0x0F96E81A, 0xD8FAFBAF, 0x700C7910,
+ 0xF72F0A4E, 0x274F704C, 0x700C11C3, 0x704C762C,
+ 0x0440240A, 0x0400250A, 0xF6EF0F42, 0x700C70CC,
+ 0x0A2ED922, 0x704CF72F, 0x0F62D8FA, 0x7910FB8F,
+ 0x0A1E700C, 0x704CF72F, 0xF19671A5, 0x0C41EDFE,
+ 0x8E012010, 0x00DF080D, 0x20538E14, 0xF21880FE,
+ 0x0EBA700C, 0x712CF6EF, 0xF68F0D86, 0x000040C3,
+ 0x0FC23A98, 0xD908FC2F, 0xFE6F0CE6, 0x40C340C1,
+ 0x0D400003, 0xFC2F0FAE, 0xF1E0D908, 0xF1D7D8C8,
+ 0xD941700C, 0xF72F09CA, 0x700C704C, 0xF6EF0E7E,
+ 0x0E41712C, 0x8E1C2010, 0x015E0831, 0xF68F0D42,
+ 0x20452053, 0xD919D880, 0xDB85744C, 0x0EAE708C,
+ 0x70CCF6EF, 0x0E56700C, 0x712CF6EF, 0x005B40C3,
+ 0x0F628D80, 0x702CFC2F, 0x09EE700C, 0x4102F8EF,
+ 0x78E0C6D4, 0x716EC2F6, 0x23064010, 0x16002013,
+ 0x80007080, 0x70140131, 0x2740224A, 0x2140240A,
+ 0x2100250A, 0x47504670, 0x0BD24628, 0x22CAF96F,
+ 0x0CDE25A1, 0x0AE2F68F, 0x70ADFE4F, 0x012A7552,
+ 0x40C20026, 0x1F912532, 0x06188000, 0x0F824122,
+ 0x2632FAAF, 0x7014144F, 0x0D11F285, 0x700C2030,
+ 0x091ED91E, 0x714CF72F, 0x11310D55, 0x762C700C,
+ 0xF72F090E, 0x700C714C, 0x704CD92C, 0x708C706C,
+ 0x0400250A, 0xF6EF0E06, 0x700C70CC, 0x704CD92D,
+ 0x708C706C, 0x0400250A, 0xF6EF0DF2, 0x700C70CC,
+ 0x08DE762C, 0x714CF72F, 0x41E14022, 0xF72F09B2,
+ 0x25424202, 0x08451600, 0xF0500154, 0x41E14022,
+ 0xF72F099E, 0xED234202, 0x14D00D31, 0x94110DE7,
+ 0x800040C3, 0x88201222, 0x203C8803, 0x0B5A0040,
+ 0x4162FB2F, 0x700CE867, 0x0896762C, 0x714CF72F,
+ 0x11C1274F, 0xF1DC4022, 0x70801600, 0x00CA8000,
+ 0x003E0859, 0xD91E700C, 0x0C47F025, 0x8E012010,
+ 0x00DF080D, 0x20538E14, 0xF21B80FE, 0xFE4F09D6,
+ 0x0D1A700C, 0x712CF6EF, 0xF68F0BE6, 0xFE4F09EA,
+ 0x000040C3, 0x0E1E3A98, 0xD908FC2F, 0xFE6F0B42,
+ 0x40C340C1, 0x0D400003, 0xFC2F0E0A, 0x700CD908,
+ 0x082ED918, 0x714CF72F, 0x762C700C, 0xF72F0822,
+ 0x71A5714C, 0x098EF16C, 0x700CFE4F, 0xF6EF0CCE,
+ 0x0F5B712C, 0x8E1C2010, 0x015E084B, 0xF68F0B92,
+ 0xFE4F0996, 0xD925700C, 0xDB85704C, 0x250A708C,
+ 0x0CFA0400, 0x70CCF6EF, 0xD926700C, 0xDB85704C,
+ 0x70AC708C, 0xF6EF0CE6, 0x094A70CC, 0x700CFE4F,
+ 0xF6EF0C8A, 0x40C3712C, 0x8D80005B, 0xFC2F0D96,
+ 0x710C702C, 0xF8EF0822, 0x09B64102, 0xC6D6F98F,
+ 0x47CBC2EA, 0x02FE8000, 0x10911700, 0xF92F0CBE,
+ 0x40C3730C, 0x11388000, 0xE80B8800, 0x70801600,
+ 0x00018000, 0x02002044, 0x00002078, 0x700CF002,
+ 0x0E36D911, 0xB913F62F, 0x207E090B, 0x0D5AD820,
+ 0x09EAFF8F, 0x8FA1F94F, 0x10901700, 0xF6AF0AF2,
+ 0x10022589, 0xFE4F08F2, 0x70CDED1B, 0x1F802600,
+ 0x03808000, 0xDA0F8820, 0xF72F0826, 0x80801080,
+ 0x762C700C, 0xF6EF0F3A, 0x258D714C, 0x71C51CBF,
+ 0xFE4F08A2, 0x0BE6700C, 0x712CF6EF, 0x0896F003,
+ 0x080FFE4F, 0xD822207E, 0xFF8F0CFE, 0x0912F1D5,
+ 0x090DF98F, 0xD821207E, 0xFF8F0CEE, 0x78E0C6CA,
+ 0x43C3C5E1, 0x04628000, 0x93034008, 0xF042242F,
+ 0x7A1DF215, 0x2200706D, 0x00040F8C, 0x20A81000,
+ 0x201503C0, 0x716512C2, 0x924192A0, 0x7D45BA10,
+ 0xBA9C6C52, 0xBA9F7185, 0x6038A2A0, 0x9300B303,
+ 0xB3006038, 0x78E0C4C2, 0x1CFCC2FA, 0x4710B6C8,
+ 0xB89FD840, 0x2100240A, 0x45504378, 0x00991000,
+ 0x10E54630, 0x700E8098, 0x716E724E, 0x24002B00,
+ 0x2004722E, 0xB80206CF, 0x040E200F, 0x70AD4003,
+ 0xF23078EB, 0x23402B00, 0xF92F0B92, 0x40C3780F,
+ 0x11388000, 0xE8188800, 0x70801600, 0x00018000,
+ 0x00FF0825, 0x259F4002, 0x209F1582, 0x42C202C1,
+ 0x708C43A2, 0x0500250A, 0x651975E2, 0xFFEF0CCA,
+ 0xF01078CF, 0x259F4002, 0x209F1582, 0x42C202C1,
+ 0x240A43A2, 0x75E20500, 0x0B126519, 0x78CFFFEF,
+ 0x218D4023, 0x71AD243F, 0x20BF228D, 0x0B2E710E,
+ 0x730CF92F, 0x341B1404, 0x78E0C6DA, 0x4568C3E6,
+ 0x47284648, 0xB0091CF8, 0x30011C04, 0x30C21C01,
+ 0xF6EF0D9A, 0x2578C360, 0x41C11000, 0x6841781B,
+ 0xF6EF0D3E, 0x0D86C080, 0x40E1F6EF, 0x0A8E700C,
+ 0x712CF6EF, 0x78E0C7C6, 0x2945C2E4, 0x4608018B,
+ 0x0D3D70AD, 0x8E0112C5, 0x8E228E40, 0x7A05B808,
+ 0xB8088E03, 0xB8107825, 0x00812005, 0x8E448E05,
+ 0xB8087734, 0xF2077845, 0xB99CB902, 0xB100B99F,
+ 0x0AD6F003, 0x76C5FC0F, 0xF1E571A5, 0x78E0C6C4,
+ 0x7034C2E4, 0x800041C3, 0xF22712E0, 0x00C1110A,
+ 0x7180244A, 0x7B31C808, 0x2144B923, 0x68520401,
+ 0x22057965, 0x90030F8C, 0x7B2FD580, 0x0F812205,
+ 0xD5849003, 0x800042C3, 0xB4600548, 0x20A8B160,
+ 0x12100300, 0x79050401, 0x2105B902, 0x90030F81,
+ 0xB160C000, 0x2042F017, 0xF215803C, 0x20A86944,
+ 0x120604C0, 0xB8020400, 0x0F832005, 0x00009000,
+ 0x04C0120E, 0xB8237911, 0x04002044, 0x780F7825,
+ 0x720CB300, 0x900345CB, 0x46CBD478, 0xF07C9007,
+ 0x10C51D00, 0xFC2F0A32, 0x10C51E00, 0x900F41C3,
+ 0x2150E008, 0x710C04C2, 0x01451900, 0x01451A00,
+ 0xB200B100, 0xB600B500, 0x78E0C6C4, 0x42C3C0E6,
+ 0x12228000, 0x40288A81, 0x0C518AA0, 0x43001364,
+ 0x00022479, 0xE20970B4, 0x22CAC808, 0x20050062,
+ 0x221F00CE, 0x2D40034B, 0x240A130F, 0x7FC57080,
+ 0x20A8706C, 0x2B400440, 0x70B40200, 0x20F478C0,
+ 0x78E512C1, 0xB8027164, 0xB8927165, 0xB89FB89C,
+ 0x7591B020, 0xF7A971A5, 0x78E0C4C6, 0x4010C2E8,
+ 0x800046CB, 0x47CB1222, 0x4DAC8001, 0x2754E903,
+ 0x8EA01F0F, 0x08578E01, 0xD8C80364, 0x800040C3,
+ 0x880012D9, 0x036E0843, 0x0F7A79AF, 0x4002FE2F,
+ 0xC8084408, 0x13822D40, 0x7280244A, 0x700C6832,
+ 0x20A87A25, 0x0C2104C0, 0x255A100E, 0x61F91501,
+ 0x000321F4, 0x02812840, 0x21057945, 0x90040F81,
+ 0xB1600320, 0x71A57104, 0x09A2F1D6, 0xC6C8FC0F,
+ 0x718EC2F4, 0x2C004610, 0x16002040, 0x80007093,
+ 0xB8020004, 0x200F4230, 0x0AAF0051, 0x235302F0,
+ 0xE28A20D3, 0x700EF4B4, 0x081372AE, 0x16002010,
+ 0x80007080, 0x08890040, 0x272F0010, 0x40421400,
+ 0xFAAF0982, 0x260041E1, 0x42C323C1, 0x0E9C8000,
+ 0x89218960, 0x6149634D, 0x6914E804, 0xF0047D05,
+ 0x7D25BD04, 0x2800710C, 0x08A20400, 0x780FF92F,
+ 0x750C7EAF, 0x41C34242, 0x000301D3, 0x0D224302,
+ 0x44C1F86F, 0x0447212F, 0xFE2F0AC2, 0x235F40C1,
+ 0x60F82B00, 0x70C37042, 0x123C8000, 0x20300A15,
+ 0x0CC7A8A0, 0x1E002010, 0x80007342, 0xF008017E,
+ 0x20100CCB, 0x73421E00, 0x017D8000, 0x258D710E,
+ 0x708E2DFE, 0x700EF064, 0x081372AE, 0x16002010,
+ 0x80007080, 0x08890040, 0x272F0010, 0x40421400,
+ 0xFAAF08E2, 0x260041E1, 0x42C323C1, 0x0E9C8000,
+ 0x89218960, 0x6149634D, 0x6914E804, 0xF0047D05,
+ 0x7D25BD04, 0x2800710C, 0x08020400, 0x780FF92F,
+ 0x750C7EAF, 0x41C34242, 0x000301D4, 0x0C824302,
+ 0x44C1F86F, 0x0447212F, 0xFE2F08BA, 0x235F40C1,
+ 0x60F82B00, 0x70C37042, 0x12388000, 0x20300A15,
+ 0x0C31A8A0, 0x1E002010, 0x80007342, 0xF00800F7,
+ 0x20100C35, 0x73421E00, 0x00F28000, 0x258D710E,
+ 0x708E2DFE, 0x1E00F014, 0x80007342, 0xF0100180,
+ 0x73421E00, 0x01018000, 0x1E00F00A, 0x80007342,
+ 0xF006017F, 0x73421E00, 0x00FC8000, 0x70801600,
+ 0x00408000, 0x730CE803, 0x710CF002, 0xF8CF0F6E,
+ 0x78E0C6D4, 0xC1A8C3E6, 0x1243276F, 0x800145CB,
+ 0x8FC04E74, 0x1756712C, 0x20441080, 0x09B60202,
+ 0x40A1FBAF, 0xD91440A1, 0xF6EF0FBE, 0x178A704C,
+ 0x40A11082, 0x099EBAC3, 0xD914FBAF, 0xF8EF0F22,
+ 0x0B4EC084, 0xC080FE2F, 0x082EC080, 0xD910F92F,
+ 0x08358F17, 0x40C3001E, 0x12D88000, 0xE8148800,
+ 0x41C3BEC3, 0x12288000, 0x1B00265F, 0x6119602A,
+ 0x1DA28902, 0x89011002, 0x10021D57, 0xAD4C8903,
+ 0x10021DED, 0xD91040A1, 0xF6EF0F5E, 0x40A1DAFB,
+ 0x0942D910, 0xDA41FBAF, 0x702C40A1, 0xDBFFC284,
+ 0xFFEF0AFA, 0x40A1708C, 0x092AD910, 0x744CFBAF,
+ 0x702C40A1, 0x0BDEC280, 0x716CF72F, 0x78E0C7C6,
+ 0x78E07EE0, 0x1CFCC2FA, 0x2482B6C8, 0x46303604,
+ 0x0F46702C, 0x4318F7AF, 0x451071AD, 0x16C02D00,
+ 0xF9EF0DE2, 0x0DEA68F2, 0x4210F9EF, 0x8E82208C,
+ 0x238A70CD, 0xF7062F83, 0xF9CF0DD6, 0x08932054,
+ 0x70831600, 0x00048000, 0x750CBBC3, 0x41C34263,
+ 0x0002040D, 0xF86F0AEA, 0x16D0270F, 0x41C3D82E,
+ 0x0E010001, 0xB70F478B, 0xB709D895, 0xB890D897,
+ 0x41C3C155, 0x012A0007, 0x2154C040, 0xB86C0942,
+ 0xC043C149, 0xC808E115, 0xC2466989, 0x00422005,
+ 0x7224B755, 0xBA30C24F, 0xB7567905, 0xC14C6C49,
+ 0x00812005, 0x03032005, 0x30441C42, 0x1C44B930,
+ 0x6A2E3044, 0x20057905, 0x00010F80, 0xB73B00FB,
+ 0xB703B930, 0xB73CB830, 0xB704D90F, 0x714CC080,
+ 0x31C51C50, 0x33441C4E, 0xB7AAB7B0, 0x1C58B7C2,
+ 0x1C523384, 0x1C4C3384, 0x1C463384, 0x1C403384,
+ 0xB7DD3384, 0xB7D7B7DA, 0xB7D1B7D4, 0xB7CBB7CE,
+ 0xB7C5B7C8, 0xFDEF0B32, 0x1600C352, 0x80007083,
+ 0x245512D9, 0x244A3801, 0x700C7200, 0x33801C8C,
+ 0x33801C88, 0x33801C84, 0x33801C80, 0x040020A8,
+ 0x0B137A1D, 0x2605008E, 0x90381F82, 0x9240012C,
+ 0x7224B140, 0x000076C3, 0x71044000, 0x1643276F,
+ 0x20448F00, 0xF2068202, 0x70851E00, 0xC3789007,
+ 0x41C3700C, 0xC25C9007, 0x800046CB, 0x1E001222,
+ 0x901C7004, 0x1E000004, 0x90077004, 0xB100F804,
+ 0x1964EA99, 0xD9400205, 0x900740C3, 0xB020C2C4,
+ 0x8E41B0A8, 0x0A778E20, 0x7A5B0064, 0x70402614,
+ 0x048C8000, 0x00412217, 0x09B66942, 0x702CF5EF,
+ 0x1600F02D, 0x80007082, 0x72540008, 0x901C43C3,
+ 0x42C30000, 0xF8009007, 0x1964F406, 0xB3000004,
+ 0xF006B200, 0x01051964, 0xB2A0B3A0, 0x8E008E21,
+ 0x0024092B, 0x71247902, 0x7040240A, 0x03C020A8,
+ 0x06812000, 0x70022614, 0x048C8000, 0x0081111C,
+ 0x21787104, 0xB9080001, 0xD8AAB220, 0x70041E00,
+ 0xC0B89007, 0xF64F0B0A, 0x0407202F, 0xC057D907,
+ 0x145CD841, 0xB8133005, 0x706C744C, 0x0C6E708C,
+ 0x70CCF6AF, 0xD907700C, 0x706CDA08, 0x70AC708C,
+ 0xF6AF0C5A, 0x145C70CC, 0xD8803005, 0xD907B893,
+ 0x706C744C, 0x0C46708C, 0x70CCF6AF, 0x0BEE700C,
+ 0x712CF6AF, 0x000040C3, 0x0CFA1388, 0x752CFBEF,
+ 0xD9FF710C, 0xFB6F0986, 0x216F704C, 0x40D32443,
+ 0x048C8000, 0x20801100, 0x01012078, 0x7424B902,
+ 0x180AB806, 0x20892042, 0x41C30E43, 0x000103E3,
+ 0x740C6846, 0xF86F089A, 0x20841808, 0x6872C808,
+ 0x901C40C3, 0x23050504, 0xB1A00001, 0x0F812305,
+ 0x04FC901C, 0x834418A4, 0x0F802305, 0x04DC901C,
+ 0x11009000, 0x0A1B2082, 0xB8C500B1, 0x02C2204F,
+ 0x8F20B140, 0x00FE0925, 0x0301204F, 0x204FF009,
+ 0xB1400302, 0x09158F20, 0x204F00FE, 0x23050341,
+ 0x901C0F80, 0xB02004F4, 0x0F802305, 0xC3EC9007,
+ 0x71051E00, 0xC12C903B, 0x088EB0A0, 0x710CFB2F,
+ 0xB802C808, 0x0F812005, 0x00949004, 0x1C909120,
+ 0x8F203040, 0x00DE091B, 0x0F812005, 0xC0949007,
+ 0x30001490, 0x0080206C, 0x00C02045, 0x1600B100,
+ 0x80007080, 0x22440126, 0xB8E22051, 0xF9A20C48,
+ 0x21004063, 0x42D32491, 0x0FB08000, 0x3A402455,
+ 0x28012240, 0x0FD2DA72, 0x2344F5AF, 0x40C32054,
+ 0xF0A70000, 0x30041C66, 0x000140C3, 0xC058FF74,
+ 0x0004208A, 0x30041C6A, 0x100AD972, 0x1C682080,
+ 0xB8063344, 0x30041C64, 0xFFEF0822, 0x3A402455,
+ 0x204B8F00, 0xF4068E00, 0x0812C098, 0xD90CFFEF,
+ 0xD90FD80F, 0x24CD2400, 0xF76F0C2A, 0x27912140,
+ 0x204B8F00, 0xF4088E00, 0xF84F0D46, 0x0E924063,
+ 0x712CFF6F, 0x78AFC217, 0x0447212F, 0xFB2F0BDA,
+ 0x8F404118, 0x8E00224B, 0x0A67F20B, 0x700C00FF,
+ 0x041441C3, 0x0C420001, 0x026FF5CF, 0x41C30000,
+ 0x0000040F, 0xF82F0F2A, 0xD861740C, 0x900745CB,
+ 0xB808C29C, 0xB500712C, 0xF6AF0A22, 0xD941D808,
+ 0x0004208A, 0xB500B914, 0xF82F0F06, 0x1600740C,
+ 0x80007080, 0xB8E20001, 0x002201FA, 0x1008DD0A,
+ 0x09FA2100, 0x712CF6AF, 0x1EFF258C, 0x41C3F0F8,
+ 0x00000411, 0xF82F0EDA, 0x710C740C, 0xF6AF09DE,
+ 0x2455712C, 0x41423A40, 0xF5AF0ECE, 0x2455DA10,
+ 0x22403940, 0x0EC22401, 0xDA10F5AF, 0x8E20700C,
+ 0xC05EC05F, 0xC05CC05D, 0x082F8E01, 0x78220064,
+ 0xC8086841, 0x7080240A, 0x20A86872, 0x294003C0,
+ 0xC2980380, 0x7A357865, 0x0F802005, 0x00A89004,
+ 0x71249000, 0x700CA200, 0xF6AF0982, 0x8E01712C,
+ 0x2001258A, 0x082F8E20, 0x78220064, 0xC8086861,
+ 0x70C0240A, 0x20A86852, 0x294003C0, 0x78450380,
+ 0x0F832005, 0x00A89004, 0x3A402455, 0x71244820,
+ 0x0FE2B300, 0x700CFD4F, 0xF6AF0942, 0x8EA0712C,
+ 0x08D98E01, 0x2D400364, 0xD8891391, 0x2F922105,
+ 0x01C89004, 0x20041A00, 0xFBEF09AE, 0x20F4D808,
+ 0x24552340, 0x23153A53, 0x24552353, 0x26153956,
+ 0x41C32356, 0x00050412, 0xB80242A1, 0x04402005,
+ 0x3E112454, 0x0F802005, 0x01CC9004, 0x21159000,
+ 0x1A002351, 0x20442005, 0x43660058, 0x1600740C,
+ 0x260A2017, 0x11000600, 0x240A2012, 0x250A05C0,
+ 0x0DBE0480, 0x4470F82F, 0x3011081B, 0x20330A17,
+ 0x20402740, 0x00F5080B, 0x71EE714E, 0x2F84F003,
+ 0x081D2FBF, 0x0A193010, 0x27402072, 0x080D2040,
+ 0x774E00F5, 0xF00477EE, 0x2FBF2F84, 0x20310A19,
+ 0x30002078, 0x00002079, 0xB805791B, 0x00522142,
+ 0x04172042, 0x25D42400, 0x25C01E00, 0x24801900,
+ 0x1B0071A5, 0xF1962500, 0x2DBD258C, 0x096A4063,
+ 0x702CF7AF, 0x00100883, 0x8E408E21, 0x00A40941,
+ 0x0A832040, 0x7942C808, 0x240A7124, 0x20A87040,
+ 0x2A400600, 0x7C05030C, 0x10C12405, 0x2105B902,
+ 0x90040F8D, 0x6C320000, 0x0F8C2105, 0x00A89004,
+ 0xB5209420, 0x4941C198, 0xB4207144, 0xFD0F0A46,
+ 0x1008F01B, 0x08062100, 0x712CF6AF, 0x0C224063,
+ 0x702CFF6F, 0x702C40C2, 0xFD2F0DD6, 0x2540724C,
+ 0xC8082A95, 0x05402005, 0x704C41C2, 0x708C706C,
+ 0xFFAF0E5E, 0x0E6E71AC, 0x70CDFD4F, 0x900745CB,
+ 0x4063C29C, 0xFAAF0F2E, 0x41C3B5C0, 0x00000415,
+ 0xF82F0CAE, 0x700C740C, 0x0D62702C, 0x704CFB2F,
+ 0xB5D4B5D2, 0x08218F00, 0xC80800DE, 0x2005B802,
+ 0x90070F81, 0x1490C094, 0xB1003000, 0x73841E00,
+ 0xC3789007, 0xF60F0E5A, 0x752C700C, 0xF6AF0AC2,
+ 0x700C714C, 0xF66F0F76, 0x0CCE712C, 0x700CFAEF,
+ 0xF60F0E3E, 0xD907700C, 0x706C744C, 0x70AC708C,
+ 0xF66F0FAA, 0x708C70CC, 0x3005145C, 0x732C4080,
+ 0x4223B890, 0x01032841, 0xF66F0F92, 0xD88070CC,
+ 0x744CD907, 0x708C706C, 0x0F8270AC, 0x70CCF66F,
+ 0x0F2A700C, 0x712CF66F, 0xFD0F095A, 0xFD4F0DB6,
+ 0xD90FC080, 0xFDAF0D02, 0x1600704C, 0x8000708C,
+ 0x245512D9, 0x244A3801, 0x700C7200, 0x040020A8,
+ 0x0C137A1D, 0x9140108E, 0x1F832605, 0x012C9038,
+ 0x7224B340, 0x000076C3, 0x71044000, 0x36042480,
+ 0x341B1404, 0x78E0C6DA, 0x2482C3F4, 0x228A3102,
+ 0x10822084, 0x2033070F, 0x250A048E, 0x46702100,
+ 0x43304450, 0xFF6F08D6, 0xE8084110, 0x710478CF,
+ 0x2049B822, 0xF0050FCE, 0x10320E45, 0x2648700E,
+ 0x40D11000, 0x780F7104, 0x7000240A, 0x034020A8,
+ 0x0407202F, 0x20002115, 0x09139020, 0x900103C5,
+ 0x10050F0B, 0x700E7706, 0x0892F006, 0x7014FF4F,
+ 0x206220C0, 0xDD3FE6BF, 0xF01DF6C2, 0xD940E6C0,
+ 0x45C96E01, 0x004B20CA, 0x240A78C2, 0x20A87000,
+ 0x21150300, 0x90202340, 0x03C50911, 0x0F0D9001,
+ 0x71A51005, 0xF007DD3F, 0xFF4F0852, 0x25C27014,
+ 0x084A1062, 0xE809FF4F, 0x24802132, 0x79026D32,
+ 0x04022018, 0x4DD1F004, 0x14022602, 0x7E2F78CF,
+ 0x200C2115, 0x4F109400, 0x94017B10, 0x7F4F78E2,
+ 0x081A7810, 0x2009FF6F, 0x701400CD, 0x138E2709,
+ 0xFF6F080A, 0x106225C0, 0x40A17014, 0x138125CA,
+ 0x710CF213, 0x20300B0F, 0x30431C05, 0x704C712C,
+ 0x702CF003, 0x0E2A42A2, 0xC380F9AF, 0x3100140C,
+ 0x710478CA, 0x7CB0B822, 0x0C177B10, 0x24892030,
+ 0x0E1B1FC3, 0x0B272051, 0xD9592071, 0x0E17F016,
+ 0x0B232051, 0xD93E2071, 0x0B17F010, 0xD9552071,
+ 0x0B17F00C, 0xD93A2071, 0xD957F008, 0xD953F006,
+ 0xD93CF004, 0xD938F002, 0x6909B99F, 0xC2608840,
+ 0x0A0DC220, 0x23890325, 0xC4200FC3, 0x8900A880,
+ 0xC020C060, 0x00C50807, 0xA960C320, 0x78E0C7D4,
+ 0x1600C2EA, 0x8000708E, 0x71141222, 0xDD75D870,
+ 0x25CA4130, 0x16001001, 0x80007080, 0x08771223,
+ 0x16000384, 0x80007080, 0x086712D9, 0x79CF03AE,
+ 0xFDEF0BA2, 0x46004022, 0x742D70EC, 0x702C720D,
+ 0x03822114, 0xBA0CC808, 0x27157845, 0x702C0042,
+ 0x02450937, 0x00AE0E2D, 0x7B0561BB, 0x2305BB02,
+ 0x90380F8C, 0x265A0000, 0x7B541503, 0x0F8B2334,
+ 0x4DAC8001, 0x800043C3, 0x23F40F60, 0xB46002C3,
+ 0x71447124, 0x712CF1E6, 0x173F208D, 0x71C5752D,
+ 0xC6CAF1C3, 0x1CFCC2FA, 0x44D3B6C8, 0x12228000,
+ 0x14014018, 0x14002080, 0x200C2090, 0x011AA000,
+ 0x4748002D, 0x0C172140, 0x000E45D3, 0x21400000,
+ 0x21400816, 0x21540402, 0x21050819, 0x2705055B,
+ 0x26052557, 0x25052556, 0x46CB2095, 0x00009000,
+ 0x800041C3, 0x892012D9, 0x040E09D5, 0x2513205A,
+ 0x800145CB, 0x7F604DAC, 0x23402334, 0x23512840,
+ 0x21055020, 0x75622612, 0x26C22205, 0xB9027945,
+ 0xB10079C5, 0x95017F60, 0x25422205, 0x79455020,
+ 0x79C5B902, 0x7F60B100, 0x22059502, 0x50202582,
+ 0xB9027945, 0xB10079C5, 0x95037F60, 0x25D22205,
+ 0x21055020, 0xB9020481, 0xB10079C5, 0x95047F60,
+ 0x26112100, 0x21964100, 0xC8082008, 0x26C22105,
+ 0xB8027845, 0xB02078C5, 0x95057F60, 0x25422105,
+ 0x79455020, 0x79C5B902, 0x7F60B100, 0x21059506,
+ 0x50202582, 0xB9027945, 0xB10079C5, 0x95077F60,
+ 0x25C22105, 0x79455020, 0x79C5B902, 0x7F60B100,
+ 0x21059508, 0x50202651, 0x04412105, 0x2105B902,
+ 0x90380F81, 0xB1000000, 0x20801401, 0xA000200C,
+ 0xFFE50720, 0x14047106, 0xC6DA341B, 0x1CFCC2FA,
+ 0x2482B6C8, 0x45683902, 0xC0414730, 0x700C700E,
+ 0x31001C90, 0x30801C8C, 0xEB05C040, 0xF80F0EF2,
+ 0x41DBC040, 0xC0C49007, 0xFF2F0D72, 0x30451900,
+ 0x30021C0D, 0x702C710C, 0x0BA642A1, 0xC382F9AF,
+ 0xD825726F, 0x8820B89F, 0x7905881B, 0x2800710C,
+ 0xB8020400, 0x0400200F, 0x0252782B, 0x16000001,
+ 0x8000708D, 0x16001222, 0x80007080, 0x75101223,
+ 0x000D023A, 0x800040C3, 0x880012D9, 0x83402011,
+ 0x00210224, 0x097E79AF, 0x148CFDEF, 0x1C983000,
+ 0x20143000, 0x70CD2340, 0x0F962000, 0x04708000,
+ 0x13002D40, 0x30001C94, 0x30001498, 0x83802011,
+ 0x40C3F2EF, 0x28F00000, 0xC1017A1B, 0x200B201F,
+ 0x794AB822, 0x251A40C9, 0x44CB1003, 0x1B3C8000,
+ 0x1184209A, 0x3089140D, 0x61787161, 0x64197001,
+ 0x89026097, 0x10300919, 0x14149142, 0x782A3101,
+ 0xB8227104, 0x10112700, 0xF0044748, 0x4150671F,
+ 0x12012E40, 0x30001494, 0xC8087905, 0xC0017905,
+ 0x0412214F, 0xE80A4330, 0x09717361, 0x23001030,
+ 0x60980200, 0xF0379002, 0x20110F23, 0x1A00255A,
+ 0x201478D5, 0x20000400, 0x80000F81, 0x70C3BEC4,
+ 0xC0048000, 0x04441900, 0x2455B0E0, 0x09463A01,
+ 0x78F0F96F, 0xE807CA05, 0x3A002455, 0xFB2F0A6A,
+ 0x09AE41E2, 0xE808FC8F, 0x20811600, 0xFB2F0A5A,
+ 0x3A002455, 0x24002205, 0x2005B802, 0x90000F8F,
+ 0x24550048, 0xF0773A00, 0x60906419, 0x60388922,
+ 0x09027810, 0x2455F96F, 0x24003A01, 0x00003F81,
+ 0x08F2009E, 0x78F0F96F, 0xE806C000, 0x3100149E,
+ 0x30041CA0, 0xE80ECA05, 0x3A002455, 0xFB2F0A0A,
+ 0x240041E2, 0x00003F80, 0x09FE009E, 0x41E2FB2F,
+ 0xFC8F093E, 0x1600E80F, 0x09EE2081, 0x2455FB2F,
+ 0x24003A00, 0x00003F80, 0x09DE009E, 0x1600FB2F,
+ 0xCA052081, 0x091AE887, 0x08A1FC8F, 0x24550030,
+ 0x24553A00, 0x24003A00, 0x00003F81, 0x724C009E,
+ 0xFD0F08DA, 0x20310F37, 0x3A002455, 0x1A15255A,
+ 0x800044D3, 0x2515C004, 0x25142395, 0x0F022415,
+ 0x2400F7EF, 0x1C002554, 0x25002004, 0x80002F80,
+ 0x1CA0BEC4, 0x180023C4, 0x22050444, 0xBF02240F,
+ 0x1F922705, 0x00489000, 0xF7EF0ECA, 0x3A002455,
+ 0x1A00BF86, 0xBF9C2004, 0x3F802400, 0x009E0000,
+ 0x0EB2BF9F, 0xB700F7CF, 0x30001490, 0x2B40E809,
+ 0x20052080, 0x90040F80, 0x18000320, 0x71C50444,
+ 0x0618E689, 0xF008FFC5, 0x3F812400, 0x009E0000,
+ 0xF1B8714C, 0xFFEF05C3, 0x238D71A5, 0x710E337B,
+ 0x30051900, 0x39022480, 0x341B1404, 0x78E0C6DA,
+ 0x1600C3F2, 0x80007091, 0x0AD20004, 0x2482FF2F,
+ 0x1C053102, 0x710C3002, 0x704C712C, 0xF9AF0902,
+ 0x2153C380, 0x718E20D1, 0x726E700E, 0x47CB714E,
+ 0x12208000, 0xB89FD825, 0x881B8820, 0x2C007905,
+ 0xB8022400, 0x0400200F, 0xF2C1782B, 0x8F038FC2,
+ 0x017A7610, 0x40C3000D, 0x12D98000, 0x20118800,
+ 0xF2B38380, 0x13002E40, 0x30881405, 0x04012005,
+ 0x7825C808, 0x7280244A, 0x706D6892, 0x1F892405,
+ 0x00A09004, 0x0A0020A8, 0x000040C3, 0x68320A3C,
+ 0x201F78CC, 0x41C32042, 0x1B3C8000, 0x4061621A,
+ 0x0184209A, 0x1030080D, 0x60386058, 0xF0069002,
+ 0x6030611B, 0x60788B62, 0x12710B0F, 0x12832B40,
+ 0x10041900, 0x7B85F007, 0x0F832305, 0x01E89004,
+ 0x7165B300, 0x70801600, 0x00EE8000, 0xF4757014,
+ 0x10100821, 0x6159622D, 0x140C8922, 0x782A3100,
+ 0x20047104, 0x00000F80, 0xB822FFFC, 0xF004651D,
+ 0x89A46159, 0x08118F05, 0x720C03A5, 0xF88F080E,
+ 0xF006710C, 0xF8AF0806, 0x700C710C, 0x4002AF00,
+ 0xFA2F08B2, 0x451041C1, 0x08AA4002, 0x41C1FA2F,
+ 0x2B01215F, 0x00002078, 0x7404B802, 0x8F006119,
+ 0x00002114, 0x700279AF, 0xA8A860F8, 0x20002578,
+ 0x0CC26841, 0x4002F5EF, 0x20300D17, 0xE8118F00,
+ 0x20100A3B, 0x73421E00, 0x00508000, 0xE810F02A,
+ 0x20100A35, 0x73421E00, 0x00FA8000, 0x0A33F022,
+ 0x1E002010, 0x80007342, 0xF01C0035, 0x20100A2D,
+ 0x73421E00, 0x00F08000, 0x1E00F014, 0x80007342,
+ 0xF0100051, 0x73421E00, 0x00FF8000, 0x1E00F00A,
+ 0x80007342, 0xF0060036, 0x73421E00, 0x00F58000,
+ 0xF86F0F5A, 0x71C5730C, 0x704EF143, 0x2D3C238D,
+ 0xC7D2710E, 0x7A00244A, 0x800040C3, 0x20A8C444,
+ 0x180001C0, 0x20800003, 0x7EE0000E, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 DMAC_TRANS_DCCM[] = {
+ 0x00000000, 0x21500030, 0x00044004, 0x00006000,
+ 0x00FF56DF, 0x00020000, 0x07000000, 0x08010000,
+ 0x00000000, 0x00000110, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x10000000,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xD0D00000, 0xDDDDD0D0,
+ 0x8686DDDD, 0x54548686, 0xB4B45454, 0x2E2EB4B4,
+ 0x00002E2E, 0x28280000, 0x28282828, 0x00002828,
+ 0x2E060000, 0x0C0C2E06, 0x10100C0C, 0x02021010,
+ 0x00000202, 0x00000000, 0x77770000, 0x00007777,
+ 0x00000000, 0x00000000, 0x24240000, 0x00002424,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x60600000, 0x00006060,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x0000001F, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x57000001, 0x0000004F, 0x00000000, 0x00000000,
+ 0x00000100, 0x00000000, 0x001E001E, 0x00FF00FF,
+ 0x000F6E0A, 0x0005000F, 0x00000000, 0x00000000,
+ 0x005C0032, 0x00E000B6, 0x0164013A, 0x01E801BE,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x01000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x06400C80, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x050B0000,
+ 0x00000006, 0x00000000, 0x00000000, 0x08080808,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x010CA635,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000000, 0x00040000,
+ 0x00000000, 0x00000000, 0x180F0E0C, 0x4746451E,
+ 0x004A4948, 0x01000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00040000, 0x00000001, 0x00000000,
+ 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0002F059, 0xFFB50003,
+ 0x00000001, 0x0001F0B5, 0xF0B30001, 0x00000001,
+ 0x0001F0B4, 0xF0B00000, 0x00300001, 0x0007F003,
+ 0xF0040000, 0x00000007, 0x0001FE03, 0xFE040000,
+ 0x00000001, 0x0007F011, 0xFE210000, 0x00000001,
+ 0x0001F0B1, 0xFFBE0182, 0x00000001, 0x0001F0BE,
+ 0xF0A70001, 0x00000001, 0x0001F0A2, 0x00790002,
+ 0x00400002, 0x00000308, 0x00000560, 0x00000000,
+ 0x80000DB4, 0x00000309, 0x00000561, 0x00000001,
+ 0x80000DC5, 0x000E0305, 0x000E0205, 0x00000003,
+ 0x80000DD6, 0x000E0300, 0x000E0200, 0x00000003,
+ 0x80000E3C, 0x000E0301, 0x000E0201, 0x00000003,
+ 0x80000E4F, 0x000E0302, 0x000E0202, 0x00000003,
+ 0x80000E62, 0x000E0303, 0x000E0203, 0x00000003,
+ 0x80000E75, 0x000E0304, 0x000E0204, 0x00000002,
+ 0x80000E88, 0x01FF01FF, 0x000E0000, 0x00000000,
+ 0x00000063, 0x00000064, 0x00000660, 0x00000000,
+ 0x80000D87, 0x00000661, 0x00000001, 0x80000DA5,
+ 0x000E00F0, 0x00000003, 0x80000DE7, 0x000E00F1,
+ 0x00000003, 0x80000DF8, 0x000E00F2, 0x00000003,
+ 0x80000E09, 0x000E00F3, 0x00000003, 0x80000E1A,
+ 0x000E00F4, 0x00000002, 0x80000E2B, 0x000E00F5,
+ 0x00000003, 0x80000D96, 0x02011210, 0x1C0A1403,
+ 0x0B112E29, 0x1916150D, 0x180F0E0C, 0x453A131E,
+ 0x49484746, 0x02006E4A, 0x00000100, 0x02150028,
+ 0x0085000A, 0x00000000, 0x02150001, 0x0085042B,
+ 0x0001010B, 0x00020000, 0x0640042B, 0x0190010B,
+ 0x00010002, 0x06400002, 0x01900855, 0x00030215,
+ 0x00030001, 0x0ABE0855, 0x02B00215, 0x00010004,
+ 0x0ABE0004, 0x02B00C80, 0x00050320, 0x00040002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00280000,
+ 0x00050215, 0x00000043, 0x00010000, 0x042B0215,
+ 0x00850043, 0x00000001, 0x042B0001, 0x00850640,
+ 0x000200C8, 0x00010001, 0x08550640, 0x010B00C8,
+ 0x00010003, 0x08550002, 0x010B0ABE, 0x00040158,
+ 0x00020001, 0x0C800ABE, 0x01900158, 0x00010005,
+ 0x0C800002, 0x01900E95, 0x000601D3, 0x00030001,
+ 0x10AB0E95, 0x021501D3, 0x00010007, 0x10AB0003,
+ 0x021512C0, 0x00080258, 0x00030002, 0x157C12C0,
+ 0x02B00258, 0x00020009, 0x157C0004, 0x02B01770,
+ 0x000A02EE, 0x00040002, 0x19001770, 0x032002EE,
+ 0x0002000B, 0x19000004, 0x03201D4C, 0x000C03AA,
+ 0x00050003, 0x21551D4C, 0x042B03AA, 0x0003000D,
+ 0x21550006, 0x042B2580, 0x000E04B0, 0x00070003,
+ 0x02150028, 0x0085000A, 0x00040004, 0x00010001,
+ 0x00030001, 0x02150004, 0x0085042B, 0x0004010B,
+ 0x00000006, 0x00020002, 0x00050003, 0x0640042B,
+ 0x0190010B, 0x00080006, 0x00030001, 0x00040002,
+ 0x06400006, 0x01900855, 0x00080215, 0x0002000A,
+ 0x00030004, 0x00070004, 0x0ABE0855, 0x02B00215,
+ 0x000E0008, 0x00070001, 0x00040004, 0x0ABE0008,
+ 0x02B00C80, 0x000A0320, 0x00030010, 0x00040009,
+ 0x00080004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00280000, 0x00050215,
+ 0x00020043, 0x00000002, 0x00010000, 0x00030002,
+ 0x042B0215, 0x00850043, 0x00030002, 0x00010000,
+ 0x00020001, 0x042B0003, 0x00850640, 0x000300C8,
+ 0x00010004, 0x00010002, 0x00030002, 0x08550640,
+ 0x010B00C8, 0x00050004, 0x00020001, 0x00020002,
+ 0x08550004, 0x010B0ABE, 0x00040158, 0x00010007,
+ 0x00020004, 0x00040002, 0x0C800ABE, 0x01900158,
+ 0x00080005, 0x00050002, 0x00020002, 0x0C800004,
+ 0x01900E95, 0x000601D3, 0x00020009, 0x00030005,
+ 0x00050002, 0x10AB0E95, 0x021501D3, 0x000B0006,
+ 0x00070002, 0x00020003, 0x10AB0005, 0x021512C0,
+ 0x00070258, 0x0003000C, 0x00030008, 0x00050002,
+ 0x157C12C0, 0x02B00258, 0x000E0008, 0x00090003,
+ 0x00020004, 0x157C0006, 0x02B01770, 0x000902EE,
+ 0x0004000F, 0x0004000A, 0x00060002, 0x19001770,
+ 0x032002EE, 0x00100009, 0x000B0004, 0x00020004,
+ 0x19000006, 0x03201D4C, 0x000B03AA, 0x00050013,
+ 0x0005000D, 0x00070002, 0x21551D4C, 0x042B03AA,
+ 0x0016000C, 0x000F0005, 0x00020006, 0x21550008,
+ 0x042B2580, 0x000E04B0, 0x00060018, 0x00070010,
+ 0x00090002, 0x02150028, 0x0085000A, 0x00060006,
+ 0x00000006, 0x00000000, 0x00060001, 0x02150007,
+ 0x0085042B, 0x0008010B, 0x00080008, 0x00000000,
+ 0x00020000, 0x00090007, 0x0640042B, 0x0190010B,
+ 0x000A000A, 0x0001000C, 0x00030001, 0x00080002,
+ 0x0640000A, 0x01900855, 0x000C0215, 0x000E000E,
+ 0x00040002, 0x00030004, 0x000B0008, 0x0ABE0855,
+ 0x02B00215, 0x00100010, 0x00030012, 0x00050003,
+ 0x000A0004, 0x0ABE000E, 0x02B00C80, 0x00120320,
+ 0x00140014, 0x00070005, 0x00040007, 0x000E000A,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00280000, 0x00050215,
+ 0x00030043, 0x00030003, 0x00000000, 0x00010000,
+ 0x00040003, 0x042B0215, 0x00850043, 0x00040004,
+ 0x00000004, 0x00000000, 0x00040001, 0x042B0005,
+ 0x00850640, 0x000500C8, 0x00050005, 0x00010001,
+ 0x00010002, 0x00050004, 0x08550640, 0x010B00C8,
+ 0x00070006, 0x00010007, 0x00020002, 0x00040002,
+ 0x08550006, 0x010B0ABE, 0x00080158, 0x00090008,
+ 0x00020002, 0x00020003, 0x00070005, 0x0C800ABE,
+ 0x01900158, 0x000A0009, 0x0003000A, 0x00040004,
+ 0x00050002, 0x0C800007, 0x01900E95, 0x000A01D3,
+ 0x000C000B, 0x00040003, 0x00030005, 0x00080005,
+ 0x10AB0E95, 0x021501D3, 0x000D000C, 0x0004000E,
+ 0x00060005, 0x00060003, 0x10AB0009, 0x021512C0,
+ 0x000D0258, 0x000F000E, 0x00060005, 0x00030007,
+ 0x00090006, 0x157C12C0, 0x02B00258, 0x0010000F,
+ 0x00060011, 0x00080007, 0x00060004, 0x157C000A,
+ 0x02B01770, 0x001002EE, 0x00130011, 0x00070006,
+ 0x00040009, 0x000B0007, 0x19001770, 0x032002EE,
+ 0x00120011, 0x00070014, 0x000A0008, 0x00070004,
+ 0x1900000B, 0x03201D4C, 0x001403AA, 0x00180016,
+ 0x00090007, 0x0005000B, 0x000E0009, 0x21551D4C,
+ 0x042B03AA, 0x00190017, 0x0008001A, 0x000B000A,
+ 0x000A0006, 0x21550010, 0x042B2580, 0x001904B0,
+ 0x001D001C, 0x000B0008, 0x0007000C, 0x0012000B,
+ 0x00000A05, 0x50000000, 0x446B6C63, 0x6F434143,
+ 0x43416564, 0x63500030, 0x43446B6C, 0x646F4341,
+ 0x53514465, 0x6C635000, 0x4143446B, 0x65646F43,
+ 0x00314341, 0x6B6C6350, 0x4F444344, 0x65736666,
+ 0x30434174, 0x6C635000, 0x4443446B, 0x7366664F,
+ 0x43417465, 0x63500031, 0x43446B6C, 0x66664F44,
+ 0x44746573, 0x50005351, 0x446B6C63, 0x6F434143,
+ 0x71446564, 0x00306E4C, 0x6B6C6350, 0x43414344,
+ 0x4465646F, 0x316E4C71, 0x6C635000, 0x4143446B,
+ 0x65646F43, 0x6E4C7144, 0x63500032, 0x43446B6C,
+ 0x646F4341, 0x4C714465, 0x5000336E, 0x446B6C63,
+ 0x6F434143, 0x71446564, 0x00346E4C, 0x6B6C6350,
+ 0x4F444344, 0x65736666, 0x4C714474, 0x5000306E,
+ 0x446B6C63, 0x664F4443, 0x74657366, 0x6E4C7144,
+ 0x63500031, 0x43446B6C, 0x66664F44, 0x44746573,
+ 0x326E4C71, 0x6C635000, 0x4443446B, 0x7366664F,
+ 0x71447465, 0x00336E4C, 0x6B6C6350, 0x4F444344,
+ 0x65736666, 0x4C714474, 0x0000346E, 0x04050607,
+ 0x00010203, 0x0C0B0A09, 0xB50F0E0D, 0x000001FF,
+ 0x01F0B500, 0xB3000100, 0x000001F0, 0x01F0B400,
+ 0xB0000100, 0x300001F0, 0x07F00300, 0x04000000,
+ 0x000007F0, 0x01FE0300, 0x04000000, 0x000001FE,
+ 0x07F01100, 0x21000000, 0x000001FE, 0x01FFBE00,
+ 0xBE000000, 0x010001F0, 0x01F0A700, 0xA2000000,
+ 0x020001F0, 0x02007900, 0x00004000, 0x0001008B,
+ 0xF05F0000, 0x00000001, 0x0001FFB5, 0xF0B30001,
+ 0x01FF0001, 0x0001F0B4, 0xF0B001FF, 0x00300001,
+ 0x0007F003, 0xF0040000, 0x00000007, 0x0001FE03,
+ 0xFE040000, 0x00000001, 0x0007F011, 0xFE210000,
+ 0x00000001, 0x0001F0B1, 0xF0A70002, 0x00000001,
+ 0x000E000F, 0x000C000D, 0x000A000B, 0x00080009,
+ 0x00060007, 0x00040005, 0x00020003, 0x00000001,
+ 0x00110010, 0x00130012, 0x00150014, 0x00170016,
+ 0x00190018, 0x001B001A, 0x001D001C, 0x001F001E,
+ 0xEF77DBB7, 0xFBDFF7BD, 0xBDDFB76F, 0xBDFFBDEF,
+ 0x00000200, 0x00000200, 0x00000200, 0x00000200,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x0001FFB5, 0xF0B30001, 0x00000001, 0x0001F0B4,
+ 0xF0B90000, 0x00010001, 0x0001F0BA, 0xF0B10001,
+ 0x00020001, 0x0007F003, 0xF0040000, 0x00000007,
+ 0x0001FE03, 0xFE040000, 0x00000001, 0x0007F011,
+ 0xFE210000, 0x00000001, 0x0007F010, 0xFE200002,
+ 0x00020001, 0x0007F01B, 0xF01CFFFF, 0xFFFF0007,
+ 0x0001FE2A, 0xFE2BFFFF, 0xFFFF0001, 0x00020079,
+ 0xFFB50040, 0x00010001, 0x0001F0B3, 0xF0B40000,
+ 0x00000001, 0x0001F0B9, 0xF0BA0001, 0x00010001,
+ 0x0001F0B1, 0xF0B00002, 0x00300001, 0x0007F003,
+ 0xF0040000, 0x00000007, 0x0001FE03, 0xFE040000,
+ 0x00000001, 0x0007F011, 0xFE210000, 0x00000001,
+ 0x0007F010, 0xFE200002, 0x00020001, 0x0007F01B,
+ 0xF01CFFFF, 0xFFFF0007, 0x0001FE2A, 0xFE2BFFFF,
+ 0xFFFF0001, 0x00020079, 0x00000040, 0x08840884,
+ 0x00000020, 0x00010010, 0x00010012, 0x0001007A,
+ 0x00010028, 0x00060000, 0x50005000, 0x02008050,
+ 0x00000000, 0x00060080, 0x3C5A5555, 0x00600000,
+ 0x00000000, 0x00000000, 0x00000070, 0x00000075,
+ 0x00000026, 0x000000A0, 0x000000A1, 0x000000A4,
+ 0x000000A5, 0x0A030201, 0x0E0D0C0B, 0x1413120F,
+ 0x18171615, 0x1E1C1A19, 0x2221201F, 0x2E292825,
+ 0x4746453A, 0x004A4948, 0x00000000, 0x00000000,
+};
+
+static const u32 DMAC_TRANS_ACSM[] = {
+ 0x0000C028, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0000C858, 0x00100000, 0x0000E088, 0x00100000,
+ 0x0000E038, 0x00100000, 0x0000C858, 0x00100000,
+ 0x0000C088, 0x00100000, 0x00000000, 0x00000000,
+ 0x0000C028, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0000C858, 0x00100000, 0x0000E208, 0x00100000,
+ 0x0000E038, 0x00100000, 0x0000C858, 0x00100000,
+ 0x0000C208, 0x00100000, 0x00000000, 0x00000000,
+ 0x0000C040, 0x00100000, 0x00000000, 0x00100000,
+ 0x0000C068, 0x00100000, 0x00000000, 0x00000000,
+ 0x0000C2F0, 0x00100000, 0x00000000, 0x00000000,
+ 0x0000C370, 0x00100000, 0x00000000, 0x00000000,
+ 0x0000D2D8, 0x00100000, 0x0000E008, 0x00100000,
+ 0x00000000, 0x7B000000, 0x00000000, 0x00000000,
+ 0x0000C0F0, 0x00100000, 0x0000CFD8, 0x00100000,
+ 0x0000C008, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000D058, 0x00100000,
+ 0x0000C008, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000D0D8, 0x00100000,
+ 0x0000C088, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000D158, 0x00100000,
+ 0x0000C008, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x6B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0D00402C, 0x04000001, 0x08004050, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x08034050, 0x00000000,
+ 0x00000000, 0x1F000000, 0x00000000, 0x08000000,
+ 0x00000000, 0x04000000, 0x0000407C, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0D00802C, 0x04100001, 0x08008050, 0x00100000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x08038050, 0x00100000,
+ 0x00000000, 0x1F000000, 0x00000000, 0x08000000,
+ 0x00000000, 0x04000000, 0x0000807C, 0x00100000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0D00402C, 0x00000001, 0x08004050, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08034050, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08034050, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08004050, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x08000000,
+ 0x00000000, 0x00000000, 0x0000407C, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x1C000000,
+ 0x0D00802C, 0x00100001, 0x08008050, 0x00100000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08038050, 0x00100000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08038050, 0x00100000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08008050, 0x00100000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x08000000,
+ 0x00000000, 0x00000000, 0x0000807C, 0x00100000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x4B000000, 0x00000000, 0x28000000,
+ 0x0D00402C, 0x00000001, 0x08035198, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08035218, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x08000000,
+ 0x00000000, 0x00000000, 0x0000407C, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x0D00802C, 0x00100001, 0x08039198, 0x00100000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08039218, 0x00100000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x08000000,
+ 0x00000000, 0x00000000, 0x0000807C, 0x00100000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x3B000000, 0x00000000, 0x04000000,
+ 0x0000D2D8, 0x00100000, 0x0000E008, 0x00100000,
+ 0x00000000, 0x7B000000, 0x00000000, 0x00000000,
+ 0x0000C0F0, 0x00100000, 0x0000CFD8, 0x00100000,
+ 0x0000C008, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000D058, 0x00100000,
+ 0x0000C008, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000D0D8, 0x00100000,
+ 0x0000C088, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000D158, 0x00100000,
+ 0x0000C008, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x6B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0D00402C, 0x04000001, 0x08004050, 0x00000000,
+ 0x00000000, 0x04000000, 0x08034050, 0x00000000,
+ 0x00000000, 0x4F000000, 0x00000000, 0x08000000,
+ 0x0000407C, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1F000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0D00802C, 0x04100001, 0x08008050, 0x00100000,
+ 0x00000000, 0x04000000, 0x08038050, 0x00100000,
+ 0x00000000, 0x4F000000, 0x00000000, 0x08000000,
+ 0x0000807C, 0x04100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1F000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x04000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0D00402C, 0x00000001, 0x08004050, 0x00000000,
+ 0x00000000, 0x00000000, 0x08034050, 0x00000000,
+ 0x00000000, 0x00000000, 0x08034050, 0x00000000,
+ 0x00000000, 0x00000000, 0x08004050, 0x00000000,
+ 0x00000000, 0x4B000000, 0x00000000, 0x08000000,
+ 0x0000407C, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x1C000000,
+ 0x0D00802C, 0x00100001, 0x08008050, 0x00100000,
+ 0x00000000, 0x00000000, 0x08038050, 0x00100000,
+ 0x00000000, 0x00000000, 0x08038050, 0x00100000,
+ 0x00000000, 0x00000000, 0x08008050, 0x00100000,
+ 0x00000000, 0x4B000000, 0x00000000, 0x08000000,
+ 0x0000807C, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x28000000,
+ 0x0D00402C, 0x00000001, 0x08035198, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08035218, 0x00000000,
+ 0x00000000, 0x4B000000, 0x00000000, 0x08000000,
+ 0x0000407C, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0D00802C, 0x00100001, 0x08039198, 0x00100000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x08039218, 0x00100000,
+ 0x00000000, 0x4B000000, 0x00000000, 0x08000000,
+ 0x0000807C, 0x00100000, 0x00000000, 0x00000000,
+ 0x00000000, 0x1B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x6B000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 DATA_A[] = {
+ 0x00000001, 0x00000019, 0x0000002E, 0x00000043,
+ 0x0000005B, 0x00000070, 0x00000085, 0x0000009D,
+ 0x000000B2, 0x000000C7, 0x000000DF, 0x000000F4,
+ 0x00000109, 0x00000113, 0x00000115, 0x00000119,
+};
+
+static const u32 DATA_B[] = {
+ 0x00000018, 0x0000002D, 0x00000042, 0x0000005A,
+ 0x0000006F, 0x00000084, 0x0000009C, 0x000000B1,
+ 0x000000C6, 0x000000DE, 0x000000F3, 0x00000108,
+ 0x00000112, 0x00000114, 0x00000118, 0x0000011A,
+};
+
+static const u32 ACSM_0[] = {
+ 0x0000C9D8, 0x00000000, 0x0000C808, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000C958, 0x00000000, 0x0000C608, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000C0D8, 0x00000000, 0x0000E848, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000C158, 0x00000000, 0x0000EEC8, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000C1D8, 0x00000000, 0x0000C348, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000C558, 0x00000000, 0x0000EA08, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000C5D8, 0x00000000, 0x0000DA48, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x000048D8, 0x00000000, 0x00004308, 0x00000000,
+ 0x000088D8, 0x00000000, 0x00009708, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000CA58, 0x00000000, 0x0000C108, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000CB58, 0x00000000, 0x0000C008, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000D4D8, 0x00000000, 0x0000F008, 0x00000000,
+ 0x00000000, 0x5B000000, 0x00000000, 0x00000000,
+ 0x0000DD58, 0x00000000, 0x0000C008, 0x00000000,
+};
+
+static const u32 ACSM_123[] = {
+ 0x0000C9D8, 0x00000000, 0x0000C008, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000C958, 0x00000000, 0x0000C008, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000C0D8, 0x00000000, 0x0000E808, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000C158, 0x00000000, 0x0000EA88, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000C1D8, 0x00000000, 0x0000C308, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000C558, 0x00000000, 0x0000EA08, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000C5D8, 0x00000000, 0x0000C008, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x000048D8, 0x00000000, 0x00004008, 0x00000000,
+ 0x000088D8, 0x00000000, 0x00009408, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000CA58, 0x00000000, 0x0000C108, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000CB58, 0x00000000, 0x0000C008, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000D4D8, 0x00000000, 0x0000F008, 0x00000000,
+ 0x00000000, 0x2B000000, 0x00000000, 0x00000000,
+ 0x0000DD58, 0x00000000, 0x0000C008, 0x00000000,
+};
+
+static const u32 DATA_C[] = {
+ 0x00000000, 0x000000FE, 0x000000A8, 0x0000F040,
+ 0x0000F040, 0x00000000, 0x0000FFFF, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 DATA_3_1[] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x0000084F,
+ 0x0000084F, 0x0000082B, 0x0000082B, 0x0000084F,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00001810, 0x00001810, 0x00000428, 0x0000192C,
+ 0x0000181C, 0x0000181C, 0x00000434, 0x00003938,
+ 0x00001808, 0x00001808, 0x00000420, 0x00001124,
+};
+
+static const u32 DATA_3_2[] = {
+ 0x000040A0, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x0000024E, 0x0000004E, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x0000024E, 0x0000004E, 0x0000006F, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 DATA_3_3[] = {
+ 0x00000086, 0x00000190, 0x00000A69, 0x00000058,
+ 0x0000001B, 0x00000000, 0x00000043, 0x00000000,
+ 0x00000017, 0x0000004F, 0x00000006, 0x00000006,
+ 0x0000000E, 0x00000068, 0x00000000, 0x00000000,
+};
+
+static const u32 DATA_3_4[] = {
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000009, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x0000001C, 0x0000071C,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000077, 0x00000707, 0x00000030, 0x00003300,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000099, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 DATA_3_5[] = {
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000009, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x0000001C, 0x0000071C,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000077, 0x00007777, 0x00000030, 0x00003300,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000099, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 DMAC_TRANS_PIE[] = {
+ 0x3f7ab480, 0x00016420, 0x00000400, 0x00000000,
+ 0x80000480, 0x00000fc0, 0x04000c00, 0x00000000,
+ 0x84000480, 0x00000c00, 0x04000800, 0x00000000,
+ 0x84000080, 0x00000c00, 0x000001e0, 0x00000000,
+ 0x80068200, 0x0000400f, 0x00008d40, 0x00000000,
+ 0xa0000480, 0x00002420, 0x04000400, 0x00000000,
+ 0x9c001ca0, 0x00001c04, 0xa8000880, 0x00001c06,
+ 0x80010080, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80010480, 0x00001c04, 0x04000800, 0x00000000,
+ 0x00000040, 0x00006000, 0xa0000080, 0x00002420,
+ 0x00001020, 0x00000000, 0x00001020, 0x00000000,
+ 0x00001020, 0x00000000, 0x00003020, 0x00000000,
+ 0x80000080, 0x00001c04, 0xa8000880, 0x00001c06,
+ 0x80010880, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80010c80, 0x00001c04, 0x04000800, 0x00000000,
+ 0x00001020, 0x00000000, 0x00002c20, 0x00000000,
+ 0x00002c20, 0x00000000, 0x00002c20, 0x00000000,
+ 0x80000080, 0x00001c04, 0x000001e0, 0x00000000,
+ 0xa8000480, 0x00001c04, 0x04000400, 0x00000000,
+ 0x40004200, 0x00004000, 0x00011140, 0x00000000,
+ 0xc80038a0, 0x00001c01, 0xcc003ca0, 0x00001c01,
+ 0xa40000a0, 0x00001c06, 0xa8001c80, 0x00001c06,
+ 0x80051080, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80051480, 0x00001c04, 0x04000800, 0x00000000,
+ 0x00000840, 0x00006000, 0x80000080, 0x00001c04,
+ 0xcc000080, 0x00001c01, 0xa8001c80, 0x00001c06,
+ 0x80051880, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80051c80, 0x00001c04, 0x04000800, 0x00000000,
+ 0x00000840, 0x00006000, 0x80000080, 0x00001c04,
+ 0xc8000080, 0x00001c01, 0xcc003ca0, 0x00001c01,
+ 0xa8001c80, 0x00001c06, 0x80052080, 0x00001c04,
+ 0x04000400, 0x00000000, 0x80052480, 0x00001c04,
+ 0x04000800, 0x00000000, 0x00000840, 0x00006000,
+ 0x80000080, 0x00001c04, 0xc80038a0, 0x00001c01,
+ 0x54000091, 0x00018fc0, 0x54000091, 0x00014fc0,
+ 0xf0000091, 0x000187c1, 0xf0000091, 0x000147c1,
+ 0x08000611, 0x00001800, 0x00013d71, 0x00000000,
+ 0x04000911, 0x0001a420, 0x04001000, 0x00000000,
+ 0x00000a11, 0x00001800, 0x00017551, 0x00000000,
+ 0x00014571, 0x00000000, 0x00000611, 0x00001800,
+ 0x00017571, 0x00000000, 0x24000491, 0x0001e420,
+ 0x000021d1, 0x00000000, 0x00001031, 0x00000000,
+ 0x00001031, 0x00000000, 0x00002c31, 0x00000000,
+ 0xa8000091, 0x00001c06, 0x80016891, 0x00001c04,
+ 0x04000400, 0x00000000, 0x80016c91, 0x00001c04,
+ 0x04000800, 0x00000000, 0x00000851, 0x00006000,
+ 0x80000091, 0x00001c04, 0xa8000080, 0x00001c04,
+ 0x04000800, 0x00000000, 0x000001e0, 0x00000000,
+ 0xa8000080, 0x00001c06, 0x80012880, 0x00001c04,
+ 0x04000400, 0x00000000, 0x80012c80, 0x00001c04,
+ 0x04000800, 0x00000000, 0x00000840, 0x00006000,
+ 0x80000080, 0x00001c04, 0x000001e0, 0x00000000,
+ 0x00080200, 0x0000400e, 0x0001b540, 0x00000000,
+ 0x00020200, 0x0000400e, 0x0001b540, 0x00000000,
+ 0x80068200, 0x0000400f, 0x30000cc0, 0x000007c4,
+ 0x000001e0, 0x00000000, 0x00100600, 0x00000010,
+ 0x2c0004c0, 0x000003c0, 0x8c0028a0, 0x00017bc1,
+ 0xa0000480, 0x00002420, 0x04000400, 0x00000000,
+ 0x8c0014a0, 0x000143c1, 0xa0000080, 0x00002420,
+ 0x78000480, 0x000003d8, 0x7c000480, 0x000007f8,
+ 0x08000080, 0x00000fe0, 0x08000080, 0x000007e0,
+ 0x00080600, 0x00000008, 0x000004c0, 0x00014fc4,
+ 0x000004c0, 0x000147c4, 0x00002420, 0x00000000,
+ 0x08000480, 0x00000fe0, 0x08000480, 0x000007e0,
+ 0x00000080, 0x00014fc4, 0x00000080, 0x000147c4,
+ 0x78000080, 0x000003d8, 0x7c000080, 0x000007f8,
+ 0x8c002ca0, 0x00017bc1, 0xa0000480, 0x00002420,
+ 0x04000400, 0x00000000, 0x8c0018a0, 0x000143c1,
+ 0xa0000080, 0x00002420, 0x2c000080, 0x00000000,
+ 0x2c000080, 0x00000040, 0x2c000080, 0x00000080,
+ 0x2c000080, 0x000000c0, 0x2c000080, 0x00000100,
+ 0x2c000080, 0x00000140, 0x00200600, 0x00000020,
+ 0x2c0000c0, 0x000001c0, 0x2c0000c0, 0x00000200,
+ 0x2c0000c0, 0x00000240, 0x2c0000c0, 0x00000280,
+ 0x2c0000c0, 0x000002c0, 0x2c0000c0, 0x00000300,
+ 0xc4000880, 0x000007c0, 0x04000400, 0x00000000,
+ 0x0c000480, 0x00000fc4, 0x04002000, 0x00000000,
+ 0x0c000480, 0x000007c4, 0x04002000, 0x00000000,
+ 0x0c000080, 0x00000fc4, 0x0c000080, 0x000007c4,
+ 0xc4000080, 0x000007c0, 0x04000400, 0x00000000,
+ 0xe0000480, 0x00000803, 0x04002000, 0x00000000,
+ 0x04000600, 0x00000400, 0x265a58c0, 0x000187c8,
+ 0x58000080, 0x000007c0, 0x04000400, 0x00000000,
+ 0xe0000080, 0x00000803, 0x04002000, 0x00000000,
+ 0x000001e0, 0x00000000, 0x50000080, 0x00001c01,
+ 0x40000480, 0x00002c0c, 0xc4000080, 0x000007c0,
+ 0x2c000080, 0x000007c2, 0x8c200080, 0x00000fc2,
+ 0x00200600, 0x00000020, 0x880c0080, 0x00000c02,
+ 0x880c00c0, 0x00000c42, 0x247ffc80, 0x000007c2,
+ 0x281ffc80, 0x000007c2, 0x04000400, 0x00000000,
+ 0x800c0080, 0x00000fc2, 0x04000800, 0x00000000,
+ 0x98000480, 0x00000fc2, 0x28000480, 0x00000fc0,
+ 0x04001000, 0x00000000, 0x80fffc80, 0x00000fc2,
+ 0x30000080, 0x000007c4, 0x00010600, 0x00000001,
+ 0x0002fd40, 0x00000000, 0x80068200, 0x0000400f,
+ 0x00030160, 0x00000000, 0x0001a1c0, 0x00000000,
+ 0xe0000480, 0x00000803, 0x04001c00, 0x00000000,
+ 0x28000080, 0x00000fc0, 0x88000480, 0x00000802,
+ 0x04000400, 0x00000000, 0x5c000080, 0x000007c2,
+ 0x02000600, 0x00000200, 0x2c0010c0, 0x00003bc1,
+ 0x2c001880, 0x00003bc1, 0x18001880, 0x00003bc1,
+ 0x1c001880, 0x00003bc1, 0x20001880, 0x00003bc1,
+ 0x24001880, 0x00003bc1, 0x28001880, 0x00003bc1,
+ 0x00020200, 0x0000400e, 0x00036d40, 0x00000000,
+ 0x40004600, 0x00000000, 0x00035940, 0x00000000,
+ 0x04000900, 0x0001a420, 0x04001000, 0x00000000,
+ 0x40004a00, 0x00000000, 0x0c0010e0, 0x00001800,
+ 0x0c0000c0, 0x00001800, 0x04000480, 0x00001800,
+ 0x04000800, 0x00000000, 0x08000480, 0x00001800,
+ 0x04000800, 0x00000000, 0x000001e0, 0x00000000,
+ 0x9c000cb1, 0x00001c01, 0x9c0010b1, 0x00001c03,
+ 0x24000091, 0x00001c01, 0x00000051, 0x00004000,
+ 0x00039531, 0x00000000, 0x40001a01, 0x00000000,
+ 0x00039561, 0x00000000, 0x24000081, 0x00001c01,
+ 0x00000041, 0x00004000, 0x000001e0, 0x00000000,
+ 0x84000900, 0x0000241c, 0xc0014200, 0x0000c001,
+ 0x0003ad40, 0x00000000, 0x04001000, 0x00000000,
+ 0x2c0008a0, 0x00000802, 0x000001e0, 0x00000000,
+ 0x40000480, 0x00002c0c, 0x04000400, 0x00000000,
+ 0x04000080, 0x00002c00, 0x04000400, 0x00000000,
+ 0x00020200, 0x0000400e, 0x00044540, 0x00000000,
+ 0x40004600, 0x00000000, 0x040004c0, 0x00001800,
+ 0x080004c0, 0x00001800, 0x00044540, 0x00000000,
+ 0x08000080, 0x00001800, 0x04000400, 0x00000000,
+ 0x04000080, 0x00001800, 0x00000081, 0x00001800,
+ 0x04000400, 0x00000000, 0x88000480, 0x00000802,
+ 0x04000800, 0x00000000, 0x0c000900, 0x00001800,
+ 0x04001000, 0x00000000, 0x00010a00, 0x00000001,
+ 0x00042140, 0x00000000, 0x0c000c80, 0x00001800,
+ 0x00000020, 0x00000000, 0x00000020, 0x00000000,
+ 0x0c000880, 0x00001800, 0x00000020, 0x00000000,
+ 0x0c000080, 0x00001800, 0x00044920, 0x00000000,
+ 0x0c001c80, 0x00001800, 0x00001020, 0x00000000,
+ 0x00001020, 0x00000000, 0x0c001880, 0x00001800,
+ 0x00001020, 0x00000000, 0x00001020, 0x00000000,
+ 0x00001020, 0x00000000, 0x0c001080, 0x00001800,
+ 0x00044920, 0x00000000, 0x00000080, 0x00001800,
+ 0x00200600, 0x00000020, 0x0004a160, 0x00000000,
+ 0x18000080, 0x00003bc1, 0x1c000080, 0x00003bc1,
+ 0x20000080, 0x00003bc1, 0x24000080, 0x00003bc1,
+ 0x28000080, 0x00003bc1, 0x2c000880, 0x00003801,
+ 0x2c001080, 0x00003841, 0x2c000880, 0x00003881,
+ 0x2c001080, 0x000038c1, 0x2c000880, 0x00003901,
+ 0x2c001080, 0x00003941, 0x2c000880, 0x00003981,
+ 0x2c001080, 0x000039c1, 0x02000600, 0x00000200,
+ 0x2c0010c0, 0x00003bc1, 0x58000080, 0x000003cf,
+ 0x5c000080, 0x000003cf, 0x5c000880, 0x000000cf,
+ 0x5c000880, 0x0000028f, 0x00052d20, 0x00000000,
+ 0x18000080, 0x00003801, 0x18000080, 0x00003841,
+ 0x18000080, 0x00003881, 0x18000080, 0x000038c1,
+ 0x1c000080, 0x00003801, 0x1c000080, 0x00003841,
+ 0x1c000080, 0x00003881, 0x1c000080, 0x000038c1,
+ 0x20000080, 0x00003801, 0x20000080, 0x00003841,
+ 0x20000080, 0x00003881, 0x20000080, 0x000038c1,
+ 0x24000080, 0x00003801, 0x24000080, 0x00003841,
+ 0x24000080, 0x00003881, 0x24000080, 0x000038c1,
+ 0x28000080, 0x00003841, 0x28000080, 0x000038c1,
+ 0x2c000880, 0x00003801, 0x2c001080, 0x00003841,
+ 0x2c000880, 0x00003881, 0x2c001080, 0x000038c1,
+ 0x02000600, 0x00000200, 0x2c0010c0, 0x00003bc1,
+ 0x58000080, 0x0000000f, 0x5c000080, 0x0000000f,
+ 0x58000080, 0x0000004f, 0x5c000080, 0x0000004f,
+ 0x58000080, 0x0000008f, 0x5c000080, 0x0000008f,
+ 0x58000080, 0x000000cf, 0x58000080, 0x0000010f,
+ 0x5c000080, 0x0000010f, 0x58000080, 0x0000014f,
+ 0x5c000080, 0x0000014f, 0x20000080, 0x00002bcc,
+ 0x00053d31, 0x00000000, 0x40001a00, 0x00000000,
+ 0x00053d60, 0x00000000, 0x040030a0, 0x00002c00,
+ 0x88000080, 0x00000802, 0x5c1ffc80, 0x000007c2,
+ 0x00800600, 0x00000080, 0xbc000900, 0x00016c0c,
+ 0x040000c0, 0x00002424, 0x040080e0, 0x00002424,
+ 0x04000000, 0x00000000, 0x98000095, 0x00002c0c,
+ 0x9c000095, 0x00002c0c, 0x98001cb5, 0x00002c0c,
+ 0x9c0020b5, 0x00002c0c, 0x98000095, 0x00002c0c,
+ 0x9c000095, 0x00002c0c, 0x40000095, 0x00002c0c,
+ 0x00000605, 0x00002000, 0x400000c5, 0x00002c0c,
+ 0x800004c5, 0x00002c0c, 0x800000c5, 0x00002c0c,
+ 0x040000e5, 0x00002c00, 0xbc0000e5, 0x00016c0c,
+ 0x04000000, 0x00000000, 0x9bfe00e5, 0x00002c0c,
+ 0x9ffe00e5, 0x00002c0c, 0x9bfe04e5, 0x00002c0c,
+ 0x9ffe04e5, 0x00002c0c, 0x9bfe00e5, 0x00002c0c,
+ 0x9ffe00e5, 0x00002c0c, 0x400004e5, 0x00002c0c,
+ 0x04000400, 0x00000000, 0xbc0008a5, 0x00016c0c,
+ 0x000001e0, 0x00000000, 0xe8030c80, 0x00001c01,
+ 0x04000400, 0x00000000, 0xe8000080, 0x00001c01,
+ 0x000001e0, 0x00000000, 0x88000080, 0x00000802,
+ 0x04000c00, 0x00000000, 0x0000cc80, 0x00000808,
+ 0x1c000480, 0x00000fc1, 0x1c000080, 0x00000fc1,
+ 0x1c000480, 0x000007c1, 0x1c000080, 0x000007c1,
+ 0x00000080, 0x00000808, 0x50000080, 0x00001c01,
+ 0xb8000480, 0x00000801, 0x04000400, 0x00000000,
+ 0x00040600, 0x00000004, 0x598000e0, 0x000007c0,
+ 0x28000480, 0x00000fc0, 0x04001000, 0x00000000,
+ 0xe0000080, 0x00000803, 0x04001400, 0x00000000,
+ 0x88000880, 0x00000802, 0x00000c20, 0x00000000,
+ 0x40004600, 0x00000000, 0x00062160, 0x00000000,
+ 0x1c000880, 0x00000fc1, 0x1c000080, 0x00000fc1,
+ 0x1c000880, 0x000007c1, 0x1c000080, 0x000007c1,
+ 0x04003c00, 0x00000000, 0x00040600, 0x00000004,
+ 0x00064140, 0x00000000, 0x0001bdc0, 0x00000000,
+ 0x28000080, 0x00000fc0, 0x80000080, 0x00000fc2,
+ 0x98000080, 0x00000fc2, 0x24000080, 0x000007c2,
+ 0x28000080, 0x000007c2, 0x883c0080, 0x00000fc2,
+ 0x80040200, 0x0000400f, 0x00067940, 0x00000000,
+ 0x00080200, 0x0000400e, 0x00067940, 0x00000000,
+ 0xe4000480, 0x00000801, 0x04000800, 0x00000000,
+ 0xe4000080, 0x00000801, 0x04000800, 0x00000000,
+ 0xe8030c81, 0x00001c01, 0x04000800, 0x00000000,
+ 0xe8000081, 0x00001c01, 0x04000400, 0x00000000,
+ 0x40001a01, 0x00000000, 0x0006a541, 0x00000000,
+ 0xa0000481, 0x00002420, 0x04000400, 0x00000000,
+ 0x40003201, 0x00000000, 0x0006c541, 0x00000000,
+ 0x0006a561, 0x00000000, 0x00001c21, 0x00000000,
+ 0xa0000081, 0x00002420, 0x04000400, 0x00000000,
+ 0x00020601, 0x00000002, 0xe8030cc1, 0x00001c01,
+ 0x04000800, 0x00000000, 0xe80000c1, 0x00001c01,
+ 0x04000400, 0x00000000, 0xa0000081, 0x00002420,
+ 0x04000400, 0x00000000, 0xe8030c91, 0x00001c01,
+ 0x04000800, 0x00000000, 0xe8000091, 0x00001c01,
+ 0x04000400, 0x00000000, 0xa8000480, 0x00001c04,
+ 0x04000400, 0x00000000, 0x18000081, 0x0001e420,
+ 0x40006611, 0x00000000, 0x0006f551, 0x00000000,
+ 0x000021d1, 0x00000000, 0xa0000491, 0x00002420,
+ 0x04000400, 0x00000000, 0x540020b1, 0x00014fc0,
+ 0xf00024b1, 0x000147c1, 0xa0000091, 0x00002420,
+ 0x000001e0, 0x00000000, 0xa8000080, 0x00001c06,
+ 0x80013080, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80013480, 0x00001c04, 0x04000800, 0x00000000,
+ 0x04001c00, 0x00000000, 0x80000080, 0x00001c04,
+ 0x00000420, 0x00000000, 0xa8000080, 0x00001c06,
+ 0x80013880, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80013c80, 0x00001c04, 0x04000800, 0x00000000,
+ 0x04001c00, 0x00000000, 0x80000080, 0x00001c04,
+ 0x000001e0, 0x00000000, 0x20000086, 0x0001c7c4,
+ 0x9e000480, 0x000007c2, 0xc4060080, 0x000007c2,
+ 0xd4000480, 0x000007c2, 0xe4000480, 0x000007c2,
+ 0x9c003080, 0x00001c04, 0x7c000080, 0x0001c7c1,
+ 0x88000c80, 0x000007c2, 0x64000c80, 0x00000801,
+ 0x90000880, 0x000007c2, 0xec0ffc80, 0x000007c2,
+ 0xec000080, 0x000007c2, 0xf8000080, 0x000007fe,
+ 0xf8000480, 0x000007c2, 0xf8000480, 0x000007d2,
+ 0xa8001080, 0x00001c06, 0x80014880, 0x00001c04,
+ 0x04000400, 0x00000000, 0x80014c80, 0x00001c04,
+ 0x04000800, 0x00000000, 0x00000840, 0x00006000,
+ 0x80000080, 0x00001c04, 0xf8000080, 0x000007c2,
+ 0xf8000080, 0x000007d2, 0xec0ffc80, 0x000007c2,
+ 0xec000080, 0x000007c2, 0xf8000480, 0x000007c6,
+ 0xf8000480, 0x000007d6, 0xa8001080, 0x00001c06,
+ 0x80015080, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80015480, 0x00001c04, 0x04000800, 0x00000000,
+ 0x00000840, 0x00006000, 0x80000080, 0x00001c04,
+ 0xf8000080, 0x000007c6, 0xf8000080, 0x000007d6,
+ 0x64000880, 0x00000801, 0x00001420, 0x00000000,
+ 0xc4000480, 0x000007c0, 0x04001000, 0x00000000,
+ 0xc4000080, 0x000007c0, 0x04000600, 0x00000400,
+ 0x24c8c8c0, 0x000147c8, 0x80000480, 0x00000802,
+ 0x04000400, 0x00000000, 0x80000080, 0x00000802,
+ 0x90000080, 0x000007c2, 0x98000c80, 0x000007c2,
+ 0xa8001080, 0x00001c06, 0x80015880, 0x00001c04,
+ 0x04000400, 0x00000000, 0x80015c80, 0x00001c04,
+ 0x04000800, 0x00000000, 0x00000840, 0x00006000,
+ 0x80000080, 0x00001c04, 0x04000800, 0x00000000,
+ 0x98000080, 0x000007c2, 0x88000080, 0x000007c2,
+ 0x64000080, 0x00000801, 0x7c000480, 0x0001c7c1,
+ 0xe4000480, 0x00000801, 0x04000800, 0x00000000,
+ 0xe4000080, 0x00000801, 0x04000800, 0x00000000,
+ 0x00001820, 0x00000000, 0x90000480, 0x000007c2,
+ 0xa8001080, 0x00001c06, 0x80016080, 0x00001c04,
+ 0x04000400, 0x00000000, 0x80016480, 0x00001c04,
+ 0x04000800, 0x00000000, 0x00000840, 0x00006000,
+ 0x80000080, 0x00001c04, 0x04000800, 0x00000000,
+ 0x80000480, 0x00000802, 0x04000400, 0x00000000,
+ 0x80000080, 0x00000802, 0x90000080, 0x000007c2,
+ 0x04000800, 0x00000000, 0xe4000480, 0x00000801,
+ 0x04000800, 0x00000000, 0xe4000080, 0x00000801,
+ 0x04000800, 0x00000000, 0xa8000080, 0x00001c04,
+ 0x50000480, 0x00001c01, 0x20000486, 0x0001c7c4,
+ 0x000001e0, 0x00000000, 0x80008600, 0x00000000,
+ 0x0008d560, 0x00000000, 0x80000480, 0x00000802,
+ 0x04000400, 0x00000000, 0x80000080, 0x00000802,
+ 0x04000400, 0x00000000, 0xe4000480, 0x00000801,
+ 0x04000800, 0x00000000, 0xe4000080, 0x00000801,
+ 0xa8000080, 0x00001c04, 0xb8000080, 0x00000801,
+ 0x04000800, 0x00000000, 0x00001080, 0x000033c2,
+ 0x50000480, 0x00001c01, 0xb4000080, 0x00002400,
+ 0x88000481, 0x00000c00, 0x24000480, 0x00001c01,
+ 0x000001e0, 0x00000000, 0x40000480, 0x00002c0c,
+ 0x2c000080, 0x000007c2, 0x8c000080, 0x00000fc2,
+ 0x00200600, 0x00000020, 0x880c0080, 0x00000c02,
+ 0x880c00c0, 0x00000c42, 0x247ffc80, 0x000007c2,
+ 0x281ffc80, 0x000007c2, 0x04000400, 0x00000000,
+ 0x98000480, 0x00000fc2, 0x28000480, 0x00000fc0,
+ 0x04001000, 0x00000000, 0x80fffc80, 0x00000fc2,
+ 0x04000400, 0x00000000, 0xe0000480, 0x00000803,
+ 0x04002000, 0x00000000, 0x28000080, 0x00000fc0,
+ 0x50000080, 0x00001c01, 0x00000480, 0x00001800,
+ 0x0c000080, 0x00001800, 0x5c000080, 0x000007c2,
+ 0x04000080, 0x00002c00, 0x02000600, 0x00000200,
+ 0x2c0010c0, 0x00003bc1, 0x2c001880, 0x00003bc1,
+ 0x18001880, 0x00003bc1, 0x1c001880, 0x00003bc1,
+ 0x20001880, 0x00003bc1, 0x24001880, 0x00003bc1,
+ 0x28001880, 0x00003bc1, 0x20000880, 0x00002bcc,
+ 0x040030a0, 0x00002c00, 0x24000080, 0x00001c01,
+ 0xb4000480, 0x00002400, 0x00000040, 0x00004000,
+ 0x00000020, 0x00000000, 0x00000020, 0x00000000,
+ 0x88000c80, 0x00000c00, 0x80000080, 0x00000fc0,
+ 0x04000c00, 0x00000000, 0x88000480, 0x00000802,
+ 0x000001e0, 0x00000000, 0x00001880, 0x000033c2,
+ 0x000009c1, 0x00000000, 0x9c000d11, 0x00001c01,
+ 0x04001011, 0x00000000, 0x9c001111, 0x00001c03,
+ 0x04001011, 0x00000000, 0x9c000091, 0x00001c01,
+ 0x9c000091, 0x00001c03, 0x0009dd21, 0x00000000,
+ 0xb8000480, 0x00000801, 0x04000800, 0x00000000,
+ 0x80068200, 0x0000400f, 0x0009d540, 0x00000000,
+ 0x000091c0, 0x00000000, 0x000181c0, 0x00000000,
+ 0x0002a5c0, 0x00000000, 0x000371c0, 0x00000000,
+ 0x000399c0, 0x00000000, 0x0003b1c0, 0x00000000,
+ 0x0005cdc0, 0x00000000, 0x40004200, 0x00000000,
+ 0x6001c0e0, 0x00002425, 0x00080200, 0x0000400e,
+ 0x000a2140, 0x00000000, 0x000a0531, 0x00000000,
+ 0x00070dc0, 0x00000000, 0x80008600, 0x00000000,
+ 0x000a2140, 0x00000000, 0x00074dc2, 0x00000000,
+ 0x80068200, 0x0000400f, 0xc40004c0, 0x000007c0,
+ 0x04001000, 0x00000000, 0xc40000c0, 0x000007c0,
+ 0x40006611, 0x00000000, 0x000a6951, 0x00000000,
+ 0x80068211, 0x0000400f, 0x000a6951, 0x00000000,
+ 0x00080211, 0x0000400e, 0x000a4151, 0x00000000,
+ 0x80008611, 0x00000000, 0x000a4d71, 0x00000000,
+ 0x00001031, 0x00000000, 0x00001031, 0x00000000,
+ 0x00002c31, 0x00000000, 0xa8000091, 0x00001c06,
+ 0x80016891, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80016c91, 0x00001c04, 0x04000800, 0x00000000,
+ 0x00000851, 0x00006000, 0x80000091, 0x00001c04,
+ 0x24000091, 0x0001e420, 0x0008adc0, 0x00000000,
+ 0x00000000, 0x00000000, 0x0008f5c0, 0x00000000,
+ 0x24000480, 0x00001c01, 0x00000400, 0x00000000,
+ 0x50000080, 0x00001c01, 0x9c000d00, 0x00001c01,
+ 0x04001000, 0x00000000, 0x9c001100, 0x00001c03,
+ 0x04001000, 0x00000000, 0x9c000080, 0x00001c01,
+ 0x9c000080, 0x00001c03, 0x00001880, 0x000033c2,
+ 0xb8000480, 0x00000801, 0x04000c00, 0x00000000,
+ 0x24000491, 0x0001e420, 0xa8000080, 0x00001c06,
+ 0x80012880, 0x00001c04, 0x04000400, 0x00000000,
+ 0x80012c80, 0x00001c04, 0x04000800, 0x00000000,
+ 0x00000840, 0x00006000, 0x80000080, 0x00001c04,
+ 0x2c000080, 0x000007c2, 0x8c200080, 0x00000fc2,
+ 0x00200600, 0x00000020, 0x883c0080, 0x00000c02,
+ 0x883c00c0, 0x00000c42, 0x98000480, 0x00000fc2,
+ 0x28000480, 0x00000fc0, 0x04001000, 0x00000000,
+ 0x80fffc80, 0x00000fc2, 0x247ffc80, 0x000007c2,
+ 0x281ffc80, 0x000007c2, 0x04000400, 0x00000000,
+ 0xe0000480, 0x00000803, 0x28000080, 0x00000fc0,
+ 0x00800600, 0x00000080, 0x040000c0, 0x00002424,
+ 0x040080e0, 0x00002424, 0x400004e2, 0x00002c0c,
+ 0x04000800, 0x00000000, 0x400000e2, 0x00002c0c,
+ 0x04000800, 0x00000000, 0x800004e0, 0x00002c0c,
+ 0x800000e0, 0x00002c0c, 0x00000605, 0x00002000,
+ 0x400004c2, 0x00002c0c, 0x04000800, 0x00000000,
+ 0x400000c2, 0x00002c0c, 0x04000800, 0x00000000,
+ 0x800004c0, 0x00002c0c, 0x800000c0, 0x00002c0c,
+ 0x04000c00, 0x00000000, 0x24000080, 0x00001c01,
+ 0x10000200, 0x00005000, 0x000b5540, 0x00000000,
+ 0x00000040, 0x00004000, 0x28000480, 0x00000fc0,
+ 0x04001000, 0x00000000, 0xe0000080, 0x00000803,
+ 0x04000800, 0x00000000, 0x28000080, 0x00000fc0,
+ 0x80000080, 0x00000fc2, 0x98000080, 0x00000fc2,
+ 0x24000080, 0x000007c2, 0x28000080, 0x000007c2,
+ 0xe4000480, 0x00000801, 0x04000800, 0x00000000,
+ 0xe4000080, 0x00000801, 0x04000800, 0x00000000,
+ 0xa8000480, 0x00001c04, 0xe8030c80, 0x00001c01,
+ 0x04000800, 0x00000000, 0xe8000080, 0x00001c01,
+ 0x04000400, 0x00000000, 0x9c000ca0, 0x00001c01,
+ 0x9c0010a0, 0x00001c03, 0x000a0520, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+#endif /* __DRIVERS_RAM_RENESAS_DBSC5_R8A78000_DRAM_H__ */
diff --git a/drivers/ram/renesas/dbsc5/rtvram.c b/drivers/ram/renesas/dbsc5/rtvram.c
index 6c149284bc6..bf30a207142 100644
--- a/drivers/ram/renesas/dbsc5/rtvram.c
+++ b/drivers/ram/renesas/dbsc5/rtvram.c
@@ -13,34 +13,41 @@
#define RTVRAM_VBUF_CFG 0x6504
#define RTVRAM_VBUF_CFG_CACHE_MODE_8WAY (1 << 8)
#define RTVRAM_VBUF_CFG_VBUF_SIZE_28M (6 << 0)
+#define RTVRAM_VBUF_CFG_VBUF_SIZE_32M (7 << 0)
#define RTVRAM_EXT_MODE 0x8500
#define RTVRAM_EXT_MODE_EXT BIT(0)
#define RTVRAM_VBUF_BADDR 0xC580
-#define RTVRAM_VBUF_NUM 7
-
-#define SDRAM_40BIT_ADDR_TOP 0x0400000000ULL
#define RTVRAM_VBUF_AREA_SIZE SZ_4M
struct renesas_dbsc5_rtvram_priv {
void __iomem *regs;
};
+struct renesas_dbsc5_rtvram_data {
+ u8 sdram_40bit_addr_top; /* Left-shift by 32 */
+ u8 vbuf_num;
+ u8 size;
+ u8 size_bit;
+};
+
static int renesas_dbsc5_rtvram_probe(struct udevice *dev)
{
struct renesas_dbsc5_rtvram_priv *priv = dev_get_priv(dev);
+ struct renesas_dbsc5_rtvram_data *data =
+ (struct renesas_dbsc5_rtvram_data *)dev_get_driver_data(dev);
u64 addr;
int i;
/* Set each 4MB from the top of SDRAM as the buffer area of RT-VRAM. */
- for (i = 0; i < RTVRAM_VBUF_NUM; i++) {
- addr = (SDRAM_40BIT_ADDR_TOP + (RTVRAM_VBUF_AREA_SIZE * i)) >> 16;
+ for (i = 0; i < data->vbuf_num + 1; i++) {
+ addr = (((u64)(data->sdram_40bit_addr_top) << 32ULL) + (RTVRAM_VBUF_AREA_SIZE * i)) >> 16;
writel(lower_32_bits(addr), priv->regs + (RTVRAM_VBUF_BADDR + (4 * i)));
}
/* Cache Mode: 8-way, VBF size: 28M */
setbits_le32(priv->regs + RTVRAM_VBUF_CFG,
- RTVRAM_VBUF_CFG_CACHE_MODE_8WAY | RTVRAM_VBUF_CFG_VBUF_SIZE_28M);
+ RTVRAM_VBUF_CFG_CACHE_MODE_8WAY | data->size_bit);
/* Change from Compatible Mode to Extended Mode */
writel(RTVRAM_EXT_MODE_EXT, priv->regs + RTVRAM_EXT_MODE);
@@ -65,9 +72,11 @@ static int renesas_dbsc5_rtvram_get_info(struct udevice *dev,
struct ram_info *info)
{
struct renesas_dbsc5_rtvram_priv *priv = dev_get_priv(dev);
+ struct renesas_dbsc5_rtvram_data *data =
+ (struct renesas_dbsc5_rtvram_data *)dev_get_driver_data(dev);
info->base = (phys_addr_t)priv->regs;
- info->size = 28 * SZ_1M;
+ info->size = data->size * SZ_1M;
return 0;
}
@@ -76,14 +85,29 @@ static const struct ram_ops renesas_dbsc5_rtvram_ops = {
.get_info = renesas_dbsc5_rtvram_get_info,
};
+struct renesas_dbsc5_rtvram_data gen4_rtvram_data = {
+ .sdram_40bit_addr_top = 0x4,
+ .vbuf_num = 7,
+ .size = 28,
+ .size_bit = RTVRAM_VBUF_CFG_VBUF_SIZE_28M,
+};
+
+struct renesas_dbsc5_rtvram_data gen5_rtvram_data = {
+ .sdram_40bit_addr_top = 0x12,
+ .vbuf_num = 8,
+ .size = 32,
+ .size_bit = RTVRAM_VBUF_CFG_VBUF_SIZE_32M,
+};
+
static const struct udevice_id renesas_dbsc5_rtvram_ids[] = {
- { .compatible = "renesas,r8a779g0-rtvram" },
- { .compatible = "renesas,r8a779h0-rtvram" },
+ { .compatible = "renesas,r8a779g0-rtvram", .data = (ulong)&gen4_rtvram_data },
+ { .compatible = "renesas,r8a779h0-rtvram", .data = (ulong)&gen4_rtvram_data },
+ { .compatible = "renesas,r8a78000-rtvram", .data = (ulong)&gen5_rtvram_data },
{ /* sentinel */ }
};
U_BOOT_DRIVER(renesas_dbsc5_rtvram) = {
- .name = "rtvram",
+ .name = "dbsc5_rtvram",
.id = UCLASS_RAM,
.of_match = renesas_dbsc5_rtvram_ids,
.of_to_plat = renesas_dbsc5_rtvram_of_to_plat,
diff --git a/drivers/ram/stm32mp1/Kconfig b/drivers/ram/stm32mp1/Kconfig
index 1aaf064c30c..76bd17a8874 100644
--- a/drivers/ram/stm32mp1/Kconfig
+++ b/drivers/ram/stm32mp1/Kconfig
@@ -6,43 +6,43 @@ config STM32MP1_DDR
select SPL_RAM if SPL
default y
help
- activate STM32MP1 DDR controller driver for STM32MP1 soc
- family: support for LPDDR2, LPDDR3 and DDR3
- the SDRAM parameters for controleur and phy need to be provided
- in device tree (computed by DDR tuning tools)
+ activate STM32MP1 DDR controller driver for STM32MP1 soc
+ family: support for LPDDR2, LPDDR3 and DDR3
+ the SDRAM parameters for controleur and phy need to be provided
+ in device tree (computed by DDR tuning tools)
config STM32MP1_DDR_INTERACTIVE
bool "STM32MP1 DDR driver : interactive support"
depends on STM32MP1_DDR
help
- activate interactive support in STM32MP1 DDR controller driver
- used for DDR tuning tools
- to enter in intercative mode type 'd' during SPL DDR driver
- initialisation
+ activate interactive support in STM32MP1 DDR controller driver
+ used for DDR tuning tools
+ to enter in intercative mode type 'd' during SPL DDR driver
+ initialisation
config STM32MP1_DDR_INTERACTIVE_FORCE
bool "STM32MP1 DDR driver : force interactive mode"
depends on STM32MP1_DDR_INTERACTIVE
help
- force interactive mode in STM32MP1 DDR controller driver
- skip the polling of character 'd' in console
- useful when SPL is loaded in sysram
- directly by programmer
+ force interactive mode in STM32MP1 DDR controller driver
+ skip the polling of character 'd' in console
+ useful when SPL is loaded in sysram
+ directly by programmer
config STM32MP1_DDR_TESTS
bool "STM32MP1 DDR driver : tests support"
depends on STM32MP1_DDR_INTERACTIVE
default y
help
- activate test support for interactive support in
- STM32MP1 DDR controller driver: command test
+ activate test support for interactive support in
+ STM32MP1 DDR controller driver: command test
config STM32MP1_DDR_TUNING
bool "STM32MP1 DDR driver : support of tuning"
depends on STM32MP1_DDR_INTERACTIVE
default y
help
- activate tuning command in STM32MP1 DDR interactive mode
- used for DDR tuning tools
- - DQ Deskew algorithm
- - DQS Trimming
+ activate tuning command in STM32MP1 DDR interactive mode
+ used for DDR tuning tools
+ - DQ Deskew algorithm
+ - DQS Trimming
diff --git a/drivers/reboot-mode/Kconfig b/drivers/reboot-mode/Kconfig
index 72b33d71223..3fdb4218a8b 100644
--- a/drivers/reboot-mode/Kconfig
+++ b/drivers/reboot-mode/Kconfig
@@ -11,26 +11,26 @@ config DM_REBOOT_MODE
depends on DM
select DEVRES
help
- Enable support for reboot mode control. This will allow users to
- adjust the boot process based on reboot mode parameter
- passed to U-Boot.
+ Enable support for reboot mode control. This will allow users to
+ adjust the boot process based on reboot mode parameter
+ passed to U-Boot.
config DM_REBOOT_MODE_GPIO
bool "Use GPIOs as reboot mode backend"
depends on DM_REBOOT_MODE
help
- Use GPIOs to control the reboot mode. This will allow users to boot
- a device in a specific mode by using a GPIO that can be controlled
- outside U-Boot.
+ Use GPIOs to control the reboot mode. This will allow users to boot
+ a device in a specific mode by using a GPIO that can be controlled
+ outside U-Boot.
config DM_REBOOT_MODE_RTC
bool "Use RTC as reboot mode backend"
depends on DM_RTC
depends on DM_REBOOT_MODE
help
- Use RTC non volatile memory to control the reboot mode. This will allow users to boot
- a device in a specific mode by using a register(s) that can be controlled
- outside U-Boot (e.g. Kernel).
+ Use RTC non volatile memory to control the reboot mode. This will allow users to boot
+ a device in a specific mode by using a register(s) that can be controlled
+ outside U-Boot (e.g. Kernel).
config REBOOT_MODE_NVMEM
bool "Use NVMEM reboot mode"
diff --git a/drivers/remoteproc/ipu_rproc.c b/drivers/remoteproc/ipu_rproc.c
index 2ca78b550a7..8f0b619daf7 100644
--- a/drivers/remoteproc/ipu_rproc.c
+++ b/drivers/remoteproc/ipu_rproc.c
@@ -695,9 +695,8 @@ static int ipu_probe(struct udevice *dev)
priv = dev_get_priv(dev);
priv->mem.bus_addr =
- devfdt_get_addr_size_name(dev,
- ipu_mem_names[0],
- (fdt_addr_t *)&priv->mem.size);
+ dev_read_addr_size_name(dev, ipu_mem_names[0],
+ (fdt_addr_t *)&priv->mem.size);
ret = reset_get_by_index(dev, 2, &reset);
if (ret < 0) {
@@ -718,7 +717,7 @@ static int ipu_probe(struct udevice *dev)
priv->mem.cpu_addr = map_physmem(priv->mem.bus_addr,
priv->mem.size, MAP_NOCACHE);
- if (devfdt_get_addr(dev) == 0x58820000)
+ if (dev_read_addr(dev) == 0x58820000)
priv->id = 0;
else
priv->id = 1;
diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
index 9aec138637b..b0823bfd22d 100644
--- a/drivers/remoteproc/pru_rproc.c
+++ b/drivers/remoteproc/pru_rproc.c
@@ -421,19 +421,16 @@ static void pru_set_id(struct pru_privdata *priv, struct udevice *dev)
static int pru_probe(struct udevice *dev)
{
struct pru_privdata *priv;
- ofnode node;
-
- node = dev_ofnode(dev);
priv = dev_get_priv(dev);
priv->prusspriv = dev_get_priv(dev->parent);
- priv->pru_iram = devfdt_get_addr_size_index(dev, PRU_MEM_IRAM,
- &priv->pru_iramsz);
- priv->pru_ctrl = devfdt_get_addr_size_index(dev, PRU_MEM_CTRL,
- &priv->pru_ctrlsz);
- priv->pru_debug = devfdt_get_addr_size_index(dev, PRU_MEM_DEBUG,
- &priv->pru_debugsz);
+ priv->pru_iram = dev_read_addr_size_index(dev, PRU_MEM_IRAM,
+ &priv->pru_iramsz);
+ priv->pru_ctrl = dev_read_addr_size_index(dev, PRU_MEM_CTRL,
+ &priv->pru_ctrlsz);
+ priv->pru_debug = dev_read_addr_size_index(dev, PRU_MEM_DEBUG,
+ &priv->pru_debugsz);
priv->iram_da = 0;
priv->pdram_da = 0;
diff --git a/drivers/remoteproc/ti_k3_r5f_rproc.c b/drivers/remoteproc/ti_k3_r5f_rproc.c
index 7326f5a4b30..c5810dd0994 100644
--- a/drivers/remoteproc/ti_k3_r5f_rproc.c
+++ b/drivers/remoteproc/ti_k3_r5f_rproc.c
@@ -861,7 +861,7 @@ static int k3_r5f_probe(struct udevice *dev)
return 0;
}
- ret = k3_r5f_proc_request(core);
+ ret = ti_sci_proc_request(&core->tsp);
if (ret)
return ret;
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index ebf484d9df4..db764ed5ace 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -64,6 +64,22 @@ config RESET_BCM6345
help
Support reset controller on BCM6345.
+config RESET_BRCMSTB
+ depends on ARCH_BCM283X
+ bool "Generic Reset controller driver for Broadcom"
+ help
+ This enables reset controller for Broadcom devices.
+ If you wish to use reset resources managed by the Broadcom
+ Reset Controller, say Y here. Otherwise, say N.
+
+config RESET_BRCMSTB_RESCAL
+ depends on ARCH_BCM283X
+ bool "Generic Rescal Reset controller driver for Broadcom"
+ help
+ Support rescal reset controller on Broadcom.
+ If you wish to use reset resources managed by the Broadcom
+ Reset Controller, say Y here. Otherwise, say N.
+
config RESET_UNIPHIER
bool "Reset controller driver for UniPhier SoCs"
depends on ARCH_UNIPHIER
@@ -91,6 +107,15 @@ config RESET_AST2600
Say Y if you want to control reset signals of different peripherals
through System Control Unit (SCU).
+config RESET_AST2700
+ bool "Reset controller driver for AST2700 SoCs"
+ depends on DM_RESET && ASPEED_AST2700
+ default y if ASPEED_AST2700
+ help
+ Support for reset controller on AST2700 SoC.
+ Say Y if you want to control reset signals of different peripherals
+ through System Control Unit (SCU).
+
config RESET_ROCKCHIP
bool "Reset controller driver for Rockchip SoCs"
depends on DM_RESET && ARCH_ROCKCHIP && CLK
@@ -100,6 +125,15 @@ config RESET_ROCKCHIP
though is that some reset signals, like I2C or MISC reset multiple
devices.
+config SPL_RESET_ROCKCHIP
+ bool "SPL reset controller driver for Rockchip SoCs"
+ depends on SPL_DM_RESET && ARCH_ROCKCHIP && SPL_CLK
+ default y
+ help
+ Support for the reset controller on Rockchip SoCs in SPL. Select this
+ if you observe any reset-related warnings or errors when booting SPL,
+ such as when using UFS storage
+
config RESET_HSDK
bool "Synopsys HSDK Reset Driver"
depends on DM_RESET && TARGET_HSDK
@@ -245,12 +279,5 @@ config RESET_RZG2L_USBPHY_CTRL
RZ/G2L SoC. This is required for USB 2.0 functionality to work on this
SoC.
-config RESET_SPACEMIT_K1
- bool "Support for SPACEMIT's K1 Reset driver"
- depends on DM_RESET
- help
- Support for SPACEMIT's K1 Reset system. Basic Assert/Deassert
- is supported.
-
source "drivers/reset/stm32/Kconfig"
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 088545c6473..384f4336331 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -13,10 +13,13 @@ obj-$(CONFIG_RESET_AIROHA) += reset-airoha.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
+obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
+obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o
obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o
-obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o rst-rk3506.o rst-rk3528.o rst-rk3576.o rst-rk3588.o
+obj-$(CONFIG_RESET_AST2700) += reset-ast2700.o
+obj-$(CONFIG_$(PHASE_)RESET_ROCKCHIP) += reset-rockchip.o rst-rk3506.o rst-rk3528.o rst-rk3576.o rst-rk3588.o
obj-$(CONFIG_RESET_MESON) += reset-meson.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o
@@ -34,7 +37,7 @@ obj-$(CONFIG_RESET_DRA7) += reset-dra7.o
obj-$(CONFIG_RESET_AT91) += reset-at91.o
obj-$(CONFIG_$(PHASE_)RESET_JH7110) += reset-jh7110.o
obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
-obj-$(CONFIG_RESET_SPACEMIT_K1) += reset-spacemit-k1.o
+obj-$(CONFIG_CLK_SPACEMIT_K1) += spacemit/
obj-$(CONFIG_ARCH_STM32) += stm32/
obj-$(CONFIG_ARCH_STM32MP) += stm32/
diff --git a/drivers/reset/reset-ast2500.c b/drivers/reset/reset-ast2500.c
index f3543fa8cc1..c85906bbeb5 100644
--- a/drivers/reset/reset-ast2500.c
+++ b/drivers/reset/reset-ast2500.c
@@ -77,10 +77,10 @@ static int ast2500_reset_probe(struct udevice *dev)
return rc;
}
- priv->scu = devfdt_get_addr_ptr(scu_dev);
+ priv->scu = dev_read_addr_ptr(scu_dev);
if (IS_ERR_OR_NULL(priv->scu)) {
debug("%s: invalid SCU base pointer\n", __func__);
- return PTR_ERR(priv->scu);
+ return -EINVAL;
}
return 0;
@@ -91,7 +91,7 @@ static const struct udevice_id ast2500_reset_ids[] = {
{ }
};
-struct reset_ops ast2500_reset_ops = {
+static const struct reset_ops ast2500_reset_ops = {
.rst_assert = ast2500_reset_assert,
.rst_deassert = ast2500_reset_deassert,
.rst_status = ast2500_reset_status,
diff --git a/drivers/reset/reset-ast2600.c b/drivers/reset/reset-ast2600.c
index ec7b9b6625d..71b6220225a 100644
--- a/drivers/reset/reset-ast2600.c
+++ b/drivers/reset/reset-ast2600.c
@@ -76,10 +76,10 @@ static int ast2600_reset_probe(struct udevice *dev)
return rc;
}
- priv->scu = devfdt_get_addr_ptr(scu_dev);
+ priv->scu = dev_read_addr_ptr(scu_dev);
if (IS_ERR_OR_NULL(priv->scu)) {
debug("%s: invalid SCU base pointer\n", __func__);
- return PTR_ERR(priv->scu);
+ return -EINVAL;
}
return 0;
@@ -90,7 +90,7 @@ static const struct udevice_id ast2600_reset_ids[] = {
{ }
};
-struct reset_ops ast2600_reset_ops = {
+static const struct reset_ops ast2600_reset_ops = {
.rst_assert = ast2600_reset_assert,
.rst_deassert = ast2600_reset_deassert,
.rst_status = ast2600_reset_status,
diff --git a/drivers/reset/reset-ast2700.c b/drivers/reset/reset-ast2700.c
new file mode 100644
index 00000000000..2dd9e36cc0a
--- /dev/null
+++ b/drivers/reset/reset-ast2700.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <linux/err.h>
+#include <reset.h>
+#include <reset-uclass.h>
+
+/* Offset of the modrst register block within the SCU. */
+#define AST2700_RESET_OFFSET 0x200
+
+struct ast2700_reset_priv {
+ void __iomem *base;
+};
+
+static int ast2700_reset_assert(struct reset_ctl *reset_ctl)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+
+ if (reset_ctl->id < 32)
+ writel(BIT(reset_ctl->id), priv->base);
+ else
+ writel(BIT(reset_ctl->id - 32), priv->base + 0x20);
+
+ return 0;
+}
+
+static int ast2700_reset_deassert(struct reset_ctl *reset_ctl)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+
+ if (reset_ctl->id < 32)
+ writel(BIT(reset_ctl->id), priv->base + 0x04);
+ else
+ writel(BIT(reset_ctl->id - 32), priv->base + 0x24);
+
+ return 0;
+}
+
+static int ast2700_reset_status(struct reset_ctl *reset_ctl)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int status;
+
+ if (reset_ctl->id < 32)
+ status = BIT(reset_ctl->id) & readl(priv->base);
+ else
+ status = BIT(reset_ctl->id - 32) & readl(priv->base + 0x20);
+
+ return !!status;
+}
+
+static int ast2700_reset_probe(struct udevice *dev)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(dev);
+ void __iomem *scu_base;
+
+ scu_base = dev_read_addr_ptr(dev);
+ if (!scu_base)
+ return -EINVAL;
+
+ priv->base = scu_base + AST2700_RESET_OFFSET;
+
+ return 0;
+}
+
+static const struct reset_ops ast2700_reset_ops = {
+ .rst_assert = ast2700_reset_assert,
+ .rst_deassert = ast2700_reset_deassert,
+ .rst_status = ast2700_reset_status,
+};
+
+U_BOOT_DRIVER(ast2700_reset) = {
+ .name = "ast2700_reset",
+ .id = UCLASS_RESET,
+ .probe = ast2700_reset_probe,
+ .ops = &ast2700_reset_ops,
+ .priv_auto = sizeof(struct ast2700_reset_priv),
+};
diff --git a/drivers/reset/reset-at91.c b/drivers/reset/reset-at91.c
index 165c87acdc4..ebbfae1469b 100644
--- a/drivers/reset/reset-at91.c
+++ b/drivers/reset/reset-at91.c
@@ -79,7 +79,7 @@ static int at91_rst_deassert(struct reset_ctl *reset_ctl)
return at91_rst_update(reset, reset_ctl->id, false);
}
-struct reset_ops at91_reset_ops = {
+static const struct reset_ops at91_reset_ops = {
.of_xlate = at91_reset_of_xlate,
.rst_assert = at91_rst_assert,
.rst_deassert = at91_rst_deassert,
diff --git a/drivers/reset/reset-bcm6345.c b/drivers/reset/reset-bcm6345.c
index 6f140574216..161d00d1b0c 100644
--- a/drivers/reset/reset-bcm6345.c
+++ b/drivers/reset/reset-bcm6345.c
@@ -49,7 +49,7 @@ static int bcm6345_reset_request(struct reset_ctl *rst)
return bcm6345_reset_assert(rst);
}
-struct reset_ops bcm6345_reset_reset_ops = {
+static const struct reset_ops bcm6345_reset_reset_ops = {
.request = bcm6345_reset_request,
.rst_assert = bcm6345_reset_assert,
.rst_deassert = bcm6345_reset_deassert,
diff --git a/drivers/reset/reset-brcmstb-rescal.c b/drivers/reset/reset-brcmstb-rescal.c
new file mode 100644
index 00000000000..fc8fcfa8b3f
--- /dev/null
+++ b/drivers/reset/reset-brcmstb-rescal.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Broadcom STB generic reset controller
+ *
+ * Copyright (C) 2024 EPAM Systems
+ * Moved from linux kernel:
+ * Copyright (C) 2018-2020 Broadcom
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <errno.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <log.h>
+#include <malloc.h>
+#include <reset-uclass.h>
+
+#define BRCM_RESCAL_START 0x0
+#define BRCM_RESCAL_START_BIT BIT(0)
+#define BRCM_RESCAL_CTRL 0x4
+#define BRCM_RESCAL_STATUS 0x8
+#define BRCM_RESCAL_STATUS_BIT BIT(0)
+
+struct brcm_rescal_reset {
+ void __iomem *base;
+};
+
+/* Also doubles a deassert */
+static int brcm_rescal_reset_set(struct reset_ctl *rst)
+{
+ struct brcm_rescal_reset *data = dev_get_priv(rst->dev);
+ void __iomem *base = data->base;
+ u32 reg;
+ int ret;
+
+ reg = readl(base + BRCM_RESCAL_START);
+ writel(reg | BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
+ reg = readl(base + BRCM_RESCAL_START);
+ if (!(reg & BRCM_RESCAL_START_BIT)) {
+ dev_err(rst->dev, "failed to start SATA/PCIe rescal\n");
+ return -EIO;
+ }
+
+ ret = readl_poll_timeout(base + BRCM_RESCAL_STATUS, reg,
+ (reg & BRCM_RESCAL_STATUS_BIT), 100);
+ if (ret) {
+ dev_err(rst->dev, "time out on SATA/PCIe rescal\n");
+ return ret;
+ }
+
+ reg = readl(base + BRCM_RESCAL_START);
+ writel(reg & ~BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
+
+ dev_dbg(rst->dev, "SATA/PCIe rescal success\n");
+ return 0;
+}
+
+/* A dummy function - deassert/reset does all the work */
+static int brcm_rescal_reset_assert(struct reset_ctl *rst)
+{
+ return 0;
+}
+
+static int brcm_rescal_reset_xlate(struct reset_ctl *reset_ctl,
+ struct ofnode_phandle_args *args)
+{
+ /* This is needed if #reset-cells == 0. */
+ return 0;
+}
+
+static const struct reset_ops brcm_rescal_reset_ops = {
+ .rst_deassert = brcm_rescal_reset_set,
+ .rst_assert = brcm_rescal_reset_assert,
+ .of_xlate = brcm_rescal_reset_xlate,
+};
+
+static int brcm_rescal_reset_probe(struct udevice *dev)
+{
+ struct brcm_rescal_reset *data = dev_get_priv(dev);
+
+ data->base = dev_remap_addr(dev);
+ if (!data->base)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct udevice_id brcm_rescal_reset_of_match[] = {
+ {.compatible = "brcm,bcm7216-pcie-sata-rescal"},
+ {},
+};
+
+U_BOOT_DRIVER(brcmstb_reset_rescal) = {
+ .name = "brcmstb-reset-rescal",
+ .id = UCLASS_RESET,
+ .of_match = brcm_rescal_reset_of_match,
+ .ops = &brcm_rescal_reset_ops,
+ .probe = brcm_rescal_reset_probe,
+ .priv_auto = sizeof(struct brcm_rescal_reset),
+};
diff --git a/drivers/reset/reset-brcmstb.c b/drivers/reset/reset-brcmstb.c
new file mode 100644
index 00000000000..7861f7c9baf
--- /dev/null
+++ b/drivers/reset/reset-brcmstb.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Broadcom STB generic reset controller
+ *
+ * Copyright (C) 2024 EPAM Systems
+ *
+ * Moved from linux kernel:
+ * Author: Florian Fainelli <[email protected]>
+ * Copyright (C) 2018 Broadcom
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <errno.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <log.h>
+#include <malloc.h>
+#include <reset-uclass.h>
+
+struct brcmstb_reset {
+ void __iomem *base;
+};
+
+#define SW_INIT_SET 0x00
+#define SW_INIT_CLEAR 0x04
+#define SW_INIT_STATUS 0x08
+
+#define SW_INIT_BIT(id) BIT((id) & 0x1f)
+#define SW_INIT_BANK(id) ((id) >> 5)
+
+#define usleep_range(a, b) udelay((b))
+
+/* A full bank contains extra registers that we are not utilizing but still
+ * qualify as a single bank.
+ */
+#define SW_INIT_BANK_SIZE 0x18
+
+static int brcmstb_reset_assert(struct reset_ctl *rst)
+{
+ unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
+ struct brcmstb_reset *priv = dev_get_priv(rst->dev);
+
+ writel_relaxed(SW_INIT_BIT(rst->id), priv->base + off + SW_INIT_SET);
+ return 0;
+}
+
+static int brcmstb_reset_deassert(struct reset_ctl *rst)
+{
+ unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
+ struct brcmstb_reset *priv = dev_get_priv(rst->dev);
+
+ writel_relaxed(SW_INIT_BIT(rst->id), priv->base + off + SW_INIT_CLEAR);
+ /* Maximum reset delay after de-asserting a line and seeing block
+ * operation is typically 14us for the worst case, build some slack
+ * here.
+ */
+ usleep_range(100, 200);
+ return 0;
+}
+
+static int brcmstb_reset_status(struct reset_ctl *rst)
+{
+ unsigned int off = SW_INIT_BANK(rst->id) * SW_INIT_BANK_SIZE;
+ struct brcmstb_reset *priv = dev_get_priv(rst->dev);
+
+ return readl_relaxed(priv->base + off + SW_INIT_STATUS) &
+ SW_INIT_BIT(rst->id);
+}
+
+struct reset_ops brcmstb_reset_reset_ops = {
+ .rst_assert = brcmstb_reset_assert,
+ .rst_deassert = brcmstb_reset_deassert,
+ .rst_status = brcmstb_reset_status};
+
+static int brcmstb_reset_probe(struct udevice *dev)
+{
+ struct brcmstb_reset *priv = dev_get_priv(dev);
+
+ priv->base = dev_remap_addr(dev);
+ if (!priv->base)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct udevice_id brcmstb_reset_ids[] = {
+ {.compatible = "brcm,brcmstb-reset"}, {/* sentinel */}};
+
+U_BOOT_DRIVER(brcmstb_reset) = {
+ .name = "brcmstb-reset",
+ .id = UCLASS_RESET,
+ .of_match = brcmstb_reset_ids,
+ .ops = &brcmstb_reset_reset_ops,
+ .probe = brcmstb_reset_probe,
+ .priv_auto = sizeof(struct brcmstb_reset),
+};
diff --git a/drivers/reset/reset-dra7.c b/drivers/reset/reset-dra7.c
index 2f0ec4c042f..6b570d87d23 100644
--- a/drivers/reset/reset-dra7.c
+++ b/drivers/reset/reset-dra7.c
@@ -51,7 +51,7 @@ static int dra7_reset_assert(struct reset_ctl *reset_ctl)
return 0;
}
-struct reset_ops dra7_reset_ops = {
+static const struct reset_ops dra7_reset_ops = {
.rst_assert = dra7_reset_assert,
.rst_deassert = dra7_reset_deassert,
};
diff --git a/drivers/reset/reset-mediatek.c b/drivers/reset/reset-mediatek.c
index 4b3afab92ea..66bcf7c29b6 100644
--- a/drivers/reset/reset-mediatek.c
+++ b/drivers/reset/reset-mediatek.c
@@ -47,7 +47,7 @@ static int mediatek_reset_deassert(struct reset_ctl *reset_ctl)
priv->regofs + ((id / 32) << 2), BIT(id % 32), 0);
}
-struct reset_ops mediatek_reset_ops = {
+static const struct reset_ops mediatek_reset_ops = {
.rst_assert = mediatek_reset_assert,
.rst_deassert = mediatek_reset_deassert,
};
diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c
index 6337cdaaffa..8c27563ce23 100644
--- a/drivers/reset/reset-meson.c
+++ b/drivers/reset/reset-meson.c
@@ -66,7 +66,7 @@ static int meson_reset_deassert(struct reset_ctl *reset_ctl)
return meson_reset_level(reset_ctl, false);
}
-struct reset_ops meson_reset_ops = {
+static const struct reset_ops meson_reset_ops = {
.request = meson_reset_request,
.rst_assert = meson_reset_assert,
.rst_deassert = meson_reset_deassert,
diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c
index a3b85a42250..66b541f09e6 100644
--- a/drivers/reset/reset-npcm.c
+++ b/drivers/reset/reset-npcm.c
@@ -126,7 +126,7 @@ static const struct udevice_id npcm_reset_ids[] = {
{ }
};
-struct reset_ops npcm_reset_ops = {
+static const struct reset_ops npcm_reset_ops = {
.request = npcm_reset_request,
.rfree = npcm_reset_free,
.rst_assert = npcm_reset_assert,
diff --git a/drivers/reset/reset-raspberrypi.c b/drivers/reset/reset-raspberrypi.c
index 1792f0813f7..73acd301e3d 100644
--- a/drivers/reset/reset-raspberrypi.c
+++ b/drivers/reset/reset-raspberrypi.c
@@ -28,7 +28,7 @@ static int raspberrypi_reset_assert(struct reset_ctl *reset_ctl)
}
}
-struct reset_ops raspberrypi_reset_ops = {
+static const struct reset_ops raspberrypi_reset_ops = {
.request = raspberrypi_reset_request,
.rst_assert = raspberrypi_reset_assert,
};
diff --git a/drivers/reset/reset-spacemit-k1.c b/drivers/reset/reset-spacemit-k1.c
deleted file mode 100644
index 613e002fc4f..00000000000
--- a/drivers/reset/reset-spacemit-k1.c
+++ /dev/null
@@ -1,548 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2022 Spacemit Inc.
- * Copyright (C) 2025 Huan Zhou <[email protected]>
- */
-
-#include <asm/io.h>
-#include <config.h>
-#include <dm.h>
-#include <dm/device_compat.h>
-#include <dm/device-internal.h>
-#include <dm/lists.h>
-#include <dt-bindings/reset/spacemit-k1-reset.h>
-#include <linux/bitops.h>
-#include <reset-uclass.h>
-
-/* APBC register offset */
-#define APBC_UART1_CLK_RST 0x0
-#define APBC_UART2_CLK_RST 0x4
-#define APBC_GPIO_CLK_RST 0x8
-#define APBC_PWM0_CLK_RST 0xc
-#define APBC_PWM1_CLK_RST 0x10
-#define APBC_PWM2_CLK_RST 0x14
-#define APBC_PWM3_CLK_RST 0x18
-#define APBC_TWSI8_CLK_RST 0x20
-#define APBC_UART3_CLK_RST 0x24
-#define APBC_RTC_CLK_RST 0x28
-#define APBC_TWSI0_CLK_RST 0x2c
-#define APBC_TWSI1_CLK_RST 0x30
-#define APBC_TIMERS1_CLK_RST 0x34
-#define APBC_TWSI2_CLK_RST 0x38
-#define APBC_AIB_CLK_RST 0x3c
-#define APBC_TWSI4_CLK_RST 0x40
-#define APBC_TIMERS2_CLK_RST 0x44
-#define APBC_ONEWIRE_CLK_RST 0x48
-#define APBC_TWSI5_CLK_RST 0x4c
-#define APBC_DRO_CLK_RST 0x58
-#define APBC_IR_CLK_RST 0x5c
-#define APBC_TWSI6_CLK_RST 0x60
-#define APBC_TWSI7_CLK_RST 0x68
-#define APBC_TSEN_CLK_RST 0x6c
-
-#define APBC_UART4_CLK_RST 0x70
-#define APBC_UART5_CLK_RST 0x74
-#define APBC_UART6_CLK_RST 0x78
-#define APBC_SSP3_CLK_RST 0x7c
-
-#define APBC_SSPA0_CLK_RST 0x80
-#define APBC_SSPA1_CLK_RST 0x84
-
-#define APBC_IPC_AP2AUD_CLK_RST 0x90
-#define APBC_UART7_CLK_RST 0x94
-#define APBC_UART8_CLK_RST 0x98
-#define APBC_UART9_CLK_RST 0x9c
-
-#define APBC_CAN0_CLK_RST 0xa0
-#define APBC_PWM4_CLK_RST 0xa8
-#define APBC_PWM5_CLK_RST 0xac
-#define APBC_PWM6_CLK_RST 0xb0
-#define APBC_PWM7_CLK_RST 0xb4
-#define APBC_PWM8_CLK_RST 0xb8
-#define APBC_PWM9_CLK_RST 0xbc
-#define APBC_PWM10_CLK_RST 0xc0
-#define APBC_PWM11_CLK_RST 0xc4
-#define APBC_PWM12_CLK_RST 0xc8
-#define APBC_PWM13_CLK_RST 0xcc
-#define APBC_PWM14_CLK_RST 0xd0
-#define APBC_PWM15_CLK_RST 0xd4
-#define APBC_PWM16_CLK_RST 0xd8
-#define APBC_PWM17_CLK_RST 0xdc
-#define APBC_PWM18_CLK_RST 0xe0
-#define APBC_PWM19_CLK_RST 0xe4
-/* end of APBC register offset */
-
-/* MPMU register offset */
-#define MPMU_WDTPCR 0x200
-/* end of MPMU register offset */
-
-/* APMU register offset */
-#define APMU_JPG_CLK_RES_CTRL 0x20
-#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24
-#define APMU_ISP_CLK_RES_CTRL 0x38
-#define APMU_LCD_CLK_RES_CTRL1 0x44
-#define APMU_LCD_SPI_CLK_RES_CTRL 0x48
-#define APMU_LCD_CLK_RES_CTRL2 0x4c
-#define APMU_CCIC_CLK_RES_CTRL 0x50
-#define APMU_SDH0_CLK_RES_CTRL 0x54
-#define APMU_SDH1_CLK_RES_CTRL 0x58
-#define APMU_USB_CLK_RES_CTRL 0x5c
-#define APMU_QSPI_CLK_RES_CTRL 0x60
-#define APMU_USB_CLK_RES_CTRL 0x5c
-#define APMU_DMA_CLK_RES_CTRL 0x64
-#define APMU_AES_CLK_RES_CTRL 0x68
-#define APMU_VPU_CLK_RES_CTRL 0xa4
-#define APMU_GPU_CLK_RES_CTRL 0xcc
-#define APMU_SDH2_CLK_RES_CTRL 0xe0
-#define APMU_PMUA_MC_CTRL 0xe8
-#define APMU_PMU_CC2_AP 0x100
-#define APMU_PMUA_EM_CLK_RES_CTRL 0x104
-
-#define APMU_AUDIO_CLK_RES_CTRL 0x14c
-#define APMU_HDMI_CLK_RES_CTRL 0x1B8
-
-#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc
-#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4
-#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc
-
-#define APMU_EMAC0_CLK_RES_CTRL 0x3e4
-#define APMU_EMAC1_CLK_RES_CTRL 0x3ec
-/* end of APMU register offset */
-
-/* APBC2 register offset */
-#define APBC2_UART1_CLK_RST 0x00
-#define APBC2_SSP2_CLK_RST 0x04
-#define APBC2_TWSI3_CLK_RST 0x08
-#define APBC2_RTC_CLK_RST 0x0c
-#define APBC2_TIMERS0_CLK_RST 0x10
-#define APBC2_KPC_CLK_RST 0x14
-#define APBC2_GPIO_CLK_RST 0x1c
-/* end of APBC2 register offset */
-
-enum spacemit_reset_base_type {
- RST_BASE_TYPE_MPMU = 0,
- RST_BASE_TYPE_APMU = 1,
- RST_BASE_TYPE_APBC = 2,
- RST_BASE_TYPE_APBS = 3,
- RST_BASE_TYPE_CIU = 4,
- RST_BASE_TYPE_DCIU = 5,
- RST_BASE_TYPE_DDRC = 6,
- RST_BASE_TYPE_AUDC = 7,
- RST_BASE_TYPE_APBC2 = 8,
-};
-
-struct spacemit_reset_signal {
- u32 offset;
- u32 mask;
- u32 deassert_val;
- u32 assert_val;
- enum spacemit_reset_base_type type;
-};
-
-struct spacemit_reset_base {
- void __iomem *mpmu_base;
- void __iomem *apmu_base;
- void __iomem *apbc_base;
- void __iomem *apbs_base;
- void __iomem *ciu_base;
- void __iomem *dciu_base;
- void __iomem *ddrc_base;
- void __iomem *audio_ctrl_base;
- void __iomem *apbc2_base;
-};
-
-struct spacemit_reset {
- struct spacemit_reset_base io_base;
- const struct spacemit_reset_signal *signals;
-};
-
-enum {
- RESET_TWSI6_SPL = 0,
- RESET_TWSI8_SPL,
- RESET_SDH_AXI_SPL,
- RESET_SDH0_SPL,
- RESET_USB_AXI_SPL,
- RESET_USBP1_AXI_SPL,
- RESET_USB3_0_SPL,
- RESET_QSPI_SPL,
- RESET_QSPI_BUS_SPL,
- RESET_AES_SPL,
- RESET_SDH2_SPL,
- RESET_NUMBER_SPL
-};
-
-static const struct spacemit_reset_signal
- k1_reset_signals[RESET_NUMBER] = {
- [RESET_UART1] = { APBC_UART1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART2] = { APBC_UART2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_GPIO] = { APBC_GPIO_CLK_RST, BIT(2), 0,
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM0] = { APBC_PWM0_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM1] = { APBC_PWM1_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM2] = { APBC_PWM2_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM3] = { APBC_PWM3_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM4] = { APBC_PWM4_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM5] = { APBC_PWM5_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM6] = { APBC_PWM6_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM7] = { APBC_PWM7_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM8] = { APBC_PWM8_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM9] = { APBC_PWM9_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM10] = { APBC_PWM10_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM11] = { APBC_PWM11_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM12] = { APBC_PWM12_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM13] = { APBC_PWM13_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM14] = { APBC_PWM14_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM15] = { APBC_PWM15_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM16] = { APBC_PWM16_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM17] = { APBC_PWM17_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM18] = { APBC_PWM18_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_PWM19] = { APBC_PWM19_CLK_RST,
- BIT(2) | BIT(0),
- BIT(0),
- BIT(2),
- RST_BASE_TYPE_APBC },
- [RESET_SSP3] = { APBC_SSP3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART3] = { APBC_UART3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_RTC] = { APBC_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI0] = { APBC_TWSI0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TIMERS1] = { APBC_TIMERS1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_AIB] = { APBC_AIB_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TIMERS2] = { APBC_TIMERS2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_ONEWIRE] = { APBC_ONEWIRE_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_SSPA0] = { APBC_SSPA0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_SSPA1] = { APBC_SSPA1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_DRO] = { APBC_DRO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_IR] = { APBC_IR_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI1] = { APBC_TWSI1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TSEN] = { APBC_TSEN_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI2] = { APBC_TWSI2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI4] = { APBC_TWSI4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI5] = { APBC_TWSI5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI6] = { APBC_TWSI6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI7] = { APBC_TWSI7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_TWSI8] = { APBC_TWSI8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_IPC_AP2AUD] = { APBC_IPC_AP2AUD_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART4] = { APBC_UART4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART5] = { APBC_UART5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART6] = { APBC_UART6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART7] = { APBC_UART7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART8] = { APBC_UART8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_UART9] = { APBC_UART9_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- [RESET_CAN0] = { APBC_CAN0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
- /* MPMU */
- [RESET_WDT] = { MPMU_WDTPCR, BIT(2), 0, BIT(2), RST_BASE_TYPE_MPMU },
- /* APMU */
- [RESET_JPG] = { APMU_JPG_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_CSI] = { APMU_CSI_CCIC2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_CCIC2_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL,
- BIT(2),
- BIT(2),
- 0,
- RST_BASE_TYPE_APMU },
- [RESET_CCIC3_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL,
- BIT(29),
- BIT(29),
- 0,
- RST_BASE_TYPE_APMU },
- [RESET_ISP] = { APMU_ISP_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_ISP_AHB] = { APMU_ISP_CLK_RES_CTRL, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU },
- [RESET_ISP_CI] = { APMU_ISP_CLK_RES_CTRL, BIT(16), BIT(16), 0, RST_BASE_TYPE_APMU },
- [RESET_ISP_CPP] = { APMU_ISP_CLK_RES_CTRL, BIT(27), BIT(27), 0, RST_BASE_TYPE_APMU },
- [RESET_LCD] = { APMU_LCD_CLK_RES_CTRL1, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
- [RESET_DSI_ESC] = { APMU_LCD_CLK_RES_CTRL1, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU },
- [RESET_V2D] = { APMU_LCD_CLK_RES_CTRL1, BIT(27), BIT(27), 0, RST_BASE_TYPE_APMU },
- [RESET_MIPI] = { APMU_LCD_CLK_RES_CTRL1, BIT(15), BIT(15), 0, RST_BASE_TYPE_APMU },
- [RESET_LCD_SPI] = { APMU_LCD_SPI_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_LCD_SPI_BUS] = { APMU_LCD_SPI_CLK_RES_CTRL,
- BIT(4),
- BIT(4),
- 0,
- RST_BASE_TYPE_APMU },
- [RESET_LCD_SPI_HBUS] = { APMU_LCD_SPI_CLK_RES_CTRL,
- BIT(2),
- BIT(2),
- 0,
- RST_BASE_TYPE_APMU },
- [RESET_LCD_MCLK] = { APMU_LCD_CLK_RES_CTRL2, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU },
- [RESET_CCIC_4X] = { APMU_CCIC_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_CCIC1_PHY] = { APMU_CCIC_CLK_RES_CTRL, BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU },
- [RESET_SDH_AXI] = { APMU_SDH0_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_SDH0] = { APMU_SDH0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_SDH1] = { APMU_SDH1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_USB_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_USBP1_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
- [RESET_USB3_0] = { APMU_USB_CLK_RES_CTRL,
- BIT(9) | BIT(10) | BIT(11),
- BIT(9) | BIT(10) | BIT(11),
- 0,
- RST_BASE_TYPE_APMU },
- [RESET_QSPI] = { APMU_QSPI_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_QSPI_BUS] = { APMU_QSPI_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_DMA] = { APMU_DMA_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_AES] = { APMU_AES_CLK_RES_CTRL, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
- [RESET_VPU] = { APMU_VPU_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_GPU] = { APMU_GPU_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_SDH2] = { APMU_SDH2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_MC] = { APMU_PMUA_MC_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_EM_AXI] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
- [RESET_EM] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_AUDIO_SYS] = { APMU_AUDIO_CLK_RES_CTRL,
- BIT(0) | BIT(2) | BIT(3),
- BIT(0) | BIT(2) | BIT(3),
- 0,
- RST_BASE_TYPE_APMU },
- [RESET_HDMI] = { APMU_HDMI_CLK_RES_CTRL, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU },
- [RESET_PCIE0] = { APMU_PCIE_CLK_RES_CTRL_0,
- BIT(3) | BIT(4) | BIT(5) | BIT(8),
- BIT(3) | BIT(4) | BIT(5),
- BIT(8),
- RST_BASE_TYPE_APMU },
- [RESET_PCIE1] = { APMU_PCIE_CLK_RES_CTRL_1,
- BIT(3) | BIT(4) | BIT(5) | BIT(8),
- BIT(3) | BIT(4) | BIT(5),
- BIT(8),
- RST_BASE_TYPE_APMU },
- [RESET_PCIE2] = { APMU_PCIE_CLK_RES_CTRL_2, 0x138, 0x38, 0x100, RST_BASE_TYPE_APMU },
- [RESET_EMAC0] = { APMU_EMAC0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_EMAC1] = { APMU_EMAC1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
- [RESET_SEC_UART1] = { APBC2_UART1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
- [RESET_SEC_SSP2] = { APBC2_SSP2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
- [RESET_SEC_TWSI3] = { APBC2_TWSI3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
- [RESET_SEC_RTC] = { APBC2_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
- [RESET_SEC_TIMERS0] = { APBC2_TIMERS0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
- [RESET_SEC_KPC] = { APBC2_KPC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
- [RESET_SEC_GPIO] = { APBC2_GPIO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
- };
-
-static u32 spacemit_reset_read(struct spacemit_reset *reset, u32 id)
-{
- void __iomem *base;
-
- switch (reset->signals[id].type) {
- case RST_BASE_TYPE_APMU:
- base = reset->io_base.apmu_base;
- break;
- case RST_BASE_TYPE_APBC:
- base = reset->io_base.apbc_base;
- break;
- default:
- base = reset->io_base.apbc_base;
- break;
- }
-
- return readl(base + reset->signals[id].offset);
-}
-
-static void spacemit_reset_write(struct spacemit_reset *reset, u32 value, u32 id)
-{
- void __iomem *base;
-
- switch (reset->signals[id].type) {
- case RST_BASE_TYPE_APMU:
- base = reset->io_base.apmu_base;
- break;
- case RST_BASE_TYPE_APBC:
- base = reset->io_base.apbc_base;
- break;
- default:
- base = reset->io_base.apbc_base;
- break;
- }
-
- writel(value, base + reset->signals[id].offset);
-}
-
-static void spacemit_reset_set(struct reset_ctl *rst, u32 id, bool assert)
-{
- u32 value;
- struct spacemit_reset *reset = dev_get_priv(rst->dev);
-
- value = spacemit_reset_read(reset, id);
-
- if (assert) {
- value &= ~reset->signals[id].mask;
- value |= reset->signals[id].assert_val;
- } else {
- value &= ~reset->signals[id].mask;
- value |= reset->signals[id].deassert_val;
- }
-
- spacemit_reset_write(reset, value, id);
-}
-
-static int spacemit_reset_update(struct reset_ctl *rst, bool assert)
-{
- if (rst->id < RESET_UART1 || rst->id >= RESET_NUMBER)
- return 0;
-
- /* can not write to twsi8 */
- if (rst->id == RESET_TWSI8)
- return 0;
-
- spacemit_reset_set(rst, rst->id, assert);
- return 0;
-}
-
-static int spacemit_reset_assert(struct reset_ctl *rst)
-{
- return spacemit_reset_update(rst, true);
-}
-
-static int spacemit_reset_deassert(struct reset_ctl *rst)
-{
- return spacemit_reset_update(rst, false);
-}
-
-static int spacemit_k1_reset_probe(struct udevice *dev)
-{
- struct spacemit_reset *reset = dev_get_priv(dev);
-
- reset->io_base.mpmu_base = (void *)dev_remap_addr_index(dev, 0);
- if (!reset->io_base.mpmu_base) {
- pr_err("failed to map mpmu registers\n");
- goto out;
- }
-
- reset->io_base.apmu_base = (void *)dev_remap_addr_index(dev, 1);
- if (!reset->io_base.apmu_base) {
- pr_err("failed to map apmu registers\n");
- goto out;
- }
-
- reset->io_base.apbc_base = (void *)dev_remap_addr_index(dev, 2);
- if (!reset->io_base.apbc_base) {
- pr_err("failed to map apbc registers\n");
- goto out;
- }
-
- reset->io_base.apbs_base = (void *)dev_remap_addr_index(dev, 3);
- if (!reset->io_base.apbs_base) {
- pr_err("failed to map apbs registers\n");
- goto out;
- }
-
- reset->io_base.ciu_base = (void *)dev_remap_addr_index(dev, 4);
- if (!reset->io_base.ciu_base) {
- pr_err("failed to map ciu registers\n");
- goto out;
- }
-
- reset->io_base.dciu_base = (void *)dev_remap_addr_index(dev, 5);
- if (!reset->io_base.dciu_base) {
- pr_err("failed to map dragon ciu registers\n");
- goto out;
- }
-
- reset->io_base.ddrc_base = (void *)dev_remap_addr_index(dev, 6);
- if (!reset->io_base.ddrc_base) {
- pr_err("failed to map ddrc registers\n");
- goto out;
- }
-
- reset->io_base.apbc2_base = (void *)dev_remap_addr_index(dev, 7);
- if (!reset->io_base.apbc2_base) {
- pr_err("failed to map apbc2 registers\n");
- goto out;
- }
-
- reset->signals = k1_reset_signals;
-
-out:
- return 0;
-}
-
-const struct reset_ops k1_reset_ops = {
- .rst_assert = spacemit_reset_assert,
- .rst_deassert = spacemit_reset_deassert,
-};
-
-static const struct udevice_id k1_reset_ids[] = {
- { .compatible = "spacemit,k1-reset", },
- {},
-};
-
-U_BOOT_DRIVER(k1_reset) = {
- .name = "spacemit,k1-reset",
- .id = UCLASS_RESET,
- .ops = &k1_reset_ops,
- .of_match = k1_reset_ids,
- .probe = spacemit_k1_reset_probe,
- .priv_auto = sizeof(struct spacemit_reset),
-};
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
index fd47e1f9e37..6195edd5b2f 100644
--- a/drivers/reset/reset-sunxi.c
+++ b/drivers/reset/reset-sunxi.c
@@ -67,7 +67,7 @@ static int sunxi_reset_deassert(struct reset_ctl *reset_ctl)
return sunxi_set_reset(reset_ctl, true);
}
-struct reset_ops sunxi_reset_ops = {
+static const struct reset_ops sunxi_reset_ops = {
.request = sunxi_reset_request,
.rst_assert = sunxi_reset_assert,
.rst_deassert = sunxi_reset_deassert,
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index fe4cebf54f1..c199e3e5da7 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -13,6 +13,7 @@
#include <reset-uclass.h>
#include <dm/devres.h>
#include <dm/lists.h>
+#include <linux/delay.h>
static inline struct reset_ops *reset_dev_ops(struct udevice *dev)
{
@@ -225,6 +226,39 @@ int reset_deassert_bulk(struct reset_ctl_bulk *bulk)
return 0;
}
+int reset_reset(struct reset_ctl *reset_ctl, ulong delay_us)
+{
+ struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
+ int ret;
+
+ debug("%s(reset_ctl=%p, delay_us=%lu)\n", __func__, reset_ctl,
+ delay_us);
+
+ if (ops->rst_reset)
+ return ops->rst_reset(reset_ctl, delay_us);
+
+ ret = reset_assert(reset_ctl);
+ if (ret < 0)
+ return ret;
+
+ udelay(delay_us);
+
+ return reset_deassert(reset_ctl);
+}
+
+int reset_reset_bulk(struct reset_ctl_bulk *bulk, ulong delay_us)
+{
+ int i, ret;
+
+ for (i = 0; i < bulk->count; i++) {
+ ret = reset_reset(&bulk->resets[i], delay_us);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
int reset_status(struct reset_ctl *reset_ctl)
{
struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
index d04e8eef3bb..2b58f3a75b4 100644
--- a/drivers/reset/reset-zynqmp.c
+++ b/drivers/reset/reset-zynqmp.c
@@ -45,6 +45,16 @@ static int zynqmp_reset_deassert(struct reset_ctl *rst)
PM_RESET_ACTION_RELEASE);
}
+static int zynqmp_reset_reset(struct reset_ctl *rst, ulong delay_us)
+{
+ struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+ dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id);
+
+ return zynqmp_pm_reset_assert(priv->reset_id + rst->id,
+ PM_RESET_ACTION_PULSE);
+}
+
static int zynqmp_reset_request(struct reset_ctl *rst)
{
struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
@@ -74,6 +84,7 @@ const struct reset_ops zynqmp_reset_ops = {
.request = zynqmp_reset_request,
.rst_assert = zynqmp_reset_assert,
.rst_deassert = zynqmp_reset_deassert,
+ .rst_reset = zynqmp_reset_reset,
};
static const struct udevice_id zynqmp_reset_ids[] = {
diff --git a/drivers/reset/sandbox-reset-test.c b/drivers/reset/sandbox-reset-test.c
index dfacb764bc7..64c205596c5 100644
--- a/drivers/reset/sandbox-reset-test.c
+++ b/drivers/reset/sandbox-reset-test.c
@@ -96,6 +96,20 @@ int sandbox_reset_test_deassert_bulk(struct udevice *dev)
return reset_deassert_bulk(sbrt->bulkp);
}
+int sandbox_reset_test_reset(struct udevice *dev)
+{
+ struct sandbox_reset_test *sbrt = dev_get_priv(dev);
+
+ return reset_reset(sbrt->ctlp, 0);
+}
+
+int sandbox_reset_test_reset_bulk(struct udevice *dev)
+{
+ struct sandbox_reset_test *sbrt = dev_get_priv(dev);
+
+ return reset_reset_bulk(sbrt->bulkp, 0);
+}
+
int sandbox_reset_test_free(struct udevice *dev)
{
struct sandbox_reset_test *sbrt = dev_get_priv(dev);
diff --git a/drivers/reset/sandbox-reset.c b/drivers/reset/sandbox-reset.c
index adf9eedcba6..12812f0f340 100644
--- a/drivers/reset/sandbox-reset.c
+++ b/drivers/reset/sandbox-reset.c
@@ -9,12 +9,14 @@
#include <reset-uclass.h>
#include <asm/io.h>
#include <asm/reset.h>
+#include <linux/delay.h>
#define SANDBOX_RESET_SIGNALS 101
struct sandbox_reset_signal {
bool asserted;
bool requested;
+ int reset_count;
};
struct sandbox_reset {
@@ -31,6 +33,7 @@ static int sandbox_reset_request(struct reset_ctl *reset_ctl)
return -EINVAL;
sbr->signals[reset_ctl->id].requested = true;
+ sbr->signals[reset_ctl->id].reset_count = 0;
return 0;
}
@@ -66,6 +69,21 @@ static int sandbox_reset_deassert(struct reset_ctl *reset_ctl)
return 0;
}
+static int sandbox_reset_reset(struct reset_ctl *reset_ctl, ulong delay_us)
+{
+ struct sandbox_reset *sbr = dev_get_priv(reset_ctl->dev);
+
+ debug("%s(reset_ctl=%p, delay_us=%lu)\n", __func__, reset_ctl,
+ delay_us);
+
+ sbr->signals[reset_ctl->id].asserted = true;
+ udelay(delay_us);
+ sbr->signals[reset_ctl->id].asserted = false;
+ sbr->signals[reset_ctl->id].reset_count++;
+
+ return 0;
+}
+
static int sandbox_reset_bind(struct udevice *dev)
{
debug("%s(dev=%p)\n", __func__, dev);
@@ -85,11 +103,12 @@ static const struct udevice_id sandbox_reset_ids[] = {
{ }
};
-struct reset_ops sandbox_reset_reset_ops = {
+static const struct reset_ops sandbox_reset_reset_ops = {
.request = sandbox_reset_request,
.rfree = sandbox_reset_free,
.rst_assert = sandbox_reset_assert,
.rst_deassert = sandbox_reset_deassert,
+ .rst_reset = sandbox_reset_reset,
};
U_BOOT_DRIVER(sandbox_reset) = {
@@ -102,6 +121,33 @@ U_BOOT_DRIVER(sandbox_reset) = {
.ops = &sandbox_reset_reset_ops,
};
+/*
+ * Second sandbox reset controller for tests: same assert/deassert
+ * behaviour as sandbox_reset, but no rst_reset so reset_reset() uses
+ * the core assert / udelay / deassert fallback (reset_count never bumps).
+ */
+static const struct udevice_id sandbox_reset_fallback_ids[] = {
+ { .compatible = "sandbox,reset-ctl-fallback-only" },
+ { }
+};
+
+static const struct reset_ops sandbox_reset_fallback_reset_ops = {
+ .request = sandbox_reset_request,
+ .rfree = sandbox_reset_free,
+ .rst_assert = sandbox_reset_assert,
+ .rst_deassert = sandbox_reset_deassert,
+};
+
+U_BOOT_DRIVER(sandbox_reset_fallback) = {
+ .name = "sandbox_reset_fallback",
+ .id = UCLASS_RESET,
+ .of_match = sandbox_reset_fallback_ids,
+ .bind = sandbox_reset_bind,
+ .probe = sandbox_reset_probe,
+ .priv_auto = sizeof(struct sandbox_reset),
+ .ops = &sandbox_reset_fallback_reset_ops,
+};
+
int sandbox_reset_query(struct udevice *dev, unsigned long id)
{
struct sandbox_reset *sbr = dev_get_priv(dev);
@@ -125,3 +171,15 @@ int sandbox_reset_is_requested(struct udevice *dev, unsigned long id)
return sbr->signals[id].requested;
}
+
+int sandbox_reset_get_count(struct udevice *dev, unsigned long id)
+{
+ struct sandbox_reset *sbr = dev_get_priv(dev);
+
+ debug("%s(dev=%p, id=%ld)\n", __func__, dev, id);
+
+ if (id >= SANDBOX_RESET_SIGNALS)
+ return -EINVAL;
+
+ return sbr->signals[id].reset_count;
+}
diff --git a/drivers/reset/spacemit/Makefile b/drivers/reset/spacemit/Makefile
new file mode 100644
index 00000000000..16722c68954
--- /dev/null
+++ b/drivers/reset/spacemit/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# SpacemiT reset drivers
+
+obj-y += reset-spacemit-k1.o
diff --git a/drivers/reset/spacemit/reset-spacemit-k1.c b/drivers/reset/spacemit/reset-spacemit-k1.c
new file mode 100644
index 00000000000..129e1cc96f1
--- /dev/null
+++ b/drivers/reset/spacemit/reset-spacemit-k1.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * SpacemiT K1 reset driver (syscon-bound).
+ *
+ * Copyright (C) 2022 Spacemit Inc.
+ * Copyright (C) 2025 Huan Zhou <[email protected]>
+ * Copyright (C) 2026 RISCstar Ltd.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/spacemit,k1-syscon.h>
+#include <linux/bitops.h>
+#include <malloc.h>
+#include <reset-uclass.h>
+#include <soc/spacemit/k1-reset.h>
+#include <soc/spacemit/k1-syscon.h>
+
+/* ===================================================================
+ * Per-syscon reset signal tables.
+ *
+ * Indexed by the kernel-side per-syscon-local IDs from
+ * <dt-bindings/clock/spacemit,k1-syscon.h>. Each entry is
+ * (offset, assert_mask, deassert_mask): bits in assert_mask are set
+ * when the reset line is asserted; bits in deassert_mask are set when
+ * deasserted; the union (assert_mask | deassert_mask) is the set of
+ * bits the controller will overwrite on each transition.
+ *
+ * Layout mirrors the kernel-side K1 reset driver.
+ * ===================================================================
+ */
+
+struct spacemit_k1_reset_data {
+ u32 offset;
+ u32 assert_mask;
+ u32 deassert_mask;
+};
+
+#define RESET_DATA(o, a, d) { \
+ .offset = (o), .assert_mask = (a), .deassert_mask = (d) \
+}
+
+static const struct spacemit_k1_reset_data k1_mpmu_resets[] = {
+ [RESET_WDT] = RESET_DATA(MPMU_WDTPCR, BIT(2), 0),
+};
+
+static const struct spacemit_k1_reset_data k1_apbc_resets[] = {
+ [RESET_UART0] = RESET_DATA(APBC_UART1_CLK_RST, BIT(2), 0),
+ [RESET_UART2] = RESET_DATA(APBC_UART2_CLK_RST, BIT(2), 0),
+ [RESET_UART3] = RESET_DATA(APBC_UART3_CLK_RST, BIT(2), 0),
+ [RESET_UART4] = RESET_DATA(APBC_UART4_CLK_RST, BIT(2), 0),
+ [RESET_UART5] = RESET_DATA(APBC_UART5_CLK_RST, BIT(2), 0),
+ [RESET_UART6] = RESET_DATA(APBC_UART6_CLK_RST, BIT(2), 0),
+ [RESET_UART7] = RESET_DATA(APBC_UART7_CLK_RST, BIT(2), 0),
+ [RESET_UART8] = RESET_DATA(APBC_UART8_CLK_RST, BIT(2), 0),
+ [RESET_UART9] = RESET_DATA(APBC_UART9_CLK_RST, BIT(2), 0),
+ [RESET_GPIO] = RESET_DATA(APBC_GPIO_CLK_RST, BIT(2), 0),
+ [RESET_PWM0] = RESET_DATA(APBC_PWM0_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM1] = RESET_DATA(APBC_PWM1_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM2] = RESET_DATA(APBC_PWM2_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM3] = RESET_DATA(APBC_PWM3_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM4] = RESET_DATA(APBC_PWM4_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM5] = RESET_DATA(APBC_PWM5_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM6] = RESET_DATA(APBC_PWM6_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM7] = RESET_DATA(APBC_PWM7_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM8] = RESET_DATA(APBC_PWM8_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM9] = RESET_DATA(APBC_PWM9_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM10] = RESET_DATA(APBC_PWM10_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM11] = RESET_DATA(APBC_PWM11_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM12] = RESET_DATA(APBC_PWM12_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM13] = RESET_DATA(APBC_PWM13_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM14] = RESET_DATA(APBC_PWM14_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM15] = RESET_DATA(APBC_PWM15_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM16] = RESET_DATA(APBC_PWM16_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM17] = RESET_DATA(APBC_PWM17_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM18] = RESET_DATA(APBC_PWM18_CLK_RST, BIT(2), BIT(0)),
+ [RESET_PWM19] = RESET_DATA(APBC_PWM19_CLK_RST, BIT(2), BIT(0)),
+ [RESET_SSP3] = RESET_DATA(APBC_SSP3_CLK_RST, BIT(2), 0),
+ [RESET_RTC] = RESET_DATA(APBC_RTC_CLK_RST, BIT(2), 0),
+ [RESET_TWSI0] = RESET_DATA(APBC_TWSI0_CLK_RST, BIT(2), 0),
+ [RESET_TWSI1] = RESET_DATA(APBC_TWSI1_CLK_RST, BIT(2), 0),
+ [RESET_TWSI2] = RESET_DATA(APBC_TWSI2_CLK_RST, BIT(2), 0),
+ [RESET_TWSI4] = RESET_DATA(APBC_TWSI4_CLK_RST, BIT(2), 0),
+ [RESET_TWSI5] = RESET_DATA(APBC_TWSI5_CLK_RST, BIT(2), 0),
+ [RESET_TWSI6] = RESET_DATA(APBC_TWSI6_CLK_RST, BIT(2), 0),
+ [RESET_TWSI7] = RESET_DATA(APBC_TWSI7_CLK_RST, BIT(2), 0),
+ [RESET_TWSI8] = RESET_DATA(APBC_TWSI8_CLK_RST, BIT(2), 0),
+ [RESET_TIMERS1] = RESET_DATA(APBC_TIMERS1_CLK_RST, BIT(2), 0),
+ [RESET_TIMERS2] = RESET_DATA(APBC_TIMERS2_CLK_RST, BIT(2), 0),
+ [RESET_AIB] = RESET_DATA(APBC_AIB_CLK_RST, BIT(2), 0),
+ [RESET_ONEWIRE] = RESET_DATA(APBC_ONEWIRE_CLK_RST, BIT(2), 0),
+ [RESET_SSPA0] = RESET_DATA(APBC_SSPA0_CLK_RST, BIT(2), 0),
+ [RESET_SSPA1] = RESET_DATA(APBC_SSPA1_CLK_RST, BIT(2), 0),
+ [RESET_DRO] = RESET_DATA(APBC_DRO_CLK_RST, BIT(2), 0),
+ [RESET_IR] = RESET_DATA(APBC_IR_CLK_RST, BIT(2), 0),
+ [RESET_TSEN] = RESET_DATA(APBC_TSEN_CLK_RST, BIT(2), 0),
+ [RESET_IPC_AP2AUD] = RESET_DATA(APBC_IPC_AP2AUD_CLK_RST, BIT(2), 0),
+ [RESET_CAN0] = RESET_DATA(APBC_CAN0_CLK_RST, BIT(2), 0),
+};
+
+static const struct spacemit_k1_reset_data k1_apmu_resets[] = {
+ [RESET_CCIC_4X] = RESET_DATA(APMU_CCIC_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_CCIC1_PHY] = RESET_DATA(APMU_CCIC_CLK_RES_CTRL, 0, BIT(2)),
+ [RESET_SDH_AXI] = RESET_DATA(APMU_SDH0_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_SDH0] = RESET_DATA(APMU_SDH0_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_SDH1] = RESET_DATA(APMU_SDH1_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_SDH2] = RESET_DATA(APMU_SDH2_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_USBP1_AXI] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(4)),
+ [RESET_USB_AXI] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_USB30_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(9)),
+ [RESET_USB30_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(10)),
+ [RESET_USB30_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(11)),
+ [RESET_QSPI] = RESET_DATA(APMU_QSPI_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_QSPI_BUS] = RESET_DATA(APMU_QSPI_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_DMA] = RESET_DATA(APMU_DMA_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_AES] = RESET_DATA(APMU_AES_CLK_RES_CTRL, 0, BIT(4)),
+ [RESET_VPU] = RESET_DATA(APMU_VPU_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_GPU] = RESET_DATA(APMU_GPU_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_EMMC] = RESET_DATA(APMU_PMUA_EM_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_EMMC_X] = RESET_DATA(APMU_PMUA_EM_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_AUDIO_SYS] = RESET_DATA(APMU_AUDIO_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_AUDIO_MCU] = RESET_DATA(APMU_AUDIO_CLK_RES_CTRL, 0, BIT(2)),
+ [RESET_AUDIO_APMU] = RESET_DATA(APMU_AUDIO_CLK_RES_CTRL, 0, BIT(3)),
+ [RESET_HDMI] = RESET_DATA(APMU_HDMI_CLK_RES_CTRL, 0, BIT(9)),
+ [RESET_PCIE0_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, 0, BIT(3)),
+ [RESET_PCIE0_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, 0, BIT(4)),
+ [RESET_PCIE0_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, 0, BIT(5)),
+ [RESET_PCIE0_GLOBAL] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_0, BIT(8), 0),
+ [RESET_PCIE1_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, 0, BIT(3)),
+ [RESET_PCIE1_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, 0, BIT(4)),
+ [RESET_PCIE1_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, 0, BIT(5)),
+ [RESET_PCIE1_GLOBAL] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_1, BIT(8), 0),
+ [RESET_PCIE2_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, 0, BIT(3)),
+ [RESET_PCIE2_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, 0, BIT(4)),
+ [RESET_PCIE2_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, 0, BIT(5)),
+ [RESET_PCIE2_GLOBAL] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_2, BIT(8), 0),
+ [RESET_EMAC0] = RESET_DATA(APMU_EMAC0_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_EMAC1] = RESET_DATA(APMU_EMAC1_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_JPG] = RESET_DATA(APMU_JPG_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_CCIC2PHY] = RESET_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL, 0, BIT(2)),
+ [RESET_CCIC3PHY] = RESET_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL, 0, BIT(29)),
+ [RESET_CSI] = RESET_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL, 0, BIT(1)),
+ [RESET_ISP] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(0)),
+ [RESET_ISP_CPP] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(27)),
+ [RESET_ISP_BUS] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(3)),
+ [RESET_ISP_CI] = RESET_DATA(APMU_ISP_CLK_RES_CTRL, 0, BIT(16)),
+ [RESET_DPU_MCLK] = RESET_DATA(APMU_LCD_CLK_RES_CTRL2, 0, BIT(9)),
+ [RESET_DPU_ESC] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(3)),
+ [RESET_DPU_HCLK] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(4)),
+ [RESET_DPU_SPIBUS] = RESET_DATA(APMU_LCD_SPI_CLK_RES_CTRL, 0, BIT(4)),
+ [RESET_DPU_SPI_HBUS] = RESET_DATA(APMU_LCD_SPI_CLK_RES_CTRL, 0, BIT(2)),
+ [RESET_V2D] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(27)),
+ [RESET_MIPI] = RESET_DATA(APMU_LCD_CLK_RES_CTRL1, 0, BIT(15)),
+ [RESET_MC] = RESET_DATA(APMU_PMUA_MC_CTRL, 0, BIT(0)),
+};
+
+static const struct spacemit_k1_reset_data k1_apbc2_resets[] = {
+ [RESET_APBC2_UART1] = RESET_DATA(APBC2_UART1_CLK_RST, BIT(2), 0),
+ [RESET_APBC2_SSP2] = RESET_DATA(APBC2_SSP2_CLK_RST, BIT(2), 0),
+ [RESET_APBC2_TWSI3] = RESET_DATA(APBC2_TWSI3_CLK_RST, BIT(2), 0),
+ [RESET_APBC2_RTC] = RESET_DATA(APBC2_RTC_CLK_RST, BIT(2), 0),
+ [RESET_APBC2_TIMERS0] = RESET_DATA(APBC2_TIMERS0_CLK_RST, BIT(2), 0),
+ [RESET_APBC2_KPC] = RESET_DATA(APBC2_KPC_CLK_RST, BIT(2), 0),
+ [RESET_APBC2_GPIO] = RESET_DATA(APBC2_GPIO_CLK_RST, BIT(2), 0),
+};
+
+/* ===================================================================
+ * Driver
+ * ===================================================================
+ */
+
+struct spacemit_k1_reset_priv {
+ void __iomem *base;
+ const struct spacemit_k1_reset_data *table;
+ size_t table_size;
+};
+
+static int spacemit_k1_reset_xfer(struct reset_ctl *rst, bool assert)
+{
+ struct spacemit_k1_reset_priv *priv = dev_get_priv(rst->dev);
+ const struct spacemit_k1_reset_data *e;
+ u32 v;
+
+ if (rst->id >= priv->table_size)
+ return -EINVAL;
+
+ e = &priv->table[rst->id];
+ if (e->assert_mask == 0 && e->deassert_mask == 0)
+ return -EINVAL; /* not owned by this syscon */
+
+ v = readl(priv->base + e->offset);
+ v &= ~(e->assert_mask | e->deassert_mask);
+ v |= assert ? e->assert_mask : e->deassert_mask;
+ writel(v, priv->base + e->offset);
+
+ return 0;
+}
+
+static int spacemit_k1_reset_assert(struct reset_ctl *rst)
+{
+ return spacemit_k1_reset_xfer(rst, true);
+}
+
+static int spacemit_k1_reset_deassert(struct reset_ctl *rst)
+{
+ return spacemit_k1_reset_xfer(rst, false);
+}
+
+static int spacemit_k1_reset_request(struct reset_ctl *rst)
+{
+ struct spacemit_k1_reset_priv *priv = dev_get_priv(rst->dev);
+
+ return rst->id < priv->table_size ? 0 : -EINVAL;
+}
+
+static const struct reset_ops spacemit_k1_reset_ops = {
+ .request = spacemit_k1_reset_request,
+ .rst_assert = spacemit_k1_reset_assert,
+ .rst_deassert = spacemit_k1_reset_deassert,
+};
+
+static int spacemit_k1_reset_probe(struct udevice *dev)
+{
+ struct spacemit_k1_reset_priv *priv = dev_get_priv(dev);
+
+ priv->base = (void __iomem *)dev_remap_addr(dev);
+ if (!priv->base)
+ return -ENODEV;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(spacemit_k1_reset) = {
+ .name = "spacemit_k1_reset",
+ .id = UCLASS_RESET,
+ .ops = &spacemit_k1_reset_ops,
+ .probe = spacemit_k1_reset_probe,
+ .priv_auto = sizeof(struct spacemit_k1_reset_priv),
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+int spacemit_k1_reset_bind(struct udevice *parent,
+ enum spacemit_k1_reset_syscon syscon)
+{
+ struct spacemit_k1_reset_priv *priv;
+ struct udevice *rst_dev;
+ const struct spacemit_k1_reset_data *table;
+ size_t table_size;
+ int ret;
+
+ switch (syscon) {
+ case SPACEMIT_K1_RESET_MPMU:
+ table = k1_mpmu_resets;
+ table_size = ARRAY_SIZE(k1_mpmu_resets);
+ break;
+ case SPACEMIT_K1_RESET_APMU:
+ table = k1_apmu_resets;
+ table_size = ARRAY_SIZE(k1_apmu_resets);
+ break;
+ case SPACEMIT_K1_RESET_APBC:
+ table = k1_apbc_resets;
+ table_size = ARRAY_SIZE(k1_apbc_resets);
+ break;
+ case SPACEMIT_K1_RESET_APBC2:
+ table = k1_apbc2_resets;
+ table_size = ARRAY_SIZE(k1_apbc2_resets);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = device_bind_driver_to_node(parent, "spacemit_k1_reset", "reset",
+ dev_ofnode(parent), &rst_dev);
+ if (ret)
+ return ret;
+
+ priv = malloc(sizeof(*priv));
+ if (!priv) {
+ device_unbind(rst_dev);
+ return -ENOMEM;
+ }
+ priv->table = table;
+ priv->table_size = table_size;
+ dev_set_priv(rst_dev, priv);
+
+ return 0;
+}
diff --git a/drivers/reset/sti-reset.c b/drivers/reset/sti-reset.c
index 412a0c5b452..37a37a72fd3 100644
--- a/drivers/reset/sti-reset.c
+++ b/drivers/reset/sti-reset.c
@@ -290,7 +290,7 @@ static int sti_reset_deassert(struct reset_ctl *reset_ctl)
return sti_reset_program_hw(reset_ctl, false);
}
-struct reset_ops sti_reset_ops = {
+static const struct reset_ops sti_reset_ops = {
.rst_assert = sti_reset_assert,
.rst_deassert = sti_reset_deassert,
};
diff --git a/drivers/reset/tegra-car-reset.c b/drivers/reset/tegra-car-reset.c
index e3ecc8d3735..63f148cf3d9 100644
--- a/drivers/reset/tegra-car-reset.c
+++ b/drivers/reset/tegra-car-reset.c
@@ -42,7 +42,7 @@ static int tegra_car_reset_deassert(struct reset_ctl *reset_ctl)
return 0;
}
-struct reset_ops tegra_car_reset_ops = {
+static const struct reset_ops tegra_car_reset_ops = {
.request = tegra_car_reset_request,
.rst_assert = tegra_car_reset_assert,
.rst_deassert = tegra_car_reset_deassert,
diff --git a/drivers/reset/tegra186-reset.c b/drivers/reset/tegra186-reset.c
index 89624227c29..1d8f40acaef 100644
--- a/drivers/reset/tegra186-reset.c
+++ b/drivers/reset/tegra186-reset.c
@@ -43,7 +43,7 @@ static int tegra186_reset_deassert(struct reset_ctl *reset_ctl)
return tegra186_reset_common(reset_ctl, CMD_RESET_DEASSERT);
}
-struct reset_ops tegra186_reset_ops = {
+static const struct reset_ops tegra186_reset_ops = {
.rst_assert = tegra186_reset_assert,
.rst_deassert = tegra186_reset_deassert,
};
diff --git a/drivers/rng/iproc_rng200.c b/drivers/rng/iproc_rng200.c
index 4c49aa9e444..aa211df28cd 100644
--- a/drivers/rng/iproc_rng200.c
+++ b/drivers/rng/iproc_rng200.c
@@ -155,7 +155,7 @@ static int iproc_rng200_of_to_plat(struct udevice *dev)
{
struct iproc_rng200_plat *pdata = dev_get_plat(dev);
- pdata->base = devfdt_map_physmem(dev, sizeof(void *));
+ pdata->base = dev_remap_addr(dev);
if (!pdata->base)
return -ENODEV;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 65d9bf533cb..6fb3019a644 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -44,8 +44,8 @@ config VPL_DM_RTC
config RTC_ENABLE_32KHZ_OUTPUT
bool "Enable RTC 32Khz output"
help
- Some real-time clocks support the output of 32kHz square waves (such as ds3231),
- the config symbol choose Real Time Clock device 32Khz output feature.
+ Some real-time clocks support the output of 32kHz square waves (such as ds3231),
+ the config symbol choose Real Time Clock device 32Khz output feature.
config RTC_ARMADA38X
bool "Enable Armada 38x Marvell SoC RTC"
@@ -163,6 +163,9 @@ config RTC_PCF85063
help
If you say yes here you get support for the NXP PCF85063 RTC
and compatible chips.
+ Support for the following chip features is currently not implemented:
+ - NVMEM device for RAM register
+ - CLKOUT generation
config RTC_PCF8563
bool "Philips PCF8563"
diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c
index 34d8f8c5276..4176ab3701e 100644
--- a/drivers/rtc/ds1307.c
+++ b/drivers/rtc/ds1307.c
@@ -116,9 +116,9 @@ static int ds1307_rtc_get(struct udevice *dev, struct rtc_time *tm)
if (ret < 0)
return ret;
- if (type == ds_1337 || type == ds_1340) {
- uint reg = (type == ds_1337) ? DS1337_STAT_REG_ADDR :
- DS1340_STAT_REG_ADDR;
+ if (type == ds_1337 || type == ds_1339 || type == ds_1340) {
+ uint reg = (type == ds_1340) ? DS1340_STAT_REG_ADDR :
+ DS1337_STAT_REG_ADDR;
int status = dm_i2c_reg_read(dev, reg);
if (status >= 0 && (status & RTC_STAT_BIT_OSF)) {
diff --git a/drivers/rtc/goldfish_rtc.c b/drivers/rtc/goldfish_rtc.c
index d2991ca6719..652eec7dd0c 100644
--- a/drivers/rtc/goldfish_rtc.c
+++ b/drivers/rtc/goldfish_rtc.c
@@ -40,8 +40,8 @@ static int goldfish_rtc_get(struct udevice *dev, struct rtc_time *time)
u64 time_low;
u64 now;
- time_low = ioread32(base + GOLDFISH_TIME_LOW);
- time_high = ioread32(base + GOLDFISH_TIME_HIGH);
+ time_low = __raw_readl(base + GOLDFISH_TIME_LOW);
+ time_high = __raw_readl(base + GOLDFISH_TIME_HIGH);
now = (time_high << 32) | time_low;
do_div(now, 1000000000U);
@@ -62,8 +62,8 @@ static int goldfish_rtc_set(struct udevice *dev, const struct rtc_time *time)
return -EINVAL;
now = rtc_mktime(time) * 1000000000ULL;
- iowrite32(now >> 32, base + GOLDFISH_TIME_HIGH);
- iowrite32(now, base + GOLDFISH_TIME_LOW);
+ __raw_writel(now >> 32, base + GOLDFISH_TIME_HIGH);
+ __raw_writel(now, base + GOLDFISH_TIME_LOW);
if (time->tm_isdst > 0)
priv->isdst = 1;
@@ -80,9 +80,13 @@ static int goldfish_rtc_of_to_plat(struct udevice *dev)
struct goldfish_rtc_plat *plat = dev_get_plat(dev);
fdt_addr_t addr;
+ plat->reg = 0;
+
addr = dev_read_addr(dev);
- if (addr != FDT_ADDR_T_NONE)
- plat->reg = addr;
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ plat->reg = addr;
return 0;
}
diff --git a/drivers/rtc/i2c_rtc_emul.c b/drivers/rtc/i2c_rtc_emul.c
index ea11c72c964..41bdf275f1e 100644
--- a/drivers/rtc/i2c_rtc_emul.c
+++ b/drivers/rtc/i2c_rtc_emul.c
@@ -191,7 +191,7 @@ static int sandbox_i2c_rtc_xfer(struct udevice *emul, struct i2c_msg *msg,
return 0;
}
-struct dm_i2c_ops sandbox_i2c_rtc_emul_ops = {
+static const struct dm_i2c_ops sandbox_i2c_rtc_emul_ops = {
.xfer = sandbox_i2c_rtc_xfer,
};
diff --git a/drivers/rtc/m41t62.c b/drivers/rtc/m41t62.c
index 7bfea9e0b31..b3734baf63e 100644
--- a/drivers/rtc/m41t62.c
+++ b/drivers/rtc/m41t62.c
@@ -66,7 +66,7 @@ static void m41t62_update_rtc_time(struct rtc_time *tm, u8 *buf)
{
debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
"mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
- __FUNCTION__,
+ __func__,
buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6], buf[7]);
@@ -83,7 +83,7 @@ static void m41t62_update_rtc_time(struct rtc_time *tm, u8 *buf)
debug("%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
- __FUNCTION__,
+ __func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
}
diff --git a/drivers/rtc/mcfrtc.c b/drivers/rtc/mcfrtc.c
index 9708971c5c4..23ffb2b31a1 100644
--- a/drivers/rtc/mcfrtc.c
+++ b/drivers/rtc/mcfrtc.c
@@ -73,7 +73,7 @@ int rtc_set(struct rtc_time *tmp)
days += month_days[i];
if (i == 1)
- days += isleap(i);
+ days += isleap(tmp->tm_year);
}
days += tmp->tm_mday - 1;
diff --git a/drivers/rtc/pcf85063.c b/drivers/rtc/pcf85063.c
index 737d4547aca..421c42c0b81 100644
--- a/drivers/rtc/pcf85063.c
+++ b/drivers/rtc/pcf85063.c
@@ -11,11 +11,33 @@
#include <dm/device_compat.h>
#define PCF85063_REG_CTRL1 0x00 /* status */
-#define PCF85063_REG_CTRL1_SR 0x58
+#define PCF85063_REG_CTRL1_CAP_SEL BIT(0)
+#define PCF85063_REG_CTRL1_STOP BIT(5)
+#define PCF85063_REG_CTRL1_EXT_TEST BIT(7)
+#define PCF85063_REG_CTRL1_SWR 0x58 /* Software reset command */
+
+#define PCF85063_REG_CTRL2 0x01
+#define PCF85063_CTRL2_AF BIT(6)
+#define PCF85063_CTRL2_AIE BIT(7)
+
+#define PCF85063_REG_OFFSET 0x02
+#define PCF85063_OFFSET_SIGN_BIT 6 /* 2's complement sign bit */
+#define PCF85063_OFFSET_MODE BIT(7)
+#define PCF85063_OFFSET_STEP0 4340
+#define PCF85063_OFFSET_STEP1 4069
+
+#define PCF85063_REG_CLKO_F_MASK 0x07 /* frequency mask */
+#define PCF85063_REG_CLKO_F_32768HZ 0x00
+#define PCF85063_REG_CLKO_F_OFF 0x07
+
+#define PCF85063_REG_RAM 0x03
#define PCF85063_REG_SC 0x04 /* datetime */
#define PCF85063_REG_SC_OS 0x80
+#define PCF85063_REG_ALM_S 0x0b
+#define PCF85063_AEN BIT(7)
+
static int pcf85063_get_time(struct udevice *dev, struct rtc_time *tm)
{
u8 regs[7];
@@ -35,7 +57,9 @@ static int pcf85063_get_time(struct udevice *dev, struct rtc_time *tm)
tm->tm_hour = bcd2bin(regs[2] & 0x3f);
tm->tm_mday = bcd2bin(regs[3] & 0x3f);
tm->tm_wday = regs[4] & 0x07;
- tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1;
+ /* rtc register and rtc_time spec uses 1 - 12 */
+ tm->tm_mon = bcd2bin(regs[5] & 0x1f);
+ /* adjust rtc_time (years since 0) to match register spec */
tm->tm_year = bcd2bin(regs[6]) + 2000;
return 0;
@@ -44,40 +68,102 @@ static int pcf85063_get_time(struct udevice *dev, struct rtc_time *tm)
static int pcf85063_set_time(struct udevice *dev, const struct rtc_time *tm)
{
u8 regs[7];
+ int rc;
if (tm->tm_year < 2000 || tm->tm_year > 2099) {
dev_err(dev, "Year must be between 2000 and 2099.\n");
return -EINVAL;
}
- regs[0] = bin2bcd(tm->tm_sec);
+ /*
+ * to accurately set the time, reset the divider chain and keep it in
+ * reset state until all time/date registers are written
+ */
+ rc = dm_i2c_reg_clrset(dev, PCF85063_REG_CTRL1,
+ PCF85063_REG_CTRL1_EXT_TEST |
+ PCF85063_REG_CTRL1_STOP,
+ PCF85063_REG_CTRL1_STOP);
+
+ if (rc)
+ return rc;
+
+ /* hours, minutes and seconds */
+ regs[0] = bin2bcd(tm->tm_sec) & (~PCF85063_REG_SC_OS);
+
regs[1] = bin2bcd(tm->tm_min);
regs[2] = bin2bcd(tm->tm_hour);
+
+ /* Day of month, 1 - 31 */
regs[3] = bin2bcd(tm->tm_mday);
- regs[4] = tm->tm_wday;
- regs[5] = bin2bcd(tm->tm_mon + 1);
+
+ /* Day of week 0 - 6 */
+ regs[4] = tm->tm_wday & 0x07;
+
+ /* rtc register and rtc_time spec uses 1 - 12 */
+ regs[5] = bin2bcd(tm->tm_mon);
+ /* adjust register to match rtc_time spec */
regs[6] = bin2bcd(tm->tm_year % 100);
- return dm_i2c_write(dev, PCF85063_REG_SC, regs, sizeof(regs));
+ rc = dm_i2c_write(dev, PCF85063_REG_SC, regs, sizeof(regs));
+ if (rc)
+ return rc;
+
+ /*
+ * Write the control register as a separate action since the size of
+ * the register space is different between the PCF85063TP and
+ * PCF85063A devices. The rollover point can not be used.
+ */
+ return dm_i2c_reg_clrset(dev, PCF85063_REG_CTRL1,
+ PCF85063_REG_CTRL1_STOP, 0);
}
static int pcf85063_reset(struct udevice *dev)
{
- return dm_i2c_reg_write(dev, PCF85063_REG_CTRL1, PCF85063_REG_CTRL1_SR);
+ return dm_i2c_reg_write(dev, PCF85063_REG_CTRL1, PCF85063_REG_CTRL1_SWR);
}
static int pcf85063_read(struct udevice *dev, unsigned int offset, u8 *buf,
unsigned int len)
{
+ if (offset + len > dev->driver_data)
+ return -EINVAL;
+
return dm_i2c_read(dev, offset, buf, len);
}
static int pcf85063_write(struct udevice *dev, unsigned int offset,
const u8 *buf, unsigned int len)
{
+ if (offset + len > dev->driver_data)
+ return -EINVAL;
+
return dm_i2c_write(dev, offset, buf, len);
}
+static int pcf85063_load_capacitance(struct udevice *dev)
+{
+ u32 load = 7000;
+ u8 reg = 0;
+
+ if (ofnode_read_u32(dev_ofnode(dev), "quartz-load-femtofarads", &load))
+ return 0;
+
+ switch (load) {
+ default:
+ dev_warn(dev, "Unknown quartz-load-femtofarads value: %d. Assuming 7000",
+ load);
+ fallthrough;
+ case 7000:
+ break;
+ case 12500:
+ reg = PCF85063_REG_CTRL1_CAP_SEL;
+ break;
+ }
+
+ return dm_i2c_reg_clrset(dev, PCF85063_REG_CTRL1,
+ PCF85063_REG_CTRL1_CAP_SEL, reg);
+}
+
static const struct rtc_ops pcf85063_rtc_ops = {
.get = pcf85063_get_time,
.set = pcf85063_set_time,
@@ -88,13 +174,45 @@ static const struct rtc_ops pcf85063_rtc_ops = {
static int pcf85063_probe(struct udevice *dev)
{
+ u8 tmp;
+ int err;
+
i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS);
+ err = dm_i2c_read(dev, PCF85063_REG_SC, &tmp, sizeof(tmp));
+ if (err) {
+ dev_err(dev, "RTC chip is not present\n");
+ return err;
+ }
+
+ /*
+ * If a Power loss is detected, SW reset the device.
+ * From PCF85063A datasheet:
+ * There is a low probability that some devices will have corruption
+ * of the registers after the automatic power-on reset...
+ */
+ if (tmp & PCF85063_REG_SC_OS) {
+ dev_warn(dev, "POR issue detected, sending a SW reset\n");
+ err = dm_i2c_reg_clrset(dev, PCF85063_REG_CTRL1,
+ 0xff, PCF85063_REG_CTRL1_SWR);
+ if (err < 0)
+ dev_warn(dev, "SW reset failed, trying to continue\n");
+ }
+
+ err = pcf85063_load_capacitance(dev);
+ if (err < 0)
+ dev_warn(dev, "failed to set xtal load capacitance: %d",
+ err);
+
return 0;
}
static const struct udevice_id pcf85063_of_id[] = {
- { .compatible = "microcrystal,rv8263" },
+ { .compatible = "microcrystal,rv8263", .data = 0x12 },
+ { .compatible = "nxp,pcf85063", .data = 0xb },
+ { .compatible = "nxp,pcf85063a", .data = 0x12 },
+ { .compatible = "nxp,pcf85063tp", .data = 0xb },
+ { .compatible = "nxp,pcf85073a", .data = 0x12 },
{ }
};
diff --git a/drivers/rtc/sandbox_rtc.c b/drivers/rtc/sandbox_rtc.c
index 4404501c2f6..1ade5d50b23 100644
--- a/drivers/rtc/sandbox_rtc.c
+++ b/drivers/rtc/sandbox_rtc.c
@@ -73,7 +73,7 @@ static int sandbox_rtc_get_name(const struct udevice *dev, char *out_name)
return acpi_copy_name(out_name, "RTCC");
}
-struct acpi_ops sandbox_rtc_acpi_ops = {
+static const struct acpi_ops sandbox_rtc_acpi_ops = {
.get_name = sandbox_rtc_get_name,
};
#endif
diff --git a/drivers/scsi/sandbox_scsi.c b/drivers/scsi/sandbox_scsi.c
index 544a0247083..5f0b01d86d5 100644
--- a/drivers/scsi/sandbox_scsi.c
+++ b/drivers/scsi/sandbox_scsi.c
@@ -128,7 +128,7 @@ static int sandbox_scsi_remove(struct udevice *dev)
return 0;
}
-struct scsi_ops sandbox_scsi_ops = {
+static const struct scsi_ops sandbox_scsi_ops = {
.exec = sandbox_scsi_exec,
.bus_reset = sandbox_scsi_bus_reset,
};
diff --git a/drivers/scsi/scsi_bootdev.c b/drivers/scsi/scsi_bootdev.c
index 28e4612f337..541b021b732 100644
--- a/drivers/scsi/scsi_bootdev.c
+++ b/drivers/scsi/scsi_bootdev.c
@@ -37,9 +37,6 @@ static int scsi_bootdev_hunt(struct bootdev_hunter *info, bool show)
return 0;
}
-struct bootdev_ops scsi_bootdev_ops = {
-};
-
static const struct udevice_id scsi_bootdev_ids[] = {
{ .compatible = "u-boot,bootdev-scsi" },
{ }
@@ -48,7 +45,6 @@ static const struct udevice_id scsi_bootdev_ids[] = {
U_BOOT_DRIVER(scsi_bootdev) = {
.name = "scsi_bootdev",
.id = UCLASS_BOOTDEV,
- .ops = &scsi_bootdev_ops,
.bind = scsi_bootdev_bind,
.of_match = scsi_bootdev_ids,
};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 5f8b98f0704..e221800d5d0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -759,11 +759,11 @@ config MVEBU_A3700_UART
config MCFUART
bool "Freescale ColdFire UART support"
depends on M68K
- help
- Choose this option to add support for UART driver on the ColdFire
- SoC's family. The serial communication channel provides a full-duplex
- asynchronous/synchronous receiver and transmitter deriving an
- operating frequency from the internal bus clock or an external clock.
+ help
+ Choose this option to add support for UART driver on the ColdFire
+ SoC's family. The serial communication channel provides a full-duplex
+ asynchronous/synchronous receiver and transmitter deriving an
+ operating frequency from the internal bus clock or an external clock.
config MXC_UART
bool "IMX serial port support"
@@ -1024,12 +1024,12 @@ config OCTEON_SERIAL_BOOTCMD
bool "MIPS Octeon PCI remote bootcmd input"
depends on ARCH_OCTEON
depends on DM_SERIAL
- select SYS_IS_IN_ENV
+ select SYS_CONSOLE_IS_IN_ENV
select CONSOLE_MUX
help
- This driver supports remote input over the PCIe bus from a host
- to U-Boot for entering commands. It is utilized by the host
- commands 'oct-remote-load' and 'oct-remote-bootcmd'.
+ This driver supports remote input over the PCIe bus from a host
+ to U-Boot for entering commands. It is utilized by the host
+ commands 'oct-remote-load' and 'oct-remote-bootcmd'.
config OCTEON_SERIAL_PCIE_CONSOLE
bool "MIPS Octeon PCIe remote console"
diff --git a/drivers/serial/serial_cortina.c b/drivers/serial/serial_cortina.c
index 3ae8fb46584..de8af5b0574 100644
--- a/drivers/serial/serial_cortina.c
+++ b/drivers/serial/serial_cortina.c
@@ -83,11 +83,13 @@ int ca_serial_setbrg(struct udevice *dev, int baudrate)
static int ca_serial_getc(struct udevice *dev)
{
struct ca_uart_priv *priv = dev_get_priv(dev);
- int ch;
+ unsigned int status;
- ch = readl(priv->base + URX_DATA) & 0xFF;
+ status = readl(priv->base + UINFO);
+ if (status & UINFO_RX_FIFO_EMPTY)
+ return -EAGAIN;
- return (int)ch;
+ return readl(priv->base + URX_DATA) & 0xFF;
}
static int ca_serial_putc(struct udevice *dev, const char ch)
diff --git a/drivers/serial/serial_goldfish.c b/drivers/serial/serial_goldfish.c
index 91dc040fcf2..732f167caae 100644
--- a/drivers/serial/serial_goldfish.c
+++ b/drivers/serial/serial_goldfish.c
@@ -74,8 +74,10 @@ static int goldfish_serial_of_to_plat(struct udevice *dev)
fdt_addr_t addr;
addr = dev_read_addr(dev);
- if (addr != FDT_ADDR_T_NONE)
- plat->reg = addr;
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ plat->reg = addr;
return 0;
}
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index 9fdb6503085..917445e1ee2 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -53,11 +53,7 @@
#define FIFO_RXSIZE_MASK 0x7
#define FIFO_RXSIZE_OFF 0
#define FIFO_TXFE 0x80
-#if defined(CONFIG_ARCH_IMX8) || defined(CONFIG_ARCH_IMXRT)
#define FIFO_RXFE 0x08
-#else
-#define FIFO_RXFE 0x40
-#endif
#define WATER_TXWATER_OFF 0
#define WATER_RXWATER_OFF 16
@@ -366,10 +362,14 @@ static int _lpuart32_serial_putc(struct lpuart_serial_plat *plat,
static int _lpuart32_serial_tstc(struct lpuart_serial_plat *plat)
{
struct lpuart_fsl_reg32 *base = plat->reg;
- u32 water;
+ u32 stat, water;
lpuart_read32(plat->flags, &base->water, &water);
+ lpuart_read32(plat->flags, &base->stat, &stat);
+ if (stat & STAT_OR)
+ lpuart_write32(plat->flags, &base->stat, STAT_OR);
+
if ((water >> 24) == 0)
return 0;
@@ -523,8 +523,7 @@ static int lpuart_serial_probe(struct udevice *dev)
static int lpuart_serial_of_to_plat(struct udevice *dev)
{
struct lpuart_serial_plat *plat = dev_get_plat(dev);
- const void *blob = gd->fdt_blob;
- int node = dev_of_offset(dev);
+ ofnode node = dev_ofnode(dev);
fdt_addr_t addr;
addr = dev_read_addr(dev);
@@ -534,18 +533,18 @@ static int lpuart_serial_of_to_plat(struct udevice *dev)
plat->reg = (void *)addr;
plat->flags = dev_get_driver_data(dev);
- if (fdtdec_get_bool(blob, node, "little-endian"))
+ if (ofnode_read_bool(node, "little-endian"))
plat->flags &= ~LPUART_FLAG_REGMAP_ENDIAN_BIG;
- if (!fdt_node_check_compatible(blob, node, "fsl,ls1021a-lpuart"))
+ if (ofnode_device_is_compatible(node, "fsl,ls1021a-lpuart"))
plat->devtype = DEV_LS1021A;
- else if (!fdt_node_check_compatible(blob, node, "fsl,imx7ulp-lpuart"))
+ else if (ofnode_device_is_compatible(node, "fsl,imx7ulp-lpuart"))
plat->devtype = DEV_MX7ULP;
- else if (!fdt_node_check_compatible(blob, node, "fsl,vf610-lpuart"))
+ else if (ofnode_device_is_compatible(node, "fsl,vf610-lpuart"))
plat->devtype = DEV_VF610;
- else if (!fdt_node_check_compatible(blob, node, "fsl,imx8qm-lpuart"))
+ else if (ofnode_device_is_compatible(node, "fsl,imx8qm-lpuart"))
plat->devtype = DEV_IMX8;
- else if (!fdt_node_check_compatible(blob, node, "fsl,imxrt-lpuart"))
+ else if (ofnode_device_is_compatible(node, "fsl,imxrt-lpuart"))
plat->devtype = DEV_IMXRT;
return 0;
diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
index 3dca581f68f..ae4015e0fdc 100644
--- a/drivers/serial/serial_msm_geni.c
+++ b/drivers/serial/serial_msm_geni.c
@@ -55,6 +55,7 @@
#define SE_UART_RX_PARITY_CFG 0x2a8
#define DEF_TX_WM 2
+#define DEF_RX_WM 2
/* GENI_FORCE_DEFAULT_REG fields */
#define UART_START_READ 0x1
@@ -345,6 +346,7 @@ static void qcom_geni_serial_start_rx(struct udevice *dev)
geni_se_setup_s_cmd(priv->base, UART_START_READ, 0);
+ writel(DEF_RX_WM, priv->base + SE_GENI_RX_WATERMARK_REG);
setbits_le32(priv->base + SE_GENI_S_IRQ_EN, S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
setbits_le32(priv->base + SE_GENI_M_IRQ_EN, M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
}
@@ -373,6 +375,7 @@ static void msm_geni_serial_setup_rx(struct udevice *dev)
geni_se_setup_s_cmd(priv->base, UART_START_READ, 0);
+ writel(DEF_RX_WM, priv->base + SE_GENI_RX_WATERMARK_REG);
setbits_le32(priv->base + SE_GENI_S_IRQ_EN, S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
setbits_le32(priv->base + SE_GENI_M_IRQ_EN, M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
}
@@ -616,6 +619,7 @@ static inline void _debug_uart_init(void)
phys_addr_t base = CONFIG_VAL(DEBUG_UART_BASE);
geni_serial_init(&init_dev);
+ writel(DEF_RX_WM, base + SE_GENI_RX_WATERMARK_REG);
geni_serial_baud(base, CLK_DIV, CONFIG_BAUDRATE);
qcom_geni_serial_start_tx(base);
}
diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c
index bc205234e24..7debff6cb3a 100644
--- a/drivers/serial/serial_sh.c
+++ b/drivers/serial/serial_sh.c
@@ -257,7 +257,7 @@ static int sh_serial_of_to_plat(struct udevice *dev)
int ret;
addr = dev_read_addr(dev);
- if (!addr)
+ if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
plat->base = addr;
diff --git a/drivers/smem/Kconfig b/drivers/smem/Kconfig
index e5d7dcc81b1..5b68ad5f10f 100644
--- a/drivers/smem/Kconfig
+++ b/drivers/smem/Kconfig
@@ -4,22 +4,22 @@ menuconfig SMEM
if SMEM
config SANDBOX_SMEM
- bool "Sandbox Shared Memory Manager (SMEM)"
- depends on SANDBOX && DM
- help
- enable SMEM support for sandbox. This is an emulation of a real SMEM
- manager.
- The sandbox driver allocates a shared memory from the heap and
- initialzies it on start.
+ bool "Sandbox Shared Memory Manager (SMEM)"
+ depends on SANDBOX && DM
+ help
+ enable SMEM support for sandbox. This is an emulation of a real SMEM
+ manager.
+ The sandbox driver allocates a shared memory from the heap and
+ initialzies it on start.
config MSM_SMEM
- bool "Qualcomm Shared Memory Manager (SMEM)"
- depends on DM
- depends on ARCH_SNAPDRAGON || ARCH_IPQ40XX
- select DEVRES
- help
- Enable support for the Qualcomm Shared Memory Manager.
- The driver provides an interface to items in a heap shared among all
- processors in a Qualcomm platform.
+ bool "Qualcomm Shared Memory Manager (SMEM)"
+ depends on DM
+ depends on ARCH_SNAPDRAGON || ARCH_IPQ40XX
+ select DEVRES
+ help
+ Enable support for the Qualcomm Shared Memory Manager.
+ The driver provides an interface to items in a heap shared among all
+ processors in a Qualcomm platform.
endif # menu "SMEM Support"
diff --git a/drivers/soc/soc_xilinx_zynqmp.c b/drivers/soc/soc_xilinx_zynqmp.c
index 4abc73013eb..0e13e230914 100644
--- a/drivers/soc/soc_xilinx_zynqmp.c
+++ b/drivers/soc/soc_xilinx_zynqmp.c
@@ -358,7 +358,9 @@ static int soc_xilinx_zynqmp_detect_machine(struct udevice *dev, u32 idcode,
} else if (device->variants & ZYNQMP_VARIANT_DR_SE) {
strlcat(priv->machine, "dr_SE", sizeof(priv->machine));
} else if (device->variants & ZYNQMP_VARIANT_TEG) {
- strlcat(priv->machine, "teg", sizeof(priv->machine));
+ /* Devices with TEG variant might be TEG or TCG family */
+ strlcat(priv->machine, (idcode2 & EFUSE_GPU_DIS_MASK) ?
+ "tcg" : "teg", sizeof(priv->machine));
}
return 0;
diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 36129cb72f6..9734bf32cb0 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -21,8 +21,8 @@ config TI_KEYSTONE_SERDES
bool "Keystone SerDes driver for ethernet"
depends on ARCH_KEYSTONE
help
- SerDes driver for Keystone SoC used for ethernet support on TI
- K2 platforms.
+ SerDes driver for Keystone SoC used for ethernet support on TI
+ K2 platforms.
config TI_PRUSS
bool "Support for TI's K3 based Pruss driver"
diff --git a/drivers/sound/da7219.c b/drivers/sound/da7219.c
index 5b9b3f65263..d1d03ae91d4 100644
--- a/drivers/sound/da7219.c
+++ b/drivers/sound/da7219.c
@@ -170,7 +170,7 @@ static int da7219_acpi_setup_nhlt(const struct udevice *dev,
}
#endif
-struct acpi_ops da7219_acpi_ops = {
+static const struct acpi_ops da7219_acpi_ops = {
#ifdef CONFIG_ACPIGEN
.fill_ssdt = da7219_acpi_fill_ssdt,
#ifdef CONFIG_X86
diff --git a/drivers/sound/max98357a.c b/drivers/sound/max98357a.c
index da56ffdd6bb..47978d4fe27 100644
--- a/drivers/sound/max98357a.c
+++ b/drivers/sound/max98357a.c
@@ -136,7 +136,7 @@ static int max98357a_acpi_setup_nhlt(const struct udevice *dev,
}
#endif
-struct acpi_ops max98357a_acpi_ops = {
+static const struct acpi_ops max98357a_acpi_ops = {
#ifdef CONFIG_ACPIGEN
.fill_ssdt = max98357a_acpi_fill_ssdt,
#ifdef CONFIG_X86
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index cfbedd64c4c..007ad5e7733 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -2,10 +2,10 @@ menuconfig SPI
bool "SPI Support"
help
The "Serial Peripheral Interface" is a low level synchronous
- protocol. Chips that support SPI can have data transfer rates
- up to several tens of Mbit/sec. Chips are addressed with a
- controller and a chipselect. Most SPI slaves don't support
- dynamic device discovery; some are even write-only or read-only.
+ protocol. Chips that support SPI can have data transfer rates
+ up to several tens of Mbit/sec. Chips are addressed with a
+ controller and a chipselect. Most SPI slaves don't support
+ dynamic device discovery; some are even write-only or read-only.
SPI is widely used by microcontrollers to talk with sensors,
eeprom and flash memory, codecs and various other controller
@@ -200,11 +200,11 @@ config CADENCE_XSPI
by using the Auto Command work mode.
config CF_SPI
- bool "ColdFire SPI driver"
- depends on M68K
- help
- Enable the ColdFire SPI driver. This driver can be used on
- some m68k SoCs.
+ bool "ColdFire SPI driver"
+ depends on M68K
+ help
+ Enable the ColdFire SPI driver. This driver can be used on
+ some m68k SoCs.
config CV1800B_SPIF
bool "Sophgo cv1800b SPI Flash Controller driver"
@@ -352,7 +352,7 @@ config MTK_SNOR
select DEVRES
help
Enable the Mediatek SPINOR controller driver. This driver has
- better read/write performance with NOR.
+ better read/write performance with NOR.
config MTK_SNFI_SPI
bool "Mediatek SPI memory controller driver"
@@ -544,11 +544,11 @@ config SPI_SIFIVE
config SOFT_SPI
bool "Soft SPI driver"
help
- Enable Soft SPI driver. This driver is to use GPIO simulate
- the SPI protocol.
+ Enable Soft SPI driver. This driver is to use GPIO simulate
+ the SPI protocol.
config SPI_SN_F_OSPI
- tristate "Socionext F_OSPI SPI flash controller"
+ bool "Socionext F_OSPI SPI flash controller"
select SPI_MEM
help
This enables support for the Socionext F_OSPI controller
@@ -673,8 +673,8 @@ config ZYNQMP_GQSPI
config SPI_STACKED_PARALLEL
bool "Enable support for stacked or parallel memories"
help
- Enable support for stacked/or parallel memories. This functionality
- may appear on Xilinx hardware. By default this is disabled.
+ Enable support for stacked/or parallel memories. This functionality
+ may appear on Xilinx hardware. By default this is disabled.
endif # if DM_SPI
diff --git a/drivers/spi/apple_spi.c b/drivers/spi/apple_spi.c
index 088d02e3b90..acc87ea7bdc 100644
--- a/drivers/spi/apple_spi.c
+++ b/drivers/spi/apple_spi.c
@@ -228,7 +228,7 @@ static int apple_spi_set_mode(struct udevice *bus, uint mode)
return 0;
}
-struct dm_spi_ops apple_spi_ops = {
+static const struct dm_spi_ops apple_spi_ops = {
.xfer = apple_spi_xfer,
.set_speed = apple_spi_set_speed,
.set_mode = apple_spi_set_mode,
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 2a4a49c5f1c..984d4a39ded 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -31,6 +31,8 @@
#define CQSPI_DISABLE_STIG_MODE BIT(0)
#define CQSPI_DMA_MODE BIT(1)
+#define CQSPI_RESET_DELAY_US 10
+
__weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
const struct spi_mem_op *op)
{
@@ -256,19 +258,9 @@ static int cadence_spi_probe(struct udevice *bus)
priv->resets = devm_reset_bulk_get_optional(bus);
if (priv->resets) {
- /* Assert all OSPI reset lines */
- ret = reset_assert_bulk(priv->resets);
- if (ret) {
- dev_err(bus, "Failed to assert OSPI reset: %d\n", ret);
- return ret;
- }
-
- udelay(10);
-
- /* Deassert all OSPI reset lines */
- ret = reset_deassert_bulk(priv->resets);
+ ret = reset_reset_bulk(priv->resets, CQSPI_RESET_DELAY_US);
if (ret) {
- dev_err(bus, "Failed to deassert OSPI reset: %d\n", ret);
+ dev_err(bus, "Failed to reset OSPI: %d\n", ret);
return ret;
}
}
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index b520c727900..0df9a4f5abd 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -497,6 +497,7 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen,
{
struct udevice *bus = dev->parent;
struct dw_spi_priv *priv = dev_get_priv(bus);
+ struct spi_slave *slave = dev_get_parent_priv(dev);
const u8 *tx = dout;
u8 *rx = din;
int ret = 0;
@@ -504,6 +505,17 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen,
u32 val;
u32 cs;
+ /* Get bits_per_word from slave (set by device driver) */
+ if (slave->bits_per_word >= 4 && slave->bits_per_word <= priv->max_xfer) {
+ priv->bits_per_word = slave->bits_per_word;
+ } else if (slave->bits_per_word == 0) {
+ priv->bits_per_word = 8; /* Default if not set */
+ } else {
+ dev_warn(dev, "Invalid bits_per_word %u, using 8\n",
+ slave->bits_per_word);
+ priv->bits_per_word = 8;
+ }
+
/* spi core configured to do 8 bit transfers */
if (bitlen % 8) {
dev_err(dev, "Non byte aligned SPI transfer.\n");
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 65ab3e306d7..5692510a558 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -267,6 +267,14 @@ static const struct fsl_qspi_devtype_data ls2080a_data = {
.little_endian = true,
};
+static const struct fsl_qspi_devtype_data spacemit_k1_data = {
+ .rxfifo = SZ_128,
+ .txfifo = SZ_256,
+ .ahb_buf_size = SZ_128,
+ .quirks = QUADSPI_QUIRK_TKT253890,
+ .little_endian = true,
+};
+
struct fsl_qspi {
struct udevice *dev;
void __iomem *iobase;
@@ -870,6 +878,7 @@ static const struct udevice_id fsl_qspi_ids[] = {
{ .compatible = "fsl,ls1021a-qspi", .data = (ulong)&ls1021a_data, },
{ .compatible = "fsl,ls1088a-qspi", .data = (ulong)&ls2080a_data, },
{ .compatible = "fsl,ls2080a-qspi", .data = (ulong)&ls2080a_data, },
+ { .compatible = "spacemit,k1-qspi", .data = (ulong)&spacemit_k1_data, },
{ }
};
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index ca29cfd7c88..0186b01ad9a 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -53,18 +53,20 @@ struct aspeed_spi_regs {
u32 dma_len; /* 0x8c DMA Length Register */
u32 dma_checksum; /* 0x90 Checksum Calculation Result */
u32 timings[ASPEED_SPI_MAX_CS]; /* 0x94 Read Timing Compensation */
+ u32 _reserved3[83]; /* 0xA8 - 0x1F0 */
+ u32 val_kept_wdt; /* 0x1F4 Value Kept WDT */
};
struct aspeed_spi_plat {
u8 max_cs;
- void __iomem *ahb_base; /* AHB address base for all flash devices. */
+ uintptr_t ahb_base; /* AHB address base for all flash devices. */
fdt_size_t ahb_sz; /* Overall AHB window size for all flash device. */
u32 hclk_rate; /* AHB clock rate */
};
struct aspeed_spi_flash {
- void __iomem *ahb_base;
- u32 ahb_decoded_sz;
+ uintptr_t ahb_base;
+ size_t ahb_decoded_sz;
u32 ce_ctrl_user;
u32 ce_ctrl_read;
u32 max_freq;
@@ -84,9 +86,9 @@ struct aspeed_spi_info {
u32 min_decoded_sz;
u32 clk_ctrl_mask;
void (*set_4byte)(struct udevice *bus, u32 cs);
- u32 (*segment_start)(struct udevice *bus, u32 reg);
- u32 (*segment_end)(struct udevice *bus, u32 reg);
- u32 (*segment_reg)(u32 start, u32 end);
+ uintptr_t (*segment_start)(struct udevice *bus, u32 reg);
+ uintptr_t (*segment_end)(struct udevice *bus, u32 reg);
+ u32 (*segment_reg)(uintptr_t start, uintptr_t end);
int (*adjust_decoded_sz)(struct udevice *bus);
u32 (*get_clk_setting)(struct udevice *dev, uint hz);
};
@@ -118,30 +120,30 @@ static u32 aspeed_spi_get_io_mode(u32 bus_width)
}
}
-static u32 ast2400_spi_segment_start(struct udevice *bus, u32 reg)
+static uintptr_t ast2400_spi_segment_start(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 start_offset = ((reg >> 16) & 0xff) << 23;
+ uintptr_t start_offset = ((reg >> 16) & 0xff) << 23;
if (start_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + start_offset;
+ return plat->ahb_base + start_offset;
}
-static u32 ast2400_spi_segment_end(struct udevice *bus, u32 reg)
+static uintptr_t ast2400_spi_segment_end(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 end_offset = ((reg >> 24) & 0xff) << 23;
+ uintptr_t end_offset = ((reg >> 24) & 0xff) << 23;
/* Meaningless end_offset, set to physical ahb base. */
if (end_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + end_offset;
+ return plat->ahb_base + end_offset;
}
-static u32 ast2400_spi_segment_reg(u32 start, u32 end)
+static u32 ast2400_spi_segment_reg(uintptr_t start, uintptr_t end)
{
if (start == end)
return 0;
@@ -206,30 +208,30 @@ static u32 ast2400_get_clk_setting(struct udevice *dev, uint max_hz)
return hclk_div;
}
-static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg)
+static uintptr_t ast2500_spi_segment_start(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 start_offset = ((reg >> 16) & 0xff) << 23;
+ uintptr_t start_offset = ((reg >> 16) & 0xff) << 23;
if (start_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + start_offset;
+ return plat->ahb_base + start_offset;
}
-static u32 ast2500_spi_segment_end(struct udevice *bus, u32 reg)
+static uintptr_t ast2500_spi_segment_end(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 end_offset = ((reg >> 24) & 0xff) << 23;
+ uintptr_t end_offset = ((reg >> 24) & 0xff) << 23;
/* Meaningless end_offset, set to physical ahb base. */
if (end_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + end_offset;
+ return plat->ahb_base + end_offset;
}
-static u32 ast2500_spi_segment_reg(u32 start, u32 end)
+static u32 ast2500_spi_segment_reg(uintptr_t start, uintptr_t end)
{
if (start == end)
return 0;
@@ -346,30 +348,30 @@ end:
return hclk_div;
}
-static u32 ast2600_spi_segment_start(struct udevice *bus, u32 reg)
+static uintptr_t ast2600_spi_segment_start(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 start_offset = (reg << 16) & 0x0ff00000;
+ uintptr_t start_offset = (reg << 16) & 0x0ff00000;
if (start_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + start_offset;
+ return plat->ahb_base + start_offset;
}
-static u32 ast2600_spi_segment_end(struct udevice *bus, u32 reg)
+static uintptr_t ast2600_spi_segment_end(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 end_offset = reg & 0x0ff00000;
+ uintptr_t end_offset = reg & 0x0ff00000;
/* Meaningless end_offset, set to physical ahb base. */
if (end_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + end_offset + 0x100000;
+ return plat->ahb_base + end_offset + 0x100000;
}
-static u32 ast2600_spi_segment_reg(u32 start, u32 end)
+static u32 ast2600_spi_segment_reg(uintptr_t start, uintptr_t end)
{
if (start == end)
return 0;
@@ -473,6 +475,70 @@ static u32 ast2600_get_clk_setting(struct udevice *dev, uint max_hz)
return hclk_div;
}
+static uintptr_t ast2700_spi_segment_start(struct udevice *bus, u32 reg)
+{
+ struct aspeed_spi_plat *plat = dev_get_plat(bus);
+ uintptr_t start_offset = (reg & 0x0000ffff) << 16;
+
+ if (start_offset == 0)
+ return plat->ahb_base;
+
+ return plat->ahb_base + start_offset;
+}
+
+static uintptr_t ast2700_spi_segment_end(struct udevice *bus, u32 reg)
+{
+ struct aspeed_spi_plat *plat = dev_get_plat(bus);
+ uintptr_t end_offset = reg & 0xffff0000;
+
+ /* Meaningless end_offset, set to physical ahb base. */
+ if (end_offset == 0)
+ return plat->ahb_base;
+
+ return plat->ahb_base + end_offset;
+}
+
+static u32 ast2700_spi_segment_reg(uintptr_t start, uintptr_t end)
+{
+ if (start == end)
+ return 0;
+
+ return (((start >> 16) & 0x7fff) | ((end + 1) & 0x7fff0000));
+}
+
+static void ast2700_spi_chip_set_4byte(struct udevice *bus, u32 cs)
+{
+ struct aspeed_spi_priv *priv = dev_get_priv(bus);
+ u32 reg_val;
+
+ reg_val = readl(&priv->regs->ctrl);
+ reg_val |= 0x11 << cs;
+ writel(reg_val, &priv->regs->ctrl);
+
+ reg_val = readl(&priv->regs->val_kept_wdt);
+ reg_val |= (0x11 << 4) << cs;
+ writel(reg_val, &priv->regs->val_kept_wdt);
+}
+
+static int ast2700_adjust_decoded_size(struct udevice *bus)
+{
+ struct aspeed_spi_plat *plat = dev_get_plat(bus);
+ struct aspeed_spi_priv *priv = dev_get_priv(bus);
+ struct aspeed_spi_flash *flashes = &priv->flashes[0];
+ int ret;
+ int cs;
+
+ /* Close unused CS. */
+ for (cs = priv->num_cs; cs < plat->max_cs; cs++)
+ flashes[cs].ahb_decoded_sz = 0;
+
+ ret = aspeed_spi_trim_decoded_size(bus);
+ if (ret != 0)
+ return ret;
+
+ return 0;
+}
+
/*
* As the flash size grows up, we need to trim some decoded
* size if needed for the sake of conforming the maximum
@@ -512,12 +578,12 @@ static int aspeed_spi_trim_decoded_size(struct udevice *bus)
return 0;
}
-static int aspeed_spi_read_from_ahb(void __iomem *ahb_base, void *buf,
+static int aspeed_spi_read_from_ahb(uintptr_t ahb_base, void *buf,
size_t len)
{
size_t offset = 0;
- if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) &&
+ if (IS_ALIGNED(ahb_base, sizeof(uintptr_t)) &&
IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) {
readsl(ahb_base, buf, len >> 2);
offset = len & ~0x3;
@@ -529,12 +595,12 @@ static int aspeed_spi_read_from_ahb(void __iomem *ahb_base, void *buf,
return 0;
}
-static int aspeed_spi_write_to_ahb(void __iomem *ahb_base, const void *buf,
+static int aspeed_spi_write_to_ahb(uintptr_t ahb_base, const void *buf,
size_t len)
{
size_t offset = 0;
- if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) &&
+ if (IS_ALIGNED(ahb_base, sizeof(uintptr_t)) &&
IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) {
writesl(ahb_base, buf, len >> 2);
offset = len & ~0x3;
@@ -589,7 +655,7 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave,
struct aspeed_spi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(slave->dev);
u32 cs = slave_plat->cs[0];
- u32 ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs];
+ uintptr_t ce_ctrl_reg = (uintptr_t)&priv->regs->ce_ctrl[cs];
u32 ce_ctrl_val;
struct aspeed_spi_flash *flash = &priv->flashes[cs];
u8 dummy_data[16] = {0};
@@ -602,7 +668,7 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave,
op->data.nbytes, op->data.buswidth);
if (priv->info == &ast2400_spi_info)
- ce_ctrl_reg = (u32)&priv->regs->ctrl;
+ ce_ctrl_reg = (uintptr_t)&priv->regs->ctrl;
/*
* Set controller to 4-byte address mode
@@ -670,7 +736,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
u32 i;
u32 cs = slave_plat->cs[0];
u32 cmd_io_conf;
- u32 ce_ctrl_reg;
+ uintptr_t ce_ctrl_reg;
if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
/*
@@ -681,9 +747,9 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
return -EOPNOTSUPP;
}
- ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs];
+ ce_ctrl_reg = (uintptr_t)&priv->regs->ce_ctrl[cs];
if (info == &ast2400_spi_info)
- ce_ctrl_reg = (u32)&priv->regs->ctrl;
+ ce_ctrl_reg = (uintptr_t)&priv->regs->ctrl;
if (desc->info.length > 0x1000000)
priv->info->set_4byte(bus, cs);
@@ -693,7 +759,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
priv->flashes[cs].ahb_decoded_sz = desc->info.length;
for (i = 0; i < priv->num_cs; i++) {
- dev_dbg(dev, "cs: %d, sz: 0x%x\n", i,
+ dev_dbg(dev, "cs: %d, sz: 0x%zx\n", i,
priv->flashes[cs].ahb_decoded_sz);
}
@@ -728,7 +794,7 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
u32 cs = slave_plat->cs[0];
int ret;
- dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n",
+ dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%zx\n",
desc->info.op_tmpl.cmd.opcode, offs, len);
if (priv->flashes[cs].ahb_decoded_sz < offs + len ||
@@ -738,7 +804,10 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
if (ret != 0)
return 0;
} else {
- memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len);
+ memcpy_fromio(buf,
+ (void __iomem *)(priv->flashes[cs].ahb_base +
+ (uintptr_t)offs),
+ len);
}
return len;
@@ -783,19 +852,19 @@ static void aspeed_spi_decoded_range_set(struct udevice *bus)
struct aspeed_spi_plat *plat = dev_get_plat(bus);
struct aspeed_spi_priv *priv = dev_get_priv(bus);
u32 decoded_reg_val;
- u32 start_addr, end_addr;
+ uintptr_t start_addr, end_addr;
u32 cs;
for (cs = 0; cs < plat->max_cs; cs++) {
- start_addr = (u32)priv->flashes[cs].ahb_base;
- end_addr = (u32)priv->flashes[cs].ahb_base +
+ start_addr = priv->flashes[cs].ahb_base;
+ end_addr = priv->flashes[cs].ahb_base +
priv->flashes[cs].ahb_decoded_sz;
decoded_reg_val = priv->info->segment_reg(start_addr, end_addr);
writel(decoded_reg_val, &priv->regs->segment_addr[cs]);
- dev_dbg(bus, "cs: %d, decoded_reg: 0x%x, start: 0x%x, end: 0x%x\n",
+ dev_dbg(bus, "cs: %d, decoded_reg: 0x%x, start: 0x%lx, end: 0x%lx\n",
cs, decoded_reg_val, start_addr, end_addr);
}
}
@@ -851,13 +920,13 @@ static int aspeed_spi_decoded_ranges_sanity(struct udevice *bus)
* address base are monotonic increasing with CE#.
*/
for (cs = plat->max_cs - 1; cs > 0; cs--) {
- if ((u32)priv->flashes[cs].ahb_base != 0 &&
- (u32)priv->flashes[cs].ahb_base <
- (u32)priv->flashes[cs - 1].ahb_base +
+ if (priv->flashes[cs].ahb_base != 0 &&
+ priv->flashes[cs].ahb_base <
+ priv->flashes[cs - 1].ahb_base +
priv->flashes[cs - 1].ahb_decoded_sz) {
- dev_err(bus, "decoded range overlay 0x%08x 0x%08x\n",
- (u32)priv->flashes[cs].ahb_base,
- (u32)priv->flashes[cs - 1].ahb_base);
+ dev_err(bus, "decoded range overlay 0x%08lx 0x%08lx\n",
+ priv->flashes[cs].ahb_base,
+ priv->flashes[cs - 1].ahb_base);
return -EINVAL;
}
}
@@ -895,14 +964,13 @@ static int aspeed_spi_read_fixed_decoded_ranges(struct udevice *bus)
return ret;
for (i = 0; i < count; i++) {
- priv->flashes[ranges[i].cs].ahb_base =
- (void __iomem *)ranges[i].ahb_base;
+ priv->flashes[ranges[i].cs].ahb_base = ranges[i].ahb_base;
priv->flashes[ranges[i].cs].ahb_decoded_sz =
ranges[i].sz;
}
for (i = 0; i < plat->max_cs; i++) {
- dev_dbg(bus, "ahb_base: 0x%p, size: 0x%08x\n",
+ dev_dbg(bus, "ahb_base: 0x%lx, size: 0x%08zx\n",
priv->flashes[i].ahb_base,
priv->flashes[i].ahb_decoded_sz);
}
@@ -1063,6 +1131,32 @@ static const struct aspeed_spi_info ast2600_spi_info = {
.get_clk_setting = ast2600_get_clk_setting,
};
+static const struct aspeed_spi_info ast2700_fmc_info = {
+ .io_mode_mask = 0xf0000000,
+ .max_bus_width = 4,
+ .min_decoded_sz = 0x10000,
+ .clk_ctrl_mask = 0x0f000f00,
+ .set_4byte = ast2700_spi_chip_set_4byte,
+ .segment_start = ast2700_spi_segment_start,
+ .segment_end = ast2700_spi_segment_end,
+ .segment_reg = ast2700_spi_segment_reg,
+ .adjust_decoded_sz = ast2700_adjust_decoded_size,
+ .get_clk_setting = ast2600_get_clk_setting,
+};
+
+static const struct aspeed_spi_info ast2700_spi_info = {
+ .io_mode_mask = 0xf0000000,
+ .max_bus_width = 4,
+ .min_decoded_sz = 0x10000,
+ .clk_ctrl_mask = 0x0f000f00,
+ .set_4byte = ast2700_spi_chip_set_4byte,
+ .segment_start = ast2700_spi_segment_start,
+ .segment_end = ast2700_spi_segment_end,
+ .segment_reg = ast2700_spi_segment_reg,
+ .adjust_decoded_sz = ast2700_adjust_decoded_size,
+ .get_clk_setting = ast2600_get_clk_setting,
+};
+
static int aspeed_spi_claim_bus(struct udevice *dev)
{
struct udevice *bus = dev->parent;
@@ -1129,7 +1223,8 @@ static int apseed_spi_of_to_plat(struct udevice *bus)
return -EINVAL;
}
- plat->ahb_base = devfdt_get_addr_size_index_ptr(bus, 1, &plat->ahb_sz);
+ plat->ahb_base =
+ (uintptr_t)devfdt_get_addr_size_index_ptr(bus, 1, &plat->ahb_sz);
if (!plat->ahb_base) {
dev_err(bus, "wrong AHB base\n");
return -EINVAL;
@@ -1147,8 +1242,8 @@ static int apseed_spi_of_to_plat(struct udevice *bus)
plat->hclk_rate = clk_get_rate(&hclk);
- dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%llx\n",
- (u32)priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz);
+ dev_dbg(bus, "ctrl_base = 0x%p, ahb_base = 0x%lx, size = 0x%llx\n",
+ priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz);
dev_dbg(bus, "hclk = %dMHz, max_cs = %d\n",
plat->hclk_rate / 1000000, plat->max_cs);
@@ -1199,6 +1294,8 @@ static const struct udevice_id aspeed_spi_ids[] = {
{ .compatible = "aspeed,ast2500-spi", .data = (ulong)&ast2500_spi_info, },
{ .compatible = "aspeed,ast2600-fmc", .data = (ulong)&ast2600_fmc_info, },
{ .compatible = "aspeed,ast2600-spi", .data = (ulong)&ast2600_spi_info, },
+ { .compatible = "aspeed,ast2700-fmc", .data = (ulong)&ast2700_fmc_info, },
+ { .compatible = "aspeed,ast2700-spi", .data = (ulong)&ast2700_spi_info, },
{ }
};
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index ab4878ebae4..e28fd9af1d0 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -3,7 +3,7 @@ menu "SPMI support"
config SPMI
bool "Enable SPMI bus support"
depends on DM
- ---help---
+ help
Select this to enable to support SPMI bus.
SPMI (System Power Management Interface) bus is used
to connect PMIC devices on various SoCs.
@@ -11,13 +11,13 @@ config SPMI
config SPMI_MSM
bool "Support Qualcomm SPMI bus"
depends on SPMI
- ---help---
+ help
Support SPMI bus implementation found on Qualcomm Snapdragon SoCs.
config SPMI_SANDBOX
bool "Support for Sandbox SPMI bus"
depends on SPMI
- ---help---
+ help
Demo SPMI bus implementation. Emulates part of PM8916 as single
- slave (0) on bus. It has 4 GPIO peripherals, pid 0xC0-0xC3.
+ slave (0) on bus. It has 4 GPIO peripherals, pid 0xC0-0xC3.
endmenu
diff --git a/drivers/sysinfo/Kconfig b/drivers/sysinfo/Kconfig
index df83df69ffb..6922dac9170 100644
--- a/drivers/sysinfo/Kconfig
+++ b/drivers/sysinfo/Kconfig
@@ -59,4 +59,12 @@ config SYSINFO_GPIO
This ternary number is then mapped to a board revision name using
device tree properties.
+config SYSINFO_TQ_EEPROM
+ bool "Enable TQ-Systems EEPROM sysinfo driver"
+ depends on I2C_EEPROM
+ depends on SPL_I2C_EEPROM || !SPL_SYSINFO
+ help
+ Support querying EEPROM of TQ-Systems SOMs to determine board
+ information.
+
endif
diff --git a/drivers/sysinfo/Makefile b/drivers/sysinfo/Makefile
index 26ca3150999..d21fb3c2270 100644
--- a/drivers/sysinfo/Makefile
+++ b/drivers/sysinfo/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_SYSINFO_IOT2050) += iot2050.o
obj-$(CONFIG_SYSINFO_RCAR3) += rcar3.o
obj-$(CONFIG_SYSINFO_SANDBOX) += sandbox.o
obj-$(CONFIG_SYSINFO_SMBIOS) += smbios.o
+obj-$(CONFIG_SYSINFO_TQ_EEPROM) += tq_eeprom.o
diff --git a/drivers/sysinfo/sysinfo-uclass.c b/drivers/sysinfo/sysinfo-uclass.c
index f04998ef8bb..d18a168614e 100644
--- a/drivers/sysinfo/sysinfo-uclass.c
+++ b/drivers/sysinfo/sysinfo-uclass.c
@@ -42,6 +42,16 @@ int sysinfo_detect(struct udevice *dev)
return ret;
}
+int sysinfo_get_and_detect(struct udevice **devp)
+{
+ int ret = sysinfo_get(devp);
+
+ if (!ret)
+ ret = sysinfo_detect(*devp);
+
+ return ret;
+}
+
int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
const char **strp)
{
@@ -152,5 +162,5 @@ UCLASS_DRIVER(sysinfo) = {
.id = UCLASS_SYSINFO,
.name = "sysinfo",
.post_bind = dm_scan_fdt_dev,
- .per_device_auto = sizeof(bool),
+ .per_device_auto = sizeof(struct sysinfo_priv),
};
diff --git a/drivers/sysinfo/tq_eeprom.c b/drivers/sysinfo/tq_eeprom.c
new file mode 100644
index 00000000000..63be07b664e
--- /dev/null
+++ b/drivers/sysinfo/tq_eeprom.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2014-2026 TQ-Systems GmbH <[email protected]>,
+ * D-82229 Seefeld, Germany.
+ * Author: Nora Schiffer
+ */
+
+#include <dm.h>
+#include <log.h>
+#include <net.h>
+#include <dm/device_compat.h>
+#include <linux/build_bug.h>
+#include <linux/ctype.h>
+#include <nvmem.h>
+#include <sysinfo/tq_eeprom.h>
+
+#define TQ_EE_RSV1_BYTES 10
+#define TQ_EE_SERIAL_BYTES 8
+#define TQ_EE_RSV2_BYTES 8
+#define TQ_EE_BDID_BYTES 0x40
+
+struct tq_eeprom_data {
+ u8 mac[ETH_ALEN]; /* 0x20 ... 0x25 */
+ u8 rsv1[TQ_EE_RSV1_BYTES];
+ u8 serial[TQ_EE_SERIAL_BYTES]; /* 0x30 ... 0x37 */
+ u8 rsv2[TQ_EE_RSV2_BYTES];
+ u8 id[TQ_EE_BDID_BYTES]; /* 0x40 ... 0x7f */
+};
+
+static_assert(sizeof(struct tq_eeprom_data) == 0x60,
+ "struct tq_eeprom_data has incorrect size");
+
+/**
+ * struct sysinfo_tq_eeprom_priv - sysinfo private data
+ */
+struct sysinfo_tq_eeprom_priv {
+ struct nvmem_cell device_info_cell;
+
+ /* Reserve extra space for \0 in id and serial */
+ char id[TQ_EE_BDID_BYTES + 1];
+ char serial[TQ_EE_SERIAL_BYTES + 1];
+ u8 mac[ETH_ALEN];
+};
+
+static void tq_eeprom_parse_id(struct udevice *dev, const struct tq_eeprom_data *data)
+{
+ struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < sizeof(data->id); i++) {
+ if (!(isprint(data->id[i]) && isascii(data->id[i])))
+ break;
+ }
+
+ if (i == 0)
+ dev_warn(dev, "no valid model name in EEPROM\n");
+
+ snprintf(priv->id, sizeof(priv->id), "%.*s", i, data->id);
+}
+
+static int tq_eeprom_serial_len(const struct tq_eeprom_data *data, bool allow_upper)
+{
+ int i;
+
+ for (i = 0; i < sizeof(data->serial); i++) {
+ if (!(isdigit(data->serial[i]) || (allow_upper && isupper(data->serial[i]))))
+ break;
+ }
+
+ return i;
+}
+
+static void tq_eeprom_parse_serial(struct udevice *dev, const struct tq_eeprom_data *data)
+{
+ struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev);
+ bool use_new_format;
+ int len;
+
+ use_new_format = data->serial[0] == 'T' && data->serial[1] == 'Q';
+
+ len = tq_eeprom_serial_len(data, use_new_format);
+
+ /* For now, only serial numbers with the exact size of the field are accepted */
+ if (len != sizeof(data->serial)) {
+ dev_warn(dev, "no valid serial number in EEPROM\n");
+ len = 0;
+ }
+
+ snprintf(priv->serial, sizeof(priv->serial), "%.*s", len, data->serial);
+}
+
+static int tq_eeprom_dump(const struct sysinfo_tq_eeprom_priv *priv)
+{
+ printf("TQ EEPROM:\n");
+ printf(" ID: %s\n", priv->id[0] ? priv->id : "<invalid>");
+ printf(" SN: %s\n", priv->serial[0] ? priv->serial : "<invalid>");
+ printf(" MAC: ");
+ if (is_valid_ethaddr(priv->mac))
+ printf("%pM\n", priv->mac);
+ else
+ printf("<invalid>\n");
+
+ return 0;
+}
+
+static int sysinfo_tq_eeprom_detect(struct udevice *dev)
+{
+ struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev);
+ struct tq_eeprom_data data;
+ int ret;
+
+ ret = nvmem_cell_read(&priv->device_info_cell, (u8 *)&data, sizeof(data));
+ if (ret < 0) {
+ dev_err(dev, "EEPROM read failed: %d\n", ret);
+ return ret;
+ }
+
+ tq_eeprom_parse_id(dev, &data);
+ tq_eeprom_parse_serial(dev, &data);
+ memcpy(priv->mac, data.mac, ETH_ALEN);
+
+ if (!IS_ENABLED(CONFIG_SPL_BUILD))
+ tq_eeprom_dump(priv);
+
+ return 0;
+}
+
+static int sysinfo_tq_eeprom_get_str(struct udevice *dev, int id, size_t size, char *val)
+{
+ struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev);
+
+ switch (id) {
+ case SYSID_TQ_MODEL:
+ if (!priv->id[0])
+ return -ENODATA;
+
+ strlcpy(val, priv->id, size);
+ return 0;
+
+ case SYSID_TQ_SERIAL:
+ if (!priv->serial[0])
+ return -ENODATA;
+
+ strlcpy(val, priv->serial, size);
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int sysinfo_tq_eeprom_get_data(struct udevice *dev, int id, void **data, size_t *size)
+{
+ struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev);
+
+ switch (id) {
+ case SYSID_TQ_MAC_ADDR:
+ if (!is_valid_ethaddr(priv->mac))
+ return -ENODATA;
+
+ *data = priv->mac;
+ *size = sizeof(priv->mac);
+
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct sysinfo_ops sysinfo_tq_eeprom_ops = {
+ .detect = sysinfo_tq_eeprom_detect,
+ .get_str = sysinfo_tq_eeprom_get_str,
+ .get_data = sysinfo_tq_eeprom_get_data,
+};
+
+static int sysinfo_tq_eeprom_probe(struct udevice *dev)
+{
+ struct sysinfo_tq_eeprom_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = nvmem_cell_get_by_name(dev, "device_info", &priv->device_info_cell);
+ if (ret) {
+ dev_err(dev, "device_info not found: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id sysinfo_tq_eeprom_ids[] = {
+ { .compatible = "tq,eeprom-sysinfo" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(sysinfo_tq_eeprom) = {
+ .name = "sysinfo_tq_eeprom",
+ .id = UCLASS_SYSINFO,
+ .of_match = sysinfo_tq_eeprom_ids,
+ .ops = &sysinfo_tq_eeprom_ops,
+ .priv_auto = sizeof(struct sysinfo_tq_eeprom_priv),
+ .probe = sysinfo_tq_eeprom_probe,
+};
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 90f740f51d4..16ef434a8d9 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -49,14 +49,6 @@ config SYSRESET_CMD_RESET
help
Enable sysreset implementation of the reset command.
-config SYSRESET_CMD_RESET_ARGS
- bool "Enable reset command to take arguments"
- help
- Pass on the arguments received by the 'reset' command to the
- sysreset driver(s). The sysreset driver(s) may make use of the
- additional arguments for implementing arch/board specific
- functionality.
-
if CMD_POWEROFF
config SYSRESET_CMD_POWEROFF
@@ -301,13 +293,6 @@ config SYSRESET_RAA215300
help
Add support for the system reboot via the Renesas RAA215300 PMIC.
-config SYSRESET_QCOM_PSCI
- bool "Support reset to EDL for Qualcomm SoCs via PSCI"
- depends on ARM_SMCCC
- help
- Add support for the reset to EDL (Emergency Download) on Qualcomm
- SoCs via PSCI.
-
config SYSRESET_QCOM_PSHOLD
bool "Support sysreset for Qualcomm SoCs via PSHOLD"
help
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index b5b99235b6e..d18a5d52360 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -30,7 +30,6 @@ obj-$(CONFIG_SYSRESET_RESETCTL) += sysreset_resetctl.o
obj-$(CONFIG_$(PHASE_)SYSRESET_AT91) += sysreset_at91.o
obj-$(CONFIG_$(PHASE_)SYSRESET_X86) += sysreset_x86.o
obj-$(CONFIG_SYSRESET_RAA215300) += sysreset_raa215300.o
-obj-$(CONFIG_SYSRESET_QCOM_PSCI) += sysreset_qcom-psci.o
obj-$(CONFIG_SYSRESET_QCOM_PSHOLD) += sysreset_qcom-pshold.o
obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
obj-$(CONFIG_SYSRESET_QEMU_VIRT_CTRL) += sysreset_qemu_virt_ctrl.o
diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c
index f25e09e9cd0..536ac727142 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -32,18 +32,6 @@ int sysreset_request(struct udevice *dev, enum sysreset_t type)
return ops->request(dev, type);
}
-#if IS_ENABLED(CONFIG_SYSRESET_CMD_RESET_ARGS)
-int sysreset_request_arg(struct udevice *dev, int argc, char * const argv[])
-{
- struct sysreset_ops *ops = sysreset_get_ops(dev);
-
- if (!ops->request_arg)
- return -ENOSYS;
-
- return ops->request_arg(dev, argc, argv);
-}
-#endif /* CONFIG_SYSRESET_CMD_RESET_ARGS */
-
int sysreset_get_status(struct udevice *dev, char *buf, int size)
{
struct sysreset_ops *ops = sysreset_get_ops(dev);
@@ -83,26 +71,6 @@ int sysreset_walk(enum sysreset_t type)
return ret;
}
-#if IS_ENABLED(CONFIG_SYSRESET_CMD_RESET_ARGS)
-int sysreset_walk_arg(int argc, char * const argv[])
-{
- struct udevice *dev;
- int ret = -ENOSYS;
-
- while (ret != -EINPROGRESS && ret != -EPROTONOSUPPORT) {
- for (uclass_first_device(UCLASS_SYSRESET, &dev);
- dev;
- uclass_next_device(&dev)) {
- ret = sysreset_request_arg(dev, argc, argv);
- if (ret == -EINPROGRESS || ret == -EPROTONOSUPPORT)
- break;
- }
- }
-
- return ret;
-}
-#endif /* CONFIG_SYSRESET_CMD_RESET_ARGS */
-
int sysreset_get_last_walk(void)
{
struct udevice *dev;
@@ -164,11 +132,6 @@ int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
printf("resetting ...\n");
mdelay(100);
-#if IS_ENABLED(CONFIG_SYSRESET_CMD_RESET_ARGS)
- if (argc > 1 && sysreset_walk_arg(argc, argv) == -EINPROGRESS)
- return 0;
-#endif
-
sysreset_walk_halt(reset_type);
return 0;
diff --git a/drivers/sysreset/sysreset_qcom-psci.c b/drivers/sysreset/sysreset_qcom-psci.c
deleted file mode 100644
index 3627bbf5c82..00000000000
--- a/drivers/sysreset/sysreset_qcom-psci.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2017 Masahiro Yamada <[email protected]>
- * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
- */
-
-#include <dm.h>
-#include <sysreset.h>
-#include <asm/system.h>
-#include <linux/errno.h>
-#include <linux/psci.h>
-#include <asm/psci.h>
-
-static int qcom_psci_sysreset_get_status(struct udevice *dev, char *buf, int size)
-{
- return -EOPNOTSUPP;
-}
-
-static int qcom_psci_sysreset_request_arg(struct udevice *dev, int argc,
- char * const argv[])
-{
- if (!strncasecmp(argv[1], "-edl", 4)) {
- /* Supported in qcs9100, qcs8300, sc7280, qcs615 */
- if (psci_features(ARM_PSCI_1_1_FN64_SYSTEM_RESET2) ==
- ARM_PSCI_RET_SUCCESS) {
- psci_system_reset2(0, 1);
- return -EINPROGRESS;
- }
- printf("PSCI SYSTEM_RESET2 not supported\n");
- }
-
- return -EPROTONOSUPPORT;
-}
-
-static struct sysreset_ops qcom_psci_sysreset_ops = {
- .request_arg = qcom_psci_sysreset_request_arg,
- .get_status = qcom_psci_sysreset_get_status,
-};
-
-U_BOOT_DRIVER(qcom_psci_sysreset) = {
- .name = "qcom_psci-sysreset",
- .id = UCLASS_SYSRESET,
- .ops = &qcom_psci_sysreset_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
diff --git a/drivers/sysreset/sysreset_qemu_virt_ctrl.c b/drivers/sysreset/sysreset_qemu_virt_ctrl.c
index e7cacc9b6e9..ce15e776f8f 100644
--- a/drivers/sysreset/sysreset_qemu_virt_ctrl.c
+++ b/drivers/sysreset/sysreset_qemu_virt_ctrl.c
@@ -8,6 +8,7 @@
#include <dm.h>
#include <qemu_virt_ctrl.h>
#include <sysreset.h>
+#include <mapmem.h>
#include <asm/io.h>
#include <linux/err.h>
@@ -24,6 +25,7 @@
static int qemu_virt_ctrl_request(struct udevice *dev, enum sysreset_t type)
{
struct qemu_virt_ctrl_plat *plat = dev_get_plat(dev);
+ void __iomem *reg = map_sysmem(plat->reg + VIRT_CTRL_REG_CMD, 0x4);
u32 val;
switch (type) {
@@ -38,7 +40,7 @@ static int qemu_virt_ctrl_request(struct udevice *dev, enum sysreset_t type)
return -EPROTONOSUPPORT;
}
- writel(val, plat->reg + VIRT_CTRL_REG_CMD);
+ __raw_writel(val, reg);
return -EINPROGRESS;
}
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 91c39aa4dee..3b7e807a024 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -13,9 +13,9 @@ config IMX_THERMAL
depends on MX6 || MX7
help
Support for Temperature Monitor (TEMPMON) found on Freescale i.MX SoCs.
- It supports one critical trip point and one passive trip point. The
- cpufreq is used as the cooling device to throttle CPUs when the
- passive trip is crossed.
+ It supports one critical trip point and one passive trip point. The
+ cpufreq is used as the cooling device to throttle CPUs when the
+ passive trip is crossed.
config IMX_SCU_THERMAL
bool "Temperature sensor driver for NXP i.MX8"
@@ -27,11 +27,12 @@ config IMX_SCU_THERMAL
trip is crossed
config IMX_TMU
- bool "Thermal Management Unit driver for NXP i.MX8M and iMX93"
- depends on ARCH_IMX8M || IMX93
- help
- Support for Temperature sensors on NXP i.MX8M and iMX93.
- It supports one critical trip point and one passive trip point.
+ bool "Thermal Management Unit driver for NXP i.MX8M / i.MX93 and QorIQ"
+ depends on ARCH_IMX8M || IMX93 || FSL_LAYERSCAPE
+ help
+ Support for the NXP Thermal Management Unit (TMU) sensors on
+ i.MX8M, i.MX93 and on QorIQ/Layerscape SoCs (LX2160A,
+ LS1028A, LS1088A, ...).
The boot is hold to the cool device to throttle CPUs when the
passive trip is crossed
@@ -44,15 +45,30 @@ config RCAR_GEN3_THERMAL
driver into the U-Boot thermal framework.
config TI_DRA7_THERMAL
- bool "Temperature sensor driver for TI dra7xx SOCs"
- help
- Enable thermal support for for the Texas Instruments DRA752 SoC family.
- The driver supports reading CPU temperature.
+ bool "Temperature sensor driver for TI dra7xx SOCs"
+ help
+ Enable thermal support for the Texas Instruments DRA752 SoC family.
+ The driver supports reading CPU temperature.
config TI_LM74_THERMAL
- bool "Temperature sensor driver for TI LM74 chip"
- help
- Enable thermal support for the Texas Instruments LM74 chip.
- The driver supports reading CPU temperature.
+ bool "Temperature sensor driver for TI LM74 chip"
+ help
+ Enable thermal support for the Texas Instruments LM74 chip.
+ The driver supports reading CPU temperature.
+
+config DM_THERMAL_JC42
+ bool "JEDEC JC-42.4/TSE2004av SPD temperature sensor"
+ depends on DM_I2C
+ help
+ Enable support for the JEDEC JC-42.4 temperature sensor found
+ on the SPD bus of DDR3 and DDR4 DIMMs (TSE2004av and compatible).
+
+config PMBUS_THERMAL
+ bool "Generic PMBus temperature"
+ depends on DM_REGULATOR_PMBUS_HELPER
+ help
+ Expose the die-temperature reading of any PMBus voltage
+ regulator bound by a pmbus_helper based chip driver
+ as a UCLASS_THERMAL device.
endif # if DM_THERMAL
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index b6f06c00ed9..475026a5ab2 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -11,3 +11,5 @@ obj-$(CONFIG_RCAR_GEN3_THERMAL) += rcar_gen3_thermal.o
obj-$(CONFIG_SANDBOX) += thermal_sandbox.o
obj-$(CONFIG_TI_DRA7_THERMAL) += ti-bandgap.o
obj-$(CONFIG_TI_LM74_THERMAL) += ti-lm74.o
+obj-$(CONFIG_DM_THERMAL_JC42) += jc42.o
+obj-$(CONFIG_PMBUS_THERMAL) += pmbus_thermal.o
diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c
index 1bde4d07f52..da0825ecd34 100644
--- a/drivers/thermal/imx_tmu.c
+++ b/drivers/thermal/imx_tmu.c
@@ -6,14 +6,17 @@
#include <config.h>
#include <asm/io.h>
-#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
+#if IS_ENABLED(CONFIG_ARCH_IMX8M) || IS_ENABLED(CONFIG_IMX93)
+#include <asm/arch/clock.h>
+#endif
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <dm/device.h>
#include <errno.h>
#include <fuse.h>
+#include <linux/bitops.h>
#include <linux/delay.h>
#include <malloc.h>
#include <thermal.h>
@@ -22,10 +25,12 @@
#define FLAGS_VER2 0x1
#define FLAGS_VER3 0x2
#define FLAGS_VER4 0x4
+#define FLAGS_QORIQ 0x8
#define TMR_DISABLE 0x0
#define TMR_ME 0x80000000
#define TMR_ALPF 0x0c000000
+#define QORIQ_TMR_ALPF (0x3 << 24) /* QorIQ ALPF lives at bits[25:24] */
#define TMTMIR_DEFAULT 0x00000002
#define TIER_DISABLE 0x0
@@ -33,7 +38,19 @@
#define TER_ADC_PD 0x40000000
#define TER_ALPF 0x3
+/* default CPU delay time to cool down if over temperature */
#define IMX_TMU_POLLING_DELAY_MS 5000
+
+/* TRITSR - QorIQ Immediate Temperature Site Register.
+ *
+ * Per LX2160A Reference Manual, Rev. 1 (10/2021) section 28.3.1.24
+ * the calibrated reading lives in TEMP[8:0] and is reported in
+ * degrees Kelvin (integer). The QorIQ regs_v1 variant has no
+ * fractional 0.5 degC bit, unlike the i.MX regs_v2 / VER4 layouts.
+ */
+#define TRITSR_V BIT(31) /* reading valid */
+#define TRITSR_TEMP_MASK GENMASK(8, 0) /* degrees Kelvin */
+#define TRITSR_KELVIN_OFFSET 273 /* TEMP[8:0] - 273 = degC */
/*
* i.MX TMU Registers
*/
@@ -148,11 +165,37 @@ struct imx_tmu_regs_v3 {
u32 trim;
};
+/*
+ * fsl,qoriq-tmu (LX2160A, LS1028A, LS1088A, ...). Same TMU IP family as
+ * the i.MX "regs_v1" layout but: site-enable is a discrete TMSR at 0x08
+ * (TMTMIR moves to 0x0C), and the temperature range registers are
+ * variable-length at 0xF10 (a SoC may use fewer than 16). Calibration is
+ * taken from the DT (fsl,tmu-range / fsl,tmu-calibration) exactly like
+ * the i.MX regs_v1 path, so qoriq reuses imx_tmu_calibration()'s scheme.
+ */
+struct qoriq_tmu_regs {
+ u32 tmr; /* 0x000 mode */
+ u32 tsr; /* 0x004 status */
+ u32 tmsr; /* 0x008 monitor-site enable (bit N = site N) */
+ u32 tmtmir; /* 0x00C measurement interval */
+ u8 res0[0x10];
+ u32 tier; /* 0x020 interrupt enable */
+ u32 tidr; /* 0x024 interrupt detect */
+ u8 res1[0x58];
+ u32 ttcfgr; /* 0x080 temperature config (cal walk) */
+ u32 tscfgr; /* 0x084 sensor config (cal walk) */
+ u8 res2[0x78];
+ struct imx_tmu_site_regs site[SITES_MAX]; /* 0x100 */
+ u8 res3[0xd10];
+ u32 ttrcr[16]; /* 0xF10 temperature range control */
+};
+
union tmu_regs {
struct imx_tmu_regs regs_v1;
struct imx_tmu_regs_v2 regs_v2;
struct imx_tmu_regs_v3 regs_v3;
struct imx_tmu_regs_v4 regs_v4;
+ struct qoriq_tmu_regs regs_qoriq;
};
struct imx_tmu_plat {
@@ -189,6 +232,9 @@ static int read_temperature(struct udevice *dev, int *temp)
} else if (drv_data & FLAGS_VER4) {
val = readl(&pdata->regs->regs_v4.tritsr0);
valid = val & 0x80000000;
+ } else if (drv_data & FLAGS_QORIQ) {
+ val = readl(&pdata->regs->regs_qoriq.site[pdata->id].tritsr);
+ valid = val & TRITSR_V;
} else {
val = readl(&pdata->regs->regs_v1.site[pdata->id].tritsr);
valid = val & 0x80000000;
@@ -213,6 +259,19 @@ static int read_temperature(struct udevice *dev, int *temp)
/* Convert Kelvin to Celsius */
*temp -= 273000;
+ } else if (drv_data & FLAGS_QORIQ) {
+ /*
+ * LX2160A Reference Manual, Rev. 1 (10/2021)
+ * section 28.3.1.24: TEMP[8:0] is the calibrated
+ * reading in degrees Kelvin (integer, no 0.5 degC
+ * bit on the regs_v1 variant). The calibration
+ * point examples in the same RM section 28.1.3
+ * use the same Kelvin/Celsius offset:
+ * TTR0CR=0x800000E6 -> 230K (-43 degC)
+ * TTR1CR=0x8001017D -> 381K (108 degC)
+ */
+ *temp = ((val & TRITSR_TEMP_MASK) -
+ TRITSR_KELVIN_OFFSET) * 1000;
} else {
*temp = (val & 0xff) * 1000;
}
@@ -265,6 +324,35 @@ static int imx_tmu_calibration(struct udevice *dev)
if (drv_data & (FLAGS_VER2 | FLAGS_VER3))
return 0;
+ if (drv_data & FLAGS_QORIQ) {
+ const fdt32_t *ranges;
+ int n;
+
+ ranges = dev_read_prop(dev, "fsl,tmu-range", &len);
+ if (!ranges || len % 4 ||
+ len / 4 > (int)ARRAY_SIZE(pdata->regs->regs_qoriq.ttrcr)) {
+ dev_err(dev, "TMU: missing/invalid fsl,tmu-range\n");
+ return -ENODEV;
+ }
+ n = len / 4;
+ for (i = 0; i < n; i++)
+ writel(fdt32_to_cpu(ranges[i]),
+ &pdata->regs->regs_qoriq.ttrcr[i]);
+
+ calibration = dev_read_prop(dev, "fsl,tmu-calibration", &len);
+ if (!calibration || len % 8) {
+ dev_err(dev, "TMU: invalid calibration data.\n");
+ return -ENODEV;
+ }
+ for (i = 0; i < len; i += 8, calibration += 2) {
+ writel(fdt32_to_cpu(*calibration),
+ &pdata->regs->regs_qoriq.ttcfgr);
+ writel(fdt32_to_cpu(*(calibration + 1)),
+ &pdata->regs->regs_qoriq.tscfgr);
+ }
+ return 0;
+ }
+
if (drv_data & FLAGS_VER4) {
calibration = dev_read_prop(dev, "fsl,tmu-calibration", &len);
if (!calibration || len % 8 || len > 128) {
@@ -402,6 +490,18 @@ static inline void imx_tmu_mx8mq_init(struct udevice *dev) { }
static void imx_tmu_arch_init(struct udevice *dev)
{
+ /*
+ * QorIQ takes its calibration from the DT (fsl,tmu-calibration),
+ * not from OCOTP fuses, so it has no per-SoC arch init. The #if
+ * below is still required: the i.MX SoC-ID helpers and fuse API
+ * (<asm/arch/sys_proto.h>) do not exist in a Layerscape build, so
+ * the references must be removed at compile time, not merely
+ * skipped at runtime.
+ */
+ if (dev_get_driver_data(dev) & FLAGS_QORIQ)
+ return;
+
+#if IS_ENABLED(CONFIG_ARCH_IMX8M) || IS_ENABLED(CONFIG_IMX93)
if (is_imx8mm() || is_imx8mn())
imx_tmu_mx8mm_mx8mn_init(dev);
else if (is_imx8mp())
@@ -412,6 +512,7 @@ static void imx_tmu_arch_init(struct udevice *dev)
imx_tmu_mx8mq_init(dev);
else
dev_err(dev, "Unsupported SoC, TMU calibration not loaded!\n");
+#endif
}
static void imx_tmu_init(struct udevice *dev)
@@ -443,6 +544,15 @@ static void imx_tmu_init(struct udevice *dev)
/* Set update_interval */
writel(TMTMIR_DEFAULT, &pdata->regs->regs_v4.tmtmir);
+ } else if (drv_data & FLAGS_QORIQ) {
+ /* Disable monitoring */
+ writel(TMR_DISABLE, &pdata->regs->regs_qoriq.tmr);
+
+ /* Disable interrupt, using polling instead */
+ writel(TIER_DISABLE, &pdata->regs->regs_qoriq.tier);
+
+ /* Set update_interval */
+ writel(TMTMIR_DEFAULT, &pdata->regs->regs_qoriq.tmtmir);
} else {
/* Disable monitoring */
writel(TMR_DISABLE, &pdata->regs->regs_v1.tmr);
@@ -511,6 +621,18 @@ static int imx_tmu_enable_msite(struct udevice *dev)
/* Enable ME */
reg |= TMR_ME;
writel(reg, &pdata->regs->regs_v4.tmr);
+ } else if (drv_data & FLAGS_QORIQ) {
+ /* Clear ME, enable every site at once via the discrete TMSR */
+ reg = readl(&pdata->regs->regs_qoriq.tmr);
+ reg &= ~TMR_ME;
+ writel(reg, &pdata->regs->regs_qoriq.tmr);
+
+ writel(GENMASK(SITES_MAX - 1, 0),
+ &pdata->regs->regs_qoriq.tmsr);
+
+ reg |= QORIQ_TMR_ALPF;
+ reg |= TMR_ME;
+ writel(reg, &pdata->regs->regs_qoriq.tmr);
} else {
/* Clear the ME before setting MSITE and ALPF*/
reg = readl(&pdata->regs->regs_v1.tmr);
@@ -650,6 +772,7 @@ static const struct udevice_id imx_tmu_ids[] = {
{ .compatible = "fsl,imx8mm-tmu", .data = FLAGS_VER2, },
{ .compatible = "fsl,imx8mp-tmu", .data = FLAGS_VER3, },
{ .compatible = "fsl,imx93-tmu", .data = FLAGS_VER4, },
+ { .compatible = "fsl,qoriq-tmu", .data = FLAGS_QORIQ, },
{ }
};
diff --git a/drivers/thermal/jc42.c b/drivers/thermal/jc42.c
new file mode 100644
index 00000000000..6945260e8b0
--- /dev/null
+++ b/drivers/thermal/jc42.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Free Mobile - Vincent Jardin
+ *
+ * JEDEC JC-42.4 / TSE2004av Temperature Sensor driver.
+ *
+ * Generic I2C temperature sensor of the Serial Presence Detect (SPD)
+ * bus of DDR3 and DDR4 SO-DIMMs / UDIMMs / RDIMMs per the JEDEC
+ * JC-42.4 standard. The TSE2004av variant adds an integrated SPD
+ * EEPROM, but the thermal register interface is the same and is
+ * what this driver exposes.
+ *
+ * Register layout (subset):
+ * 0x05 Ambient temperature, 16-bit big-endian:
+ * bit 15 : T_CRIT alarm flag (read-only)
+ * bit 14 : T_HIGH alarm flag (read-only)
+ * bit 13 : T_LOW alarm flag (read-only)
+ * bit 12 : sign (two's-complement within bits[12:0])
+ * bits[11:0]: magnitude * 16 (LSB = 0.0625 degC = 62.5 mC)
+ * 0x06 Manufacturer ID (16-bit BE, JEP-106 vendor code)
+ * 0x07 Device ID + Revision (upper byte = ID, lower = revision)
+ * ...
+ */
+
+#include <dm.h>
+#include <i2c.h>
+#include <thermal.h>
+#include <linux/bitops.h>
+
+#define JC42_REG_TEMP 0x05
+
+#define JC42_TEMP_SIGN BIT(12)
+#define JC42_TEMP_MAGNITUDE GENMASK(11, 0)
+
+static int jc42_get_temp(struct udevice *dev, int *temp)
+{
+ u8 buf[2];
+ int ret;
+ int mag;
+
+ ret = dm_i2c_read(dev, JC42_REG_TEMP, buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ mag = ((buf[0] << 8) | buf[1]) & (JC42_TEMP_SIGN | JC42_TEMP_MAGNITUDE);
+ if (mag & JC42_TEMP_SIGN)
+ mag -= (JC42_TEMP_SIGN << 1);
+
+ /*
+ * mag is in units of 1/16 degC. Multiply first to keep one
+ * extra bit of precision before the divide. Worst-case range
+ * for a 13-bit signed value is +/-4096, so the product fits
+ * comfortably in an int (~4.1M mC).
+ */
+ *temp = mag * 1000 / 16;
+
+ return 0;
+}
+
+static const struct dm_thermal_ops jc42_ops = {
+ .get_temp = jc42_get_temp,
+};
+
+/*
+ * Optional DT label property override: it replace the default DM
+ * device name (the ofnode name, eg "temp@18") so
+ * temperature list or temperature get commands
+ * show a human-meaningful identifier such as "ddr-top" or
+ * "ddr-bottom".
+ * It mirrors the Linux hwmon binding which uses label for the
+ * per-sensor display name.
+ */
+static int jc42_bind(struct udevice *dev)
+{
+ const char *label = dev_read_string(dev, "label");
+
+ if (label && *label)
+ return device_set_name(dev, label);
+ return 0;
+}
+
+static const struct udevice_id jc42_match[] = {
+ { .compatible = "jedec,jc-42.4-temp" },
+ { }
+};
+
+U_BOOT_DRIVER(jc42_thermal) = {
+ .name = "jc42_thermal",
+ .id = UCLASS_THERMAL,
+ .of_match = jc42_match,
+ .bind = jc42_bind,
+ .ops = &jc42_ops,
+};
diff --git a/drivers/thermal/pmbus_thermal.c b/drivers/thermal/pmbus_thermal.c
new file mode 100644
index 00000000000..c251cea8ddf
--- /dev/null
+++ b/drivers/thermal/pmbus_thermal.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Free Mobile - Vincent Jardin
+ *
+ * Generic UCLASS_THERMAL companion for PMBus voltage regulators.
+ *
+ * Works with any chip bound by a pmbus_helper based regulator driver
+ * (drivers/power/regulator/<chip>.c calling
+ * pmbus_regulator_probe_common()). It auto-spawns one
+ * of these thermal devices per regulator.
+ *
+ * The reading is the chip's READ_TEMPERATURE_1 (PMBus 0x8D), decoded
+ * through the parent's pmbus_driver_info.
+ */
+
+#include <dm.h>
+#include <pmbus.h>
+#include <thermal.h>
+
+static int pmbus_thermal_get_temp(struct udevice *dev, int *temp)
+{
+ return pmbus_regulator_read_temp(dev_get_parent(dev), temp);
+}
+
+static const struct dm_thermal_ops pmbus_thermal_ops = {
+ .get_temp = pmbus_thermal_get_temp,
+};
+
+U_BOOT_DRIVER(pmbus_thermal) = {
+ .name = "pmbus_thermal",
+ .id = UCLASS_THERMAL,
+ .ops = &pmbus_thermal_ops,
+};
diff --git a/drivers/thermal/ti-bandgap.c b/drivers/thermal/ti-bandgap.c
index dc869f108e4..643971e12cd 100644
--- a/drivers/thermal/ti-bandgap.c
+++ b/drivers/thermal/ti-bandgap.c
@@ -176,7 +176,7 @@ static int ti_bandgap_probe(struct udevice *dev)
{
struct ti_bandgap *bgp = dev_get_priv(dev);
- bgp->base = devfdt_get_addr_index(dev, 1);
+ bgp->base = dev_read_addr_index(dev, 1);
return 0;
}
diff --git a/drivers/timer/goldfish_timer.c b/drivers/timer/goldfish_timer.c
index 70673bbd93c..59ce43fcb46 100644
--- a/drivers/timer/goldfish_timer.c
+++ b/drivers/timer/goldfish_timer.c
@@ -31,8 +31,8 @@ static u64 goldfish_timer_get_count(struct udevice *dev)
* We must read LOW before HIGH to latch the high 32-bit value
* and ensure a consistent 64-bit timestamp.
*/
- low = readl(priv->base + TIMER_TIME_LOW);
- high = readl(priv->base + TIMER_TIME_HIGH);
+ low = __raw_readl(priv->base + TIMER_TIME_LOW);
+ high = __raw_readl(priv->base + TIMER_TIME_HIGH);
time = ((u64)high << 32) | low;
@@ -45,8 +45,10 @@ static int goldfish_timer_of_to_plat(struct udevice *dev)
fdt_addr_t addr;
addr = dev_read_addr(dev);
- if (addr != FDT_ADDR_T_NONE)
- plat->reg = addr;
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ plat->reg = addr;
return 0;
}
diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c
index 821b681a232..4d1c6b5cef2 100644
--- a/drivers/timer/orion-timer.c
+++ b/drivers/timer/orion-timer.c
@@ -2,6 +2,7 @@
#include <asm/io.h>
#include <config.h>
#include <div64.h>
+#include <dm.h>
#include <dm/device.h>
#include <dm/fdtaddr.h>
#include <timer.h>
@@ -113,7 +114,7 @@ static int orion_timer_probe(struct udevice *dev)
enum input_clock_type type = dev_get_driver_data(dev);
struct orion_timer_priv *priv = dev_get_priv(dev);
- priv->base = devfdt_remap_addr_index(dev, 0);
+ priv->base = dev_remap_addr_index(dev, 0);
if (!priv->base) {
debug("unable to map registers\n");
return -ENOMEM;
diff --git a/drivers/timer/sp804_timer.c b/drivers/timer/sp804_timer.c
index 05532e3330c..d1a5fc8c5bf 100644
--- a/drivers/timer/sp804_timer.c
+++ b/drivers/timer/sp804_timer.c
@@ -44,7 +44,7 @@ static int sp804_clk_of_to_plat(struct udevice *dev)
struct sp804_timer_plat *plat = dev_get_plat(dev);
plat->base = dev_read_addr(dev);
- if (!plat->base)
+ if (plat->base == FDT_ADDR_T_NONE)
return -ENOENT;
return 0;
diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c
index 14a94f8d4a8..46805eaa013 100644
--- a/drivers/tpm/cr50_i2c.c
+++ b/drivers/tpm/cr50_i2c.c
@@ -889,7 +889,7 @@ static int cr50_i2c_probe(struct udevice *dev)
return 0;
}
-struct acpi_ops cr50_acpi_ops = {
+static const struct acpi_ops cr50_acpi_ops = {
.fill_ssdt = cr50_acpi_fill_ssdt,
};
diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig
index 49472933de3..c1b84bd7559 100644
--- a/drivers/ufs/Kconfig
+++ b/drivers/ufs/Kconfig
@@ -19,12 +19,12 @@ config UFS_AMD_VERSAL2
config UFS_CADENCE
bool "Cadence platform driver for UFS"
depends on UFS
- help
+ help
This selects the platform driver for the Cadence UFS host
controller present on present TI's J721e devices.
config UFS_MEDIATEK
- tristate "MediaTek UFS Host Controller Driver"
+ bool "MediaTek UFS Host Controller Driver"
depends on UFS && ARCH_MEDIATEK
select PHY_MTK_UFS
help
@@ -51,7 +51,7 @@ config UFS_PCI
config UFS_QCOM
bool "Qualcomm Host Controller driver for UFS"
depends on UFS && ARCH_SNAPDRAGON
- help
+ help
This selects the platform driver for the UFS host
controller present on Qualcomm Snapdragon SoCs.
diff --git a/drivers/ufs/ufs-amd-versal2.c b/drivers/ufs/ufs-amd-versal2.c
index 6c949b2ca76..3369d32d924 100644
--- a/drivers/ufs/ufs-amd-versal2.c
+++ b/drivers/ufs/ufs-amd-versal2.c
@@ -563,4 +563,5 @@ U_BOOT_DRIVER(ufs_versal2_pltfm) = {
.id = UCLASS_UFS,
.of_match = ufs_versal2_ids,
.probe = ufs_versal2_probe,
+ .priv_auto = sizeof(struct ufs_versal2_priv),
};
diff --git a/drivers/ufs/ufs-qcom.c b/drivers/ufs/ufs-qcom.c
index dc40ee62daf..f5f5a6eb110 100644
--- a/drivers/ufs/ufs-qcom.c
+++ b/drivers/ufs/ufs-qcom.c
@@ -30,6 +30,7 @@
#define UFS_CPU_MAX_BANDWIDTH 819200
static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_hba *hba, bool enable);
+static u32 ufs_qcom_get_core_clk_unipro_max_freq(struct ufs_hba *hba);
static int ufs_qcom_enable_clks(struct ufs_qcom_priv *priv)
{
@@ -47,17 +48,6 @@ static int ufs_qcom_enable_clks(struct ufs_qcom_priv *priv)
return 0;
}
-static int ufs_qcom_init_clks(struct ufs_qcom_priv *priv)
-{
- int err;
- struct udevice *dev = priv->hba->dev;
-
- err = clk_get_bulk(dev, &priv->clks);
- if (err)
- return err;
-
- return 0;
-}
static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
{
@@ -557,10 +547,45 @@ static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_hba *hba, bool enable)
static int ufs_qcom_init(struct ufs_hba *hba)
{
struct ufs_qcom_priv *priv = dev_get_priv(hba->dev);
+ struct udevice *dev = hba->dev;
+ struct clk clk;
+ u32 max_freq;
+ long rate;
int err;
priv->hba = hba;
+ /* Get maximum frequency for core_clk_unipro from device tree */
+ max_freq = ufs_qcom_get_core_clk_unipro_max_freq(hba);
+
+ /* Get and configure core_clk_unipro */
+ err = clk_get_by_name(dev, "core_clk_unipro", &clk);
+ if (err) {
+ dev_err(dev, "Failed to get core_clk_unipro: %d\n", err);
+ return err;
+ }
+
+ rate = clk_set_rate(&clk, max_freq);
+ if (rate < 0) {
+ dev_err(dev, "Failed to set core_clk_unipro rate to %u Hz: %ld\n",
+ max_freq, rate);
+ }
+
+ /* Get all clocks */
+ err = clk_get_bulk(dev, &priv->clks);
+ if (err) {
+ dev_err(dev, "clk_get_bulk failed: %d\n", err);
+ return err;
+ }
+
+ /* Enable clocks */
+ err = ufs_qcom_enable_clks(priv);
+ if (err) {
+ dev_err(dev, "failed to enable clocks: %d\n", err);
+ clk_release_bulk(&priv->clks);
+ return err;
+ }
+
/* setup clocks */
ufs_qcom_setup_clocks(hba, true, PRE_CHANGE);
@@ -579,14 +604,7 @@ static int ufs_qcom_init(struct ufs_hba *hba)
priv->hw_ver.minor,
priv->hw_ver.step);
- err = ufs_qcom_init_clks(priv);
- if (err) {
- dev_err(hba->dev, "failed to initialize clocks, err:%d\n", err);
- return err;
- }
-
ufs_qcom_advertise_quirks(hba);
- ufs_qcom_setup_clocks(hba, true, POST_CHANGE);
return 0;
}
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 93c5ee69b25..05ac388ecf2 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -1,7 +1,7 @@
menuconfig USB
bool "USB support"
select BLK
- ---help---
+ help
Universal Serial Bus (USB) is a specification for a serial bus
subsystem which offers higher speeds and more features than the
traditional PC serial port. The bus supplies power to peripherals
@@ -94,7 +94,7 @@ comment "USB peripherals"
config USB_STORAGE
bool "USB Mass Storage support"
- ---help---
+ help
Say Y here if you want to connect USB mass storage devices to your
board's USB port.
@@ -103,7 +103,7 @@ config USB_KEYBOARD
depends on DM_USB
select DM_KEYBOARD
select SYS_STDIO_DEREGISTER
- ---help---
+ help
Say Y here if you want to use a USB keyboard for U-Boot command line
input.
@@ -111,7 +111,7 @@ config USB_ONBOARD_HUB
bool "Onboard USB hub support"
depends on DM_USB
select DEVRES
- ---help---
+ help
Say Y here if you want to support discrete onboard USB hubs that
don't require an additional control bus for initialization, but
need some non-trivial form of initialization, such as enabling a
@@ -163,17 +163,17 @@ choice
prompt "USB keyboard polling"
default SYS_USB_EVENT_POLL_VIA_INT_QUEUE if ARCH_SUNXI
default SYS_USB_EVENT_POLL
- ---help---
+ help
Enable a polling mechanism for USB keyboard.
config SYS_USB_EVENT_POLL
- bool "Interrupt polling"
+ bool "Interrupt polling"
config SYS_USB_EVENT_POLL_VIA_INT_QUEUE
- bool "Poll via interrupt queue"
+ bool "Poll via interrupt queue"
config SYS_USB_EVENT_POLL_VIA_CONTROL_EP
- bool "Poll via control EP"
+ bool "Poll via control EP"
endchoice
diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig
index 7964f3f41d5..ad0ef8ac2ba 100644
--- a/drivers/usb/cdns3/Kconfig
+++ b/drivers/usb/cdns3/Kconfig
@@ -1,5 +1,5 @@
config USB_CDNS3
- tristate "Cadence USB3 Dual-Role Controller"
+ bool "Cadence USB3 Dual-Role Controller"
depends on USB_XHCI_HCD || USB_GADGET
select DEVRES
help
@@ -51,14 +51,14 @@ config SPL_USB_CDNS3_HOST
standard XHCI driver.
config USB_CDNS3_STARFIVE
- tristate "Cadence USB3 support on Starfive platforms"
+ bool "Cadence USB3 support on Starfive platforms"
default y if STARFIVE_JH7110
help
Say 'Y' here if you are building for Starfive platforms
that contain Cadence USB3 controller core. E.g.: JH7110.
config USB_CDNS3_TI
- tristate "Cadence USB3 support on TI platforms"
+ bool "Cadence USB3 support on TI platforms"
default USB_CDNS3
help
Say 'Y' here if you are building for Texas Instruments
diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c
index 99519602eb2..8cb5796b6ad 100644
--- a/drivers/usb/dwc3/dwc3-am62.c
+++ b/drivers/usb/dwc3/dwc3-am62.c
@@ -105,7 +105,7 @@ static void dwc3_ti_am62_glue_configure(struct udevice *dev, int index,
writel(reg, usbss + USBSS_MODE_CONTROL);
}
-struct dwc3_glue_ops ti_am62_ops = {
+static const struct dwc3_glue_ops ti_am62_ops = {
.glue_configure = dwc3_ti_am62_glue_configure,
};
diff --git a/drivers/usb/dwc3/dwc3-generic-sti.c b/drivers/usb/dwc3/dwc3-generic-sti.c
index b34f5ceceac..ce195b2553b 100644
--- a/drivers/usb/dwc3/dwc3-generic-sti.c
+++ b/drivers/usb/dwc3/dwc3-generic-sti.c
@@ -114,7 +114,7 @@ static void dwc3_stih407_glue_configure(struct udevice *dev, int index,
setbits_le32(glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N);
};
-struct dwc3_glue_ops stih407_ops = {
+static const struct dwc3_glue_ops stih407_ops = {
.glue_configure = dwc3_stih407_glue_configure,
};
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 22b9ef0b24e..2356b3bc0aa 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -330,7 +330,7 @@ void dwc3_imx8mp_glue_configure(struct udevice *dev, int index,
unmap_physmem(base, MAP_NOCACHE);
}
-struct dwc3_glue_ops imx8mp_ops = {
+static const struct dwc3_glue_ops imx8mp_ops = {
.glue_configure = dwc3_imx8mp_glue_configure,
};
@@ -414,7 +414,7 @@ enum dwc3_omap_utmi_mode {
unmap_physmem(base, MAP_NOCACHE);
}
-struct dwc3_glue_ops ti_ops = {
+static const struct dwc3_glue_ops ti_ops = {
.glue_configure = dwc3_ti_glue_configure,
};
@@ -506,16 +506,16 @@ static int dwc3_flat_dt_get_ctrl_dev(struct udevice *dev, ofnode *node)
return 0;
}
-struct dwc3_glue_ops qcom_ops = {
+static const struct dwc3_glue_ops qcom_ops = {
.glue_configure = dwc3_qcom_glue_configure,
};
-struct dwc3_glue_ops qcom_flat_dt_ops = {
+static const struct dwc3_glue_ops qcom_flat_dt_ops = {
.glue_configure = dwc3_qcom_glue_configure,
.glue_get_ctrl_dev = dwc3_flat_dt_get_ctrl_dev,
};
-struct dwc3_glue_ops rk_ops = {
+static const struct dwc3_glue_ops rk_ops = {
.glue_get_ctrl_dev = dwc3_flat_dt_get_ctrl_dev,
};
diff --git a/drivers/usb/eth/Kconfig b/drivers/usb/eth/Kconfig
index 2f6bfa8e71b..b9b77f46743 100644
--- a/drivers/usb/eth/Kconfig
+++ b/drivers/usb/eth/Kconfig
@@ -1,6 +1,6 @@
menuconfig USB_HOST_ETHER
bool "USB to Ethernet Controller Drivers"
- ---help---
+ help
Say Y here if you would like to enable support for USB Ethernet
adapters.
@@ -9,14 +9,14 @@ if USB_HOST_ETHER
config USB_ETHER_ASIX
bool "ASIX AX8817X (USB 2.0) support"
depends on USB_HOST_ETHER
- ---help---
+ help
Say Y here if you would like to support ASIX AX8817X based USB 2.0
Ethernet Devices.
config USB_ETHER_ASIX88179
bool "ASIX AX88179 (USB 3.0) support"
depends on USB_HOST_ETHER
- ---help---
+ help
Say Y here if you would like to support ASIX AX88179 based USB 3.0
Ethernet Devices.
@@ -24,7 +24,7 @@ config USB_ETHER_LAN75XX
bool "Microchip LAN75XX support"
depends on USB_HOST_ETHER
depends on PHYLIB
- ---help---
+ help
Say Y here if you would like to support Microchip LAN75XX Hi-Speed
USB 2.0 to 10/100/1000 Gigabit Ethernet controller.
Supports 10Base-T/ 100Base-TX/1000Base-T.
@@ -34,7 +34,7 @@ config USB_ETHER_LAN78XX
bool "Microchip LAN78XX support"
depends on USB_HOST_ETHER
depends on PHYLIB
- ---help---
+ help
Say Y here if you would like to support Microchip LAN78XX USB 3.1
Gen 1 to 10/100/1000 Gigabit Ethernet controller.
Supports 10Base-T/ 100Base-TX/1000Base-T.
@@ -43,14 +43,14 @@ config USB_ETHER_LAN78XX
config USB_ETHER_MCS7830
bool "MOSCHIP MCS7830 (7730/7830/7832) suppport"
depends on USB_HOST_ETHER
- ---help---
+ help
Say Y here if you would like to support MOSCHIP MCS7830 based
(7730/7830/7832) USB 2.0 Ethernet Devices.
config USB_ETHER_RTL8152
bool "Realtek RTL8152B/RTL8153 support"
depends on USB_HOST_ETHER
- ---help---
+ help
Say Y here if you would like to support Realtek RTL8152B/RTL8153 base
USB Ethernet Devices. This driver also supports compatible devices
from Samsung, Lenovo, TP-LINK and Nvidia.
@@ -58,7 +58,7 @@ config USB_ETHER_RTL8152
config USB_ETHER_SMSC95XX
bool "SMSC LAN95x support"
depends on USB_HOST_ETHER
- ---help---
+ help
Say Y here if you would like to support SMSC LAN95xx based USB 2.0
Ethernet Devices.
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 5390878254a..e42d5a43696 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -19,10 +19,10 @@ menuconfig USB_GADGET
select DM_USB
imply CMD_BIND
help
- USB is a master/slave protocol, organized with one master
- host (such as a PC) controlling up to 127 peripheral devices.
- The USB hardware is asymmetric, which makes it easier to set up:
- you can't connect a "to-the-host" connector to a peripheral.
+ USB is a master/slave protocol, organized with one master
+ host (such as a PC) controlling up to 127 peripheral devices.
+ The USB hardware is asymmetric, which makes it easier to set up:
+ you can't connect a "to-the-host" connector to a peripheral.
U-Boot can run in the host, or in the peripheral. In both cases
you need a low level bus controller driver, and some software
@@ -164,10 +164,10 @@ config USB_GADGET_VBUS_DRAW
range 2 500
default 2
help
- Some devices need to draw power from USB when they are
- configured, perhaps to operate circuitry or to recharge
- batteries. This is in addition to any local power supply,
- such as an AC adapter or batteries.
+ Some devices need to draw power from USB when they are
+ configured, perhaps to operate circuitry or to recharge
+ batteries. This is in addition to any local power supply,
+ such as an AC adapter or batteries.
Enter the maximum power your device draws through USB, in
milliAmperes. The permitted range of values is 2 - 500 mA;
@@ -350,9 +350,9 @@ config SPL_DFU_RAM
bool "RAM device"
depends on SPL_DFU && SPL_RAM_SUPPORT
help
- select RAM/DDR memory device for loading binary images
- (u-boot/kernel) to the selected device partition using
- DFU and execute the u-boot/kernel from RAM.
+ select RAM/DDR memory device for loading binary images
+ (u-boot/kernel) to the selected device partition using
+ DFU and execute the u-boot/kernel from RAM.
endchoice
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index a2eee2bca2c..0caf8b8b7b4 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1201,7 +1201,7 @@ static struct usba_ep *usba_udc_pdata(struct usba_platform_data *pdata,
struct usba_ep *eps;
int i;
- eps = malloc(sizeof(struct usba_ep) * pdata->num_ep);
+ eps = calloc(pdata->num_ep, sizeof(struct usba_ep));
if (!eps) {
log_err("failed to alloc eps\n");
return NULL;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 71dc58da3f0..87ed25e8bb3 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2275,6 +2275,17 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
static void fsg_disable(struct usb_function *f)
{
struct fsg_dev *fsg = fsg_from_func(f);
+
+ /* Disable the endpoints */
+ if (fsg->bulk_in_enabled) {
+ usb_ep_disable(fsg->bulk_in);
+ fsg->bulk_in_enabled = 0;
+ }
+ if (fsg->bulk_out_enabled) {
+ usb_ep_disable(fsg->bulk_out);
+ fsg->bulk_out_enabled = 0;
+ }
+
fsg->common->new_fsg = NULL;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
}
diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
index f72e27028b7..cd2c282247a 100644
--- a/drivers/usb/gadget/f_sdp.c
+++ b/drivers/usb/gadget/f_sdp.c
@@ -75,6 +75,7 @@ struct hid_report {
#define SDP_HID_PACKET_SIZE_EP1 1024
#define SDP_EXIT 1
+#define SDP_FAIL 2
struct sdp_command {
u16 cmd;
@@ -840,11 +841,14 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image,
#ifdef CONFIG_SPL_LOAD_FIT
if (image_get_magic(header) == FDT_MAGIC) {
struct spl_load_info load;
+ int ret;
debug("Found FIT\n");
spl_load_init(&load, sdp_load_read, header, 1);
- spl_load_simple_fit(spl_image, &load, 0,
- header);
+ ret = spl_load_simple_fit(spl_image, &load, 0,
+ header);
+ if (ret)
+ return SDP_FAIL;
return SDP_EXIT;
}
@@ -852,9 +856,13 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image,
if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) &&
valid_container_hdr((void *)header)) {
struct spl_load_info load;
+ int ret;
spl_load_init(&load, sdp_load_read, header, 1);
- spl_load_imx_container(spl_image, &load, 0);
+ ret = spl_load_imx_container(spl_image, &load, 0);
+ if (ret)
+ return SDP_FAIL;
+
return SDP_EXIT;
}
@@ -924,6 +932,8 @@ int spl_sdp_handle(struct udevice *udc, struct spl_image_info *spl_image,
if (flag == SDP_EXIT)
return 0;
+ else if (flag == SDP_FAIL)
+ return -EIO;
schedule();
dm_usb_gadget_handle_interrupts(udc);
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index d75883e2865..6bbed9cb513 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -24,7 +24,7 @@ config USB_XHCI_HCD
bool "xHCI HCD (USB 3.0) support"
depends on DM && OF_CONTROL
select USB_HOST
- ---help---
+ help
The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0
"SuperSpeed" host controller hardware.
@@ -149,7 +149,7 @@ config USB_EHCI_HCD
select USB_HOST
select EHCI_DESC_BIG_ENDIAN if SYS_BIG_ENDIAN
select EHCI_MMIO_BIG_ENDIAN if SYS_BIG_ENDIAN
- ---help---
+ help
The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
"high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
If your USB host controller supports USB 2.0, you will likely want to
@@ -174,14 +174,14 @@ config USB_EHCI_ATMEL
bool "Support for Atmel on-chip EHCI USB controller"
depends on ARCH_AT91
default y
- ---help---
+ help
Enables support for the on-chip EHCI controller on Atmel chips.
config USB_EHCI_EXYNOS
bool "Support for Samsung Exynos EHCI USB controller"
depends on ARCH_EXYNOS
default y
- ---help---
+ help
Enables support for the on-chip EHCI controller on Samsung Exynos
SoCs.
@@ -191,7 +191,7 @@ config USB_EHCI_MARVELL
default y
select USB_EHCI_IS_TDI if !ARM64
select USB_EHCI_IS_TDI if ALLEYCAT_5
- ---help---
+ help
Enables support for the on-chip EHCI controller on MVEBU SoCs.
config USB_EHCI_MX5
@@ -205,7 +205,7 @@ config USB_EHCI_MX6
depends on ARCH_MX6 || ARCH_MX7ULP || ARCH_IMXRT
select EHCI_HCD_INIT_AFTER_RESET
default y
- ---help---
+ help
Enables support for the on-chip EHCI controller on i.MX6 SoCs.
config USB_EHCI_MX7
@@ -215,7 +215,7 @@ config USB_EHCI_MX7
select PHY if IMX8M || IMX9
select NOP_PHY if IMX8M || IMX9
default y
- ---help---
+ help
Enables support for the on-chip EHCI controller on i.MX7/i.MX8M/i.MX9 SoCs.
config USB_EHCI_MXS
@@ -230,7 +230,7 @@ config USB_EHCI_MXS
config USB_EHCI_NPCM
bool "Support for Nuvoton NPCM on-chip EHCI USB controller"
depends on ARCH_NPCM
- ---help---
+ help
Enables support for the on-chip EHCI controller on
Nuvoton NPCM chips.
@@ -240,7 +240,7 @@ config USB_EHCI_OMAP
select PHY
imply NOP_PHY
default y
- ---help---
+ help
Enables support for the on-chip EHCI controller on OMAP3 and later
SoCs.
@@ -255,7 +255,7 @@ if USB_EHCI_MX6 || USB_EHCI_MX7
config MXC_USB_OTG_HACTIVE
bool "USB Power pin high active"
- ---help---
+ help
Set the USB Power pin polarity to be high active (PWR_POL)
endif
@@ -265,7 +265,7 @@ config USB_EHCI_MSM
depends on DM_USB
select USB_ULPI
select MSM8916_USB_PHY
- ---help---
+ help
Enables support for the on-chip EHCI controller on Qualcomm
Snapdragon SoCs.
@@ -280,7 +280,7 @@ config USB_EHCI_TEGRA
bool "Support for NVIDIA Tegra on-chip EHCI USB controller"
depends on ARCH_TEGRA
select USB_EHCI_IS_TDI
- ---help---
+ help
Enable support for Tegra on-chip EHCI USB controller. If you enable
ULPI and your PHY needs a different reference clock than the standard
24 MHz then you have to define CFG_ULPI_REF_CLK to the appropriate
@@ -291,14 +291,14 @@ config USB_EHCI_ZYNQ
depends on ARCH_ZYNQ
default y
select USB_EHCI_IS_TDI
- ---help---
+ help
Enable support for Zynq on-chip EHCI USB controller
config USB_EHCI_GENERIC
bool "Support for generic EHCI USB controller"
depends on DM_USB
default ARCH_SUNXI
- ---help---
+ help
Enables support for generic EHCI controller.
config EHCI_HCD_INIT_AFTER_RESET
@@ -310,7 +310,7 @@ config USB_EHCI_FSL
select EHCI_HCD_INIT_AFTER_RESET
select SYS_FSL_USB_INTERNAL_UTMI_PHY if MPC85xx && \
!(ARCH_B4860 || ARCH_B4420 || ARCH_P4080 || ARCH_P1020 || ARCH_P2020)
- ---help---
+ help
Enables support for the on-chip EHCI controller on FSL chips.
config SYS_FSL_USB_INTERNAL_UTMI_PHY
@@ -340,7 +340,7 @@ config USB_OHCI_HCD
depends on DM && OF_CONTROL
select USB_HOST
select USB_OHCI_NEW
- ---help---
+ help
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
UHCI specification. If your USB host controller follows the OHCI spec,
@@ -361,7 +361,7 @@ config USB_OHCI_PCI
config USB_OHCI_GENERIC
bool "Support for generic OHCI USB controller"
default ARCH_SUNXI
- ---help---
+ help
Enables support for generic OHCI controller.
config USB_OHCI_DA8XX
@@ -374,7 +374,7 @@ config USB_OHCI_DA8XX
config USB_OHCI_NPCM
bool "Support for Nuvoton NPCM on-chip OHCI USB controller"
depends on ARCH_NPCM
- ---help---
+ help
Enables support for the on-chip OHCI controller on
Nuvoton NPCM chips.
@@ -391,7 +391,7 @@ config SYS_OHCI_SWAP_REG_ACCESS
config USB_UHCI_HCD
bool "UHCI HCD (most Intel and VIA) support"
select USB_HOST
- ---help---
+ help
The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
host controller). If your USB host controller conforms to this
@@ -410,7 +410,7 @@ config USB_DWC2
bool "DesignWare USB2 Core support"
depends on DM && OF_CONTROL
select USB_HOST
- ---help---
+ help
The DesignWare USB 2.0 controller is compliant with the
USB-Implementers Forum (USB-IF) USB 2.0 specifications.
Hi-Speed (480 Mbps), Full-Speed (12 Mbps), and Low-Speed (1.5 Mbps)
@@ -421,7 +421,7 @@ if USB_DWC2
config USB_DWC2_BUFFER_SIZE
int "Data buffer size in kB"
default 64
- ---help---
+ help
By default 64 kB buffer is used but if amount of RAM avaialble on
the target is not enough to accommodate allocation of buffer of
that size it is possible to shrink it. Smaller sizes should be fine
@@ -433,7 +433,7 @@ config USB_R8A66597_HCD
bool "Renesas R8A66597 USB Core support"
depends on DM && OF_CONTROL
select USB_HOST
- ---help---
+ help
This enables support for the on-chip Renesas R8A66597 USB 2.0
controller, present in various RZ and SH SoCs.
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
index 794a4168913..38ee17f063d 100644
--- a/drivers/usb/host/ehci-marvell.c
+++ b/drivers/usb/host/ehci-marvell.c
@@ -222,8 +222,8 @@ static void usb_brg_adrdec_setup(int index)
break;
}
- size = gd->bd->bi_dram[i].size;
- base = gd->bd->bi_dram[i].start;
+ size = gd->dram[i].size;
+ base = gd->dram[i].start;
if ((size) && (attrib))
writel(MVCPU_WIN_CTRL_DATA(size, USB_TARGET_DRAM,
attrib, MVCPU_WIN_ENABLE),
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1d6711ccec4..3fcf9d53d59 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1750,7 +1750,7 @@ static int hc_reset(ohci_t *ohci)
int timeout = 30;
int smm_timeout = 50; /* 0,5 sec */
- dbg("%s\n", __FUNCTION__);
+ dbg("%s\n", __func__);
#ifdef CONFIG_PCI_EHCI_DEVNO
/*
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 7247245a702..1c74d6fd39a 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -134,7 +134,7 @@ int usb_alloc_device(struct usb_device *udev)
struct udevice *bus = udev->controller_dev;
struct dm_usb_ops *ops = usb_get_ops(bus);
- /* This is only requird by some controllers - current XHCI */
+ /* This is only required by some controllers - currently XHCI */
if (!ops->alloc_device)
return 0;
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index 12dc61aee9d..c294a56b3c9 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -82,6 +82,7 @@ static int xhci_usb_of_to_plat(struct udevice *dev)
static const struct udevice_id xhci_usb_ids[] = {
{ .compatible = "marvell,armada3700-xhci" },
+ { .compatible = "marvell,armada-375-xhci" },
{ .compatible = "marvell,armada-380-xhci" },
{ .compatible = "marvell,armada-8k-xhci" },
{ }
diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig
index f8daaddc657..208e47d8ff5 100644
--- a/drivers/usb/musb-new/Kconfig
+++ b/drivers/usb/musb-new/Kconfig
@@ -23,11 +23,11 @@ config USB_MUSB_GADGET
if USB_MUSB_HOST || USB_MUSB_GADGET
config USB_MUSB_SC5XX
- bool "Analog Devices MUSB support"
- depends on (SC57X || SC58X)
+ bool "Analog Devices MUSB support"
+ depends on (SC57X || SC58X)
help
- Say y here to enable support for the USB controller on
- ADI SC57X/SC58X processors.
+ Say y here to enable support for the USB controller on
+ ADI SC57X/SC58X processors.
config USB_MUSB_DA8XX
bool "Enable DA8xx MUSB Controller"
@@ -48,7 +48,7 @@ config USB_MUSB_TI
silicon IP.
config USB_MUSB_OMAP2PLUS
- tristate "OMAP2430 and onwards"
+ bool "OMAP2430 and onwards"
depends on ARCH_OMAP2PLUS
config USB_MUSB_AM35X
@@ -81,9 +81,9 @@ config USB_MUSB_SUNXI
depends on PHY_SUN4I_USB
select USB_MUSB_PIO_ONLY
default y
- ---help---
- Say y here to enable support for the sunxi OTG / DRC USB controller
- used on almost all sunxi boards.
+ help
+ Say y here to enable support for the sunxi OTG / DRC USB controller
+ used on almost all sunxi boards.
config USB_MUSB_UX500
bool "Enable ST-Ericsson Ux500 USB controller"
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
index 7fd6639013a..c8c6bf0c84f 100644
--- a/drivers/usb/musb-new/omap2430.c
+++ b/drivers/usb/musb-new/omap2430.c
@@ -100,7 +100,7 @@ static int omap2430_musb_enable(struct musb *musb)
#ifdef CONFIG_TWL4030_USB
if (twl4030_usb_ulpi_init()) {
serial_printf("ERROR: %s Could not initialize PHY\n",
- __PRETTY_FUNCTION__);
+ __func__);
}
#endif
return 0;
diff --git a/drivers/usb/tcpm/Kconfig b/drivers/usb/tcpm/Kconfig
index 9be4b496e82..b1ea7253720 100644
--- a/drivers/usb/tcpm/Kconfig
+++ b/drivers/usb/tcpm/Kconfig
@@ -1,14 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
config TYPEC_TCPM
- tristate "USB Type-C Port Controller Manager"
+ bool "USB Type-C Port Controller Manager"
depends on DM
help
The Type-C Port Controller Manager provides a USB PD and USB Type-C
state machine for use with Type-C Port Controllers.
config TYPEC_FUSB302
- tristate "Fairchild FUSB302 Type-C chip driver"
+ bool "Fairchild FUSB302 Type-C chip driver"
depends on DM && DM_I2C && TYPEC_TCPM
help
The Fairchild FUSB302 Type-C chip driver that works with
diff --git a/drivers/usb/tcpm/tcpm.c b/drivers/usb/tcpm/tcpm.c
index 3061b466d7c..d6c0be82333 100644
--- a/drivers/usb/tcpm/tcpm.c
+++ b/drivers/usb/tcpm/tcpm.c
@@ -207,7 +207,7 @@ static int tcpm_pd_transmit(struct udevice *dev,
*/
timeout_us *= 5;
ret = read_poll_timeout(tcpm_transmit_helper, tx_complete,
- !tx_complete, false, timeout_us, dev);
+ tx_complete, false, timeout_us, dev);
if (ret < 0) {
dev_err(dev, "TCPM: PD transmit data failed: %d\n", ret);
return ret;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index c2acc13139c..15000e21840 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -29,6 +29,13 @@ config VIDEO_FONT_4X6
Provides character bitmap data in header file.
When selecting multiple fonts, you may want to enable CMD_SELECT_FONT too.
+config VIDEO_FONT_6X8
+ bool "6 x 8 font size"
+ help
+ Font for video console driver, 6 x 8 pixels.
+ Provides character bitmap data in header file.
+ When selecting multiple fonts, you may want to enable CMD_SELECT_FONT too.
+
config VIDEO_FONT_8X16
bool "8 x 16 font size"
default y
@@ -247,10 +254,10 @@ config SYS_WHITE_ON_BLACK
bool "Display console as white on a black background"
default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || ARCH_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
- better in low-light situations or to reduce eye strain in some
- cases.
+ 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
+ better in low-light situations or to reduce eye strain in some
+ cases.
config NO_FB_CLEAR
bool "Skip framebuffer clear"
@@ -508,10 +515,10 @@ config FRAMEBUFFER_VESA_MODE
config VIDEO_LCD_ANX9804
bool "ANX9804 bridge chip"
- ---help---
- Support for the ANX9804 bridge chip, which can take pixel data coming
- from a parallel LCD interface and translate it on the fy into a DP
- interface for driving eDP TFT displays. It uses I2C for configuration.
+ help
+ Support for the ANX9804 bridge chip, which can take pixel data coming
+ from a parallel LCD interface and translate it on the fy into a DP
+ interface for driving eDP TFT displays. It uses I2C for configuration.
config ATMEL_LCD
bool "Atmel LCD panel support"
@@ -534,7 +541,7 @@ config VIDEO_BCM2835
that U-Boot can access it with full colour depth.
config VIDEO_LCD_ENDEAVORU
- tristate "Endeavoru 720x1280 DSI video mode panel"
+ bool "Endeavoru 720x1280 DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -549,8 +556,8 @@ config VIDEO_LCD_HIMAX_HX8394
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
- Say Y here if you want to enable support for Himax HX8394
- dsi 4dl panel.
+ Say Y here if you want to enable support for Himax HX8394
+ dsi 4dl panel.
config VIDEO_LCD_ILITEK_ILI9806E
bool "Ilitek ILI9806E-based panels"
@@ -561,7 +568,7 @@ config VIDEO_LCD_ILITEK_ILI9806E
is implemented.
config VIDEO_LCD_MOT
- tristate "Atrix 4G and Droid X2 540x960 DSI video mode panel"
+ bool "Atrix 4G and Droid X2 540x960 DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -574,15 +581,15 @@ config VIDEO_LCD_NOVATEK_NT35510
bool "Novatek NT35510 DSI LCD panel support"
select VIDEO_MIPI_DSI
help
- Say Y here if you want to enable support for Novatek nt35510
- dsi panel.
+ Say Y here if you want to enable support for Novatek nt35510
+ dsi panel.
config VIDEO_LCD_ORISETECH_OTM8009A
bool "OTM8009A DSI LCD panel support"
select VIDEO_MIPI_DSI
help
- Say Y here if you want to enable support for Orise Technology
- otm8009a 480x800 dsi 2dl panel.
+ Say Y here if you want to enable support for Orise Technology
+ otm8009a 480x800 dsi 2dl panel.
config VIDEO_LCD_LG_LD070WX3
bool "LD070WX3 DSI LCD panel support"
@@ -602,13 +609,14 @@ config VIDEO_LCD_LG_LH400WV3
config VIDEO_LCD_RAYDIUM_RM68200
bool "RM68200 DSI LCD panel support"
+ depends on BACKLIGHT
select VIDEO_MIPI_DSI
help
- Say Y here if you want to enable support for Raydium RM68200
- 720x1280 DSI video mode panel.
+ Say Y here if you want to enable support for Raydium RM68200
+ 720x1280 DSI video mode panel.
config VIDEO_LCD_RENESAS_R61307
- tristate "Renesas R61307 DSI video mode panel"
+ bool "Renesas R61307 DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -617,7 +625,7 @@ config VIDEO_LCD_RENESAS_R61307
resolution and uses 24 bit RGB per pixel.
config VIDEO_LCD_RENESAS_R69328
- tristate "Renesas R69328 720x1280 DSI video mode panel"
+ bool "Renesas R69328 720x1280 DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -626,7 +634,7 @@ config VIDEO_LCD_RENESAS_R69328
resolution and uses 24 bit RGB per pixel.
config VIDEO_LCD_SAMSUNG_LTL106HL02
- tristate "Samsung LTL106HL02 1920x1080 DSI video mode panel"
+ bool "Samsung LTL106HL02 1920x1080 DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -635,7 +643,7 @@ config VIDEO_LCD_SAMSUNG_LTL106HL02
resolution (1920x1080).
config VIDEO_LCD_SHARP_LQ079L1SX01
- tristate "Sharp LQ079L1SX01 1536x2048 DSI video mode panel"
+ bool "Sharp LQ079L1SX01 1536x2048 DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -644,7 +652,7 @@ config VIDEO_LCD_SHARP_LQ079L1SX01
resolution (1536x2048).
config VIDEO_LCD_SHARP_LQ101R1SX01
- tristate "Sharp LQ101R1SX01 2560x1600 DSI video mode panel"
+ bool "Sharp LQ101R1SX01 2560x1600 DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -654,41 +662,41 @@ config VIDEO_LCD_SHARP_LQ101R1SX01
config VIDEO_LCD_SSD2828
bool "SSD2828 bridge chip"
- ---help---
- Support for the SSD2828 bridge chip, which can take pixel data coming
- from a parallel LCD interface and translate it on the fly into MIPI DSI
- interface for driving a MIPI compatible LCD panel. It uses SPI for
- configuration.
+ help
+ Support for the SSD2828 bridge chip, which can take pixel data coming
+ from a parallel LCD interface and translate it on the fly into MIPI DSI
+ interface for driving a MIPI compatible LCD panel. It uses SPI for
+ configuration.
config VIDEO_LCD_SSD2828_TX_CLK
int "SSD2828 TX_CLK frequency (in MHz)"
depends on VIDEO_LCD_SSD2828
default 0
- ---help---
- The frequency of the crystal, which is clocking SSD2828. It may be
- anything in the 8MHz-30MHz range and the exact value should be
- retrieved from the board schematics. Or in the case of Allwinner
- hardware, it can be usually found as 'lcd_xtal_freq' variable in
- FEX files. It can be also set to 0 for selecting PCLK from the
- parallel LCD interface instead of TX_CLK as the PLL clock source.
+ help
+ The frequency of the crystal, which is clocking SSD2828. It may be
+ anything in the 8MHz-30MHz range and the exact value should be
+ retrieved from the board schematics. Or in the case of Allwinner
+ hardware, it can be usually found as 'lcd_xtal_freq' variable in
+ FEX files. It can be also set to 0 for selecting PCLK from the
+ parallel LCD interface instead of TX_CLK as the PLL clock source.
config VIDEO_LCD_SSD2828_RESET
string "RESET pin of SSD2828"
depends on VIDEO_LCD_SSD2828
default ""
- ---help---
- The reset pin of SSD2828 chip. This takes a string in the format
- understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+ help
+ The reset pin of SSD2828 chip. This takes a string in the format
+ understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
config VIDEO_LCD_TDO_TL070WSH30
bool "TDO TL070WSH30 DSI LCD panel support"
select VIDEO_MIPI_DSI
help
- Say Y here if you want to enable support for TDO TL070WSH30
- 1024x600 DSI video mode panel.
+ Say Y here if you want to enable support for TDO TL070WSH30
+ 1024x600 DSI video mode panel.
config VIDEO_LCD_HITACHI_TX10D07VM0BAA
- tristate "Hitachi TX10D07VM0BAA 480x800 MIPI DSI video mode panel"
+ bool "Hitachi TX10D07VM0BAA 480x800 MIPI DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
@@ -697,13 +705,13 @@ config VIDEO_LCD_HITACHI_TX10D07VM0BAA
config VIDEO_LCD_HITACHI_TX18D42VM
bool "Hitachi tx18d42vm LVDS LCD panel support"
- ---help---
- Support for Hitachi tx18d42vm LVDS LCD panels, these panels have a
- lcd controller which needs to be initialized over SPI, once that is
- done they work like a regular LVDS panel.
+ help
+ Support for Hitachi tx18d42vm LVDS LCD panels, these panels have a
+ lcd controller which needs to be initialized over SPI, once that is
+ done they work like a regular LVDS panel.
config VIDEO_LCD_SONY_L4F00430T01
- tristate "Sony L4F00430T01 480x800 LCD panel support"
+ bool "Sony L4F00430T01 480x800 LCD panel support"
depends on PANEL
help
Say Y here if you want to enable support for Sony L4F00430T01
@@ -712,7 +720,7 @@ config VIDEO_LCD_SONY_L4F00430T01
data comes from RGB.
config VIDEO_LCD_SAMSUNG_S6E63M0
- tristate "Samsung S6E63M0 controller based panel support"
+ bool "Samsung S6E63M0 controller based panel support"
depends on PANEL && BACKLIGHT
help
Say Y here if you want to enable support for Samsung S6E63M0
@@ -723,44 +731,44 @@ config VIDEO_LCD_SPI_CS
string "SPI CS pin for LCD related config job"
depends on VIDEO_LCD_SSD2828 || VIDEO_LCD_HITACHI_TX18D42VM
default ""
- ---help---
- This is one of the SPI communication pins, involved in setting up a
- working LCD configuration. The exact role of SPI may differ for
- different hardware setups. The option takes a string in the format
- understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+ help
+ This is one of the SPI communication pins, involved in setting up a
+ working LCD configuration. The exact role of SPI may differ for
+ different hardware setups. The option takes a string in the format
+ understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
config VIDEO_LCD_SPI_SCLK
string "SPI SCLK pin for LCD related config job"
depends on VIDEO_LCD_SSD2828 || VIDEO_LCD_HITACHI_TX18D42VM
default ""
- ---help---
- This is one of the SPI communication pins, involved in setting up a
- working LCD configuration. The exact role of SPI may differ for
- different hardware setups. The option takes a string in the format
- understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+ help
+ This is one of the SPI communication pins, involved in setting up a
+ working LCD configuration. The exact role of SPI may differ for
+ different hardware setups. The option takes a string in the format
+ understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
config VIDEO_LCD_SPI_MOSI
string "SPI MOSI pin for LCD related config job"
depends on VIDEO_LCD_SSD2828 || VIDEO_LCD_HITACHI_TX18D42VM
default ""
- ---help---
- This is one of the SPI communication pins, involved in setting up a
- working LCD configuration. The exact role of SPI may differ for
- different hardware setups. The option takes a string in the format
- understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
+ help
+ This is one of the SPI communication pins, involved in setting up a
+ working LCD configuration. The exact role of SPI may differ for
+ different hardware setups. The option takes a string in the format
+ understood by 'sunxi_name_to_gpio' function, e.g. PH1 for pin 1 of port H.
config VIDEO_LCD_SPI_MISO
string "SPI MISO pin for LCD related config job (optional)"
depends on VIDEO_LCD_SSD2828
default ""
- ---help---
- This is one of the SPI communication pins, involved in setting up a
- working LCD configuration. The exact role of SPI may differ for
- different hardware setups. If wired up, this pin may provide additional
- useful functionality. Such as bi-directional communication with the
- hardware and LCD panel id retrieval (if the panel can report it). The
- option takes a string in the format understood by 'sunxi_name_to_gpio'
- function, e.g. PH1 for pin 1 of port H.
+ help
+ This is one of the SPI communication pins, involved in setting up a
+ working LCD configuration. The exact role of SPI may differ for
+ different hardware setups. If wired up, this pin may provide additional
+ useful functionality. Such as bi-directional communication with the
+ hardware and LCD panel id retrieval (if the panel can report it). The
+ option takes a string in the format understood by 'sunxi_name_to_gpio'
+ function, e.g. PH1 for pin 1 of port H.
source "drivers/video/meson/Kconfig"
@@ -768,9 +776,9 @@ config VIDEO_MVEBU
bool "Armada XP LCD controller"
depends on ARCH_MVEBU
imply VIDEO_DAMAGE
- ---help---
- Support for the LCD controller integrated in the Marvell
- Armada XP SoC.
+ help
+ Support for the LCD controller integrated in the Marvell
+ Armada XP SoC.
config VIDEO_OMAP3
bool "Enable OMAP3+ DSS Support"
@@ -781,23 +789,23 @@ config VIDEO_OMAP3
config I2C_EDID
bool "Enable EDID library"
help
- This enables library for accessing EDID data from an LCD panel.
+ This enables library for accessing EDID data from an LCD panel.
config I2C_EDID_STANDARD
bool "Enable standard timings EDID library expansion"
depends on I2C_EDID
help
- This enables standard timings expansion for EDID data from an LCD panel.
+ This enables standard timings expansion for EDID data from an LCD panel.
config DISPLAY
bool "Enable Display support"
depends on DM
select I2C_EDID
help
- This supports drivers that provide a display, such as eDP (Embedded
- DisplayPort) and HDMI (High Definition Multimedia Interface).
- The devices provide a simple interface to start up the display,
- read display information and enable it.
+ This supports drivers that provide a display, such as eDP (Embedded
+ DisplayPort) and HDMI (High Definition Multimedia Interface).
+ The devices provide a simple interface to start up the display,
+ read display information and enable it.
config NXP_TDA19988
bool "Enable NXP TDA19988 support"
@@ -811,7 +819,7 @@ config ATMEL_HLCD
depends on ARCH_AT91
imply VIDEO_DAMAGE
help
- HLCDC supports video output to an attached LCD panel.
+ HLCDC supports video output to an attached LCD panel.
config BACKLIGHT_AAT2870
bool "Backlight Driver for AAT2870"
@@ -865,7 +873,7 @@ source "drivers/video/exynos/Kconfig"
config LOGICORE_DP_TX
bool "Enable Logicore DP TX driver"
- depends on DISPLAY
+ depends on DISPLAY && AXI
help
Enable the driver for the transmitter part of the Xilinx LogiCORE
DisplayPort, a IP core for Xilinx FPGAs that implements a DisplayPort
@@ -930,9 +938,9 @@ config VIDEO_NX
bool "Enable video support on Nexell SoC"
depends on ARCH_S5P6818 || ARCH_S5P4418
help
- Nexell SoC supports many video output options including eDP and
- HDMI. This option enables this support which can be used on devices
- which have an eDP display connected.
+ Nexell SoC supports many video output options including eDP and
+ HDMI. This option enables this support which can be used on devices
+ which have an eDP display connected.
config VIDEO_SEPS525
bool "Enable video support for Seps525"
@@ -1018,9 +1026,9 @@ config OSD
bool "Enable OSD support"
depends on DM
help
- This supports drivers that provide a OSD (on-screen display), which
- is a (usually text-oriented) graphics buffer to show information on
- a display.
+ This supports drivers that provide a OSD (on-screen display), which
+ is a (usually text-oriented) graphics buffer to show information on
+ a display.
config SANDBOX_OSD
bool "Enable sandbox OSD"
@@ -1213,10 +1221,10 @@ config SPL_SPLASH_SCREEN
config SPL_SYS_WHITE_ON_BLACK
bool "Display console as white on a black background at SPL"
help
- Normally the display is black on a white background, Enable this
- option to invert this, i.e. white on a black background at spl stage.
- This can be better in low-light situations or to reduce eye strain in
- some cases.
+ Normally the display is black on a white background, Enable this
+ option to invert this, i.e. white on a black background at spl stage.
+ This can be better in low-light situations or to reduce eye strain in
+ some cases.
config SPL_VIDEO_PCI_DEFAULT_FB_SIZE
hex "Default framebuffer size to use if no drivers request it at SPL"
@@ -1279,10 +1287,10 @@ config SPL_SIMPLE_PANEL
config SPL_SYS_WHITE_ON_BLACK
bool "Display console as white on a black background at SPL"
help
- Normally the display is black on a white background, Enable this
- option to invert this, i.e. white on a black background at spl stage.
- This can be better in low-light situations or to reduce eye strain in
- some cases.
+ Normally the display is black on a white background, Enable this
+ option to invert this, i.e. white on a black background at spl stage.
+ This can be better in low-light situations or to reduce eye strain in
+ some cases.
config SPL_VIDEO_REMOVE
bool "Remove video driver after SPL stage"
@@ -1408,13 +1416,13 @@ config SPL_VIDEO_BPP32
will be empty.
config SPL_HIDE_LOGO_VERSION
- bool "Hide the version information on the splash screen at SPL"
- help
- Normally the U-Boot version string is shown on the display when the
- splash screen is enabled. This information is not otherwise visible
- since video starts up after U-Boot has displayed the initial banner.
+ bool "Hide the version information on the splash screen at SPL"
+ help
+ Normally the U-Boot version string is shown on the display when the
+ splash screen is enabled. This information is not otherwise visible
+ since video starts up after U-Boot has displayed the initial banner.
- Enable this option to hide this information.
+ Enable this option to hide this information.
endif
endmenu
diff --git a/drivers/video/bridge/Kconfig b/drivers/video/bridge/Kconfig
index 5322a002928..81261c61005 100644
--- a/drivers/video/bridge/Kconfig
+++ b/drivers/video/bridge/Kconfig
@@ -41,8 +41,8 @@ config VIDEO_BRIDGE_ANALOGIX_ANX6345
depends on VIDEO_BRIDGE
select DM_I2C
help
- The Analogix ANX6345 is RGB-to-DP converter. It enables an eDP LCD
- panel to be connected to an parallel LCD interface.
+ The Analogix ANX6345 is RGB-to-DP converter. It enables an eDP LCD
+ panel to be connected to an parallel LCD interface.
config VIDEO_BRIDGE_SOLOMON_SSD2825
bool "Solomon SSD2825 bridge driver"
diff --git a/drivers/video/bridge/anx6345.c b/drivers/video/bridge/anx6345.c
index 8cee4c958bd..a5d2781aa48 100644
--- a/drivers/video/bridge/anx6345.c
+++ b/drivers/video/bridge/anx6345.c
@@ -403,7 +403,7 @@ static int anx6345_probe(struct udevice *dev)
return anx6345_enable(dev);
}
-struct video_bridge_ops anx6345_ops = {
+static const struct video_bridge_ops anx6345_ops = {
.attach = anx6345_attach,
.set_backlight = anx6345_set_backlight,
.read_edid = anx6345_read_edid,
diff --git a/drivers/video/bridge/ps862x.c b/drivers/video/bridge/ps862x.c
index efd03752281..a08227f8355 100644
--- a/drivers/video/bridge/ps862x.c
+++ b/drivers/video/bridge/ps862x.c
@@ -116,7 +116,7 @@ static int ps8622_probe(struct udevice *dev)
return 0;
}
-struct video_bridge_ops ps8622_ops = {
+static const struct video_bridge_ops ps8622_ops = {
.attach = ps8622_attach,
.set_backlight = ps8622_set_backlight,
};
diff --git a/drivers/video/bridge/ptn3460.c b/drivers/video/bridge/ptn3460.c
index 5851e1ef15e..ce576c0b282 100644
--- a/drivers/video/bridge/ptn3460.c
+++ b/drivers/video/bridge/ptn3460.c
@@ -15,7 +15,7 @@ static int ptn3460_attach(struct udevice *dev)
return video_bridge_set_active(dev, true);
}
-struct video_bridge_ops ptn3460_ops = {
+static const struct video_bridge_ops ptn3460_ops = {
.attach = ptn3460_attach,
};
diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index 07db613ac53..6dc0a6eaf9d 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -133,7 +133,7 @@ static int console_set_cursor_visible(struct udevice *dev, bool visible,
return 0;
}
-struct vidconsole_ops console_ops = {
+static const struct vidconsole_ops console_ops = {
.putc_xy = console_putc_xy,
.move_rows = console_move_rows,
.set_row = console_set_row,
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index 886b25dcfaf..e478e0ef3bc 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -284,7 +284,7 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp)
return VID_TO_POS(fontdata->width);
}
-struct vidconsole_ops console_ops_1 = {
+static const struct vidconsole_ops console_ops_1 = {
.putc_xy = console_putc_xy_1,
.move_rows = console_move_rows_1,
.set_row = console_set_row_1,
@@ -293,7 +293,7 @@ struct vidconsole_ops console_ops_1 = {
.select_font = console_simple_select_font,
};
-struct vidconsole_ops console_ops_2 = {
+static const struct vidconsole_ops console_ops_2 = {
.putc_xy = console_putc_xy_2,
.move_rows = console_move_rows_2,
.set_row = console_set_row_2,
@@ -302,7 +302,7 @@ struct vidconsole_ops console_ops_2 = {
.select_font = console_simple_select_font,
};
-struct vidconsole_ops console_ops_3 = {
+static const struct vidconsole_ops console_ops_3 = {
.putc_xy = console_putc_xy_3,
.move_rows = console_move_rows_3,
.set_row = console_set_row_3,
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index eaf169e8386..b9b6f394fbc 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -1069,7 +1069,7 @@ static int console_truetype_probe(struct udevice *dev)
return 0;
}
-struct vidconsole_ops console_truetype_ops = {
+static const struct vidconsole_ops console_truetype_ops = {
.putc_xy = console_truetype_putc_xy,
.move_rows = console_truetype_move_rows,
.set_row = console_truetype_set_row,
diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c
index c74fe678d12..ec5d4c81812 100644
--- a/drivers/video/dw_mipi_dsi.c
+++ b/drivers/video/dw_mipi_dsi.c
@@ -837,7 +837,7 @@ static int dw_mipi_dsi_enable(struct udevice *dev)
return 0;
}
-struct dsi_host_ops dw_mipi_dsi_ops = {
+static const struct dsi_host_ops dw_mipi_dsi_ops = {
.init = dw_mipi_dsi_init,
.enable = dw_mipi_dsi_enable,
};
diff --git a/drivers/video/imx/Kconfig b/drivers/video/imx/Kconfig
index c25f209629e..0c386595559 100644
--- a/drivers/video/imx/Kconfig
+++ b/drivers/video/imx/Kconfig
@@ -20,7 +20,7 @@ config IPU_CLK_LEGACY
depends on VIDEO_IPUV3 && !CLK
default y
help
- Use legacy clock management instead of Common Clock Framework.
+ Use legacy clock management instead of Common Clock Framework.
config IMX_LDB
bool "Freescale i.MX8MP LDB bridge"
diff --git a/drivers/video/imx/ipu.h b/drivers/video/imx/ipu.h
index ae40e20bc28..aecb6adffce 100644
--- a/drivers/video/imx/ipu.h
+++ b/drivers/video/imx/ipu.h
@@ -136,7 +136,6 @@ struct ipu_ctx {
struct clk *ipu_clk;
struct clk *ldb_clk;
- unsigned char ipu_clk_enabled;
struct clk *di_clk[2];
struct clk *pixel_clk[2];
diff --git a/drivers/video/imx/ipu_common.c b/drivers/video/imx/ipu_common.c
index 8630374a055..d3b52605731 100644
--- a/drivers/video/imx/ipu_common.c
+++ b/drivers/video/imx/ipu_common.c
@@ -299,9 +299,9 @@ struct ipu_ctx *ipu_probe(struct udevice *dev)
#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
clk_set_parent(ctx->pixel_clk[0], ctx->ipu_clk);
clk_set_parent(ctx->pixel_clk[1], ctx->ipu_clk);
+#endif
clk_enable(ctx->ipu_clk);
-#endif
for (int i = 0; i <= 1; i++) {
ret = ipu_di_clk_init(ctx, i);
@@ -384,10 +384,8 @@ int32_t ipu_init_channel(struct ipu_ctx *ctx, ipu_channel_t channel,
debug("init channel = %d\n", IPU_CHAN_ID(channel));
- if (ctx->ipu_clk_enabled == 0) {
- ctx->ipu_clk_enabled = 1;
+ if (!ipu_clk_enabled(ctx))
clk_enable(ipu_clk);
- }
if (*channel_init_mask & (1L << IPU_CHAN_ID(channel))) {
printf("Warning: channel already initialized %d\n",
@@ -543,7 +541,6 @@ void ipu_uninit_channel(struct ipu_ctx *ctx, ipu_channel_t channel)
if (ipu_conf == 0) {
clk_disable(ctx->ipu_clk);
- ctx->ipu_clk_enabled = 0;
}
}
@@ -1045,5 +1042,9 @@ ipu_color_space_t format_to_colorspace(u32 fmt)
bool ipu_clk_enabled(struct ipu_ctx *ctx)
{
- return ctx->ipu_clk_enabled;
+#if CONFIG_IS_ENABLED(IPU_CLK_LEGACY)
+ return clk_get_usecount(ctx->ipu_clk);
+#else
+ return ctx->ipu_clk->enable_count;
+#endif
}
diff --git a/drivers/video/imx/ldb.c b/drivers/video/imx/ldb.c
index e918341c0a3..32a327647f8 100644
--- a/drivers/video/imx/ldb.c
+++ b/drivers/video/imx/ldb.c
@@ -230,7 +230,7 @@ dis_clk:
return ret;
}
-struct video_bridge_ops imx_ldb_ops = {
+static const struct video_bridge_ops imx_ldb_ops = {
.attach = imx_ldb_attach,
.set_backlight = imx_ldb_set_backlight,
};
diff --git a/drivers/video/meson/meson_vpu.c b/drivers/video/meson/meson_vpu.c
index ca627728743..a686faf9f58 100644
--- a/drivers/video/meson/meson_vpu.c
+++ b/drivers/video/meson/meson_vpu.c
@@ -81,8 +81,8 @@ cvbs:
meson_fb.fb_size = ALIGN(meson_fb.xsize * meson_fb.ysize *
((1 << VPU_MAX_LOG2_BPP) / 8) +
MESON_VPU_OVERSCAN, EFI_PAGE_SIZE);
- meson_fb.base = gd->bd->bi_dram[0].start +
- gd->bd->bi_dram[0].size - meson_fb.fb_size;
+ meson_fb.base = gd->dram[0].start +
+ gd->dram[0].size - meson_fb.fb_size;
/* Override the framebuffer address */
uc_plat->base = meson_fb.base;
@@ -175,8 +175,8 @@ static void meson_vpu_setup_simplefb(void *fdt)
* at the end of the RAM and we strip this portion from the kernel
* allowed region
*/
- mem_start = gd->bd->bi_dram[0].start;
- mem_size = gd->bd->bi_dram[0].size - meson_fb.fb_size;
+ mem_start = gd->dram[0].start;
+ mem_size = gd->dram[0].size - meson_fb.fb_size;
ret = fdt_fixup_memory_banks(fdt, &mem_start, &mem_size, 1);
if (ret) {
eprintf("Cannot setup simplefb: Error reserving memory\n");
diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig
index 96af6d28ef0..41d249cb90c 100644
--- a/drivers/video/rockchip/Kconfig
+++ b/drivers/video/rockchip/Kconfig
@@ -21,7 +21,7 @@ menuconfig VIDEO_ROCKCHIP
Rockchip RK3288 and RK3399.
config VIDEO_ROCKCHIP_MAX_XRES
- int "Maximum horizontal resolution (for memory allocation purposes)"
+ int "Maximum horizontal resolution (for memory allocation purposes)"
depends on VIDEO_ROCKCHIP
default 3840 if DISPLAY_ROCKCHIP_HDMI
default 1920
@@ -31,7 +31,7 @@ config VIDEO_ROCKCHIP_MAX_XRES
framebuffer during device-model binding/probing.
config VIDEO_ROCKCHIP_MAX_YRES
- int "Maximum vertical resolution (for memory allocation purposes)"
+ int "Maximum vertical resolution (for memory allocation purposes)"
depends on VIDEO_ROCKCHIP
default 2160 if DISPLAY_ROCKCHIP_HDMI
default 1080
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c
index 8d0772d4e51..631ae00b1e1 100644
--- a/drivers/video/simplefb.c
+++ b/drivers/video/simplefb.c
@@ -9,6 +9,8 @@
#include <log.h>
#include <video.h>
#include <asm/global_data.h>
+#include <asm/system.h>
+#include <linux/sizes.h>
static int simple_video_probe(struct udevice *dev)
{
@@ -20,8 +22,14 @@ static int simple_video_probe(struct udevice *dev)
fdt_addr_t base;
fdt_size_t size;
u32 width, height, stride, rot;
+ struct ofnode_phandle_args args;
+
+ ret = dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 0, &args);
+ if (ret)
+ base = dev_read_addr_size(dev, &size);
+ else
+ base = ofnode_get_addr_size(args.node, "reg", &size);
- base = dev_read_addr_size(dev, &size);
if (base == FDT_ADDR_T_NONE) {
debug("%s: Failed to decode memory region\n", __func__);
return -EINVAL;
@@ -37,6 +45,13 @@ static int simple_video_probe(struct udevice *dev)
plat->base = base;
plat->size = size;
+#ifdef CONFIG_ARM64
+ /* The framebuffer buffer might not be mapped on some devices */
+ if (plat->base % SZ_4K)
+ log_warning("Framebuffer base %lx is not 4k aligned!\n", plat->base);
+ mmu_map_region((phys_addr_t)plat->base, (phys_addr_t)ALIGN(plat->size, SZ_4K), false);
+#endif
+
video_set_flush_dcache(dev, true);
debug("%s: Query resolution...\n", __func__);
diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c
index 5c4d8d2aab5..29c57a4ff89 100644
--- a/drivers/video/stm32/stm32_dsi.c
+++ b/drivers/video/stm32/stm32_dsi.c
@@ -511,7 +511,7 @@ err_reg:
return ret;
}
-struct video_bridge_ops stm32_dsi_ops = {
+static const struct video_bridge_ops stm32_dsi_ops = {
.attach = stm32_dsi_attach,
.set_backlight = stm32_dsi_set_backlight,
};
diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c
index 154641b9a69..ab36ee1595b 100644
--- a/drivers/video/sunxi/sunxi_de2.c
+++ b/drivers/video/sunxi/sunxi_de2.c
@@ -368,7 +368,7 @@ int sunxi_simplefb_setup(void *blob)
return 0; /* Keep older kernels working */
}
- start = gd->bd->bi_dram[0].start;
+ start = gd->dram[0].start;
size = de2_plat->base - start;
ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
if (ret) {
diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
index 4a6a89ef9d2..fa492c661db 100644
--- a/drivers/video/sunxi/sunxi_display.c
+++ b/drivers/video/sunxi/sunxi_display.c
@@ -1336,7 +1336,7 @@ int sunxi_simplefb_setup(void *blob)
* and e.g. Linux refuses to iomap RAM on ARM, see:
* linux/arch/arm/mm/ioremap.c around line 301.
*/
- start = gd->bd->bi_dram[0].start;
+ start = gd->dram[0].start;
size = sunxi_display->fb_addr - start;
ret = fdt_fixup_memory_banks(blob, &start, &size, 1);
if (ret) {
diff --git a/drivers/video/tda19988.c b/drivers/video/tda19988.c
index ebc8521c6ed..a4cc3a49232 100644
--- a/drivers/video/tda19988.c
+++ b/drivers/video/tda19988.c
@@ -522,7 +522,7 @@ static int tda19988_enable(struct udevice *dev, int panel_bpp,
return 0;
}
-struct dm_display_ops tda19988_ops = {
+static const struct dm_display_ops tda19988_ops = {
.read_edid = tda19988_read_edid,
.enable = tda19988_enable,
};
diff --git a/drivers/video/tegra/Kconfig b/drivers/video/tegra/Kconfig
index 8bc29f2838b..125504024fc 100644
--- a/drivers/video/tegra/Kconfig
+++ b/drivers/video/tegra/Kconfig
@@ -9,13 +9,13 @@ config VIDEO_TEGRA
depends on OF_CONTROL && ARCH_TEGRA
select HOST1X_TEGRA
help
- Enable support for Display Controller found in Tegra SoC. The
- Display Controller Complex integrates two independent display
- controllers. Each display controller is capable of interfacing
- to an external display device, which can be a parallel interface
- or SPI LCD, DVI, an HDMI HDTV, RGB monitor or a MIPI DSI LCD.
- Direct interface is supported directly to most LCD displays with
- TFT or TFT-like interface.
+ Enable support for Display Controller found in Tegra SoC. The
+ Display Controller Complex integrates two independent display
+ controllers. Each display controller is capable of interfacing
+ to an external display device, which can be a parallel interface
+ or SPI LCD, DVI, an HDMI HDTV, RGB monitor or a MIPI DSI LCD.
+ Direct interface is supported directly to most LCD displays with
+ TFT or TFT-like interface.
config VIDEO_DSI_TEGRA
bool "Enable DSI controller support on Tegra devices"
@@ -23,9 +23,9 @@ config VIDEO_DSI_TEGRA
select VIDEO_TEGRA
select VIDEO_MIPI_DSI
help
- Enable support for the Display Serial Interface (DSI) found in
- Tegra SoC. It is a MIPI standard serial bitstream, intended to
- provide a low pin count interface to a display panel.
+ Enable support for the Display Serial Interface (DSI) found in
+ Tegra SoC. It is a MIPI standard serial bitstream, intended to
+ provide a low pin count interface to a display panel.
config VIDEO_HDMI_TEGRA
bool "Enable HDMI support on Tegra devices"
@@ -33,31 +33,31 @@ config VIDEO_HDMI_TEGRA
select I2C_EDID
select VIDEO_TEGRA
help
- Enable support for the High-Definition Multimedia Interface (HDMI)
- found in Tegra SoC.
+ Enable support for the High-Definition Multimedia Interface (HDMI)
+ found in Tegra SoC.
config TEGRA_BACKLIGHT_PWM
bool "Enable Tegra DC PWM backlight support"
depends on BACKLIGHT && VIDEO_TEGRA
help
- Enable support for the Display Controller dependent PWM backlight
- found in the Tegra SoC and usually used with DSI panels.
+ Enable support for the Display Controller dependent PWM backlight
+ found in the Tegra SoC and usually used with DSI panels.
config TEGRA_8BIT_CPU_BRIDGE
bool "Enable 8 bit panel communication protocol for Tegra 20/30"
depends on VIDEO_BRIDGE && DM_GPIO && VIDEO_TEGRA
select VIDEO_MIPI_DSI
help
- Tegra 20 and Tegra 30 feature 8 bit CPU driver panel control
- protocol. This option allows use it as a MIPI DSI bridge to
- set up and control compatible panel.
+ Tegra 20 and Tegra 30 feature 8 bit CPU driver panel control
+ protocol. This option allows use it as a MIPI DSI bridge to
+ set up and control compatible panel.
config VIDEO_TEGRA124
bool "Enable video support on Tegra124"
depends on ARCH_TEGRA
imply VIDEO_DAMAGE
help
- Tegra124 supports many video output options including eDP and
- HDMI. At present only eDP is supported by U-Boot. This option
- enables this support which can be used on devices which
- have an eDP display connected.
+ Tegra124 supports many video output options including eDP and
+ HDMI. At present only eDP is supported by U-Boot. This option
+ enables this support which can be used on devices which
+ have an eDP display connected.
diff --git a/drivers/video/tegra/dsi.c b/drivers/video/tegra/dsi.c
index bc308869f4e..f53fabf6fd6 100644
--- a/drivers/video/tegra/dsi.c
+++ b/drivers/video/tegra/dsi.c
@@ -337,7 +337,7 @@ static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
return count;
}
-struct mipi_dsi_host_ops tegra_dsi_bridge_host_ops = {
+static const struct mipi_dsi_host_ops tegra_dsi_bridge_host_ops = {
.transfer = tegra_dsi_host_transfer,
};
diff --git a/drivers/video/ti/Kconfig b/drivers/video/ti/Kconfig
index 0483f760ea1..a3cbefef0de 100644
--- a/drivers/video/ti/Kconfig
+++ b/drivers/video/ti/Kconfig
@@ -6,4 +6,4 @@ config AM335X_LCD
bool "Enable AM335x video support"
depends on ARCH_OMAP2PLUS
help
- Supports video output to an attached LCD panel.
+ Supports video output to an attached LCD panel.
diff --git a/drivers/video/tidss/Kconfig b/drivers/video/tidss/Kconfig
index 3291b3ceb8d..c9849110059 100644
--- a/drivers/video/tidss/Kconfig
+++ b/drivers/video/tidss/Kconfig
@@ -10,7 +10,7 @@
menuconfig VIDEO_TIDSS
bool "Enable TIDSS video support"
- depends on VIDEO
+ depends on VIDEO && PANEL
imply VIDEO_DAMAGE
help
TIDSS supports video output options LVDS and
@@ -19,7 +19,7 @@ menuconfig VIDEO_TIDSS
config SPL_VIDEO_TIDSS
bool "Enable TIDSS video support in SPL Stage"
- depends on SPL_VIDEO
+ depends on SPL_VIDEO && SPL_PANEL
help
This options enables tidss driver in SPL stage. If
you need to use tidss at SPL stage use this config.
diff --git a/drivers/video/zynqmp/Kconfig b/drivers/video/zynqmp/Kconfig
index b35cd1fb342..2c737710639 100644
--- a/drivers/video/zynqmp/Kconfig
+++ b/drivers/video/zynqmp/Kconfig
@@ -3,6 +3,6 @@ config VIDEO_ZYNQMP_DPSUB
bool "Enable video support for ZynqMP Display Port"
depends on ZYNQMP_POWER_DOMAIN
help
- Enable support for Xilinx ZynqMP Display Port. Currently this file
- is used as placeholder for driver. The main reason is to record
- compatible string and calling power domain driver.
+ Enable support for Xilinx ZynqMP Display Port. Currently this file
+ is used as placeholder for driver. The main reason is to record
+ compatible string and calling power domain driver.
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index c36e9e9b3a7..a871a1439d4 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -400,9 +400,6 @@ UCLASS_DRIVER(virtio) = {
.per_device_auto = sizeof(struct virtio_dev_priv),
};
-struct bootdev_ops virtio_bootdev_ops = {
-};
-
static const struct udevice_id virtio_bootdev_ids[] = {
{ .compatible = "u-boot,bootdev-virtio" },
{ }
@@ -411,7 +408,6 @@ static const struct udevice_id virtio_bootdev_ids[] = {
U_BOOT_DRIVER(virtio_bootdev) = {
.name = "virtio_bootdev",
.id = UCLASS_BOOTDEV,
- .ops = &virtio_bootdev_ops,
.bind = virtio_bootdev_bind,
.of_match = virtio_bootdev_ids,
};
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
index 7b1d891cdcb..404d9140cb2 100644
--- a/drivers/virtio/virtio_blk.c
+++ b/drivers/virtio/virtio_blk.c
@@ -232,14 +232,11 @@ static int virtio_blk_bind(struct udevice *dev)
return devnum;
desc->devnum = devnum;
desc->part_type = PART_TYPE_UNKNOWN;
- /*
- * virtio mmio transport supplies string identification for us,
- * while pci trnasport uses a 2-byte subvendor value.
- */
- if (uc_priv->vendor >> 16)
- sprintf(desc->vendor, "%s", (char *)&uc_priv->vendor);
+
+ if (uc_priv->vendor == VIRTIO_VENDOR_QEMU)
+ strcpy(desc->vendor, "QEMU");
else
- sprintf(desc->vendor, "%04x", uc_priv->vendor);
+ sprintf(desc->vendor, "%08x", uc_priv->vendor);
desc->bdev = dev;
/* Indicate what driver features we support */
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index d90d8309f99..975f98cd9e5 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -12,6 +12,7 @@
#include <virtio_types.h>
#include <virtio.h>
#include <virtio_ring.h>
+#include <virtio_mmio.h>
#include <linux/bug.h>
#include <linux/compat.h>
#include <linux/err.h>
@@ -335,21 +336,28 @@ static int virtio_mmio_notify(struct udevice *udev, struct virtqueue *vq)
static int virtio_mmio_of_to_plat(struct udevice *udev)
{
- struct virtio_mmio_priv *priv = dev_get_priv(udev);
+ struct virtio_mmio_plat *plat = dev_get_plat(udev);
+ fdt_addr_t addr;
+
+ addr = dev_read_addr(udev);
- priv->base = (void __iomem *)(ulong)dev_read_addr(udev);
- if (priv->base == (void __iomem *)FDT_ADDR_T_NONE)
+ if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
+ plat->base = addr;
+
return 0;
}
static int virtio_mmio_probe(struct udevice *udev)
{
+ struct virtio_mmio_plat *plat = dev_get_plat(udev);
struct virtio_mmio_priv *priv = dev_get_priv(udev);
struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
u32 magic;
+ priv->base = (void __iomem *)(uintptr_t)plat->base;
+
/* Check magic value */
magic = readl(priv->base + VIRTIO_MMIO_MAGIC_VALUE);
if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
@@ -405,11 +413,12 @@ static const struct udevice_id virtio_mmio_ids[] = {
};
U_BOOT_DRIVER(virtio_mmio) = {
- .name = "virtio-mmio",
- .id = UCLASS_VIRTIO,
- .of_match = virtio_mmio_ids,
- .ops = &virtio_mmio_ops,
- .probe = virtio_mmio_probe,
+ .name = "virtio-mmio",
+ .id = UCLASS_VIRTIO,
+ .of_match = virtio_mmio_ids,
+ .ops = &virtio_mmio_ops,
+ .probe = virtio_mmio_probe,
.of_to_plat = virtio_mmio_of_to_plat,
- .priv_auto = sizeof(struct virtio_mmio_priv),
+ .priv_auto = sizeof(struct virtio_mmio_priv),
+ .plat_auto = sizeof(struct virtio_mmio_plat),
};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 9ea617f1e43..b91727e1265 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -217,6 +217,7 @@ config SPL_WDT_GPIO
config WDT_MAX6370
bool "MAX6370 watchdog timer support"
depends on WDT
+ select GPIO
select DM_GPIO
help
Select this to enable max6370 watchdog timer.
@@ -383,10 +384,10 @@ config WDT_SBSA
bool "SBSA watchdog timer support"
depends on WDT
help
- Select this to enable SBSA watchdog timer.
- This driver can operate ARM SBSA Generic Watchdog as a single stage.
- In the single stage mode, when the timeout is reached, your system
- will be reset by WS1. The first signal (WS0) is ignored.
+ Select this to enable SBSA watchdog timer.
+ This driver can operate ARM SBSA Generic Watchdog as a single stage.
+ In the single stage mode, when the timeout is reached, your system
+ will be reset by WS1. The first signal (WS0) is ignored.
config WDT_SIEMENS_PMIC
bool "Enable PMIC Watchdog Timer support for Siemens platforms"
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
index bd9d7105366..91228de5e8e 100644
--- a/drivers/watchdog/designware_wdt.c
+++ b/drivers/watchdog/designware_wdt.c
@@ -122,7 +122,7 @@ static int designware_wdt_probe(struct udevice *dev)
return ret;
ret = clk_enable(&clk);
- if (ret)
+ if (ret && ret != -ENOSYS)
return ret;
priv->clk_khz = clk_get_rate(&clk) / 1000;
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 7fcb866f574..068f99c5fc6 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -81,7 +81,7 @@ static int mpc8xxx_wdt_of_to_plat(struct udevice *dev)
{
struct mpc8xxx_wdt_priv *priv = dev_get_priv(dev);
- priv->base = (void __iomem *)devfdt_remap_addr(dev);
+ priv->base = (void __iomem *)dev_remap_addr(dev);
if (!priv->base)
return -EINVAL;
diff --git a/drivers/watchdog/octeontx_wdt.c b/drivers/watchdog/octeontx_wdt.c
index c79d9539c13..7299a9f9739 100644
--- a/drivers/watchdog/octeontx_wdt.c
+++ b/drivers/watchdog/octeontx_wdt.c
@@ -159,7 +159,8 @@ static const struct octeontx_wdt_data octeon_data = {
};
static const struct udevice_id octeontx_wdt_ids[] = {
- { .compatible = "arm,sbsa-gwdt", .data = (ulong)&octeontx_data },
+ { .compatible = "marvell,cn10624-wdt", .data = (ulong)&octeontx_data },
+ { .compatible = "marvell,cn9670-wdt", .data = (ulong)&octeontx_data },
{ .compatible = "cavium,octeon-7890-ciu3", .data = (ulong)&octeon_data },
{}
};
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index a2000b968c9..5a6cad135aa 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -40,8 +40,14 @@ struct orion_wdt_priv {
#define TIMER_A370_STATUS 0x04
#define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
+#define TIMER1_FIXED_ENABLE_BIT BIT(12)
#define WDT_A370_EXPIRED BIT(31)
+struct orion_watchdog_data {
+ int (*plat_start)(struct udevice *dev, u64 timeout, ulong flags);
+ int (*plat_stop)(struct udevice *dev);
+};
+
static int orion_wdt_reset(struct udevice *dev)
{
struct orion_wdt_priv *priv = dev_get_priv(dev);
@@ -53,7 +59,59 @@ static int orion_wdt_reset(struct udevice *dev)
return 0;
}
-static int orion_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+static int armadaxp_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+ struct orion_wdt_priv *priv = dev_get_priv(dev);
+ u32 reg;
+
+ priv->timeout = DIV_ROUND_UP(timeout_ms, 1000);
+
+ /* Fix the wdt and timer1 clock freqency to 25MHz */
+ reg = readl(priv->reg + TIMER_CTRL);
+ reg |= (WDT_AXP_FIXED_ENABLE_BIT | TIMER1_FIXED_ENABLE_BIT);
+ writel(reg, priv->reg + TIMER_CTRL);
+
+ /* Set watchdog duration */
+ writel(priv->clk_rate * priv->timeout,
+ priv->reg + priv->wdt_counter_offset);
+
+ /* Clear the watchdog expiration bit */
+ reg = readl(priv->reg + TIMER_A370_STATUS);
+ reg &= ~WDT_A370_EXPIRED;
+ writel(reg, priv->reg + TIMER_A370_STATUS);
+
+ /* Enable watchdog timer */
+ reg = readl(priv->reg + TIMER_CTRL);
+ reg |= WDT_ENABLE_BIT;
+ writel(reg, priv->reg + TIMER_CTRL);
+
+ /* Enable reset on watchdog */
+ reg = readl(priv->rstout);
+ reg |= RSTOUT_ENABLE_BIT;
+ writel(reg, priv->rstout);
+
+ return 0;
+}
+
+static int armadaxp_wdt_stop(struct udevice *dev)
+{
+ struct orion_wdt_priv *priv = dev_get_priv(dev);
+ u32 reg;
+
+ /* Disable reset on watchdog */
+ reg = readl(priv->rstout);
+ reg &= ~RSTOUT_ENABLE_BIT;
+ writel(reg, priv->rstout);
+
+ /* Disable watchdog timer */
+ reg = readl(priv->reg + TIMER_CTRL);
+ reg &= ~WDT_ENABLE_BIT;
+ writel(reg, priv->reg + TIMER_CTRL);
+
+ return 0;
+}
+
+static int armada380_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
{
struct orion_wdt_priv *priv = dev_get_priv(dev);
u32 reg;
@@ -91,7 +149,7 @@ static int orion_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
return 0;
}
-static int orion_wdt_stop(struct udevice *dev)
+static int armada380_wdt_stop(struct udevice *dev)
{
struct orion_wdt_priv *priv = dev_get_priv(dev);
u32 reg;
@@ -113,13 +171,29 @@ static int orion_wdt_stop(struct udevice *dev)
return 0;
}
+static int orion_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
+{
+ struct orion_watchdog_data *data =
+ (struct orion_watchdog_data *)dev_get_driver_data(dev);
+
+ return data->plat_start(dev, timeout_ms, flags);
+}
+
+static int orion_wdt_stop(struct udevice *dev)
+{
+ struct orion_watchdog_data *data =
+ (struct orion_watchdog_data *)dev_get_driver_data(dev);
+
+ return data->plat_stop(dev);
+}
+
static inline bool save_reg_from_ofdata(struct udevice *dev, int index,
void __iomem **reg, int *offset)
{
fdt_addr_t addr;
fdt_size_t off;
- addr = devfdt_get_addr_size_index(dev, index, &off);
+ addr = dev_read_addr_size_index(dev, index, &off);
if (addr == FDT_ADDR_T_NONE)
return false;
@@ -141,8 +215,10 @@ static int orion_wdt_of_to_plat(struct udevice *dev)
if (!save_reg_from_ofdata(dev, 1, &priv->rstout, NULL))
goto err;
- if (!save_reg_from_ofdata(dev, 2, &priv->rstout_mask, NULL))
- goto err;
+ if (device_is_compatible(dev, "marvell,armada-380-wdt")) {
+ if (!save_reg_from_ofdata(dev, 2, &priv->rstout_mask, NULL))
+ goto err;
+ }
return 0;
err:
@@ -173,9 +249,20 @@ static const struct wdt_ops orion_wdt_ops = {
.stop = orion_wdt_stop,
};
+static struct orion_watchdog_data armada380_data = {
+ .plat_start = armada380_wdt_start,
+ .plat_stop = armada380_wdt_stop,
+};
+
+static struct orion_watchdog_data armadaxp_data = {
+ .plat_start = armadaxp_wdt_start,
+ .plat_stop = armadaxp_wdt_stop,
+};
+
static const struct udevice_id orion_wdt_ids[] = {
- { .compatible = "marvell,armada-380-wdt" },
- {}
+ { .compatible = "marvell,armada-380-wdt", .data = (ulong)&armada380_data},
+ { .compatible = "marvell,armada-xp-wdt", .data = (ulong)&armadaxp_data},
+ { }
};
U_BOOT_DRIVER(orion_wdt) = {
diff --git a/drivers/watchdog/renesas_wwdt.c b/drivers/watchdog/renesas_wwdt.c
index f6f508c95c2..60f2ac466bf 100644
--- a/drivers/watchdog/renesas_wwdt.c
+++ b/drivers/watchdog/renesas_wwdt.c
@@ -13,8 +13,6 @@
#include <syscon.h>
#include <wdt.h>
-#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
-
#define RSIP_CTL_CFG4 0xc0
#define RSIP_CTL_CFG4_OPWDEN BIT(3)
#define RSIP_CTL_CFG4_OPWDVAC BIT(5)
diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c
index 7b387266b99..866f555789c 100644
--- a/drivers/watchdog/rti_wdt.c
+++ b/drivers/watchdog/rti_wdt.c
@@ -39,7 +39,7 @@
#define WDT_PRELOAD_MAX 0xfff
struct rti_wdt_priv {
- phys_addr_t regs;
+ void __iomem *regs;
unsigned int clk_hz;
};
@@ -177,7 +177,7 @@ static int rti_wdt_probe(struct udevice *dev)
struct clk clk;
int ret;
- priv->regs = devfdt_get_addr(dev);
+ priv->regs = dev_read_addr_ptr(dev);
if (!priv->regs)
return -EINVAL;
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c
index 807884c5bc7..3a924cb2b9a 100644
--- a/drivers/watchdog/sbsa_gwdt.c
+++ b/drivers/watchdog/sbsa_gwdt.c
@@ -50,6 +50,7 @@ static int sbsa_gwdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
struct sbsa_gwdt_priv *priv = dev_get_priv(dev);
u32 clk;
+ u64 tout_wdog;
/*
* it work in the single stage mode in u-boot,
@@ -58,8 +59,13 @@ static int sbsa_gwdt_start(struct udevice *dev, u64 timeout, ulong flags)
* to half value of timeout.
*/
clk = get_tbclk();
- writel(clk / (2 * 1000) * timeout,
- priv->reg_control + SBSA_GWDT_WOR);
+
+ /* if requested timeout overflows, clamp it to u32_max */
+ tout_wdog = ((u64)clk * timeout) / (2 * 1000);
+ if (tout_wdog > U32_MAX)
+ tout_wdog = U32_MAX;
+
+ writel(tout_wdog, priv->reg_control + SBSA_GWDT_WOR);
/* writing WCS will cause an explicit watchdog refresh */
writel(SBSA_GWDT_WCS_EN, priv->reg_control + SBSA_GWDT_WCS);
diff --git a/drivers/watchdog/starfive_wdt.c b/drivers/watchdog/starfive_wdt.c
index ee9ec4cdc3a..d2c16150f4c 100644
--- a/drivers/watchdog/starfive_wdt.c
+++ b/drivers/watchdog/starfive_wdt.c
@@ -290,9 +290,9 @@ static int starfive_wdt_of_to_plat(struct udevice *dev)
{
struct starfive_wdt_priv *wdt = dev_get_priv(dev);
- wdt->base = (void *)dev_read_addr(dev);
+ wdt->base = dev_read_addr_ptr(dev);
if (!wdt->base)
- return -ENODEV;
+ return -EINVAL;
wdt->apb_clk = devm_clk_get(dev, "apb");
if (IS_ERR(wdt->apb_clk))
diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c
index 83f19dc0e86..e3a89031c44 100644
--- a/drivers/watchdog/ulp_wdog.c
+++ b/drivers/watchdog/ulp_wdog.c
@@ -7,6 +7,7 @@
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <dm.h>
+#include <linux/delay.h>
#include <wdt.h>
/*
@@ -51,11 +52,9 @@ struct ulp_wdt_priv {
#define CLK_RATE_1KHZ 1000
#define CLK_RATE_32KHZ 125
-void hw_watchdog_set_timeout(u16 val)
+void hw_watchdog_set_timeout(struct wdog_regs *wdog, u16 val)
{
/* setting timeout value */
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
-
writel(val, &wdog->toval);
}
@@ -89,7 +88,7 @@ void ulp_watchdog_init(struct wdog_regs *wdog, u16 timeout)
while (!(readl(&wdog->cs) & WDGCS_ULK))
;
- hw_watchdog_set_timeout(timeout);
+ hw_watchdog_set_timeout(wdog, timeout);
writel(0, &wdog->win);
/* setting 1-kHz clock source, enable counter running, and clear interrupt */
@@ -107,57 +106,20 @@ void ulp_watchdog_init(struct wdog_regs *wdog, u16 timeout)
ulp_watchdog_reset(wdog);
}
-void hw_watchdog_reset(void)
-{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
-
- ulp_watchdog_reset(wdog);
-}
-
-void hw_watchdog_init(void)
-{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
-
- ulp_watchdog_init(wdog, CONFIG_WATCHDOG_TIMEOUT_MSECS);
-}
-
-#if !CONFIG_IS_ENABLED(SYSRESET)
+#if !CONFIG_IS_ENABLED(SYSRESET) && CONFIG_IS_ENABLED(WDT)
void reset_cpu(void)
{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- u32 cmd32 = 0;
-
- if (readl(&wdog->cs) & WDGCS_CMD32EN) {
- writel(UNLOCK_WORD, &wdog->cnt);
- cmd32 = WDGCS_CMD32EN;
- } else {
- dmb();
- __raw_writel(UNLOCK_WORD0, &wdog->cnt);
- __raw_writel(UNLOCK_WORD1, &wdog->cnt);
- dmb();
- }
+ struct udevice *wdt;
- /* Wait WDOG Unlock */
- while (!(readl(&wdog->cs) & WDGCS_ULK))
- ;
+ for (uclass_first_device(UCLASS_WDT, &wdt);
+ wdt;
+ uclass_next_device(&wdt)) {
+ if (!dev_read_enabled(wdt))
+ continue;
- hw_watchdog_set_timeout(5); /* 5ms timeout for general; 40ms timeout for imx93 */
- writel(0, &wdog->win);
-
- /* enable counter running */
- if (IS_ENABLED(CONFIG_ARCH_IMX9))
- writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8) | WDOG_CS_PRES |
- WDGCS_INT), &wdog->cs);
- else
- writel((cmd32 | WDGCS_WDGE | (WDG_LPO_CLK << 8)), &wdog->cs);
-
- /* Wait WDOG reconfiguration */
- while (!(readl(&wdog->cs) & WDGCS_RCS))
- ;
-
- hw_watchdog_reset();
-
- while (1);
+ wdt_expire_now(wdt, 0);
+ break;
+ }
}
#endif
@@ -184,6 +146,20 @@ static int ulp_wdt_reset(struct udevice *dev)
return 0;
}
+static int ulp_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ int ret;
+
+ /* 5ms timeout for all others; 40ms timeout for "fsl,imx93-wdt" */
+ ret = ulp_wdt_start(dev, 5, flags);
+ if (ret)
+ return ret;
+
+ mdelay(50);
+
+ return 0;
+}
+
static int ulp_wdt_probe(struct udevice *dev)
{
struct ulp_wdt_priv *priv = dev_get_priv(dev);
@@ -202,6 +178,7 @@ static int ulp_wdt_probe(struct udevice *dev)
static const struct wdt_ops ulp_wdt_ops = {
.start = ulp_wdt_start,
.reset = ulp_wdt_reset,
+ .expire_now = ulp_wdt_expire_now,
};
static const struct udevice_id ulp_wdt_ids[] = {