summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/adc/adc-uclass.c14
-rw-r--r--drivers/adc/exynos-adc.c2
-rw-r--r--drivers/block/blk-uclass.c91
-rw-r--r--drivers/block/dwc_ahci.c10
-rw-r--r--drivers/block/ide.c11
-rw-r--r--drivers/block/sata_ceva.c3
-rw-r--r--drivers/block/sil680.c1
-rw-r--r--drivers/bootcount/bootcount.c20
-rw-r--r--drivers/clk/aspeed/clk_ast2500.c2
-rw-r--r--drivers/clk/at91/clk-generated.c2
-rw-r--r--drivers/clk/at91/clk-h32mx.c2
-rw-r--r--drivers/clk/at91/clk-main.c2
-rw-r--r--drivers/clk/at91/clk-master.c2
-rw-r--r--drivers/clk/at91/clk-peripheral.c2
-rw-r--r--drivers/clk/at91/clk-plla.c2
-rw-r--r--drivers/clk/at91/clk-slow.c2
-rw-r--r--drivers/clk/at91/clk-system.c2
-rw-r--r--drivers/clk/at91/clk-utmi.c2
-rw-r--r--drivers/clk/at91/pmc.c11
-rw-r--r--drivers/clk/at91/pmc.h2
-rw-r--r--drivers/clk/at91/sckc.c3
-rw-r--r--drivers/clk/clk-uclass.c14
-rw-r--r--drivers/clk/clk_bcm6345.c2
-rw-r--r--drivers/clk/clk_fixed_rate.c7
-rw-r--r--drivers/clk/clk_stm32f7.c3
-rw-r--r--drivers/clk/clk_zynq.c4
-rw-r--r--drivers/clk/clk_zynqmp.c2
-rw-r--r--drivers/clk/exynos/clk-exynos7420.c4
-rw-r--r--drivers/clk/rockchip/Makefile2
-rw-r--r--drivers/clk/rockchip/clk_rk3036.c101
-rw-r--r--drivers/clk/rockchip/clk_rk3188.c2
-rw-r--r--drivers/clk/rockchip/clk_rk3288.c148
-rw-r--r--drivers/clk/rockchip/clk_rk3328.c2
-rw-r--r--drivers/clk/rockchip/clk_rk3368.c291
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c4
-rw-r--r--drivers/clk/rockchip/clk_rv1108.c220
-rw-r--r--drivers/clk/uniphier/clk-uniphier-core.c6
-rw-r--r--drivers/core/Kconfig4
-rw-r--r--drivers/core/Makefile7
-rw-r--r--drivers/core/device.c153
-rw-r--r--drivers/core/fdtaddr.c143
-rw-r--r--drivers/core/lists.c29
-rw-r--r--drivers/core/of_access.c741
-rw-r--r--drivers/core/of_addr.c359
-rw-r--r--drivers/core/of_extra.c37
-rw-r--r--drivers/core/ofnode.c579
-rw-r--r--drivers/core/read.c140
-rw-r--r--drivers/core/regmap.c36
-rw-r--r--drivers/core/root.c77
-rw-r--r--drivers/core/simple-bus.c3
-rw-r--r--drivers/core/uclass.c42
-rw-r--r--drivers/cpu/bmips_cpu.c74
-rw-r--r--drivers/cpu/cpu-uclass.c6
-rw-r--r--drivers/ddr/fsl/arm_ddr_gen3.c1
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c4
-rw-r--r--drivers/ddr/fsl/fsl_ddr_gen4.c4
-rw-r--r--drivers/ddr/fsl/interactive.c4
-rw-r--r--drivers/ddr/fsl/options.c4
-rw-r--r--drivers/ddr/fsl/util.c4
-rw-r--r--drivers/ddr/marvell/axp/ddr3_dqs.c2
-rw-r--r--drivers/dfu/dfu_sf.c3
-rw-r--r--drivers/dma/ti-edma3.c4
-rw-r--r--drivers/firmware/firmware-uclass.c3
-rw-r--r--drivers/firmware/psci.c10
-rw-r--r--drivers/fpga/zynqmppl.c25
-rw-r--r--drivers/gpio/74x164_gpio.c2
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/altera_pio.c2
-rw-r--r--drivers/gpio/at91_gpio.c2
-rw-r--r--drivers/gpio/atmel_pio4.c5
-rw-r--r--drivers/gpio/bcm2835_gpio.c2
-rw-r--r--drivers/gpio/bcm6345_gpio.c8
-rw-r--r--drivers/gpio/gpio-uclass.c82
-rw-r--r--drivers/gpio/gpio-uniphier.c4
-rw-r--r--drivers/gpio/imx_rgpio2p.c2
-rw-r--r--drivers/gpio/intel_ich6_gpio.c2
-rw-r--r--drivers/gpio/lpc32xx_gpio.c1
-rw-r--r--drivers/gpio/msm_gpio.c2
-rw-r--r--drivers/gpio/mvebu_gpio.c2
-rw-r--r--drivers/gpio/mxc_gpio.c2
-rw-r--r--drivers/gpio/omap_gpio.c2
-rw-r--r--drivers/gpio/pca953x_gpio.c2
-rw-r--r--drivers/gpio/pm8916_gpio.c10
-rw-r--r--drivers/gpio/rk_gpio.c2
-rw-r--r--drivers/gpio/s3c2440_gpio.c88
-rw-r--r--drivers/gpio/s5p_gpio.c4
-rw-r--r--drivers/gpio/sandbox.c12
-rw-r--r--drivers/gpio/stm32f7_gpio.c2
-rw-r--r--drivers/gpio/sunxi_gpio.c4
-rw-r--r--drivers/gpio/tegra186_gpio.c4
-rw-r--r--drivers/gpio/tegra_gpio.c4
-rw-r--r--drivers/gpio/vybrid_gpio.c2
-rw-r--r--drivers/gpio/zynq_gpio.c2
-rw-r--r--drivers/i2c/Kconfig1
-rw-r--r--drivers/i2c/ast_i2c.c2
-rw-r--r--drivers/i2c/at91_i2c.c2
-rw-r--r--drivers/i2c/davinci_i2c.c2
-rw-r--r--drivers/i2c/designware_i2c.c2
-rw-r--r--drivers/i2c/exynos_hs_i2c.c2
-rw-r--r--drivers/i2c/i2c-cdns.c4
-rw-r--r--drivers/i2c/i2c-uclass.c28
-rw-r--r--drivers/i2c/i2c-uniphier-f.c4
-rw-r--r--drivers/i2c/i2c-uniphier.c4
-rw-r--r--drivers/i2c/i2c_core.c11
-rw-r--r--drivers/i2c/imx_lpi2c.c80
-rw-r--r--drivers/i2c/muxes/i2c-mux-uclass.c11
-rw-r--r--drivers/i2c/mv_i2c.c2
-rw-r--r--drivers/i2c/mvtwsi.c2
-rw-r--r--drivers/i2c/mxc_i2c.c14
-rw-r--r--drivers/i2c/omap24xx_i2c.c2
-rw-r--r--drivers/i2c/rk_i2c.c2
-rw-r--r--drivers/i2c/s3c24x0_i2c.c6
-rw-r--r--drivers/i2c/sandbox_i2c.c1
-rw-r--r--drivers/i2c/soft_i2c.c12
-rw-r--r--drivers/i2c/tegra_i2c.c2
-rw-r--r--drivers/input/cros_ec_keyb.c24
-rw-r--r--drivers/input/key_matrix.c19
-rw-r--r--drivers/input/keyboard.c2
-rw-r--r--drivers/input/ps2ser.c94
-rw-r--r--drivers/input/tegra-kbc.c5
-rw-r--r--drivers/led/led_bcm6328.c7
-rw-r--r--drivers/led/led_bcm6358.c7
-rw-r--r--drivers/led/led_gpio.c13
-rw-r--r--drivers/mailbox/mailbox-uclass.c20
-rw-r--r--drivers/mailbox/tegra-hsp.c4
-rw-r--r--drivers/misc/Kconfig13
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/altera_sysid.c2
-rw-r--r--drivers/misc/cros_ec.c36
-rw-r--r--drivers/misc/cros_ec_sandbox.c23
-rw-r--r--drivers/misc/fsl_iim.c2
-rw-r--r--drivers/misc/i2c_eeprom.c4
-rw-r--r--drivers/misc/i2c_eeprom_emul.c7
-rw-r--r--drivers/misc/rockchip-efuse.c161
-rw-r--r--drivers/misc/tegra186_bpmp.c6
-rw-r--r--drivers/misc/tegra_car.c4
-rw-r--r--drivers/mmc/Kconfig2
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/atmel_sdhci.c2
-rw-r--r--drivers/mmc/bcm2835_sdhci.c2
-rw-r--r--drivers/mmc/fsl_esdhc.c8
-rw-r--r--drivers/mmc/gen_atmel_mci.c4
-rw-r--r--drivers/mmc/meson_gx_mmc.c4
-rw-r--r--drivers/mmc/mmc-uclass.c30
-rw-r--r--drivers/mmc/mmc.c15
-rw-r--r--drivers/mmc/msm_sdhci.c2
-rw-r--r--drivers/mmc/omap_hsmmc.c3
-rw-r--r--drivers/mmc/pic32_sdhci.c2
-rw-r--r--drivers/mmc/rockchip_dw_mmc.c2
-rw-r--r--drivers/mmc/rockchip_sdhci.c2
-rw-r--r--drivers/mmc/s3c_sdi.c323
-rw-r--r--drivers/mmc/s5p_sdhci.c8
-rw-r--r--drivers/mmc/sdhci-cadence.c6
-rw-r--r--drivers/mmc/sh_sdhi.c95
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c2
-rw-r--r--drivers/mmc/sti_sdhci.c2
-rw-r--r--drivers/mmc/tangier_sdhci.c2
-rw-r--r--drivers/mmc/tegra_mmc.c78
-rw-r--r--drivers/mmc/uniphier-sd.c4
-rw-r--r--drivers/mmc/xenon_sdhci.c6
-rw-r--r--drivers/mmc/zynq_sdhci.c4
-rw-r--r--drivers/mtd/altera_qspi.c2
-rw-r--r--drivers/mtd/cfi_flash.c2
-rw-r--r--drivers/mtd/dataflash.c12
-rw-r--r--drivers/mtd/nand/Kconfig4
-rw-r--r--drivers/mtd/nand/Makefile2
-rw-r--r--drivers/mtd/nand/mpc5121_nfc.c656
-rw-r--r--drivers/mtd/nand/s3c2410_nand.c175
-rw-r--r--drivers/mtd/nand/sunxi_nand.c2
-rw-r--r--drivers/mtd/nand/tegra_nand.c4
-rw-r--r--drivers/mtd/onenand/onenand_base.c6
-rw-r--r--drivers/mtd/onenand/onenand_spl.c36
-rw-r--r--drivers/mtd/pic32_flash.c2
-rw-r--r--drivers/mtd/spi/Kconfig7
-rw-r--r--drivers/mtd/spi/sandbox.c6
-rw-r--r--drivers/mtd/spi/spi_flash.c7
-rw-r--r--drivers/net/4xx_enet.c1
-rw-r--r--drivers/net/Kconfig8
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/ag7xxx.c2
-rw-r--r--drivers/net/altera_tse.c2
-rw-r--r--drivers/net/cpsw-common.c4
-rw-r--r--drivers/net/cpsw.c36
-rw-r--r--drivers/net/designware.c19
-rw-r--r--drivers/net/dwc_eth_qos.c4
-rw-r--r--drivers/net/ethoc.c6
-rw-r--r--drivers/net/fec_mxc.c2
-rw-r--r--drivers/net/fm/ls1043.c4
-rw-r--r--drivers/net/fm/ls1046.c4
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_portal.c1
-rw-r--r--drivers/net/fsl-mc/mc.c274
-rw-r--r--drivers/net/fsl_mcdmafec.c2
-rw-r--r--drivers/net/ftmac100.c2
-rw-r--r--drivers/net/keystone_net.c8
-rw-r--r--drivers/net/macb.c9
-rw-r--r--drivers/net/mpc512x_fec.c769
-rw-r--r--drivers/net/mpc512x_fec.h98
-rw-r--r--drivers/net/mpc5xxx_fec.c1031
-rw-r--r--drivers/net/mpc5xxx_fec.h282
-rw-r--r--drivers/net/mvneta.c4
-rw-r--r--drivers/net/mvpp2.c63
-rw-r--r--drivers/net/ne2000_base.c2
-rw-r--r--drivers/net/pch_gbe.c44
-rw-r--r--drivers/net/phy/Kconfig34
-rw-r--r--drivers/net/phy/marvell.c50
-rw-r--r--drivers/net/phy/phy.c2
-rw-r--r--drivers/net/phy/ti.c2
-rw-r--r--drivers/net/pic32_eth.c3
-rw-r--r--drivers/net/sandbox-raw.c2
-rw-r--r--drivers/net/sandbox.c2
-rw-r--r--drivers/net/sun8i_emac.c8
-rw-r--r--drivers/net/sunxi_emac.c2
-rw-r--r--drivers/net/tsec.c2
-rw-r--r--drivers/net/xilinx_axi_emac.c2
-rw-r--r--drivers/net/xilinx_emaclite.c2
-rw-r--r--drivers/net/zynq_gem.c18
-rw-r--r--drivers/pci/pci-uclass.c26
-rw-r--r--drivers/pci/pci_indirect.c17
-rw-r--r--drivers/pci/pcie_dw_mvebu.c4
-rw-r--r--drivers/pci/pcie_layerscape.c4
-rw-r--r--drivers/pci/pcie_layerscape_fixup.c3
-rw-r--r--drivers/pcmcia/Makefile2
-rw-r--r--drivers/pcmcia/mpc8xx_pcmcia.c258
-rw-r--r--drivers/pcmcia/tqm8xx_pcmcia.c254
-rw-r--r--drivers/phy/marvell/comphy_core.c8
-rw-r--r--drivers/phy/phy-uclass.c21
-rw-r--r--drivers/phy/sandbox-phy.c3
-rw-r--r--drivers/phy/ti-pipe3-phy.c4
-rw-r--r--drivers/pinctrl/Kconfig21
-rw-r--r--drivers/pinctrl/Makefile2
-rw-r--r--drivers/pinctrl/ath79/pinctrl_ar933x.c2
-rw-r--r--drivers/pinctrl/ath79/pinctrl_qca953x.c2
-rw-r--r--drivers/pinctrl/exynos/pinctrl-exynos.c2
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-gxbb.c3
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.c2
-rw-r--r--drivers/pinctrl/mvebu/Kconfig18
-rw-r--r--drivers/pinctrl/mvebu/Makefile3
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-37xx.c632
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-mvebu.c2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx.c2
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx5.c3
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx6.c3
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx7.c3
-rw-r--r--drivers/pinctrl/nxp/pinctrl-imx7ulp.c3
-rw-r--r--drivers/pinctrl/pinctrl-at91-pio4.c4
-rw-r--r--drivers/pinctrl/pinctrl-at91.c6
-rw-r--r--drivers/pinctrl/pinctrl-generic.c2
-rw-r--r--drivers/pinctrl/pinctrl-sandbox.c2
-rw-r--r--drivers/pinctrl/pinctrl-single.c13
-rw-r--r--drivers/pinctrl/pinctrl-uclass.c18
-rw-r--r--drivers/pinctrl/pinctrl_stm32.c2
-rw-r--r--drivers/pinctrl/rockchip/Makefile2
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3036.c44
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3188.c4
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3328.c230
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rk3368.c149
-rw-r--r--drivers/pinctrl/rockchip/pinctrl_rv1108.c184
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-core.c4
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-sld3.c3
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c3
-rw-r--r--drivers/power/domain/bcm6328-power-domain.c2
-rw-r--r--drivers/power/domain/power-domain-uclass.c19
-rw-r--r--drivers/power/pmic/Kconfig7
-rw-r--r--drivers/power/pmic/Makefile1
-rw-r--r--drivers/power/pmic/act8846.c8
-rw-r--r--drivers/power/pmic/i2c_pmic_emul.c6
-rw-r--r--drivers/power/pmic/lp873x.c12
-rw-r--r--drivers/power/pmic/lp87565.c87
-rw-r--r--drivers/power/pmic/max77686.c8
-rw-r--r--drivers/power/pmic/palmas.c16
-rw-r--r--drivers/power/pmic/pfuze100.c8
-rw-r--r--drivers/power/pmic/pm8916.c2
-rw-r--r--drivers/power/pmic/pmic-uclass.c22
-rw-r--r--drivers/power/pmic/pmic_tps65218.c3
-rw-r--r--drivers/power/pmic/rk8xx.c9
-rw-r--r--drivers/power/pmic/s5m8767.c7
-rw-r--r--drivers/power/pmic/sandbox.c2
-rw-r--r--drivers/power/pmic/tps65090.c8
-rw-r--r--drivers/power/regulator/Kconfig10
-rw-r--r--drivers/power/regulator/Makefile1
-rw-r--r--drivers/power/regulator/fixed.c17
-rw-r--r--drivers/power/regulator/lp87565_regulator.c199
-rw-r--r--drivers/power/regulator/palmas_regulator.c6
-rw-r--r--drivers/power/regulator/pwm_regulator.c8
-rw-r--r--drivers/power/regulator/regulator-uclass.c47
-rw-r--r--drivers/power/regulator/rk8xx.c4
-rw-r--r--drivers/pwm/exynos_pwm.c2
-rw-r--r--drivers/pwm/rk_pwm.c3
-rw-r--r--drivers/pwm/tegra_pwm.c2
-rw-r--r--drivers/qe/qe.c36
-rw-r--r--drivers/ram/bmips_ram.c58
-rw-r--r--drivers/ram/stm32_sdram.c4
-rw-r--r--drivers/reset/reset-bcm6345.c2
-rw-r--r--drivers/reset/reset-uclass.c21
-rw-r--r--drivers/reset/reset-uniphier.c22
-rw-r--r--drivers/reset/sti-reset.c41
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/ds1337.c16
-rw-r--r--drivers/rtc/i2c_rtc_emul.c1
-rw-r--r--drivers/rtc/mpc5xxx.c128
-rw-r--r--drivers/rtc/mpc8xx.c60
-rw-r--r--drivers/serial/Kconfig4
-rw-r--r--drivers/serial/altera_jtag_uart.c2
-rw-r--r--drivers/serial/altera_uart.c2
-rw-r--r--drivers/serial/atmel_usart.c2
-rw-r--r--drivers/serial/ns16550.c2
-rw-r--r--drivers/serial/serial-uclass.c3
-rw-r--r--drivers/serial/serial.c5
-rw-r--r--drivers/serial/serial_ar933x.c2
-rw-r--r--drivers/serial/serial_arc.c2
-rw-r--r--drivers/serial/serial_bcm283x_mu.c2
-rw-r--r--drivers/serial/serial_bcm6345.c14
-rw-r--r--drivers/serial/serial_lpuart.c4
-rw-r--r--drivers/serial/serial_meson.c2
-rw-r--r--drivers/serial/serial_msm.c2
-rw-r--r--drivers/serial/serial_mvebu_a3700.c2
-rw-r--r--drivers/serial/serial_mxc.c2
-rw-r--r--drivers/serial/serial_pl01x.c2
-rw-r--r--drivers/serial/serial_s5p.c2
-rw-r--r--drivers/serial/serial_sti_asc.c2
-rw-r--r--drivers/serial/serial_stm32x7.c30
-rw-r--r--drivers/serial/serial_stm32x7.h5
-rw-r--r--drivers/serial/serial_uniphier.c5
-rw-r--r--drivers/serial/serial_xuartlite.c2
-rw-r--r--drivers/serial/serial_zynq.c2
-rw-r--r--drivers/sound/max98095.c2
-rw-r--r--drivers/sound/wm8994.c2
-rw-r--r--drivers/spi/altera_spi.c2
-rw-r--r--drivers/spi/ath79_spi.c2
-rw-r--r--drivers/spi/atmel_spi.c2
-rw-r--r--drivers/spi/davinci_spi.c2
-rw-r--r--drivers/spi/designware_spi.c2
-rw-r--r--drivers/spi/exynos_spi.c2
-rw-r--r--drivers/spi/fsl_dspi.c4
-rw-r--r--drivers/spi/kirkwood_spi.c2
-rw-r--r--drivers/spi/mvebu_a3700_spi.c2
-rw-r--r--drivers/spi/omap3_spi.c2
-rw-r--r--drivers/spi/pic32_spi.c2
-rw-r--r--drivers/spi/rk_spi.c2
-rw-r--r--drivers/spi/spi-uclass.c31
-rw-r--r--drivers/spi/tegra114_spi.c3
-rw-r--r--drivers/spi/tegra20_sflash.c2
-rw-r--r--drivers/spi/tegra20_slink.c2
-rw-r--r--drivers/spi/tegra210_qspi.c2
-rw-r--r--drivers/spi/ti_qspi.c12
-rw-r--r--drivers/spi/zynq_spi.c2
-rw-r--r--drivers/spmi/spmi-msm.c2
-rw-r--r--drivers/sysreset/Kconfig6
-rw-r--r--drivers/sysreset/Makefile3
-rw-r--r--drivers/sysreset/sysreset_psci.c3
-rw-r--r--drivers/sysreset/sysreset_rk3368.c62
-rw-r--r--drivers/sysreset/sysreset_rv1108.c46
-rw-r--r--drivers/sysreset/sysreset_sandbox.c2
-rw-r--r--drivers/sysreset/sysreset_snapdragon.c2
-rw-r--r--drivers/sysreset/sysreset_watchdog.c60
-rw-r--r--drivers/timer/ae3xx_timer.c2
-rw-r--r--drivers/timer/ag101p_timer.c2
-rw-r--r--drivers/timer/altera_timer.c2
-rw-r--r--drivers/timer/arc_timer.c2
-rw-r--r--drivers/timer/ast_timer.c2
-rw-r--r--drivers/timer/omap-timer.c2
-rw-r--r--drivers/timer/timer-uclass.c3
-rw-r--r--drivers/tpm/tpm_tis_lpc.c2
-rw-r--r--drivers/usb/common/fsl-errata.c4
-rw-r--r--drivers/usb/emul/sandbox_flash.c4
-rw-r--r--drivers/usb/emul/sandbox_hub.c3
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/at91_udc.c10
-rw-r--r--drivers/usb/gadget/gadget_chips.h17
-rw-r--r--drivers/usb/gadget/mpc8xx_udc.c1386
-rw-r--r--drivers/usb/host/Makefile5
-rw-r--r--drivers/usb/host/dwc2.c21
-rw-r--r--drivers/usb/host/ehci-atmel.c2
-rw-r--r--drivers/usb/host/ehci-exynos.c2
-rw-r--r--drivers/usb/host/ehci-fsl.c2
-rw-r--r--drivers/usb/host/ehci-generic.c2
-rw-r--r--drivers/usb/host/ehci-marvell.c4
-rw-r--r--drivers/usb/host/ehci-mpc512x.c140
-rw-r--r--drivers/usb/host/ehci-msm.c2
-rw-r--r--drivers/usb/host/ehci-mx6.c5
-rw-r--r--drivers/usb/host/ehci-pci.c1
-rw-r--r--drivers/usb/host/ehci-sunxi.c2
-rw-r--r--drivers/usb/host/ehci-tegra.c9
-rw-r--r--drivers/usb/host/ehci-vf.c7
-rw-r--r--drivers/usb/host/ehci-zynq.c2
-rw-r--r--drivers/usb/host/ehci.h10
-rw-r--r--drivers/usb/host/ohci-generic.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c6
-rw-r--r--drivers/usb/host/ohci-s3c24xx.c1688
-rw-r--r--drivers/usb/host/ohci-s3c24xx.h409
-rw-r--r--drivers/usb/host/ohci-sunxi.c2
-rw-r--r--drivers/usb/host/ohci.h7
-rw-r--r--drivers/usb/host/usb-uclass.c8
-rw-r--r--drivers/usb/host/xhci-exynos5.c2
-rw-r--r--drivers/usb/host/xhci-fsl.c2
-rw-r--r--drivers/usb/host/xhci-mvebu.c2
-rw-r--r--drivers/usb/host/xhci-rockchip.c37
-rw-r--r--drivers/usb/musb-new/sunxi.c1
-rw-r--r--drivers/usb/musb-new/ti-musb.c4
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/atmel_hlcdfb.c14
-rw-r--r--drivers/video/exynos/exynos_dp.c4
-rw-r--r--drivers/video/exynos/exynos_fb.c2
-rw-r--r--drivers/video/mpc8xx_lcd.c400
-rw-r--r--drivers/video/rockchip/Kconfig29
-rw-r--r--drivers/video/rockchip/Makefile6
-rw-r--r--drivers/video/rockchip/rk3288_hdmi.c116
-rw-r--r--drivers/video/rockchip/rk3288_vop.c109
-rw-r--r--drivers/video/rockchip/rk3399_hdmi.c81
-rw-r--r--drivers/video/rockchip/rk3399_vop.c105
-rw-r--r--drivers/video/rockchip/rk_edp.c18
-rw-r--r--drivers/video/rockchip/rk_hdmi.c117
-rw-r--r--drivers/video/rockchip/rk_hdmi.h76
-rw-r--r--drivers/video/rockchip/rk_lvds.c2
-rw-r--r--drivers/video/rockchip/rk_mipi.c2
-rw-r--r--drivers/video/rockchip/rk_vop.c190
-rw-r--r--drivers/video/rockchip/rk_vop.h67
-rw-r--r--drivers/video/sm501.c1
-rw-r--r--drivers/video/sunxi/Makefile2
-rw-r--r--drivers/video/sunxi/sunxi_de2.c60
-rw-r--r--drivers/video/sunxi/tve_common.c (renamed from drivers/video/sunxi/tve.c)0
-rw-r--r--drivers/video/tegra.c2
-rw-r--r--drivers/video/tegra124/dp.c2
-rw-r--r--drivers/video/tegra124/sor.c9
-rw-r--r--drivers/watchdog/Kconfig8
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/ast_wdt.c2
-rw-r--r--drivers/watchdog/bcm6345_wdt.c110
436 files changed, 7211 insertions, 10192 deletions
diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c
index 3e28a5600b..a5ef722d21 100644
--- a/drivers/adc/adc-uclass.c
+++ b/drivers/adc/adc-uclass.c
@@ -345,12 +345,11 @@ nodev:
static int adc_vdd_platdata_set(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
- int ret, offset = dev_of_offset(dev);
- const void *fdt = gd->fdt_blob;
+ int ret;
char *prop;
prop = "vdd-polarity-negative";
- uc_pdata->vdd_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
+ uc_pdata->vdd_polarity_negative = dev_read_bool(dev, prop);
ret = adc_vdd_platdata_update(dev);
if (ret != -ENOENT)
@@ -358,7 +357,7 @@ static int adc_vdd_platdata_set(struct udevice *dev)
/* No vdd-supply phandle. */
prop = "vdd-microvolts";
- uc_pdata->vdd_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
+ uc_pdata->vdd_microvolts = dev_read_u32_default(dev, prop, -ENODATA);
return 0;
}
@@ -366,12 +365,11 @@ static int adc_vdd_platdata_set(struct udevice *dev)
static int adc_vss_platdata_set(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
- int ret, offset = dev_of_offset(dev);
- const void *fdt = gd->fdt_blob;
+ int ret;
char *prop;
prop = "vss-polarity-negative";
- uc_pdata->vss_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
+ uc_pdata->vss_polarity_negative = dev_read_bool(dev, prop);
ret = adc_vss_platdata_update(dev);
if (ret != -ENOENT)
@@ -379,7 +377,7 @@ static int adc_vss_platdata_set(struct udevice *dev)
/* No vss-supply phandle. */
prop = "vss-microvolts";
- uc_pdata->vss_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
+ uc_pdata->vss_microvolts = dev_read_u32_default(dev, prop, -ENODATA);
return 0;
}
diff --git a/drivers/adc/exynos-adc.c b/drivers/adc/exynos-adc.c
index 534e68db8b..324d72f3a9 100644
--- a/drivers/adc/exynos-adc.c
+++ b/drivers/adc/exynos-adc.c
@@ -107,7 +107,7 @@ int exynos_adc_ofdata_to_platdata(struct udevice *dev)
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
struct exynos_adc_priv *priv = dev_get_priv(dev);
- priv->regs = (struct exynos_adc_v2 *)dev_get_addr(dev);
+ priv->regs = (struct exynos_adc_v2 *)devfdt_get_addr(dev);
if (priv->regs == (struct exynos_adc_v2 *)FDT_ADDR_T_NONE) {
error("Dev: %s - can't get address!", dev->name);
return -ENODATA;
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index af3c35f6d0..23f131b7ad 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -363,7 +363,7 @@ int blk_next_device(struct udevice **devp)
} while (1);
}
-int blk_get_device(int if_type, int devnum, struct udevice **devp)
+int blk_find_device(int if_type, int devnum, struct udevice **devp)
{
struct uclass *uc;
struct udevice *dev;
@@ -379,13 +379,24 @@ int blk_get_device(int if_type, int devnum, struct udevice **devp)
if_type, devnum, dev->name, desc->if_type, desc->devnum);
if (desc->if_type == if_type && desc->devnum == devnum) {
*devp = dev;
- return device_probe(dev);
+ return 0;
}
}
return -ENODEV;
}
+int blk_get_device(int if_type, int devnum, struct udevice **devp)
+{
+ int ret;
+
+ ret = blk_find_device(if_type, devnum, devp);
+ if (ret)
+ return ret;
+
+ return device_probe(*devp);
+}
+
unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
@@ -442,6 +453,32 @@ int blk_prepare_device(struct udevice *dev)
return 0;
}
+int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
+{
+ struct udevice *dev;
+ enum uclass_id id;
+ int ret;
+
+ device_find_first_child(parent, &dev);
+ if (!dev) {
+ debug("%s: No block device found for parent '%s'\n", __func__,
+ parent->name);
+ return -ENODEV;
+ }
+ id = device_get_uclass_id(dev);
+ if (id != UCLASS_BLK) {
+ debug("%s: Incorrect uclass %s for block device '%s'\n",
+ __func__, uclass_get_name(id), dev->name);
+ return -ENOTBLK;
+ }
+ ret = device_probe(dev);
+ if (ret)
+ return ret;
+ *devp = dev;
+
+ return 0;
+}
+
int blk_find_max_devnum(enum if_type if_type)
{
struct udevice *dev;
@@ -462,6 +499,44 @@ int blk_find_max_devnum(enum if_type if_type)
return max_devnum;
}
+static int blk_next_free_devnum(enum if_type if_type)
+{
+ int ret;
+
+ ret = blk_find_max_devnum(if_type);
+ if (ret == -ENODEV)
+ return 0;
+ if (ret < 0)
+ return ret;
+
+ return ret + 1;
+}
+
+static int blk_claim_devnum(enum if_type if_type, int devnum)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_BLK, &uc);
+ if (ret)
+ return ret;
+ uclass_foreach_dev(dev, uc) {
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+ if (desc->if_type == if_type && desc->devnum == devnum) {
+ int next = blk_next_free_devnum(if_type);
+
+ if (next < 0)
+ return next;
+ desc->devnum = next;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
int blk_create_device(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
lbaint_t size, struct udevice **devp)
@@ -471,14 +546,14 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
int ret;
if (devnum == -1) {
- ret = blk_find_max_devnum(if_type);
- if (ret == -ENODEV)
- devnum = 0;
- else if (ret < 0)
+ devnum = blk_next_free_devnum(if_type);
+ } else {
+ ret = blk_claim_devnum(if_type, devnum);
+ if (ret < 0 && ret != -ENOENT)
return ret;
- else
- devnum = ret + 1;
}
+ if (devnum < 0)
+ return devnum;
ret = device_bind_driver(parent, drv_name, name, &dev);
if (ret)
return ret;
diff --git a/drivers/block/dwc_ahci.c b/drivers/block/dwc_ahci.c
index d5bb0b887a..3f839bf987 100644
--- a/drivers/block/dwc_ahci.c
+++ b/drivers/block/dwc_ahci.c
@@ -31,15 +31,15 @@ static int dwc_ahci_ofdata_to_platdata(struct udevice *dev)
struct scsi_platdata *plat = dev_get_platdata(dev);
fdt_addr_t addr;
- plat->max_id = fdtdec_get_uint(gd->fdt_blob, dev->of_offset, "max-id",
- CONFIG_SYS_SCSI_MAX_SCSI_ID);
- plat->max_lun = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+ plat->max_id = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+ "max-id", CONFIG_SYS_SCSI_MAX_SCSI_ID);
+ plat->max_lun = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
"max-lun", CONFIG_SYS_SCSI_MAX_LUN);
- priv->base = map_physmem(dev_get_addr(dev), sizeof(void *),
+ priv->base = map_physmem(devfdt_get_addr(dev), sizeof(void *),
MAP_NOCACHE);
- addr = dev_get_addr_index(dev, 1);
+ addr = devfdt_get_addr_index(dev, 1);
if (addr != FDT_ADDR_T_NONE) {
priv->wrapper_base = map_physmem(addr, sizeof(void *),
MAP_NOCACHE);
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index ac5b91c01a..308ad7396b 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -770,10 +770,6 @@ void ide_init(void)
unsigned char c;
int i, bus;
-#ifdef CONFIG_IDE_8xx_PCCARD
- extern int ide_devices_found; /* Initialized in check_ide_device() */
-#endif /* CONFIG_IDE_8xx_PCCARD */
-
#ifdef CONFIG_IDE_PREINIT
WATCHDOG_RESET();
@@ -812,13 +808,6 @@ void ide_init(void)
bus * (CONFIG_SYS_IDE_MAXDEVICE /
CONFIG_SYS_IDE_MAXBUS);
-#ifdef CONFIG_IDE_8xx_PCCARD
- /* Skip non-ide devices from probing */
- if ((ide_devices_found & (1 << bus)) == 0) {
- ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */
- continue;
- }
-#endif
printf("Bus %d: ", bus);
ide_bus_ok[bus] = 0;
diff --git a/drivers/block/sata_ceva.c b/drivers/block/sata_ceva.c
index 9b5466483a..0c24fce8dc 100644
--- a/drivers/block/sata_ceva.c
+++ b/drivers/block/sata_ceva.c
@@ -6,7 +6,6 @@
*/
#include <common.h>
#include <dm.h>
-#include <netdev.h>
#include <ahci.h>
#include <scsi.h>
#include <asm/arch/hardware.h>
@@ -129,7 +128,7 @@ static int sata_ceva_ofdata_to_platdata(struct udevice *dev)
{
struct scsi_platdata *plat = dev_get_platdata(dev);
- plat->base = dev_get_addr(dev);
+ plat->base = devfdt_get_addr(dev);
if (plat->base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/block/sil680.c b/drivers/block/sil680.c
index b1db257838..bca3397d94 100644
--- a/drivers/block/sil680.c
+++ b/drivers/block/sil680.c
@@ -18,7 +18,6 @@
* #define CONFIG_SYS_PCI_CACHE_LINE_SIZE 0
*
* #define CONFIG_IDE
- * #undef CONFIG_IDE_8xx_DIRECT
* #undef CONFIG_IDE_LED
* #undef CONFIG_IDE_RESET
* #define CONFIG_IDE_PREINIT
diff --git a/drivers/bootcount/bootcount.c b/drivers/bootcount/bootcount.c
index d5ce450c15..0299a5a839 100644
--- a/drivers/bootcount/bootcount.c
+++ b/drivers/bootcount/bootcount.c
@@ -14,26 +14,6 @@
*/
#if !defined(CONFIG_SYS_BOOTCOUNT_ADDR)
-#if defined(CONFIG_MPC5xxx)
-#define CONFIG_SYS_BOOTCOUNT_ADDR (MPC5XXX_CDM_BRDCRMB)
-#define CONFIG_SYS_BOOTCOUNT_SINGLEWORD
-#endif /* defined(CONFIG_MPC5xxx) */
-
-#if defined(CONFIG_MPC512X)
-#define CONFIG_SYS_BOOTCOUNT_ADDR (&((immap_t *)CONFIG_SYS_IMMR)->clk.bcr)
-#define CONFIG_SYS_BOOTCOUNT_SINGLEWORD
-#endif /* defined(CONFIG_MPC512X) */
-
-#if defined(CONFIG_8xx)
-#define CONFIG_SYS_BOOTCOUNT_ADDR (((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_dpmem + \
- CPM_BOOTCOUNT_ADDR)
-#endif /* defined(CONFIG_8xx) */
-
-#if defined(CONFIG_MPC8260)
-#include <asm/cpm_8260.h>
-#define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_IMMR + CPM_BOOTCOUNT_ADDR)
-#endif /* defined(CONFIG_MPC8260) */
-
#if defined(CONFIG_QE)
#include <linux/immap_qe.h>
#define CONFIG_SYS_BOOTCOUNT_ADDR (CONFIG_SYS_IMMR + 0x110000 + \
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index ccf47a1da1..c2efddaff2 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -429,7 +429,7 @@ static int ast2500_clk_probe(struct udevice *dev)
{
struct ast2500_clk_priv *priv = dev_get_priv(dev);
- priv->scu = dev_get_addr_ptr(dev);
+ priv->scu = devfdt_get_addr_ptr(dev);
if (IS_ERR(priv->scu))
return PTR_ERR(priv->scu);
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index ac27d3e675..8c9a3cb053 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/io.h>
#include <mach/at91_pmc.h>
#include "pmc.h"
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index 1a304bab21..dcc64fbd6d 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/util.h>
#include <linux/io.h>
#include <mach/at91_pmc.h>
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 252d076bd5..a234ce8b7e 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/io.h>
#include <mach/at91_pmc.h>
#include "pmc.h"
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index 72d0a739f1..6bc78bad0d 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 62fabe304d..212a30bd5e 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/io.h>
#include <mach/at91_pmc.h>
#include "pmc.h"
diff --git a/drivers/clk/at91/clk-plla.c b/drivers/clk/at91/clk-plla.c
index 2a71399741..f5b2ca1673 100644
--- a/drivers/clk/at91/clk-plla.c
+++ b/drivers/clk/at91/clk-plla.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/io.h>
#include <mach/at91_pmc.h>
#include "pmc.h"
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
index f7666b4041..f18f002bea 100644
--- a/drivers/clk/at91/clk-slow.c
+++ b/drivers/clk/at91/clk-slow.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
static int at91_slow_clk_enable(struct clk *clk)
{
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 5b59a0c852..24b271aa18 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/io.h>
#include <mach/at91_pmc.h>
#include "pmc.h"
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index 369a6870d8..af5362da42 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/io.h>
#include <mach/at91_pmc.h>
#include "pmc.h"
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 72d52c5818..be1d11ed4e 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -7,9 +7,8 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/lists.h>
-#include <dm/root.h>
#include <dm/util.h>
#include "pmc.h"
@@ -40,7 +39,7 @@ int at91_pmc_core_probe(struct udevice *dev)
dev = dev_get_parent(dev);
- plat->reg_base = (struct at91_pmc *)dev_get_addr_ptr(dev);
+ plat->reg_base = (struct at91_pmc *)devfdt_get_addr_ptr(dev);
return 0;
}
@@ -80,7 +79,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
if (!name)
return -EINVAL;
ret = device_bind_driver_to_node(dev, drv_name, name,
- offset, NULL);
+ offset_to_ofnode(offset), NULL);
if (ret)
return ret;
}
@@ -88,7 +87,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
return 0;
}
-int at91_clk_of_xlate(struct clk *clk, struct fdtdec_phandle_args *args)
+int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
{
int periph;
@@ -115,7 +114,7 @@ int at91_clk_probe(struct udevice *dev)
dev_periph_container = dev_get_parent(dev);
dev_pmc = dev_get_parent(dev_periph_container);
- plat->reg_base = (struct at91_pmc *)dev_get_addr_ptr(dev_pmc);
+ plat->reg_base = (struct at91_pmc *)devfdt_get_addr_ptr(dev_pmc);
return 0;
}
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index f222fce11f..bd3caba48d 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -15,7 +15,7 @@ struct pmc_platdata {
int at91_pmc_core_probe(struct udevice *dev);
int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name);
-int at91_clk_of_xlate(struct clk *clk, struct fdtdec_phandle_args *args);
+int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args);
int at91_clk_probe(struct udevice *dev);
#endif
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c
index 6035e20959..0c0881237c 100644
--- a/drivers/clk/at91/sckc.c
+++ b/drivers/clk/at91/sckc.c
@@ -6,8 +6,7 @@
*/
#include <common.h>
-#include <dm/device.h>
-#include <dm/root.h>
+#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 6fcfd6997c..83b63288fb 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -38,7 +38,7 @@ int clk_get_by_index_platdata(struct udevice *dev, int index,
}
# else
static int clk_of_xlate_default(struct clk *clk,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
debug("%s(clk=%p)\n", __func__, clk);
@@ -58,23 +58,22 @@ static int clk_of_xlate_default(struct clk *clk,
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
{
int ret;
- struct fdtdec_phandle_args args;
+ struct ofnode_phandle_args args;
struct udevice *dev_clk;
struct clk_ops *ops;
debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
assert(clk);
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
- "clocks", "#clock-cells", 0, index,
- &args);
+ ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
+ index, &args);
if (ret) {
debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
__func__, ret);
return ret;
}
- ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev_clk);
+ ret = uclass_get_device_by_ofnode(UCLASS_CLK, args.node, &dev_clk);
if (ret) {
debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
__func__, ret);
@@ -104,8 +103,7 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
debug("%s(dev=%p, name=%s, clk=%p)\n", __func__, dev, name, clk);
- index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
- "clock-names", name);
+ index = dev_read_stringlist_search(dev, "clock-names", name);
if (index < 0) {
debug("fdt_stringlist_search() failed: %d\n", index);
return index;
diff --git a/drivers/clk/clk_bcm6345.c b/drivers/clk/clk_bcm6345.c
index 4c7a2dfb70..93603fa825 100644
--- a/drivers/clk/clk_bcm6345.c
+++ b/drivers/clk/clk_bcm6345.c
@@ -59,7 +59,7 @@ static int bcm63xx_clk_probe(struct udevice *dev)
fdt_addr_t addr;
fdt_size_t size;
- addr = dev_get_addr_size_index(dev, 0, &size);
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c
index 3911bf61a0..63565b6ed8 100644
--- a/drivers/clk/clk_fixed_rate.c
+++ b/drivers/clk/clk_fixed_rate.c
@@ -6,7 +6,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -31,9 +31,8 @@ const struct clk_ops clk_fixed_rate_ops = {
static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
- to_clk_fixed_rate(dev)->fixed_rate =
- fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "clock-frequency", 0);
+ to_clk_fixed_rate(dev)->fixed_rate = dev_read_u32_default(dev,
+ "clock-frequency", 0);
#endif
return 0;
diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c
index da3c204ff5..fcdc3c052b 100644
--- a/drivers/clk/clk_stm32f7.c
+++ b/drivers/clk/clk_stm32f7.c
@@ -252,8 +252,7 @@ static int stm32_clk_probe(struct udevice *dev)
return 0;
}
-static int stm32_clk_of_xlate(struct clk *clk,
- struct fdtdec_phandle_args *args)
+static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
{
debug("%s(clk=%p)\n", __func__, clk);
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index 6edc4dc6ca..50f2a65c20 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -459,14 +459,14 @@ static int zynq_clk_probe(struct udevice *dev)
for (i = 0; i < 2; i++) {
sprintf(name, "gem%d_emio_clk", i);
ret = clk_get_by_name(dev, name, &priv->gem_emio_clk[i]);
- if (ret < 0 && ret != -FDT_ERR_NOTFOUND) {
+ if (ret < 0 && ret != -ENODATA) {
dev_err(dev, "failed to get %s clock\n", name);
return ret;
}
}
#endif
- priv->ps_clk_freq = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+ priv->ps_clk_freq = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
"ps-clk-frequency", 33333333UL);
return 0;
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index 694274d991..50eaf31613 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -9,8 +9,8 @@
#include <common.h>
#include <linux/bitops.h>
#include <clk-uclass.h>
-#include <dm/device.h>
#include <clk.h>
+#include <dm.h>
#define ZYNQMP_GEM0_REF_CTRL 0xFF5E0050
#define ZYNQMP_IOPLL_CTRL 0xFF5E0020
diff --git a/drivers/clk/exynos/clk-exynos7420.c b/drivers/clk/exynos/clk-exynos7420.c
index 1f017a307f..e34945dbbc 100644
--- a/drivers/clk/exynos/clk-exynos7420.c
+++ b/drivers/clk/exynos/clk-exynos7420.c
@@ -98,7 +98,7 @@ static int exynos7420_clk_topc_probe(struct udevice *dev)
fdt_addr_t base;
int ret;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -152,7 +152,7 @@ static int exynos7420_clk_top0_probe(struct udevice *dev)
if (!priv)
return -EINVAL;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 1091a76f05..e404c0cdb9 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,4 +8,6 @@ obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o
+obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o
obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
+obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
index d866d0bf7a..5ecf5129d8 100644
--- a/drivers/clk/rockchip/clk_rk3036.c
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -40,7 +40,7 @@ enum {
#hz "Hz cannot be hit with PLL "\
"divisors on line " __stringify(__LINE__));
-/* use interge mode*/
+/* use integer mode*/
static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
@@ -61,16 +61,15 @@ static int rkclk_set_pll(struct rk3036_cru *cru, enum rk_clk_id clk_id,
assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
- /* use interger mode */
- rk_clrreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+ /* use integer mode */
+ rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
rk_clrsetreg(&pll->con0,
- PLL_POSTDIV1_MASK << PLL_POSTDIV1_SHIFT | PLL_FBDIV_MASK,
+ PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
(div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
- rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK << PLL_POSTDIV2_SHIFT |
- PLL_REFDIV_MASK << PLL_REFDIV_SHIFT,
- (div->postdiv2 << PLL_POSTDIV2_SHIFT |
- div->refdiv << PLL_REFDIV_SHIFT));
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+ (div->postdiv2 << PLL_POSTDIV2_SHIFT |
+ div->refdiv << PLL_REFDIV_SHIFT));
/* waiting for pll lock */
while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
@@ -87,8 +86,7 @@ static void rkclk_init(struct rk3036_cru *cru)
/* pll enter slow-mode */
rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- APLL_MODE_MASK << APLL_MODE_SHIFT,
+ GPLL_MODE_MASK | APLL_MODE_MASK,
GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
APLL_MODE_SLOW << APLL_MODE_SHIFT);
@@ -97,8 +95,8 @@ static void rkclk_init(struct rk3036_cru *cru)
rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
/*
- * select apll as core clock pll source and
- * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ * select apll as cpu/core clock pll source and
+ * set up dependent divisors for PERI and ACLK clocks.
* core hz : apll = 1:1
*/
aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
@@ -108,44 +106,40 @@ static void rkclk_init(struct rk3036_cru *cru)
assert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);
rk_clrsetreg(&cru->cru_clksel_con[0],
- CORE_CLK_PLL_SEL_MASK << CORE_CLK_PLL_SEL_SHIFT |
- CORE_DIV_CON_MASK << CORE_DIV_CON_SHIFT,
+ CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
0 << CORE_DIV_CON_SHIFT);
rk_clrsetreg(&cru->cru_clksel_con[1],
- CORE_ACLK_DIV_MASK << CORE_ACLK_DIV_SHIFT |
- CORE_PERI_DIV_MASK << CORE_PERI_DIV_SHIFT,
+ CORE_ACLK_DIV_MASK | CORE_PERI_DIV_MASK,
aclk_div << CORE_ACLK_DIV_SHIFT |
pclk_div << CORE_PERI_DIV_SHIFT);
/*
- * select apll as cpu clock pll source and
+ * select apll as pd_bus bus clock source and
* set up dependent divisors for PCLK/HCLK and ACLK clocks.
*/
- aclk_div = APLL_HZ / CPU_ACLK_HZ - 1;
- assert((aclk_div + 1) * CPU_ACLK_HZ == APLL_HZ && aclk_div < 0x1f);
+ aclk_div = GPLL_HZ / BUS_ACLK_HZ - 1;
+ assert((aclk_div + 1) * BUS_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
- pclk_div = APLL_HZ / CPU_PCLK_HZ - 1;
- assert((pclk_div + 1) * CPU_PCLK_HZ == APLL_HZ && pclk_div < 0x7);
+ pclk_div = GPLL_HZ / BUS_PCLK_HZ - 1;
+ assert((pclk_div + 1) * BUS_PCLK_HZ == GPLL_HZ && pclk_div <= 0x7);
- hclk_div = APLL_HZ / CPU_HCLK_HZ - 1;
- assert((hclk_div + 1) * CPU_HCLK_HZ == APLL_HZ && hclk_div < 0x3);
+ hclk_div = GPLL_HZ / BUS_HCLK_HZ - 1;
+ assert((hclk_div + 1) * BUS_HCLK_HZ == GPLL_HZ && hclk_div <= 0x3);
rk_clrsetreg(&cru->cru_clksel_con[0],
- CPU_CLK_PLL_SEL_MASK << CPU_CLK_PLL_SEL_SHIFT |
- ACLK_CPU_DIV_MASK << ACLK_CPU_DIV_SHIFT,
- CPU_CLK_PLL_SEL_APLL << CPU_CLK_PLL_SEL_SHIFT |
- aclk_div << ACLK_CPU_DIV_SHIFT);
+ BUS_ACLK_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
+ BUS_ACLK_PLL_SEL_GPLL << BUS_ACLK_PLL_SEL_SHIFT |
+ aclk_div << BUS_ACLK_DIV_SHIFT);
rk_clrsetreg(&cru->cru_clksel_con[1],
- CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
- CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
- pclk_div << CPU_PCLK_DIV_SHIFT |
- hclk_div << CPU_HCLK_DIV_SHIFT);
+ BUS_PCLK_DIV_MASK | BUS_HCLK_DIV_MASK,
+ pclk_div << BUS_PCLK_DIV_SHIFT |
+ hclk_div << BUS_HCLK_DIV_SHIFT);
/*
- * select gpll as peri clock pll source and
+ * select gpll as pd_peri bus clock source and
* set up dependent divisors for PCLK/HCLK and ACLK clocks.
*/
aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
@@ -153,17 +147,15 @@ static void rkclk_init(struct rk3036_cru *cru)
hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
assert((1 << hclk_div) * PERI_HCLK_HZ ==
- PERI_ACLK_HZ && (pclk_div < 0x4));
+ PERI_ACLK_HZ && (hclk_div < 0x4));
pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
assert((1 << pclk_div) * PERI_PCLK_HZ ==
PERI_ACLK_HZ && pclk_div < 0x8);
rk_clrsetreg(&cru->cru_clksel_con[10],
- PERI_PLL_SEL_MASK << PERI_PLL_SEL_SHIFT |
- PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
- PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
- PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+ PERI_PLL_SEL_MASK | PERI_PCLK_DIV_MASK |
+ PERI_HCLK_DIV_MASK | PERI_ACLK_DIV_MASK,
PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
pclk_div << PERI_PCLK_DIV_SHIFT |
hclk_div << PERI_HCLK_DIV_SHIFT |
@@ -171,8 +163,7 @@ static void rkclk_init(struct rk3036_cru *cru)
/* PLL enter normal-mode */
rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- APLL_MODE_MASK << APLL_MODE_SHIFT,
+ GPLL_MODE_MASK | APLL_MODE_MASK,
GPLL_MODE_NORM << GPLL_MODE_SHIFT |
APLL_MODE_NORM << APLL_MODE_SHIFT);
}
@@ -189,9 +180,9 @@ static uint32_t rkclk_pll_get_rate(struct rk3036_cru *cru,
0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, 0xff,
GPLL_MODE_SHIFT, 0xff
};
- static u8 clk_mask[CLK_COUNT] = {
- 0xff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xff,
- GPLL_MODE_MASK, 0xff
+ static u32 clk_mask[CLK_COUNT] = {
+ 0xffffffff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xffffffff,
+ GPLL_MODE_MASK, 0xffffffff
};
uint shift;
uint mask;
@@ -200,18 +191,18 @@ static uint32_t rkclk_pll_get_rate(struct rk3036_cru *cru,
shift = clk_shift[clk_id];
mask = clk_mask[clk_id];
- switch ((con >> shift) & mask) {
+ switch ((con & mask) >> shift) {
case GPLL_MODE_SLOW:
return OSC_HZ;
case GPLL_MODE_NORM:
/* normal mode */
con = readl(&pll->con0);
- postdiv1 = (con >> PLL_POSTDIV1_SHIFT) & PLL_POSTDIV1_MASK;
- fbdiv = (con >> PLL_FBDIV_SHIFT) & PLL_FBDIV_MASK;
+ postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
+ fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
con = readl(&pll->con1);
- postdiv2 = (con >> PLL_POSTDIV2_SHIFT) & PLL_POSTDIV2_MASK;
- refdiv = (con >> PLL_REFDIV_SHIFT) & PLL_REFDIV_MASK;
+ postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
+ refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
case GPLL_MODE_DEEP:
default:
@@ -230,14 +221,14 @@ static ulong rockchip_mmc_get_clk(struct rk3036_cru *cru, uint clk_general_rate,
case HCLK_EMMC:
case SCLK_EMMC:
con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
- div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+ mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;
+ div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
break;
case HCLK_SDIO:
case SCLK_SDIO:
con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
- div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+ mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;
+ div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;
break;
default:
return -EINVAL;
@@ -269,16 +260,14 @@ static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
case HCLK_EMMC:
case SCLK_EMMC:
rk_clrsetreg(&cru->cru_clksel_con[12],
- EMMC_PLL_MASK << EMMC_PLL_SHIFT |
- EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+ EMMC_PLL_MASK | EMMC_DIV_MASK,
mux << EMMC_PLL_SHIFT |
(src_clk_div - 1) << EMMC_DIV_SHIFT);
break;
case HCLK_SDIO:
case SCLK_SDIO:
rk_clrsetreg(&cru->cru_clksel_con[11],
- MMC0_PLL_MASK << MMC0_PLL_SHIFT |
- MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+ MMC0_PLL_MASK | MMC0_DIV_MASK,
mux << MMC0_PLL_SHIFT |
(src_clk_div - 1) << MMC0_DIV_SHIFT);
break;
@@ -331,7 +320,7 @@ static int rk3036_clk_probe(struct udevice *dev)
{
struct rk3036_clk_priv *priv = dev_get_priv(dev);
- priv->cru = (struct rk3036_cru *)dev_get_addr(dev);
+ priv->cru = (struct rk3036_cru *)devfdt_get_addr(dev);
rkclk_init(priv->cru);
return 0;
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
index b32491d3db..6f30332878 100644
--- a/drivers/clk/rockchip/clk_rk3188.c
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -542,7 +542,7 @@ static int rk3188_clk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3188_clk_priv *priv = dev_get_priv(dev);
- priv->cru = (struct rk3188_cru *)dev_get_addr(dev);
+ priv->cru = (struct rk3188_cru *)devfdt_get_addr(dev);
#endif
return 0;
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index fc369dde08..792ee76509 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -59,14 +59,14 @@ enum {
PLL_RESET_SHIFT = 5,
/* CLKSEL0 */
- CORE_SEL_PLL_MASK = 1,
CORE_SEL_PLL_SHIFT = 15,
- A17_DIV_MASK = 0x1f,
+ CORE_SEL_PLL_MASK = 1 << CORE_SEL_PLL_SHIFT,
A17_DIV_SHIFT = 8,
- MP_DIV_MASK = 0xf,
+ A17_DIV_MASK = 0x1f << A17_DIV_SHIFT,
MP_DIV_SHIFT = 4,
- M0_DIV_MASK = 0xf,
+ MP_DIV_MASK = 0xf << MP_DIV_SHIFT,
M0_DIV_SHIFT = 0,
+ M0_DIV_MASK = 0xf << M0_DIV_SHIFT,
/* CLKSEL1: pd bus clk pll sel: codec or general */
PD_BUS_SEL_PLL_MASK = 15,
@@ -75,41 +75,41 @@ enum {
/* pd bus pclk div: pclk = pd_bus_aclk /(div + 1) */
PD_BUS_PCLK_DIV_SHIFT = 12,
- PD_BUS_PCLK_DIV_MASK = 7,
+ PD_BUS_PCLK_DIV_MASK = 7 << PD_BUS_PCLK_DIV_SHIFT,
/* pd bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
PD_BUS_HCLK_DIV_SHIFT = 8,
- PD_BUS_HCLK_DIV_MASK = 3,
+ PD_BUS_HCLK_DIV_MASK = 3 << PD_BUS_HCLK_DIV_SHIFT,
/* pd bus aclk div: pd_bus_aclk = pd_bus_src_clk /(div0 * div1) */
PD_BUS_ACLK_DIV0_SHIFT = 3,
- PD_BUS_ACLK_DIV0_MASK = 0x1f,
+ PD_BUS_ACLK_DIV0_MASK = 0x1f << PD_BUS_ACLK_DIV0_SHIFT,
PD_BUS_ACLK_DIV1_SHIFT = 0,
- PD_BUS_ACLK_DIV1_MASK = 0x7,
+ PD_BUS_ACLK_DIV1_MASK = 0x7 << PD_BUS_ACLK_DIV1_SHIFT,
/*
* CLKSEL10
* peripheral bus pclk div:
* aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1
*/
- PERI_SEL_PLL_MASK = 1,
PERI_SEL_PLL_SHIFT = 15,
+ PERI_SEL_PLL_MASK = 1 << PERI_SEL_PLL_SHIFT,
PERI_SEL_CPLL = 0,
PERI_SEL_GPLL,
PERI_PCLK_DIV_SHIFT = 12,
- PERI_PCLK_DIV_MASK = 3,
+ PERI_PCLK_DIV_MASK = 3 << PERI_PCLK_DIV_SHIFT,
/* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
PERI_HCLK_DIV_SHIFT = 8,
- PERI_HCLK_DIV_MASK = 3,
+ PERI_HCLK_DIV_MASK = 3 << PERI_HCLK_DIV_SHIFT,
/*
* peripheral bus aclk div:
* aclk_periph = periph_clk_src / (peri_aclk_div_con + 1)
*/
PERI_ACLK_DIV_SHIFT = 0,
- PERI_ACLK_DIV_MASK = 0x1f,
+ PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT,
SOCSTS_DPLL_LOCK = 1 << 5,
SOCSTS_APLL_LOCK = 1 << 6,
@@ -131,10 +131,8 @@ enum {
/* Keep divisors as low as possible to reduce jitter and power usage */
static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
-#ifdef CONFIG_SPL_BUILD
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
-#endif
static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
const struct pll_div *div)
@@ -154,8 +152,7 @@ static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
/* enter reset */
rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
- rk_clrsetreg(&pll->con0,
- CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
+ rk_clrsetreg(&pll->con0, CLKR_MASK | PLL_OD_MASK,
((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
@@ -198,7 +195,7 @@ static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
}
/* pll enter slow-mode */
- rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
@@ -208,7 +205,7 @@ static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
udelay(1);
/* PLL enter normal-mode */
- rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
DPLL_MODE_NORMAL << DPLL_MODE_SHIFT);
return 0;
@@ -296,7 +293,7 @@ static int rockchip_mac_set_clk(struct rk3288_cru *cru,
{
/* Assuming mac_clk is fed by an external clock */
rk_clrsetreg(&cru->cru_clksel_con[21],
- RMII_EXTCLK_MASK << RMII_EXTCLK_SHIFT,
+ RMII_EXTCLK_MASK,
RMII_EXTCLK_SELECT_EXT_CLK << RMII_EXTCLK_SHIFT);
return 0;
@@ -313,7 +310,7 @@ static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
if (ret)
return ret;
- rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT,
+ rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK,
NPLL_MODE_SLOW << NPLL_MODE_SHIFT);
rkclk_set_pll(cru, CLK_NEW, &npll_config);
@@ -324,7 +321,7 @@ static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
udelay(1);
}
- rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT,
+ rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK,
NPLL_MODE_NORMAL << NPLL_MODE_SHIFT);
/* vop dclk source clk: npll,dclk_div: 1 */
@@ -341,9 +338,8 @@ static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
return 0;
}
-#endif
+#endif /* CONFIG_SPL_BUILD */
-#ifdef CONFIG_SPL_BUILD
static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
{
u32 aclk_div;
@@ -352,8 +348,7 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
/* pll enter slow-mode */
rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_MASK | CPLL_MODE_MASK,
GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
@@ -382,10 +377,8 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
PD_BUS_ACLK_HZ && pclk_div < 0x7);
rk_clrsetreg(&cru->cru_clksel_con[1],
- PD_BUS_PCLK_DIV_MASK << PD_BUS_PCLK_DIV_SHIFT |
- PD_BUS_HCLK_DIV_MASK << PD_BUS_HCLK_DIV_SHIFT |
- PD_BUS_ACLK_DIV0_MASK << PD_BUS_ACLK_DIV0_SHIFT |
- PD_BUS_ACLK_DIV1_MASK << PD_BUS_ACLK_DIV1_SHIFT,
+ PD_BUS_PCLK_DIV_MASK | PD_BUS_HCLK_DIV_MASK |
+ PD_BUS_ACLK_DIV0_MASK | PD_BUS_ACLK_DIV1_MASK,
pclk_div << PD_BUS_PCLK_DIV_SHIFT |
hclk_div << PD_BUS_HCLK_DIV_SHIFT |
aclk_div << PD_BUS_ACLK_DIV0_SHIFT |
@@ -407,9 +400,8 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
PERI_ACLK_HZ && (pclk_div < 0x4));
rk_clrsetreg(&cru->cru_clksel_con[10],
- PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
- PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
- PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+ PERI_PCLK_DIV_MASK | PERI_HCLK_DIV_MASK |
+ PERI_ACLK_DIV_MASK,
PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
pclk_div << PERI_PCLK_DIV_SHIFT |
hclk_div << PERI_HCLK_DIV_SHIFT |
@@ -417,18 +409,15 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
/* PLL enter normal-mode */
rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_MASK | CPLL_MODE_MASK,
GPLL_MODE_NORMAL << GPLL_MODE_SHIFT |
CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
}
-#endif
void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
{
/* pll enter slow-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- APLL_MODE_MASK << APLL_MODE_SHIFT,
+ rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
APLL_MODE_SLOW << APLL_MODE_SHIFT);
rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
@@ -444,10 +433,8 @@ void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
* arm clk = 1800MHz, mpclk = 450MHz, m0clk = 900MHz
*/
rk_clrsetreg(&cru->cru_clksel_con[0],
- CORE_SEL_PLL_MASK << CORE_SEL_PLL_SHIFT |
- A17_DIV_MASK << A17_DIV_SHIFT |
- MP_DIV_MASK << MP_DIV_SHIFT |
- M0_DIV_MASK << M0_DIV_SHIFT,
+ CORE_SEL_PLL_MASK | A17_DIV_MASK | MP_DIV_MASK |
+ M0_DIV_MASK,
0 << A17_DIV_SHIFT |
3 << MP_DIV_SHIFT |
1 << M0_DIV_SHIFT);
@@ -457,16 +444,14 @@ void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
* l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz
*/
rk_clrsetreg(&cru->cru_clksel_con[37],
- CLK_L2RAM_DIV_MASK << CLK_L2RAM_DIV_SHIFT |
- ATCLK_CORE_DIV_CON_MASK << ATCLK_CORE_DIV_CON_SHIFT |
- PCLK_CORE_DBG_DIV_MASK >> PCLK_CORE_DBG_DIV_SHIFT,
+ CLK_L2RAM_DIV_MASK | ATCLK_CORE_DIV_CON_MASK |
+ PCLK_CORE_DBG_DIV_MASK,
1 << CLK_L2RAM_DIV_SHIFT |
3 << ATCLK_CORE_DIV_CON_SHIFT |
3 << PCLK_CORE_DBG_DIV_SHIFT);
/* PLL enter normal-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- APLL_MODE_MASK << APLL_MODE_SHIFT,
+ rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
APLL_MODE_NORMAL << APLL_MODE_SHIFT);
}
@@ -486,16 +471,16 @@ static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru,
con = readl(&cru->cru_mode_con);
shift = clk_shift[clk_id];
- switch ((con >> shift) & APLL_MODE_MASK) {
+ switch ((con >> shift) & CRU_MODE_MASK) {
case APLL_MODE_SLOW:
return OSC_HZ;
case APLL_MODE_NORMAL:
/* normal mode */
con = readl(&pll->con0);
- no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1;
- nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1;
+ no = ((con & CLKOD_MASK) >> CLKOD_SHIFT) + 1;
+ nr = ((con & CLKR_MASK) >> CLKR_SHIFT) + 1;
con = readl(&pll->con1);
- nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1;
+ nf = ((con & CLKF_MASK) >> CLKF_SHIFT) + 1;
return (24 * nf / (nr * no)) * 1000000;
case APLL_MODE_DEEP:
@@ -515,20 +500,20 @@ static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
case HCLK_EMMC:
case SCLK_EMMC:
con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
- div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+ mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;
+ div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
break;
case HCLK_SDMMC:
case SCLK_SDMMC:
con = readl(&cru->cru_clksel_con[11]);
- mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
- div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+ mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;
+ div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;
break;
case HCLK_SDIO0:
case SCLK_SDIO0:
con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> SDIO0_PLL_SHIFT) & SDIO0_PLL_MASK;
- div = (con >> SDIO0_DIV_SHIFT) & SDIO0_DIV_MASK;
+ mux = (con & SDIO0_PLL_MASK) >> SDIO0_PLL_SHIFT;
+ div = (con & SDIO0_DIV_MASK) >> SDIO0_DIV_SHIFT;
break;
default:
return -EINVAL;
@@ -561,24 +546,21 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
case HCLK_EMMC:
case SCLK_EMMC:
rk_clrsetreg(&cru->cru_clksel_con[12],
- EMMC_PLL_MASK << EMMC_PLL_SHIFT |
- EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+ EMMC_PLL_MASK | EMMC_DIV_MASK,
mux << EMMC_PLL_SHIFT |
(src_clk_div - 1) << EMMC_DIV_SHIFT);
break;
case HCLK_SDMMC:
case SCLK_SDMMC:
rk_clrsetreg(&cru->cru_clksel_con[11],
- MMC0_PLL_MASK << MMC0_PLL_SHIFT |
- MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+ MMC0_PLL_MASK | MMC0_DIV_MASK,
mux << MMC0_PLL_SHIFT |
(src_clk_div - 1) << MMC0_DIV_SHIFT);
break;
case HCLK_SDIO0:
case SCLK_SDIO0:
rk_clrsetreg(&cru->cru_clksel_con[12],
- SDIO0_PLL_MASK << SDIO0_PLL_SHIFT |
- SDIO0_DIV_MASK << SDIO0_DIV_SHIFT,
+ SDIO0_PLL_MASK | SDIO0_DIV_MASK,
mux << SDIO0_PLL_SHIFT |
(src_clk_div - 1) << SDIO0_DIV_SHIFT);
break;
@@ -598,18 +580,18 @@ static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint gclk_rate,
switch (periph) {
case SCLK_SPI0:
con = readl(&cru->cru_clksel_con[25]);
- mux = (con >> SPI0_PLL_SHIFT) & SPI0_PLL_MASK;
- div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK;
+ mux = (con & SPI0_PLL_MASK) >> SPI0_PLL_SHIFT;
+ div = (con & SPI0_DIV_MASK) >> SPI0_DIV_SHIFT;
break;
case SCLK_SPI1:
con = readl(&cru->cru_clksel_con[25]);
- mux = (con >> SPI1_PLL_SHIFT) & SPI1_PLL_MASK;
- div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK;
+ mux = (con & SPI1_PLL_MASK) >> SPI1_PLL_SHIFT;
+ div = (con & SPI1_DIV_MASK) >> SPI1_DIV_SHIFT;
break;
case SCLK_SPI2:
con = readl(&cru->cru_clksel_con[39]);
- mux = (con >> SPI2_PLL_SHIFT) & SPI2_PLL_MASK;
- div = (con >> SPI2_DIV_SHIFT) & SPI2_DIV_MASK;
+ mux = (con & SPI2_PLL_MASK) >> SPI2_PLL_SHIFT;
+ div = (con & SPI2_DIV_MASK) >> SPI2_DIV_SHIFT;
break;
default:
return -EINVAL;
@@ -629,22 +611,19 @@ static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
switch (periph) {
case SCLK_SPI0:
rk_clrsetreg(&cru->cru_clksel_con[25],
- SPI0_PLL_MASK << SPI0_PLL_SHIFT |
- SPI0_DIV_MASK << SPI0_DIV_SHIFT,
+ SPI0_PLL_MASK | SPI0_DIV_MASK,
SPI0_PLL_SELECT_GENERAL << SPI0_PLL_SHIFT |
src_clk_div << SPI0_DIV_SHIFT);
break;
case SCLK_SPI1:
rk_clrsetreg(&cru->cru_clksel_con[25],
- SPI1_PLL_MASK << SPI1_PLL_SHIFT |
- SPI1_DIV_MASK << SPI1_DIV_SHIFT,
+ SPI1_PLL_MASK | SPI1_DIV_MASK,
SPI1_PLL_SELECT_GENERAL << SPI1_PLL_SHIFT |
src_clk_div << SPI1_DIV_SHIFT);
break;
case SCLK_SPI2:
rk_clrsetreg(&cru->cru_clksel_con[39],
- SPI2_PLL_MASK << SPI2_PLL_SHIFT |
- SPI2_DIV_MASK << SPI2_DIV_SHIFT,
+ SPI2_PLL_MASK | SPI2_DIV_MASK,
SPI2_PLL_SELECT_GENERAL << SPI2_PLL_SHIFT |
src_clk_div << SPI2_DIV_SHIFT);
break;
@@ -794,7 +773,7 @@ static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3288_clk_priv *priv = dev_get_priv(dev);
- priv->cru = (struct rk3288_cru *)dev_get_addr(dev);
+ priv->cru = (struct rk3288_cru *)devfdt_get_addr(dev);
#endif
return 0;
@@ -803,6 +782,7 @@ static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
static int rk3288_clk_probe(struct udevice *dev)
{
struct rk3288_clk_priv *priv = dev_get_priv(dev);
+ bool init_clocks = false;
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
if (IS_ERR(priv->grf))
@@ -813,8 +793,24 @@ static int rk3288_clk_probe(struct udevice *dev)
priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
#endif
- rkclk_init(priv->cru, priv->grf);
+ init_clocks = true;
#endif
+ if (!(gd->flags & GD_FLG_RELOC)) {
+ u32 reg;
+
+ /*
+ * Init clocks in U-Boot proper if the NPLL is runnning. This
+ * indicates that a previous boot loader set up the clocks, so
+ * we need to redo it. U-Boot's SPL does not set this clock.
+ */
+ reg = readl(&priv->cru->cru_mode_con);
+ if (((reg & NPLL_MODE_MASK) >> NPLL_MODE_SHIFT) ==
+ NPLL_MODE_NORMAL)
+ init_clocks = true;
+ }
+
+ if (init_clocks)
+ rkclk_init(priv->cru, priv->grf);
return 0;
}
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c
index 8ec157416e..2065a8a65b 100644
--- a/drivers/clk/rockchip/clk_rk3328.c
+++ b/drivers/clk/rockchip/clk_rk3328.c
@@ -555,7 +555,7 @@ static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
{
struct rk3328_clk_priv *priv = dev_get_priv(dev);
- priv->cru = (struct rk3328_cru *)dev_get_addr(dev);
+ priv->cru = (struct rk3328_cru *)devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c
new file mode 100644
index 0000000000..52cad38446
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3368.c
@@ -0,0 +1,291 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3368.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rk3368-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pll_div {
+ u32 nr;
+ u32 nf;
+ u32 no;
+};
+
+#define OSC_HZ (24 * 1000 * 1000)
+#define APLL_L_HZ (800 * 1000 * 1000)
+#define APLL_B_HZ (816 * 1000 * 1000)
+#define GPLL_HZ (576 * 1000 * 1000)
+#define CPLL_HZ (400 * 1000 * 1000)
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+ ((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) { \
+ .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no}; \
+ _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+ (_nr * _no) == hz, #hz "Hz cannot be hit with PLL " \
+ "divisors on line " __stringify(__LINE__));
+
+static const struct pll_div apll_l_init_cfg = PLL_DIVISORS(APLL_L_HZ, 12, 2);
+static const struct pll_div apll_b_init_cfg = PLL_DIVISORS(APLL_B_HZ, 1, 2);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 6);
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3368_cru *cru,
+ enum rk3368_pll_id pll_id)
+{
+ uint32_t nr, no, nf;
+ uint32_t con;
+ struct rk3368_pll *pll = &cru->pll[pll_id];
+
+ con = readl(&pll->con3);
+
+ switch ((con & PLL_MODE_MASK) >> PLL_MODE_SHIFT) {
+ case PLL_MODE_SLOW:
+ return OSC_HZ;
+ case PLL_MODE_NORMAL:
+ con = readl(&pll->con0);
+ no = ((con & PLL_OD_MASK) >> PLL_OD_SHIFT) + 1;
+ nr = ((con & PLL_NR_MASK) >> PLL_NR_SHIFT) + 1;
+ con = readl(&pll->con1);
+ nf = ((con & PLL_NF_MASK) >> PLL_NF_SHIFT) + 1;
+
+ return (24 * nf / (nr * no)) * 1000000;
+ case PLL_MODE_DEEP_SLOW:
+ default:
+ return 32768;
+ }
+}
+
+static int rkclk_set_pll(struct rk3368_cru *cru, enum rk3368_pll_id pll_id,
+ const struct pll_div *div, bool has_bwadj)
+{
+ struct rk3368_pll *pll = &cru->pll[pll_id];
+ /* All PLLs have same VCO and output frequency range restrictions*/
+ uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+ uint output_hz = vco_hz / div->no;
+
+ debug("PLL at %p: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
+ pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+
+ /* enter slow mode and reset pll */
+ rk_clrsetreg(&pll->con3, PLL_MODE_MASK | PLL_RESET_MASK,
+ PLL_RESET << PLL_RESET_SHIFT);
+
+ rk_clrsetreg(&pll->con0, PLL_NR_MASK | PLL_OD_MASK,
+ ((div->nr - 1) << PLL_NR_SHIFT) |
+ ((div->no - 1) << PLL_OD_SHIFT));
+ writel((div->nf - 1) << PLL_NF_SHIFT, &pll->con1);
+ udelay(10);
+
+ /* return from reset */
+ rk_clrreg(&pll->con3, PLL_RESET_MASK);
+
+ /* waiting for pll lock */
+ while (!(readl(&pll->con1) & PLL_LOCK_STA))
+ udelay(1);
+
+ rk_clrsetreg(&pll->con3, PLL_MODE_MASK,
+ PLL_MODE_NORMAL << PLL_MODE_SHIFT);
+
+ return 0;
+}
+
+static void rkclk_init(struct rk3368_cru *cru)
+{
+ u32 apllb, aplll, dpll, cpll, gpll;
+
+ rkclk_set_pll(cru, APLLB, &apll_b_init_cfg, false);
+ rkclk_set_pll(cru, APLLL, &apll_l_init_cfg, false);
+ rkclk_set_pll(cru, GPLL, &gpll_init_cfg, false);
+ rkclk_set_pll(cru, CPLL, &cpll_init_cfg, false);
+
+ apllb = rkclk_pll_get_rate(cru, APLLB);
+ aplll = rkclk_pll_get_rate(cru, APLLL);
+ dpll = rkclk_pll_get_rate(cru, DPLL);
+ cpll = rkclk_pll_get_rate(cru, CPLL);
+ gpll = rkclk_pll_get_rate(cru, GPLL);
+
+ debug("%s apllb(%d) apll(%d) dpll(%d) cpll(%d) gpll(%d)\n",
+ __func__, apllb, aplll, dpll, cpll, gpll);
+}
+
+static ulong rk3368_mmc_get_clk(struct rk3368_cru *cru, uint clk_id)
+{
+ u32 div, con, con_id, rate;
+ u32 pll_rate;
+
+ switch (clk_id) {
+ case SCLK_SDMMC:
+ con_id = 50;
+ break;
+ case SCLK_EMMC:
+ con_id = 51;
+ break;
+ case SCLK_SDIO0:
+ con_id = 48;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ con = readl(&cru->clksel_con[con_id]);
+ switch ((con & MMC_PLL_SEL_MASK) >> MMC_PLL_SEL_SHIFT) {
+ case MMC_PLL_SEL_GPLL:
+ pll_rate = rkclk_pll_get_rate(cru, GPLL);
+ break;
+ case MMC_PLL_SEL_24M:
+ pll_rate = OSC_HZ;
+ break;
+ case MMC_PLL_SEL_CPLL:
+ case MMC_PLL_SEL_USBPHY_480M:
+ default:
+ return -EINVAL;
+ }
+ div = (con & MMC_CLK_DIV_MASK) >> MMC_CLK_DIV_SHIFT;
+ rate = DIV_TO_RATE(pll_rate, div);
+
+ return rate >> 1;
+}
+
+static ulong rk3368_mmc_set_clk(struct rk3368_cru *cru,
+ ulong clk_id, ulong rate)
+{
+ u32 div;
+ u32 con_id;
+ u32 gpll_rate = rkclk_pll_get_rate(cru, GPLL);
+
+ div = RATE_TO_DIV(gpll_rate, rate << 1);
+
+ switch (clk_id) {
+ case SCLK_SDMMC:
+ con_id = 50;
+ break;
+ case SCLK_EMMC:
+ con_id = 51;
+ break;
+ case SCLK_SDIO0:
+ con_id = 48;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (div > 0x3f) {
+ div = RATE_TO_DIV(OSC_HZ, rate);
+ rk_clrsetreg(&cru->clksel_con[con_id],
+ MMC_PLL_SEL_MASK | MMC_CLK_DIV_MASK,
+ (MMC_PLL_SEL_24M << MMC_PLL_SEL_SHIFT) |
+ (div << MMC_CLK_DIV_SHIFT));
+ } else {
+ rk_clrsetreg(&cru->clksel_con[con_id],
+ MMC_PLL_SEL_MASK | MMC_CLK_DIV_MASK,
+ (MMC_PLL_SEL_GPLL << MMC_PLL_SEL_SHIFT) |
+ div << MMC_CLK_DIV_SHIFT);
+ }
+
+ return rk3368_mmc_get_clk(cru, clk_id);
+}
+
+static ulong rk3368_clk_get_rate(struct clk *clk)
+{
+ struct rk3368_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ debug("%s id:%ld\n", __func__, clk->id);
+ switch (clk->id) {
+ case HCLK_SDMMC:
+ case HCLK_EMMC:
+ rate = rk3368_mmc_get_clk(priv->cru, clk->id);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static ulong rk3368_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3368_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong ret = 0;
+
+ debug("%s id:%ld rate:%ld\n", __func__, clk->id, rate);
+ switch (clk->id) {
+ case SCLK_SDMMC:
+ case SCLK_EMMC:
+ ret = rk3368_mmc_set_clk(priv->cru, clk->id, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return ret;
+}
+
+static struct clk_ops rk3368_clk_ops = {
+ .get_rate = rk3368_clk_get_rate,
+ .set_rate = rk3368_clk_set_rate,
+};
+
+static int rk3368_clk_probe(struct udevice *dev)
+{
+ struct rk3368_clk_priv *priv = dev_get_priv(dev);
+
+ rkclk_init(priv->cru);
+
+ return 0;
+}
+
+static int rk3368_clk_ofdata_to_platdata(struct udevice *dev)
+{
+ struct rk3368_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3368_cru *)devfdt_get_addr(dev);
+
+ return 0;
+}
+
+static int rk3368_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "rk3368_sysreset", "reset", &dev);
+ if (ret)
+ error("bind RK3368 reset driver failed: ret=%d\n", ret);
+
+ return ret;
+}
+
+static const struct udevice_id rk3368_clk_ids[] = {
+ { .compatible = "rockchip,rk3368-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3368_cru) = {
+ .name = "rockchip_rk3368_cru",
+ .id = UCLASS_CLK,
+ .of_match = rk3368_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3368_cru),
+ .ofdata_to_platdata = rk3368_clk_ofdata_to_platdata,
+ .ops = &rk3368_clk_ops,
+ .bind = rk3368_clk_bind,
+ .probe = rk3368_clk_probe,
+};
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 026ed4dde7..53d2a3f85d 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -970,7 +970,7 @@ static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_priv *priv = dev_get_priv(dev);
- priv->cru = (struct rk3399_cru *)dev_get_addr(dev);
+ priv->cru = (struct rk3399_cru *)devfdt_get_addr(dev);
#endif
return 0;
}
@@ -1154,7 +1154,7 @@ static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
- priv->pmucru = (struct rk3399_pmucru *)dev_get_addr(dev);
+ priv->pmucru = (struct rk3399_pmucru *)devfdt_get_addr(dev);
#endif
return 0;
}
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c
new file mode 100644
index 0000000000..818293dfe8
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rv1108.c
@@ -0,0 +1,220 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rv1108.h>
+#include <asm/arch/hardware.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rv1108-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ VCO_MAX_HZ = 2400U * 1000000,
+ VCO_MIN_HZ = 600 * 1000000,
+ OUTPUT_MAX_HZ = 2400U * 1000000,
+ OUTPUT_MIN_HZ = 24 * 1000000,
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+ ((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
+ .refdiv = _refdiv,\
+ .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
+ .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\
+ _Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
+ OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
+ #hz "Hz cannot be hit with PLL "\
+ "divisors on line " __stringify(__LINE__));
+
+/* use interge mode*/
+static inline int rv1108_pll_id(enum rk_clk_id clk_id)
+{
+ int id = 0;
+
+ switch (clk_id) {
+ case CLK_ARM:
+ case CLK_DDR:
+ id = clk_id - 1;
+ break;
+ case CLK_GENERAL:
+ id = 2;
+ break;
+ default:
+ printf("invalid pll id:%d\n", clk_id);
+ id = -1;
+ break;
+ }
+
+ return id;
+}
+
+static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ uint32_t refdiv, fbdiv, postdiv1, postdiv2;
+ uint32_t con0, con1, con3;
+ int pll_id = rv1108_pll_id(clk_id);
+ struct rv1108_pll *pll = &cru->pll[pll_id];
+ uint32_t freq;
+
+ con3 = readl(&pll->con3);
+
+ if (con3 & WORK_MODE_MASK) {
+ con0 = readl(&pll->con0);
+ con1 = readl(&pll->con1);
+ fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK;
+ postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT;
+ postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
+ refdiv = (con1 & REFDIV_MASK) >> REFDIV_SHIFT;
+ freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+ } else {
+ freq = OSC_HZ;
+ }
+
+ return freq;
+}
+
+static int rv1108_mac_set_clk(struct rv1108_cru *cru, ulong rate)
+{
+ uint32_t con = readl(&cru->clksel_con[24]);
+ ulong pll_rate;
+ uint8_t div;
+
+ if ((con >> MAC_PLL_SEL_SHIFT) & MAC_PLL_SEL_GPLL)
+ pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+ else
+ pll_rate = rkclk_pll_get_rate(cru, CLK_ARM);
+
+ /*default set 50MHZ for gmac*/
+ if (!rate)
+ rate = 50000000;
+
+ div = DIV_ROUND_UP(pll_rate, rate) - 1;
+ if (div <= 0x1f)
+ rk_clrsetreg(&cru->clksel_con[24], MAC_CLK_DIV_MASK,
+ div << MAC_CLK_DIV_SHIFT);
+ else
+ debug("Unsupported div for gmac:%d\n", div);
+
+ return DIV_TO_RATE(pll_rate, div);
+}
+
+static int rv1108_sfc_set_clk(struct rv1108_cru *cru, uint rate)
+{
+ u32 con = readl(&cru->clksel_con[27]);
+ u32 pll_rate;
+ u32 div;
+
+ if ((con >> SFC_PLL_SEL_SHIFT) && SFC_PLL_SEL_GPLL)
+ pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
+ else
+ pll_rate = rkclk_pll_get_rate(cru, CLK_DDR);
+
+ div = DIV_ROUND_UP(pll_rate, rate) - 1;
+ if (div <= 0x3f)
+ rk_clrsetreg(&cru->clksel_con[27], SFC_CLK_DIV_MASK,
+ div << SFC_CLK_DIV_SHIFT);
+ else
+ debug("Unsupported sfc clk rate:%d\n", rate);
+
+ return DIV_TO_RATE(pll_rate, div);
+}
+
+static ulong rv1108_clk_get_rate(struct clk *clk)
+{
+ struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case 0 ... 63:
+ return rkclk_pll_get_rate(priv->cru, clk->id);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate;
+
+ switch (clk->id) {
+ case SCLK_MAC:
+ new_rate = rv1108_mac_set_clk(priv->cru, rate);
+ break;
+ case SCLK_SFC:
+ new_rate = rv1108_sfc_set_clk(priv->cru, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static const struct clk_ops rv1108_clk_ops = {
+ .get_rate = rv1108_clk_get_rate,
+ .set_rate = rv1108_clk_set_rate,
+};
+
+static void rkclk_init(struct rv1108_cru *cru)
+{
+ unsigned int apll = rkclk_pll_get_rate(cru, CLK_ARM);
+ unsigned int dpll = rkclk_pll_get_rate(cru, CLK_DDR);
+ unsigned int gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
+
+ rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK,
+ 0 << MAC_CLK_DIV_SHIFT);
+
+ printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
+}
+
+static int rv1108_clk_probe(struct udevice *dev)
+{
+ struct rv1108_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rv1108_cru *)devfdt_get_addr(dev);
+
+ rkclk_init(priv->cru);
+
+ return 0;
+}
+
+static int rv1108_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "rv1108_sysreset", "reset", &dev);
+ if (ret)
+ error("No Rv1108 reset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+static const struct udevice_id rv1108_clk_ids[] = {
+ { .compatible = "rockchip,rv1108-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(clk_rv1108) = {
+ .name = "clk_rv1108",
+ .id = UCLASS_CLK,
+ .of_match = rv1108_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rv1108_clk_priv),
+ .ops = &rv1108_clk_ops,
+ .bind = rv1108_clk_bind,
+ .probe = rv1108_clk_probe,
+};
diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c
index bcb2d2edb7..0fb48541b9 100644
--- a/drivers/clk/uniphier/clk-uniphier-core.c
+++ b/drivers/clk/uniphier/clk-uniphier-core.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <clk-uclass.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -121,7 +121,7 @@ static ulong uniphier_clk_set_rate(struct clk *clk, ulong rate)
return best_rate;
}
-const struct clk_ops uniphier_clk_ops = {
+static const struct clk_ops uniphier_clk_ops = {
.enable = uniphier_clk_enable,
.get_rate = uniphier_clk_get_rate,
.set_rate = uniphier_clk_set_rate,
@@ -132,7 +132,7 @@ static int uniphier_clk_probe(struct udevice *dev)
struct uniphier_clk_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev->parent);
+ addr = devfdt_get_addr(dev->parent);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 405e9ad8ef..fb5c4e834d 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -215,4 +215,8 @@ config OF_ISA_BUS
mistranslation of device addresses, so ensure that this is
enabled if your board does include an ISA bus.
+config DM_DEV_READ_INLINE
+ bool
+ default y if !OF_LIVE
+
endmenu
diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 07adb61c28..435cf98ae1 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -4,10 +4,15 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y += device.o lists.o root.o uclass.o util.o
+obj-y += device.o fdtaddr.o lists.o root.o uclass.o util.o
obj-$(CONFIG_DEVRES) += devres.o
obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o
obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o
obj-$(CONFIG_DM) += dump.o
obj-$(CONFIG_$(SPL_)REGMAP) += regmap.o
obj-$(CONFIG_$(SPL_)SYSCON) += syscon-uclass.o
+obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o
+ifndef CONFIG_DM_DEV_READ_INLINE
+obj-$(CONFIG_OF_CONTROL) += read.o
+endif
+obj-$(CONFIG_OF_CONTROL) += of_extra.o ofnode.o
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 09a115f753..5463d1ffa5 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -19,6 +19,7 @@
#include <dm/lists.h>
#include <dm/pinctrl.h>
#include <dm/platdata.h>
+#include <dm/read.h>
#include <dm/uclass.h>
#include <dm/uclass-internal.h>
#include <dm/util.h>
@@ -29,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int device_bind_common(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata,
- ulong driver_data, int of_offset,
+ ulong driver_data, ofnode node,
uint of_platdata_size, struct udevice **devp)
{
struct udevice *dev;
@@ -60,7 +61,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
dev->platdata = platdata;
dev->driver_data = driver_data;
dev->name = name;
- dev->of_offset = of_offset;
+ dev->node = node;
dev->parent = parent;
dev->driver = drv;
dev->uclass = uc;
@@ -76,10 +77,8 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
* resolved (and ->seq updated) when the device is probed.
*/
if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
- if (uc->uc_drv->name && of_offset != -1) {
- fdtdec_get_alias_seq(gd->fdt_blob,
- uc->uc_drv->name, of_offset,
- &dev->req_seq);
+ if (uc->uc_drv->name && ofnode_valid(node)) {
+ dev_read_alias_seq(dev, &dev->req_seq);
}
}
}
@@ -215,19 +214,19 @@ fail_alloc1:
int device_bind_with_driver_data(struct udevice *parent,
const struct driver *drv, const char *name,
- ulong driver_data, int of_offset,
+ ulong driver_data, ofnode node,
struct udevice **devp)
{
- return device_bind_common(parent, drv, name, NULL, driver_data,
- of_offset, 0, devp);
+ return device_bind_common(parent, drv, name, NULL, driver_data, node,
+ 0, devp);
}
int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, int of_offset,
struct udevice **devp)
{
- return device_bind_common(parent, drv, name, platdata, 0, of_offset, 0,
- devp);
+ return device_bind_common(parent, drv, name, platdata, 0,
+ offset_to_ofnode(of_offset), 0, devp);
}
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
@@ -246,7 +245,8 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
platdata_size = info->platdata_size;
#endif
return device_bind_common(parent, drv, info->name,
- (void *)info->platdata, 0, -1, platdata_size, devp);
+ (void *)info->platdata, 0, ofnode_null(), platdata_size,
+ devp);
}
static void *alloc_priv(int size, uint flags)
@@ -383,7 +383,7 @@ int device_probe(struct udevice *dev)
goto fail;
}
- if (drv->ofdata_to_platdata && dev_of_offset(dev) >= 0) {
+ if (drv->ofdata_to_platdata && dev_has_of_node(dev)) {
ret = drv->ofdata_to_platdata(dev);
if (ret)
goto fail;
@@ -655,131 +655,6 @@ const char *dev_get_uclass_name(struct udevice *dev)
return dev->uclass->uc_drv->name;
}
-fdt_addr_t dev_get_addr_index(struct udevice *dev, int index)
-{
-#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
- fdt_addr_t addr;
-
- if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
- const fdt32_t *reg;
- int len = 0;
- int na, ns;
-
- na = fdt_address_cells(gd->fdt_blob,
- dev_of_offset(dev->parent));
- if (na < 1) {
- debug("bad #address-cells\n");
- return FDT_ADDR_T_NONE;
- }
-
- ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
- if (ns < 0) {
- debug("bad #size-cells\n");
- return FDT_ADDR_T_NONE;
- }
-
- reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg",
- &len);
- if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) {
- debug("Req index out of range\n");
- return FDT_ADDR_T_NONE;
- }
-
- reg += index * (na + ns);
-
- /*
- * Use the full-fledged translate function for complex
- * bus setups.
- */
- addr = fdt_translate_address((void *)gd->fdt_blob,
- dev_of_offset(dev), reg);
- } else {
- /*
- * Use the "simple" translate function for less complex
- * bus setups.
- */
- addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
- dev_of_offset(dev->parent), dev_of_offset(dev),
- "reg", index, NULL, false);
- if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
- if (device_get_uclass_id(dev->parent) ==
- UCLASS_SIMPLE_BUS)
- addr = simple_bus_translate(dev->parent, addr);
- }
- }
-
- /*
- * Some platforms need a special address translation. Those
- * platforms (e.g. mvebu in SPL) can configure a translation
- * offset in the DM by calling dm_set_translation_offset() that
- * will get added to all addresses returned by dev_get_addr().
- */
- addr += dm_get_translation_offset();
-
- return addr;
-#else
- return FDT_ADDR_T_NONE;
-#endif
-}
-
-fdt_addr_t dev_get_addr_size_index(struct udevice *dev, int index,
- fdt_size_t *size)
-{
-#if CONFIG_IS_ENABLED(OF_CONTROL)
- /*
- * Only get the size in this first call. We'll get the addr in the
- * next call to the exisiting dev_get_xxx function which handles
- * all config options.
- */
- fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev),
- "reg", index, size, false);
-
- /*
- * Get the base address via the existing function which handles
- * all Kconfig cases
- */
- return dev_get_addr_index(dev, index);
-#else
- return FDT_ADDR_T_NONE;
-#endif
-}
-
-fdt_addr_t dev_get_addr_name(struct udevice *dev, const char *name)
-{
-#if CONFIG_IS_ENABLED(OF_CONTROL)
- int index;
-
- index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
- "reg-names", name);
- if (index < 0)
- return index;
-
- return dev_get_addr_index(dev, index);
-#else
- return FDT_ADDR_T_NONE;
-#endif
-}
-
-fdt_addr_t dev_get_addr(struct udevice *dev)
-{
- return dev_get_addr_index(dev, 0);
-}
-
-void *dev_get_addr_ptr(struct udevice *dev)
-{
- return (void *)(uintptr_t)dev_get_addr_index(dev, 0);
-}
-
-void *dev_map_physmem(struct udevice *dev, unsigned long size)
-{
- fdt_addr_t addr = dev_get_addr(dev);
-
- if (addr == FDT_ADDR_T_NONE)
- return NULL;
-
- return map_physmem(addr, size, MAP_NOCACHE);
-}
-
bool device_has_children(struct udevice *dev)
{
return !list_empty(&dev->child_head);
@@ -824,7 +699,7 @@ int device_set_name(struct udevice *dev, const char *name)
return 0;
}
-bool of_device_is_compatible(struct udevice *dev, const char *compat)
+bool device_is_compatible(struct udevice *dev, const char *compat)
{
const void *fdt = gd->fdt_blob;
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
new file mode 100644
index 0000000000..3847dd836e
--- /dev/null
+++ b/drivers/core/fdtaddr.c
@@ -0,0 +1,143 @@
+/*
+ * Device addresses
+ *
+ * Copyright (c) 2017 Google, Inc
+ *
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdt_support.h>
+#include <asm/io.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+fdt_addr_t devfdt_get_addr_index(struct udevice *dev, int index)
+{
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+ fdt_addr_t addr;
+
+ if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {
+ const fdt32_t *reg;
+ int len = 0;
+ int na, ns;
+
+ na = fdt_address_cells(gd->fdt_blob,
+ dev_of_offset(dev->parent));
+ if (na < 1) {
+ debug("bad #address-cells\n");
+ return FDT_ADDR_T_NONE;
+ }
+
+ ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
+ if (ns < 0) {
+ debug("bad #size-cells\n");
+ return FDT_ADDR_T_NONE;
+ }
+
+ reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg",
+ &len);
+ if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) {
+ debug("Req index out of range\n");
+ return FDT_ADDR_T_NONE;
+ }
+
+ reg += index * (na + ns);
+
+ /*
+ * Use the full-fledged translate function for complex
+ * bus setups.
+ */
+ addr = fdt_translate_address((void *)gd->fdt_blob,
+ dev_of_offset(dev), reg);
+ } else {
+ /*
+ * Use the "simple" translate function for less complex
+ * bus setups.
+ */
+ addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
+ dev_of_offset(dev->parent), dev_of_offset(dev),
+ "reg", index, NULL, false);
+ if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
+ if (device_get_uclass_id(dev->parent) ==
+ UCLASS_SIMPLE_BUS)
+ addr = simple_bus_translate(dev->parent, addr);
+ }
+ }
+
+ /*
+ * Some platforms need a special address translation. Those
+ * platforms (e.g. mvebu in SPL) can configure a translation
+ * offset in the DM by calling dm_set_translation_offset() that
+ * will get added to all addresses returned by devfdt_get_addr().
+ */
+ addr += dm_get_translation_offset();
+
+ return addr;
+#else
+ return FDT_ADDR_T_NONE;
+#endif
+}
+
+fdt_addr_t devfdt_get_addr_size_index(struct udevice *dev, int index,
+ fdt_size_t *size)
+{
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+ /*
+ * Only get the size in this first call. We'll get the addr in the
+ * next call to the exisiting dev_get_xxx function which handles
+ * all config options.
+ */
+ fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, dev_of_offset(dev),
+ "reg", index, size, false);
+
+ /*
+ * Get the base address via the existing function which handles
+ * all Kconfig cases
+ */
+ return devfdt_get_addr_index(dev, index);
+#else
+ return FDT_ADDR_T_NONE;
+#endif
+}
+
+fdt_addr_t devfdt_get_addr_name(struct udevice *dev, const char *name)
+{
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+ int index;
+
+ index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
+ "reg-names", name);
+ if (index < 0)
+ return index;
+
+ return devfdt_get_addr_index(dev, index);
+#else
+ return FDT_ADDR_T_NONE;
+#endif
+}
+
+fdt_addr_t devfdt_get_addr(struct udevice *dev)
+{
+ return devfdt_get_addr_index(dev, 0);
+}
+
+void *devfdt_get_addr_ptr(struct udevice *dev)
+{
+ return (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
+}
+
+void *devfdt_map_physmem(struct udevice *dev, unsigned long size)
+{
+ fdt_addr_t addr = devfdt_get_addr(dev);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_physmem(addr, size, MAP_NOCACHE);
+}
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 23b6ba78d3..b79f26dbe6 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -74,11 +74,12 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
int device_bind_driver(struct udevice *parent, const char *drv_name,
const char *dev_name, struct udevice **devp)
{
- return device_bind_driver_to_node(parent, drv_name, dev_name, -1, devp);
+ return device_bind_driver_to_node(parent, drv_name, dev_name,
+ ofnode_null(), devp);
}
int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
- const char *dev_name, int node,
+ const char *dev_name, ofnode node,
struct udevice **devp)
{
struct driver *drv;
@@ -89,14 +90,10 @@ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
debug("Cannot find driver '%s'\n", drv_name);
return -ENOENT;
}
- ret = device_bind(parent, drv, dev_name, NULL, node, devp);
- if (ret) {
- debug("Cannot create device named '%s' (err=%d)\n",
- dev_name, ret);
- return ret;
- }
+ ret = device_bind_with_driver_data(parent, drv, dev_name, 0 /* data */,
+ node, devp);
- return 0;
+ return ret;
}
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
@@ -126,8 +123,7 @@ static int driver_check_compatible(const struct udevice_id *of_match,
return -ENOENT;
}
-int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
- struct udevice **devp)
+int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp)
{
struct driver *driver = ll_entry_start(struct driver, driver);
const int n_ents = ll_entry_count(struct driver, driver);
@@ -140,19 +136,20 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
int result = 0;
int ret = 0;
- name = fdt_get_name(blob, offset, NULL);
- dm_dbg("bind node %s\n", name);
if (devp)
*devp = NULL;
+ name = ofnode_get_name(node);
+ dm_dbg("bind node %s\n", name);
- compat_list = fdt_getprop(blob, offset, "compatible", &compat_length);
+ compat_list = (const char *)ofnode_read_prop(node, "compatible",
+ &compat_length);
if (!compat_list) {
if (compat_length == -FDT_ERR_NOTFOUND) {
dm_dbg("Device '%s' has no compatible string\n", name);
return 0;
}
- dm_warn("Device tree error at offset %d\n", offset);
+ dm_warn("Device tree error at node '%s'\n", name);
return compat_length;
}
@@ -177,7 +174,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
dm_dbg(" - found match at '%s'\n", entry->name);
ret = device_bind_with_driver_data(parent, entry, name,
- id->data, offset, &dev);
+ id->data, node, &dev);
if (ret == -ENODEV) {
dm_dbg("Driver '%s' refuses to bind\n", entry->name);
continue;
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
new file mode 100644
index 0000000000..93a6560496
--- /dev/null
+++ b/drivers/core/of_access.c
@@ -0,0 +1,741 @@
+/*
+ * Originally from Linux v4.9
+ * Paul Mackerras August 1996.
+ * Copyright (C) 1996-2005 Paul Mackerras.
+ *
+ * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
+ * {engebret|bergner}@us.ibm.com
+ *
+ * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net
+ *
+ * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and
+ * Grant Likely.
+ *
+ * Modified for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * This file follows drivers/of/base.c with functions in the same order as the
+ * Linux version.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/ioport.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* list of struct alias_prop aliases */
+LIST_HEAD(aliases_lookup);
+
+/* "/aliaes" node */
+static struct device_node *of_aliases;
+
+/* "/chosen" node */
+static struct device_node *of_chosen;
+
+/* node pointed to by the stdout-path alias */
+static struct device_node *of_stdout;
+
+/* pointer to options given after the alias (separated by :) or NULL if none */
+static const char *of_stdout_options;
+
+/**
+ * struct alias_prop - Alias property in 'aliases' node
+ *
+ * The structure represents one alias property of 'aliases' node as
+ * an entry in aliases_lookup list.
+ *
+ * @link: List node to link the structure in aliases_lookup list
+ * @alias: Alias property name
+ * @np: Pointer to device_node that the alias stands for
+ * @id: Index value from end of alias name
+ * @stem: Alias string without the index
+ */
+struct alias_prop {
+ struct list_head link;
+ const char *alias;
+ struct device_node *np;
+ int id;
+ char stem[0];
+};
+
+int of_n_addr_cells(const struct device_node *np)
+{
+ const __be32 *ip;
+
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = of_get_property(np, "#address-cells", NULL);
+ if (ip)
+ return be32_to_cpup(ip);
+ } while (np->parent);
+
+ /* No #address-cells property for the root node */
+ return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+}
+
+int of_n_size_cells(const struct device_node *np)
+{
+ const __be32 *ip;
+
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = of_get_property(np, "#size-cells", NULL);
+ if (ip)
+ return be32_to_cpup(ip);
+ } while (np->parent);
+
+ /* No #size-cells property for the root node */
+ return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+}
+
+struct property *of_find_property(const struct device_node *np,
+ const char *name, int *lenp)
+{
+ struct property *pp;
+
+ if (!np)
+ return NULL;
+
+ for (pp = np->properties; pp; pp = pp->next) {
+ if (strcmp(pp->name, name) == 0) {
+ if (lenp)
+ *lenp = pp->length;
+ break;
+ }
+ }
+ if (!pp && lenp)
+ *lenp = -FDT_ERR_NOTFOUND;
+
+ return pp;
+}
+
+struct device_node *of_find_all_nodes(struct device_node *prev)
+{
+ struct device_node *np;
+
+ if (!prev) {
+ np = gd->of_root;
+ } else if (prev->child) {
+ np = prev->child;
+ } else {
+ /*
+ * Walk back up looking for a sibling, or the end of the
+ * structure
+ */
+ np = prev;
+ while (np->parent && !np->sibling)
+ np = np->parent;
+ np = np->sibling; /* Might be null at the end of the tree */
+ }
+
+ return np;
+}
+
+const void *of_get_property(const struct device_node *np, const char *name,
+ int *lenp)
+{
+ struct property *pp = of_find_property(np, name, lenp);
+
+ return pp ? pp->value : NULL;
+}
+
+static const char *of_prop_next_string(struct property *prop, const char *cur)
+{
+ const void *curv = cur;
+
+ if (!prop)
+ return NULL;
+
+ if (!cur)
+ return prop->value;
+
+ curv += strlen(cur) + 1;
+ if (curv >= prop->value + prop->length)
+ return NULL;
+
+ return curv;
+}
+
+int of_device_is_compatible(const struct device_node *device,
+ const char *compat, const char *type,
+ const char *name)
+{
+ struct property *prop;
+ const char *cp;
+ int index = 0, score = 0;
+
+ /* Compatible match has highest priority */
+ if (compat && compat[0]) {
+ prop = of_find_property(device, "compatible", NULL);
+ for (cp = of_prop_next_string(prop, NULL); cp;
+ cp = of_prop_next_string(prop, cp), index++) {
+ if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
+ score = INT_MAX/2 - (index << 2);
+ break;
+ }
+ }
+ if (!score)
+ return 0;
+ }
+
+ /* Matching type is better than matching name */
+ if (type && type[0]) {
+ if (!device->type || of_node_cmp(type, device->type))
+ return 0;
+ score += 2;
+ }
+
+ /* Matching name is a bit better than not */
+ if (name && name[0]) {
+ if (!device->name || of_node_cmp(name, device->name))
+ return 0;
+ score++;
+ }
+
+ return score;
+}
+
+bool of_device_is_available(const struct device_node *device)
+{
+ const char *status;
+ int statlen;
+
+ if (!device)
+ return false;
+
+ status = of_get_property(device, "status", &statlen);
+ if (status == NULL)
+ return true;
+
+ if (statlen > 0) {
+ if (!strcmp(status, "okay"))
+ return true;
+ }
+
+ return false;
+}
+
+struct device_node *of_get_parent(const struct device_node *node)
+{
+ const struct device_node *np;
+
+ if (!node)
+ return NULL;
+
+ np = of_node_get(node->parent);
+
+ return (struct device_node *)np;
+}
+
+static struct device_node *__of_get_next_child(const struct device_node *node,
+ struct device_node *prev)
+{
+ struct device_node *next;
+
+ if (!node)
+ return NULL;
+
+ next = prev ? prev->sibling : node->child;
+ /*
+ * coverity[dead_error_line : FALSE]
+ * Dead code here since our current implementation of of_node_get()
+ * always returns NULL (Coverity CID 163245). But we leave it as is
+ * since we may want to implement get/put later.
+ */
+ for (; next; next = next->sibling)
+ if (of_node_get(next))
+ break;
+ of_node_put(prev);
+ return next;
+}
+
+#define __for_each_child_of_node(parent, child) \
+ for (child = __of_get_next_child(parent, NULL); child != NULL; \
+ child = __of_get_next_child(parent, child))
+
+static struct device_node *__of_find_node_by_path(struct device_node *parent,
+ const char *path)
+{
+ struct device_node *child;
+ int len;
+
+ len = strcspn(path, "/:");
+ if (!len)
+ return NULL;
+
+ __for_each_child_of_node(parent, child) {
+ const char *name = strrchr(child->full_name, '/');
+
+ name++;
+ if (strncmp(path, name, len) == 0 && (strlen(name) == len))
+ return child;
+ }
+ return NULL;
+}
+
+#define for_each_property_of_node(dn, pp) \
+ for (pp = dn->properties; pp != NULL; pp = pp->next)
+
+struct device_node *of_find_node_opts_by_path(const char *path,
+ const char **opts)
+{
+ struct device_node *np = NULL;
+ struct property *pp;
+ const char *separator = strchr(path, ':');
+
+ if (opts)
+ *opts = separator ? separator + 1 : NULL;
+
+ if (strcmp(path, "/") == 0)
+ return of_node_get(gd->of_root);
+
+ /* The path could begin with an alias */
+ if (*path != '/') {
+ int len;
+ const char *p = separator;
+
+ if (!p)
+ p = strchrnul(path, '/');
+ len = p - path;
+
+ /* of_aliases must not be NULL */
+ if (!of_aliases)
+ return NULL;
+
+ for_each_property_of_node(of_aliases, pp) {
+ if (strlen(pp->name) == len && !strncmp(pp->name, path,
+ len)) {
+ np = of_find_node_by_path(pp->value);
+ break;
+ }
+ }
+ if (!np)
+ return NULL;
+ path = p;
+ }
+
+ /* Step down the tree matching path components */
+ if (!np)
+ np = of_node_get(gd->of_root);
+ while (np && *path == '/') {
+ struct device_node *tmp = np;
+
+ path++; /* Increment past '/' delimiter */
+ np = __of_find_node_by_path(np, path);
+ of_node_put(tmp);
+ path = strchrnul(path, '/');
+ if (separator && separator < path)
+ break;
+ }
+
+ return np;
+}
+
+struct device_node *of_find_compatible_node(struct device_node *from,
+ const char *type, const char *compatible)
+{
+ struct device_node *np;
+
+ for_each_of_allnodes_from(from, np)
+ if (of_device_is_compatible(np, compatible, type, NULL) &&
+ of_node_get(np))
+ break;
+ of_node_put(from);
+
+ return np;
+}
+
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+ struct device_node *np;
+
+ if (!handle)
+ return NULL;
+
+ for_each_of_allnodes(np)
+ if (np->phandle == handle)
+ break;
+ (void)of_node_get(np);
+
+ return np;
+}
+
+/**
+ * of_find_property_value_of_size() - find property of given size
+ *
+ * Search for a property in a device node and validate the requested size.
+ *
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @len: requested length of property value
+ *
+ * @return the property value on success, -EINVAL if the property does not
+ * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ */
+static void *of_find_property_value_of_size(const struct device_node *np,
+ const char *propname, u32 len)
+{
+ struct property *prop = of_find_property(np, propname, NULL);
+
+ if (!prop)
+ return ERR_PTR(-EINVAL);
+ if (!prop->value)
+ return ERR_PTR(-ENODATA);
+ if (len > prop->length)
+ return ERR_PTR(-EOVERFLOW);
+
+ return prop->value;
+}
+
+int of_read_u32(const struct device_node *np, const char *propname, u32 *outp)
+{
+ const __be32 *val;
+
+ debug("%s: %s: ", __func__, propname);
+ if (!np)
+ return -EINVAL;
+ val = of_find_property_value_of_size(np, propname, sizeof(*outp));
+ if (IS_ERR(val)) {
+ debug("(not found)\n");
+ return PTR_ERR(val);
+ }
+
+ *outp = be32_to_cpup(val);
+ debug("%#x (%d)\n", *outp, *outp);
+
+ return 0;
+}
+
+int of_read_u32_array(const struct device_node *np, const char *propname,
+ u32 *out_values, size_t sz)
+{
+ const __be32 *val;
+
+ debug("%s: %s: ", __func__, propname);
+ val = of_find_property_value_of_size(np, propname,
+ sz * sizeof(*out_values));
+
+ if (IS_ERR(val))
+ return PTR_ERR(val);
+
+ debug("size %zd\n", sz);
+ while (sz--)
+ *out_values++ = be32_to_cpup(val++);
+
+ return 0;
+}
+
+int of_property_match_string(const struct device_node *np, const char *propname,
+ const char *string)
+{
+ const struct property *prop = of_find_property(np, propname, NULL);
+ size_t l;
+ int i;
+ const char *p, *end;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+
+ p = prop->value;
+ end = p + prop->length;
+
+ for (i = 0; p < end; i++, p += l) {
+ l = strnlen(p, end - p) + 1;
+ if (p + l > end)
+ return -EILSEQ;
+ debug("comparing %s with %s\n", string, p);
+ if (strcmp(string, p) == 0)
+ return i; /* Found it; return index */
+ }
+ return -ENODATA;
+}
+
+/**
+ * of_property_read_string_helper() - Utility helper for parsing string properties
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @out_strs: output array of string pointers.
+ * @sz: number of array elements to read.
+ * @skip: Number of strings to skip over at beginning of list.
+ *
+ * Don't call this function directly. It is a utility helper for the
+ * of_property_read_string*() family of functions.
+ */
+int of_property_read_string_helper(const struct device_node *np,
+ const char *propname, const char **out_strs,
+ size_t sz, int skip)
+{
+ const struct property *prop = of_find_property(np, propname, NULL);
+ int l = 0, i = 0;
+ const char *p, *end;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ p = prop->value;
+ end = p + prop->length;
+
+ for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
+ l = strnlen(p, end - p) + 1;
+ if (p + l > end)
+ return -EILSEQ;
+ if (out_strs && i >= skip)
+ *out_strs++ = p;
+ }
+ i -= skip;
+ return i <= 0 ? -ENODATA : i;
+}
+
+static int __of_parse_phandle_with_args(const struct device_node *np,
+ const char *list_name,
+ const char *cells_name,
+ int cell_count, int index,
+ struct of_phandle_args *out_args)
+{
+ const __be32 *list, *list_end;
+ int rc = 0, cur_index = 0;
+ uint32_t count = 0;
+ struct device_node *node = NULL;
+ phandle phandle;
+ int size;
+
+ /* Retrieve the phandle list property */
+ list = of_get_property(np, list_name, &size);
+ if (!list)
+ return -ENOENT;
+ list_end = list + size / sizeof(*list);
+
+ /* Loop over the phandles until all the requested entry is found */
+ while (list < list_end) {
+ rc = -EINVAL;
+ count = 0;
+
+ /*
+ * If phandle is 0, then it is an empty entry with no
+ * arguments. Skip forward to the next entry.
+ */
+ phandle = be32_to_cpup(list++);
+ if (phandle) {
+ /*
+ * Find the provider node and parse the #*-cells
+ * property to determine the argument length.
+ *
+ * This is not needed if the cell count is hard-coded
+ * (i.e. cells_name not set, but cell_count is set),
+ * except when we're going to return the found node
+ * below.
+ */
+ if (cells_name || cur_index == index) {
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ debug("%s: could not find phandle\n",
+ np->full_name);
+ goto err;
+ }
+ }
+
+ if (cells_name) {
+ if (of_read_u32(node, cells_name, &count)) {
+ debug("%s: could not get %s for %s\n",
+ np->full_name, cells_name,
+ node->full_name);
+ goto err;
+ }
+ } else {
+ count = cell_count;
+ }
+
+ /*
+ * Make sure that the arguments actually fit in the
+ * remaining property data length
+ */
+ if (list + count > list_end) {
+ debug("%s: arguments longer than property\n",
+ np->full_name);
+ goto err;
+ }
+ }
+
+ /*
+ * All of the error cases above bail out of the loop, so at
+ * this point, the parsing is successful. If the requested
+ * index matches, then fill the out_args structure and return,
+ * or return -ENOENT for an empty entry.
+ */
+ rc = -ENOENT;
+ if (cur_index == index) {
+ if (!phandle)
+ goto err;
+
+ if (out_args) {
+ int i;
+ if (WARN_ON(count > OF_MAX_PHANDLE_ARGS))
+ count = OF_MAX_PHANDLE_ARGS;
+ out_args->np = node;
+ out_args->args_count = count;
+ for (i = 0; i < count; i++)
+ out_args->args[i] =
+ be32_to_cpup(list++);
+ } else {
+ of_node_put(node);
+ }
+
+ /* Found it! return success */
+ return 0;
+ }
+
+ of_node_put(node);
+ node = NULL;
+ list += count;
+ cur_index++;
+ }
+
+ /*
+ * Unlock node before returning result; will be one of:
+ * -ENOENT : index is for empty phandle
+ * -EINVAL : parsing error on data
+ * [1..n] : Number of phandle (count mode; when index = -1)
+ */
+ rc = index < 0 ? cur_index : -ENOENT;
+ err:
+ if (node)
+ of_node_put(node);
+ return rc;
+}
+
+struct device_node *of_parse_phandle(const struct device_node *np,
+ const char *phandle_name, int index)
+{
+ struct of_phandle_args args;
+
+ if (index < 0)
+ return NULL;
+
+ if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index,
+ &args))
+ return NULL;
+
+ return args.np;
+}
+
+int of_parse_phandle_with_args(const struct device_node *np,
+ const char *list_name, const char *cells_name,
+ int index, struct of_phandle_args *out_args)
+{
+ if (index < 0)
+ return -EINVAL;
+
+ return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
+ index, out_args);
+}
+
+static void of_alias_add(struct alias_prop *ap, struct device_node *np,
+ int id, const char *stem, int stem_len)
+{
+ ap->np = np;
+ ap->id = id;
+ strncpy(ap->stem, stem, stem_len);
+ ap->stem[stem_len] = 0;
+ list_add_tail(&ap->link, &aliases_lookup);
+ debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
+ ap->alias, ap->stem, ap->id, of_node_full_name(np));
+}
+
+int of_alias_scan(void)
+{
+ struct property *pp;
+
+ of_aliases = of_find_node_by_path("/aliases");
+ of_chosen = of_find_node_by_path("/chosen");
+ if (of_chosen == NULL)
+ of_chosen = of_find_node_by_path("/chosen@0");
+
+ if (of_chosen) {
+ const char *name;
+
+ name = of_get_property(of_chosen, "stdout-path", NULL);
+ if (name)
+ of_stdout = of_find_node_opts_by_path(name,
+ &of_stdout_options);
+ }
+
+ if (!of_aliases)
+ return 0;
+
+ for_each_property_of_node(of_aliases, pp) {
+ const char *start = pp->name;
+ const char *end = start + strlen(start);
+ struct device_node *np;
+ struct alias_prop *ap;
+ ulong id;
+ int len;
+
+ /* Skip those we do not want to proceed */
+ if (!strcmp(pp->name, "name") ||
+ !strcmp(pp->name, "phandle") ||
+ !strcmp(pp->name, "linux,phandle"))
+ continue;
+
+ np = of_find_node_by_path(pp->value);
+ if (!np)
+ continue;
+
+ /*
+ * walk the alias backwards to extract the id and work out
+ * the 'stem' string
+ */
+ while (isdigit(*(end-1)) && end > start)
+ end--;
+ len = end - start;
+
+ if (strict_strtoul(end, 10, &id) < 0)
+ continue;
+
+ /* Allocate an alias_prop with enough space for the stem */
+ ap = malloc(sizeof(*ap) + len + 1);
+ if (!ap)
+ return -ENOMEM;
+ memset(ap, 0, sizeof(*ap) + len + 1);
+ ap->alias = start;
+ of_alias_add(ap, np, id, start, len);
+ }
+
+ return 0;
+}
+
+int of_alias_get_id(const struct device_node *np, const char *stem)
+{
+ struct alias_prop *app;
+ int id = -ENODEV;
+
+ mutex_lock(&of_mutex);
+ list_for_each_entry(app, &aliases_lookup, link) {
+ if (strcmp(app->stem, stem) != 0)
+ continue;
+
+ if (np == app->np) {
+ id = app->id;
+ break;
+ }
+ }
+ mutex_unlock(&of_mutex);
+
+ return id;
+}
+
+struct device_node *of_get_stdout(void)
+{
+ return of_stdout;
+}
diff --git a/drivers/core/of_addr.c b/drivers/core/of_addr.c
new file mode 100644
index 0000000000..4757066967
--- /dev/null
+++ b/drivers/core/of_addr.c
@@ -0,0 +1,359 @@
+/*
+ * Taken from Linux v4.9 drivers/of/address.c
+ *
+ * Modified for U-Boot
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <dm/of_addr.h>
+#include <linux/err.h>
+#include <linux/ioport.h>
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS 4
+#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
+#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
+
+static struct of_bus *of_match_bus(struct device_node *np);
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, const __be32 *addr, int na)
+{
+ debug("%s", s);
+ while (na--)
+ pr_cont(" %08x", be32_to_cpu(*(addr++)));
+ pr_cont("\n");
+}
+#else
+static void of_dump_addr(const char *s, const __be32 *addr, int na) { }
+#endif
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+ const char *name;
+ const char *addresses;
+ int (*match)(struct device_node *parent);
+ void (*count_cells)(const struct device_node *child, int *addrc,
+ int *sizec);
+ u64 (*map)(__be32 *addr, const __be32 *range, int na, int ns, int pna);
+ int (*translate)(__be32 *addr, u64 offset, int na);
+ unsigned int (*get_flags)(const __be32 *addr);
+};
+
+static void of_bus_default_count_cells(const struct device_node *np,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(np);
+ if (sizec)
+ *sizec = of_n_size_cells(np);
+}
+
+static u64 of_bus_default_map(__be32 *addr, const __be32 *range,
+ int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ cp = of_read_number(range, na);
+ s = of_read_number(range + na + pna, ns);
+ da = of_read_number(addr, na);
+
+ debug("default map, cp=%llx, s=%llx, da=%llx\n",
+ (unsigned long long)cp, (unsigned long long)s,
+ (unsigned long long)da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_default_translate(__be32 *addr, u64 offset, int na)
+{
+ u64 a = of_read_number(addr, na);
+ memset(addr, 0, na * 4);
+ a += offset;
+ if (na > 1)
+ addr[na - 2] = cpu_to_be32(a >> 32);
+ addr[na - 1] = cpu_to_be32(a & 0xffffffffu);
+
+ return 0;
+}
+
+static unsigned int of_bus_default_get_flags(const __be32 *addr)
+{
+ return IORESOURCE_MEM;
+}
+
+/*
+ * Array of bus-specific translators
+ */
+static struct of_bus of_busses[] = {
+ /* Default */
+ {
+ .name = "default",
+ .addresses = "reg",
+ .match = NULL,
+ .count_cells = of_bus_default_count_cells,
+ .map = of_bus_default_map,
+ .translate = of_bus_default_translate,
+ .get_flags = of_bus_default_get_flags,
+ },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(of_busses); i++)
+ if (!of_busses[i].match || of_busses[i].match(np))
+ return &of_busses[i];
+ BUG();
+ return NULL;
+}
+
+static void dev_count_cells(const struct device_node *np, int *nap, int *nsp)
+{
+ of_bus_default_count_cells(np, nap, nsp);
+}
+
+const __be32 *of_get_address(const struct device_node *dev, int index,
+ u64 *size, unsigned int *flags)
+{
+ const __be32 *prop;
+ int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ dev_count_cells(dev, &na, &ns);
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+ of_node_put(parent);
+ if (!OF_CHECK_ADDR_COUNT(na))
+ return NULL;
+
+ /* Get "reg" or "assigned-addresses" property */
+ prop = of_get_property(dev, "reg", &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if (i == index) {
+ if (size)
+ *size = of_read_number(prop + na, ns);
+ if (flags)
+ *flags = bus->get_flags(prop);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+static int of_empty_ranges_quirk(const struct device_node *np)
+{
+ return false;
+}
+
+static int of_translate_one(const struct device_node *parent,
+ struct of_bus *bus, struct of_bus *pbus,
+ __be32 *addr, int na, int ns, int pna,
+ const char *rprop)
+{
+ const __be32 *ranges;
+ int rlen;
+ int rone;
+ u64 offset = OF_BAD_ADDR;
+
+ /*
+ * Normally, an absence of a "ranges" property means we are
+ * crossing a non-translatable boundary, and thus the addresses
+ * below the current cannot be converted to CPU physical ones.
+ * Unfortunately, while this is very clear in the spec, it's not
+ * what Apple understood, and they do have things like /uni-n or
+ * /ht nodes with no "ranges" property and a lot of perfectly
+ * useable mapped devices below them. Thus we treat the absence of
+ * "ranges" as equivalent to an empty "ranges" property which means
+ * a 1:1 translation at that level. It's up to the caller not to try
+ * to translate addresses that aren't supposed to be translated in
+ * the first place. --BenH.
+ *
+ * As far as we know, this damage only exists on Apple machines, so
+ * This code is only enabled on powerpc. --gcl
+ */
+ ranges = of_get_property(parent, rprop, &rlen);
+ if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
+ debug("no ranges; cannot translate\n");
+ return 1;
+ }
+ if (ranges == NULL || rlen == 0) {
+ offset = of_read_number(addr, na);
+ memset(addr, 0, pna * 4);
+ debug("empty ranges; 1:1 translation\n");
+ goto finish;
+ }
+
+ debug("walking ranges...\n");
+
+ /* Now walk through the ranges */
+ rlen /= 4;
+ rone = na + pna + ns;
+ for (; rlen >= rone; rlen -= rone, ranges += rone) {
+ offset = bus->map(addr, ranges, na, ns, pna);
+ if (offset != OF_BAD_ADDR)
+ break;
+ }
+ if (offset == OF_BAD_ADDR) {
+ debug("not found !\n");
+ return 1;
+ }
+ memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+ of_dump_addr("parent translation for:", addr, pna);
+ debug("with offset: %llx\n", (unsigned long long)offset);
+
+ /* Translate it into parent bus space */
+ return pbus->translate(addr, offset, pna);
+}
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+static u64 __of_translate_address(const struct device_node *dev,
+ const __be32 *in_addr, const char *rprop)
+{
+ struct device_node *parent = NULL;
+ struct of_bus *bus, *pbus;
+ __be32 addr[OF_MAX_ADDR_CELLS];
+ int na, ns, pna, pns;
+ u64 result = OF_BAD_ADDR;
+
+ debug("** translation for device %s **\n", of_node_full_name(dev));
+
+ /* Increase refcount at current level */
+ (void)of_node_get(dev);
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ goto bail;
+ bus = of_match_bus(parent);
+
+ /* Count address cells & copy address locally */
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_COUNTS(na, ns)) {
+ debug("Bad cell count for %s\n", of_node_full_name(dev));
+ goto bail;
+ }
+ memcpy(addr, in_addr, na * 4);
+
+ debug("bus is %s (na=%d, ns=%d) on %s\n", bus->name, na, ns,
+ of_node_full_name(parent));
+ of_dump_addr("translating address:", addr, na);
+
+ /* Translate */
+ for (;;) {
+ /* Switch to parent bus */
+ of_node_put(dev);
+ dev = parent;
+ parent = of_get_parent(dev);
+
+ /* If root, we have finished */
+ if (parent == NULL) {
+ debug("reached root node\n");
+ result = of_read_number(addr, na);
+ break;
+ }
+
+ /* Get new parent bus and counts */
+ pbus = of_match_bus(parent);
+ pbus->count_cells(dev, &pna, &pns);
+ if (!OF_CHECK_COUNTS(pna, pns)) {
+ debug("Bad cell count for %s\n",
+ of_node_full_name(dev));
+ break;
+ }
+
+ debug("parent bus is %s (na=%d, ns=%d) on %s\n", pbus->name,
+ pna, pns, of_node_full_name(parent));
+
+ /* Apply bus translation */
+ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+ break;
+
+ /* Complete the move up one level */
+ na = pna;
+ ns = pns;
+ bus = pbus;
+
+ of_dump_addr("one level translation:", addr, na);
+ }
+ bail:
+ of_node_put(parent);
+ of_node_put(dev);
+
+ return result;
+}
+
+u64 of_translate_address(const struct device_node *dev, const __be32 *in_addr)
+{
+ return __of_translate_address(dev, in_addr, "ranges");
+}
+
+
+static int __of_address_to_resource(const struct device_node *dev,
+ const __be32 *addrp, u64 size, unsigned int flags,
+ const char *name, struct resource *r)
+{
+ u64 taddr;
+
+ if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+ return -EINVAL;
+ taddr = of_translate_address(dev, addrp);
+ if (taddr == OF_BAD_ADDR)
+ return -EINVAL;
+ memset(r, 0, sizeof(struct resource));
+ r->start = taddr;
+ r->end = taddr + size - 1;
+ r->flags = flags;
+ r->name = name ? name : dev->full_name;
+
+ return 0;
+}
+
+int of_address_to_resource(const struct device_node *dev, int index,
+ struct resource *r)
+{
+ const __be32 *addrp;
+ u64 size;
+ unsigned int flags;
+ const char *name = NULL;
+
+ addrp = of_get_address(dev, index, &size, &flags);
+ if (addrp == NULL)
+ return -EINVAL;
+
+ /* Get optional "reg-names" property to add a name to a resource */
+ of_property_read_string_index(dev, "reg-names", index, &name);
+
+ return __of_address_to_resource(dev, addrp, size, flags, name, r);
+}
diff --git a/drivers/core/of_extra.c b/drivers/core/of_extra.c
new file mode 100644
index 0000000000..0381909848
--- /dev/null
+++ b/drivers/core/of_extra.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <dm/of_extra.h>
+#include <dm/ofnode.h>
+
+int of_read_fmap_entry(ofnode node, const char *name,
+ struct fmap_entry *entry)
+{
+ const char *prop;
+ u32 reg[2];
+
+ if (ofnode_read_u32_array(node, "reg", reg, 2)) {
+ debug("Node '%s' has bad/missing 'reg' property\n", name);
+ return -FDT_ERR_NOTFOUND;
+ }
+ entry->offset = reg[0];
+ entry->length = reg[1];
+ entry->used = ofnode_read_s32_default(node, "used", entry->length);
+ prop = ofnode_read_string(node, "compress");
+ entry->compress_algo = prop && !strcmp(prop, "lzo") ?
+ FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE;
+ prop = ofnode_read_string(node, "hash");
+ if (prop)
+ entry->hash_size = strlen(prop);
+ entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
+ entry->hash = (uint8_t *)prop;
+
+ return 0;
+}
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
new file mode 100644
index 0000000000..ac312d6546
--- /dev/null
+++ b/drivers/core/ofnode.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+#include <dm/of_access.h>
+#include <dm/of_addr.h>
+#include <dm/ofnode.h>
+#include <linux/err.h>
+
+int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
+{
+ assert(ofnode_valid(node));
+ debug("%s: %s: ", __func__, propname);
+
+ if (ofnode_is_np(node)) {
+ return of_read_u32(ofnode_to_np(node), propname, outp);
+ } else {
+ const int *cell;
+ int len;
+
+ cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+ propname, &len);
+ if (!cell || len < sizeof(int)) {
+ debug("(not found)\n");
+ return -EINVAL;
+ }
+ *outp = fdt32_to_cpu(cell[0]);
+ }
+ debug("%#x (%d)\n", *outp, *outp);
+
+ return 0;
+}
+
+int ofnode_read_u32_default(ofnode node, const char *propname, u32 def)
+{
+ assert(ofnode_valid(node));
+ ofnode_read_u32(node, propname, &def);
+
+ return def;
+}
+
+int ofnode_read_s32_default(ofnode node, const char *propname, s32 def)
+{
+ assert(ofnode_valid(node));
+ ofnode_read_u32(node, propname, (u32 *)&def);
+
+ return def;
+}
+
+bool ofnode_read_bool(ofnode node, const char *propname)
+{
+ bool val;
+
+ assert(ofnode_valid(node));
+ debug("%s: %s: ", __func__, propname);
+
+ if (ofnode_is_np(node)) {
+ val = !!of_find_property(ofnode_to_np(node), propname, NULL);
+ } else {
+ val = !!fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+ propname, NULL);
+ }
+ debug("%s\n", val ? "true" : "false");
+
+ return val;
+}
+
+const char *ofnode_read_string(ofnode node, const char *propname)
+{
+ const char *str = NULL;
+ int len = -1;
+
+ assert(ofnode_valid(node));
+ debug("%s: %s: ", __func__, propname);
+
+ if (ofnode_is_np(node)) {
+ struct property *prop = of_find_property(
+ ofnode_to_np(node), propname, NULL);
+
+ if (prop) {
+ str = prop->value;
+ len = prop->length;
+ }
+ } else {
+ str = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+ propname, &len);
+ }
+ if (!str) {
+ debug("<not found>\n");
+ return NULL;
+ }
+ if (strnlen(str, len) >= len) {
+ debug("<invalid>\n");
+ return NULL;
+ }
+ debug("%s\n", str);
+
+ return str;
+}
+
+ofnode ofnode_find_subnode(ofnode node, const char *subnode_name)
+{
+ ofnode subnode;
+
+ assert(ofnode_valid(node));
+ debug("%s: %s: ", __func__, subnode_name);
+
+ if (ofnode_is_np(node)) {
+ const struct device_node *np = ofnode_to_np(node);
+
+ for (np = np->child; np; np = np->sibling) {
+ if (!strcmp(subnode_name, np->name))
+ break;
+ }
+ subnode = np_to_ofnode(np);
+ } else {
+ int ooffset = fdt_subnode_offset(gd->fdt_blob,
+ ofnode_to_offset(node), subnode_name);
+ subnode = offset_to_ofnode(ooffset);
+ }
+ debug("%s\n", ofnode_valid(subnode) ?
+ ofnode_get_name(subnode) : "<none>");
+
+ return subnode;
+}
+
+int ofnode_read_u32_array(ofnode node, const char *propname,
+ u32 *out_values, size_t sz)
+{
+ assert(ofnode_valid(node));
+ debug("%s: %s: ", __func__, propname);
+
+ if (ofnode_is_np(node)) {
+ return of_read_u32_array(ofnode_to_np(node), propname,
+ out_values, sz);
+ } else {
+ return fdtdec_get_int_array(gd->fdt_blob,
+ ofnode_to_offset(node), propname,
+ out_values, sz);
+ }
+}
+
+ofnode ofnode_first_subnode(ofnode node)
+{
+ assert(ofnode_valid(node));
+ if (ofnode_is_np(node))
+ return np_to_ofnode(node.np->child);
+
+ return offset_to_ofnode(
+ fdt_first_subnode(gd->fdt_blob, ofnode_to_offset(node)));
+}
+
+ofnode ofnode_next_subnode(ofnode node)
+{
+ assert(ofnode_valid(node));
+ if (ofnode_is_np(node))
+ return np_to_ofnode(node.np->sibling);
+
+ return offset_to_ofnode(
+ fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node)));
+}
+
+const char *ofnode_get_name(ofnode node)
+{
+ assert(ofnode_valid(node));
+ if (ofnode_is_np(node))
+ return strrchr(node.np->full_name, '/') + 1;
+
+ return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL);
+}
+
+int ofnode_read_size(ofnode node, const char *propname)
+{
+ int len;
+
+ if (ofnode_is_np(node)) {
+ struct property *prop = of_find_property(
+ ofnode_to_np(node), propname, NULL);
+
+ if (prop)
+ return prop->length;
+ } else {
+ if (fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
+ &len))
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
+{
+ if (ofnode_is_np(node)) {
+ const __be32 *prop_val;
+ uint flags;
+ u64 size;
+
+ prop_val = of_get_address(
+ (struct device_node *)ofnode_to_np(node), index,
+ &size, &flags);
+ if (!prop_val)
+ return FDT_ADDR_T_NONE;
+ return be32_to_cpup(prop_val);
+ } else {
+ return fdt_get_base_address(gd->fdt_blob,
+ ofnode_to_offset(node));
+ }
+
+ return FDT_ADDR_T_NONE;
+}
+
+fdt_addr_t ofnode_get_addr(ofnode node)
+{
+ return ofnode_get_addr_index(node, 0);
+}
+
+int ofnode_stringlist_search(ofnode node, const char *property,
+ const char *string)
+{
+ if (ofnode_is_np(node)) {
+ return of_property_match_string(ofnode_to_np(node),
+ property, string);
+ } else {
+ int ret;
+
+ ret = fdt_stringlist_search(gd->fdt_blob,
+ ofnode_to_offset(node), property,
+ string);
+ if (ret == -FDT_ERR_NOTFOUND)
+ return -ENODATA;
+ else if (ret < 0)
+ return -EINVAL;
+
+ return ret;
+ }
+}
+
+int ofnode_read_string_index(ofnode node, const char *property, int index,
+ const char **outp)
+{
+ if (ofnode_is_np(node)) {
+ return of_property_read_string_index(ofnode_to_np(node),
+ property, index, outp);
+ } else {
+ int len;
+
+ *outp = fdt_stringlist_get(gd->fdt_blob, ofnode_to_offset(node),
+ property, index, &len);
+ if (len < 0)
+ return -EINVAL;
+ return 0;
+ }
+}
+
+static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in,
+ struct ofnode_phandle_args *out)
+{
+ assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
+ out->node = offset_to_ofnode(in->node);
+ out->args_count = in->args_count;
+ memcpy(out->args, in->args, sizeof(out->args));
+}
+
+static void ofnode_from_of_phandle_args(struct of_phandle_args *in,
+ struct ofnode_phandle_args *out)
+{
+ assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
+ out->node = np_to_ofnode(in->np);
+ out->args_count = in->args_count;
+ memcpy(out->args, in->args, sizeof(out->args));
+}
+
+int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
+ const char *cells_name, int cell_count,
+ int index,
+ struct ofnode_phandle_args *out_args)
+{
+ if (ofnode_is_np(node)) {
+ struct of_phandle_args args;
+ int ret;
+
+ ret = of_parse_phandle_with_args(ofnode_to_np(node),
+ list_name, cells_name, index, &args);
+ if (ret)
+ return ret;
+ ofnode_from_of_phandle_args(&args, out_args);
+ } else {
+ struct fdtdec_phandle_args args;
+ int ret;
+
+ ret = fdtdec_parse_phandle_with_args(gd->fdt_blob,
+ ofnode_to_offset(node), list_name, cells_name,
+ cell_count, index, &args);
+ if (ret)
+ return ret;
+ ofnode_from_fdtdec_phandle_args(&args, out_args);
+ }
+
+ return 0;
+}
+
+ofnode ofnode_path(const char *path)
+{
+ if (of_live_active())
+ return np_to_ofnode(of_find_node_by_path(path));
+ else
+ return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path));
+}
+
+const char *ofnode_get_chosen_prop(const char *name)
+{
+ ofnode chosen_node;
+
+ chosen_node = ofnode_path("/chosen");
+
+ return ofnode_read_string(chosen_node, name);
+}
+
+ofnode ofnode_get_chosen_node(const char *name)
+{
+ const char *prop;
+
+ prop = ofnode_get_chosen_prop(name);
+ if (!prop)
+ return ofnode_null();
+
+ return ofnode_path(prop);
+}
+
+static int decode_timing_property(ofnode node, const char *name,
+ struct timing_entry *result)
+{
+ int length, ret = 0;
+
+ length = ofnode_read_size(node, name);
+ if (length < 0) {
+ debug("%s: could not find property %s\n",
+ ofnode_get_name(node), name);
+ return length;
+ }
+
+ if (length == sizeof(u32)) {
+ result->typ = ofnode_read_u32_default(node, name, 0);
+ result->min = result->typ;
+ result->max = result->typ;
+ } else {
+ ret = ofnode_read_u32_array(node, name, &result->min, 3);
+ }
+
+ return ret;
+}
+
+int ofnode_decode_display_timing(ofnode parent, int index,
+ struct display_timing *dt)
+{
+ int i;
+ ofnode timings, node;
+ u32 val = 0;
+ int ret = 0;
+
+ timings = ofnode_find_subnode(parent, "display-timings");
+ if (!ofnode_valid(timings))
+ return -EINVAL;
+
+ for (i = 0, node = ofnode_first_subnode(timings);
+ ofnode_valid(node) && i != index;
+ node = ofnode_first_subnode(node))
+ i++;
+
+ if (!ofnode_valid(node))
+ return -EINVAL;
+
+ memset(dt, 0, sizeof(*dt));
+
+ ret |= decode_timing_property(node, "hback-porch", &dt->hback_porch);
+ ret |= decode_timing_property(node, "hfront-porch", &dt->hfront_porch);
+ ret |= decode_timing_property(node, "hactive", &dt->hactive);
+ ret |= decode_timing_property(node, "hsync-len", &dt->hsync_len);
+ ret |= decode_timing_property(node, "vback-porch", &dt->vback_porch);
+ ret |= decode_timing_property(node, "vfront-porch", &dt->vfront_porch);
+ ret |= decode_timing_property(node, "vactive", &dt->vactive);
+ ret |= decode_timing_property(node, "vsync-len", &dt->vsync_len);
+ ret |= decode_timing_property(node, "clock-frequency", &dt->pixelclock);
+
+ dt->flags = 0;
+ val = ofnode_read_u32_default(node, "vsync-active", -1);
+ if (val != -1) {
+ dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
+ DISPLAY_FLAGS_VSYNC_LOW;
+ }
+ val = ofnode_read_u32_default(node, "hsync-active", -1);
+ if (val != -1) {
+ dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
+ DISPLAY_FLAGS_HSYNC_LOW;
+ }
+ val = ofnode_read_u32_default(node, "de-active", -1);
+ if (val != -1) {
+ dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
+ DISPLAY_FLAGS_DE_LOW;
+ }
+ val = ofnode_read_u32_default(node, "pixelclk-active", -1);
+ if (val != -1) {
+ dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
+ DISPLAY_FLAGS_PIXDATA_NEGEDGE;
+ }
+
+ if (ofnode_read_bool(node, "interlaced"))
+ dt->flags |= DISPLAY_FLAGS_INTERLACED;
+ if (ofnode_read_bool(node, "doublescan"))
+ dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
+ if (ofnode_read_bool(node, "doubleclk"))
+ dt->flags |= DISPLAY_FLAGS_DOUBLECLK;
+
+ return ret;
+}
+
+const u32 *ofnode_read_prop(ofnode node, const char *propname, int *lenp)
+{
+ if (ofnode_is_np(node)) {
+ struct property *prop;
+
+ prop = of_find_property(ofnode_to_np(node), propname, lenp);
+ if (!prop)
+ return NULL;
+ return prop->value;
+ } else {
+ return fdt_getprop(gd->fdt_blob, ofnode_to_offset(node),
+ propname, lenp);
+ }
+}
+
+bool ofnode_is_available(ofnode node)
+{
+ if (ofnode_is_np(node))
+ return of_device_is_available(ofnode_to_np(node));
+ else
+ return fdtdec_get_is_enabled(gd->fdt_blob,
+ ofnode_to_offset(node));
+}
+
+fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
+ fdt_size_t *sizep)
+{
+ if (ofnode_is_np(node)) {
+ int na, ns;
+ int psize;
+ const struct device_node *np = ofnode_to_np(node);
+ const __be32 *prop = of_get_property(np, "reg", &psize);
+
+ na = of_n_addr_cells(np);
+ ns = of_n_addr_cells(np);
+ *sizep = of_read_number(prop + na, ns);
+ return of_read_number(prop, na);
+ } else {
+ return fdtdec_get_addr_size(gd->fdt_blob,
+ ofnode_to_offset(node), property,
+ sizep);
+ }
+}
+
+const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
+ size_t sz)
+{
+ if (ofnode_is_np(node)) {
+ const struct device_node *np = ofnode_to_np(node);
+ int psize;
+ const __be32 *prop = of_get_property(np, propname, &psize);
+
+ if (!prop || sz != psize)
+ return NULL;
+ return (uint8_t *)prop;
+
+ } else {
+ return fdtdec_locate_byte_array(gd->fdt_blob,
+ ofnode_to_offset(node), propname, sz);
+ }
+}
+
+int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
+ const char *propname, struct fdt_pci_addr *addr)
+{
+ const u32 *cell;
+ int len;
+ int ret = -ENOENT;
+
+ debug("%s: %s: ", __func__, propname);
+
+ /*
+ * If we follow the pci bus bindings strictly, we should check
+ * the value of the node's parent node's #address-cells and
+ * #size-cells. They need to be 3 and 2 accordingly. However,
+ * for simplicity we skip the check here.
+ */
+ cell = ofnode_read_prop(node, propname, &len);
+ if (!cell)
+ goto fail;
+
+ if ((len % FDT_PCI_REG_SIZE) == 0) {
+ int num = len / FDT_PCI_REG_SIZE;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ debug("pci address #%d: %08lx %08lx %08lx\n", i,
+ (ulong)fdt32_to_cpu(cell[0]),
+ (ulong)fdt32_to_cpu(cell[1]),
+ (ulong)fdt32_to_cpu(cell[2]));
+ if ((fdt32_to_cpu(*cell) & type) == type) {
+ addr->phys_hi = fdt32_to_cpu(cell[0]);
+ addr->phys_mid = fdt32_to_cpu(cell[1]);
+ addr->phys_lo = fdt32_to_cpu(cell[1]);
+ break;
+ } else {
+ cell += (FDT_PCI_ADDR_CELLS +
+ FDT_PCI_SIZE_CELLS);
+ }
+ }
+
+ if (i == num) {
+ ret = -ENXIO;
+ goto fail;
+ }
+
+ return 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+fail:
+ debug("(not found)\n");
+ return ret;
+}
+
+int ofnode_read_addr_cells(ofnode node)
+{
+ if (ofnode_is_np(node))
+ return of_n_addr_cells(ofnode_to_np(node));
+ else
+ return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+int ofnode_read_size_cells(ofnode node)
+{
+ if (ofnode_is_np(node))
+ return of_n_size_cells(ofnode_to_np(node));
+ else
+ return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+bool ofnode_pre_reloc(ofnode node)
+{
+ if (ofnode_read_prop(node, "u-boot,dm-pre-reloc", NULL))
+ return true;
+
+#ifdef CONFIG_TPL_BUILD
+ if (ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+ return true;
+#elif defined(CONFIG_SPL_BUILD)
+ if (ofnode_read_prop(node, "u-boot,dm-spl", NULL))
+ return true;
+#else
+ /*
+ * In regular builds individual spl and tpl handling both
+ * count as handled pre-relocation for later second init.
+ */
+ if (ofnode_read_prop(node, "u-boot,dm-spl", NULL) ||
+ ofnode_read_prop(node, "u-boot,dm-tpl", NULL))
+ return true;
+#endif
+
+ return false;
+}
diff --git a/drivers/core/read.c b/drivers/core/read.c
new file mode 100644
index 0000000000..3131e5379c
--- /dev/null
+++ b/drivers/core/read.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/of_access.h>
+
+int dev_read_u32_default(struct udevice *dev, const char *propname, int def)
+{
+ return ofnode_read_u32_default(dev_ofnode(dev), propname, def);
+}
+
+const char *dev_read_string(struct udevice *dev, const char *propname)
+{
+ return ofnode_read_string(dev_ofnode(dev), propname);
+}
+
+bool dev_read_bool(struct udevice *dev, const char *propname)
+{
+ return ofnode_read_bool(dev_ofnode(dev), propname);
+}
+
+ofnode dev_read_subnode(struct udevice *dev, const char *subnode_name)
+{
+ return ofnode_find_subnode(dev_ofnode(dev), subnode_name);
+}
+
+ofnode dev_read_first_subnode(struct udevice *dev)
+{
+ return ofnode_first_subnode(dev_ofnode(dev));
+}
+
+ofnode dev_read_next_subnode(ofnode node)
+{
+ return ofnode_next_subnode(node);
+}
+
+int dev_read_size(struct udevice *dev, const char *propname)
+{
+ return ofnode_read_size(dev_ofnode(dev), propname);
+}
+
+fdt_addr_t dev_read_addr_index(struct udevice *dev, int index)
+{
+ if (ofnode_is_np(dev_ofnode(dev)))
+ return ofnode_get_addr_index(dev_ofnode(dev), index);
+ else
+ return devfdt_get_addr_index(dev, index);
+}
+
+fdt_addr_t dev_read_addr(struct udevice *dev)
+{
+ return dev_read_addr_index(dev, 0);
+}
+
+fdt_addr_t dev_read_addr_size(struct udevice *dev, const char *property,
+ fdt_size_t *sizep)
+{
+ return ofnode_get_addr_size(dev_ofnode(dev), property, sizep);
+}
+
+const char *dev_read_name(struct udevice *dev)
+{
+ return ofnode_get_name(dev_ofnode(dev));
+}
+
+int dev_read_stringlist_search(struct udevice *dev, const char *property,
+ const char *string)
+{
+ return ofnode_stringlist_search(dev_ofnode(dev), property, string);
+}
+
+int dev_read_phandle_with_args(struct udevice *dev, const char *list_name,
+ const char *cells_name, int cell_count,
+ int index,
+ struct ofnode_phandle_args *out_args)
+{
+ return ofnode_parse_phandle_with_args(dev_ofnode(dev), list_name,
+ cells_name, cell_count, index,
+ out_args);
+}
+
+int dev_read_addr_cells(struct udevice *dev)
+{
+ return ofnode_read_addr_cells(dev_ofnode(dev));
+}
+
+int dev_read_size_cells(struct udevice *dev)
+{
+ return ofnode_read_size_cells(dev_ofnode(dev));
+}
+
+int dev_read_phandle(struct udevice *dev)
+{
+ ofnode node = dev_ofnode(dev);
+
+ if (ofnode_is_np(node))
+ return ofnode_to_np(node)->phandle;
+ else
+ return fdt_get_phandle(gd->fdt_blob, ofnode_to_offset(node));
+}
+
+const u32 *dev_read_prop(struct udevice *dev, const char *propname, int *lenp)
+{
+ return ofnode_read_prop(dev_ofnode(dev), propname, lenp);
+}
+
+int dev_read_alias_seq(struct udevice *dev, int *devnump)
+{
+ ofnode node = dev_ofnode(dev);
+ const char *uc_name = dev->uclass->uc_drv->name;
+ int ret;
+
+ if (ofnode_is_np(node)) {
+ ret = of_alias_get_id(ofnode_to_np(node), uc_name);
+ if (ret >= 0)
+ *devnump = ret;
+ } else {
+ ret = fdtdec_get_alias_seq(gd->fdt_blob, uc_name,
+ ofnode_to_offset(node), devnump);
+ }
+
+ return ret;
+}
+
+int dev_read_u32_array(struct udevice *dev, const char *propname,
+ u32 *out_values, size_t sz)
+{
+ return ofnode_read_u32_array(dev_ofnode(dev), propname, out_values, sz);
+}
+
+const uint8_t *dev_read_u8_array_ptr(struct udevice *dev, const char *propname,
+ size_t sz)
+{
+ return ofnode_read_u8_array_ptr(dev_ofnode(dev), propname, sz);
+}
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 3bec3df9b6..749d913372 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -12,8 +12,9 @@
#include <malloc.h>
#include <mapmem.h>
#include <regmap.h>
-
#include <asm/io.h>
+#include <dm/of_addr.h>
+#include <linux/ioport.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -62,25 +63,25 @@ int regmap_init_mem_platdata(struct udevice *dev, u32 *reg, int count,
#else
int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
{
- const void *blob = gd->fdt_blob;
struct regmap_range *range;
- const fdt32_t *cell;
struct regmap *map;
int count;
int addr_len, size_len, both_len;
- int parent;
int len;
int index;
+ ofnode node = dev_ofnode(dev);
+ struct resource r;
- parent = dev_of_offset(dev->parent);
- addr_len = fdt_address_cells(blob, parent);
- size_len = fdt_size_cells(blob, parent);
+ addr_len = dev_read_addr_cells(dev->parent);
+ size_len = dev_read_size_cells(dev->parent);
both_len = addr_len + size_len;
- cell = fdt_getprop(blob, dev_of_offset(dev), "reg", &len);
- len /= sizeof(*cell);
+ len = dev_read_size(dev, "reg");
+ if (len < 0)
+ return len;
+ len /= sizeof(fdt32_t);
count = len / both_len;
- if (!cell || !count)
+ if (!count)
return -EINVAL;
map = regmap_alloc_count(count);
@@ -88,11 +89,18 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
return -ENOMEM;
for (range = map->range, index = 0; count > 0;
- count--, cell += both_len, range++, index++) {
+ count--, range++, index++) {
fdt_size_t sz;
- range->start = fdtdec_get_addr_size_fixed(blob, dev->of_offset,
- "reg", index, addr_len, size_len, &sz, true);
- range->size = sz;
+ if (of_live_active()) {
+ of_address_to_resource(ofnode_to_np(node), index, &r);
+ range->start = r.start;
+ range->size = r.end - r.start + 1;
+ } else {
+ range->start = fdtdec_get_addr_size_fixed(gd->fdt_blob,
+ dev_of_offset(dev), "reg", index,
+ addr_len, size_len, &sz, true);
+ range->size = sz;
+ }
}
map->base = map->range[0].start;
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 42679d047c..d691d6ff94 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -15,7 +15,10 @@
#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
+#include <dm/of.h>
+#include <dm/of_access.h>
#include <dm/platdata.h>
+#include <dm/read.h>
#include <dm/root.h>
#include <dm/uclass.h>
#include <dm/util.h>
@@ -147,7 +150,7 @@ void fix_devices(void)
#endif
-int dm_init(void)
+int dm_init(bool of_live)
{
int ret;
@@ -167,7 +170,12 @@ int dm_init(void)
if (ret)
return ret;
#if CONFIG_IS_ENABLED(OF_CONTROL)
- DM_ROOT_NON_CONST->of_offset = 0;
+# if CONFIG_IS_ENABLED(OF_LIVE)
+ if (of_live)
+ DM_ROOT_NON_CONST->node = np_to_ofnode(gd->of_root);
+ else
+#endif
+ DM_ROOT_NON_CONST->node = offset_to_ofnode(0);
#endif
ret = device_probe(DM_ROOT_NON_CONST);
if (ret)
@@ -206,9 +214,52 @@ int dm_scan_platdata(bool pre_reloc_only)
return ret;
}
+#if CONFIG_IS_ENABLED(OF_LIVE)
+static int dm_scan_fdt_live(struct udevice *parent,
+ const struct device_node *node_parent,
+ bool pre_reloc_only)
+{
+ struct device_node *np;
+ int ret = 0, err;
+
+ for (np = node_parent->child; np; np = np->sibling) {
+ if (pre_reloc_only &&
+ !of_find_property(np, "u-boot,dm-pre-reloc", NULL))
+ continue;
+ if (!of_device_is_available(np)) {
+ dm_dbg(" - ignoring disabled device\n");
+ continue;
+ }
+ err = lists_bind_fdt(parent, np_to_ofnode(np), NULL);
+ if (err && !ret) {
+ ret = err;
+ debug("%s: ret=%d\n", np->name, ret);
+ }
+ }
+
+ if (ret)
+ dm_warn("Some drivers failed to bind\n");
+
+ return ret;
+}
+#endif /* CONFIG_IS_ENABLED(OF_LIVE) */
+
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
-int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
- bool pre_reloc_only)
+/**
+ * dm_scan_fdt_node() - Scan the device tree and bind drivers for a node
+ *
+ * This scans the subnodes of a device tree node and and creates a driver
+ * for each one.
+ *
+ * @parent: Parent device for the devices that will be created
+ * @blob: Pointer to device tree blob
+ * @offset: Offset of node to scan
+ * @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC
+ * flag. If false bind all drivers.
+ * @return 0 if OK, -ve on error
+ */
+static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
+ int offset, bool pre_reloc_only)
{
int ret = 0, err;
@@ -222,7 +273,7 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
dm_dbg(" - ignoring disabled device\n");
continue;
}
- err = lists_bind_fdt(parent, blob, offset, NULL);
+ err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL);
if (err && !ret) {
ret = err;
debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL),
@@ -238,15 +289,27 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
int dm_scan_fdt_dev(struct udevice *dev)
{
- if (dev_of_offset(dev) == -1)
+ if (!dev_of_valid(dev))
return 0;
+#if CONFIG_IS_ENABLED(OF_LIVE)
+ if (of_live_active())
+ return dm_scan_fdt_live(dev, dev_np(dev),
+ gd->flags & GD_FLG_RELOC ? false : true);
+ else
+#endif
return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev),
gd->flags & GD_FLG_RELOC ? false : true);
}
int dm_scan_fdt(const void *blob, bool pre_reloc_only)
{
+#if CONFIG_IS_ENABLED(OF_LIVE)
+ if (of_live_active())
+ return dm_scan_fdt_live(gd->dm_root, gd->of_root,
+ pre_reloc_only);
+ else
+#endif
return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
}
#endif
@@ -260,7 +323,7 @@ int dm_init_and_scan(bool pre_reloc_only)
{
int ret;
- ret = dm_init();
+ ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));
if (ret) {
debug("dm_init() failed: %d\n", ret);
return ret;
diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
index a300217d39..14803e32b1 100644
--- a/drivers/core/simple-bus.c
+++ b/drivers/core/simple-bus.c
@@ -33,8 +33,7 @@ static int simple_bus_post_bind(struct udevice *dev)
u32 cell[3];
int ret;
- ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "ranges",
- cell, ARRAY_SIZE(cell));
+ ret = dev_read_u32_array(dev, "ranges", cell, ARRAY_SIZE(cell));
if (!ret) {
struct simple_bus_plat *plat = dev_get_uclass_platdata(dev);
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 04fb45b01a..21dc696da3 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -8,6 +8,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <dm/device.h>
@@ -287,6 +288,30 @@ int uclass_find_device_by_of_offset(enum uclass_id id, int node,
return -ENODEV;
}
+int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
+ struct udevice **devp)
+{
+ struct uclass *uc;
+ struct udevice *dev;
+ int ret;
+
+ *devp = NULL;
+ if (!ofnode_valid(node))
+ return -ENODEV;
+ ret = uclass_get(id, &uc);
+ if (ret)
+ return ret;
+
+ list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+ if (ofnode_equal(dev_ofnode(dev), node)) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
#if CONFIG_IS_ENABLED(OF_CONTROL)
static int uclass_find_device_by_phandle(enum uclass_id id,
struct udevice *parent,
@@ -299,8 +324,7 @@ static int uclass_find_device_by_phandle(enum uclass_id id,
int ret;
*devp = NULL;
- find_phandle = fdtdec_get_int(gd->fdt_blob, dev_of_offset(parent), name,
- -1);
+ find_phandle = dev_read_u32_default(parent, name, -1);
if (find_phandle <= 0)
return -ENOENT;
ret = uclass_get(id, &uc);
@@ -310,7 +334,7 @@ static int uclass_find_device_by_phandle(enum uclass_id id,
list_for_each_entry(dev, &uc->dev_head, uclass_node) {
uint phandle;
- phandle = fdt_get_phandle(gd->fdt_blob, dev_of_offset(dev));
+ phandle = dev_read_phandle(dev);
if (phandle == find_phandle) {
*devp = dev;
@@ -407,6 +431,18 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node,
return uclass_get_device_tail(dev, ret, devp);
}
+int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,
+ struct udevice **devp)
+{
+ struct udevice *dev;
+ int ret;
+
+ *devp = NULL;
+ ret = uclass_find_device_by_ofnode(id, node, &dev);
+
+ return uclass_get_device_tail(dev, ret, devp);
+}
+
#if CONFIG_IS_ENABLED(OF_CONTROL)
int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,
const char *name, struct udevice **devp)
diff --git a/drivers/cpu/bmips_cpu.c b/drivers/cpu/bmips_cpu.c
index 379acf2d55..1eb744adcd 100644
--- a/drivers/cpu/bmips_cpu.c
+++ b/drivers/cpu/bmips_cpu.c
@@ -30,6 +30,14 @@ DECLARE_GLOBAL_DATA_PTR;
#define STRAPBUS_6328_FCVO_SHIFT 7
#define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT)
+#define REG_BCM6348_PERF_MIPSPLLCFG 0x34
+#define MIPSPLLCFG_6348_M1CPU_SHIFT 6
+#define MIPSPLLCFG_6348_M1CPU_MASK (0x7 << MIPSPLLCFG_6348_M1CPU_SHIFT)
+#define MIPSPLLCFG_6348_N2_SHIFT 15
+#define MIPSPLLCFG_6348_N2_MASK (0x1F << MIPSPLLCFG_6348_N2_SHIFT)
+#define MIPSPLLCFG_6348_N1_SHIFT 20
+#define MIPSPLLCFG_6348_N1_MASK (0x7 << MIPSPLLCFG_6348_N1_SHIFT)
+
#define REG_BCM6358_DDR_DMIPSPLLCFG 0x12b8
#define DMIPSPLLCFG_6358_M1_SHIFT 0
#define DMIPSPLLCFG_6358_M1_MASK (0xff << DMIPSPLLCFG_6358_M1_SHIFT)
@@ -56,7 +64,7 @@ struct bmips_cpu_priv {
};
/* Specific CPU Ops */
-static int bcm6358_get_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
+static int bmips_short_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
int size)
{
unsigned short cpu_id;
@@ -72,7 +80,7 @@ static int bcm6358_get_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
return 0;
}
-static int bcm6328_get_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
+static int bmips_long_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
int size)
{
unsigned int cpu_id;
@@ -88,6 +96,11 @@ static int bcm6328_get_cpu_desc(struct bmips_cpu_priv *priv, char *buf,
return 0;
}
+static ulong bcm3380_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+ return 333000000;
+}
+
static ulong bcm6328_get_cpu_freq(struct bmips_cpu_priv *priv)
{
unsigned int mips_pll_fcvo;
@@ -115,6 +128,23 @@ static ulong bcm6328_get_cpu_freq(struct bmips_cpu_priv *priv)
}
}
+static ulong bcm6338_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+ return 240000000;
+}
+
+static ulong bcm6348_get_cpu_freq(struct bmips_cpu_priv *priv)
+{
+ unsigned int tmp, n1, n2, m1;
+
+ tmp = readl_be(priv->regs + REG_BCM6348_PERF_MIPSPLLCFG);
+ n1 = (tmp & MIPSPLLCFG_6348_N1_MASK) >> MIPSPLLCFG_6348_N1_SHIFT;
+ n2 = (tmp & MIPSPLLCFG_6348_N2_MASK) >> MIPSPLLCFG_6348_N2_SHIFT;
+ m1 = (tmp & MIPSPLLCFG_6348_M1CPU_MASK) >> MIPSPLLCFG_6348_M1CPU_SHIFT;
+
+ return (16 * 1000000 * (n1 + 1) * (n2 + 2)) / (m1 + 1);
+}
+
static ulong bcm6358_get_cpu_freq(struct bmips_cpu_priv *priv)
{
unsigned int tmp, n1, n2, m1;
@@ -160,25 +190,48 @@ static int bcm6328_get_cpu_count(struct bmips_cpu_priv *priv)
return 2;
}
+static int bcm6345_get_cpu_count(struct bmips_cpu_priv *priv)
+{
+ return 1;
+}
+
static int bcm6358_get_cpu_count(struct bmips_cpu_priv *priv)
{
return 2;
}
+static const struct bmips_cpu_hw bmips_cpu_bcm3380 = {
+ .get_cpu_desc = bmips_short_cpu_desc,
+ .get_cpu_freq = bcm3380_get_cpu_freq,
+ .get_cpu_count = bcm6358_get_cpu_count,
+};
+
static const struct bmips_cpu_hw bmips_cpu_bcm6328 = {
- .get_cpu_desc = bcm6328_get_cpu_desc,
+ .get_cpu_desc = bmips_long_cpu_desc,
.get_cpu_freq = bcm6328_get_cpu_freq,
.get_cpu_count = bcm6328_get_cpu_count,
};
+static const struct bmips_cpu_hw bmips_cpu_bcm6338 = {
+ .get_cpu_desc = bmips_short_cpu_desc,
+ .get_cpu_freq = bcm6338_get_cpu_freq,
+ .get_cpu_count = bcm6345_get_cpu_count,
+};
+
+static const struct bmips_cpu_hw bmips_cpu_bcm6348 = {
+ .get_cpu_desc = bmips_short_cpu_desc,
+ .get_cpu_freq = bcm6348_get_cpu_freq,
+ .get_cpu_count = bcm6345_get_cpu_count,
+};
+
static const struct bmips_cpu_hw bmips_cpu_bcm6358 = {
- .get_cpu_desc = bcm6358_get_cpu_desc,
+ .get_cpu_desc = bmips_short_cpu_desc,
.get_cpu_freq = bcm6358_get_cpu_freq,
.get_cpu_count = bcm6358_get_cpu_count,
};
static const struct bmips_cpu_hw bmips_cpu_bcm63268 = {
- .get_cpu_desc = bcm6328_get_cpu_desc,
+ .get_cpu_desc = bmips_long_cpu_desc,
.get_cpu_freq = bcm63268_get_cpu_freq,
.get_cpu_count = bcm6358_get_cpu_count,
};
@@ -247,7 +300,7 @@ int bmips_cpu_probe(struct udevice *dev)
fdt_addr_t addr;
fdt_size_t size;
- addr = dev_get_addr_size_index(dev_get_parent(dev), 0, &size);
+ addr = devfdt_get_addr_size_index(dev_get_parent(dev), 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -259,9 +312,18 @@ int bmips_cpu_probe(struct udevice *dev)
static const struct udevice_id bmips_cpu_ids[] = {
{
+ .compatible = "brcm,bcm3380-cpu",
+ .data = (ulong)&bmips_cpu_bcm3380,
+ }, {
.compatible = "brcm,bcm6328-cpu",
.data = (ulong)&bmips_cpu_bcm6328,
}, {
+ .compatible = "brcm,bcm6338-cpu",
+ .data = (ulong)&bmips_cpu_bcm6338,
+ }, {
+ .compatible = "brcm,bcm6348-cpu",
+ .data = (ulong)&bmips_cpu_bcm6348,
+ }, {
.compatible = "brcm,bcm6358-cpu",
.data = (ulong)&bmips_cpu_bcm6358,
}, {
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c
index c57ac16b3a..73e4853939 100644
--- a/drivers/cpu/cpu-uclass.c
+++ b/drivers/cpu/cpu-uclass.c
@@ -63,11 +63,11 @@ U_BOOT_DRIVER(cpu_bus) = {
static int uclass_cpu_init(struct uclass *uc)
{
struct udevice *dev;
- int node;
+ ofnode node;
int ret;
- node = fdt_path_offset(gd->fdt_blob, "/cpus");
- if (node < 0)
+ node = ofnode_path("/cpus");
+ if (!ofnode_valid(node))
return 0;
ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node,
diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c
index 5b7ced5949..aaf4dfb1e7 100644
--- a/drivers/ddr/fsl/arm_ddr_gen3.c
+++ b/drivers/ddr/fsl/arm_ddr_gen3.c
@@ -12,6 +12,7 @@
#include <asm/processor.h>
#include <fsl_immap.h>
#include <fsl_ddr.h>
+#include <asm/arch/clock.h>
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 21687dd077..c0ee858a02 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -16,6 +16,10 @@
#include <fsl_ddr.h>
#include <fsl_immap.h>
#include <asm/io.h>
+#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_ARM)
+#include <asm/arch/clock.h>
+#endif
/*
* Determine Rtt value.
diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index e0f9e2ca3d..3349fc5c3b 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -11,6 +11,10 @@
#include <fsl_immap.h>
#include <fsl_ddr.h>
#include <fsl_errata.h>
+#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_ARM)
+#include <asm/arch/clock.h>
+#endif
#if defined(CONFIG_SYS_FSL_ERRATUM_A008511) | \
defined(CONFIG_SYS_FSL_ERRATUM_A009803)
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 202ad138f9..653bbabc95 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -154,7 +154,9 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
static const struct options_string options[] = {
COMMON_TIMING(tckmin_x_ps),
COMMON_TIMING(tckmax_ps),
+#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
COMMON_TIMING(taamin_ps),
+#endif
COMMON_TIMING(trcd_ps),
COMMON_TIMING(trp_ps),
COMMON_TIMING(tras_ps),
@@ -422,7 +424,9 @@ static void print_lowest_common_dimm_parameters(
const common_timing_params_t *plcd_dimm_params)
{
static const struct options_string options[] = {
+#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
COMMON_TIMING(taamin_ps),
+#endif
COMMON_TIMING(trcd_ps),
COMMON_TIMING(trp_ps),
COMMON_TIMING(tras_ps),
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index b45a8797e4..20edd2dc28 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -9,6 +9,10 @@
#include <fsl_ddr_sdram.h>
#include <fsl_ddr.h>
+#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_ARM)
+#include <asm/arch/clock.h>
+#endif
/*
* Use our own stack based buffer before relocation to allow accessing longer
diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c
index b58784be65..0a305b36b8 100644
--- a/drivers/ddr/fsl/util.c
+++ b/drivers/ddr/fsl/util.c
@@ -13,6 +13,10 @@
#include <fsl_ddr.h>
#include <fsl_immap.h>
#include <asm/io.h>
+#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_ARM)
+#include <asm/arch/clock.h>
+#endif
/* To avoid 64-bit full-divides, we factor this here */
#define ULL_2E12 2000000000000ULL
diff --git a/drivers/ddr/marvell/axp/ddr3_dqs.c b/drivers/ddr/marvell/axp/ddr3_dqs.c
index 71a986d54f..46443364d1 100644
--- a/drivers/ddr/marvell/axp/ddr3_dqs.c
+++ b/drivers/ddr/marvell/axp/ddr3_dqs.c
@@ -1268,7 +1268,7 @@ int ddr3_set_dqs_centralization_results(MV_DRAM_INFO *dram_info, u32 cs,
max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups);
- DEBUG_DQS_RESULTS_S("\n############ LOG LEVEL 2(Windows margins) ############\n");;
+ DEBUG_DQS_RESULTS_S("\n############ LOG LEVEL 2(Windows margins) ############\n");
if (is_tx) {
DEBUG_DQS_RESULTS_C("DDR3 - DQS TX - Set Dqs Centralization Results - CS: ",
diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
index 9702eeea20..b6d5fe24dc 100644
--- a/drivers/dfu/dfu_sf.c
+++ b/drivers/dfu/dfu_sf.c
@@ -20,7 +20,8 @@ static long dfu_get_medium_size_sf(struct dfu_entity *dfu)
static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
long *len)
{
- return spi_flash_read(dfu->data.sf.dev, offset, *len, buf);
+ return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
+ *len, buf);
}
static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset)
diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c
index 247843891e..39e9793013 100644
--- a/drivers/dma/ti-edma3.c
+++ b/drivers/dma/ti-edma3.c
@@ -11,8 +11,8 @@
#include <asm/io.h>
#include <common.h>
+#include <dm.h>
#include <dma.h>
-#include <dm/device.h>
#include <asm/omap_common.h>
#include <asm/ti-common/ti-edma3.h>
@@ -505,7 +505,7 @@ static int ti_edma3_ofdata_to_platdata(struct udevice *dev)
{
struct ti_edma3_priv *priv = dev_get_priv(dev);
- priv->base = dev_get_addr(dev);
+ priv->base = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/firmware/firmware-uclass.c b/drivers/firmware/firmware-uclass.c
index 01b6a44b9d..af781b5b69 100644
--- a/drivers/firmware/firmware-uclass.c
+++ b/drivers/firmware/firmware-uclass.c
@@ -2,7 +2,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/uclass.h>
+#include <common.h>
+#include <dm.h>
/* Firmware access is platform-dependent. No generic code in uclass */
UCLASS_DRIVER(firmware) = {
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 40fba6432c..451fbdebba 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -8,7 +8,7 @@
*/
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/lists.h>
#include <libfdt.h>
#include <linux/arm-smccc.h>
@@ -40,8 +40,8 @@ static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
static int psci_bind(struct udevice *dev)
{
/* No SYSTEM_RESET support for PSCI 0.1 */
- if (of_device_is_compatible(dev, "arm,psci-0.2") ||
- of_device_is_compatible(dev, "arm,psci-1.0")) {
+ if (device_is_compatible(dev, "arm,psci-0.2") ||
+ device_is_compatible(dev, "arm,psci-1.0")) {
int ret;
/* bind psci-sysreset optionally */
@@ -59,8 +59,8 @@ static int psci_probe(struct udevice *dev)
DECLARE_GLOBAL_DATA_PTR;
const char *method;
- method = fdt_stringlist_get(gd->fdt_blob, dev->of_offset, "method", 0,
- NULL);
+ method = fdt_stringlist_get(gd->fdt_blob, dev_of_offset(dev), "method",
+ 0, NULL);
if (!method) {
printf("missing \"method\" property\n");
return -ENXIO;
diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c
index 23039c3eb2..57a4e6c88e 100644
--- a/drivers/fpga/zynqmppl.c
+++ b/drivers/fpga/zynqmppl.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <zynqmppl.h>
#include <linux/sizes.h>
+#include <asm/arch/sys_proto.h>
#define DUMMY_WORD 0xffffffff
@@ -191,25 +192,14 @@ static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf,
return 0;
}
-static int invoke_smc(ulong id, ulong reg0, ulong reg1, ulong reg2)
-{
- struct pt_regs regs;
- regs.regs[0] = id;
- regs.regs[1] = reg0;
- regs.regs[2] = reg1;
- regs.regs[3] = reg2;
-
- smc_call(&regs);
-
- return regs.regs[0];
-}
-
static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize,
bitstream_type bstype)
{
u32 swap;
- ulong bin_buf, flags;
+ ulong bin_buf;
int ret;
+ u32 buf_lo, buf_hi;
+ u32 ret_payload[PAYLOAD_ARG_CNT];
if (zynqmp_validate_bitstream(desc, buf, bsize, bsize, &swap))
return FPGA_FAIL;
@@ -224,9 +214,10 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize,
else
bsize = bsize / 4;
- flags = (u32)bsize | ((u64)bstype << 32);
-
- ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, bin_buf, flags, 0);
+ buf_lo = (u32)bin_buf;
+ buf_hi = upper_32_bits(bin_buf);
+ ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, buf_hi, bsize,
+ bstype, ret_payload);
if (ret)
debug("PL FPGA LOAD fail\n");
diff --git a/drivers/gpio/74x164_gpio.c b/drivers/gpio/74x164_gpio.c
index 53a639ae65..eb2c0b63d7 100644
--- a/drivers/gpio/74x164_gpio.c
+++ b/drivers/gpio/74x164_gpio.c
@@ -106,7 +106,7 @@ static int gen_74x164_get_function(struct udevice *dev, unsigned offset)
}
static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 03df558879..8937e99b47 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,7 +42,6 @@ obj-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o
obj-$(CONFIG_OMAP_GPIO) += omap_gpio.o
obj-$(CONFIG_DB8500_GPIO) += db8500_gpio.o
obj-$(CONFIG_BCM2835_GPIO) += bcm2835_gpio.o
-obj-$(CONFIG_S3C2440_GPIO) += s3c2440_gpio.o
obj-$(CONFIG_XILINX_GPIO) += xilinx_gpio.o
obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o
obj-$(CONFIG_TCA642X) += tca642x.o
diff --git a/drivers/gpio/altera_pio.c b/drivers/gpio/altera_pio.c
index 92849c5295..d17245ac23 100644
--- a/drivers/gpio/altera_pio.c
+++ b/drivers/gpio/altera_pio.c
@@ -89,7 +89,7 @@ static int altera_pio_ofdata_to_platdata(struct udevice *dev)
{
struct altera_pio_platdata *plat = dev_get_platdata(dev);
- plat->regs = map_physmem(dev_get_addr(dev),
+ plat->regs = map_physmem(devfdt_get_addr(dev),
sizeof(struct altera_pio_regs),
MAP_NOCACHE);
plat->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 98dbd8210e..174d5610aa 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -587,7 +587,7 @@ static int at91_gpio_probe(struct udevice *dev)
uc_priv->gpio_count = GPIO_PER_BANK;
#if CONFIG_IS_ENABLED(OF_CONTROL)
- plat->base_addr = (uint32_t)dev_get_addr_ptr(dev);
+ plat->base_addr = (uint32_t)devfdt_get_addr_ptr(dev);
#endif
port->regs = (struct at91_port *)plat->base_addr;
diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c
index 81c3047551..f3689467f0 100644
--- a/drivers/gpio/atmel_pio4.c
+++ b/drivers/gpio/atmel_pio4.c
@@ -10,7 +10,6 @@
#include <clk.h>
#include <dm.h>
#include <fdtdec.h>
-#include <dm/root.h>
#include <asm/arch/hardware.h>
#include <asm/gpio.h>
#include <mach/gpio.h>
@@ -276,7 +275,7 @@ static const struct dm_gpio_ops atmel_pio4_ops = {
static int atmel_pio4_bind(struct udevice *dev)
{
- return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev), false);
+ return dm_scan_fdt_dev(dev);
}
static int atmel_pio4_probe(struct udevice *dev)
@@ -299,7 +298,7 @@ static int atmel_pio4_probe(struct udevice *dev)
clk_free(&clk);
- addr_base = dev_get_addr(dev);
+ addr_base = devfdt_get_addr(dev);
if (addr_base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c
index cd5480ee09..beaa21853a 100644
--- a/drivers/gpio/bcm2835_gpio.c
+++ b/drivers/gpio/bcm2835_gpio.c
@@ -130,7 +130,7 @@ static int bcm2835_gpio_ofdata_to_platdata(struct udevice *dev)
struct bcm2835_gpio_platdata *plat = dev_get_platdata(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/bcm6345_gpio.c b/drivers/gpio/bcm6345_gpio.c
index 1c46020aa4..b9100cdc58 100644
--- a/drivers/gpio/bcm6345_gpio.c
+++ b/drivers/gpio/bcm6345_gpio.c
@@ -9,10 +9,10 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <dm/device.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +64,8 @@ static int bcm6345_gpio_direction_output(struct udevice *dev, unsigned offset,
{
struct bcm6345_gpio_priv *priv = dev_get_priv(dev);
+ bcm6345_gpio_set_value(dev, offset, value);
+
return bcm6345_gpio_set_direction(priv->reg_dirout, offset, 0);
}
@@ -92,11 +94,11 @@ static int bcm6345_gpio_probe(struct udevice *dev)
fdt_addr_t data_addr, dirout_addr;
fdt_size_t data_size, dirout_size;
- dirout_addr = dev_get_addr_size_index(dev, 0, &dirout_size);
+ dirout_addr = devfdt_get_addr_size_index(dev, 0, &dirout_size);
if (dirout_addr == FDT_ADDR_T_NONE)
return -EINVAL;
- data_addr = dev_get_addr_size_index(dev, 1, &data_size);
+ data_addr = devfdt_get_addr_size_index(dev, 1, &data_size);
if (data_addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index ba4804083d..f611996f17 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -114,9 +114,8 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
return 0;
}
-int gpio_xlate_offs_flags(struct udevice *dev,
- struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
+ struct ofnode_phandle_args *args)
{
if (args->args_count < 1)
return -EINVAL;
@@ -133,7 +132,7 @@ int gpio_xlate_offs_flags(struct udevice *dev,
}
static int gpio_find_and_xlate(struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
@@ -642,37 +641,30 @@ int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
return vector;
}
-static int _gpio_request_by_name_nodev(const void *blob, int node,
- const char *list_name, int index,
- struct gpio_desc *desc, int flags,
- bool add_index)
+static int gpio_request_tail(int ret, ofnode node,
+ struct ofnode_phandle_args *args,
+ const char *list_name, int index,
+ struct gpio_desc *desc, int flags, bool add_index)
{
- struct fdtdec_phandle_args args;
- int ret;
-
desc->dev = NULL;
desc->offset = 0;
desc->flags = 0;
- ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
- "#gpio-cells", 0, index, &args);
- if (ret) {
- debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
+ if (ret)
goto err;
- }
- ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
- &desc->dev);
+ ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
+ &desc->dev);
if (ret) {
debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
goto err;
}
- ret = gpio_find_and_xlate(desc, &args);
+ ret = gpio_find_and_xlate(desc, args);
if (ret) {
debug("%s: gpio_find_and_xlate failed\n", __func__);
goto err;
}
ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
- fdt_get_name(blob, node, NULL),
+ ofnode_get_name(node),
list_name, index);
if (ret) {
debug("%s: dm_gpio_requestf failed\n", __func__);
@@ -687,32 +679,45 @@ static int _gpio_request_by_name_nodev(const void *blob, int node,
return 0;
err:
debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
- __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
+ __func__, ofnode_get_name(node), list_name, index, ret);
return ret;
}
-int gpio_request_by_name_nodev(const void *blob, int node,
- const char *list_name, int index,
+static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
+ int index, struct gpio_desc *desc,
+ int flags, bool add_index)
+{
+ struct ofnode_phandle_args args;
+ int ret;
+
+ ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
+ index, &args);
+
+ return gpio_request_tail(ret, node, &args, list_name, index, desc,
+ flags, add_index);
+}
+
+int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
struct gpio_desc *desc, int flags)
{
- return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
- flags, index > 0);
+ return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
+ index > 0);
}
-int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
+int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
struct gpio_desc *desc, int flags)
{
- /*
- * This isn't ideal since we don't use dev->name in the debug()
- * calls in gpio_request_by_name(), but we can do this until
- * gpio_request_by_name_nodev() can be dropped.
- */
- return gpio_request_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
- list_name, index, desc, flags);
+ struct ofnode_phandle_args args;
+ int ret;
+
+ ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
+ index, &args);
+
+ return gpio_request_tail(ret, dev_ofnode(dev), &args, list_name,
+ index, desc, flags, index > 0);
}
-int gpio_request_list_by_name_nodev(const void *blob, int node,
- const char *list_name,
+int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
struct gpio_desc *desc, int max_count,
int flags)
{
@@ -720,7 +725,7 @@ int gpio_request_list_by_name_nodev(const void *blob, int node,
int ret;
for (count = 0; count < max_count; count++) {
- ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
+ ret = _gpio_request_by_name_nodev(node, list_name, count,
&desc[count], flags, true);
if (ret == -ENOENT)
break;
@@ -746,9 +751,8 @@ int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
* calls in gpio_request_by_name(), but we can do this until
* gpio_request_list_by_name_nodev() can be dropped.
*/
- return gpio_request_list_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
- list_name, desc, max_count,
- flags);
+ return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
+ max_count, flags);
}
int gpio_get_list_count(struct udevice *dev, const char *list_name)
diff --git a/drivers/gpio/gpio-uniphier.c b/drivers/gpio/gpio-uniphier.c
index ad1176420d..c11e95355b 100644
--- a/drivers/gpio/gpio-uniphier.c
+++ b/drivers/gpio/gpio-uniphier.c
@@ -6,7 +6,7 @@
*/
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -95,7 +95,7 @@ static int uniphier_gpio_probe(struct udevice *dev)
fdt_addr_t addr;
unsigned int tmp;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/imx_rgpio2p.c b/drivers/gpio/imx_rgpio2p.c
index 886b16188e..5abc88ba54 100644
--- a/drivers/gpio/imx_rgpio2p.c
+++ b/drivers/gpio/imx_rgpio2p.c
@@ -166,7 +166,7 @@ static int imx_rgpio2p_bind(struct udevice *dev)
if (plat)
return 0;
- addr = dev_get_addr_index(dev, 1);
+ addr = devfdt_get_addr_index(dev, 1);
if (addr == FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 0a9eb03fd0..ffc3ccb276 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -129,7 +129,7 @@ static int ich6_gpio_probe(struct udevice *dev)
bank->io_sel = plat->base_addr + 4;
bank->lvl = plat->base_addr + 8;
- prop = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ prop = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
"use-lvl-write-cache", NULL);
if (prop)
bank->use_lvl_write_cache = true;
diff --git a/drivers/gpio/lpc32xx_gpio.c b/drivers/gpio/lpc32xx_gpio.c
index 1bf945acfc..292fc74fc3 100644
--- a/drivers/gpio/lpc32xx_gpio.c
+++ b/drivers/gpio/lpc32xx_gpio.c
@@ -7,6 +7,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <common.h>
#include <asm/io.h>
#include <asm/arch-lpc32xx/cpu.h>
#include <asm/arch-lpc32xx/gpio.h>
diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c
index 01ce1d6fa0..ff38fc5bd3 100644
--- a/drivers/gpio/msm_gpio.c
+++ b/drivers/gpio/msm_gpio.c
@@ -97,7 +97,7 @@ static int msm_gpio_probe(struct udevice *dev)
{
struct msm_gpio_bank *priv = dev_get_priv(dev);
- priv->base = dev_get_addr(dev);
+ priv->base = devfdt_get_addr(dev);
return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
}
diff --git a/drivers/gpio/mvebu_gpio.c b/drivers/gpio/mvebu_gpio.c
index 75dc73e586..85dea14c51 100644
--- a/drivers/gpio/mvebu_gpio.c
+++ b/drivers/gpio/mvebu_gpio.c
@@ -92,7 +92,7 @@ static int mvebu_gpio_probe(struct udevice *dev)
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct mvebu_gpio_priv *priv = dev_get_priv(dev);
- priv->regs = (struct mvebu_gpio_regs *)dev_get_addr(dev);
+ priv->regs = (struct mvebu_gpio_regs *)devfdt_get_addr(dev);
uc_priv->gpio_count = MVEBU_GPIOS_PER_BANK;
priv->name[0] = 'A' + dev->req_seq;
uc_priv->bank_name = priv->name;
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 70fe5b6a4e..0eb6c600f1 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -302,7 +302,7 @@ static int mxc_gpio_bind(struct udevice *dev)
if (plat)
return 0;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 5338552179..b423e34ca4 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -305,7 +305,7 @@ static int omap_gpio_bind(struct udevice *dev)
if (plat)
return 0;
- base_addr = dev_get_addr(dev);
+ base_addr = devfdt_get_addr(dev);
if (base_addr == FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c
index b81f0fa90c..4962f25230 100644
--- a/drivers/gpio/pca953x_gpio.c
+++ b/drivers/gpio/pca953x_gpio.c
@@ -228,7 +228,7 @@ static int pca953x_get_function(struct udevice *dev, unsigned offset)
}
static int pca953x_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
desc->offset = args->args[0];
desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/pm8916_gpio.c
index e38cee8869..9ec2a24b3e 100644
--- a/drivers/gpio/pm8916_gpio.c
+++ b/drivers/gpio/pm8916_gpio.c
@@ -173,7 +173,7 @@ static int pm8916_gpio_probe(struct udevice *dev)
struct pm8916_gpio_bank *priv = dev_get_priv(dev);
int reg;
- priv->pid = dev_get_addr(dev);
+ priv->pid = dev_read_addr(dev);
if (priv->pid == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -193,10 +193,8 @@ static int pm8916_gpio_ofdata_to_platdata(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
- uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "gpio-count", 0);
- uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
- "gpio-bank-name", NULL);
+ uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0);
+ uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
if (uc_priv->bank_name == NULL)
uc_priv->bank_name = "pm8916";
@@ -259,7 +257,7 @@ static int pm8941_pwrkey_probe(struct udevice *dev)
struct pm8916_gpio_bank *priv = dev_get_priv(dev);
int reg;
- priv->pid = dev_get_addr(dev);
+ priv->pid = devfdt_get_addr(dev);
if (priv->pid == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 5dbd228203..6f7366acba 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -104,7 +104,7 @@ static int rockchip_gpio_probe(struct udevice *dev)
int ret;
/* This only supports RK3288 at present */
- priv->regs = (struct rockchip_gpio_regs *)dev_get_addr(dev);
+ priv->regs = (struct rockchip_gpio_regs *)devfdt_get_addr(dev);
ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
if (ret)
return ret;
diff --git a/drivers/gpio/s3c2440_gpio.c b/drivers/gpio/s3c2440_gpio.c
deleted file mode 100644
index d6c7eeb693..0000000000
--- a/drivers/gpio/s3c2440_gpio.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2012
- * Gabriel Huau <contact@huau-gabriel.fr>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-#include <common.h>
-#include <asm/arch/s3c2440.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
-#include <errno.h>
-
-#define GPIO_INPUT 0x0
-#define GPIO_OUTPUT 0x1
-
-#define S3C_GPIO_CON 0x0
-#define S3C_GPIO_DAT 0x4
-
-static uint32_t s3c_gpio_get_bank_addr(unsigned gpio)
-{
- /* There is up to 16 pins per bank, one bank is 0x10 big. */
- uint32_t addr = gpio & ~0xf;
-
- if (addr >= 0x80 && addr != 0xd0) { /* Wrong GPIO bank. */
- printf("Invalid GPIO bank (bank %02x)\n", addr);
- return 0xffffffff;
- }
-
- return addr | S3C24X0_GPIO_BASE;
-}
-
-int gpio_set_value(unsigned gpio, int value)
-{
- uint32_t addr = s3c_gpio_get_bank_addr(gpio);
-
- if (addr == 0xffffffff)
- return -EINVAL;
-
- if (value)
- setbits_le32(addr | S3C_GPIO_DAT, 1 << (gpio & 0xf));
- else
- clrbits_le32(addr | S3C_GPIO_DAT, 1 << (gpio & 0xf));
-
- return 0;
-}
-
-int gpio_get_value(unsigned gpio)
-{
- uint32_t addr = s3c_gpio_get_bank_addr(gpio);
-
- if (addr == 0xffffffff)
- return -EINVAL;
-
- return !!(readl(addr | S3C_GPIO_DAT) & (1 << (gpio & 0xf)));
-}
-
-int gpio_request(unsigned gpio, const char *label)
-{
- return 0;
-}
-
-int gpio_free(unsigned gpio)
-{
- return 0;
-}
-
-static int s3c_gpio_direction(unsigned gpio, uint8_t dir)
-{
- uint32_t addr = s3c_gpio_get_bank_addr(gpio);
- const uint32_t mask = 0x3 << ((gpio & 0xf) << 1);
- const uint32_t dirm = dir << ((gpio & 0xf) << 1);
-
- if (addr == 0xffffffff)
- return -EINVAL;
-
- clrsetbits_le32(addr | S3C_GPIO_CON, mask, dirm);
- return 0;
-}
-
-int gpio_direction_input(unsigned gpio)
-{
- return s3c_gpio_direction(gpio, GPIO_INPUT);
-}
-
-int gpio_direction_output(unsigned gpio, int value)
-{
- return s3c_gpio_direction(gpio, GPIO_OUTPUT);
-}
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 042996e559..5c894a26d7 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -316,7 +316,7 @@ static int gpio_exynos_bind(struct udevice *parent)
if (plat)
return 0;
- base = (struct s5p_gpio_bank *)dev_get_addr(parent);
+ base = (struct s5p_gpio_bank *)devfdt_get_addr(parent);
for (node = fdt_first_subnode(blob, dev_of_offset(parent)), bank = base;
node > 0;
node = fdt_next_subnode(blob, node), bank++) {
@@ -339,7 +339,7 @@ static int gpio_exynos_bind(struct udevice *parent)
dev_set_of_offset(dev, node);
- reg = dev_get_addr(dev);
+ reg = devfdt_get_addr(dev);
if (reg != FDT_ADDR_T_NONE)
bank = (struct s5p_gpio_bank *)((ulong)base + reg);
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index ae6d93013f..4f7b62eba0 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -8,6 +8,7 @@
#include <fdtdec.h>
#include <malloc.h>
#include <asm/gpio.h>
+#include <dm/of.h>
#include <dt-bindings/gpio/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -165,7 +166,7 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
}
static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
desc->offset = args->args[0];
if (args->args_count < 2)
@@ -197,10 +198,8 @@ static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
- uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "num-gpios", 0);
- uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
- "gpio-bank-name", NULL);
+ uc_priv->gpio_count = dev_read_u32_default(dev, "num-gpios", 0);
+ uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
return 0;
}
@@ -209,10 +208,9 @@ static int gpio_sandbox_probe(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
- if (dev_of_offset(dev) == -1) {
+ if (!dev_of_valid(dev))
/* Tell the uclass how many GPIOs we have */
uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
- }
dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count);
diff --git a/drivers/gpio/stm32f7_gpio.c b/drivers/gpio/stm32f7_gpio.c
index 5e0546357f..653e9bef4b 100644
--- a/drivers/gpio/stm32f7_gpio.c
+++ b/drivers/gpio/stm32f7_gpio.c
@@ -84,7 +84,7 @@ static int gpio_stm32_probe(struct udevice *dev)
fdt_addr_t addr;
char *name;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 3f40e83830..b47cc66c58 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -217,7 +217,7 @@ static int sunxi_gpio_get_function(struct udevice *dev, unsigned offset)
}
static int sunxi_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
int ret;
@@ -296,7 +296,7 @@ static int gpio_sunxi_bind(struct udevice *parent)
if (plat)
return 0;
- ctlr = (struct sunxi_gpio_reg *)dev_get_addr(parent);
+ ctlr = (struct sunxi_gpio_reg *)devfdt_get_addr(parent);
for (bank = 0; bank < soc_data->no_banks; bank++) {
struct sunxi_gpio_platdata *plat;
struct udevice *dev;
diff --git a/drivers/gpio/tegra186_gpio.c b/drivers/gpio/tegra186_gpio.c
index b0c22e5bfe..c5a7e13cce 100644
--- a/drivers/gpio/tegra186_gpio.c
+++ b/drivers/gpio/tegra186_gpio.c
@@ -139,7 +139,7 @@ static int tegra186_gpio_get_function(struct udevice *dev, unsigned offset)
}
static int tegra186_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
int gpio, port, ret;
@@ -179,7 +179,7 @@ static int tegra186_gpio_bind(struct udevice *parent)
if (parent_plat)
return 0;
- regs = (uint32_t *)dev_get_addr_name(parent, "gpio");
+ regs = (uint32_t *)devfdt_get_addr_name(parent, "gpio");
if (regs == (uint32_t *)FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index b01968a304..687cd74fee 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -236,7 +236,7 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
}
static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
int gpio, port, ret;
@@ -341,7 +341,7 @@ static int gpio_tegra_bind(struct udevice *parent)
&len))
return -EINVAL;
bank_count = len / 3 / sizeof(u32);
- ctlr = (struct gpio_ctlr *)dev_get_addr(parent);
+ ctlr = (struct gpio_ctlr *)devfdt_get_addr(parent);
}
#endif
for (bank = 0; bank < bank_count; bank++) {
diff --git a/drivers/gpio/vybrid_gpio.c b/drivers/gpio/vybrid_gpio.c
index 458104e8b0..b7a1b6a45b 100644
--- a/drivers/gpio/vybrid_gpio.c
+++ b/drivers/gpio/vybrid_gpio.c
@@ -113,7 +113,7 @@ static int vybrid_gpio_bind(struct udevice *dev)
if (plat)
return 0;
- base_addr = dev_get_addr(dev);
+ base_addr = devfdt_get_addr(dev);
if (base_addr == FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c
index 64579a1b6c..4cb75a8627 100644
--- a/drivers/gpio/zynq_gpio.c
+++ b/drivers/gpio/zynq_gpio.c
@@ -375,7 +375,7 @@ static int zynq_gpio_ofdata_to_platdata(struct udevice *dev)
{
struct zynq_gpio_privdata *priv = dev_get_priv(dev);
- priv->base = dev_get_addr(dev);
+ priv->base = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index c58bc1e1cf..8ac1cc6a15 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -134,7 +134,6 @@ config SYS_I2C_INTEL
config SYS_I2C_IMX_LPI2C
bool "NXP i.MX LPI2C driver"
- depends on ARCH_MX7ULP
help
Add support for the NXP i.MX LPI2C driver.
diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c
index 16dfb57066..7ed0c10f72 100644
--- a/drivers/i2c/ast_i2c.c
+++ b/drivers/i2c/ast_i2c.c
@@ -92,7 +92,7 @@ static int ast_i2c_ofdata_to_platdata(struct udevice *dev)
struct ast_i2c_priv *priv = dev_get_priv(dev);
int ret;
- priv->regs = dev_get_addr_ptr(dev);
+ priv->regs = devfdt_get_addr_ptr(dev);
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c
index 5a636697a5..b7298cf774 100644
--- a/drivers/i2c/at91_i2c.c
+++ b/drivers/i2c/at91_i2c.c
@@ -244,7 +244,7 @@ static int at91_i2c_ofdata_to_platdata(struct udevice *dev)
struct at91_i2c_bus *bus = dev_get_priv(dev);
int node = dev_of_offset(dev);
- bus->regs = (struct at91_i2c_regs *)dev_get_addr(dev);
+ bus->regs = (struct at91_i2c_regs *)devfdt_get_addr(dev);
bus->pdata = (struct at91_i2c_pdata *)dev_get_driver_data(dev);
bus->clock_frequency = fdtdec_get_int(blob, node,
"clock-frequency", 100000);
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index 4471193402..2df07bbe8c 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -470,7 +470,7 @@ static int davinci_i2c_probe(struct udevice *dev)
struct i2c_bus *i2c_bus = dev_get_priv(dev);
i2c_bus->id = dev->seq;
- i2c_bus->regs = (struct i2c_regs *)dev_get_addr(dev);
+ i2c_bus->regs = (struct i2c_regs *)devfdt_get_addr(dev);
i2c_bus->speed = 100000;
_davinci_i2c_init(i2c_bus->regs, i2c_bus->speed, 0);
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index c68ff6420b..d4df35a69a 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -545,7 +545,7 @@ static int designware_i2c_probe(struct udevice *bus)
#endif
#endif
} else {
- priv->regs = (struct i2c_regs *)dev_get_addr_ptr(bus);
+ priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
}
__dw_i2c_init(priv->regs, 0, 0);
diff --git a/drivers/i2c/exynos_hs_i2c.c b/drivers/i2c/exynos_hs_i2c.c
index 2dd75fd154..9f4ac2fc9a 100644
--- a/drivers/i2c/exynos_hs_i2c.c
+++ b/drivers/i2c/exynos_hs_i2c.c
@@ -524,7 +524,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
node = dev_of_offset(dev);
- i2c_bus->hsregs = (struct exynos5_hsi2c *)dev_get_addr(dev);
+ i2c_bus->hsregs = (struct exynos5_hsi2c *)devfdt_get_addr(dev);
i2c_bus->id = pinmux_decode_periph_id(blob, node);
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
index dec18200ce..8265ce3210 100644
--- a/drivers/i2c/i2c-cdns.c
+++ b/drivers/i2c/i2c-cdns.c
@@ -9,10 +9,10 @@
*/
#include <common.h>
+#include <dm.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/errno.h>
-#include <dm/device.h>
#include <dm/root.h>
#include <i2c.h>
#include <fdtdec.h>
@@ -419,7 +419,7 @@ static int cdns_i2c_ofdata_to_platdata(struct udevice *dev)
struct cdns_i2c_platform_data *pdata =
(struct cdns_i2c_platform_data *)dev_get_driver_data(dev);
- i2c_bus->regs = (struct cdns_i2c_regs *)dev_get_addr(dev);
+ i2c_bus->regs = (struct cdns_i2c_regs *)devfdt_get_addr(dev);
if (!i2c_bus->regs)
return -ENOMEM;
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index f3184c71d9..1397f34dda 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -7,7 +7,6 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
#include <i2c.h>
#include <malloc.h>
#include <dm/device-internal.h>
@@ -467,18 +466,20 @@ int i2c_deblock(struct udevice *bus)
}
#if CONFIG_IS_ENABLED(OF_CONTROL)
-int i2c_chip_ofdata_to_platdata(const void *blob, int node,
- struct dm_i2c_chip *chip)
+int i2c_chip_ofdata_to_platdata(struct udevice *dev, struct dm_i2c_chip *chip)
{
- chip->offset_len = fdtdec_get_int(gd->fdt_blob, node,
- "u-boot,i2c-offset-len", 1);
+ int addr;
+
+ chip->offset_len = dev_read_u32_default(dev, "u-boot,i2c-offset-len",
+ 1);
chip->flags = 0;
- chip->chip_addr = fdtdec_get_int(gd->fdt_blob, node, "reg", -1);
- if (chip->chip_addr == -1) {
- debug("%s: I2C Node '%s' has no 'reg' property\n", __func__,
- fdt_get_name(blob, node, NULL));
+ addr = dev_read_u32_default(dev, "reg", -1);
+ if (addr == -1) {
+ debug("%s: I2C Node '%s' has no 'reg' property %s\n", __func__,
+ dev_read_name(dev), dev->name);
return -EINVAL;
}
+ chip->chip_addr = addr;
return 0;
}
@@ -489,8 +490,7 @@ static int i2c_post_probe(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL)
struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
- i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "clock-frequency", 100000);
+ i2c->speed_hz = dev_read_u32_default(dev, "clock-frequency", 100000);
return dm_i2c_set_bus_speed(dev, i2c->speed_hz);
#else
@@ -503,11 +503,9 @@ static int i2c_child_post_bind(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL)
struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);
- if (dev_of_offset(dev) == -1)
+ if (!dev_of_valid(dev))
return 0;
-
- return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev_of_offset(dev),
- plat);
+ return i2c_chip_ofdata_to_platdata(dev, plat);
#else
return 0;
#endif
diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c
index 9f0df599a0..e51537b80e 100644
--- a/drivers/i2c/i2c-uniphier-f.c
+++ b/drivers/i2c/i2c-uniphier-f.c
@@ -7,12 +7,12 @@
*/
#include <common.h>
+#include <dm.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/sizes.h>
#include <linux/errno.h>
-#include <dm/device.h>
#include <i2c.h>
#include <fdtdec.h>
@@ -104,7 +104,7 @@ static int uniphier_fi2c_probe(struct udevice *dev)
struct uniphier_fi2c_dev *priv = dev_get_priv(dev);
int ret;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c
index 73575e9895..3412e2a189 100644
--- a/drivers/i2c/i2c-uniphier.c
+++ b/drivers/i2c/i2c-uniphier.c
@@ -7,11 +7,11 @@
*/
#include <common.h>
+#include <dm.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/sizes.h>
#include <linux/errno.h>
-#include <dm/device.h>
#include <i2c.h>
#include <fdtdec.h>
@@ -49,7 +49,7 @@ static int uniphier_i2c_probe(struct udevice *dev)
fdt_addr_t addr;
struct uniphier_i2c_dev *priv = dev_get_priv(dev);
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c
index 19769dab67..911563be0b 100644
--- a/drivers/i2c/i2c_core.c
+++ b/drivers/i2c/i2c_core.c
@@ -323,11 +323,6 @@ uint8_t i2c_reg_read(uint8_t addr, uint8_t reg)
{
uint8_t buf;
-#ifdef CONFIG_8xx
- /* MPC8xx needs this. Maybe one day we can get rid of it. */
- /* maybe it is now the time for it ... */
- i2c_set_bus_num(i2c_get_bus_num());
-#endif
i2c_read(addr, reg, 1, &buf, 1);
#ifdef DEBUG
@@ -340,12 +335,6 @@ uint8_t i2c_reg_read(uint8_t addr, uint8_t reg)
void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val)
{
-#ifdef CONFIG_8xx
- /* MPC8xx needs this. Maybe one day we can get rid of it. */
- /* maybe it is now the time for it ... */
- i2c_set_bus_num(i2c_get_bus_num());
-#endif
-
#ifdef DEBUG
printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
__func__, i2c_get_bus_num(), addr, reg, val);
diff --git a/drivers/i2c/imx_lpi2c.c b/drivers/i2c/imx_lpi2c.c
index f792d4432d..aa97196e23 100644
--- a/drivers/i2c/imx_lpi2c.c
+++ b/drivers/i2c/imx_lpi2c.c
@@ -25,9 +25,8 @@ int __weak init_i2c_power(unsigned i2c_num)
return 0;
}
-static int imx_lpci2c_check_busy_bus(struct udevice *bus)
+static int imx_lpci2c_check_busy_bus(const struct imx_lpi2c_reg *regs)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
lpi2c_status_t result = LPI2C_SUCESS;
u32 status;
@@ -39,9 +38,8 @@ static int imx_lpci2c_check_busy_bus(struct udevice *bus)
return result;
}
-static int imx_lpci2c_check_clear_error(struct udevice *bus)
+static int imx_lpci2c_check_clear_error(struct imx_lpi2c_reg *regs)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
lpi2c_status_t result = LPI2C_SUCESS;
u32 val, status;
@@ -71,9 +69,8 @@ static int imx_lpci2c_check_clear_error(struct udevice *bus)
return result;
}
-static int bus_i2c_wait_for_tx_ready(struct udevice *bus)
+static int bus_i2c_wait_for_tx_ready(struct imx_lpi2c_reg *regs)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
lpi2c_status_t result = LPI2C_SUCESS;
u32 txcount = 0;
ulong start_time = get_timer(0);
@@ -81,7 +78,7 @@ static int bus_i2c_wait_for_tx_ready(struct udevice *bus)
do {
txcount = LPI2C_MFSR_TXCOUNT(readl(&regs->mfsr));
txcount = LPI2C_FIFO_SIZE - txcount;
- result = imx_lpci2c_check_clear_error(bus);
+ result = imx_lpci2c_check_clear_error(regs);
if (result) {
debug("i2c: wait for tx ready: result 0x%x\n", result);
return result;
@@ -95,9 +92,8 @@ static int bus_i2c_wait_for_tx_ready(struct udevice *bus)
return result;
}
-static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
+static int bus_i2c_send(struct imx_lpi2c_reg *regs, u8 *txbuf, int len)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
lpi2c_status_t result = LPI2C_SUCESS;
/* empty tx */
@@ -105,7 +101,7 @@ static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
return result;
while (len--) {
- result = bus_i2c_wait_for_tx_ready(bus);
+ result = bus_i2c_wait_for_tx_ready(regs);
if (result) {
debug("i2c: send wait fot tx ready: %d\n", result);
return result;
@@ -116,9 +112,8 @@ static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
return result;
}
-static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
+static int bus_i2c_receive(struct imx_lpi2c_reg *regs, u8 *rxbuf, int len)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
lpi2c_status_t result = LPI2C_SUCESS;
u32 val;
ulong start_time = get_timer(0);
@@ -127,7 +122,7 @@ static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
if (!len)
return result;
- result = bus_i2c_wait_for_tx_ready(bus);
+ result = bus_i2c_wait_for_tx_ready(regs);
if (result) {
debug("i2c: receive wait fot tx ready: %d\n", result);
return result;
@@ -141,9 +136,10 @@ static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
while (len--) {
do {
- result = imx_lpci2c_check_clear_error(bus);
+ result = imx_lpci2c_check_clear_error(regs);
if (result) {
- debug("i2c: receive check clear error: %d\n", result);
+ debug("i2c: receive check clear error: %d\n",
+ result);
return result;
}
if (get_timer(start_time) > LPI2C_TIMEOUT_MS) {
@@ -158,13 +154,12 @@ static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
return result;
}
-static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir)
+static int bus_i2c_start(struct imx_lpi2c_reg *regs, u8 addr, u8 dir)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
lpi2c_status_t result = LPI2C_SUCESS;
u32 val;
- result = imx_lpci2c_check_busy_bus(bus);
+ result = imx_lpci2c_check_busy_bus(regs);
if (result) {
debug("i2c: start check busy bus: 0x%x\n", result);
return result;
@@ -175,7 +170,7 @@ static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir)
val = readl(&regs->mcfgr1) & ~LPI2C_MCFGR1_AUTOSTOP_MASK;
writel(val, &regs->mcfgr1);
/* wait tx fifo ready */
- result = bus_i2c_wait_for_tx_ready(bus);
+ result = bus_i2c_wait_for_tx_ready(regs);
if (result) {
debug("i2c: start wait for tx ready: 0x%x\n", result);
return result;
@@ -186,13 +181,13 @@ static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir)
return result;
}
-static int bus_i2c_stop(struct udevice *bus)
+
+static int bus_i2c_stop(struct imx_lpi2c_reg *regs)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
lpi2c_status_t result = LPI2C_SUCESS;
u32 status;
- result = bus_i2c_wait_for_tx_ready(bus);
+ result = bus_i2c_wait_for_tx_ready(regs);
if (result) {
debug("i2c: stop wait for tx ready: 0x%x\n", result);
return result;
@@ -203,7 +198,7 @@ static int bus_i2c_stop(struct udevice *bus)
while (result == LPI2C_SUCESS) {
status = readl(&regs->msr);
- result = imx_lpci2c_check_clear_error(bus);
+ result = imx_lpci2c_check_clear_error(regs);
/* stop detect flag */
if (status & LPI2C_MSR_SDF_MASK) {
/* clear stop flag */
@@ -216,34 +211,34 @@ static int bus_i2c_stop(struct udevice *bus)
return result;
}
-static int bus_i2c_read(struct udevice *bus, u32 chip, u8 *buf, int len)
+static int bus_i2c_read(struct imx_lpi2c_reg *regs, u32 chip, u8 *buf, int len)
{
lpi2c_status_t result = LPI2C_SUCESS;
- result = bus_i2c_start(bus, chip, 1);
+ result = bus_i2c_start(regs, chip, 1);
if (result)
return result;
- result = bus_i2c_receive(bus, buf, len);
+ result = bus_i2c_receive(regs, buf, len);
if (result)
return result;
- result = bus_i2c_stop(bus);
+ result = bus_i2c_stop(regs);
if (result)
return result;
return result;
}
-static int bus_i2c_write(struct udevice *bus, u32 chip, u8 *buf, int len)
+static int bus_i2c_write(struct imx_lpi2c_reg *regs, u32 chip, u8 *buf, int len)
{
lpi2c_status_t result = LPI2C_SUCESS;
- result = bus_i2c_start(bus, chip, 0);
+ result = bus_i2c_start(regs, chip, 0);
if (result)
return result;
- result = bus_i2c_send(bus, buf, len);
+ result = bus_i2c_send(regs, buf, len);
if (result)
return result;
- result = bus_i2c_stop(bus);
+ result = bus_i2c_stop(regs);
if (result)
return result;
@@ -253,7 +248,7 @@ static int bus_i2c_write(struct udevice *bus, u32 chip, u8 *buf, int len)
static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
+ struct imx_lpi2c_reg *regs;
u32 val;
u32 preescale = 0, best_pre = 0, clkhi = 0;
u32 best_clkhi = 0, abs_error = 0, rate;
@@ -262,6 +257,7 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
bool mode;
int i;
+ regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
clock_rate = imx_get_i2cclk(bus->seq + 4);
if (!clock_rate)
return -EPERM;
@@ -320,10 +316,11 @@ static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
static int bus_i2c_init(struct udevice *bus, int speed)
{
- struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)dev_get_addr(bus);
+ struct imx_lpi2c_reg *regs;
u32 val;
int ret;
+ regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
/* reset peripheral */
writel(LPI2C_MCR_RST_MASK, &regs->mcr);
writel(0x0, &regs->mcr);
@@ -356,16 +353,18 @@ static int bus_i2c_init(struct udevice *bus, int speed)
static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
u32 chip_flags)
{
+ struct imx_lpi2c_reg *regs;
lpi2c_status_t result = LPI2C_SUCESS;
- result = bus_i2c_start(bus, chip, 0);
+ regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
+ result = bus_i2c_start(regs, chip, 0);
if (result) {
- bus_i2c_stop(bus);
+ bus_i2c_stop(regs);
bus_i2c_init(bus, 100000);
return result;
}
- result = bus_i2c_stop(bus);
+ result = bus_i2c_stop(regs);
if (result) {
bus_i2c_init(bus, 100000);
return -result;
@@ -376,15 +375,16 @@ static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
static int imx_lpi2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
{
+ struct imx_lpi2c_reg *regs;
int ret = 0;
+ regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
for (; nmsgs > 0; nmsgs--, msg++) {
debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
if (msg->flags & I2C_M_RD)
- ret = bus_i2c_read(bus, msg->addr, msg->buf,
- msg->len);
+ ret = bus_i2c_read(regs, msg->addr, msg->buf, msg->len);
else {
- ret = bus_i2c_write(bus, msg->addr, msg->buf,
+ ret = bus_i2c_write(regs, msg->addr, msg->buf,
msg->len);
if (ret)
break;
@@ -410,7 +410,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
i2c_bus->driver_data = dev_get_driver_data(bus);
- addr = dev_get_addr(bus);
+ addr = devfdt_get_addr(bus);
if (addr == FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c
index d243b8e32d..187e8a7c91 100644
--- a/drivers/i2c/muxes/i2c-mux-uclass.c
+++ b/drivers/i2c/muxes/i2c-mux-uclass.c
@@ -51,24 +51,21 @@ static int i2c_mux_child_post_bind(struct udevice *dev)
/* Find the I2C buses selected by this mux */
static int i2c_mux_post_bind(struct udevice *mux)
{
- const void *blob = gd->fdt_blob;
+ ofnode node;
int ret;
- int offset;
debug("%s: %s\n", __func__, mux->name);
/*
* There is no compatible string in the sub-nodes, so we must manually
* bind these
*/
- for (offset = fdt_first_subnode(blob, dev_of_offset(mux));
- offset > 0;
- offset = fdt_next_subnode(blob, offset)) {
+ dev_for_each_subnode(node, mux) {
struct udevice *dev;
const char *name;
- name = fdt_get_name(blob, offset, NULL);
+ name = ofnode_get_name(node);
ret = device_bind_driver_to_node(mux, "i2c_mux_bus_drv", name,
- offset, &dev);
+ node, &dev);
debug(" - bind ret=%d, %s\n", ret, dev ? dev->name : NULL);
if (ret)
return ret;
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index c78027239f..913721b987 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -579,7 +579,7 @@ static int mv_i2c_probe(struct udevice *bus)
{
struct mv_i2c_priv *priv = dev_get_priv(bus);
- priv->base = (void *)dev_get_addr_ptr(bus);
+ priv->base = (void *)devfdt_get_addr_ptr(bus);
return 0;
}
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 3703519aa5..dfbc4e053f 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -778,7 +778,7 @@ static int mvtwsi_i2c_ofdata_to_platdata(struct udevice *bus)
{
struct mvtwsi_i2c_dev *dev = dev_get_priv(bus);
- dev->base = dev_get_addr_ptr(bus);
+ dev->base = devfdt_get_addr_ptr(bus);
if (!dev->base)
return -ENOMEM;
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index b68e82770b..110b9d6119 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -752,7 +752,7 @@ static int mxc_i2c_probe(struct udevice *bus)
i2c_bus->driver_data = dev_get_driver_data(bus);
- addr = dev_get_addr(bus);
+ addr = devfdt_get_addr(bus);
if (addr == FDT_ADDR_T_NONE)
return -ENODEV;
@@ -773,12 +773,12 @@ static int mxc_i2c_probe(struct udevice *bus)
if (ret < 0) {
debug("i2c bus %d at 0x%2lx, no gpio pinctrl state.\n", bus->seq, i2c_bus->base);
} else {
- ret = gpio_request_by_name_nodev(fdt, node, "scl-gpios",
- 0, &i2c_bus->scl_gpio,
- GPIOD_IS_OUT);
- ret2 = gpio_request_by_name_nodev(fdt, node, "sda-gpios",
- 0, &i2c_bus->sda_gpio,
- GPIOD_IS_OUT);
+ ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
+ "scl-gpios", 0, &i2c_bus->scl_gpio,
+ GPIOD_IS_OUT);
+ ret2 = gpio_request_by_name_nodev(offset_to_ofnode(node),
+ "sda-gpios", 0, &i2c_bus->sda_gpio,
+ GPIOD_IS_OUT);
if (!dm_gpio_is_valid(&i2c_bus->sda_gpio) |
!dm_gpio_is_valid(&i2c_bus->scl_gpio) |
ret | ret2) {
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 4b8397a890..f71e0a5a26 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -896,7 +896,7 @@ static int omap_i2c_ofdata_to_platdata(struct udevice *bus)
{
struct omap_i2c *priv = dev_get_priv(bus);
- priv->regs = map_physmem(dev_get_addr(bus), sizeof(void *),
+ priv->regs = map_physmem(devfdt_get_addr(bus), sizeof(void *),
MAP_NOCACHE);
priv->speed = CONFIG_SYS_OMAP24_I2C_SPEED;
diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
index 76f41f7e85..8bc045a1a0 100644
--- a/drivers/i2c/rk_i2c.c
+++ b/drivers/i2c/rk_i2c.c
@@ -369,7 +369,7 @@ static int rockchip_i2c_probe(struct udevice *bus)
{
struct rk_i2c *priv = dev_get_priv(bus);
- priv->regs = (void *)dev_get_addr(bus);
+ priv->regs = (void *)devfdt_get_addr(bus);
return 0;
}
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index 3c69dbf409..996a6510a3 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -5,10 +5,6 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-/* This code should work for both the S3C2400 and the S3C2410
- * as they seem to have the same I2C controller inside.
- * The different address mapping is handled by the s3c24xx.h files below.
- */
#include <common.h>
#include <errno.h>
#include <dm.h>
@@ -314,7 +310,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
node = dev_of_offset(dev);
- i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev);
+ i2c_bus->regs = (struct s3c24x0_i2c *)devfdt_get_addr(dev);
i2c_bus->id = pinmux_decode_periph_id(blob, node);
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index 4696a1ae62..f5978fda29 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -9,7 +9,6 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
#include <i2c.h>
#include <asm/test.h>
#include <dm/lists.h>
diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c
index c102a1ab10..de3758d946 100644
--- a/drivers/i2c/soft_i2c.c
+++ b/drivers/i2c/soft_i2c.c
@@ -17,10 +17,6 @@
*/
#include <common.h>
-#ifdef CONFIG_MPC8260 /* only valid for MPC8260 */
-#include <ioports.h>
-#include <asm/io.h>
-#endif
#if defined(CONFIG_AVR32)
#include <asm/arch/portmux.h>
#endif
@@ -94,15 +90,7 @@
DECLARE_GLOBAL_DATA_PTR;
#ifndef I2C_SOFT_DECLARATIONS
-# if defined(CONFIG_MPC8260)
-# define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = \
- ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT);
-# elif defined(CONFIG_8xx)
-# define I2C_SOFT_DECLARATIONS volatile immap_t *immr = \
- (immap_t *)CONFIG_SYS_IMMR;
-# else
# define I2C_SOFT_DECLARATIONS
-# endif
#endif
#if !defined(CONFIG_SYS_I2C_SOFT_SPEED)
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 898f12a946..055f48153a 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -365,7 +365,7 @@ static int tegra_i2c_probe(struct udevice *dev)
i2c_bus->id = dev->seq;
i2c_bus->type = dev_get_driver_data(dev);
- i2c_bus->regs = (struct i2c_ctlr *)dev_get_addr(dev);
+ i2c_bus->regs = (struct i2c_ctlr *)devfdt_get_addr(dev);
ret = reset_get_by_name(dev, "i2c", &i2c_bus->reset_ctl);
if (ret) {
diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c
index 00381dcd72..6fa35a63dd 100644
--- a/drivers/input/cros_ec_keyb.c
+++ b/drivers/input/cros_ec_keyb.c
@@ -10,7 +10,6 @@
#include <cros_ec.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
#include <input.h>
#include <keyboard.h>
#include <key_matrix.h>
@@ -161,15 +160,15 @@ int cros_ec_kbc_check(struct input_config *input)
* @param config Configuration data read from fdt
* @return 0 if ok, -1 on error
*/
-static int cros_ec_keyb_decode_fdt(const void *blob, int node,
- struct cros_ec_keyb_priv *config)
+static int cros_ec_keyb_decode_fdt(struct udevice *dev,
+ struct cros_ec_keyb_priv *config)
{
/*
* Get keyboard rows and columns - at present we are limited to
* 8 columns by the protocol (one byte per row scan)
*/
- config->key_rows = fdtdec_get_int(blob, node, "keypad,num-rows", 0);
- config->key_cols = fdtdec_get_int(blob, node, "keypad,num-columns", 0);
+ config->key_rows = dev_read_u32_default(dev, "keypad,num-rows", 0);
+ config->key_cols = dev_read_u32_default(dev, "keypad,num-columns", 0);
if (!config->key_rows || !config->key_cols ||
config->key_rows * config->key_cols / 8
> CROS_EC_KEYSCAN_COLS) {
@@ -177,8 +176,8 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node,
config->key_rows, config->key_cols);
return -1;
}
- config->ghost_filter = fdtdec_get_bool(blob, node,
- "google,needs-ghost-filter");
+ config->ghost_filter = dev_read_bool(dev, "google,needs-ghost-filter");
+
return 0;
}
@@ -188,12 +187,13 @@ static int cros_ec_kbd_probe(struct udevice *dev)
struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
struct stdio_dev *sdev = &uc_priv->sdev;
struct input_config *input = &uc_priv->input;
- const void *blob = gd->fdt_blob;
- int node = dev_of_offset(dev);
int ret;
- if (cros_ec_keyb_decode_fdt(blob, node, priv))
- return -1;
+ ret = cros_ec_keyb_decode_fdt(dev, priv);
+ if (ret) {
+ debug("%s: Cannot decode node (ret=%d)\n", __func__, ret);
+ return -EINVAL;
+ }
input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS);
ret = key_matrix_init(&priv->matrix, priv->key_rows, priv->key_cols,
priv->ghost_filter);
@@ -201,7 +201,7 @@ static int cros_ec_kbd_probe(struct udevice *dev)
debug("%s: cannot init key matrix\n", __func__);
return ret;
}
- ret = key_matrix_decode_fdt(&priv->matrix, gd->fdt_blob, node);
+ ret = key_matrix_decode_fdt(dev, &priv->matrix);
if (ret) {
debug("%s: Could not decode key matrix from fdt\n", __func__);
return ret;
diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c
index 8867e4964e..cd5bce3613 100644
--- a/drivers/input/key_matrix.c
+++ b/drivers/input/key_matrix.c
@@ -8,7 +8,7 @@
*/
#include <common.h>
-#include <fdtdec.h>
+#include <dm.h>
#include <key_matrix.h>
#include <malloc.h>
#include <linux/input.h>
@@ -105,7 +105,7 @@ int key_matrix_decode(struct key_matrix *config, struct key_matrix_key keys[],
* @param pos Returns position of map_keycode, if found, else -1
* @return map Pointer to allocated map
*/
-static uchar *create_keymap(struct key_matrix *config, u32 *data, int len,
+static uchar *create_keymap(struct key_matrix *config, const u32 *data, int len,
int map_keycode, int *pos)
{
uchar *map;
@@ -138,33 +138,32 @@ static uchar *create_keymap(struct key_matrix *config, u32 *data, int len,
return map;
}
-int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, int node)
+int key_matrix_decode_fdt(struct udevice *dev, struct key_matrix *config)
{
- const struct fdt_property *prop;
+ const u32 *prop;
int proplen;
uchar *plain_keycode;
- prop = fdt_get_property(blob, node, "linux,keymap", &proplen);
+ prop = dev_read_prop(dev, "linux,keymap", &proplen);
/* Basic keymap is required */
if (!prop) {
debug("%s: cannot find keycode-plain map\n", __func__);
return -1;
}
- plain_keycode = create_keymap(config, (u32 *)prop->data,
- proplen, KEY_FN, &config->fn_pos);
+ plain_keycode = create_keymap(config, prop, proplen, KEY_FN,
+ &config->fn_pos);
config->plain_keycode = plain_keycode;
/* Conversion error -> fail */
if (!config->plain_keycode)
return -1;
- prop = fdt_get_property(blob, node, "linux,fn-keymap", &proplen);
+ prop = dev_read_prop(dev, "linux,fn-keymap", &proplen);
/* fn keymap is optional */
if (!prop)
goto done;
- config->fn_keycode = create_keymap(config, (u32 *)prop->data,
- proplen, -1, NULL);
+ config->fn_keycode = create_keymap(config, prop, proplen, -1, NULL);
/* Conversion error -> fail */
if (!config->fn_keycode) {
free(plain_keycode);
diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c
index 7af5868dea..84ee015cb3 100644
--- a/drivers/input/keyboard.c
+++ b/drivers/input/keyboard.c
@@ -20,7 +20,7 @@ static struct input_config config;
static int kbd_read_keys(struct input_config *config)
{
-#if defined(CONFIG_MPC5xxx) || defined(CONFIG_ARCH_MPC8540) || \
+#if defined(CONFIG_ARCH_MPC8540) || \
defined(CONFIG_ARCH_MPC8541) || defined(CONFIG_ARCH_MPC8555)
/* no ISR is used, so received chars must be polled */
ps2ser_check();
diff --git a/drivers/input/ps2ser.c b/drivers/input/ps2ser.c
index bcbe52af15..0b5ce06853 100644
--- a/drivers/input/ps2ser.c
+++ b/drivers/input/ps2ser.c
@@ -29,25 +29,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define PS2SER_BAUD 57600
-#ifdef CONFIG_MPC5xxx
-#if CONFIG_PS2SERIAL == 1
-#define PSC_BASE MPC5XXX_PSC1
-#elif CONFIG_PS2SERIAL == 2
-#define PSC_BASE MPC5XXX_PSC2
-#elif CONFIG_PS2SERIAL == 3
-#define PSC_BASE MPC5XXX_PSC3
-#elif CONFIG_PS2SERIAL == 4
-#define PSC_BASE MPC5XXX_PSC4
-#elif CONFIG_PS2SERIAL == 5
-#define PSC_BASE MPC5XXX_PSC5
-#elif CONFIG_PS2SERIAL == 6
-#define PSC_BASE MPC5XXX_PSC6
-#else
-#error CONFIG_PS2SERIAL must be in 1 ... 6
-#endif
-
-#else
-
#if CONFIG_PS2SERIAL == 1
#define COM_BASE (CONFIG_SYS_CCSRBAR+0x4500)
#elif CONFIG_PS2SERIAL == 2
@@ -56,8 +37,6 @@ DECLARE_GLOBAL_DATA_PTR;
#error CONFIG_PS2SERIAL must be in 1 ... 2
#endif
-#endif /* CONFIG_MPC5xxx / other */
-
static int ps2ser_getc_hw(void);
static void ps2ser_interrupt(void *dev_id);
@@ -68,45 +47,6 @@ static atomic_t ps2buf_cnt;
static int ps2buf_in_idx;
static int ps2buf_out_idx;
-#ifdef CONFIG_MPC5xxx
-int ps2ser_init(void)
-{
- volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
- unsigned long baseclk;
- int div;
-
- /* reset PSC */
- psc->command = PSC_SEL_MODE_REG_1;
-
- /* select clock sources */
- psc->psc_clock_select = 0;
- baseclk = (gd->arch.ipb_clk + 16) / 32;
-
- /* switch to UART mode */
- psc->sicr = 0;
-
- /* configure parity, bit length and so on */
- psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
- psc->mode = PSC_MODE_ONE_STOP;
-
- /* set up UART divisor */
- div = (baseclk + (PS2SER_BAUD/2)) / PS2SER_BAUD;
- psc->ctur = (div >> 8) & 0xff;
- psc->ctlr = div & 0xff;
-
- /* disable all interrupts */
- psc->psc_imr = 0;
-
- /* reset and enable Rx/Tx */
- psc->command = PSC_RST_RX;
- psc->command = PSC_RST_TX;
- psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;
-
- return (0);
-}
-
-#else
-
int ps2ser_init(void)
{
NS16550_t com_port = (NS16550_t)COM_BASE;
@@ -122,45 +62,23 @@ int ps2ser_init(void)
return (0);
}
-#endif /* CONFIG_MPC5xxx / other */
-
void ps2ser_putc(int chr)
{
-#ifdef CONFIG_MPC5xxx
- volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#else
NS16550_t com_port = (NS16550_t)COM_BASE;
-#endif
debug(">>>> 0x%02x\n", chr);
-#ifdef CONFIG_MPC5xxx
- while (!(psc->psc_status & PSC_SR_TXRDY));
-
- psc->psc_buffer_8 = chr;
-#else
while ((com_port->lsr & UART_LSR_THRE) == 0);
com_port->thr = chr;
-#endif
}
static int ps2ser_getc_hw(void)
{
-#ifdef CONFIG_MPC5xxx
- volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#else
NS16550_t com_port = (NS16550_t)COM_BASE;
-#endif
int res = -1;
-#ifdef CONFIG_MPC5xxx
- if (psc->psc_status & PSC_SR_RXRDY) {
- res = (psc->psc_buffer_8);
- }
-#else
if (com_port->lsr & UART_LSR_DR) {
res = com_port->rbr;
}
-#endif
return res;
}
@@ -206,21 +124,13 @@ int ps2ser_check(void)
static void ps2ser_interrupt(void *dev_id)
{
-#ifdef CONFIG_MPC5xxx
- volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
-#else
NS16550_t com_port = (NS16550_t)COM_BASE;
-#endif
int chr;
int status;
do {
chr = ps2ser_getc_hw();
-#ifdef CONFIG_MPC5xxx
- status = psc->psc_status;
-#else
status = com_port->lsr;
-#endif
if (chr < 0) continue;
if (atomic_read(&ps2buf_cnt) < PS2BUF_SIZE) {
@@ -230,11 +140,7 @@ static void ps2ser_interrupt(void *dev_id)
} else {
printf ("ps2ser.c: buffer overflow\n");
}
-#ifdef CONFIG_MPC5xxx
- } while (status & PSC_SR_RXRDY);
-#else
} while (status & UART_LSR_DR);
-#endif
if (atomic_read(&ps2buf_cnt)) {
ps2mult_callback(atomic_read(&ps2buf_cnt));
}
diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c
index d36f1a1dfa..cb5695784e 100644
--- a/drivers/input/tegra-kbc.c
+++ b/drivers/input/tegra-kbc.c
@@ -290,10 +290,9 @@ static int tegra_kbd_probe(struct udevice *dev)
struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
struct stdio_dev *sdev = &uc_priv->sdev;
struct input_config *input = &uc_priv->input;
- int node = dev_of_offset(dev);
int ret;
- priv->kbc = (struct kbc_tegra *)dev_get_addr(dev);
+ priv->kbc = (struct kbc_tegra *)devfdt_get_addr(dev);
if ((fdt_addr_t)priv->kbc == FDT_ADDR_T_NONE) {
debug("%s: No keyboard register found\n", __func__);
return -EINVAL;
@@ -306,7 +305,7 @@ static int tegra_kbd_probe(struct udevice *dev)
debug("%s: Could not init key matrix: %d\n", __func__, ret);
return ret;
}
- ret = key_matrix_decode_fdt(&priv->matrix, gd->fdt_blob, node);
+ ret = key_matrix_decode_fdt(dev, &priv->matrix);
if (ret) {
debug("%s: Could not decode key matrix from fdt: %d\n",
__func__, ret);
diff --git a/drivers/led/led_bcm6328.c b/drivers/led/led_bcm6328.c
index ef8c6a7061..5d545c5096 100644
--- a/drivers/led/led_bcm6328.c
+++ b/drivers/led/led_bcm6328.c
@@ -158,7 +158,7 @@ static int bcm6328_led_probe(struct udevice *dev)
void __iomem *regs;
u32 set_bits = 0;
- addr = dev_get_addr_size_index(dev, 0, &size);
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -185,7 +185,8 @@ static int bcm6328_led_probe(struct udevice *dev)
struct bcm6328_led_priv *priv = dev_get_priv(dev);
unsigned int pin;
- addr = dev_get_addr_size_index(dev_get_parent(dev), 0, &size);
+ addr = devfdt_get_addr_size_index(dev_get_parent(dev), 0,
+ &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -235,7 +236,7 @@ static int bcm6328_led_bind(struct udevice *parent)
ret = device_bind_driver_to_node(parent, "bcm6328-led",
fdt_get_name(blob, node, NULL),
- node, &dev);
+ offset_to_ofnode(node), &dev);
if (ret)
return ret;
diff --git a/drivers/led/led_bcm6358.c b/drivers/led/led_bcm6358.c
index 11caecdc26..e8a3b64e68 100644
--- a/drivers/led/led_bcm6358.c
+++ b/drivers/led/led_bcm6358.c
@@ -124,7 +124,7 @@ static int bcm6358_led_probe(struct udevice *dev)
unsigned int clk_div;
u32 set_bits = 0;
- addr = dev_get_addr_size_index(dev, 0, &size);
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -158,7 +158,8 @@ static int bcm6358_led_probe(struct udevice *dev)
struct bcm6358_led_priv *priv = dev_get_priv(dev);
unsigned int pin;
- addr = dev_get_addr_size_index(dev_get_parent(dev), 0, &size);
+ addr = devfdt_get_addr_size_index(dev_get_parent(dev), 0,
+ &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -200,7 +201,7 @@ static int bcm6358_led_bind(struct udevice *parent)
ret = device_bind_driver_to_node(parent, "bcm6358-led",
fdt_get_name(blob, node, NULL),
- node, &dev);
+ offset_to_ofnode(node), &dev);
if (ret)
return ret;
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index 4106ecb679..9976635887 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -85,25 +85,22 @@ static int led_gpio_remove(struct udevice *dev)
static int led_gpio_bind(struct udevice *parent)
{
- const void *blob = gd->fdt_blob;
struct udevice *dev;
- int node;
+ ofnode node;
int ret;
- for (node = fdt_first_subnode(blob, dev_of_offset(parent));
- node > 0;
- node = fdt_next_subnode(blob, node)) {
+ dev_for_each_subnode(node, parent) {
struct led_uc_plat *uc_plat;
const char *label;
- label = fdt_getprop(blob, node, "label", NULL);
+ label = ofnode_read_string(node, "label");
if (!label) {
debug("%s: node %s has no label\n", __func__,
- fdt_get_name(blob, node, NULL));
+ ofnode_get_name(node));
return -EINVAL;
}
ret = device_bind_driver_to_node(parent, "gpio_led",
- fdt_get_name(blob, node, NULL),
+ ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
diff --git a/drivers/mailbox/mailbox-uclass.c b/drivers/mailbox/mailbox-uclass.c
index 38448de965..822ae5b45e 100644
--- a/drivers/mailbox/mailbox-uclass.c
+++ b/drivers/mailbox/mailbox-uclass.c
@@ -6,7 +6,6 @@
#include <common.h>
#include <dm.h>
-#include <fdtdec.h>
#include <mailbox.h>
#include <mailbox-uclass.h>
@@ -18,7 +17,7 @@ static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev)
}
static int mbox_of_xlate_default(struct mbox_chan *chan,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
debug("%s(chan=%p)\n", __func__, chan);
@@ -34,24 +33,22 @@ static int mbox_of_xlate_default(struct mbox_chan *chan,
int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan)
{
- struct fdtdec_phandle_args args;
+ struct ofnode_phandle_args args;
int ret;
struct udevice *dev_mbox;
struct mbox_ops *ops;
debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
- "mboxes", "#mbox-cells", 0,
- index, &args);
+ ret = dev_read_phandle_with_args(dev, "mboxes", "#mbox-cells", 0, index,
+ &args);
if (ret) {
- debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
- __func__, ret);
+ debug("%s: dev_read_phandle_with_args failed: %d\n", __func__,
+ ret);
return ret;
}
- ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node,
- &dev_mbox);
+ ret = uclass_get_device_by_ofnode(UCLASS_MAILBOX, args.node, &dev_mbox);
if (ret) {
debug("%s: uclass_get_device_by_of_offset failed: %d\n",
__func__, ret);
@@ -85,8 +82,7 @@ int mbox_get_by_name(struct udevice *dev, const char *name,
debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan);
- index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
- "mbox-names", name);
+ index = dev_read_stringlist_search(dev, "mbox-names", name);
if (index < 0) {
debug("fdt_stringlist_search() failed: %d\n", index);
return index;
diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
index 3d0362d587..bd2ec411c7 100644
--- a/drivers/mailbox/tegra-hsp.c
+++ b/drivers/mailbox/tegra-hsp.c
@@ -72,7 +72,7 @@ static int tegra_hsp_db_id(ulong chan_id)
}
static int tegra_hsp_of_xlate(struct mbox_chan *chan,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
debug("%s(chan=%p)\n", __func__, chan);
@@ -153,7 +153,7 @@ static int tegra_hsp_probe(struct udevice *dev)
debug("%s(dev=%p)\n", __func__, dev);
- thsp->regs = dev_get_addr(dev);
+ thsp->regs = devfdt_get_addr(dev);
if (thsp->regs == FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index ecca159d14..92f348f409 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -20,6 +20,19 @@ config ALTERA_SYSID
Select this to enable a sysid for Altera devices. Please find
details on the "Embedded Peripherals IP User Guide" of Altera.
+config ROCKCHIP_EFUSE
+ bool "Rockchip e-fuse support"
+ depends on MISC
+ help
+ Enable (read-only) access for the e-fuse block found in Rockchip
+ SoCs: accesses can either be made using byte addressing and a length
+ or through child-nodes that are generated based on the e-fuse map
+ retrieved from the DTS.
+
+ This driver currently supports the RK3399 only, but can easily be
+ extended (by porting the read function from the Linux kernel sources)
+ to support other recent Rockchip devices.
+
config CMD_CROS_EC
bool "Enable crosec command"
depends on CROS_EC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 4543cd647e..ea64677c33 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -50,3 +50,4 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
obj-$(CONFIG_QFW) += qfw.o
+obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c
index ed6d462c95..87aadaf24f 100644
--- a/drivers/misc/altera_sysid.c
+++ b/drivers/misc/altera_sysid.c
@@ -74,7 +74,7 @@ static int altera_sysid_ofdata_to_platdata(struct udevice *dev)
{
struct altera_sysid_platdata *plat = dev_get_platdata(dev);
- plat->regs = map_physmem(dev_get_addr(dev),
+ plat->regs = map_physmem(devfdt_get_addr(dev),
sizeof(struct altera_sysid_regs),
MAP_NOCACHE);
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 3d449b2a55..feaa5d8567 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -26,6 +26,7 @@
#include <asm/io.h>
#include <asm-generic/gpio.h>
#include <dm/device-internal.h>
+#include <dm/of_extra.h>
#include <dm/uclass-internal.h>
#ifdef DEBUG_TRACE
@@ -304,8 +305,7 @@ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd,
NULL, 0, &din, din_len);
}
- debug("%s: len=%d, dinp=%p, *dinp=%p\n", __func__, len, dinp,
- dinp ? *dinp : NULL);
+ debug("%s: len=%d, din=%p\n", __func__, len, din);
if (dinp) {
/* If we have any data to return, it must be 64bit-aligned */
assert(len <= 0 || !((uintptr_t)din & 7));
@@ -997,15 +997,12 @@ int cros_ec_get_ldo(struct udevice *dev, uint8_t index, uint8_t *state)
int cros_ec_register(struct udevice *dev)
{
struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
- const void *blob = gd->fdt_blob;
- int node = dev_of_offset(dev);
char id[MSG_BYTES];
cdev->dev = dev;
gpio_request_by_name(dev, "ec-interrupt", 0, &cdev->ec_int,
GPIOD_IS_IN);
- cdev->optimise_flash_write = fdtdec_get_bool(blob, node,
- "optimise-flash-write");
+ cdev->optimise_flash_write = dev_read_bool(dev, "optimise-flash-write");
if (cros_ec_check_version(cdev)) {
debug("%s: Could not detect CROS-EC version\n", __func__);
@@ -1024,28 +1021,26 @@ int cros_ec_register(struct udevice *dev)
return 0;
}
-int cros_ec_decode_ec_flash(const void *blob, int node,
- struct fdt_cros_ec *config)
+int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config)
{
- int flash_node;
+ ofnode flash_node, node;
- flash_node = fdt_subnode_offset(blob, node, "flash");
- if (flash_node < 0) {
+ flash_node = dev_read_subnode(dev, "flash");
+ if (!ofnode_valid(flash_node)) {
debug("Failed to find flash node\n");
return -1;
}
- if (fdtdec_read_fmap_entry(blob, flash_node, "flash",
- &config->flash)) {
- debug("Failed to decode flash node in chrome-ec'\n");
+ if (of_read_fmap_entry(flash_node, "flash", &config->flash)) {
+ debug("Failed to decode flash node in chrome-ec\n");
return -1;
}
- config->flash_erase_value = fdtdec_get_int(blob, flash_node,
- "erase-value", -1);
- for (node = fdt_first_subnode(blob, flash_node); node >= 0;
- node = fdt_next_subnode(blob, node)) {
- const char *name = fdt_get_name(blob, node, NULL);
+ config->flash_erase_value = ofnode_read_s32_default(flash_node,
+ "erase-value", -1);
+ for (node = ofnode_first_subnode(flash_node); ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ const char *name = ofnode_get_name(node);
enum ec_flash_region region;
if (0 == strcmp(name, "ro")) {
@@ -1059,8 +1054,7 @@ int cros_ec_decode_ec_flash(const void *blob, int node,
return -1;
}
- if (fdtdec_read_fmap_entry(blob, node, "reg",
- &config->region[region])) {
+ if (of_read_fmap_entry(node, "reg", &config->region[region])) {
debug("Failed to decode flash region in chrome-ec'\n");
return -1;
}
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 848c67bc23..c96e26e6b7 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -188,18 +188,16 @@ static int get_image_used(struct ec_state *ec, struct fmap_entry *entry)
* RR=Row CC=Column KKKK=Key Code
*
* @param ec Current emulated EC state
- * @param blob Device tree blob containing keyscan information
* @param node Keyboard node of device tree containing keyscan information
* @return 0 if ok, -1 on error
*/
-static int keyscan_read_fdt_matrix(struct ec_state *ec, const void *blob,
- int node)
+static int keyscan_read_fdt_matrix(struct ec_state *ec, ofnode node)
{
const u32 *cell;
int upto;
int len;
- cell = fdt_getprop(blob, node, "linux,keymap", &len);
+ cell = ofnode_read_prop(node, "linux,keymap", &len);
ec->matrix_count = len / 4;
ec->matrix = calloc(ec->matrix_count, sizeof(*ec->matrix));
if (!ec->matrix) {
@@ -516,28 +514,29 @@ int cros_ec_probe(struct udevice *dev)
{
struct ec_state *ec = dev->priv;
struct cros_ec_dev *cdev = dev->uclass_priv;
- const void *blob = gd->fdt_blob;
struct udevice *keyb_dev;
- int node;
+ ofnode node;
int err;
memcpy(ec, &s_state, sizeof(*ec));
- err = cros_ec_decode_ec_flash(blob, dev_of_offset(dev), &ec->ec_config);
- if (err)
+ err = cros_ec_decode_ec_flash(dev, &ec->ec_config);
+ if (err) {
+ debug("%s: Cannot device EC flash\n", __func__);
return err;
+ }
- node = -1;
+ node = ofnode_null();
for (device_find_first_child(dev, &keyb_dev);
keyb_dev;
device_find_next_child(&keyb_dev)) {
if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) {
- node = dev_of_offset(keyb_dev);
+ node = dev_ofnode(keyb_dev);
break;
}
}
- if (node < 0) {
+ if (!ofnode_valid(node)) {
debug("%s: No cros_ec keyboard found\n", __func__);
- } else if (keyscan_read_fdt_matrix(ec, blob, node)) {
+ } else if (keyscan_read_fdt_matrix(ec, node)) {
debug("%s: Could not read key matrix\n", __func__);
return -1;
}
diff --git a/drivers/misc/fsl_iim.c b/drivers/misc/fsl_iim.c
index 2feb1823e4..3c9f029eda 100644
--- a/drivers/misc/fsl_iim.c
+++ b/drivers/misc/fsl_iim.c
@@ -13,9 +13,7 @@
#include <fuse.h>
#include <linux/errno.h>
#include <asm/io.h>
-#ifndef CONFIG_MPC512X
#include <asm/arch/imx-regs.h>
-#endif
#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
#include <asm/arch/clock.h>
#endif
diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c
index da6e2b05f7..a14e83225b 100644
--- a/drivers/misc/i2c_eeprom.c
+++ b/drivers/misc/i2c_eeprom.c
@@ -42,7 +42,7 @@ static int i2c_eeprom_std_write(struct udevice *dev, int offset,
return -ENODEV;
}
-struct i2c_eeprom_ops i2c_eeprom_std_ops = {
+static const struct i2c_eeprom_ops i2c_eeprom_std_ops = {
.read = i2c_eeprom_std_read,
.write = i2c_eeprom_std_write,
};
@@ -59,7 +59,7 @@ static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev)
return 0;
}
-int i2c_eeprom_std_probe(struct udevice *dev)
+static int i2c_eeprom_std_probe(struct udevice *dev)
{
return 0;
}
diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c
index 02de8d7df3..52aa7d69e9 100644
--- a/drivers/misc/i2c_eeprom_emul.c
+++ b/drivers/misc/i2c_eeprom_emul.c
@@ -9,7 +9,6 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
#include <i2c.h>
#include <malloc.h>
#include <asm/test.h>
@@ -115,10 +114,8 @@ static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev)
{
struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
- plat->size = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
- "sandbox,size", 32);
- plat->filename = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
- "sandbox,filename", NULL);
+ plat->size = dev_read_u32_default(dev, "sandbox,size", 32);
+ plat->filename = dev_read_string(dev, "sandbox,filename");
if (!plat->filename) {
debug("%s: No filename for device '%s'\n", __func__,
dev->name);
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
new file mode 100644
index 0000000000..423d24c26e
--- /dev/null
+++ b/drivers/misc/rockchip-efuse.c
@@ -0,0 +1,161 @@
+/*
+ * eFuse driver for Rockchip devices
+ *
+ * Copyright 2017, Theobroma Systems Design und Consulting GmbH
+ * Written by Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <command.h>
+#include <display_options.h>
+#include <dm.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <misc.h>
+
+#define RK3399_A_SHIFT 16
+#define RK3399_A_MASK 0x3ff
+#define RK3399_NFUSES 32
+#define RK3399_BYTES_PER_FUSE 4
+#define RK3399_STROBSFTSEL BIT(9)
+#define RK3399_RSB BIT(7)
+#define RK3399_PD BIT(5)
+#define RK3399_PGENB BIT(3)
+#define RK3399_LOAD BIT(2)
+#define RK3399_STROBE BIT(1)
+#define RK3399_CSB BIT(0)
+
+struct rockchip_efuse_regs {
+ u32 ctrl; /* 0x00 efuse control register */
+ u32 dout; /* 0x04 efuse data out register */
+ u32 rf; /* 0x08 efuse redundancy bit used register */
+ u32 _rsvd0;
+ u32 jtag_pass; /* 0x10 JTAG password */
+ u32 strobe_finish_ctrl;
+ /* 0x14 efuse strobe finish control register */
+};
+
+struct rockchip_efuse_platdata {
+ void __iomem *base;
+ struct clk *clk;
+};
+
+#if defined(DEBUG)
+static int dump_efuses(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ /*
+ * N.B.: This function is tailored towards the RK3399 and assumes that
+ * there's always 32 fuses x 32 bits (i.e. 128 bytes of data) to
+ * be read.
+ */
+
+ struct udevice *dev;
+ u8 fuses[128];
+ int ret;
+
+ /* retrieve the device */
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(rockchip_efuse), &dev);
+ if (ret) {
+ printf("%s: no misc-device found\n", __func__);
+ return 0;
+ }
+
+ ret = misc_read(dev, 0, &fuses, sizeof(fuses));
+ if (ret) {
+ printf("%s: misc_read failed\n", __func__);
+ return 0;
+ }
+
+ printf("efuse-contents:\n");
+ print_buffer(0, fuses, 1, 128, 16);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ rk3399_dump_efuses, 1, 1, dump_efuses,
+ "Dump the content of the efuses",
+ ""
+);
+#endif
+
+static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
+ void *buf, int size)
+{
+ struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
+ struct rockchip_efuse_regs *efuse =
+ (struct rockchip_efuse_regs *)plat->base;
+
+ unsigned int addr_start, addr_end, addr_offset;
+ u32 out_value;
+ u8 bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE];
+ int i = 0;
+ u32 addr;
+
+ addr_start = offset / RK3399_BYTES_PER_FUSE;
+ addr_offset = offset % RK3399_BYTES_PER_FUSE;
+ addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE);
+
+ /* cap to the size of the efuse block */
+ if (addr_end > RK3399_NFUSES)
+ addr_end = RK3399_NFUSES;
+
+ writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB,
+ &efuse->ctrl);
+ udelay(1);
+ for (addr = addr_start; addr < addr_end; addr++) {
+ setbits_le32(&efuse->ctrl,
+ RK3399_STROBE | (addr << RK3399_A_SHIFT));
+ udelay(1);
+ out_value = readl(&efuse->dout);
+ clrbits_le32(&efuse->ctrl, RK3399_STROBE);
+ udelay(1);
+
+ memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE);
+ i += RK3399_BYTES_PER_FUSE;
+ }
+
+ /* Switch to standby mode */
+ writel(RK3399_PD | RK3399_CSB, &efuse->ctrl);
+
+ memcpy(buf, bytes + addr_offset, size);
+
+ return 0;
+}
+
+static int rockchip_efuse_read(struct udevice *dev, int offset,
+ void *buf, int size)
+{
+ return rockchip_rk3399_efuse_read(dev, offset, buf, size);
+}
+
+static const struct misc_ops rockchip_efuse_ops = {
+ .read = rockchip_efuse_read,
+};
+
+static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
+{
+ struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
+
+ plat->base = (void *)devfdt_get_addr(dev);
+ return 0;
+}
+
+static const struct udevice_id rockchip_efuse_ids[] = {
+ { .compatible = "rockchip,rk3399-efuse" },
+ {}
+};
+
+U_BOOT_DRIVER(rockchip_efuse) = {
+ .name = "rockchip_efuse",
+ .id = UCLASS_MISC,
+ .of_match = rockchip_efuse_ids,
+ .ofdata_to_platdata = rockchip_efuse_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct rockchip_efuse_platdata),
+ .ops = &rockchip_efuse_ops,
+};
diff --git a/drivers/misc/tegra186_bpmp.c b/drivers/misc/tegra186_bpmp.c
index bd8b9602e0..d61bacfc44 100644
--- a/drivers/misc/tegra186_bpmp.c
+++ b/drivers/misc/tegra186_bpmp.c
@@ -112,19 +112,19 @@ static int tegra186_bpmp_bind(struct udevice *dev)
debug("%s(dev=%p)\n", __func__, dev);
ret = device_bind_driver_to_node(dev, "tegra186_clk", "tegra186_clk",
- dev_of_offset(dev), &child);
+ dev_ofnode(dev), &child);
if (ret)
return ret;
ret = device_bind_driver_to_node(dev, "tegra186_reset",
- "tegra186_reset", dev_of_offset(dev),
+ "tegra186_reset", dev_ofnode(dev),
&child);
if (ret)
return ret;
ret = device_bind_driver_to_node(dev, "tegra186_power_domain",
"tegra186_power_domain",
- dev_of_offset(dev), &child);
+ dev_ofnode(dev), &child);
if (ret)
return ret;
diff --git a/drivers/misc/tegra_car.c b/drivers/misc/tegra_car.c
index 5db3c374ce..93639e1989 100644
--- a/drivers/misc/tegra_car.c
+++ b/drivers/misc/tegra_car.c
@@ -22,12 +22,12 @@ static int tegra_car_bpmp_bind(struct udevice *dev)
debug("%s(dev=%p)\n", __func__, dev);
ret = device_bind_driver_to_node(dev, "tegra_car_clk", "tegra_car_clk",
- dev_of_offset(dev), &child);
+ dev_ofnode(dev), &child);
if (ret)
return ret;
ret = device_bind_driver_to_node(dev, "tegra_car_reset",
- "tegra_car_reset", dev_of_offset(dev),
+ "tegra_car_reset", dev_ofnode(dev),
&child);
if (ret)
return ret;
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 0dd4443602..82b8d75686 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -156,7 +156,7 @@ config MMC_OMAP36XX_PINS
config SH_SDHI
bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
- depends on RMOBILE
+ depends on ARCH_RMOBILE
help
Support for the on-chip SDHI host controller on SuperH/Renesas ARM SoCs platform
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index a078649899..2d781c38a6 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -40,7 +40,6 @@ obj-$(CONFIG_MMC_MXS) += mxsmmc.o
obj-$(CONFIG_MMC_PCI) += pci_mmc.o
obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
-obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
obj-$(CONFIG_MMC_SANDBOX) += sandbox_mmc.o
obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c
index 86e36a9c28..c19a1f36b6 100644
--- a/drivers/mmc/atmel_sdhci.c
+++ b/drivers/mmc/atmel_sdhci.c
@@ -72,7 +72,7 @@ static int atmel_sdhci_probe(struct udevice *dev)
return ret;
host->name = dev->name;
- host->ioaddr = (void *)dev_get_addr(dev);
+ host->ioaddr = (void *)devfdt_get_addr(dev);
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD;
host->bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index b6e2fc6897..3157354d2a 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -179,7 +179,7 @@ static int bcm2835_sdhci_probe(struct udevice *dev)
int emmc_freq;
int ret;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 6f08a2d045..73748c5658 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -966,7 +966,7 @@ static int fsl_esdhc_probe(struct udevice *dev)
unsigned int val;
int ret;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -986,15 +986,15 @@ static int fsl_esdhc_probe(struct udevice *dev)
} else {
priv->non_removable = 0;
#ifdef CONFIG_DM_GPIO
- gpio_request_by_name_nodev(fdt, node, "cd-gpios", 0,
- &priv->cd_gpio, GPIOD_IS_IN);
+ gpio_request_by_name_nodev(offset_to_ofnode(node), "cd-gpios",
+ 0, &priv->cd_gpio, GPIOD_IS_IN);
#endif
}
priv->wp_enable = 1;
#ifdef CONFIG_DM_GPIO
- ret = gpio_request_by_name_nodev(fdt, node, "wp-gpios", 0,
+ ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "wp-gpios", 0,
&priv->wp_gpio, GPIOD_IS_IN);
if (ret)
priv->wp_enable = 0;
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index c25d9ed96e..e9f061e55d 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -11,6 +11,7 @@
#include <common.h>
#include <clk.h>
+#include <dm.h>
#include <mmc.h>
#include <part.h>
#include <malloc.h>
@@ -19,7 +20,6 @@
#include <asm/byteorder.h>
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
-#include <dm/device.h>
#include "atmel_mci.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -576,7 +576,7 @@ static int atmel_mci_probe(struct udevice *dev)
if (ret)
return ret;
- priv->mci = (struct atmel_mci *)dev_get_addr_ptr(dev);
+ priv->mci = (struct atmel_mci *)devfdt_get_addr_ptr(dev);
atmel_mci_setup_cfg(priv);
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c
index 2dda1b7064..4652fab45e 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -5,12 +5,12 @@
*/
#include <common.h>
+#include <dm.h>
#include <fdtdec.h>
#include <malloc.h>
#include <mmc.h>
#include <asm/io.h>
#include <asm/arch/sd_emmc.h>
-#include <dm/device.h>
#include <linux/log2.h>
static inline void *get_regbase(const struct mmc *mmc)
@@ -221,7 +221,7 @@ static int meson_mmc_ofdata_to_platdata(struct udevice *dev)
struct meson_mmc_platdata *pdata = dev_get_platdata(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 9c07871d3a..994d2686f4 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -97,7 +97,7 @@ struct mmc *find_mmc_device(int dev_num)
struct udevice *dev, *mmc_dev;
int ret;
- ret = blk_get_device(IF_TYPE_MMC, dev_num, &dev);
+ ret = blk_find_device(IF_TYPE_MMC, dev_num, &dev);
if (ret) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
@@ -108,7 +108,9 @@ struct mmc *find_mmc_device(int dev_num)
mmc_dev = dev_get_parent(dev);
- return mmc_get_mmc_dev(mmc_dev);
+ struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
+
+ return mmc;
}
int get_mmc_num(void)
@@ -196,9 +198,14 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
struct udevice *bdev;
int ret, devnum = -1;
+#ifdef CONFIG_DM_MMC_OPS
+ if (!mmc_get_ops(dev))
+ return -ENOSYS;
+#endif
#ifndef CONFIG_SPL_BUILD
/* Use the fixed index with aliase node's index */
- fdtdec_get_alias_seq(gd->fdt_blob, "mmc", dev->of_offset, &devnum);
+ ret = dev_read_alias_seq(dev, &devnum);
+ debug("%s: alias ret=%d, devnum=%d\n", __func__, ret, devnum);
#endif
ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC,
@@ -256,13 +263,18 @@ static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
static int mmc_blk_probe(struct udevice *dev)
{
- struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
- int dev_num = block_dev->devnum;
- struct mmc *mmc = find_mmc_device(dev_num);
+ struct udevice *mmc_dev = dev_get_parent(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev);
+ struct mmc *mmc = upriv->mmc;
+ int ret;
- if (!mmc)
- return -ENODEV;
- return mmc_init(mmc);
+ ret = mmc_init(mmc);
+ if (ret) {
+ debug("%s: mmc_init() failed (err=%d)\n", __func__, ret);
+ return ret;
+ }
+
+ return 0;
}
static const struct blk_ops mmc_blk_ops = {
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 72fc17716e..3cdf6a4f3b 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1608,17 +1608,17 @@ static int mmc_send_if_cond(struct mmc *mmc)
return 0;
}
+#ifndef CONFIG_DM_MMC
/* board-specific MMC power initializations. */
__weak void board_mmc_power_init(void)
{
}
+#endif
static int mmc_power_init(struct mmc *mmc)
{
- board_mmc_power_init();
-
-#if defined(CONFIG_DM_MMC) && defined(CONFIG_DM_REGULATOR) && \
- !defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_DM_MMC)
+#if defined(CONFIG_DM_REGULATOR) && !defined(CONFIG_SPL_BUILD)
struct udevice *vmmc_supply;
int ret;
@@ -1635,6 +1635,13 @@ static int mmc_power_init(struct mmc *mmc)
return ret;
}
#endif
+#else /* !CONFIG_DM_MMC */
+ /*
+ * Driver model should use a regulator, as above, rather than calling
+ * out to board code.
+ */
+ board_mmc_power_init();
+#endif
return 0;
}
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 7a7e67f6f3..9117ab6bf9 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -171,7 +171,7 @@ static int msm_ofdata_to_platdata(struct udevice *dev)
int node = dev_of_offset(dev);
host->name = strdup(dev->name);
- host->ioaddr = (void *)dev_get_addr(dev);
+ host->ioaddr = (void *)devfdt_get_addr(dev);
host->bus_width = fdtdec_get_int(gd->fdt_blob, node, "bus-width", 4);
host->index = fdtdec_get_uint(gd->fdt_blob, node, "index", 0);
priv->base = (void *)fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 0b21ec6efc..bb10caaf32 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -808,7 +808,8 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
int node = dev_of_offset(dev);
int val;
- plat->base_addr = map_physmem(dev_get_addr(dev), sizeof(struct hsmmc *),
+ plat->base_addr = map_physmem(devfdt_get_addr(dev),
+ sizeof(struct hsmmc *),
MAP_NOCACHE) + data->reg_offset;
cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c
index 9d8a392ed9..212e22ee02 100644
--- a/drivers/mmc/pic32_sdhci.c
+++ b/drivers/mmc/pic32_sdhci.c
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm.h>
#include <common.h>
+#include <dm.h>
#include <sdhci.h>
#include <linux/errno.h>
#include <mach/pic32.h>
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 2885ef2497..25a21e29d0 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -58,7 +58,7 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
struct dwmci_host *host = &priv->host;
host->name = dev->name;
- host->ioaddr = (void *)dev_get_addr(dev);
+ host->ioaddr = (void *)devfdt_get_addr(dev);
host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"bus-width", 4);
host->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index bdde831ffd..8985878d7e 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -83,7 +83,7 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
struct sdhci_host *host = dev_get_priv(dev);
host->name = dev->name;
- host->ioaddr = dev_get_addr_ptr(dev);
+ host->ioaddr = devfdt_get_addr_ptr(dev);
#endif
return 0;
diff --git a/drivers/mmc/s3c_sdi.c b/drivers/mmc/s3c_sdi.c
deleted file mode 100644
index faf7b83a14..0000000000
--- a/drivers/mmc/s3c_sdi.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * S3C24xx SD/MMC driver
- *
- * Based on OpenMoko S3C24xx driver by Harald Welte <laforge@openmoko.org>
- *
- * Copyright (C) 2014 Marek Vasut <marex@denx.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <mmc.h>
-#include <errno.h>
-#include <asm/arch/s3c24x0_cpu.h>
-#include <asm/io.h>
-#include <asm/unaligned.h>
-
-#define S3C2440_SDICON_SDRESET (1 << 8)
-#define S3C2410_SDICON_FIFORESET (1 << 1)
-#define S3C2410_SDICON_CLOCKTYPE (1 << 0)
-
-#define S3C2410_SDICMDCON_LONGRSP (1 << 10)
-#define S3C2410_SDICMDCON_WAITRSP (1 << 9)
-#define S3C2410_SDICMDCON_CMDSTART (1 << 8)
-#define S3C2410_SDICMDCON_SENDERHOST (1 << 6)
-#define S3C2410_SDICMDCON_INDEX 0x3f
-
-#define S3C2410_SDICMDSTAT_CRCFAIL (1 << 12)
-#define S3C2410_SDICMDSTAT_CMDSENT (1 << 11)
-#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1 << 10)
-#define S3C2410_SDICMDSTAT_RSPFIN (1 << 9)
-
-#define S3C2440_SDIDCON_DS_WORD (2 << 22)
-#define S3C2410_SDIDCON_TXAFTERRESP (1 << 20)
-#define S3C2410_SDIDCON_RXAFTERCMD (1 << 19)
-#define S3C2410_SDIDCON_BLOCKMODE (1 << 17)
-#define S3C2410_SDIDCON_WIDEBUS (1 << 16)
-#define S3C2440_SDIDCON_DATSTART (1 << 14)
-#define S3C2410_SDIDCON_XFER_RXSTART (2 << 12)
-#define S3C2410_SDIDCON_XFER_TXSTART (3 << 12)
-#define S3C2410_SDIDCON_BLKNUM 0x7ff
-
-#define S3C2410_SDIDSTA_FIFOFAIL (1 << 8)
-#define S3C2410_SDIDSTA_CRCFAIL (1 << 7)
-#define S3C2410_SDIDSTA_RXCRCFAIL (1 << 6)
-#define S3C2410_SDIDSTA_DATATIMEOUT (1 << 5)
-#define S3C2410_SDIDSTA_XFERFINISH (1 << 4)
-
-#define S3C2410_SDIFSTA_TFHALF (1 << 11)
-#define S3C2410_SDIFSTA_COUNTMASK 0x7f
-
-/*
- * WARNING: We only support one SD IP block.
- * NOTE: It's not likely there will ever exist an S3C24xx with two,
- * at least not in this universe all right.
- */
-static int wide_bus;
-
-static int
-s3cmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
-{
- struct s3c24x0_sdi *sdi_regs = s3c24x0_get_base_sdi();
- uint32_t sdiccon, sdicsta, sdidcon, sdidsta, sdidat, sdifsta;
- uint32_t sdicsta_wait_bit = S3C2410_SDICMDSTAT_CMDSENT;
- unsigned int timeout = 100000;
- int ret = 0, xfer_len, data_offset = 0;
- const uint32_t sdidsta_err_mask = S3C2410_SDIDSTA_FIFOFAIL |
- S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL |
- S3C2410_SDIDSTA_DATATIMEOUT;
-
-
- writel(0xffffffff, &sdi_regs->sdicsta);
- writel(0xffffffff, &sdi_regs->sdidsta);
- writel(0xffffffff, &sdi_regs->sdifsta);
-
- /* Set up data transfer (if applicable). */
- if (data) {
- writel(data->blocksize, &sdi_regs->sdibsize);
-
- sdidcon = data->blocks & S3C2410_SDIDCON_BLKNUM;
- sdidcon |= S3C2410_SDIDCON_BLOCKMODE;
-#if defined(CONFIG_S3C2440)
- sdidcon |= S3C2440_SDIDCON_DS_WORD | S3C2440_SDIDCON_DATSTART;
-#endif
- if (wide_bus)
- sdidcon |= S3C2410_SDIDCON_WIDEBUS;
-
- if (data->flags & MMC_DATA_READ) {
- sdidcon |= S3C2410_SDIDCON_RXAFTERCMD;
- sdidcon |= S3C2410_SDIDCON_XFER_RXSTART;
- } else {
- sdidcon |= S3C2410_SDIDCON_TXAFTERRESP;
- sdidcon |= S3C2410_SDIDCON_XFER_TXSTART;
- }
-
- writel(sdidcon, &sdi_regs->sdidcon);
- }
-
- /* Write CMD arg. */
- writel(cmd->cmdarg, &sdi_regs->sdicarg);
-
- /* Write CMD index. */
- sdiccon = cmd->cmdidx & S3C2410_SDICMDCON_INDEX;
- sdiccon |= S3C2410_SDICMDCON_SENDERHOST;
- sdiccon |= S3C2410_SDICMDCON_CMDSTART;
-
- /* Command with short response. */
- if (cmd->resp_type & MMC_RSP_PRESENT) {
- sdiccon |= S3C2410_SDICMDCON_WAITRSP;
- sdicsta_wait_bit = S3C2410_SDICMDSTAT_RSPFIN;
- }
-
- /* Command with long response. */
- if (cmd->resp_type & MMC_RSP_136)
- sdiccon |= S3C2410_SDICMDCON_LONGRSP;
-
- /* Start the command. */
- writel(sdiccon, &sdi_regs->sdiccon);
-
- /* Wait for the command to complete or for response. */
- for (timeout = 100000; timeout; timeout--) {
- sdicsta = readl(&sdi_regs->sdicsta);
- if (sdicsta & sdicsta_wait_bit)
- break;
-
- if (sdicsta & S3C2410_SDICMDSTAT_CMDTIMEOUT)
- timeout = 1;
- }
-
- /* Clean the status bits. */
- setbits_le32(&sdi_regs->sdicsta, 0xf << 9);
-
- if (!timeout) {
- puts("S3C SDI: Command timed out!\n");
- ret = -ETIMEDOUT;
- goto error;
- }
-
- /* Read out the response. */
- if (cmd->resp_type & MMC_RSP_136) {
- cmd->response[0] = readl(&sdi_regs->sdirsp0);
- cmd->response[1] = readl(&sdi_regs->sdirsp1);
- cmd->response[2] = readl(&sdi_regs->sdirsp2);
- cmd->response[3] = readl(&sdi_regs->sdirsp3);
- } else {
- cmd->response[0] = readl(&sdi_regs->sdirsp0);
- }
-
- /* If there are no data, we're done. */
- if (!data)
- return 0;
-
- xfer_len = data->blocksize * data->blocks;
-
- while (xfer_len > 0) {
- sdidsta = readl(&sdi_regs->sdidsta);
- sdifsta = readl(&sdi_regs->sdifsta);
-
- if (sdidsta & sdidsta_err_mask) {
- printf("S3C SDI: Data error (sdta=0x%08x)\n", sdidsta);
- ret = -EIO;
- goto error;
- }
-
- if (data->flags & MMC_DATA_READ) {
- if ((sdifsta & S3C2410_SDIFSTA_COUNTMASK) < 4)
- continue;
- sdidat = readl(&sdi_regs->sdidat);
- put_unaligned_le32(sdidat, data->dest + data_offset);
- } else { /* Write */
- /* TX FIFO half full. */
- if (!(sdifsta & S3C2410_SDIFSTA_TFHALF))
- continue;
-
- /* TX FIFO is below 32b full, write. */
- sdidat = get_unaligned_le32(data->src + data_offset);
- writel(sdidat, &sdi_regs->sdidat);
- }
- data_offset += 4;
- xfer_len -= 4;
- }
-
- /* Wait for the command to complete or for response. */
- for (timeout = 100000; timeout; timeout--) {
- sdidsta = readl(&sdi_regs->sdidsta);
- if (sdidsta & S3C2410_SDIDSTA_XFERFINISH)
- break;
-
- if (sdidsta & S3C2410_SDIDSTA_DATATIMEOUT)
- timeout = 1;
- }
-
- /* Clear status bits. */
- writel(0x6f8, &sdi_regs->sdidsta);
-
- if (!timeout) {
- puts("S3C SDI: Command timed out!\n");
- ret = -ETIMEDOUT;
- goto error;
- }
-
- writel(0, &sdi_regs->sdidcon);
-
- return 0;
-error:
- return ret;
-}
-
-static int s3cmmc_set_ios(struct mmc *mmc)
-{
- struct s3c24x0_sdi *sdi_regs = s3c24x0_get_base_sdi();
- uint32_t divider = 0;
-
- wide_bus = (mmc->bus_width == 4);
-
- if (!mmc->clock)
- return 0;
-
- divider = DIV_ROUND_UP(get_PCLK(), mmc->clock);
- if (divider)
- divider--;
-
- writel(divider, &sdi_regs->sdipre);
- mdelay(125);
-
- return 0;
-}
-
-static int s3cmmc_init(struct mmc *mmc)
-{
- struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
- struct s3c24x0_sdi *sdi_regs = s3c24x0_get_base_sdi();
-
- /* Start the clock. */
- setbits_le32(&clk_power->clkcon, 1 << 9);
-
-#if defined(CONFIG_S3C2440)
- writel(S3C2440_SDICON_SDRESET, &sdi_regs->sdicon);
- mdelay(10);
- writel(0x7fffff, &sdi_regs->sdidtimer);
-#else
- writel(0xffff, &sdi_regs->sdidtimer);
-#endif
- writel(MMC_MAX_BLOCK_LEN, &sdi_regs->sdibsize);
- writel(0x0, &sdi_regs->sdiimsk);
-
- writel(S3C2410_SDICON_FIFORESET | S3C2410_SDICON_CLOCKTYPE,
- &sdi_regs->sdicon);
-
- mdelay(125);
-
- return 0;
-}
-
-struct s3cmmc_priv {
- struct mmc_config cfg;
- int (*getcd)(struct mmc *);
- int (*getwp)(struct mmc *);
-};
-
-static int s3cmmc_getcd(struct mmc *mmc)
-{
- struct s3cmmc_priv *priv = mmc->priv;
- if (priv->getcd)
- return priv->getcd(mmc);
- else
- return 0;
-}
-
-static int s3cmmc_getwp(struct mmc *mmc)
-{
- struct s3cmmc_priv *priv = mmc->priv;
- if (priv->getwp)
- return priv->getwp(mmc);
- else
- return 0;
-}
-
-static const struct mmc_ops s3cmmc_ops = {
- .send_cmd = s3cmmc_send_cmd,
- .set_ios = s3cmmc_set_ios,
- .init = s3cmmc_init,
- .getcd = s3cmmc_getcd,
- .getwp = s3cmmc_getwp,
-};
-
-int s3cmmc_initialize(bd_t *bis, int (*getcd)(struct mmc *),
- int (*getwp)(struct mmc *))
-{
- struct s3cmmc_priv *priv;
- struct mmc *mmc;
- struct mmc_config *cfg;
-
- priv = calloc(1, sizeof(*priv));
- if (!priv)
- return -ENOMEM;
- cfg = &priv->cfg;
-
- cfg->name = "S3C MMC";
- cfg->ops = &s3cmmc_ops;
- cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
- cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS;
- cfg->f_min = 400000;
- cfg->f_max = get_PCLK() / 2;
- cfg->b_max = 0x80;
-
-#if defined(CONFIG_S3C2410)
- /*
- * S3C2410 has some bug that prevents reliable
- * operation at higher speed
- */
- cfg->f_max /= 2;
-#endif
-
- mmc = mmc_create(cfg, priv);
- if (!mmc) {
- free(priv);
- return -ENOMEM;
- }
-
- return 0;
-}
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 640ea0261e..62817a0d07 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -184,10 +184,10 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
}
host->ioaddr = (void *)base;
- gpio_request_by_name_nodev(blob, node, "pwr-gpios", 0, &host->pwr_gpio,
- GPIOD_IS_OUT);
- gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio,
- GPIOD_IS_IN);
+ gpio_request_by_name_nodev(offset_to_ofnode(node), "pwr-gpios", 0,
+ &host->pwr_gpio, GPIOD_IS_OUT);
+ gpio_request_by_name_nodev(offset_to_ofnode(node), "cd-gpios", 0,
+ &host->cd_gpio, GPIOD_IS_IN);
return 0;
}
diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c
index dc86d108a6..4bd2623eae 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -6,10 +6,10 @@
*/
#include <common.h>
+#include <dm.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/sizes.h>
-#include <dm/device.h>
#include <libfdt.h>
#include <mmc.h>
#include <sdhci.h>
@@ -127,7 +127,7 @@ static int sdhci_cdns_probe(struct udevice *dev)
fdt_addr_t base;
int ret;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -139,7 +139,7 @@ static int sdhci_cdns_probe(struct udevice *dev)
host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE;
host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD;
- ret = sdhci_cdns_phy_init(plat, gd->fdt_blob, dev->of_offset);
+ ret = sdhci_cdns_phy_init(plat, gd->fdt_blob, dev_of_offset(dev));
if (ret)
return ret;
diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c
index 25224e2e1d..d181b63905 100644
--- a/drivers/mmc/sh_sdhi.c
+++ b/drivers/mmc/sh_sdhi.c
@@ -3,7 +3,7 @@
*
* SD/MMC driver for Renesas rmobile ARM SoCs.
*
- * Copyright (C) 2011,2013-2014 Renesas Electronics Corporation
+ * Copyright (C) 2011,2013-2017 Renesas Electronics Corporation
* Copyright (C) 2014 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
* Copyright (C) 2008-2009 Renesas Solutions Corp.
*
@@ -29,6 +29,17 @@ struct sh_sdhi_host {
unsigned char sd_error;
unsigned char detect_waiting;
};
+
+static inline void sh_sdhi_writeq(struct sh_sdhi_host *host, int reg, u64 val)
+{
+ writeq(val, host->addr + (reg << host->bus_shift));
+}
+
+static inline u64 sh_sdhi_readq(struct sh_sdhi_host *host, int reg)
+{
+ return readq(host->addr + (reg << host->bus_shift));
+}
+
static inline void sh_sdhi_writew(struct sh_sdhi_host *host, int reg, u16 val)
{
writew(val, host->addr + (reg << host->bus_shift));
@@ -261,6 +272,7 @@ static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
long time;
unsigned short blocksize, i;
unsigned short *p = (unsigned short *)data->dest;
+ u64 *q = (u64 *)data->dest;
if ((unsigned long)p & 0x00000001) {
debug(DRIVER_NAME": %s: The data pointer is unaligned.",
@@ -281,8 +293,12 @@ static int sh_sdhi_single_read(struct sh_sdhi_host *host, struct mmc_data *data)
host->wait_int = 0;
blocksize = sh_sdhi_readw(host, SDHI_SIZE);
- for (i = 0; i < blocksize / 2; i++)
- *p++ = sh_sdhi_readw(host, SDHI_BUF0);
+ if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
+ for (i = 0; i < blocksize / 8; i++)
+ *q++ = sh_sdhi_readq(host, SDHI_BUF0);
+ else
+ for (i = 0; i < blocksize / 2; i++)
+ *p++ = sh_sdhi_readw(host, SDHI_BUF0);
time = sh_sdhi_wait_interrupt_flag(host);
if (time == 0 || host->sd_error != 0)
@@ -297,6 +313,7 @@ static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
long time;
unsigned short blocksize, i, sec;
unsigned short *p = (unsigned short *)data->dest;
+ u64 *q = (u64 *)data->dest;
if ((unsigned long)p & 0x00000001) {
debug(DRIVER_NAME": %s: The data pointer is unaligned.",
@@ -319,8 +336,12 @@ static int sh_sdhi_multi_read(struct sh_sdhi_host *host, struct mmc_data *data)
host->wait_int = 0;
blocksize = sh_sdhi_readw(host, SDHI_SIZE);
- for (i = 0; i < blocksize / 2; i++)
- *p++ = sh_sdhi_readw(host, SDHI_BUF0);
+ if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
+ for (i = 0; i < blocksize / 8; i++)
+ *q++ = sh_sdhi_readq(host, SDHI_BUF0);
+ else
+ for (i = 0; i < blocksize / 2; i++)
+ *p++ = sh_sdhi_readw(host, SDHI_BUF0);
}
return 0;
@@ -332,6 +353,7 @@ static int sh_sdhi_single_write(struct sh_sdhi_host *host,
long time;
unsigned short blocksize, i;
const unsigned short *p = (const unsigned short *)data->src;
+ const u64 *q = (const u64 *)data->src;
if ((unsigned long)p & 0x00000001) {
debug(DRIVER_NAME": %s: The data pointer is unaligned.",
@@ -356,8 +378,12 @@ static int sh_sdhi_single_write(struct sh_sdhi_host *host,
host->wait_int = 0;
blocksize = sh_sdhi_readw(host, SDHI_SIZE);
- for (i = 0; i < blocksize / 2; i++)
- sh_sdhi_writew(host, SDHI_BUF0, *p++);
+ if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
+ for (i = 0; i < blocksize / 8; i++)
+ sh_sdhi_writeq(host, SDHI_BUF0, *q++);
+ else
+ for (i = 0; i < blocksize / 2; i++)
+ sh_sdhi_writew(host, SDHI_BUF0, *p++);
time = sh_sdhi_wait_interrupt_flag(host);
if (time == 0 || host->sd_error != 0)
@@ -372,6 +398,7 @@ static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
long time;
unsigned short i, sec, blocksize;
const unsigned short *p = (const unsigned short *)data->src;
+ const u64 *q = (const u64 *)data->src;
debug("%s: blocks = %d, blocksize = %d\n",
__func__, data->blocks, data->blocksize);
@@ -388,8 +415,12 @@ static int sh_sdhi_multi_write(struct sh_sdhi_host *host, struct mmc_data *data)
host->wait_int = 0;
blocksize = sh_sdhi_readw(host, SDHI_SIZE);
- for (i = 0; i < blocksize / 2; i++)
- sh_sdhi_writew(host, SDHI_BUF0, *p++);
+ if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
+ for (i = 0; i < blocksize / 8; i++)
+ sh_sdhi_writeq(host, SDHI_BUF0, *q++);
+ else
+ for (i = 0; i < blocksize / 2; i++)
+ sh_sdhi_writew(host, SDHI_BUF0, *p++);
}
return 0;
@@ -458,6 +489,13 @@ static unsigned short sh_sdhi_set_cmd(struct sh_sdhi_host *host,
else /* SD_SWITCH */
opc = SDHI_SD_SWITCH;
break;
+ case MMC_CMD_SEND_OP_COND:
+ opc = SDHI_MMC_SEND_OP_COND;
+ break;
+ case MMC_CMD_SEND_EXT_CSD:
+ if (data)
+ opc = SDHI_MMC_SEND_EXT_CSD;
+ break;
default:
break;
}
@@ -482,6 +520,7 @@ static unsigned short sh_sdhi_data_trans(struct sh_sdhi_host *host,
case MMC_CMD_READ_SINGLE_BLOCK:
case SDHI_SD_APP_SEND_SCR:
case SDHI_SD_SWITCH: /* SD_SWITCH */
+ case SDHI_MMC_SEND_EXT_CSD:
ret = sh_sdhi_single_read(host, data);
break;
default:
@@ -546,8 +585,6 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host,
break;
}
- sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK));
-
host->wait_int = 0;
sh_sdhi_writew(host, SDHI_INFO1_MASK,
~INFO1M_RESP_END & sh_sdhi_readw(host, SDHI_INFO1_MASK));
@@ -557,6 +594,8 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host,
INFO2M_RESP_TIMEOUT | INFO2M_ILA) &
sh_sdhi_readw(host, SDHI_INFO2_MASK));
+ sh_sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK));
+
time = sh_sdhi_wait_interrupt_flag(host);
if (!time)
return sh_sdhi_error_manage(host);
@@ -617,12 +656,18 @@ static int sh_sdhi_set_ios(struct mmc *mmc)
if (ret)
return -EINVAL;
- if (mmc->bus_width == 4)
- sh_sdhi_writew(host, SDHI_OPTION, ~OPT_BUS_WIDTH_1 &
- sh_sdhi_readw(host, SDHI_OPTION));
+ if (mmc->bus_width == 8)
+ sh_sdhi_writew(host, SDHI_OPTION,
+ OPT_BUS_WIDTH_8 | (~OPT_BUS_WIDTH_M &
+ sh_sdhi_readw(host, SDHI_OPTION)));
+ else if (mmc->bus_width == 4)
+ sh_sdhi_writew(host, SDHI_OPTION,
+ OPT_BUS_WIDTH_4 | (~OPT_BUS_WIDTH_M &
+ sh_sdhi_readw(host, SDHI_OPTION)));
else
- sh_sdhi_writew(host, SDHI_OPTION, OPT_BUS_WIDTH_1 |
- sh_sdhi_readw(host, SDHI_OPTION));
+ sh_sdhi_writew(host, SDHI_OPTION,
+ OPT_BUS_WIDTH_1 | (~OPT_BUS_WIDTH_M &
+ sh_sdhi_readw(host, SDHI_OPTION)));
debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
@@ -653,6 +698,19 @@ static const struct mmc_ops sh_sdhi_ops = {
.init = sh_sdhi_initialize,
};
+#ifdef CONFIG_RCAR_GEN3
+static struct mmc_config sh_sdhi_cfg = {
+ .name = DRIVER_NAME,
+ .ops = &sh_sdhi_ops,
+ .f_min = CLKDEV_INIT,
+ .f_max = CLKDEV_HS_DATA,
+ .voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+ .host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HS |
+ MMC_MODE_HS_52MHz,
+ .part_type = PART_TYPE_DOS,
+ .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+};
+#else
static struct mmc_config sh_sdhi_cfg = {
.name = DRIVER_NAME,
.ops = &sh_sdhi_ops,
@@ -663,6 +721,7 @@ static struct mmc_config sh_sdhi_cfg = {
.part_type = PART_TYPE_DOS,
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
};
+#endif
int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
{
@@ -687,7 +746,9 @@ int sh_sdhi_init(unsigned long addr, int ch, unsigned long quirks)
host->addr = addr;
host->quirks = quirks;
- if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
+ if (host->quirks & SH_SDHI_QUIRK_64BIT_BUF)
+ host->bus_shift = 2;
+ else if (host->quirks & SH_SDHI_QUIRK_16BIT_BUF)
host->bus_shift = 1;
return ret;
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index d0c3c5155a..759686ccd6 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -78,7 +78,7 @@ static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev)
}
host->name = dev->name;
- host->ioaddr = (void *)dev_get_addr(dev);
+ host->ioaddr = (void *)devfdt_get_addr(dev);
host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"bus-width", 4);
host->clksel = socfpga_dwmci_clksel;
diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c
index 2a07082036..f85f6b4db6 100644
--- a/drivers/mmc/sti_sdhci.c
+++ b/drivers/mmc/sti_sdhci.c
@@ -108,7 +108,7 @@ static int sti_sdhci_ofdata_to_platdata(struct udevice *dev)
struct sdhci_host *host = dev_get_priv(dev);
host->name = strdup(dev->name);
- host->ioaddr = (void *)dev_get_addr(dev);
+ host->ioaddr = (void *)devfdt_get_addr(dev);
host->bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"bus-width", 4);
diff --git a/drivers/mmc/tangier_sdhci.c b/drivers/mmc/tangier_sdhci.c
index 77b18e75f0..bafe85bf64 100644
--- a/drivers/mmc/tangier_sdhci.c
+++ b/drivers/mmc/tangier_sdhci.c
@@ -36,7 +36,7 @@ static int sdhci_tangier_probe(struct udevice *dev)
fdt_addr_t base;
int ret;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 6c6affb925..7d945a172e 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -9,7 +9,7 @@
#include <bouncebuf.h>
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <errno.h>
#include <asm/gpio.h>
#include <asm/io.h>
@@ -18,6 +18,11 @@
DECLARE_GLOBAL_DATA_PTR;
+struct tegra_mmc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
struct tegra_mmc_priv {
struct tegra_mmc *reg;
struct reset_ctl reset_ctl;
@@ -27,8 +32,6 @@ struct tegra_mmc_priv {
struct gpio_desc wp_gpio; /* Write Protect GPIO */
unsigned int version; /* SDHCI spec. version */
unsigned int clock; /* Current clock (MHz) */
- struct mmc_config cfg; /* mmc configuration */
- struct mmc *mmc;
};
static void tegra_mmc_set_power(struct tegra_mmc_priv *priv,
@@ -151,11 +154,11 @@ static int tegra_mmc_wait_inhibit(struct tegra_mmc_priv *priv,
return 0;
}
-static int tegra_mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd,
+static int tegra_mmc_send_cmd_bounced(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data,
struct bounce_buffer *bbstate)
{
- struct tegra_mmc_priv *priv = mmc->priv;
+ struct tegra_mmc_priv *priv = dev_get_priv(dev);
int flags, i;
int result;
unsigned int mask = 0;
@@ -324,7 +327,7 @@ static int tegra_mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd,
return 0;
}
-static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+static int tegra_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
void *buf;
@@ -346,7 +349,7 @@ static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
bounce_buffer_start(&bbstate, buf, len, bbflags);
}
- ret = tegra_mmc_send_cmd_bounced(mmc, cmd, data, &bbstate);
+ ret = tegra_mmc_send_cmd_bounced(dev, cmd, data, &bbstate);
if (data)
bounce_buffer_stop(&bbstate);
@@ -408,9 +411,10 @@ out:
priv->clock = clock;
}
-static int tegra_mmc_set_ios(struct mmc *mmc)
+static int tegra_mmc_set_ios(struct udevice *dev)
{
- struct tegra_mmc_priv *priv = mmc->priv;
+ struct tegra_mmc_priv *priv = dev_get_priv(dev);
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
unsigned char ctrl;
debug(" mmc_set_ios called\n");
@@ -434,7 +438,7 @@ static int tegra_mmc_set_ios(struct mmc *mmc)
else if (mmc->bus_width == 4)
ctrl |= (1 << 1);
else
- ctrl &= ~(1 << 1);
+ ctrl &= ~(1 << 1 | 1 << 5);
writeb(ctrl, &priv->reg->hostctl);
debug("mmc_set_ios: hostctl = %08X\n", ctrl);
@@ -505,9 +509,10 @@ static void tegra_mmc_reset(struct tegra_mmc_priv *priv, struct mmc *mmc)
tegra_mmc_pad_init(priv);
}
-static int tegra_mmc_init(struct mmc *mmc)
+static int tegra_mmc_init(struct udevice *dev)
{
- struct tegra_mmc_priv *priv = mmc->priv;
+ struct tegra_mmc_priv *priv = dev_get_priv(dev);
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
unsigned int mask;
debug(" tegra_mmc_init called\n");
@@ -566,9 +571,9 @@ static int tegra_mmc_init(struct mmc *mmc)
return 0;
}
-static int tegra_mmc_getcd(struct mmc *mmc)
+static int tegra_mmc_getcd(struct udevice *dev)
{
- struct tegra_mmc_priv *priv = mmc->priv;
+ struct tegra_mmc_priv *priv = dev_get_priv(dev);
debug("tegra_mmc_getcd called\n");
@@ -578,32 +583,32 @@ static int tegra_mmc_getcd(struct mmc *mmc)
return 1;
}
-static const struct mmc_ops tegra_mmc_ops = {
+static const struct dm_mmc_ops tegra_mmc_ops = {
.send_cmd = tegra_mmc_send_cmd,
.set_ios = tegra_mmc_set_ios,
- .init = tegra_mmc_init,
- .getcd = tegra_mmc_getcd,
+ .get_cd = tegra_mmc_getcd,
};
static int tegra_mmc_probe(struct udevice *dev)
{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct tegra_mmc_plat *plat = dev_get_platdata(dev);
struct tegra_mmc_priv *priv = dev_get_priv(dev);
+ struct mmc_config *cfg = &plat->cfg;
int bus_width, ret;
- priv->cfg.name = "Tegra SD/MMC";
- priv->cfg.ops = &tegra_mmc_ops;
+ cfg->name = dev->name;
bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"bus-width", 1);
- priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
- priv->cfg.host_caps = 0;
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ cfg->host_caps = 0;
if (bus_width == 8)
- priv->cfg.host_caps |= MMC_MODE_8BIT;
+ cfg->host_caps |= MMC_MODE_8BIT;
if (bus_width >= 4)
- priv->cfg.host_caps |= MMC_MODE_4BIT;
- priv->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ cfg->host_caps |= MMC_MODE_4BIT;
+ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
/*
* min freq is for card identification, and is the highest
@@ -611,12 +616,12 @@ static int tegra_mmc_probe(struct udevice *dev)
* max freq is highest HS eMMC clock as per the SD/MMC spec
* (actually 52MHz)
*/
- priv->cfg.f_min = 375000;
- priv->cfg.f_max = 48000000;
+ cfg->f_min = 375000;
+ cfg->f_max = 48000000;
- priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
- priv->reg = (void *)dev_get_addr(dev);
+ priv->reg = (void *)devfdt_get_addr(dev);
ret = reset_get_by_name(dev, "sdhci", &priv->reset_ctl);
if (ret) {
@@ -652,14 +657,16 @@ static int tegra_mmc_probe(struct udevice *dev)
if (dm_gpio_is_valid(&priv->pwr_gpio))
dm_gpio_set_value(&priv->pwr_gpio, 1);
- priv->mmc = mmc_create(&priv->cfg, priv);
- if (priv->mmc == NULL)
- return -1;
+ upriv->mmc = &plat->mmc;
- priv->mmc->dev = dev;
- upriv->mmc = priv->mmc;
+ return tegra_mmc_init(dev);
+}
- return 0;
+static int tegra_mmc_bind(struct udevice *dev)
+{
+ struct tegra_mmc_plat *plat = dev_get_platdata(dev);
+
+ return mmc_bind(dev, &plat->mmc, &plat->cfg);
}
static const struct udevice_id tegra_mmc_ids[] = {
@@ -676,6 +683,9 @@ U_BOOT_DRIVER(tegra_mmc_drv) = {
.name = "tegra_mmc",
.id = UCLASS_MMC,
.of_match = tegra_mmc_ids,
+ .bind = tegra_mmc_bind,
.probe = tegra_mmc_probe,
+ .ops = &tegra_mmc_ops,
+ .platdata_auto_alloc_size = sizeof(struct tegra_mmc_plat),
.priv_auto_alloc_size = sizeof(struct tegra_mmc_priv),
};
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 7f20ef124d..3c462bd583 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -9,7 +9,7 @@
#include <clk.h>
#include <fdtdec.h>
#include <mmc.h>
-#include <dm/device.h>
+#include <dm.h>
#include <linux/compat.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -673,7 +673,7 @@ static int uniphier_sd_probe(struct udevice *dev)
struct clk clk;
int ret;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c
index 2a0d8b46c6..2b7cb7f6b6 100644
--- a/drivers/mmc/xenon_sdhci.c
+++ b/drivers/mmc/xenon_sdhci.c
@@ -452,10 +452,10 @@ static int xenon_sdhci_ofdata_to_platdata(struct udevice *dev)
const char *name;
host->name = dev->name;
- host->ioaddr = (void *)dev_get_addr(dev);
+ host->ioaddr = (void *)devfdt_get_addr(dev);
- if (of_device_is_compatible(dev, "marvell,armada-3700-sdhci"))
- priv->pad_ctrl_reg = (void *)dev_get_addr_index(dev, 1);
+ if (device_is_compatible(dev, "marvell,armada-3700-sdhci"))
+ priv->pad_ctrl_reg = (void *)devfdt_get_addr_index(dev, 1);
name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "marvell,pad-type",
NULL);
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 28cedf0c46..0fddb420dc 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -81,9 +81,9 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
struct sdhci_host *host = dev_get_priv(dev);
host->name = dev->name;
- host->ioaddr = (void *)dev_get_addr(dev);
+ host->ioaddr = (void *)devfdt_get_addr(dev);
- plat->f_max = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ plat->f_max = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
return 0;
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c
index e04964b558..fb33cef13f 100644
--- a/drivers/mtd/altera_qspi.c
+++ b/drivers/mtd/altera_qspi.c
@@ -362,7 +362,7 @@ static int altera_qspi_ofdata_to_platdata(struct udevice *dev)
* match with reg-names.
*/
parent = fdt_parent_offset(blob, node);
- of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+ fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
list = fdt_getprop(blob, node, "reg-names", &len);
if (!list)
return -ENOENT;
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index d440f5ccd9..048a51785e 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -2448,7 +2448,7 @@ static int cfi_flash_probe(struct udevice *dev)
int len, idx;
parent = fdt_parent_offset(blob, node);
- of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+ fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
/* decode regs, there may be multiple reg tuples. */
cell = fdt_getprop(blob, node, "reg", &len);
if (!cell)
diff --git a/drivers/mtd/dataflash.c b/drivers/mtd/dataflash.c
index 3fb6ed6df7..2d2c318adf 100644
--- a/drivers/mtd/dataflash.c
+++ b/drivers/mtd/dataflash.c
@@ -49,7 +49,7 @@ int AT91F_DataflashInit (void)
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i].addr;
dataflash_info[i].id = dfcode;
- found[i] += dfcode;;
+ found[i] += dfcode;
break;
case AT45DB081:
@@ -61,7 +61,7 @@ int AT91F_DataflashInit (void)
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i].addr;
dataflash_info[i].id = dfcode;
- found[i] += dfcode;;
+ found[i] += dfcode;
break;
case AT45DB161:
@@ -73,7 +73,7 @@ int AT91F_DataflashInit (void)
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i].addr;
dataflash_info[i].id = dfcode;
- found[i] += dfcode;;
+ found[i] += dfcode;
break;
case AT45DB321:
@@ -85,7 +85,7 @@ int AT91F_DataflashInit (void)
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i].addr;
dataflash_info[i].id = dfcode;
- found[i] += dfcode;;
+ found[i] += dfcode;
break;
case AT45DB642:
@@ -97,7 +97,7 @@ int AT91F_DataflashInit (void)
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i].addr;
dataflash_info[i].id = dfcode;
- found[i] += dfcode;;
+ found[i] += dfcode;
break;
case AT45DB128:
@@ -109,7 +109,7 @@ int AT91F_DataflashInit (void)
dataflash_info[i].Desc.DataFlash_state = IDLE;
dataflash_info[i].logical_address = cs[i].addr;
dataflash_info[i].id = dfcode;
- found[i] += dfcode;;
+ found[i] += dfcode;
break;
default:
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index a7b76f4218..ce8ba99c82 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -33,11 +33,11 @@ config NAND_DENALI_SPARE_AREA_SKIP_BYTES
used to preserve the bad block marker in the OOB area.
config NAND_VF610_NFC
- bool "Support for Freescale NFC for VF610/MPC5125"
+ bool "Support for Freescale NFC for VF610"
select SYS_NAND_SELF_INIT
help
Enables support for NAND Flash Controller on some Freescale
- processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
+ processors like the VF610, MCF54418 or Kinetis K70.
The driver supports a maximum 2k page size. The driver
currently does not support hardware ECC.
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 82358f674b..c3d4a996f3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -53,13 +53,11 @@ obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o
obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o
-obj-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o
obj-$(CONFIG_NAND_MXC) += mxc_nand.o
obj-$(CONFIG_NAND_MXS) += mxs_nand.o
obj-$(CONFIG_NAND_NDFC) += ndfc.o
obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
-obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
obj-$(CONFIG_NAND_SPEAR) += spr_nand.o
obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c
deleted file mode 100644
index 7faabddbf2..0000000000
--- a/drivers/mtd/nand/mpc5121_nfc.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright 2004-2008 Freescale Semiconductor, Inc.
- * Copyright 2009 Semihalf.
- * (C) Copyright 2009 Stefan Roese <sr@denx.de>
- *
- * Based on original driver from Freescale Semiconductor
- * written by John Rigby <jrigby@freescale.com> on basis
- * of drivers/mtd/nand/mxc_nand.c. Reworked and extended
- * Piotr Ziecik <kosmo@semihalf.com>.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <malloc.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/compat.h>
-
-#include <linux/errno.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <nand.h>
-
-#define DRV_NAME "mpc5121_nfc"
-
-/* Timeouts */
-#define NFC_RESET_TIMEOUT 1000 /* 1 ms */
-#define NFC_TIMEOUT 2000 /* 2000 us */
-
-/* Addresses for NFC MAIN RAM BUFFER areas */
-#define NFC_MAIN_AREA(n) ((n) * 0x200)
-
-/* Addresses for NFC SPARE BUFFER areas */
-#define NFC_SPARE_BUFFERS 8
-#define NFC_SPARE_LEN 0x40
-#define NFC_SPARE_AREA(n) (0x1000 + ((n) * NFC_SPARE_LEN))
-
-/* MPC5121 NFC registers */
-#define NFC_BUF_ADDR 0x1E04
-#define NFC_FLASH_ADDR 0x1E06
-#define NFC_FLASH_CMD 0x1E08
-#define NFC_CONFIG 0x1E0A
-#define NFC_ECC_STATUS1 0x1E0C
-#define NFC_ECC_STATUS2 0x1E0E
-#define NFC_SPAS 0x1E10
-#define NFC_WRPROT 0x1E12
-#define NFC_NF_WRPRST 0x1E18
-#define NFC_CONFIG1 0x1E1A
-#define NFC_CONFIG2 0x1E1C
-#define NFC_UNLOCKSTART_BLK0 0x1E20
-#define NFC_UNLOCKEND_BLK0 0x1E22
-#define NFC_UNLOCKSTART_BLK1 0x1E24
-#define NFC_UNLOCKEND_BLK1 0x1E26
-#define NFC_UNLOCKSTART_BLK2 0x1E28
-#define NFC_UNLOCKEND_BLK2 0x1E2A
-#define NFC_UNLOCKSTART_BLK3 0x1E2C
-#define NFC_UNLOCKEND_BLK3 0x1E2E
-
-/* Bit Definitions: NFC_BUF_ADDR */
-#define NFC_RBA_MASK (7 << 0)
-#define NFC_ACTIVE_CS_SHIFT 5
-#define NFC_ACTIVE_CS_MASK (3 << NFC_ACTIVE_CS_SHIFT)
-
-/* Bit Definitions: NFC_CONFIG */
-#define NFC_BLS_UNLOCKED (1 << 1)
-
-/* Bit Definitions: NFC_CONFIG1 */
-#define NFC_ECC_4BIT (1 << 0)
-#define NFC_FULL_PAGE_DMA (1 << 1)
-#define NFC_SPARE_ONLY (1 << 2)
-#define NFC_ECC_ENABLE (1 << 3)
-#define NFC_INT_MASK (1 << 4)
-#define NFC_BIG_ENDIAN (1 << 5)
-#define NFC_RESET (1 << 6)
-#define NFC_CE (1 << 7)
-#define NFC_ONE_CYCLE (1 << 8)
-#define NFC_PPB_32 (0 << 9)
-#define NFC_PPB_64 (1 << 9)
-#define NFC_PPB_128 (2 << 9)
-#define NFC_PPB_256 (3 << 9)
-#define NFC_PPB_MASK (3 << 9)
-#define NFC_FULL_PAGE_INT (1 << 11)
-
-/* Bit Definitions: NFC_CONFIG2 */
-#define NFC_COMMAND (1 << 0)
-#define NFC_ADDRESS (1 << 1)
-#define NFC_INPUT (1 << 2)
-#define NFC_OUTPUT (1 << 3)
-#define NFC_ID (1 << 4)
-#define NFC_STATUS (1 << 5)
-#define NFC_CMD_FAIL (1 << 15)
-#define NFC_INT (1 << 15)
-
-/* Bit Definitions: NFC_WRPROT */
-#define NFC_WPC_LOCK_TIGHT (1 << 0)
-#define NFC_WPC_LOCK (1 << 1)
-#define NFC_WPC_UNLOCK (1 << 2)
-
-struct mpc5121_nfc_prv {
- struct nand_chip chip;
- int irq;
- void __iomem *regs;
- struct clk *clk;
- uint column;
- int spareonly;
- int chipsel;
-};
-
-int mpc5121_nfc_chip = 0;
-
-static void mpc5121_nfc_done(struct mtd_info *mtd);
-
-/* Read NFC register */
-static inline u16 nfc_read(struct mtd_info *mtd, uint reg)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip);
-
- return in_be16(prv->regs + reg);
-}
-
-/* Write NFC register */
-static inline void nfc_write(struct mtd_info *mtd, uint reg, u16 val)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip);
-
- out_be16(prv->regs + reg, val);
-}
-
-/* Set bits in NFC register */
-static inline void nfc_set(struct mtd_info *mtd, uint reg, u16 bits)
-{
- nfc_write(mtd, reg, nfc_read(mtd, reg) | bits);
-}
-
-/* Clear bits in NFC register */
-static inline void nfc_clear(struct mtd_info *mtd, uint reg, u16 bits)
-{
- nfc_write(mtd, reg, nfc_read(mtd, reg) & ~bits);
-}
-
-/* Invoke address cycle */
-static inline void mpc5121_nfc_send_addr(struct mtd_info *mtd, u16 addr)
-{
- nfc_write(mtd, NFC_FLASH_ADDR, addr);
- nfc_write(mtd, NFC_CONFIG2, NFC_ADDRESS);
- mpc5121_nfc_done(mtd);
-}
-
-/* Invoke command cycle */
-static inline void mpc5121_nfc_send_cmd(struct mtd_info *mtd, u16 cmd)
-{
- nfc_write(mtd, NFC_FLASH_CMD, cmd);
- nfc_write(mtd, NFC_CONFIG2, NFC_COMMAND);
- mpc5121_nfc_done(mtd);
-}
-
-/* Send data from NFC buffers to NAND flash */
-static inline void mpc5121_nfc_send_prog_page(struct mtd_info *mtd)
-{
- nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK);
- nfc_write(mtd, NFC_CONFIG2, NFC_INPUT);
- mpc5121_nfc_done(mtd);
-}
-
-/* Receive data from NAND flash */
-static inline void mpc5121_nfc_send_read_page(struct mtd_info *mtd)
-{
- nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK);
- nfc_write(mtd, NFC_CONFIG2, NFC_OUTPUT);
- mpc5121_nfc_done(mtd);
-}
-
-/* Receive ID from NAND flash */
-static inline void mpc5121_nfc_send_read_id(struct mtd_info *mtd)
-{
- nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK);
- nfc_write(mtd, NFC_CONFIG2, NFC_ID);
- mpc5121_nfc_done(mtd);
-}
-
-/* Receive status from NAND flash */
-static inline void mpc5121_nfc_send_read_status(struct mtd_info *mtd)
-{
- nfc_clear(mtd, NFC_BUF_ADDR, NFC_RBA_MASK);
- nfc_write(mtd, NFC_CONFIG2, NFC_STATUS);
- mpc5121_nfc_done(mtd);
-}
-
-static void mpc5121_nfc_done(struct mtd_info *mtd)
-{
- int max_retries = NFC_TIMEOUT;
-
- while (1) {
- max_retries--;
- if (nfc_read(mtd, NFC_CONFIG2) & NFC_INT)
- break;
- udelay(1);
- }
-
- if (max_retries <= 0)
- printk(KERN_WARNING DRV_NAME
- ": Timeout while waiting for completion.\n");
-}
-
-/* Do address cycle(s) */
-static void mpc5121_nfc_addr_cycle(struct mtd_info *mtd, int column, int page)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- u32 pagemask = chip->pagemask;
-
- if (column != -1) {
- mpc5121_nfc_send_addr(mtd, column);
- if (mtd->writesize > 512)
- mpc5121_nfc_send_addr(mtd, column >> 8);
- }
-
- if (page != -1) {
- do {
- mpc5121_nfc_send_addr(mtd, page & 0xFF);
- page >>= 8;
- pagemask >>= 8;
- } while (pagemask);
- }
-}
-
-/* Control chip select signals */
-
-/*
- * Selecting the active device:
- *
- * This is different than the linux version. Switching between chips
- * is done via board_nand_select_device(). The Linux select_chip
- * function used here in U-Boot has only 2 valid chip numbers:
- * 0 select
- * -1 deselect
- */
-
-/*
- * Implement it as a weak default, so that boards with a specific
- * chip-select routine can use their own function.
- */
-void __mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip)
-{
- if (chip < 0) {
- nfc_clear(mtd, NFC_CONFIG1, NFC_CE);
- return;
- }
-
- nfc_clear(mtd, NFC_BUF_ADDR, NFC_ACTIVE_CS_MASK);
- nfc_set(mtd, NFC_BUF_ADDR, (chip << NFC_ACTIVE_CS_SHIFT) &
- NFC_ACTIVE_CS_MASK);
- nfc_set(mtd, NFC_CONFIG1, NFC_CE);
-}
-void mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip)
- __attribute__((weak, alias("__mpc5121_nfc_select_chip")));
-
-void board_nand_select_device(struct nand_chip *nand, int chip)
-{
- /*
- * Only save this chip number in global variable here. This
- * will be used later in mpc5121_nfc_select_chip().
- */
- mpc5121_nfc_chip = chip;
-}
-
-/* Read NAND Ready/Busy signal */
-static int mpc5121_nfc_dev_ready(struct mtd_info *mtd)
-{
- /*
- * NFC handles ready/busy signal internally. Therefore, this function
- * always returns status as ready.
- */
- return 1;
-}
-
-/* Write command to NAND flash */
-static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command,
- int column, int page)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip);
-
- prv->column = (column >= 0) ? column : 0;
- prv->spareonly = 0;
-
- switch (command) {
- case NAND_CMD_PAGEPROG:
- mpc5121_nfc_send_prog_page(mtd);
- break;
- /*
- * NFC does not support sub-page reads and writes,
- * so emulate them using full page transfers.
- */
- case NAND_CMD_READ0:
- column = 0;
- break;
-
- case NAND_CMD_READ1:
- prv->column += 256;
- command = NAND_CMD_READ0;
- column = 0;
- break;
-
- case NAND_CMD_READOOB:
- prv->spareonly = 1;
- command = NAND_CMD_READ0;
- column = 0;
- break;
-
- case NAND_CMD_SEQIN:
- mpc5121_nfc_command(mtd, NAND_CMD_READ0, column, page);
- column = 0;
- break;
-
- case NAND_CMD_ERASE1:
- case NAND_CMD_ERASE2:
- case NAND_CMD_READID:
- case NAND_CMD_STATUS:
- case NAND_CMD_RESET:
- break;
-
- default:
- return;
- }
-
- mpc5121_nfc_send_cmd(mtd, command);
- mpc5121_nfc_addr_cycle(mtd, column, page);
-
- switch (command) {
- case NAND_CMD_READ0:
- if (mtd->writesize > 512)
- mpc5121_nfc_send_cmd(mtd, NAND_CMD_READSTART);
- mpc5121_nfc_send_read_page(mtd);
- break;
-
- case NAND_CMD_READID:
- mpc5121_nfc_send_read_id(mtd);
- break;
-
- case NAND_CMD_STATUS:
- mpc5121_nfc_send_read_status(mtd);
- if (chip->options & NAND_BUSWIDTH_16)
- prv->column = 1;
- else
- prv->column = 0;
- break;
- }
-}
-
-/* Copy data from/to NFC spare buffers. */
-static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset,
- u8 * buffer, uint size, int wr)
-{
- struct nand_chip *nand = mtd_to_nand(mtd);
- struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand);
- uint o, s, sbsize, blksize;
-
- /*
- * NAND spare area is available through NFC spare buffers.
- * The NFC divides spare area into (page_size / 512) chunks.
- * Each chunk is placed into separate spare memory area, using
- * first (spare_size / num_of_chunks) bytes of the buffer.
- *
- * For NAND device in which the spare area is not divided fully
- * by the number of chunks, number of used bytes in each spare
- * buffer is rounded down to the nearest even number of bytes,
- * and all remaining bytes are added to the last used spare area.
- *
- * For more information read section 26.6.10 of MPC5121e
- * Microcontroller Reference Manual, Rev. 3.
- */
-
- /* Calculate number of valid bytes in each spare buffer */
- sbsize = (mtd->oobsize / (mtd->writesize / 512)) & ~1;
-
- while (size) {
- /* Calculate spare buffer number */
- s = offset / sbsize;
- if (s > NFC_SPARE_BUFFERS - 1)
- s = NFC_SPARE_BUFFERS - 1;
-
- /*
- * Calculate offset to requested data block in selected spare
- * buffer and its size.
- */
- o = offset - (s * sbsize);
- blksize = min(sbsize - o, size);
-
- if (wr)
- memcpy_toio(prv->regs + NFC_SPARE_AREA(s) + o,
- buffer, blksize);
- else
- memcpy_fromio(buffer,
- prv->regs + NFC_SPARE_AREA(s) + o,
- blksize);
-
- buffer += blksize;
- offset += blksize;
- size -= blksize;
- };
-}
-
-/* Copy data from/to NFC main and spare buffers */
-static void mpc5121_nfc_buf_copy(struct mtd_info *mtd, u_char * buf, int len,
- int wr)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip);
- uint c = prv->column;
- uint l;
-
- /* Handle spare area access */
- if (prv->spareonly || c >= mtd->writesize) {
- /* Calculate offset from beginning of spare area */
- if (c >= mtd->writesize)
- c -= mtd->writesize;
-
- prv->column += len;
- mpc5121_nfc_copy_spare(mtd, c, buf, len, wr);
- return;
- }
-
- /*
- * Handle main area access - limit copy length to prevent
- * crossing main/spare boundary.
- */
- l = min((uint) len, mtd->writesize - c);
- prv->column += l;
-
- if (wr)
- memcpy_toio(prv->regs + NFC_MAIN_AREA(0) + c, buf, l);
- else
- memcpy_fromio(buf, prv->regs + NFC_MAIN_AREA(0) + c, l);
-
- /* Handle crossing main/spare boundary */
- if (l != len) {
- buf += l;
- len -= l;
- mpc5121_nfc_buf_copy(mtd, buf, len, wr);
- }
-}
-
-/* Read data from NFC buffers */
-static void mpc5121_nfc_read_buf(struct mtd_info *mtd, u_char * buf, int len)
-{
- mpc5121_nfc_buf_copy(mtd, buf, len, 0);
-}
-
-/* Write data to NFC buffers */
-static void mpc5121_nfc_write_buf(struct mtd_info *mtd,
- const u_char * buf, int len)
-{
- mpc5121_nfc_buf_copy(mtd, (u_char *) buf, len, 1);
-}
-
-/* Read byte from NFC buffers */
-static u8 mpc5121_nfc_read_byte(struct mtd_info *mtd)
-{
- u8 tmp;
-
- mpc5121_nfc_read_buf(mtd, &tmp, sizeof(tmp));
-
- return tmp;
-}
-
-/* Read word from NFC buffers */
-static u16 mpc5121_nfc_read_word(struct mtd_info *mtd)
-{
- u16 tmp;
-
- mpc5121_nfc_read_buf(mtd, (u_char *) & tmp, sizeof(tmp));
-
- return tmp;
-}
-
-/*
- * Read NFC configuration from Reset Config Word
- *
- * NFC is configured during reset in basis of information stored
- * in Reset Config Word. There is no other way to set NAND block
- * size, spare size and bus width.
- */
-static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd)
-{
- immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
- struct nand_chip *chip = mtd_to_nand(mtd);
- uint rcw_pagesize = 0;
- uint rcw_sparesize = 0;
- uint rcw_width;
- uint rcwh;
- uint romloc, ps;
-
- rcwh = in_be32(&(im->reset.rcwh));
-
- /* Bit 6: NFC bus width */
- rcw_width = ((rcwh >> 6) & 0x1) ? 2 : 1;
-
- /* Bit 7: NFC Page/Spare size */
- ps = (rcwh >> 7) & 0x1;
-
- /* Bits [22:21]: ROM Location */
- romloc = (rcwh >> 21) & 0x3;
-
- /* Decode RCW bits */
- switch ((ps << 2) | romloc) {
- case 0x00:
- case 0x01:
- rcw_pagesize = 512;
- rcw_sparesize = 16;
- break;
- case 0x02:
- case 0x03:
- rcw_pagesize = 4096;
- rcw_sparesize = 128;
- break;
- case 0x04:
- case 0x05:
- rcw_pagesize = 2048;
- rcw_sparesize = 64;
- break;
- case 0x06:
- case 0x07:
- rcw_pagesize = 4096;
- rcw_sparesize = 218;
- break;
- }
-
- mtd->writesize = rcw_pagesize;
- mtd->oobsize = rcw_sparesize;
- if (rcw_width == 2)
- chip->options |= NAND_BUSWIDTH_16;
-
- debug(KERN_NOTICE DRV_NAME ": Configured for "
- "%u-bit NAND, page size %u with %u spare.\n",
- rcw_width * 8, rcw_pagesize, rcw_sparesize);
- return 0;
-}
-
-int board_nand_init(struct nand_chip *chip)
-{
- struct mpc5121_nfc_prv *prv;
- struct mtd_info *mtd;
- int resettime = 0;
- int retval = 0;
- int rev;
-
- /*
- * Check SoC revision. This driver supports only NFC
- * in MPC5121 revision 2.
- */
- rev = (mfspr(SPRN_SVR) >> 4) & 0xF;
- if (rev != 2) {
- printk(KERN_ERR DRV_NAME
- ": SoC revision %u is not supported!\n", rev);
- return -ENXIO;
- }
-
- prv = malloc(sizeof(*prv));
- if (!prv) {
- printk(KERN_ERR DRV_NAME ": Memory exhausted!\n");
- return -ENOMEM;
- }
-
- mtd = &chip->mtd;
- nand_set_controller_data(chip, prv);
-
- /* Read NFC configuration from Reset Config Word */
- retval = mpc5121_nfc_read_hw_config(mtd);
- if (retval) {
- printk(KERN_ERR DRV_NAME ": Unable to read NFC config!\n");
- return retval;
- }
-
- prv->regs = (void __iomem *)CONFIG_SYS_NAND_BASE;
- chip->dev_ready = mpc5121_nfc_dev_ready;
- chip->cmdfunc = mpc5121_nfc_command;
- chip->read_byte = mpc5121_nfc_read_byte;
- chip->read_word = mpc5121_nfc_read_word;
- chip->read_buf = mpc5121_nfc_read_buf;
- chip->write_buf = mpc5121_nfc_write_buf;
- chip->select_chip = mpc5121_nfc_select_chip;
- chip->bbt_options = NAND_BBT_USE_FLASH;
- chip->ecc.mode = NAND_ECC_SOFT;
-
- /* Reset NAND Flash controller */
- nfc_set(mtd, NFC_CONFIG1, NFC_RESET);
- while (nfc_read(mtd, NFC_CONFIG1) & NFC_RESET) {
- if (resettime++ >= NFC_RESET_TIMEOUT) {
- printk(KERN_ERR DRV_NAME
- ": Timeout while resetting NFC!\n");
- retval = -EINVAL;
- goto error;
- }
-
- udelay(1);
- }
-
- /* Enable write to NFC memory */
- nfc_write(mtd, NFC_CONFIG, NFC_BLS_UNLOCKED);
-
- /* Enable write to all NAND pages */
- nfc_write(mtd, NFC_UNLOCKSTART_BLK0, 0x0000);
- nfc_write(mtd, NFC_UNLOCKEND_BLK0, 0xFFFF);
- nfc_write(mtd, NFC_WRPROT, NFC_WPC_UNLOCK);
-
- /*
- * Setup NFC:
- * - Big Endian transfers,
- * - Interrupt after full page read/write.
- */
- nfc_write(mtd, NFC_CONFIG1, NFC_BIG_ENDIAN | NFC_INT_MASK |
- NFC_FULL_PAGE_INT);
-
- /* Set spare area size */
- nfc_write(mtd, NFC_SPAS, mtd->oobsize >> 1);
-
- /* Detect NAND chips */
- if (nand_scan(mtd, 1)) {
- printk(KERN_ERR DRV_NAME ": NAND Flash not found !\n");
- retval = -ENXIO;
- goto error;
- }
-
- /* Set erase block size */
- switch (mtd->erasesize / mtd->writesize) {
- case 32:
- nfc_set(mtd, NFC_CONFIG1, NFC_PPB_32);
- break;
-
- case 64:
- nfc_set(mtd, NFC_CONFIG1, NFC_PPB_64);
- break;
-
- case 128:
- nfc_set(mtd, NFC_CONFIG1, NFC_PPB_128);
- break;
-
- case 256:
- nfc_set(mtd, NFC_CONFIG1, NFC_PPB_256);
- break;
-
- default:
- printk(KERN_ERR DRV_NAME ": Unsupported NAND flash!\n");
- retval = -ENXIO;
- goto error;
- }
-
- return 0;
-error:
- return retval;
-}
diff --git a/drivers/mtd/nand/s3c2410_nand.c b/drivers/mtd/nand/s3c2410_nand.c
deleted file mode 100644
index dd742a6351..0000000000
--- a/drivers/mtd/nand/s3c2410_nand.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * (C) Copyright 2006 OpenMoko, Inc.
- * Author: Harald Welte <laforge@openmoko.org>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-
-#include <nand.h>
-#include <asm/arch/s3c24x0_cpu.h>
-#include <asm/io.h>
-
-#define S3C2410_NFCONF_EN (1<<15)
-#define S3C2410_NFCONF_512BYTE (1<<14)
-#define S3C2410_NFCONF_4STEP (1<<13)
-#define S3C2410_NFCONF_INITECC (1<<12)
-#define S3C2410_NFCONF_nFCE (1<<11)
-#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
-#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
-#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
-
-#define S3C2410_ADDR_NALE 4
-#define S3C2410_ADDR_NCLE 8
-
-#ifdef CONFIG_NAND_SPL
-
-/* in the early stage of NAND flash booting, printf() is not available */
-#define printf(fmt, args...)
-
-static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
- int i;
- struct nand_chip *this = mtd_to_nand(mtd);
-
- for (i = 0; i < len; i++)
- buf[i] = readb(this->IO_ADDR_R);
-}
-#endif
-
-static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
-
- debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
-
- if (ctrl & NAND_CTRL_CHANGE) {
- ulong IO_ADDR_W = (ulong)nand;
-
- if (!(ctrl & NAND_CLE))
- IO_ADDR_W |= S3C2410_ADDR_NCLE;
- if (!(ctrl & NAND_ALE))
- IO_ADDR_W |= S3C2410_ADDR_NALE;
-
- chip->IO_ADDR_W = (void *)IO_ADDR_W;
-
- if (ctrl & NAND_NCE)
- writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
- &nand->nfconf);
- else
- writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,
- &nand->nfconf);
- }
-
- if (cmd != NAND_CMD_NONE)
- writeb(cmd, chip->IO_ADDR_W);
-}
-
-static int s3c24x0_dev_ready(struct mtd_info *mtd)
-{
- struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
- debug("dev_ready\n");
- return readl(&nand->nfstat) & 0x01;
-}
-
-#ifdef CONFIG_S3C2410_NAND_HWECC
-void s3c24x0_nand_enable_hwecc(struct mtd_info *mtd, int mode)
-{
- struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
- debug("s3c24x0_nand_enable_hwecc(%p, %d)\n", mtd, mode);
- writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf);
-}
-
-static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
- u_char *ecc_code)
-{
- struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
- ecc_code[0] = readb(&nand->nfecc);
- ecc_code[1] = readb(&nand->nfecc + 1);
- ecc_code[2] = readb(&nand->nfecc + 2);
- debug("s3c24x0_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
- mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
-
- return 0;
-}
-
-static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat,
- u_char *read_ecc, u_char *calc_ecc)
-{
- if (read_ecc[0] == calc_ecc[0] &&
- read_ecc[1] == calc_ecc[1] &&
- read_ecc[2] == calc_ecc[2])
- return 0;
-
- printf("s3c24x0_nand_correct_data: not implemented\n");
- return -EBADMSG;
-}
-#endif
-
-int board_nand_init(struct nand_chip *nand)
-{
- u_int32_t cfg;
- u_int8_t tacls, twrph0, twrph1;
- struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
- struct s3c24x0_nand *nand_reg = s3c24x0_get_base_nand();
-
- debug("board_nand_init()\n");
-
- writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
-
- /* initialize hardware */
-#if defined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING)
- tacls = CONFIG_S3C24XX_TACLS;
- twrph0 = CONFIG_S3C24XX_TWRPH0;
- twrph1 = CONFIG_S3C24XX_TWRPH1;
-#else
- tacls = 4;
- twrph0 = 8;
- twrph1 = 8;
-#endif
-
- cfg = S3C2410_NFCONF_EN;
- cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
- cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
- cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
- writel(cfg, &nand_reg->nfconf);
-
- /* initialize nand_chip data structure */
- nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
- nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
-
- nand->select_chip = NULL;
-
- /* read_buf and write_buf are default */
- /* read_byte and write_byte are default */
-#ifdef CONFIG_NAND_SPL
- nand->read_buf = nand_read_buf;
-#endif
-
- /* hwcontrol always must be implemented */
- nand->cmd_ctrl = s3c24x0_hwcontrol;
-
- nand->dev_ready = s3c24x0_dev_ready;
-
-#ifdef CONFIG_S3C2410_NAND_HWECC
- nand->ecc.hwctl = s3c24x0_nand_enable_hwecc;
- nand->ecc.calculate = s3c24x0_nand_calculate_ecc;
- nand->ecc.correct = s3c24x0_nand_correct_data;
- nand->ecc.mode = NAND_ECC_HW;
- nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
- nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
- nand->ecc.strength = 1;
-#else
- nand->ecc.mode = NAND_ECC_SOFT;
-#endif
-
-#ifdef CONFIG_S3C2410_NAND_BBT
- nand->bbt_options |= NAND_BBT_USE_FLASH;
-#endif
-
- debug("end of nand_init\n");
-
- return 0;
-}
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index c4e2cd7f55..8bc3828854 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1663,7 +1663,7 @@ static int sunxi_nand_chip_init(int node, struct sunxi_nfc *nfc, int devnum)
chip->sels[i].rb.type = RB_NATIVE;
chip->sels[i].rb.info.nativeid = tmp;
} else {
- ret = gpio_request_by_name_nodev(blob, node,
+ ret = gpio_request_by_name_nodev(offset_to_ofnode(node),
"rb-gpios", i,
&chip->sels[i].rb.info.gpio,
GPIOD_IS_IN);
diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c
index 5c9b485b08..c03c9cb178 100644
--- a/drivers/mtd/nand/tegra_nand.c
+++ b/drivers/mtd/nand/tegra_nand.c
@@ -894,8 +894,8 @@ static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config)
config->reg = (struct nand_ctlr *)fdtdec_get_addr(blob, node, "reg");
config->enabled = fdtdec_get_is_enabled(blob, node);
config->width = fdtdec_get_int(blob, node, "nvidia,nand-width", 8);
- err = gpio_request_by_name_nodev(blob, node, "nvidia,wp-gpios", 0,
- &config->wp_gpio, GPIOD_IS_OUT);
+ err = gpio_request_by_name_nodev(offset_to_ofnode(node),
+ "nvidia,wp-gpios", 0, &config->wp_gpio, GPIOD_IS_OUT);
if (err)
return err;
err = fdtdec_get_int_array(blob, node, "nvidia,timing",
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 2e3d0e5c9a..8282f683a5 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1919,6 +1919,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
*/
int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
{
+ struct onenand_chip *this = mtd->priv;
int ret;
ret = onenand_block_isbad(mtd, ofs);
@@ -1929,7 +1930,10 @@ int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
return ret;
}
- ret = mtd_block_markbad(mtd, ofs);
+ onenand_get_device(mtd, FL_WRITING);
+ ret = this->block_markbad(mtd, ofs);
+ onenand_release_device(mtd);
+
return ret;
}
diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c
index 1925f41d8a..0b78067a23 100644
--- a/drivers/mtd/onenand/onenand_spl.c
+++ b/drivers/mtd/onenand/onenand_spl.c
@@ -23,11 +23,29 @@ enum onenand_spl_pagesize {
PAGE_4K = 4096,
};
+static unsigned int density_mask;
+
#define ONENAND_PAGES_PER_BLOCK 64
-#define onenand_block_address(block) (block)
#define onenand_sector_address(page) (page << 2)
#define onenand_buffer_address() ((1 << 3) << 8)
-#define onenand_bufferram_address(block) (0)
+
+static inline int onenand_block_address(int block)
+{
+ /* Device Flash Core select, NAND Flash Block Address */
+ if (block & density_mask)
+ return ONENAND_DDP_CHIP1 | (block ^ density_mask);
+
+ return block;
+}
+
+static inline int onenand_bufferram_address(int block)
+{
+ /* Device BufferRAM Select */
+ if (block & density_mask)
+ return ONENAND_DDP_CHIP1;
+
+ return ONENAND_DDP_CHIP0;
+}
static inline uint16_t onenand_readw(uint32_t addr)
{
@@ -41,7 +59,7 @@ static inline void onenand_writew(uint16_t value, uint32_t addr)
static enum onenand_spl_pagesize onenand_spl_get_geometry(void)
{
- uint32_t dev_id, density;
+ unsigned int dev_id, density, size;
if (!onenand_readw(ONENAND_REG_TECHNOLOGY)) {
dev_id = onenand_readw(ONENAND_REG_DEVICE_ID);
@@ -51,8 +69,11 @@ static enum onenand_spl_pagesize onenand_spl_get_geometry(void)
if (density < ONENAND_DEVICE_DENSITY_4Gb)
return PAGE_2K;
- if (dev_id & ONENAND_DEVICE_IS_DDP)
+ if (dev_id & ONENAND_DEVICE_IS_DDP) {
+ size = onenand_readw(ONENAND_REG_DATA_BUFFER_SIZE);
+ density_mask = 1 << (18 + density - ffs(size));
return PAGE_2K;
+ }
}
return PAGE_4K;
@@ -110,9 +131,12 @@ static u8 scratch_buf[PAGE_4K];
*/
int onenand_spl_read_block(int block, int offset, int len, void *dst)
{
- int page, read, psize;
+ int page, read;
+ static int psize;
+
+ if (!psize)
+ psize = onenand_spl_get_geometry();
- psize = onenand_spl_get_geometry();
/* Calculate the page number */
page = offset / psize;
/* Offset to the start of a flash page */
diff --git a/drivers/mtd/pic32_flash.c b/drivers/mtd/pic32_flash.c
index 8ed7874cc9..e1a8d3bc4b 100644
--- a/drivers/mtd/pic32_flash.c
+++ b/drivers/mtd/pic32_flash.c
@@ -384,7 +384,7 @@ static int pic32_flash_probe(struct udevice *dev)
* match with reg-names.
*/
parent = fdt_parent_offset(blob, node);
- of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+ fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
list = fdt_getprop(blob, node, "reg-names", &len);
if (!list)
return -ENOENT;
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 5ca0a712d8..5700859ff2 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -42,6 +42,13 @@ config SPI_FLASH_BAR
Bank/Extended address registers are used to access the flash
which has size > 16MiB in 3-byte addressing.
+config SF_DUAL_FLASH
+ bool "SPI DUAL flash memory support"
+ depends on SPI_FLASH
+ help
+ Enable this option to support two flash memories connected to a single
+ controller. Currently Xilinx Zynq qspi supports this.
+
if SPI_FLASH
config SPI_FLASH_ATMEL
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index a53f4ebc68..1ba6815232 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -515,11 +515,9 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen,
int sandbox_sf_ofdata_to_platdata(struct udevice *dev)
{
struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
- const void *blob = gd->fdt_blob;
- int node = dev_of_offset(dev);
- pdata->filename = fdt_getprop(blob, node, "sandbox,filename", NULL);
- pdata->device_name = fdt_getprop(blob, node, "compatible", NULL);
+ pdata->filename = dev_read_string(dev, "sandbox,filename");
+ pdata->device_name = dev_read_string(dev, "compatible");
if (!pdata->filename || !pdata->device_name) {
debug("%s: Missing properties, filename=%s, device_name=%s\n",
__func__, pdata->filename, pdata->device_name);
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index ab7910bc14..0034a28d5f 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -914,14 +914,13 @@ static int set_quad_mode(struct spi_flash *flash,
}
#if CONFIG_IS_ENABLED(OF_CONTROL)
-int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
+int spi_flash_decode_fdt(struct spi_flash *flash)
{
#ifdef CONFIG_DM_SPI_FLASH
fdt_addr_t addr;
fdt_size_t size;
- int node = dev_of_offset(flash->dev);
- addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
+ addr = dev_read_addr_size(flash->dev, "memory-map", &size);
if (addr == FDT_ADDR_T_NONE) {
debug("%s: Cannot decode address\n", __func__);
return 0;
@@ -1081,7 +1080,7 @@ int spi_flash_scan(struct spi_flash *flash)
#endif
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
- ret = spi_flash_decode_fdt(gd->fdt_blob, flash);
+ ret = spi_flash_decode_fdt(flash);
if (ret) {
debug("SF: FDT decode error\n");
return -EINVAL;
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index ca1139676b..e759339a5f 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -67,7 +67,6 @@
#include <asm/io.h>
#include <asm/cache.h>
#include <asm/mmu.h>
-#include <commproc.h>
#include <asm/ppc4xx.h>
#include <asm/ppc4xx-emac.h>
#include <asm/ppc4xx-mal.h>
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index d49bf572f8..33634c33d4 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -22,6 +22,13 @@ menuconfig NETDEVICES
if NETDEVICES
+config PHY_GIGE
+ bool "Enable GbE PHY status parsing and configuration"
+ help
+ Enables support for parsing the status output and for
+ configuring GbE PHYs (affects the inner workings of some
+ commands and miiphyutil.c).
+
config AG7XXX
bool "Atheros AG7xxx Ethernet MAC support"
depends on DM_ETH && ARCH_ATH79
@@ -187,6 +194,7 @@ config SUN8I_EMAC
bool "Allwinner Sun8i Ethernet MAC support"
depends on DM_ETH
select PHYLIB
+ select PHY_GIGE
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
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0aaac6bd81..03ed224cea 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -39,8 +39,6 @@ obj-$(CONFIG_LAN91C96) += lan91c96.o
obj-$(CONFIG_LPC32XX_ETH) += lpc32xx_eth.o
obj-$(CONFIG_MACB) += macb.o
obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
-obj-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
-obj-$(CONFIG_MPC512x_FEC) += mpc512x_fec.o
obj-$(CONFIG_MVGBE) += mvgbe.o
obj-$(CONFIG_MVNETA) += mvneta.o
obj-$(CONFIG_MVPP2) += mvpp2.o
diff --git a/drivers/net/ag7xxx.c b/drivers/net/ag7xxx.c
index f8782bcbd0..cf60d11475 100644
--- a/drivers/net/ag7xxx.c
+++ b/drivers/net/ag7xxx.c
@@ -941,7 +941,7 @@ static int ag7xxx_eth_ofdata_to_platdata(struct udevice *dev)
const char *phy_mode;
int ret;
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
pdata->phy_interface = -1;
/* Decoding of convoluted PHY wiring on Atheros MIPS. */
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index d4d17dd222..fb878d4e63 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -595,7 +595,7 @@ static int altera_tse_probe(struct udevice *dev)
* match with reg-names.
*/
parent = fdt_parent_offset(blob, node);
- of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+ fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
list = fdt_getprop(blob, node, "reg-names", &len);
if (!list)
return -ENOENT;
diff --git a/drivers/net/cpsw-common.c b/drivers/net/cpsw-common.c
index 55f56d9555..8970ee00af 100644
--- a/drivers/net/cpsw-common.c
+++ b/drivers/net/cpsw-common.c
@@ -104,10 +104,10 @@ int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr)
if (of_machine_is_compatible("ti,am33xx"))
return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
- if (of_device_is_compatible(dev, "ti,am3517-emac"))
+ if (device_is_compatible(dev, "ti,am3517-emac"))
return davinci_emac_3517_get_macid(dev, 0x110, slave, mac_addr);
- if (of_device_is_compatible(dev, "ti,dm816-emac"))
+ if (device_is_compatible(dev, "ti,dm816-emac"))
return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr);
if (of_machine_is_compatible("ti,am43"))
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 5fbab9e492..d7db0fc432 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -612,21 +612,25 @@ static void cpsw_set_slave_mac(struct cpsw_slave *slave,
#endif
}
-static void cpsw_slave_update_link(struct cpsw_slave *slave,
+static int cpsw_slave_update_link(struct cpsw_slave *slave,
struct cpsw_priv *priv, int *link)
{
struct phy_device *phy;
u32 mac_control = 0;
+ int ret = -ENODEV;
phy = priv->phydev;
-
if (!phy)
- return;
+ goto out;
+
+ ret = phy_startup(phy);
+ if (ret)
+ goto out;
- phy_startup(phy);
- *link = phy->link;
+ if (link)
+ *link = phy->link;
- if (*link) { /* link up */
+ if (phy->link) { /* link up */
mac_control = priv->data.mac_control;
if (phy->speed == 1000)
mac_control |= GIGABITEN;
@@ -637,7 +641,7 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
}
if (mac_control == slave->mac_control)
- return;
+ goto out;
if (mac_control) {
printf("link up on port %d, speed %d, %s duplex\n",
@@ -649,17 +653,20 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
__raw_writel(mac_control, &slave->sliver->mac_control);
slave->mac_control = mac_control;
+
+out:
+ return ret;
}
static int cpsw_update_link(struct cpsw_priv *priv)
{
- int link = 0;
+ int ret = -ENODEV;
struct cpsw_slave *slave;
for_active_slave(slave, priv)
- cpsw_slave_update_link(slave, priv, &link);
+ ret = cpsw_slave_update_link(slave, priv, NULL);
- return link;
+ return ret;
}
static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
@@ -822,7 +829,9 @@ static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
for_active_slave(slave, priv)
cpsw_slave_init(slave, priv);
- cpsw_update_link(priv);
+ ret = cpsw_update_link(priv);
+ if (ret)
+ goto out;
/* init descriptor pool */
for (i = 0; i < NUM_DESCS; i++) {
@@ -897,7 +906,8 @@ static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
}
}
- return 0;
+out:
+ return ret;
}
static void _cpsw_halt(struct cpsw_priv *priv)
@@ -1293,7 +1303,7 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
int num_mode_gpios;
int ret;
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
priv->data.version = CPSW_CTRL_VERSION_2;
priv->data.bd_ram_ofs = CPSW_BD_OFFSET;
priv->data.ale_reg_ofs = CPSW_ALE_OFFSET;
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index f9fb8e0886..e8569e6fef 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -18,6 +18,7 @@
#include <linux/compiler.h>
#include <linux/err.h>
#include <asm/io.h>
+#include <power/regulator.h>
#include "designware.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -661,6 +662,22 @@ int designware_eth_probe(struct udevice *dev)
ulong ioaddr;
int ret;
+#if defined(CONFIG_DM_REGULATOR)
+ struct udevice *phy_supply;
+
+ ret = device_get_supply_regulator(dev, "phy-supply",
+ &phy_supply);
+ if (ret) {
+ debug("%s: No phy supply\n", dev->name);
+ } else {
+ ret = regulator_set_enable(phy_supply, true);
+ if (ret) {
+ puts("Error enabling phy supply\n");
+ return ret;
+ }
+ }
+#endif
+
#ifdef CONFIG_DM_PCI
/*
* If we are on PCI bus, either directly attached to a PCI root port,
@@ -726,7 +743,7 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev)
#endif
int ret = 0;
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
pdata->phy_interface = -1;
phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
NULL);
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 81eeba2e05..5c4315ffea 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1452,9 +1452,9 @@ static int eqos_probe(struct udevice *dev)
eqos->dev = dev;
eqos->config = (void *)dev_get_driver_data(dev);
- eqos->regs = dev_get_addr(dev);
+ eqos->regs = devfdt_get_addr(dev);
if (eqos->regs == FDT_ADDR_T_NONE) {
- error("dev_get_addr() failed");
+ error("devfdt_get_addr() failed");
return -ENODEV;
}
eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE);
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index ad8c462a60..a6df950081 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -11,7 +11,7 @@
*/
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/platform_data/net_ethoc.h>
#include <linux/io.h>
#include <malloc.h>
@@ -689,8 +689,8 @@ static int ethoc_ofdata_to_platdata(struct udevice *dev)
struct ethoc_eth_pdata *pdata = dev_get_platdata(dev);
fdt_addr_t addr;
- pdata->eth_pdata.iobase = dev_get_addr(dev);
- addr = dev_get_addr_index(dev, 1);
+ pdata->eth_pdata.iobase = devfdt_get_addr(dev);
+ addr = devfdt_get_addr_index(dev, 1);
if (addr != FDT_ADDR_T_NONE)
pdata->packet_base = addr;
return 0;
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 08bea8b052..6840908fb2 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -1279,7 +1279,7 @@ static int fecmxc_ofdata_to_platdata(struct udevice *dev)
struct fec_priv *priv = dev_get_priv(dev);
const char *phy_mode;
- pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+ pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
priv->eth = (struct ethernet_regs *)pdata->iobase;
pdata->phy_interface = -1;
diff --git a/drivers/net/fm/ls1043.c b/drivers/net/fm/ls1043.c
index 93ba318bf5..6bb6a71470 100644
--- a/drivers/net/fm/ls1043.c
+++ b/drivers/net/fm/ls1043.c
@@ -66,12 +66,12 @@ phy_interface_t fman_port_enet_if(enum fm_port port)
if (port == FM1_DTSEC3)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC1) ==
FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII) {
- return PHY_INTERFACE_MODE_RGMII;
+ return PHY_INTERFACE_MODE_RGMII_TXID;
}
if (port == FM1_DTSEC4)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC2) ==
FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII) {
- return PHY_INTERFACE_MODE_RGMII;
+ return PHY_INTERFACE_MODE_RGMII_TXID;
}
/* handle SGMII */
diff --git a/drivers/net/fm/ls1046.c b/drivers/net/fm/ls1046.c
index bf555548b7..6c91fb97f4 100644
--- a/drivers/net/fm/ls1046.c
+++ b/drivers/net/fm/ls1046.c
@@ -72,12 +72,12 @@ phy_interface_t fman_port_enet_if(enum fm_port port)
if (port == FM1_DTSEC3)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC1) ==
FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII)
- return PHY_INTERFACE_MODE_RGMII;
+ return PHY_INTERFACE_MODE_RGMII_TXID;
if (port == FM1_DTSEC4)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC2) ==
FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII)
- return PHY_INTERFACE_MODE_RGMII;
+ return PHY_INTERFACE_MODE_RGMII_TXID;
/* handle SGMII, only MAC 2/5/6/9/10 available */
switch (port) {
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c
index 86dc13d70d..6e31244f20 100644
--- a/drivers/net/fsl-mc/dpio/qbman_portal.c
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm/arch/clock.h>
#include "qbman_portal.h"
/* QBMan portal management command codes */
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 0a74e3e42e..8bf25c7040 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -27,6 +27,7 @@
#define MC_MEM_SIZE_ENV_VAR "mcmemsize"
#define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout"
+#define MC_BOOT_ENV_VAR "mcinitcmd"
DECLARE_GLOBAL_DATA_PTR;
static int mc_boot_status = -1;
@@ -155,19 +156,142 @@ int parse_mc_firmware_fit_image(u64 mc_fw_addr,
}
#endif
-static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id,
- struct eth_device *eth_dev)
+#define MC_DT_INCREASE_SIZE 64
+
+enum mc_fixup_type {
+ MC_FIXUP_DPL,
+ MC_FIXUP_DPC
+};
+
+static int mc_fixup_mac_addr(void *blob, int nodeoffset,
+ const char *propname, struct eth_device *eth_dev,
+ enum mc_fixup_type type)
{
- int nodeoffset, err = 0;
+ int err = 0, len = 0, size, i;
+ unsigned char env_enetaddr[ARP_HLEN];
+ unsigned int enetaddr_32[ARP_HLEN];
+ void *val = NULL;
+
+ switch (type) {
+ case MC_FIXUP_DPL:
+ /* DPL likes its addresses on 32 * ARP_HLEN bits */
+ for (i = 0; i < ARP_HLEN; i++)
+ enetaddr_32[i] = cpu_to_fdt32(eth_dev->enetaddr[i]);
+ val = enetaddr_32;
+ len = sizeof(enetaddr_32);
+ break;
+
+ case MC_FIXUP_DPC:
+ val = eth_dev->enetaddr;
+ len = ARP_HLEN;
+ break;
+ }
+
+ /* MAC address property present */
+ if (fdt_get_property(blob, nodeoffset, propname, NULL)) {
+ /* u-boot MAC addr randomly assigned - leave the present one */
+ if (!eth_getenv_enetaddr_by_index("eth", eth_dev->index,
+ env_enetaddr))
+ return err;
+ } else {
+ size = MC_DT_INCREASE_SIZE + strlen(propname) + len;
+ /* make room for mac address property */
+ err = fdt_increase_size(blob, size);
+ if (err) {
+ printf("fdt_increase_size: err=%s\n",
+ fdt_strerror(err));
+ return err;
+ }
+ }
+
+ err = fdt_setprop(blob, nodeoffset, propname, val, len);
+ if (err) {
+ printf("fdt_setprop: err=%s\n", fdt_strerror(err));
+ return err;
+ }
+
+ return err;
+}
+
+#define is_dpni(s) (s != NULL ? !strncmp(s, "dpni@", 5) : 0)
+
+const char *dpl_get_connection_endpoint(void *blob, char *endpoint)
+{
+ int connoffset = fdt_path_offset(blob, "/connections"), off;
+ const char *s1, *s2;
+
+ for (off = fdt_first_subnode(blob, connoffset);
+ off >= 0;
+ off = fdt_next_subnode(blob, off)) {
+ s1 = fdt_stringlist_get(blob, off, "endpoint1", 0, NULL);
+ s2 = fdt_stringlist_get(blob, off, "endpoint2", 0, NULL);
+
+ if (!s1 || !s2)
+ continue;
+
+ if (strcmp(endpoint, s1) == 0)
+ return s2;
+
+ if (strcmp(endpoint, s2) == 0)
+ return s1;
+ }
+
+ return NULL;
+}
+
+static int mc_fixup_dpl_mac_addr(void *blob, int dpmac_id,
+ struct eth_device *eth_dev)
+{
+ int objoff = fdt_path_offset(blob, "/objects");
+ int dpmacoff = -1, dpnioff = -1;
+ const char *endpoint;
char mac_name[10];
- const char link_type_mode[] = "FIXED_LINK";
- unsigned char env_enetaddr[6];
+ int err;
+
+ sprintf(mac_name, "dpmac@%d", dpmac_id);
+ dpmacoff = fdt_subnode_offset(blob, objoff, mac_name);
+ if (dpmacoff < 0)
+ /* dpmac not defined in DPL, so skip it. */
+ return 0;
+
+ err = mc_fixup_mac_addr(blob, dpmacoff, "mac_addr", eth_dev,
+ MC_FIXUP_DPL);
+ if (err) {
+ printf("Error fixing up dpmac mac_addr in DPL\n");
+ return err;
+ }
+
+ /* now we need to figure out if there is any
+ * DPNI connected to this MAC, so we walk the
+ * connection list
+ */
+ endpoint = dpl_get_connection_endpoint(blob, mac_name);
+ if (!is_dpni(endpoint))
+ return 0;
+
+ /* let's see if we can fixup the DPNI as well */
+ dpnioff = fdt_subnode_offset(blob, objoff, endpoint);
+ if (dpnioff < 0)
+ /* DPNI not defined in DPL in the objects area */
+ return 0;
+
+ return mc_fixup_mac_addr(blob, dpnioff, "mac_addr", eth_dev,
+ MC_FIXUP_DPL);
+}
+
+static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id,
+ struct eth_device *eth_dev)
+{
+ int nodeoffset = fdt_path_offset(blob, "/board_info/ports"), noff;
+ int err = 0;
+ char mac_name[10];
+ const char link_type_mode[] = "MAC_LINK_TYPE_FIXED";
sprintf(mac_name, "mac@%d", dpmac_id);
/* node not found - create it */
- nodeoffset = fdt_subnode_offset(blob, noff, (const char *) mac_name);
- if (nodeoffset < 0) {
+ noff = fdt_subnode_offset(blob, nodeoffset, (const char *)mac_name);
+ if (noff < 0) {
err = fdt_increase_size(blob, 200);
if (err) {
printf("fdt_increase_size: err=%s\n",
@@ -175,10 +299,15 @@ static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id,
return err;
}
- nodeoffset = fdt_add_subnode(blob, noff, mac_name);
+ noff = fdt_add_subnode(blob, nodeoffset, mac_name);
+ if (noff < 0) {
+ printf("fdt_add_subnode: err=%s\n",
+ fdt_strerror(err));
+ return err;
+ }
/* add default property of fixed link */
- err = fdt_appendprop_string(blob, nodeoffset,
+ err = fdt_appendprop_string(blob, noff,
"link_type", link_type_mode);
if (err) {
printf("fdt_appendprop_string: err=%s\n",
@@ -187,49 +316,53 @@ static int mc_fixup_dpc_mac_addr(void *blob, int noff, int dpmac_id,
}
}
- /* port_mac_address property present in DPC */
- if (fdt_get_property(blob, nodeoffset, "port_mac_address", NULL)) {
- /* MAC addr randomly assigned - leave the one in DPC */
- eth_getenv_enetaddr_by_index("eth", eth_dev->index,
- env_enetaddr);
- if (is_zero_ethaddr(env_enetaddr))
- return err;
+ return mc_fixup_mac_addr(blob, noff, "port_mac_address", eth_dev,
+ MC_FIXUP_DPC);
+}
- /* replace DPC MAC address with u-boot env one */
- err = fdt_setprop(blob, nodeoffset, "port_mac_address",
- eth_dev->enetaddr, 6);
- if (err) {
- printf("fdt_setprop mac: err=%s\n", fdt_strerror(err));
- return err;
- }
+static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type)
+{
+ int i, err = 0, ret = 0;
+ char ethname[10];
+ struct eth_device *eth_dev;
- return 0;
- }
+ for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
+ /* port not enabled */
+ if ((wriop_is_enabled_dpmac(i) != 1) ||
+ (wriop_get_phy_address(i) == -1))
+ continue;
- /* append port_mac_address property to mac node in DPC */
- err = fdt_increase_size(blob, 80);
- if (err) {
- printf("fdt_increase_size: err=%s\n", fdt_strerror(err));
- return err;
- }
+ sprintf(ethname, "DPMAC%d@%s", i,
+ phy_interface_strings[wriop_get_enet_if(i)]);
- err = fdt_appendprop(blob, nodeoffset,
- "port_mac_address", eth_dev->enetaddr, 6);
- if (err) {
- printf("fdt_appendprop: err=%s\n", fdt_strerror(err));
- return err;
+ eth_dev = eth_get_dev_by_name(ethname);
+ if (eth_dev == NULL)
+ continue;
+
+ switch (type) {
+ case MC_FIXUP_DPL:
+ err = mc_fixup_dpl_mac_addr(blob, i, eth_dev);
+ break;
+ case MC_FIXUP_DPC:
+ err = mc_fixup_dpc_mac_addr(blob, i, eth_dev);
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ printf("fsl-mc: ERROR fixing mac address for %s\n",
+ ethname);
+ ret |= err;
}
- return err;
+ return ret;
}
static int mc_fixup_dpc(u64 dpc_addr)
{
void *blob = (void *)dpc_addr;
int nodeoffset, err = 0;
- char ethname[10];
- struct eth_device *eth_dev;
- int i;
/* delete any existing ICID pools */
nodeoffset = fdt_path_offset(blob, "/resources/icid_pools");
@@ -254,30 +387,9 @@ static int mc_fixup_dpc(u64 dpc_addr)
/* fixup MAC addresses for dpmac ports */
nodeoffset = fdt_path_offset(blob, "/board_info/ports");
if (nodeoffset < 0)
- goto out;
-
- for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
- /* port not enabled */
- if ((wriop_is_enabled_dpmac(i) != 1) ||
- (wriop_get_phy_address(i) == -1))
- continue;
-
- sprintf(ethname, "DPMAC%d@%s", i,
- phy_interface_strings[wriop_get_enet_if(i)]);
-
- eth_dev = eth_get_dev_by_name(ethname);
- if (eth_dev == NULL)
- continue;
-
- err = mc_fixup_dpc_mac_addr(blob, nodeoffset, i, eth_dev);
- if (err) {
- printf("mc_fixup_dpc_mac_addr failed: err=%s\n",
- fdt_strerror(err));
- goto out;
- }
- }
+ return 0;
-out:
+ err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPC);
flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob));
return err;
@@ -340,6 +452,25 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr)
return 0;
}
+
+static int mc_fixup_dpl(u64 dpl_addr)
+{
+ void *blob = (void *)dpl_addr;
+ u32 ver = fdt_getprop_u32_default(blob, "/", "dpl-version", 0);
+ int err = 0;
+
+ /* The DPL fixup for mac addresses is only relevant
+ * for old-style DPLs
+ */
+ if (ver >= 10)
+ return 0;
+
+ err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPL);
+ flush_dcache_range(dpl_addr, dpl_addr + fdt_totalsize(blob));
+
+ return err;
+}
+
static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr)
{
u64 mc_dpl_offset;
@@ -386,6 +517,8 @@ static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr)
(u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
#endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */
+ if (mc_fixup_dpl(mc_ram_addr + mc_dpl_offset))
+ return -EINVAL;
dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset));
return 0;
}
@@ -1368,3 +1501,18 @@ U_BOOT_CMD(
"fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
"fsl_mc start aiop [FW_addr] - Start AIOP\n"
);
+
+void mc_env_boot(void)
+{
+#if defined(CONFIG_FSL_MC_ENET)
+ char *mc_boot_env_var;
+ /* The MC may only be initialized in the reset PHY function
+ * because otherwise U-Boot has not yet set up all the MAC
+ * address info properly. Without MAC addresses, the MC code
+ * can not properly initialize the DPC.
+ */
+ mc_boot_env_var = getenv(MC_BOOT_ENV_VAR);
+ if (mc_boot_env_var)
+ run_command_list(mc_boot_env_var, -1, 0);
+#endif /* CONFIG_FSL_MC_ENET */
+}
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
index 15a3ce03ae..628b420add 100644
--- a/drivers/net/fsl_mcdmafec.c
+++ b/drivers/net/fsl_mcdmafec.c
@@ -475,7 +475,7 @@ static void fec_halt(struct eth_device *dev)
/* Disable DMA tasks */
MCD_killDma(info->txTask);
- MCD_killDma(info->rxTask);;
+ MCD_killDma(info->rxTask);
/* Disable the Ethernet Controller */
fecp->ecr &= ~FEC_ECR_ETHER_EN;
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index b79c467e69..cd24a21f04 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -392,7 +392,7 @@ static int ftmac100_ofdata_to_platdata(struct udevice *dev)
struct ftmac100_data *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
const char *mac;
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
priv->iobase = pdata->iobase;
mac = dtbmacaddr(0);
if (mac)
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index 1b781f4d95..72ef42cca8 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -1008,8 +1008,8 @@ static int ks2_eth_bind_slaves(struct udevice *dev, int gbe, int *gbe_0)
slave_name = malloc(20);
snprintf(slave_name, 20, "netcp@slave-%d", slave_no);
ret = device_bind_driver_to_node(dev, "eth_ks2_sl",
- slave_name, slave,
- &sl_dev);
+ slave_name, offset_to_ofnode(slave),
+ &sl_dev);
if (ret) {
error("ks2_net - not able to bind slave interfaces\n");
return ret;
@@ -1029,7 +1029,7 @@ static int ks2_eth_bind_slaves(struct udevice *dev, int gbe, int *gbe_0)
slave_name = malloc(20);
snprintf(slave_name, 20, "netcp@slave-%d", slave_no);
ret = device_bind_driver_to_node(dev, "eth_ks2_sl", slave_name,
- slave, &sl_dev);
+ offset_to_ofnode(slave), &sl_dev);
if (ret) {
error("ks2_net - not able to bind slave interfaces\n");
return ret;
@@ -1134,7 +1134,7 @@ static int ks2_eth_ofdata_to_platdata(struct udevice *dev)
ks2_eth_parse_slave_interface(dev_of_offset(dev), gbe_0, priv, pdata);
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 21a620c244..f9373db0b9 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -450,7 +450,6 @@ static void macb_phy_reset(struct macb_device *macb, const char *name)
name, status);
}
-#ifdef CONFIG_MACB_SEARCH_PHY
static int macb_phy_find(struct macb_device *macb, const char *name)
{
int i;
@@ -471,7 +470,6 @@ static int macb_phy_find(struct macb_device *macb, const char *name)
return 0;
}
-#endif /* CONFIG_MACB_SEARCH_PHY */
#ifdef CONFIG_DM_ETH
static int macb_phy_init(struct udevice *dev, const char *name)
@@ -488,11 +486,9 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
int i;
arch_get_mdio_control(name);
-#ifdef CONFIG_MACB_SEARCH_PHY
/* Auto-detect phy_addr */
if (!macb_phy_find(macb, name))
return 0;
-#endif /* CONFIG_MACB_SEARCH_PHY */
/* Check if the PHY is up to snuff... */
phy_id = macb_mdio_read(macb, MII_PHYSID1);
@@ -667,7 +663,8 @@ static int _macb_init(struct macb_device *macb, const char *name)
* to select interface between RMII and MII.
*/
#ifdef CONFIG_DM_ETH
- if (macb->phy_interface == PHY_INTERFACE_MODE_RMII)
+ if ((macb->phy_interface == PHY_INTERFACE_MODE_RMII) ||
+ (macb->phy_interface == PHY_INTERFACE_MODE_RGMII))
gem_writel(macb, UR, GEM_BIT(RGMII));
else
gem_writel(macb, UR, 0);
@@ -1090,7 +1087,7 @@ static int macb_eth_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/net/mpc512x_fec.c b/drivers/net/mpc512x_fec.c
deleted file mode 100644
index b3746fbb9a..0000000000
--- a/drivers/net/mpc512x_fec.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * (C) Copyright 2003-2010
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * Derived from the MPC8xx FEC driver.
- * Adapted for MPC512x by Grzegorz Bernacki <gjb@semihalf.com>
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-#include <netdev.h>
-#include <miiphy.h>
-#include <asm/io.h>
-#include "mpc512x_fec.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define DEBUG 0
-
-#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
-#error "CONFIG_MII has to be defined!"
-#endif
-
-int fec512x_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr);
-int fec512x_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr, u16 data);
-int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
-
-static uchar rx_buff[FEC_BUFFER_SIZE];
-static int rx_buff_idx = 0;
-
-/********************************************************************/
-#if (DEBUG & 0x2)
-static void mpc512x_fec_phydump (char *devname)
-{
- u16 phyStatus, i;
- u8 phyAddr = CONFIG_PHY_ADDR;
- u8 reg_mask[] = {
- /* regs to print: 0...8, 21,27,31 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
- };
-
- for (i = 0; i < 32; i++) {
- if (reg_mask[i]) {
- miiphy_read (devname, phyAddr, i, &phyStatus);
- printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
- }
- }
-}
-#endif
-
-/********************************************************************/
-static int mpc512x_fec_bd_init (mpc512x_fec_priv *fec)
-{
- int ix;
-
- /*
- * Receive BDs init
- */
- for (ix = 0; ix < FEC_RBD_NUM; ix++) {
- fec->bdBase->rbd[ix].dataPointer =
- (u32)&fec->bdBase->recv_frames[ix];
- fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY;
- fec->bdBase->rbd[ix].dataLength = 0;
- }
-
- /*
- * have the last RBD to close the ring
- */
- fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP;
- fec->rbdIndex = 0;
-
- /*
- * Trasmit BDs init
- */
- for (ix = 0; ix < FEC_TBD_NUM; ix++) {
- fec->bdBase->tbd[ix].status = 0;
- }
-
- /*
- * Have the last TBD to close the ring
- */
- fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP;
-
- /*
- * Initialize some indices
- */
- fec->tbdIndex = 0;
- fec->usedTbdIndex = 0;
- fec->cleanTbdNum = FEC_TBD_NUM;
-
- return 0;
-}
-
-/********************************************************************/
-static void mpc512x_fec_rbd_clean (mpc512x_fec_priv *fec, volatile FEC_RBD * pRbd)
-{
- /*
- * Reset buffer descriptor as empty
- */
- if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
- pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
- else
- pRbd->status = FEC_RBD_EMPTY;
-
- pRbd->dataLength = 0;
-
- /*
- * Increment BD count
- */
- fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
-
- /*
- * Now, we have an empty RxBD, notify FEC
- * Set Descriptor polling active
- */
- out_be32(&fec->eth->r_des_active, 0x01000000);
-}
-
-/********************************************************************/
-static void mpc512x_fec_tbd_scrub (mpc512x_fec_priv *fec)
-{
- volatile FEC_TBD *pUsedTbd;
-
-#if (DEBUG & 0x1)
- printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
- fec->cleanTbdNum, fec->usedTbdIndex);
-#endif
-
- /*
- * process all the consumed TBDs
- */
- while (fec->cleanTbdNum < FEC_TBD_NUM) {
- pUsedTbd = &fec->bdBase->tbd[fec->usedTbdIndex];
- if (pUsedTbd->status & FEC_TBD_READY) {
-#if (DEBUG & 0x20)
- printf ("Cannot clean TBD %d, in use\n", fec->usedTbdIndex);
-#endif
- return;
- }
-
- /*
- * clean this buffer descriptor
- */
- if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
- pUsedTbd->status = FEC_TBD_WRAP;
- else
- pUsedTbd->status = 0;
-
- /*
- * update some indeces for a correct handling of the TBD ring
- */
- fec->cleanTbdNum++;
- fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
- }
-}
-
-/********************************************************************/
-static void mpc512x_fec_set_hwaddr (mpc512x_fec_priv *fec, unsigned char *mac)
-{
- u8 currByte; /* byte for which to compute the CRC */
- int byte; /* loop - counter */
- int bit; /* loop - counter */
- u32 crc = 0xffffffff; /* initial value */
-
- /*
- * The algorithm used is the following:
- * we loop on each of the six bytes of the provided address,
- * and we compute the CRC by left-shifting the previous
- * value by one position, so that each bit in the current
- * byte of the address may contribute the calculation. If
- * the latter and the MSB in the CRC are different, then
- * the CRC value so computed is also ex-ored with the
- * "polynomium generator". The current byte of the address
- * is also shifted right by one bit at each iteration.
- * This is because the CRC generatore in hardware is implemented
- * as a shift-register with as many ex-ores as the radixes
- * in the polynomium. This suggests that we represent the
- * polynomiumm itself as a 32-bit constant.
- */
- for (byte = 0; byte < 6; byte++) {
- currByte = mac[byte];
- for (bit = 0; bit < 8; bit++) {
- if ((currByte & 0x01) ^ (crc & 0x01)) {
- crc >>= 1;
- crc = crc ^ 0xedb88320;
- } else {
- crc >>= 1;
- }
- currByte >>= 1;
- }
- }
-
- crc = crc >> 26;
-
- /*
- * Set individual hash table register
- */
- if (crc >= 32) {
- out_be32(&fec->eth->iaddr1, (1 << (crc - 32)));
- out_be32(&fec->eth->iaddr2, 0);
- } else {
- out_be32(&fec->eth->iaddr1, 0);
- out_be32(&fec->eth->iaddr2, (1 << crc));
- }
-
- /*
- * Set physical address
- */
- out_be32(&fec->eth->paddr1, (mac[0] << 24) + (mac[1] << 16) +
- (mac[2] << 8) + mac[3]);
- out_be32(&fec->eth->paddr2, (mac[4] << 24) + (mac[5] << 16) +
- 0x8808);
-}
-
-/********************************************************************/
-static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis)
-{
- mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
-
-#if (DEBUG & 0x1)
- printf ("mpc512x_fec_init... Begin\n");
-#endif
-
- mpc512x_fec_set_hwaddr (fec, dev->enetaddr);
- out_be32(&fec->eth->gaddr1, 0x00000000);
- out_be32(&fec->eth->gaddr2, 0x00000000);
-
- mpc512x_fec_init_phy (dev, bis);
-
- /* Set interrupt mask register */
- out_be32(&fec->eth->imask, 0x00000000);
-
- /* Clear FEC-Lite interrupt event register(IEVENT) */
- out_be32(&fec->eth->ievent, 0xffffffff);
-
- /* Set transmit fifo watermark register(X_WMRK), default = 64 */
- out_be32(&fec->eth->x_wmrk, 0x0);
-
- /* Set Opcode/Pause Duration Register */
- out_be32(&fec->eth->op_pause, 0x00010020);
-
- /* Frame length=1522; MII mode */
- out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x24);
-
- /* Half-duplex, heartbeat disabled */
- out_be32(&fec->eth->x_cntrl, 0x00000000);
-
- /* Enable MIB counters */
- out_be32(&fec->eth->mib_control, 0x0);
-
- /* Setup recv fifo start and buff size */
- out_be32(&fec->eth->r_fstart, 0x500);
- out_be32(&fec->eth->r_buff_size, FEC_BUFFER_SIZE);
-
- /* Setup BD base addresses */
- out_be32(&fec->eth->r_des_start, (u32)fec->bdBase->rbd);
- out_be32(&fec->eth->x_des_start, (u32)fec->bdBase->tbd);
-
- /* DMA Control */
- out_be32(&fec->eth->dma_control, 0xc0000000);
-
- /* Enable FEC */
- setbits_be32(&fec->eth->ecntrl, 0x00000006);
-
- /* Initilize addresses and status words of BDs */
- mpc512x_fec_bd_init (fec);
-
- /* Descriptor polling active */
- out_be32(&fec->eth->r_des_active, 0x01000000);
-
-#if (DEBUG & 0x1)
- printf("mpc512x_fec_init... Done \n");
-#endif
- return 1;
-}
-
-/********************************************************************/
-int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
-{
- mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
- const u8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */
- int timeout = 1;
- u16 phyStatus;
-
-#if (DEBUG & 0x1)
- printf ("mpc512x_fec_init_phy... Begin\n");
-#endif
-
- /*
- * Clear FEC-Lite interrupt event register(IEVENT)
- */
- out_be32(&fec->eth->ievent, 0xffffffff);
-
- /*
- * Set interrupt mask register
- */
- out_be32(&fec->eth->imask, 0x00000000);
-
- if (fec->xcv_type != SEVENWIRE) {
- /*
- * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
- * and do not drop the Preamble.
- */
- out_be32(&fec->eth->mii_speed,
- (((gd->arch.ips_clk / 1000000) / 5) + 1) << 1);
-
- /*
- * Reset PHY, then delay 300ns
- */
- miiphy_write (dev->name, phyAddr, 0x0, 0x8000);
- udelay (1000);
-
- if (fec->xcv_type == MII10) {
- /*
- * Force 10Base-T, FDX operation
- */
-#if (DEBUG & 0x2)
- printf ("Forcing 10 Mbps ethernet link... ");
-#endif
- miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
-
- miiphy_write (dev->name, phyAddr, 0x0, 0x0180);
-
- timeout = 20;
- do { /* wait for link status to go down */
- udelay (10000);
- if ((timeout--) == 0) {
-#if (DEBUG & 0x2)
- printf ("hmmm, should not have waited...");
-#endif
- break;
- }
- miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
-#if (DEBUG & 0x2)
- printf ("=");
-#endif
- } while ((phyStatus & 0x0004)); /* !link up */
-
- timeout = 1000;
- do { /* wait for link status to come back up */
- udelay (10000);
- if ((timeout--) == 0) {
- printf ("failed. Link is down.\n");
- break;
- }
- miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
-#if (DEBUG & 0x2)
- printf ("+");
-#endif
- } while (!(phyStatus & 0x0004)); /* !link up */
-
-#if (DEBUG & 0x2)
- printf ("done.\n");
-#endif
- } else { /* MII100 */
- /*
- * Set the auto-negotiation advertisement register bits
- */
- miiphy_write (dev->name, phyAddr, 0x4, 0x01e1);
-
- /*
- * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
- */
- miiphy_write (dev->name, phyAddr, 0x0, 0x1200);
-
- /*
- * Wait for AN completion
- */
- timeout = 2500;
- do {
- udelay (1000);
-
- if ((timeout--) == 0) {
-#if (DEBUG & 0x2)
- printf ("PHY auto neg 0 failed...\n");
-#endif
- return -1;
- }
-
- if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) {
-#if (DEBUG & 0x2)
- printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
-#endif
- return -1;
- }
- } while (!(phyStatus & 0x0004));
-
-#if (DEBUG & 0x2)
- printf ("PHY auto neg complete! \n");
-#endif
- }
- }
-
-#if (DEBUG & 0x2)
- if (fec->xcv_type != SEVENWIRE)
- mpc512x_fec_phydump (dev->name);
-#endif
-
-#if (DEBUG & 0x1)
- printf ("mpc512x_fec_init_phy... Done \n");
-#endif
- return 1;
-}
-
-/********************************************************************/
-static void mpc512x_fec_halt (struct eth_device *dev)
-{
- mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
- int counter = 0xffff;
-
-#if (DEBUG & 0x2)
- if (fec->xcv_type != SEVENWIRE)
- mpc512x_fec_phydump (dev->name);
-#endif
-
- /*
- * mask FEC chip interrupts
- */
- out_be32(&fec->eth->imask, 0);
-
- /*
- * issue graceful stop command to the FEC transmitter if necessary
- */
- setbits_be32(&fec->eth->x_cntrl, 0x00000001);
-
- /*
- * wait for graceful stop to register
- */
- while ((counter--) && (!(in_be32(&fec->eth->ievent) & 0x10000000)))
- ;
-
- /*
- * Disable the Ethernet Controller
- */
- clrbits_be32(&fec->eth->ecntrl, 0x00000002);
-
- /*
- * Issue a reset command to the FEC chip
- */
- setbits_be32(&fec->eth->ecntrl, 0x1);
-
- /*
- * wait at least 16 clock cycles
- */
- udelay (10);
-#if (DEBUG & 0x3)
- printf ("Ethernet task stopped\n");
-#endif
-}
-
-/********************************************************************/
-
-static int mpc512x_fec_send(struct eth_device *dev, void *eth_data,
- int data_length)
-{
- /*
- * This routine transmits one frame. This routine only accepts
- * 6-byte Ethernet addresses.
- */
- mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
- volatile FEC_TBD *pTbd;
-
-#if (DEBUG & 0x20)
- printf("tbd status: 0x%04x\n", fec->tbdBase[fec->tbdIndex].status);
-#endif
-
- /*
- * Clear Tx BD ring at first
- */
- mpc512x_fec_tbd_scrub (fec);
-
- /*
- * Check for valid length of data.
- */
- if ((data_length > 1500) || (data_length <= 0)) {
- return -1;
- }
-
- /*
- * Check the number of vacant TxBDs.
- */
- if (fec->cleanTbdNum < 1) {
-#if (DEBUG & 0x20)
- printf ("No available TxBDs ...\n");
-#endif
- return -1;
- }
-
- /*
- * Get the first TxBD to send the mac header
- */
- pTbd = &fec->bdBase->tbd[fec->tbdIndex];
- pTbd->dataLength = data_length;
- pTbd->dataPointer = (u32)eth_data;
- pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
- fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
-
- /* Activate transmit Buffer Descriptor polling */
- out_be32(&fec->eth->x_des_active, 0x01000000);
-
-#if (DEBUG & 0x8)
- printf ( "+" );
-#endif
-
- fec->cleanTbdNum -= 1;
-
- /*
- * wait until frame is sent .
- */
- while (pTbd->status & FEC_TBD_READY) {
- udelay (10);
-#if (DEBUG & 0x8)
- printf ("TDB status = %04x\n", pTbd->status);
-#endif
- }
-
- return 0;
-}
-
-
-/********************************************************************/
-static int mpc512x_fec_recv (struct eth_device *dev)
-{
- /*
- * This command pulls one frame from the card
- */
- mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
- volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex];
- unsigned long ievent;
- int frame_length = 0;
-
-#if (DEBUG & 0x1)
- printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex);
-#endif
-#if (DEBUG & 0x8)
- printf( "-" );
-#endif
-
- /*
- * Check if any critical events have happened
- */
- ievent = in_be32(&fec->eth->ievent);
- out_be32(&fec->eth->ievent, ievent);
- if (ievent & 0x20060000) {
- /* BABT, Rx/Tx FIFO errors */
- mpc512x_fec_halt (dev);
- mpc512x_fec_init (dev, NULL);
- return 0;
- }
- if (ievent & 0x80000000) {
- /* Heartbeat error */
- setbits_be32(&fec->eth->x_cntrl, 0x00000001);
- }
- if (ievent & 0x10000000) {
- /* Graceful stop complete */
- if (in_be32(&fec->eth->x_cntrl) & 0x00000001) {
- mpc512x_fec_halt (dev);
- clrbits_be32(&fec->eth->x_cntrl, 0x00000001);;
- mpc512x_fec_init (dev, NULL);
- }
- }
-
- if (!(pRbd->status & FEC_RBD_EMPTY)) {
- if (!(pRbd->status & FEC_RBD_ERR) &&
- ((pRbd->dataLength - 4) > 14)) {
-
- /*
- * Get buffer size
- */
- if (pRbd->status & FEC_RBD_LAST)
- frame_length = pRbd->dataLength - 4;
- else
- frame_length = pRbd->dataLength;
-#if (DEBUG & 0x20)
- {
- int i;
- printf ("recv data length 0x%08x data hdr: ",
- pRbd->dataLength);
- for (i = 0; i < 14; i++)
- printf ("%x ", *((u8*)pRbd->dataPointer + i));
- printf("\n");
- }
-#endif
- /*
- * Fill the buffer and pass it to upper layers
- */
- memcpy (&rx_buff[rx_buff_idx], (void*)pRbd->dataPointer,
- frame_length - rx_buff_idx);
- rx_buff_idx = frame_length;
-
- if (pRbd->status & FEC_RBD_LAST) {
- net_process_received_packet((uchar *)rx_buff,
- frame_length);
- rx_buff_idx = 0;
- }
- }
-
- /*
- * Reset buffer descriptor as empty
- */
- mpc512x_fec_rbd_clean (fec, pRbd);
- }
-
- /* Try to fill Buffer Descriptors */
- out_be32(&fec->eth->r_des_active, 0x01000000);
-
- return frame_length;
-}
-
-/********************************************************************/
-int mpc512x_fec_initialize (bd_t * bis)
-{
- volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
- mpc512x_fec_priv *fec;
- struct eth_device *dev;
- void * bd;
-
- fec = (mpc512x_fec_priv *) malloc (sizeof(*fec));
- dev = (struct eth_device *) malloc (sizeof(*dev));
- memset (dev, 0, sizeof *dev);
-
- fec->eth = &im->fec;
-
-# ifndef CONFIG_FEC_10MBIT
- fec->xcv_type = MII100;
-# else
- fec->xcv_type = MII10;
-# endif
- dev->priv = (void *)fec;
- dev->iobase = (int)&im->fec;
- dev->init = mpc512x_fec_init;
- dev->halt = mpc512x_fec_halt;
- dev->send = mpc512x_fec_send;
- dev->recv = mpc512x_fec_recv;
-
- strcpy(dev->name, "FEC");
- eth_register (dev);
-
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
- int retval;
- struct mii_dev *mdiodev = mdio_alloc();
- if (!mdiodev)
- return -ENOMEM;
- strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
- mdiodev->read = fec512x_miiphy_read;
- mdiodev->write = fec512x_miiphy_write;
-
- retval = mdio_register(mdiodev);
- if (retval < 0)
- return retval;
-#endif
-
- /* Clean up space FEC's MIB and FIFO RAM ...*/
- memset ((void *)&im->fec.mib, 0x00, sizeof(im->fec.mib));
- memset ((void *)&im->fec.fifo, 0x00, sizeof(im->fec.fifo));
-
- /*
- * Malloc space for BDs (must be quad word-aligned)
- * this pointer is lost, so cannot be freed
- */
- bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f);
- fec->bdBase = (mpc512x_buff_descs*)((u32)bd & 0xfffffff0);
- memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f);
-
- /*
- * Set interrupt mask register
- */
- out_be32(&fec->eth->imask, 0x00000000);
-
- /*
- * Clear FEC-Lite interrupt event register(IEVENT)
- */
- out_be32(&fec->eth->ievent, 0xffffffff);
-
- return 1;
-}
-
-/* MII-interface related functions */
-/********************************************************************/
-int fec512x_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr)
-{
- u16 retVal = 0;
- volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
- volatile fec512x_t *eth = &im->fec;
- u32 reg; /* convenient holder for the PHY register */
- u32 phy; /* convenient holder for the PHY */
- int timeout = 0xffff;
-
- /*
- * reading from any PHY's register is done by properly
- * programming the FEC's MII data register.
- */
- reg = regAddr << FEC_MII_DATA_RA_SHIFT;
- phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
-
- out_be32(&eth->mii_data, FEC_MII_DATA_ST |
- FEC_MII_DATA_OP_RD |
- FEC_MII_DATA_TA |
- phy | reg);
-
- /*
- * wait for the related interrupt
- */
- while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
- ;
-
- if (timeout == 0) {
-#if (DEBUG & 0x2)
- printf ("Read MDIO failed...\n");
-#endif
- return -1;
- }
-
- /*
- * clear mii interrupt bit
- */
- out_be32(&eth->ievent, 0x00800000);
-
- /*
- * it's now safe to read the PHY's register
- */
- retVal = (u16) in_be32(&eth->mii_data);
-
- return retVal;
-}
-
-/********************************************************************/
-int fec512x_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr, u16 data)
-{
- volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
- volatile fec512x_t *eth = &im->fec;
- u32 reg; /* convenient holder for the PHY register */
- u32 phy; /* convenient holder for the PHY */
- int timeout = 0xffff;
-
- reg = regAddr << FEC_MII_DATA_RA_SHIFT;
- phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
-
- out_be32(&eth->mii_data, FEC_MII_DATA_ST |
- FEC_MII_DATA_OP_WR |
- FEC_MII_DATA_TA |
- phy | reg | data);
-
- /*
- * wait for the MII interrupt
- */
- while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
- ;
-
- if (timeout == 0) {
-#if (DEBUG & 0x2)
- printf ("Write MDIO failed...\n");
-#endif
- return -1;
- }
-
- /*
- * clear MII interrupt bit
- */
- out_be32(&eth->ievent, 0x00800000);
-
- return 0;
-}
diff --git a/drivers/net/mpc512x_fec.h b/drivers/net/mpc512x_fec.h
deleted file mode 100644
index a083cca2f8..0000000000
--- a/drivers/net/mpc512x_fec.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * (C) Copyright 2003 - 2009
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * Derived from the MPC8xx driver's header file.
- */
-
-#ifndef __MPC512X_FEC_H
-#define __MPC512X_FEC_H
-
-#include <common.h>
-
-/* Receive & Transmit Buffer Descriptor definitions */
-typedef struct BufferDescriptor {
- u16 status;
- u16 dataLength;
- u32 dataPointer;
-} FEC_RBD;
-
-typedef struct {
- u16 status;
- u16 dataLength;
- u32 dataPointer;
-} FEC_TBD;
-
-/* private structure */
-typedef enum {
- SEVENWIRE, /* 7-wire */
- MII10, /* MII 10Mbps */
- MII100 /* MII 100Mbps */
-} xceiver_type;
-
-/* BD Numer definitions */
-#define FEC_TBD_NUM 48 /* The user can adjust this value */
-#define FEC_RBD_NUM 32 /* The user can adjust this value */
-
-/* packet size limit */
-#define FEC_MAX_FRAME_LEN 1522 /* recommended default value */
-
-/* Buffer size must be evenly divisible by 16 */
-#define FEC_BUFFER_SIZE ((FEC_MAX_FRAME_LEN + 0x10) & (~0xf))
-
-typedef struct {
- u8 frame[FEC_BUFFER_SIZE];
-} mpc512x_frame;
-
-typedef struct {
- FEC_RBD rbd[FEC_RBD_NUM]; /* RBD ring */
- FEC_TBD tbd[FEC_TBD_NUM]; /* TBD ring */
- mpc512x_frame recv_frames[FEC_RBD_NUM]; /* receive buff */
-} mpc512x_buff_descs;
-
-typedef struct {
- volatile fec512x_t *eth;
- xceiver_type xcv_type; /* transceiver type */
- mpc512x_buff_descs *bdBase; /* BD rings and recv buffer */
- u16 rbdIndex; /* next receive BD to read */
- u16 tbdIndex; /* next transmit BD to send */
- u16 usedTbdIndex; /* next transmit BD to clean */
- u16 cleanTbdNum; /* the number of available transmit BDs */
-} mpc512x_fec_priv;
-
-/* RBD bits definitions */
-#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */
-#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */
-#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */
-#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */
-#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */
-#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */
-#define FEC_RBD_LG 0x0020 /* Frame length violation */
-#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */
-#define FEC_RBD_SH 0x0008 /* Short frame */
-#define FEC_RBD_CR 0x0004 /* CRC error */
-#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */
-#define FEC_RBD_TR 0x0001 /* Frame is truncated */
-#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
- FEC_RBD_OV | FEC_RBD_TR)
-
-/* TBD bits definitions */
-#define FEC_TBD_READY 0x8000 /* Buffer is ready */
-#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */
-#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */
-#define FEC_TBD_TC 0x0400 /* Transmit the CRC */
-#define FEC_TBD_ABC 0x0200 /* Append bad CRC */
-
-/* MII-related definitios */
-#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */
-#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */
-#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */
-#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */
-#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */
-#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */
-#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */
-
-#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */
-#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */
-
-#endif /* __MPC512X_FEC_H */
diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c
deleted file mode 100644
index d75e858a38..0000000000
--- a/drivers/net/mpc5xxx_fec.c
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * (C) Copyright 2003-2010
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * This file is based on mpc4200fec.c,
- * (C) Copyright Motorola, Inc., 2000
- */
-
-#include <common.h>
-#include <mpc5xxx.h>
-#include <mpc5xxx_sdma.h>
-#include <malloc.h>
-#include <net.h>
-#include <netdev.h>
-#include <miiphy.h>
-#include "mpc5xxx_fec.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/* #define DEBUG 0x28 */
-
-#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
-#error "CONFIG_MII has to be defined!"
-#endif
-
-#if (DEBUG & 0x60)
-static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec);
-static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec);
-#endif /* DEBUG */
-
-typedef struct {
- uint8 data[1500]; /* actual data */
- int length; /* actual length */
- int used; /* buffer in use or not */
- uint8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */
-} NBUF;
-
-int fec5xxx_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr);
-int fec5xxx_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr, u16 data);
-
-static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis);
-
-/********************************************************************/
-#if (DEBUG & 0x2)
-static void mpc5xxx_fec_phydump (char *devname)
-{
- uint16 phyStatus, i;
- uint8 phyAddr = CONFIG_PHY_ADDR;
- uint8 reg_mask[] = {
-#if CONFIG_PHY_TYPE == 0x79c874 /* AMD Am79C874 */
- /* regs to print: 0...7, 16...19, 21, 23, 24 */
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
-#else
- /* regs to print: 0...8, 16...20 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-#endif
- };
-
- for (i = 0; i < 32; i++) {
- if (reg_mask[i]) {
- miiphy_read(devname, phyAddr, i, &phyStatus);
- printf("Mii reg %d: 0x%04x\n", i, phyStatus);
- }
- }
-}
-#endif
-
-/********************************************************************/
-static int mpc5xxx_fec_rbd_init(mpc5xxx_fec_priv *fec)
-{
- int ix;
- char *data;
- static int once = 0;
-
- for (ix = 0; ix < FEC_RBD_NUM; ix++) {
- if (!once) {
- data = (char *)malloc(FEC_MAX_PKT_SIZE);
- if (data == NULL) {
- printf ("RBD INIT FAILED\n");
- return -1;
- }
- fec->rbdBase[ix].dataPointer = (uint32)data;
- }
- fec->rbdBase[ix].status = FEC_RBD_EMPTY;
- fec->rbdBase[ix].dataLength = 0;
- }
- once ++;
-
- /*
- * have the last RBD to close the ring
- */
- fec->rbdBase[ix - 1].status |= FEC_RBD_WRAP;
- fec->rbdIndex = 0;
-
- return 0;
-}
-
-/********************************************************************/
-static void mpc5xxx_fec_tbd_init(mpc5xxx_fec_priv *fec)
-{
- int ix;
-
- for (ix = 0; ix < FEC_TBD_NUM; ix++) {
- fec->tbdBase[ix].status = 0;
- }
-
- /*
- * Have the last TBD to close the ring
- */
- fec->tbdBase[ix - 1].status |= FEC_TBD_WRAP;
-
- /*
- * Initialize some indices
- */
- fec->tbdIndex = 0;
- fec->usedTbdIndex = 0;
- fec->cleanTbdNum = FEC_TBD_NUM;
-}
-
-/********************************************************************/
-static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, volatile FEC_RBD * pRbd)
-{
- /*
- * Reset buffer descriptor as empty
- */
- if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
- pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
- else
- pRbd->status = FEC_RBD_EMPTY;
-
- pRbd->dataLength = 0;
-
- /*
- * Now, we have an empty RxBD, restart the SmartDMA receive task
- */
- SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
-
- /*
- * Increment BD count
- */
- fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
-}
-
-/********************************************************************/
-static void mpc5xxx_fec_tbd_scrub(mpc5xxx_fec_priv *fec)
-{
- volatile FEC_TBD *pUsedTbd;
-
-#if (DEBUG & 0x1)
- printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
- fec->cleanTbdNum, fec->usedTbdIndex);
-#endif
-
- /*
- * process all the consumed TBDs
- */
- while (fec->cleanTbdNum < FEC_TBD_NUM) {
- pUsedTbd = &fec->tbdBase[fec->usedTbdIndex];
- if (pUsedTbd->status & FEC_TBD_READY) {
-#if (DEBUG & 0x20)
- printf("Cannot clean TBD %d, in use\n", fec->cleanTbdNum);
-#endif
- return;
- }
-
- /*
- * clean this buffer descriptor
- */
- if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
- pUsedTbd->status = FEC_TBD_WRAP;
- else
- pUsedTbd->status = 0;
-
- /*
- * update some indeces for a correct handling of the TBD ring
- */
- fec->cleanTbdNum++;
- fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
- }
-}
-
-/********************************************************************/
-static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac)
-{
- uint8 currByte; /* byte for which to compute the CRC */
- int byte; /* loop - counter */
- int bit; /* loop - counter */
- uint32 crc = 0xffffffff; /* initial value */
-
- /*
- * The algorithm used is the following:
- * we loop on each of the six bytes of the provided address,
- * and we compute the CRC by left-shifting the previous
- * value by one position, so that each bit in the current
- * byte of the address may contribute the calculation. If
- * the latter and the MSB in the CRC are different, then
- * the CRC value so computed is also ex-ored with the
- * "polynomium generator". The current byte of the address
- * is also shifted right by one bit at each iteration.
- * This is because the CRC generatore in hardware is implemented
- * as a shift-register with as many ex-ores as the radixes
- * in the polynomium. This suggests that we represent the
- * polynomiumm itself as a 32-bit constant.
- */
- for (byte = 0; byte < 6; byte++) {
- currByte = mac[byte];
- for (bit = 0; bit < 8; bit++) {
- if ((currByte & 0x01) ^ (crc & 0x01)) {
- crc >>= 1;
- crc = crc ^ 0xedb88320;
- } else {
- crc >>= 1;
- }
- currByte >>= 1;
- }
- }
-
- crc = crc >> 26;
-
- /*
- * Set individual hash table register
- */
- if (crc >= 32) {
- fec->eth->iaddr1 = (1 << (crc - 32));
- fec->eth->iaddr2 = 0;
- } else {
- fec->eth->iaddr1 = 0;
- fec->eth->iaddr2 = (1 << crc);
- }
-
- /*
- * Set physical address
- */
- fec->eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
- fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
-}
-
-/********************************************************************/
-static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
-{
- mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
- struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
-
-#if (DEBUG & 0x1)
- printf ("mpc5xxx_fec_init... Begin\n");
-#endif
-
- mpc5xxx_fec_init_phy(dev, bis);
-
- /*
- * Call board-specific PHY fixups (if any)
- */
-#ifdef CONFIG_RESET_PHY_R
- reset_phy();
-#endif
-
- /*
- * Initialize RxBD/TxBD rings
- */
- mpc5xxx_fec_rbd_init(fec);
- mpc5xxx_fec_tbd_init(fec);
-
- /*
- * Clear FEC-Lite interrupt event register(IEVENT)
- */
- fec->eth->ievent = 0xffffffff;
-
- /*
- * Set interrupt mask register
- */
- fec->eth->imask = 0x00000000;
-
- /*
- * Set FEC-Lite receive control register(R_CNTRL):
- */
- if (fec->xcv_type == SEVENWIRE) {
- /*
- * Frame length=1518; 7-wire mode
- */
- fec->eth->r_cntrl = 0x05ee0020; /*0x05ee0000;FIXME */
- } else {
- /*
- * Frame length=1518; MII mode;
- */
- fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */
- }
-
- fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */
-
- /*
- * Set Opcode/Pause Duration Register
- */
- fec->eth->op_pause = 0x00010020; /*FIXME 0xffff0020; */
-
- /*
- * Set Rx FIFO alarm and granularity value
- */
- fec->eth->rfifo_cntrl = 0x0c000000
- | (fec->eth->rfifo_cntrl & ~0x0f000000);
- fec->eth->rfifo_alarm = 0x0000030c;
-#if (DEBUG & 0x22)
- if (fec->eth->rfifo_status & 0x00700000 ) {
- printf("mpc5xxx_fec_init() RFIFO error\n");
- }
-#endif
-
- /*
- * Set Tx FIFO granularity value
- */
- fec->eth->tfifo_cntrl = 0x0c000000
- | (fec->eth->tfifo_cntrl & ~0x0f000000);
-#if (DEBUG & 0x2)
- printf("tfifo_status: 0x%08x\n", fec->eth->tfifo_status);
- printf("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm);
-#endif
-
- /*
- * Set transmit fifo watermark register(X_WMRK), default = 64
- */
- fec->eth->tfifo_alarm = 0x00000080;
- fec->eth->x_wmrk = 0x2;
-
- /*
- * Set individual address filter for unicast address
- * and set physical address registers.
- */
- mpc5xxx_fec_set_hwaddr(fec, (char *)dev->enetaddr);
-
- /*
- * Set multicast address filter
- */
- fec->eth->gaddr1 = 0x00000000;
- fec->eth->gaddr2 = 0x00000000;
-
- /*
- * Turn ON cheater FSM: ????
- */
- fec->eth->xmit_fsm = 0x03000000;
-
- /*
- * Turn off COMM bus prefetch in the MPC5200 BestComm. It doesn't
- * work w/ the current receive task.
- */
- sdma->PtdCntrl |= 0x00000001;
-
- /*
- * Set priority of different initiators
- */
- sdma->IPR0 = 7; /* always */
- sdma->IPR3 = 6; /* Eth RX */
- sdma->IPR4 = 5; /* Eth Tx */
-
- /*
- * Clear SmartDMA task interrupt pending bits
- */
- SDMA_CLEAR_IEVENT(FEC_RECV_TASK_NO);
-
- /*
- * Initialize SmartDMA parameters stored in SRAM
- */
- *(volatile int *)FEC_TBD_BASE = (int)fec->tbdBase;
- *(volatile int *)FEC_RBD_BASE = (int)fec->rbdBase;
- *(volatile int *)FEC_TBD_NEXT = (int)fec->tbdBase;
- *(volatile int *)FEC_RBD_NEXT = (int)fec->rbdBase;
-
- /*
- * Enable FEC-Lite controller
- */
- fec->eth->ecntrl |= 0x00000006;
-
-#if (DEBUG & 0x2)
- if (fec->xcv_type != SEVENWIRE)
- mpc5xxx_fec_phydump (dev->name);
-#endif
-
- /*
- * Enable SmartDMA receive task
- */
- SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
-
-#if (DEBUG & 0x1)
- printf("mpc5xxx_fec_init... Done \n");
-#endif
-
- return 1;
-}
-
-/********************************************************************/
-static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
-{
- mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
- const uint8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */
- static int initialized = 0;
-
- if(initialized)
- return 0;
- initialized = 1;
-
-#if (DEBUG & 0x1)
- printf ("mpc5xxx_fec_init_phy... Begin\n");
-#endif
-
- /*
- * Initialize GPIO pins
- */
- if (fec->xcv_type == SEVENWIRE) {
- /* 10MBit with 7-wire operation */
- /* 7-wire only */
- *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000;
- } else {
- /* 100MBit with MD operation */
- *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000;
- }
-
- /*
- * Clear FEC-Lite interrupt event register(IEVENT)
- */
- fec->eth->ievent = 0xffffffff;
-
- /*
- * Set interrupt mask register
- */
- fec->eth->imask = 0x00000000;
-
-/*
- * In original Promess-provided code PHY initialization is disabled with the
- * following comment: "Phy initialization is DISABLED for now. There was a
- * problem with running 100 Mbps on PRO board". Thus we temporarily disable
- * PHY initialization for the Motion-PRO board, until a proper fix is found.
- */
-
- if (fec->xcv_type != SEVENWIRE) {
- /*
- * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
- * and do not drop the Preamble.
- * No MII for 7-wire mode
- */
- fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1);
- }
-
- if (fec->xcv_type != SEVENWIRE) {
- /*
- * Initialize PHY(LXT971A):
- *
- * Generally, on power up, the LXT971A reads its configuration
- * pins to check for forced operation, If not cofigured for
- * forced operation, it uses auto-negotiation/parallel detection
- * to automatically determine line operating conditions.
- * If the PHY device on the other side of the link supports
- * auto-negotiation, the LXT971A auto-negotiates with it
- * using Fast Link Pulse(FLP) Bursts. If the PHY partner does not
- * support auto-negotiation, the LXT971A automatically detects
- * the presence of either link pulses(10Mbps PHY) or Idle
- * symbols(100Mbps) and sets its operating conditions accordingly.
- *
- * When auto-negotiation is controlled by software, the following
- * steps are recommended.
- *
- * Note:
- * The physical address is dependent on hardware configuration.
- *
- */
- int timeout = 1;
- uint16 phyStatus;
-
- /*
- * Reset PHY, then delay 300ns
- */
- miiphy_write(dev->name, phyAddr, 0x0, 0x8000);
- udelay(1000);
-
- if (fec->xcv_type == MII10) {
- /*
- * Force 10Base-T, FDX operation
- */
-#if (DEBUG & 0x2)
- printf("Forcing 10 Mbps ethernet link... ");
-#endif
- miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
- /*
- miiphy_write(dev->name, fec, phyAddr, 0x0, 0x0100);
- */
- miiphy_write(dev->name, phyAddr, 0x0, 0x0180);
-
- timeout = 20;
- do { /* wait for link status to go down */
- udelay(10000);
- if ((timeout--) == 0) {
-#if (DEBUG & 0x2)
- printf("hmmm, should not have waited...");
-#endif
- break;
- }
- miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
-#if (DEBUG & 0x2)
- printf("=");
-#endif
- } while ((phyStatus & 0x0004)); /* !link up */
-
- timeout = 1000;
- do { /* wait for link status to come back up */
- udelay(10000);
- if ((timeout--) == 0) {
- printf("failed. Link is down.\n");
- break;
- }
- miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
-#if (DEBUG & 0x2)
- printf("+");
-#endif
- } while (!(phyStatus & 0x0004)); /* !link up */
-
-#if (DEBUG & 0x2)
- printf ("done.\n");
-#endif
- } else { /* MII100 */
- /*
- * Set the auto-negotiation advertisement register bits
- */
- miiphy_write(dev->name, phyAddr, 0x4, 0x01e1);
-
- /*
- * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
- */
- miiphy_write(dev->name, phyAddr, 0x0, 0x1200);
-
- /*
- * Wait for AN completion
- */
- timeout = 5000;
- do {
- udelay(1000);
-
- if ((timeout--) == 0) {
-#if (DEBUG & 0x2)
- printf("PHY auto neg 0 failed...\n");
-#endif
- return -1;
- }
-
- if (miiphy_read(dev->name, phyAddr, 0x1, &phyStatus) != 0) {
-#if (DEBUG & 0x2)
- printf("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
-#endif
- return -1;
- }
- } while (!(phyStatus & 0x0004));
-
-#if (DEBUG & 0x2)
- printf("PHY auto neg complete! \n");
-#endif
- }
-
- }
-
-#if (DEBUG & 0x2)
- if (fec->xcv_type != SEVENWIRE)
- mpc5xxx_fec_phydump (dev->name);
-#endif
-
-
-#if (DEBUG & 0x1)
- printf("mpc5xxx_fec_init_phy... Done \n");
-#endif
-
- return 1;
-}
-
-/********************************************************************/
-static void mpc5xxx_fec_halt(struct eth_device *dev)
-{
- struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
- mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
- int counter = 0xffff;
-
-#if (DEBUG & 0x2)
- if (fec->xcv_type != SEVENWIRE)
- mpc5xxx_fec_phydump (dev->name);
-#endif
-
- /*
- * mask FEC chip interrupts
- */
- fec->eth->imask = 0;
-
- /*
- * issue graceful stop command to the FEC transmitter if necessary
- */
- fec->eth->x_cntrl |= 0x00000001;
-
- /*
- * wait for graceful stop to register
- */
- while ((counter--) && (!(fec->eth->ievent & 0x10000000))) ;
-
- /*
- * Disable SmartDMA tasks
- */
- SDMA_TASK_DISABLE (FEC_XMIT_TASK_NO);
- SDMA_TASK_DISABLE (FEC_RECV_TASK_NO);
-
- /*
- * Turn on COMM bus prefetch in the MPC5200 BestComm after we're
- * done. It doesn't work w/ the current receive task.
- */
- sdma->PtdCntrl &= ~0x00000001;
-
- /*
- * Disable the Ethernet Controller
- */
- fec->eth->ecntrl &= 0xfffffffd;
-
- /*
- * Clear FIFO status registers
- */
- fec->eth->rfifo_status &= 0x00700000;
- fec->eth->tfifo_status &= 0x00700000;
-
- fec->eth->reset_cntrl = 0x01000000;
-
- /*
- * Issue a reset command to the FEC chip
- */
- fec->eth->ecntrl |= 0x1;
-
- /*
- * wait at least 16 clock cycles
- */
- udelay(10);
-
- /* don't leave the MII speed set to zero */
- if (fec->xcv_type != SEVENWIRE) {
- /*
- * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
- * and do not drop the Preamble.
- * No MII for 7-wire mode
- */
- fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1);
- }
-
-#if (DEBUG & 0x3)
- printf("Ethernet task stopped\n");
-#endif
-}
-
-#if (DEBUG & 0x60)
-/********************************************************************/
-
-static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec)
-{
- uint16 phyAddr = CONFIG_PHY_ADDR;
- uint16 phyStatus;
-
- if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
- || (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
-
- miiphy_read(devname, phyAddr, 0x1, &phyStatus);
- printf("\nphyStatus: 0x%04x\n", phyStatus);
- printf("ecntrl: 0x%08x\n", fec->eth->ecntrl);
- printf("ievent: 0x%08x\n", fec->eth->ievent);
- printf("x_status: 0x%08x\n", fec->eth->x_status);
- printf("tfifo: status 0x%08x\n", fec->eth->tfifo_status);
-
- printf(" control 0x%08x\n", fec->eth->tfifo_cntrl);
- printf(" lrfp 0x%08x\n", fec->eth->tfifo_lrf_ptr);
- printf(" lwfp 0x%08x\n", fec->eth->tfifo_lwf_ptr);
- printf(" alarm 0x%08x\n", fec->eth->tfifo_alarm);
- printf(" readptr 0x%08x\n", fec->eth->tfifo_rdptr);
- printf(" writptr 0x%08x\n", fec->eth->tfifo_wrptr);
- }
-}
-
-static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec)
-{
- uint16 phyAddr = CONFIG_PHY_ADDR;
- uint16 phyStatus;
-
- if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
- || (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
-
- miiphy_read(devname, phyAddr, 0x1, &phyStatus);
- printf("\nphyStatus: 0x%04x\n", phyStatus);
- printf("ecntrl: 0x%08x\n", fec->eth->ecntrl);
- printf("ievent: 0x%08x\n", fec->eth->ievent);
- printf("x_status: 0x%08x\n", fec->eth->x_status);
- printf("rfifo: status 0x%08x\n", fec->eth->rfifo_status);
-
- printf(" control 0x%08x\n", fec->eth->rfifo_cntrl);
- printf(" lrfp 0x%08x\n", fec->eth->rfifo_lrf_ptr);
- printf(" lwfp 0x%08x\n", fec->eth->rfifo_lwf_ptr);
- printf(" alarm 0x%08x\n", fec->eth->rfifo_alarm);
- printf(" readptr 0x%08x\n", fec->eth->rfifo_rdptr);
- printf(" writptr 0x%08x\n", fec->eth->rfifo_wrptr);
- }
-}
-#endif /* DEBUG */
-
-/********************************************************************/
-
-static int mpc5xxx_fec_send(struct eth_device *dev, void *eth_data,
- int data_length)
-{
- /*
- * This routine transmits one frame. This routine only accepts
- * 6-byte Ethernet addresses.
- */
- mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
- volatile FEC_TBD *pTbd;
-
-#if (DEBUG & 0x20)
- printf("tbd status: 0x%04x\n", fec->tbdBase[0].status);
- tfifo_print(dev->name, fec);
-#endif
-
- /*
- * Clear Tx BD ring at first
- */
- mpc5xxx_fec_tbd_scrub(fec);
-
- /*
- * Check for valid length of data.
- */
- if ((data_length > 1500) || (data_length <= 0)) {
- return -1;
- }
-
- /*
- * Check the number of vacant TxBDs.
- */
- if (fec->cleanTbdNum < 1) {
-#if (DEBUG & 0x20)
- printf("No available TxBDs ...\n");
-#endif
- return -1;
- }
-
- /*
- * Get the first TxBD to send the mac header
- */
- pTbd = &fec->tbdBase[fec->tbdIndex];
- pTbd->dataLength = data_length;
- pTbd->dataPointer = (uint32)eth_data;
- pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
- fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
-
-#if (DEBUG & 0x100)
- printf("SDMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex);
-#endif
-
- /*
- * Kick the MII i/f
- */
- if (fec->xcv_type != SEVENWIRE) {
- uint16 phyStatus;
- miiphy_read(dev->name, 0, 0x1, &phyStatus);
- }
-
- /*
- * Enable SmartDMA transmit task
- */
-
-#if (DEBUG & 0x20)
- tfifo_print(dev->name, fec);
-#endif
- SDMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
-#if (DEBUG & 0x20)
- tfifo_print(dev->name, fec);
-#endif
-#if (DEBUG & 0x8)
- printf( "+" );
-#endif
-
- fec->cleanTbdNum -= 1;
-
-#if (DEBUG & 0x129) && (DEBUG & 0x80000000)
- printf ("smartDMA ethernet Tx task enabled\n");
-#endif
- /*
- * wait until frame is sent .
- */
- while (pTbd->status & FEC_TBD_READY) {
- udelay(10);
-#if (DEBUG & 0x8)
- printf ("TDB status = %04x\n", pTbd->status);
-#endif
- }
-
- return 0;
-}
-
-
-/********************************************************************/
-static int mpc5xxx_fec_recv(struct eth_device *dev)
-{
- /*
- * This command pulls one frame from the card
- */
- mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
- volatile FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
- unsigned long ievent;
- int frame_length, len = 0;
- NBUF *frame;
- uchar buff[FEC_MAX_PKT_SIZE];
-
-#if (DEBUG & 0x1)
- printf ("mpc5xxx_fec_recv %d Start...\n", fec->rbdIndex);
-#endif
-#if (DEBUG & 0x8)
- printf( "-" );
-#endif
-
- /*
- * Check if any critical events have happened
- */
- ievent = fec->eth->ievent;
- fec->eth->ievent = ievent;
- if (ievent & 0x20060000) {
- /* BABT, Rx/Tx FIFO errors */
- mpc5xxx_fec_halt(dev);
- mpc5xxx_fec_init(dev, NULL);
- return 0;
- }
- if (ievent & 0x80000000) {
- /* Heartbeat error */
- fec->eth->x_cntrl |= 0x00000001;
- }
- if (ievent & 0x10000000) {
- /* Graceful stop complete */
- if (fec->eth->x_cntrl & 0x00000001) {
- mpc5xxx_fec_halt(dev);
- fec->eth->x_cntrl &= ~0x00000001;
- mpc5xxx_fec_init(dev, NULL);
- }
- }
-
- if (!(pRbd->status & FEC_RBD_EMPTY)) {
- if ((pRbd->status & FEC_RBD_LAST) && !(pRbd->status & FEC_RBD_ERR) &&
- ((pRbd->dataLength - 4) > 14)) {
-
- /*
- * Get buffer address and size
- */
- frame = (NBUF *)pRbd->dataPointer;
- frame_length = pRbd->dataLength - 4;
-
-#if (DEBUG & 0x20)
- {
- int i;
- printf("recv data hdr:");
- for (i = 0; i < 14; i++)
- printf("%x ", *(frame->head + i));
- printf("\n");
- }
-#endif
- /*
- * Fill the buffer and pass it to upper layers
- */
- memcpy(buff, frame->head, 14);
- memcpy(buff + 14, frame->data, frame_length);
- net_process_received_packet(buff, frame_length);
- len = frame_length;
- }
- /*
- * Reset buffer descriptor as empty
- */
- mpc5xxx_fec_rbd_clean(fec, pRbd);
- }
- SDMA_CLEAR_IEVENT (FEC_RECV_TASK_NO);
- return len;
-}
-
-
-/********************************************************************/
-int mpc5xxx_fec_initialize(bd_t * bis)
-{
- mpc5xxx_fec_priv *fec;
- struct eth_device *dev;
- char *tmp, *end;
- char env_enetaddr[6];
- int i;
-
- fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
- dev = (struct eth_device *)malloc(sizeof(*dev));
- memset(dev, 0, sizeof *dev);
-
- fec->eth = (ethernet_regs *)MPC5XXX_FEC;
- fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
- fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
-#if defined(CONFIG_MPC5xxx_FEC_MII100)
- fec->xcv_type = MII100;
-#elif defined(CONFIG_MPC5xxx_FEC_MII10)
- fec->xcv_type = MII10;
-#elif defined(CONFIG_MPC5xxx_FEC_SEVENWIRE)
- fec->xcv_type = SEVENWIRE;
-#else
-#error fec->xcv_type not initialized.
-#endif
- if (fec->xcv_type != SEVENWIRE) {
- /*
- * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
- * and do not drop the Preamble.
- * No MII for 7-wire mode
- */
- fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1);
- }
-
- dev->priv = (void *)fec;
- dev->iobase = MPC5XXX_FEC;
- dev->init = mpc5xxx_fec_init;
- dev->halt = mpc5xxx_fec_halt;
- dev->send = mpc5xxx_fec_send;
- dev->recv = mpc5xxx_fec_recv;
-
- strcpy(dev->name, "FEC");
- eth_register(dev);
-
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
- int retval;
- struct mii_dev *mdiodev = mdio_alloc();
- if (!mdiodev)
- return -ENOMEM;
- strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
- mdiodev->read = fec5xxx_miiphy_read;
- mdiodev->write = fec5xxx_miiphy_write;
-
- retval = mdio_register(mdiodev);
- if (retval < 0)
- return retval;
-#endif
-
- /*
- * Try to set the mac address now. The fec mac address is
- * a garbage after reset. When not using fec for booting
- * the Linux fec driver will try to work with this garbage.
- */
- tmp = getenv("ethaddr");
- if (tmp) {
- for (i=0; i<6; i++) {
- env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
- if (tmp)
- tmp = (*end) ? end+1 : end;
- }
- mpc5xxx_fec_set_hwaddr(fec, env_enetaddr);
- }
-
- return 1;
-}
-
-/* MII-interface related functions */
-/********************************************************************/
-int fec5xxx_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr)
-{
- uint16 retVal = 0;
- ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
- uint32 reg; /* convenient holder for the PHY register */
- uint32 phy; /* convenient holder for the PHY */
- int timeout = 0xffff;
-
- /*
- * reading from any PHY's register is done by properly
- * programming the FEC's MII data register.
- */
- reg = regAddr << FEC_MII_DATA_RA_SHIFT;
- phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
-
- eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg);
-
- /*
- * wait for the related interrupt
- */
- while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
-
- if (timeout == 0) {
-#if (DEBUG & 0x2)
- printf ("Read MDIO failed...\n");
-#endif
- return -1;
- }
-
- /*
- * clear mii interrupt bit
- */
- eth->ievent = 0x00800000;
-
- /*
- * it's now safe to read the PHY's register
- */
- retVal = (uint16) eth->mii_data;
-
- return retVal;
-}
-
-/********************************************************************/
-int fec5xxx_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
- int regAddr, u16 data)
-{
- ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
- uint32 reg; /* convenient holder for the PHY register */
- uint32 phy; /* convenient holder for the PHY */
- int timeout = 0xffff;
-
- reg = regAddr << FEC_MII_DATA_RA_SHIFT;
- phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
-
- eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
- FEC_MII_DATA_TA | phy | reg | data);
-
- /*
- * wait for the MII interrupt
- */
- while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
-
- if (timeout == 0) {
-#if (DEBUG & 0x2)
- printf ("Write MDIO failed...\n");
-#endif
- return -1;
- }
-
- /*
- * clear MII interrupt bit
- */
- eth->ievent = 0x00800000;
-
- return 0;
-}
diff --git a/drivers/net/mpc5xxx_fec.h b/drivers/net/mpc5xxx_fec.h
deleted file mode 100644
index 16c3e8e918..0000000000
--- a/drivers/net/mpc5xxx_fec.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * This file is based on mpc4200fec.h
- * (C) Copyright Motorola, Inc., 2000
- *
- * odin ethernet header file
- */
-
-#ifndef __MPC5XXX_FEC_H
-#define __MPC5XXX_FEC_H
-
-typedef unsigned long uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
-
-typedef struct ethernet_register_set {
-
-/* [10:2]addr = 00 */
-
-/* Control and status Registers (offset 000-1FF) */
-
- volatile uint32 fec_id; /* MBAR_ETH + 0x000 */
- volatile uint32 ievent; /* MBAR_ETH + 0x004 */
- volatile uint32 imask; /* MBAR_ETH + 0x008 */
-
- volatile uint32 RES0[1]; /* MBAR_ETH + 0x00C */
- volatile uint32 r_des_active; /* MBAR_ETH + 0x010 */
- volatile uint32 x_des_active; /* MBAR_ETH + 0x014 */
- volatile uint32 r_des_active_cl; /* MBAR_ETH + 0x018 */
- volatile uint32 x_des_active_cl; /* MBAR_ETH + 0x01C */
- volatile uint32 ivent_set; /* MBAR_ETH + 0x020 */
- volatile uint32 ecntrl; /* MBAR_ETH + 0x024 */
-
- volatile uint32 RES1[6]; /* MBAR_ETH + 0x028-03C */
- volatile uint32 mii_data; /* MBAR_ETH + 0x040 */
- volatile uint32 mii_speed; /* MBAR_ETH + 0x044 */
- volatile uint32 mii_status; /* MBAR_ETH + 0x048 */
-
- volatile uint32 RES2[5]; /* MBAR_ETH + 0x04C-05C */
- volatile uint32 mib_data; /* MBAR_ETH + 0x060 */
- volatile uint32 mib_control; /* MBAR_ETH + 0x064 */
-
- volatile uint32 RES3[6]; /* MBAR_ETH + 0x068-7C */
- volatile uint32 r_activate; /* MBAR_ETH + 0x080 */
- volatile uint32 r_cntrl; /* MBAR_ETH + 0x084 */
- volatile uint32 r_hash; /* MBAR_ETH + 0x088 */
- volatile uint32 r_data; /* MBAR_ETH + 0x08C */
- volatile uint32 ar_done; /* MBAR_ETH + 0x090 */
- volatile uint32 r_test; /* MBAR_ETH + 0x094 */
- volatile uint32 r_mib; /* MBAR_ETH + 0x098 */
- volatile uint32 r_da_low; /* MBAR_ETH + 0x09C */
- volatile uint32 r_da_high; /* MBAR_ETH + 0x0A0 */
-
- volatile uint32 RES4[7]; /* MBAR_ETH + 0x0A4-0BC */
- volatile uint32 x_activate; /* MBAR_ETH + 0x0C0 */
- volatile uint32 x_cntrl; /* MBAR_ETH + 0x0C4 */
- volatile uint32 backoff; /* MBAR_ETH + 0x0C8 */
- volatile uint32 x_data; /* MBAR_ETH + 0x0CC */
- volatile uint32 x_status; /* MBAR_ETH + 0x0D0 */
- volatile uint32 x_mib; /* MBAR_ETH + 0x0D4 */
- volatile uint32 x_test; /* MBAR_ETH + 0x0D8 */
- volatile uint32 fdxfc_da1; /* MBAR_ETH + 0x0DC */
- volatile uint32 fdxfc_da2; /* MBAR_ETH + 0x0E0 */
- volatile uint32 paddr1; /* MBAR_ETH + 0x0E4 */
- volatile uint32 paddr2; /* MBAR_ETH + 0x0E8 */
- volatile uint32 op_pause; /* MBAR_ETH + 0x0EC */
-
- volatile uint32 RES5[4]; /* MBAR_ETH + 0x0F0-0FC */
- volatile uint32 instr_reg; /* MBAR_ETH + 0x100 */
- volatile uint32 context_reg; /* MBAR_ETH + 0x104 */
- volatile uint32 test_cntrl; /* MBAR_ETH + 0x108 */
- volatile uint32 acc_reg; /* MBAR_ETH + 0x10C */
- volatile uint32 ones; /* MBAR_ETH + 0x110 */
- volatile uint32 zeros; /* MBAR_ETH + 0x114 */
- volatile uint32 iaddr1; /* MBAR_ETH + 0x118 */
- volatile uint32 iaddr2; /* MBAR_ETH + 0x11C */
- volatile uint32 gaddr1; /* MBAR_ETH + 0x120 */
- volatile uint32 gaddr2; /* MBAR_ETH + 0x124 */
- volatile uint32 random; /* MBAR_ETH + 0x128 */
- volatile uint32 rand1; /* MBAR_ETH + 0x12C */
- volatile uint32 tmp; /* MBAR_ETH + 0x130 */
-
- volatile uint32 RES6[3]; /* MBAR_ETH + 0x134-13C */
- volatile uint32 fifo_id; /* MBAR_ETH + 0x140 */
- volatile uint32 x_wmrk; /* MBAR_ETH + 0x144 */
- volatile uint32 fcntrl; /* MBAR_ETH + 0x148 */
- volatile uint32 r_bound; /* MBAR_ETH + 0x14C */
- volatile uint32 r_fstart; /* MBAR_ETH + 0x150 */
- volatile uint32 r_count; /* MBAR_ETH + 0x154 */
- volatile uint32 r_lag; /* MBAR_ETH + 0x158 */
- volatile uint32 r_read; /* MBAR_ETH + 0x15C */
- volatile uint32 r_write; /* MBAR_ETH + 0x160 */
- volatile uint32 x_count; /* MBAR_ETH + 0x164 */
- volatile uint32 x_lag; /* MBAR_ETH + 0x168 */
- volatile uint32 x_retry; /* MBAR_ETH + 0x16C */
- volatile uint32 x_write; /* MBAR_ETH + 0x170 */
- volatile uint32 x_read; /* MBAR_ETH + 0x174 */
-
- volatile uint32 RES7[2]; /* MBAR_ETH + 0x178-17C */
- volatile uint32 fm_cntrl; /* MBAR_ETH + 0x180 */
- volatile uint32 rfifo_data; /* MBAR_ETH + 0x184 */
- volatile uint32 rfifo_status; /* MBAR_ETH + 0x188 */
- volatile uint32 rfifo_cntrl; /* MBAR_ETH + 0x18C */
- volatile uint32 rfifo_lrf_ptr; /* MBAR_ETH + 0x190 */
- volatile uint32 rfifo_lwf_ptr; /* MBAR_ETH + 0x194 */
- volatile uint32 rfifo_alarm; /* MBAR_ETH + 0x198 */
- volatile uint32 rfifo_rdptr; /* MBAR_ETH + 0x19C */
- volatile uint32 rfifo_wrptr; /* MBAR_ETH + 0x1A0 */
- volatile uint32 tfifo_data; /* MBAR_ETH + 0x1A4 */
- volatile uint32 tfifo_status; /* MBAR_ETH + 0x1A8 */
- volatile uint32 tfifo_cntrl; /* MBAR_ETH + 0x1AC */
- volatile uint32 tfifo_lrf_ptr; /* MBAR_ETH + 0x1B0 */
- volatile uint32 tfifo_lwf_ptr; /* MBAR_ETH + 0x1B4 */
- volatile uint32 tfifo_alarm; /* MBAR_ETH + 0x1B8 */
- volatile uint32 tfifo_rdptr; /* MBAR_ETH + 0x1BC */
- volatile uint32 tfifo_wrptr; /* MBAR_ETH + 0x1C0 */
-
- volatile uint32 reset_cntrl; /* MBAR_ETH + 0x1C4 */
- volatile uint32 xmit_fsm; /* MBAR_ETH + 0x1C8 */
-
- volatile uint32 RES8[3]; /* MBAR_ETH + 0x1CC-1D4 */
- volatile uint32 rdes_data0; /* MBAR_ETH + 0x1D8 */
- volatile uint32 rdes_data1; /* MBAR_ETH + 0x1DC */
- volatile uint32 r_length; /* MBAR_ETH + 0x1E0 */
- volatile uint32 x_length; /* MBAR_ETH + 0x1E4 */
- volatile uint32 x_addr; /* MBAR_ETH + 0x1E8 */
- volatile uint32 cdes_data; /* MBAR_ETH + 0x1EC */
- volatile uint32 status; /* MBAR_ETH + 0x1F0 */
- volatile uint32 dma_control; /* MBAR_ETH + 0x1F4 */
- volatile uint32 des_cmnd; /* MBAR_ETH + 0x1F8 */
- volatile uint32 data; /* MBAR_ETH + 0x1FC */
-
-/* MIB COUNTERS (Offset 200-2FF) */
-
- volatile uint32 rmon_t_drop; /* MBAR_ETH + 0x200 */
- volatile uint32 rmon_t_packets; /* MBAR_ETH + 0x204 */
- volatile uint32 rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */
- volatile uint32 rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */
- volatile uint32 rmon_t_crc_align; /* MBAR_ETH + 0x210 */
- volatile uint32 rmon_t_undersize; /* MBAR_ETH + 0x214 */
- volatile uint32 rmon_t_oversize; /* MBAR_ETH + 0x218 */
- volatile uint32 rmon_t_frag; /* MBAR_ETH + 0x21C */
- volatile uint32 rmon_t_jab; /* MBAR_ETH + 0x220 */
- volatile uint32 rmon_t_col; /* MBAR_ETH + 0x224 */
- volatile uint32 rmon_t_p64; /* MBAR_ETH + 0x228 */
- volatile uint32 rmon_t_p65to127; /* MBAR_ETH + 0x22C */
- volatile uint32 rmon_t_p128to255; /* MBAR_ETH + 0x230 */
- volatile uint32 rmon_t_p256to511; /* MBAR_ETH + 0x234 */
- volatile uint32 rmon_t_p512to1023; /* MBAR_ETH + 0x238 */
- volatile uint32 rmon_t_p1024to2047; /* MBAR_ETH + 0x23C */
- volatile uint32 rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */
- volatile uint32 rmon_t_octets; /* MBAR_ETH + 0x244 */
- volatile uint32 ieee_t_drop; /* MBAR_ETH + 0x248 */
- volatile uint32 ieee_t_frame_ok; /* MBAR_ETH + 0x24C */
- volatile uint32 ieee_t_1col; /* MBAR_ETH + 0x250 */
- volatile uint32 ieee_t_mcol; /* MBAR_ETH + 0x254 */
- volatile uint32 ieee_t_def; /* MBAR_ETH + 0x258 */
- volatile uint32 ieee_t_lcol; /* MBAR_ETH + 0x25C */
- volatile uint32 ieee_t_excol; /* MBAR_ETH + 0x260 */
- volatile uint32 ieee_t_macerr; /* MBAR_ETH + 0x264 */
- volatile uint32 ieee_t_cserr; /* MBAR_ETH + 0x268 */
- volatile uint32 ieee_t_sqe; /* MBAR_ETH + 0x26C */
- volatile uint32 t_fdxfc; /* MBAR_ETH + 0x270 */
- volatile uint32 ieee_t_octets_ok; /* MBAR_ETH + 0x274 */
-
- volatile uint32 RES9[2]; /* MBAR_ETH + 0x278-27C */
- volatile uint32 rmon_r_drop; /* MBAR_ETH + 0x280 */
- volatile uint32 rmon_r_packets; /* MBAR_ETH + 0x284 */
- volatile uint32 rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */
- volatile uint32 rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */
- volatile uint32 rmon_r_crc_align; /* MBAR_ETH + 0x290 */
- volatile uint32 rmon_r_undersize; /* MBAR_ETH + 0x294 */
- volatile uint32 rmon_r_oversize; /* MBAR_ETH + 0x298 */
- volatile uint32 rmon_r_frag; /* MBAR_ETH + 0x29C */
- volatile uint32 rmon_r_jab; /* MBAR_ETH + 0x2A0 */
-
- volatile uint32 rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */
-
- volatile uint32 rmon_r_p64; /* MBAR_ETH + 0x2A8 */
- volatile uint32 rmon_r_p65to127; /* MBAR_ETH + 0x2AC */
- volatile uint32 rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */
- volatile uint32 rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */
- volatile uint32 rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */
- volatile uint32 rmon_r_p1024to2047; /* MBAR_ETH + 0x2BC */
- volatile uint32 rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */
- volatile uint32 rmon_r_octets; /* MBAR_ETH + 0x2C4 */
- volatile uint32 ieee_r_drop; /* MBAR_ETH + 0x2C8 */
- volatile uint32 ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */
- volatile uint32 ieee_r_crc; /* MBAR_ETH + 0x2D0 */
- volatile uint32 ieee_r_align; /* MBAR_ETH + 0x2D4 */
- volatile uint32 r_macerr; /* MBAR_ETH + 0x2D8 */
- volatile uint32 r_fdxfc; /* MBAR_ETH + 0x2DC */
- volatile uint32 ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */
-
- volatile uint32 RES10[6]; /* MBAR_ETH + 0x2E4-2FC */
-
- volatile uint32 RES11[64]; /* MBAR_ETH + 0x300-3FF */
-} ethernet_regs;
-
-/* Receive & Transmit Buffer Descriptor definitions */
-typedef struct BufferDescriptor {
- uint16 status;
- uint16 dataLength;
- uint32 dataPointer;
-} FEC_RBD;
-typedef struct {
- uint16 status;
- uint16 dataLength;
- uint32 dataPointer;
-} FEC_TBD;
-
-/* private structure */
-typedef enum {
- SEVENWIRE, /* 7-wire */
- MII10, /* MII 10Mbps */
- MII100 /* MII 100Mbps */
-} xceiver_type;
-
-typedef struct {
- ethernet_regs *eth;
- xceiver_type xcv_type; /* transceiver type */
- FEC_RBD *rbdBase; /* RBD ring */
- FEC_TBD *tbdBase; /* TBD ring */
- uint16 rbdIndex; /* next receive BD to read */
- uint16 tbdIndex; /* next transmit BD to send */
- uint16 usedTbdIndex; /* next transmit BD to clean */
- uint16 cleanTbdNum; /* the number of available transmit BDs */
-} mpc5xxx_fec_priv;
-
-/* Ethernet parameter area */
-#define FEC_TBD_BASE (FEC_PARAM_BASE + 0x00)
-#define FEC_TBD_NEXT (FEC_PARAM_BASE + 0x04)
-#define FEC_RBD_BASE (FEC_PARAM_BASE + 0x08)
-#define FEC_RBD_NEXT (FEC_PARAM_BASE + 0x0c)
-
-/* BD Numer definitions */
-#define FEC_TBD_NUM 48 /* The user can adjust this value */
-#define FEC_RBD_NUM 32 /* The user can adjust this value */
-
-/* packet size limit */
-#define FEC_MAX_PKT_SIZE 1536
-
-/* RBD bits definitions */
-#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */
-#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */
-#define FEC_RBD_INT 0x1000 /* Interrupt */
-#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */
-#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */
-#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */
-#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */
-#define FEC_RBD_LG 0x0020 /* Frame length violation */
-#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */
-#define FEC_RBD_SH 0x0008 /* Short frame */
-#define FEC_RBD_CR 0x0004 /* CRC error */
-#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */
-#define FEC_RBD_TR 0x0001 /* Frame is truncated */
-#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
- FEC_RBD_OV | FEC_RBD_TR)
-
-/* TBD bits definitions */
-#define FEC_TBD_READY 0x8000 /* Buffer is ready */
-#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */
-#define FEC_TBD_INT 0x1000 /* Interrupt */
-#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */
-#define FEC_TBD_TC 0x0400 /* Transmit the CRC */
-#define FEC_TBD_ABC 0x0200 /* Append bad CRC */
-
-/* MII-related definitios */
-#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */
-#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */
-#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */
-#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */
-#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */
-#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */
-#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */
-
-#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */
-#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */
-
-#endif /* __MPC5XXX_FEC_H */
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index 8881cc77fe..50577d7f07 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -1695,7 +1695,7 @@ static int mvneta_probe(struct udevice *dev)
pp->base = (void __iomem *)pdata->iobase;
/* Configure MBUS address windows */
- if (of_device_is_compatible(dev, "marvell,armada-3700-neta"))
+ if (device_is_compatible(dev, "marvell,armada-3700-neta"))
mvneta_bypass_mbus_windows(pp);
else
mvneta_conf_mbus_windows(pp);
@@ -1756,7 +1756,7 @@ static int mvneta_ofdata_to_platdata(struct udevice *dev)
struct eth_pdata *pdata = dev_get_platdata(dev);
const char *phy_mode;
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
/* Get phy-mode / phy_interface from DT */
pdata->phy_interface = -1;
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index 08adb68aa5..1b46218e4d 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -442,7 +442,7 @@ do { \
/* MPCS registers */
#define PCS40G_COMMON_CONTROL 0x14
-#define FORWARD_ERROR_CORRECTION_MASK BIT(1)
+#define FORWARD_ERROR_CORRECTION_MASK BIT(10)
#define PCS_CLOCK_RESET 0x14c
#define TX_SD_CLK_RESET_MASK BIT(0)
@@ -3251,7 +3251,7 @@ static int gop_xpcs_mode(struct mvpp2_port *port, int num_of_lanes)
/* configure XG MAC mode */
val = readl(port->priv->xpcs_base + MVPP22_XPCS_GLOBAL_CFG_0_REG);
- val &= ~MVPP22_XPCS_PCSMODE_OFFS;
+ val &= ~MVPP22_XPCS_PCSMODE_MASK;
val &= ~MVPP22_XPCS_LANEACTIVE_MASK;
val |= (2 * lane) << MVPP22_XPCS_LANEACTIVE_OFFS;
writel(val, port->priv->xpcs_base + MVPP22_XPCS_GLOBAL_CFG_0_REG);
@@ -4479,7 +4479,15 @@ static int mvpp2_rx_refill(struct mvpp2_port *port,
/* Set hw internals when starting port */
static void mvpp2_start_dev(struct mvpp2_port *port)
{
- mvpp2_gmac_max_rx_size_set(port);
+ switch (port->phy_interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_SGMII:
+ mvpp2_gmac_max_rx_size_set(port);
+ default:
+ break;
+ }
+
mvpp2_txp_max_tx_size_set(port);
if (port->priv->hw_version == MVPP21)
@@ -4574,11 +4582,16 @@ static int mvpp2_open(struct udevice *dev, struct mvpp2_port *port)
return err;
}
- err = mvpp2_phy_connect(dev, port);
- if (err < 0)
- return err;
+ if (port->phy_node) {
+ err = mvpp2_phy_connect(dev, port);
+ if (err < 0)
+ return err;
- mvpp2_link_event(port);
+ mvpp2_link_event(port);
+ } else {
+ mvpp2_egress_enable(port);
+ mvpp2_ingress_enable(port);
+ }
mvpp2_start_dev(port);
@@ -4723,13 +4736,19 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
const char *phy_mode_str;
int phy_node;
u32 id;
- u32 phyaddr;
+ u32 phyaddr = 0;
int phy_mode = -1;
phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy");
- if (phy_node < 0) {
- dev_err(&pdev->dev, "missing phy\n");
- return -ENODEV;
+
+ if (phy_node > 0) {
+ phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node, "reg", 0);
+ if (phyaddr < 0) {
+ dev_err(&pdev->dev, "could not find phy address\n");
+ return -1;
+ }
+ } else {
+ phy_node = 0;
}
phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, "phy-mode", NULL);
@@ -4755,8 +4774,6 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
port->phy_speed = fdtdec_get_int(gd->fdt_blob, port_node,
"phy-speed", 1000);
- phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node, "reg", 0);
-
port->id = id;
if (port->priv->hw_version == MVPP21)
port->first_rxq = port->id * rxq_number;
@@ -5316,7 +5333,14 @@ static int mvpp2_start(struct udevice *dev)
/* Reconfigure parser accept the original MAC address */
mvpp2_prs_update_mac_da(port, port->dev_addr);
- mvpp2_port_power_up(port);
+ switch (port->phy_interface) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_SGMII:
+ mvpp2_port_power_up(port);
+ default:
+ break;
+ }
mvpp2_open(dev, port);
@@ -5394,18 +5418,18 @@ static int mvpp2_base_probe(struct udevice *dev)
memset(bd_space, 0, size);
/* Save base addresses for later use */
- priv->base = (void *)dev_get_addr_index(dev, 0);
+ priv->base = (void *)devfdt_get_addr_index(dev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
if (priv->hw_version == MVPP21) {
- priv->lms_base = (void *)dev_get_addr_index(dev, 1);
+ priv->lms_base = (void *)devfdt_get_addr_index(dev, 1);
if (IS_ERR(priv->lms_base))
return PTR_ERR(priv->lms_base);
priv->mdio_base = priv->lms_base + MVPP21_SMI;
} else {
- priv->iface_base = (void *)dev_get_addr_index(dev, 1);
+ priv->iface_base = (void *)devfdt_get_addr_index(dev, 1);
if (IS_ERR(priv->iface_base))
return PTR_ERR(priv->iface_base);
@@ -5463,7 +5487,7 @@ static int mvpp2_probe(struct udevice *dev)
if (priv->hw_version == MVPP21) {
int priv_common_regs_num = 2;
- port->base = (void __iomem *)dev_get_addr_index(
+ port->base = (void __iomem *)devfdt_get_addr_index(
dev->parent, priv_common_regs_num + port->id);
if (IS_ERR(port->base))
return PTR_ERR(port->base);
@@ -5479,7 +5503,8 @@ static int mvpp2_probe(struct udevice *dev)
port->gop_id * MVPP22_PORT_OFFSET;
/* Set phy address of the port */
- mvpp22_smi_phy_addr_cfg(port);
+ if(port->phy_node)
+ mvpp22_smi_phy_addr_cfg(port);
/* GoP Init */
gop_port_init(port);
diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c
index 67bf140a37..377d87f04b 100644
--- a/drivers/net/ne2000_base.c
+++ b/drivers/net/ne2000_base.c
@@ -495,7 +495,7 @@ dp83902a_recv(u8 *data, int len)
printf(" %02x", tmp);
if (0 == (++dx % 16)) printf("\n ");
#endif
- *data++ = tmp;;
+ *data++ = tmp;
mlen--;
}
}
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index d40fff0e48..8866f6632f 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -117,15 +117,17 @@ static void pch_gbe_rx_descs_init(struct udevice *dev)
memset(rx_desc, 0, sizeof(struct pch_gbe_rx_desc) * PCH_GBE_DESC_NUM);
for (i = 0; i < PCH_GBE_DESC_NUM; i++)
- rx_desc->buffer_addr = dm_pci_phys_to_mem(priv->dev,
- (ulong)(priv->rx_buff[i]));
+ rx_desc[i].buffer_addr = dm_pci_virt_to_mem(priv->dev,
+ priv->rx_buff[i]);
- writel(dm_pci_phys_to_mem(priv->dev, (ulong)rx_desc),
+ flush_dcache_range((ulong)rx_desc, (ulong)&rx_desc[PCH_GBE_DESC_NUM]);
+
+ writel(dm_pci_virt_to_mem(priv->dev, rx_desc),
&mac_regs->rx_dsc_base);
writel(sizeof(struct pch_gbe_rx_desc) * (PCH_GBE_DESC_NUM - 1),
&mac_regs->rx_dsc_size);
- writel(dm_pci_phys_to_mem(priv->dev, (ulong)(rx_desc + 1)),
+ writel(dm_pci_virt_to_mem(priv->dev, rx_desc + 1),
&mac_regs->rx_dsc_sw_p);
}
@@ -137,11 +139,13 @@ static void pch_gbe_tx_descs_init(struct udevice *dev)
memset(tx_desc, 0, sizeof(struct pch_gbe_tx_desc) * PCH_GBE_DESC_NUM);
- writel(dm_pci_phys_to_mem(priv->dev, (ulong)tx_desc),
+ flush_dcache_range((ulong)tx_desc, (ulong)&tx_desc[PCH_GBE_DESC_NUM]);
+
+ writel(dm_pci_virt_to_mem(priv->dev, tx_desc),
&mac_regs->tx_dsc_base);
writel(sizeof(struct pch_gbe_tx_desc) * (PCH_GBE_DESC_NUM - 1),
&mac_regs->tx_dsc_size);
- writel(dm_pci_phys_to_mem(priv->dev, (ulong)(tx_desc + 1)),
+ writel(dm_pci_virt_to_mem(priv->dev, tx_desc + 1),
&mac_regs->tx_dsc_sw_p);
}
@@ -245,24 +249,28 @@ static int pch_gbe_send(struct udevice *dev, void *packet, int length)
u32 int_st;
ulong start;
+ flush_dcache_range((ulong)packet, (ulong)packet + length);
+
tx_head = &priv->tx_desc[0];
tx_desc = &priv->tx_desc[priv->tx_idx];
if (length < 64)
frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
- tx_desc->buffer_addr = dm_pci_phys_to_mem(priv->dev, (ulong)packet);
+ tx_desc->buffer_addr = dm_pci_virt_to_mem(priv->dev, packet);
tx_desc->length = length;
tx_desc->tx_words_eob = length + 3;
tx_desc->tx_frame_ctrl = frame_ctrl;
tx_desc->dma_status = 0;
tx_desc->gbec_status = 0;
+ flush_dcache_range((ulong)tx_desc, (ulong)&tx_desc[1]);
+
/* Test the wrap-around condition */
if (++priv->tx_idx >= PCH_GBE_DESC_NUM)
priv->tx_idx = 0;
- writel(dm_pci_phys_to_mem(priv->dev, (ulong)(tx_head + priv->tx_idx)),
+ writel(dm_pci_virt_to_mem(priv->dev, tx_head + priv->tx_idx),
&mac_regs->tx_dsc_sw_p);
start = get_timer(0);
@@ -283,7 +291,8 @@ static int pch_gbe_recv(struct udevice *dev, int flags, uchar **packetp)
struct pch_gbe_priv *priv = dev_get_priv(dev);
struct pch_gbe_regs *mac_regs = priv->mac_regs;
struct pch_gbe_rx_desc *rx_desc;
- ulong hw_desc, buffer_addr, length;
+ ulong hw_desc, length;
+ void *buffer;
rx_desc = &priv->rx_desc[priv->rx_idx];
@@ -291,12 +300,16 @@ static int pch_gbe_recv(struct udevice *dev, int flags, uchar **packetp)
hw_desc = readl(&mac_regs->rx_dsc_hw_p_hld);
/* Just return if not receiving any packet */
- if ((ulong)rx_desc == hw_desc)
+ if (virt_to_phys(rx_desc) == hw_desc)
return -EAGAIN;
- buffer_addr = dm_pci_mem_to_phys(priv->dev, rx_desc->buffer_addr);
- *packetp = (uchar *)buffer_addr;
+ /* Invalidate the descriptor */
+ invalidate_dcache_range((ulong)rx_desc, (ulong)&rx_desc[1]);
+
length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN;
+ buffer = dm_pci_mem_to_virt(priv->dev, rx_desc->buffer_addr, length, 0);
+ invalidate_dcache_range((ulong)buffer, (ulong)buffer + length);
+ *packetp = (uchar *)buffer;
return length;
}
@@ -315,7 +328,7 @@ static int pch_gbe_free_pkt(struct udevice *dev, uchar *packet, int length)
if (++rx_swp >= PCH_GBE_DESC_NUM)
rx_swp = 0;
- writel(dm_pci_phys_to_mem(priv->dev, (ulong)(rx_head + rx_swp)),
+ writel(dm_pci_virt_to_mem(priv->dev, rx_head + rx_swp),
&mac_regs->rx_dsc_sw_p);
return 0;
@@ -422,6 +435,7 @@ int pch_gbe_probe(struct udevice *dev)
struct pch_gbe_priv *priv;
struct eth_pdata *plat = dev_get_platdata(dev);
void *iobase;
+ int err;
/*
* The priv structure contains the descriptors and frame buffers which
@@ -444,6 +458,10 @@ int pch_gbe_probe(struct udevice *dev)
pch_gbe_mdio_init(dev->name, priv->mac_regs);
priv->bus = miiphy_get_dev_by_name(dev->name);
+ err = pch_gbe_reset(dev);
+ if (err)
+ return err;
+
return pch_gbe_phy_init(dev);
}
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index ce1b30a4b6..0230852244 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -57,6 +57,40 @@ config PHY_MARVELL
config PHY_MICREL
bool "Micrel Ethernet PHYs support"
+ help
+ Enable support for the GbE PHYs manufactured by Micrel (now
+ a part of Microchip). This includes drivers for the KSZ804,
+ KSZ8031, KSZ8051, KSZ8081, KSZ8895, KSZ886x, KSZ8721
+ either/or KSZ9021 (see the "Micrel KSZ9021 family support"
+ config option for details), and KSZ9031 (if configured).
+
+if PHY_MICREL
+
+config PHY_MICREL_KSZ9021
+ bool "Micrel KSZ9021 family support"
+ select PHY_GIGE
+ help
+ Enable support for the Micrel KSZ9021 GbE PHY family. If
+ enabled, the extended register read/write for KSZ9021 PHYs
+ is supported through the 'mdio' command and any RGMII signal
+ delays configured in the device tree will be applied to the
+ PHY during initialisation.
+
+ Note that the KSZ9021 uses the same part number os the
+ KSZ8921BL, so enabling this option disables support for the
+ KSZ8721BL.
+
+config PHY_MICREL_KSZ9031
+ bool "Micrel KSZ9031 family support"
+ select PHY_GIGE
+ help
+ Enable support for the Micrel KSZ9031 GbE PHY family. If
+ enabled, the extended register read/write for KSZ9021 PHYs
+ is supported through the 'mdio' command and any RGMII signal
+ delays configured in the device tree will be applied to the
+ PHY during initialisatioin.
+
+endif # PHY_MICREL
config PHY_MICREL_KSZ9021
bool "Micrel KSZ9021 Ethernet PHYs support"
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index ab0c44354c..b7f300e40f 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -13,6 +13,8 @@
#define PHY_AUTONEGOTIATE_TIMEOUT 5000
+#define MII_MARVELL_PHY_PAGE 22
+
/* 88E1011 PHY Status Register */
#define MIIM_88E1xxx_PHY_STATUS 0x11
#define MIIM_88E1xxx_PHYSTAT_SPEED 0xc000
@@ -83,6 +85,11 @@
#define MIIM_88E1310_PHY_PAGE 22
/* 88E151x PHY defines */
+/* Page 2 registers */
+#define MIIM_88E151x_PHY_MSCR 21
+#define MIIM_88E151x_RGMII_RX_DELAY BIT(5)
+#define MIIM_88E151x_RGMII_TX_DELAY BIT(4)
+#define MIIM_88E151x_RGMII_RXTX_DELAY (BIT(5) | BIT(4))
/* Page 3 registers */
#define MIIM_88E151x_LED_FUNC_CTRL 16
#define MIIM_88E151x_LED_FLD_SZ 4
@@ -295,6 +302,8 @@ void m88e1518_phy_writebits(struct phy_device *phydev,
static int m88e1518_config(struct phy_device *phydev)
{
+ u16 reg;
+
/*
* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
* /88E1514 Rev A0, Errata Section 3.1
@@ -331,7 +340,41 @@ static int m88e1518_config(struct phy_device *phydev)
udelay(100);
}
- return m88e1111s_config(phydev);
+ if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
+ reg = phy_read(phydev, MDIO_DEVAD_NONE,
+ MIIM_88E1111_PHY_EXT_SR);
+
+ reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
+ reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK;
+ reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
+
+ phy_write(phydev, MDIO_DEVAD_NONE,
+ MIIM_88E1111_PHY_EXT_SR, reg);
+ }
+
+ if (phy_interface_is_rgmii(phydev)) {
+ phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 2);
+
+ reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR);
+ reg &= ~MIIM_88E151x_RGMII_RXTX_DELAY;
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ reg |= MIIM_88E151x_RGMII_RXTX_DELAY;
+ else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ reg |= MIIM_88E151x_RGMII_RX_DELAY;
+ else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ reg |= MIIM_88E151x_RGMII_TX_DELAY;
+ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR, reg);
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 0);
+ }
+
+ /* soft reset */
+ phy_reset(phydev);
+
+ genphy_config_aneg(phydev);
+ genphy_restart_aneg(phydev);
+
+ return 0;
}
/* Marvell 88E1510 */
@@ -439,7 +482,10 @@ static int m88e1145_config(struct phy_device *phydev)
genphy_config_aneg(phydev);
- phy_reset(phydev);
+ /* soft reset */
+ reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+ reg |= BMCR_RESET;
+ phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, reg);
return 0;
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 8bacd991ad..97e0bc022b 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -860,7 +860,7 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr,
#ifdef CONFIG_PHY_FIXED
int sn;
const char *name;
- sn = fdt_first_subnode(gd->fdt_blob, dev->of_offset);
+ sn = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev));
while (sn > 0) {
name = fdt_get_name(gd->fdt_blob, sn, NULL);
if (name != NULL && strcmp(name, "fixed-link") == 0) {
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index 1d870806a3..6ad31a0465 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -174,7 +174,7 @@ static int dp83867_of_init(struct phy_device *phydev)
{
struct dp83867_private *dp83867 = phydev->priv;
struct udevice *dev = phydev->dev;
- int node = dev->of_offset;
+ int node = dev_of_offset(dev);
const void *fdt = gd->fdt_blob;
if (fdtdec_get_bool(fdt, node, "ti,max-output-impedance"))
diff --git a/drivers/net/pic32_eth.c b/drivers/net/pic32_eth.c
index 385aad5b7e..0b89911f04 100644
--- a/drivers/net/pic32_eth.c
+++ b/drivers/net/pic32_eth.c
@@ -561,8 +561,7 @@ static int pic32_eth_probe(struct udevice *dev)
phy_addr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
/* phy reset gpio */
- gpio_request_by_name_nodev(gd->fdt_blob, dev_of_offset(dev),
- "reset-gpios", 0,
+ gpio_request_by_name_nodev(dev_ofnode(dev), "reset-gpios", 0,
&priv->rst_gpio, GPIOD_IS_OUT);
priv->phyif = pdata->phy_interface;
diff --git a/drivers/net/sandbox-raw.c b/drivers/net/sandbox-raw.c
index 9742c2c4f6..f5fa0e8533 100644
--- a/drivers/net/sandbox-raw.c
+++ b/drivers/net/sandbox-raw.c
@@ -145,7 +145,7 @@ static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
index 79d0ae68bf..59c57d1c6d 100644
--- a/drivers/net/sandbox.c
+++ b/drivers/net/sandbox.c
@@ -205,7 +205,7 @@ static int sb_eth_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index a3dbe2823b..09bbb2cdb5 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -776,8 +776,8 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
int ret = 0;
#endif
- pdata->iobase = dev_get_addr_name(dev, "emac");
- priv->sysctl_reg = dev_get_addr_name(dev, "syscon");
+ pdata->iobase = devfdt_get_addr_name(dev, "emac");
+ priv->sysctl_reg = devfdt_get_addr_name(dev, "syscon");
pdata->phy_interface = -1;
priv->phyaddr = -1;
@@ -820,7 +820,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
parse_phy_pins(dev);
#ifdef CONFIG_DM_GPIO
- if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
+ if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
"snps,reset-active-low"))
reset_flags |= GPIOD_ACTIVE_LOW;
@@ -828,7 +828,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
&priv->reset_gpio, reset_flags);
if (ret == 0) {
- ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
"snps,reset-delays-us",
sun8i_pdata->reset_delays, 3);
} else if (ret == -ENOENT) {
diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
index 99339db4bf..37685f30f3 100644
--- a/drivers/net/sunxi_emac.c
+++ b/drivers/net/sunxi_emac.c
@@ -576,7 +576,7 @@ static int sunxi_emac_eth_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
- pdata->iobase = dev_get_addr(dev);
+ pdata->iobase = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index f2ce4e2a8e..18e7a83d0f 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -780,7 +780,7 @@ int tsec_probe(struct udevice *dev)
const char *phy_mode;
int ret;
- pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+ pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
priv->regs = (struct tsec *)pdata->iobase;
offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index a6f24b3cbe..25c66c6098 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -686,7 +686,7 @@ static int axi_emac_ofdata_to_platdata(struct udevice *dev)
int offset = 0;
const char *phy_mode;
- pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+ pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
priv->iobase = (struct axi_regs *)pdata->iobase;
offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 7d4e14f8ef..e3e58aeb83 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -598,7 +598,7 @@ static int emaclite_ofdata_to_platdata(struct udevice *dev)
struct xemaclite *emaclite = dev_get_priv(dev);
int offset = 0;
- pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+ pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
emaclite->regs = (struct emaclite_regs *)ioremap_nocache(pdata->iobase,
0x10000);
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 357f8c2917..f6bbcdc48e 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -192,7 +192,7 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
int err;
err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
- true, 20000, true);
+ true, 20000, false);
if (err)
return err;
@@ -205,7 +205,7 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
writel(mgtcr, &regs->phymntnc);
err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
- true, 20000, true);
+ true, 20000, false);
if (err)
return err;
@@ -407,10 +407,6 @@ static int zynq_gem_init(struct udevice *dev)
dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
ZYNQ_GEM_RXBUF_NEW_MASK;
dummy_rx_bd->status = 0;
- flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
- sizeof(dummy_tx_bd));
- flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
- sizeof(dummy_rx_bd));
writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);
@@ -587,14 +583,12 @@ __weak int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
static int zynq_gem_read_rom_mac(struct udevice *dev)
{
- int retval;
struct eth_pdata *pdata = dev_get_platdata(dev);
- retval = zynq_board_read_rom_ethaddr(pdata->enetaddr);
- if (retval == -ENOSYS)
- retval = 0;
+ if (!pdata)
+ return -ENOSYS;
- return retval;
+ return zynq_board_read_rom_ethaddr(pdata->enetaddr);
}
static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr,
@@ -683,7 +677,7 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
int node = dev_of_offset(dev);
const char *phy_mode;
- pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+ pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
priv->iobase = (struct zynq_gem_regs *)pdata->iobase;
/* Hardcode for now */
priv->phyaddr = -1;
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 504d7e3bb1..b36ef3338c 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -8,12 +8,11 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
#include <inttypes.h>
#include <pci.h>
#include <asm/io.h>
-#include <dm/lists.h>
#include <dm/device-internal.h>
+#include <dm/lists.h>
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
#include <asm/fsp/fsp_support.h>
#endif
@@ -754,8 +753,8 @@ error:
return ret;
}
-static int decode_regions(struct pci_controller *hose, const void *blob,
- int parent_node, int node)
+static int decode_regions(struct pci_controller *hose, ofnode parent_node,
+ ofnode node)
{
int pci_addr_cells, addr_cells, size_cells;
phys_addr_t base = 0, size;
@@ -764,12 +763,12 @@ static int decode_regions(struct pci_controller *hose, const void *blob,
int len;
int i;
- prop = fdt_getprop(blob, node, "ranges", &len);
+ prop = ofnode_read_prop(node, "ranges", &len);
if (!prop)
return -EINVAL;
- pci_addr_cells = fdt_address_cells(blob, node);
- addr_cells = fdt_address_cells(blob, parent_node);
- size_cells = fdt_size_cells(blob, node);
+ pci_addr_cells = ofnode_read_addr_cells(node);
+ addr_cells = ofnode_read_addr_cells(parent_node);
+ size_cells = ofnode_read_size_cells(node);
/* PCI addresses are always 3-cells */
len /= sizeof(u32);
@@ -841,9 +840,8 @@ static int pci_uclass_pre_probe(struct udevice *bus)
/* For bridges, use the top-level PCI controller */
if (!device_is_on_pci_bus(bus)) {
hose->ctlr = bus;
- ret = decode_regions(hose, gd->fdt_blob,
- dev_of_offset(bus->parent),
- dev_of_offset(bus));
+ ret = decode_regions(hose, dev_ofnode(bus->parent),
+ dev_ofnode(bus));
if (ret) {
debug("%s: Cannot decode regions\n", __func__);
return ret;
@@ -906,7 +904,7 @@ static int pci_uclass_child_post_bind(struct udevice *dev)
struct fdt_pci_addr addr;
int ret;
- if (dev_of_offset(dev) == -1)
+ if (!dev_of_valid(dev))
return 0;
/*
@@ -914,8 +912,8 @@ static int pci_uclass_child_post_bind(struct udevice *dev)
* just check the address.
*/
pplat = dev_get_parent_platdata(dev);
- ret = fdtdec_get_pci_addr(gd->fdt_blob, dev_of_offset(dev),
- FDT_PCI_SPACE_CONFIG, "reg", &addr);
+ ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, "reg",
+ &addr);
if (ret) {
if (ret != -ENOENT)
diff --git a/drivers/pci/pci_indirect.c b/drivers/pci/pci_indirect.c
index aee0bd6d93..efa13a2393 100644
--- a/drivers/pci/pci_indirect.c
+++ b/drivers/pci/pci_indirect.c
@@ -17,22 +17,7 @@
#define cfg_read(val, addr, type, op) *val = op((type)(addr))
#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
-#if defined(CONFIG_MPC8260)
-#define INDIRECT_PCI_OP(rw, size, type, op, mask) \
-static int \
-indirect_##rw##_config_##size(struct pci_controller *hose, \
- pci_dev_t dev, int offset, type val) \
-{ \
- u32 b, d,f; \
- b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
- b = b - hose->first_busno; \
- dev = PCI_BDF(b, d, f); \
- out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \
- sync(); \
- cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
- return 0; \
-}
-#elif defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+#if defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
#define INDIRECT_PCI_OP(rw, size, type, op, mask) \
static int \
indirect_##rw##_config_##size(struct pci_controller *hose, \
diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c
index 05a06604e6..202cfe9d03 100644
--- a/drivers/pci/pcie_dw_mvebu.c
+++ b/drivers/pci/pcie_dw_mvebu.c
@@ -521,12 +521,12 @@ static int pcie_dw_mvebu_ofdata_to_platdata(struct udevice *dev)
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
/* Get the controller base address */
- pcie->ctrl_base = (void *)dev_get_addr_index(dev, 0);
+ pcie->ctrl_base = (void *)devfdt_get_addr_index(dev, 0);
if ((fdt_addr_t)pcie->ctrl_base == FDT_ADDR_T_NONE)
return -EINVAL;
/* Get the config space base address and size */
- pcie->cfg_base = (void *)dev_get_addr_size_index(dev, 1,
+ pcie->cfg_base = (void *)devfdt_get_addr_size_index(dev, 1,
&pcie->cfg_size);
if ((fdt_addr_t)pcie->cfg_base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index 7565e2fd92..78cde21cf4 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -13,6 +13,10 @@
#include <errno.h>
#include <malloc.h>
#include <dm.h>
+#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_ARM)
+#include <asm/arch/clock.h>
+#endif
#include "pcie_layerscape.h"
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/pci/pcie_layerscape_fixup.c b/drivers/pci/pcie_layerscape_fixup.c
index ce709bfc14..9e6c2f5dfc 100644
--- a/drivers/pci/pcie_layerscape_fixup.c
+++ b/drivers/pci/pcie_layerscape_fixup.c
@@ -14,6 +14,9 @@
#ifdef CONFIG_OF_BOARD_SETUP
#include <libfdt.h>
#include <fdt_support.h>
+#ifdef CONFIG_ARM
+#include <asm/arch/clock.h>
+#endif
#include "pcie_layerscape.h"
#if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index c506f796fa..b7e6188429 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -5,7 +5,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-$(CONFIG_8xx) += mpc8xx_pcmcia.o
obj-$(CONFIG_IDE_TI_CARDBUS) += ti_pci1410a.o
-obj-y += tqm8xx_pcmcia.o
obj-$(CONFIG_MARUBUN_PCCARD) += marubun_pcmcia.o
diff --git a/drivers/pcmcia/mpc8xx_pcmcia.c b/drivers/pcmcia/mpc8xx_pcmcia.c
deleted file mode 100644
index dae5560f8c..0000000000
--- a/drivers/pcmcia/mpc8xx_pcmcia.c
+++ /dev/null
@@ -1,258 +0,0 @@
-#include <common.h>
-#include <mpc8xx.h>
-#include <pcmcia.h>
-#include <linux/compiler.h>
-
-#undef CONFIG_PCMCIA
-
-#if defined(CONFIG_CMD_PCMCIA)
-#define CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
-#define CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_PCMCIA)
-
-#if defined(CONFIG_IDE_8xx_PCCARD)
-extern int check_ide_device (int slot);
-#endif
-
-extern int pcmcia_hardware_enable (int slot);
-extern int pcmcia_voltage_set(int slot, int vcc, int vpp);
-
-#if defined(CONFIG_CMD_PCMCIA)
-extern int pcmcia_hardware_disable(int slot);
-#endif
-
-static u_int m8xx_get_graycode(u_int size);
-#if 0 /* Disabled */
-static u_int m8xx_get_speed(u_int ns, u_int is_io);
-#endif
-
-/* look up table for pgcrx registers */
-u_int *pcmcia_pgcrx[2] = {
- &((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pgcra,
- &((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pgcrb,
-};
-
-/*
- * Search this table to see if the windowsize is
- * supported...
- */
-
-#define M8XX_SIZES_NO 32
-
-static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
-{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
- 0x00000080, 0x00000040, 0x00000010, 0x00000020,
- 0x00008000, 0x00004000, 0x00001000, 0x00002000,
- 0x00000100, 0x00000200, 0x00000800, 0x00000400,
-
- 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
- 0x00010000, 0x00020000, 0x00080000, 0x00040000,
- 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
-
-
-/* -------------------------------------------------------------------- */
-
-#define CONFIG_SYS_PCMCIA_TIMING ( PCMCIA_SHT(2) \
- | PCMCIA_SST(4) \
- | PCMCIA_SL(9))
-
-/* -------------------------------------------------------------------- */
-
-int pcmcia_on (void)
-{
- u_long reg, base;
- pcmcia_win_t *win;
- u_int rc, slot;
- __maybe_unused u_int slotbit;
- int i;
-
- debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
-
- /* intialize the fixed memory windows */
- win = (pcmcia_win_t *)(&((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pbr0);
- base = CONFIG_SYS_PCMCIA_MEM_ADDR;
-
- if((reg = m8xx_get_graycode(CONFIG_SYS_PCMCIA_MEM_SIZE)) == -1) {
- printf ("Cannot set window size to 0x%08x\n",
- CONFIG_SYS_PCMCIA_MEM_SIZE);
- return (1);
- }
-
- slotbit = PCMCIA_SLOT_x;
- for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
- win->br = base;
-
-#if (PCMCIA_SOCKETS_NO == 2)
- if (i == 4) /* Another slot starting from win 4 */
- slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
-#endif
- switch (i) {
-#ifdef CONFIG_IDE_8xx_PCCARD
- case 4:
- case 0: { /* map attribute memory */
- win->or = ( PCMCIA_BSIZE_64M
- | PCMCIA_PPS_8
- | PCMCIA_PRS_ATTR
- | slotbit
- | PCMCIA_PV
- | CONFIG_SYS_PCMCIA_TIMING );
- break;
- }
- case 5:
- case 1: { /* map I/O window for data reg */
- win->or = ( PCMCIA_BSIZE_1K
- | PCMCIA_PPS_16
- | PCMCIA_PRS_IO
- | slotbit
- | PCMCIA_PV
- | CONFIG_SYS_PCMCIA_TIMING );
- break;
- }
- case 6:
- case 2: { /* map I/O window for cmd/ctrl reg block */
- win->or = ( PCMCIA_BSIZE_1K
- | PCMCIA_PPS_8
- | PCMCIA_PRS_IO
- | slotbit
- | PCMCIA_PV
- | CONFIG_SYS_PCMCIA_TIMING );
- break;
- }
-#endif /* CONFIG_IDE_8xx_PCCARD */
- default: /* set to not valid */
- win->or = 0;
- break;
- }
-
- debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
- i, win->br, win->or);
- base += CONFIG_SYS_PCMCIA_MEM_SIZE;
- ++win;
- }
-
- for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
- /* turn off voltage */
- if ((rc = pcmcia_voltage_set(slot, 0, 0)))
- continue;
-
- /* Enable external hardware */
- if ((rc = pcmcia_hardware_enable(slot)))
- continue;
-
-#ifdef CONFIG_IDE_8xx_PCCARD
- if ((rc = check_ide_device(i)))
- continue;
-#endif
- }
- return rc;
-}
-
-#if defined(CONFIG_CMD_PCMCIA)
-int pcmcia_off (void)
-{
- int i;
- pcmcia_win_t *win;
-
- printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
-
- /* clear interrupt state, and disable interrupts */
- ((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
- ((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
-
- /* turn off interrupt and disable CxOE */
- PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
-
- /* turn off memory windows */
- win = (pcmcia_win_t *)(&((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pbr0);
-
- for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
- /* disable memory window */
- win->or = 0;
- ++win;
- }
-
- /* turn off voltage */
- pcmcia_voltage_set(_slot_, 0, 0);
-
- /* disable external hardware */
- printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
- pcmcia_hardware_disable(_slot_);
- return 0;
-}
-#endif
-
-
-static u_int m8xx_get_graycode(u_int size)
-{
- u_int k;
-
- for (k = 0; k < M8XX_SIZES_NO; k++) {
- if(m8xx_size_to_gray[k] == size)
- break;
- }
-
- if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
- k = -1;
-
- return k;
-}
-
-#if 0
-
-static u_int m8xx_get_speed(u_int ns, u_int is_io)
-{
- u_int reg, clocks, psst, psl, psht;
-
- if(!ns) {
-
- /*
- * We get called with IO maps setup to 0ns
- * if not specified by the user.
- * They should be 255ns.
- */
-
- if(is_io)
- ns = 255;
- else
- ns = 100; /* fast memory if 0 */
- }
-
- /*
- * In PSST, PSL, PSHT fields we tell the controller
- * timing parameters in CLKOUT clock cycles.
- * CLKOUT is the same as GCLK2_50.
- */
-
- /* how we want to adjust the timing - in percent */
-
-#define ADJ 180 /* 80 % longer accesstime - to be sure */
-
- clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
- clocks = (clocks * ADJ) / (100*1000);
-
- if(clocks >= PCMCIA_BMT_LIMIT) {
- DEBUG(0, "Max access time limit reached\n");
- clocks = PCMCIA_BMT_LIMIT-1;
- }
-
- psst = clocks / 7; /* setup time */
- psht = clocks / 7; /* hold time */
- psl = (clocks * 5) / 7; /* strobe length */
-
- psst += clocks - (psst + psht + psl);
-
- reg = psst << 12;
- reg |= psl << 7;
- reg |= psht << 16;
-
- return reg;
-}
-#endif /* 0 */
-
-#endif /* CONFIG_PCMCIA */
diff --git a/drivers/pcmcia/tqm8xx_pcmcia.c b/drivers/pcmcia/tqm8xx_pcmcia.c
deleted file mode 100644
index edff50f630..0000000000
--- a/drivers/pcmcia/tqm8xx_pcmcia.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/* -------------------------------------------------------------------- */
-/* TQM8xxL Boards by TQ Components */
-/* SC8xx Boards by SinoVee Microsystems */
-/* -------------------------------------------------------------------- */
-#include <common.h>
-#include <asm/io.h>
-#ifdef CONFIG_8xx
-#include <mpc8xx.h>
-#endif
-#include <pcmcia.h>
-
-#undef CONFIG_PCMCIA
-
-#if defined(CONFIG_CMD_PCMCIA)
-#define CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
-#define CONFIG_PCMCIA
-#endif
-
-#if defined(CONFIG_PCMCIA) \
- && defined(CONFIG_TQM8xxL)
-
-#if defined(CONFIG_TQM8xxL)
-#define PCMCIA_BOARD_MSG "TQM8xxL"
-#endif
-
-static inline void power_config(int slot)
-{
- immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
- /*
- * Configure Port C pins for
- * 5 Volts Enable and 3 Volts enable
- */
- clrbits_be16(&immap->im_ioport.iop_pcpar, 0x0002 | 0x0004);
- clrbits_be16(&immap->im_ioport.iop_pcso, 0x0002 | 0x0004);
-}
-
-static inline void power_off(int slot)
-{
- immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
- clrbits_be16(&immap->im_ioport.iop_pcdat, 0x0002 | 0x0004);
-}
-
-static inline void power_on_5_0(int slot)
-{
- immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
- setbits_be16(&immap->im_ioport.iop_pcdat, 0x0004);
- setbits_be16(&immap->im_ioport.iop_pcdir, 0x0002 | 0x0004);
-}
-
-static inline void power_on_3_3(int slot)
-{
- immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
- setbits_be16(&immap->im_ioport.iop_pcdat, 0x0002);
- setbits_be16(&immap->im_ioport.iop_pcdir, 0x0002 | 0x0004);
-}
-
-/*
- * Function to retrieve the PIPR register, used for debuging purposes.
- */
-static inline uint32_t debug_get_pipr(void)
-{
- uint32_t pipr = 0;
-#ifdef DEBUG
- immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
- pipr = in_be32(&immap->im_pcmcia.pcmc_pipr);
-#endif
- return pipr;
-}
-
-
-static inline int check_card_is_absent(int slot)
-{
- immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
- uint32_t pipr = in_be32(&immap->im_pcmcia.pcmc_pipr);
- return pipr & (0x18000000 >> (slot << 4));
-}
-
-#define NSCU_GCRX_CXOE __MY_PCMCIA_GCRX_CXOE
-
-int pcmcia_hardware_enable(int slot)
-{
- immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
- uint reg, mask;
-
- debug("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- udelay(10000);
-
- /*
- * Configure SIUMCR to enable PCMCIA port B
- * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
- */
-
- /* Set DBGC to 00 */
- clrbits_be32(&immap->im_siu_conf.sc_siumcr, SIUMCR_DBGC11);
-
- /* Clear interrupt state, and disable interrupts */
- out_be32(&immap->im_pcmcia.pcmc_pscr, PCMCIA_MASK(slot));
- clrbits_be32(&immap->im_pcmcia.pcmc_per, PCMCIA_MASK(slot));
-
- /*
- * Disable interrupts, DMA, and PCMCIA buffers
- * (isolate the interface) and assert RESET signal
- */
- debug("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= NSCU_GCRX_CXOE;
-
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
- power_config(slot);
- power_off(slot);
-
- /*
- * Make sure there is a card in the slot, then configure the interface.
- */
- udelay(10000);
- reg = debug_get_pipr();
- debug("[%d] %s: PIPR(%p)=0x%x\n", __LINE__, __FUNCTION__,
- &immap->im_pcmcia.pcmc_pipr, reg);
-
- if (check_card_is_absent(slot)) {
- printf (" No Card found\n");
- return (1);
- }
-
- /*
- * Power On.
- */
- mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
- reg = in_be32(&immap->im_pcmcia.pcmc_pipr);
- debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
- reg,
- (reg & PCMCIA_VS1(slot)) ? "n" : "ff",
- (reg & PCMCIA_VS2(slot)) ? "n" : "ff");
-
- if ((reg & mask) == mask) {
- power_on_5_0(slot);
- puts (" 5.0V card found: ");
- } else {
- power_on_3_3(slot);
- puts (" 3.3V card found: ");
- }
-
-#if 0
- /* VCC switch error flag, PCMCIA slot INPACK_ pin */
- cp->cp_pbdir &= ~(0x0020 | 0x0010);
- cp->cp_pbpar &= ~(0x0020 | 0x0010);
- udelay(500000);
-#endif
-
- udelay(1000);
- debug("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- reg &= ~NSCU_GCRX_CXOE;
-
- PCMCIA_PGCRX(slot) = reg;
-
- udelay(250000); /* some cards need >150 ms to come up :-( */
-
- debug("# hardware_enable done\n");
-
- return (0);
-}
-
-
-#if defined(CONFIG_CMD_PCMCIA)
-int pcmcia_hardware_disable(int slot)
-{
- u_long reg;
-
- debug("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
-
- /* remove all power */
- power_off(slot);
-
- debug("Disable PCMCIA buffers and assert RESET\n");
- reg = 0;
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= NSCU_GCRX_CXOE; /* active low */
-
- PCMCIA_PGCRX(slot) = reg;
-
- udelay(10000);
-
- return (0);
-}
-#endif
-
-int pcmcia_voltage_set(int slot, int vcc, int vpp)
-{
- u_long reg;
- uint32_t pipr = 0;
-
- debug("voltage_set: " PCMCIA_BOARD_MSG
- " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
- 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
-
- /*
- * Disable PCMCIA buffers (isolate the interface)
- * and assert RESET signal
- */
- debug("Disable PCMCIA buffers and assert RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
- reg |= NSCU_GCRX_CXOE; /* active low */
-
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
- debug("PCMCIA power OFF\n");
- power_config(slot);
- power_off(slot);
-
- switch(vcc) {
- case 0: break;
- case 33: power_on_3_3(slot); break;
- case 50: power_on_5_0(slot); break;
- default: goto done;
- }
-
- /* Checking supported voltages */
- pipr = debug_get_pipr();
- debug("PIPR: 0x%x --> %s\n", pipr,
- (pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
-
- if (vcc)
- debug("PCMCIA powered at %sV\n", (vcc == 50) ? "5.0" : "3.3");
- else
- debug("PCMCIA powered down\n");
-
-done:
- debug("Enable PCMCIA buffers and stop RESET\n");
- reg = PCMCIA_PGCRX(slot);
- reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
- reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
- reg &= ~NSCU_GCRX_CXOE; /* active low */
-
- PCMCIA_PGCRX(slot) = reg;
- udelay(500);
-
- debug("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
- return 0;
-}
-
-#endif /* CONFIG_PCMCIA && CONFIG_TQM8xxL */
diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c
index 596921b6c3..426db30f73 100644
--- a/drivers/phy/marvell/comphy_core.c
+++ b/drivers/phy/marvell/comphy_core.c
@@ -113,11 +113,11 @@ static int comphy_probe(struct udevice *dev)
static int current_idx;
/* Save base addresses for later use */
- chip_cfg->comphy_base_addr = (void *)dev_get_addr_index(dev, 0);
+ chip_cfg->comphy_base_addr = (void *)devfdt_get_addr_index(dev, 0);
if (IS_ERR(chip_cfg->comphy_base_addr))
return PTR_ERR(chip_cfg->comphy_base_addr);
- chip_cfg->hpipe3_base_addr = (void *)dev_get_addr_index(dev, 1);
+ chip_cfg->hpipe3_base_addr = (void *)devfdt_get_addr_index(dev, 1);
if (IS_ERR(chip_cfg->hpipe3_base_addr))
return PTR_ERR(chip_cfg->hpipe3_base_addr);
@@ -135,10 +135,10 @@ static int comphy_probe(struct udevice *dev)
return -EINVAL;
}
- if (of_device_is_compatible(dev, "marvell,comphy-armada-3700"))
+ if (device_is_compatible(dev, "marvell,comphy-armada-3700"))
chip_cfg->ptr_comphy_chip_init = comphy_a3700_init;
- if (of_device_is_compatible(dev, "marvell,comphy-cp110"))
+ if (device_is_compatible(dev, "marvell,comphy-cp110"))
chip_cfg->ptr_comphy_chip_init = comphy_cp110_init;
/*
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
index 0d8bef76db..d8b8d58e44 100644
--- a/drivers/phy/phy-uclass.c
+++ b/drivers/phy/phy-uclass.c
@@ -17,7 +17,7 @@ static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
}
static int generic_phy_xlate_offs_flags(struct phy *phy,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
debug("%s(phy=%p)\n", __func__, phy);
@@ -31,14 +31,13 @@ static int generic_phy_xlate_offs_flags(struct phy *phy,
else
phy->id = 0;
-
return 0;
}
int generic_phy_get_by_index(struct udevice *dev, int index,
struct phy *phy)
{
- struct fdtdec_phandle_args args;
+ struct ofnode_phandle_args args;
struct phy_ops *ops;
int ret;
struct udevice *phydev;
@@ -46,18 +45,17 @@ int generic_phy_get_by_index(struct udevice *dev, int index,
debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy);
assert(phy);
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
- "phys", "#phy-cells", 0, index,
- &args);
+ ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index,
+ &args);
if (ret) {
- debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
+ debug("%s: dev_read_phandle_with_args failed: err=%d\n",
__func__, ret);
return ret;
}
- ret = uclass_get_device_by_of_offset(UCLASS_PHY, args.node, &phydev);
+ ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
if (ret) {
- debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
+ debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
__func__, ret);
return ret;
}
@@ -88,10 +86,9 @@ int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
- index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
- "phy-names", phy_name);
+ index = dev_read_stringlist_search(dev, "phy-names", phy_name);
if (index < 0) {
- debug("fdt_stringlist_search() failed: %d\n", index);
+ debug("dev_read_stringlist_search() failed: %d\n", index);
return index;
}
diff --git a/drivers/phy/sandbox-phy.c b/drivers/phy/sandbox-phy.c
index 9ad820c24c..867c6fe704 100644
--- a/drivers/phy/sandbox-phy.c
+++ b/drivers/phy/sandbox-phy.c
@@ -80,8 +80,7 @@ static int sandbox_phy_probe(struct udevice *dev)
priv->initialized = false;
priv->on = false;
- priv->broken = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
- "broken");
+ priv->broken = dev_read_bool(dev, "broken");
return 0;
}
diff --git a/drivers/phy/ti-pipe3-phy.c b/drivers/phy/ti-pipe3-phy.c
index ed80f0ff0b..680e32f3ea 100644
--- a/drivers/phy/ti-pipe3-phy.c
+++ b/drivers/phy/ti-pipe3-phy.c
@@ -296,7 +296,7 @@ static void *get_reg(struct udevice *dev, const char *name)
return NULL;
}
- cell = fdt_getprop(gd->fdt_blob, dev->of_offset, name,
+ cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), name,
&len);
if (len < 2*sizeof(fdt32_t)) {
error("offset not available for %s\n", name);
@@ -316,7 +316,7 @@ static int pipe3_phy_probe(struct udevice *dev)
fdt_size_t sz;
struct omap_pipe3 *pipe3 = dev_get_priv(dev);
- addr = dev_get_addr_size_index(dev, 2, &sz);
+ addr = devfdt_get_addr_size_index(dev, 2, &sz);
if (addr == FDT_ADDR_T_NONE) {
error("missing pll ctrl address\n");
return -EINVAL;
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index f6616c5329..f948783170 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -69,6 +69,7 @@ config SPL_PINCTRL
config SPL_PINCTRL_FULL
bool "Support full pin controllers in SPL"
depends on SPL_PINCTRL && SPL_OF_CONTROL
+ default n if TARGET_STM32F746_DISCO
default y
help
This option is an SPL-variant of the PINCTRL_FULL option.
@@ -197,6 +198,16 @@ config PINCTRL_ROCKCHIP_RK3328
the GPIO definitions and pin control functions for each available
multiplex function.
+config PINCTRL_ROCKCHIP_RK3368
+ bool "Rockchip RK3368 pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rk3368 SoCs.
+
+ The driver is controlled by a device tree node which contains both
+ the GPIO definitions and pin control functions for each available
+ multiplex function.
+
config PINCTRL_ROCKCHIP_RK3399
bool "Rockchip rk3399 pin control driver"
depends on DM
@@ -207,6 +218,16 @@ config PINCTRL_ROCKCHIP_RK3399
the GPIO definitions and pin control functions for each available
multiplex function.
+config PINCTRL_ROCKCHIP_RV1108
+ bool "Rockchip rv1108 pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rv1108 SoC.
+
+ The driver is controlled by a device tree node which contains
+ both the GPIO definitions and pin control functions for each
+ available multiplex function.
+
config PINCTRL_SANDBOX
bool "Sandbox pinctrl driver"
depends on SANDBOX
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 1e5c4257c4..64da7c608b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -17,7 +17,7 @@ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o
obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/
obj-$(CONFIG_PINCTRL_MESON) += meson/
-obj-$(CONFIG_PINCTRL_MVEBU) += mvebu/
+obj-$(CONFIG_ARCH_MVEBU) += mvebu/
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o
diff --git a/drivers/pinctrl/ath79/pinctrl_ar933x.c b/drivers/pinctrl/ath79/pinctrl_ar933x.c
index fccc7c4b06..83f4d5332a 100644
--- a/drivers/pinctrl/ath79/pinctrl_ar933x.c
+++ b/drivers/pinctrl/ath79/pinctrl_ar933x.c
@@ -111,7 +111,7 @@ static int ar933x_pinctrl_probe(struct udevice *dev)
struct ar933x_pinctrl_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/pinctrl/ath79/pinctrl_qca953x.c b/drivers/pinctrl/ath79/pinctrl_qca953x.c
index a7f8c7082e..abc0368593 100644
--- a/drivers/pinctrl/ath79/pinctrl_qca953x.c
+++ b/drivers/pinctrl/ath79/pinctrl_qca953x.c
@@ -131,7 +131,7 @@ static int qca953x_pinctrl_probe(struct udevice *dev)
struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.c b/drivers/pinctrl/exynos/pinctrl-exynos.c
index 5b9a592b0d..95610a7e16 100644
--- a/drivers/pinctrl/exynos/pinctrl-exynos.c
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.c
@@ -128,7 +128,7 @@ int exynos_pinctrl_probe(struct udevice *dev)
if (!priv)
return -EINVAL;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
index a0a7de5f0f..2fa840c21a 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
@@ -7,7 +7,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include <dt-bindings/gpio/meson-gxbb-gpio.h>
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index b5486b8fe4..6281f529ea 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -5,7 +5,7 @@
*/
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include <fdt_support.h>
#include <linux/err.h>
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig
index cf9c299f13..a9388ff7e2 100644
--- a/drivers/pinctrl/mvebu/Kconfig
+++ b/drivers/pinctrl/mvebu/Kconfig
@@ -1,7 +1,17 @@
-config PINCTRL_MVEBU
- depends on ARCH_MVEBU
- bool
- default y
+if ARCH_MVEBU
+
+config PINCTRL_ARMADA_37XX
+ depends on ARMADA_3700
+ bool "Armada 37xx pin control driver"
+ help
+ Support pin multiplexing and pin configuration control on
+ Marvell's Armada-37xx SoC.
+
+config PINCTRL_ARMADA_8K
+ depends on ARMADA_8K
+ bool "Armada 7k/8k pin control driver"
help
Support pin multiplexing and pin configuration control on
Marvell's Armada-8K SoC.
+
+endif
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile
index f4f78640b9..13a38d5a1a 100644
--- a/drivers/pinctrl/mvebu/Makefile
+++ b/drivers/pinctrl/mvebu/Makefile
@@ -4,4 +4,5 @@
# SPDX-License-Identifier: GPL-2.0
# https://spdx.org/licenses
-obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
+obj-$(CONFIG_PINCTRL_ARMADA_37XX) += pinctrl-armada-37xx.o
+obj-$(CONFIG_PINCTRL_ARMADA_8K) += pinctrl-mvebu.o
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
new file mode 100644
index 0000000000..27165b0007
--- /dev/null
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -0,0 +1,632 @@
+/*
+ * U-Boot Marvell 37xx SoC pinctrl driver
+ *
+ * Copyright (C) 2017 Stefan Roese <sr@denx.de>
+ *
+ * This driver is based on the Linux driver version, which is:
+ * Copyright (C) 2017 Marvell
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * Additionally parts are derived from the Meson U-Boot pinctrl driver,
+ * which is:
+ * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
+ * Based on code from Linux kernel:
+ * Copyright (C) 2016 Endless Mobile, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ * https://spdx.org/licenses
+ */
+
+#include <common.h>
+#include <config.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <regmap.h>
+#include <asm/gpio.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define OUTPUT_EN 0x0
+#define INPUT_VAL 0x10
+#define OUTPUT_VAL 0x18
+#define OUTPUT_CTL 0x20
+#define SELECTION 0x30
+
+#define IRQ_EN 0x0
+#define IRQ_POL 0x08
+#define IRQ_STATUS 0x10
+#define IRQ_WKUP 0x18
+
+#define NB_FUNCS 2
+#define GPIO_PER_REG 32
+
+/**
+ * struct armada_37xx_pin_group: represents group of pins of a pinmux function.
+ * The pins of a pinmux groups are composed of one or two groups of contiguous
+ * pins.
+ * @name: Name of the pin group, used to lookup the group.
+ * @start_pins: Index of the first pin of the main range of pins belonging to
+ * the group
+ * @npins: Number of pins included in the first range
+ * @reg_mask: Bit mask matching the group in the selection register
+ * @extra_pins: Index of the first pin of the optional second range of pins
+ * belonging to the group
+ * @npins: Number of pins included in the second optional range
+ * @funcs: A list of pinmux functions that can be selected for this group.
+ * @pins: List of the pins included in the group
+ */
+struct armada_37xx_pin_group {
+ const char *name;
+ unsigned int start_pin;
+ unsigned int npins;
+ u32 reg_mask;
+ u32 val[NB_FUNCS];
+ unsigned int extra_pin;
+ unsigned int extra_npins;
+ const char *funcs[NB_FUNCS];
+ unsigned int *pins;
+};
+
+struct armada_37xx_pin_data {
+ u8 nr_pins;
+ char *name;
+ struct armada_37xx_pin_group *groups;
+ int ngroups;
+};
+
+struct armada_37xx_pmx_func {
+ const char *name;
+ const char **groups;
+ unsigned int ngroups;
+};
+
+struct armada_37xx_pinctrl {
+ void __iomem *base;
+ const struct armada_37xx_pin_data *data;
+ struct udevice *dev;
+ struct pinctrl_dev *pctl_dev;
+ struct armada_37xx_pin_group *groups;
+ unsigned int ngroups;
+ struct armada_37xx_pmx_func *funcs;
+ unsigned int nfuncs;
+};
+
+#define PIN_GRP(_name, _start, _nr, _mask, _func1, _func2) \
+ { \
+ .name = _name, \
+ .start_pin = _start, \
+ .npins = _nr, \
+ .reg_mask = _mask, \
+ .val = {0, _mask}, \
+ .funcs = {_func1, _func2} \
+ }
+
+#define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \
+ { \
+ .name = _name, \
+ .start_pin = _start, \
+ .npins = _nr, \
+ .reg_mask = _mask, \
+ .val = {0, _mask}, \
+ .funcs = {_func1, "gpio"} \
+ }
+
+#define PIN_GRP_GPIO_2(_name, _start, _nr, _mask, _val1, _val2, _func1) \
+ { \
+ .name = _name, \
+ .start_pin = _start, \
+ .npins = _nr, \
+ .reg_mask = _mask, \
+ .val = {_val1, _val2}, \
+ .funcs = {_func1, "gpio"} \
+ }
+
+#define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
+ _f1, _f2) \
+ { \
+ .name = _name, \
+ .start_pin = _start, \
+ .npins = _nr, \
+ .reg_mask = _mask, \
+ .val = {_v1, _v2}, \
+ .extra_pin = _start2, \
+ .extra_npins = _nr2, \
+ .funcs = {_f1, _f2} \
+ }
+
+static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
+ PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"),
+ PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"),
+ PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
+ PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"),
+ PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"),
+ PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"),
+ PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"),
+ PIN_GRP_GPIO("pmic1", 17, 1, BIT(7), "pmic"),
+ PIN_GRP_GPIO("pmic0", 16, 1, BIT(8), "pmic"),
+ PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
+ PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"),
+ PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"),
+ PIN_GRP_GPIO_2("spi_cs2", 18, 1, BIT(13) | BIT(19), 0, BIT(13), "spi"),
+ PIN_GRP_GPIO_2("spi_cs3", 19, 1, BIT(14) | BIT(19), 0, BIT(14), "spi"),
+ PIN_GRP_GPIO("onewire", 4, 1, BIT(16), "onewire"),
+ PIN_GRP_GPIO("uart1", 25, 2, BIT(17), "uart"),
+ PIN_GRP_GPIO("spi_quad", 15, 2, BIT(18), "spi"),
+ PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19),
+ BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19),
+ 18, 2, "gpio", "uart"),
+ PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"),
+ PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"),
+ PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"),
+ PIN_GRP_GPIO("led3_od", 14, 1, BIT(23), "led"),
+
+};
+
+static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
+ PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
+ PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
+ PIN_GRP_GPIO("sdio_sb", 24, 5, BIT(2), "sdio"),
+ PIN_GRP_EXTRA("rgmii", 6, 14, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
+ PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"),
+ PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"),
+ PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
+ PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"),
+ PIN_GRP("mii_col", 23, 1, BIT(8), "mii", "mii_err"),
+};
+
+const struct armada_37xx_pin_data armada_37xx_pin_nb = {
+ .nr_pins = 36,
+ .name = "GPIO1",
+ .groups = armada_37xx_nb_groups,
+ .ngroups = ARRAY_SIZE(armada_37xx_nb_groups),
+};
+
+const struct armada_37xx_pin_data armada_37xx_pin_sb = {
+ .nr_pins = 29,
+ .name = "GPIO2",
+ .groups = armada_37xx_sb_groups,
+ .ngroups = ARRAY_SIZE(armada_37xx_sb_groups),
+};
+
+static inline void armada_37xx_update_reg(unsigned int *reg,
+ unsigned int offset)
+{
+ /* We never have more than 2 registers */
+ if (offset >= GPIO_PER_REG) {
+ offset -= GPIO_PER_REG;
+ *reg += sizeof(u32);
+ }
+}
+
+static int armada_37xx_get_func_reg(struct armada_37xx_pin_group *grp,
+ const char *func)
+{
+ int f;
+
+ for (f = 0; f < NB_FUNCS; f++)
+ if (!strcmp(grp->funcs[f], func))
+ return f;
+
+ return -ENOTSUPP;
+}
+
+static int armada_37xx_pmx_get_groups_count(struct udevice *dev)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev);
+
+ return info->ngroups;
+}
+
+static const char *armada_37xx_pmx_dummy_name = "_dummy";
+
+static const char *armada_37xx_pmx_get_group_name(struct udevice *dev,
+ unsigned selector)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev);
+
+ if (!info->groups[selector].name)
+ return armada_37xx_pmx_dummy_name;
+
+ return info->groups[selector].name;
+}
+
+static int armada_37xx_pmx_get_funcs_count(struct udevice *dev)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev);
+
+ return info->nfuncs;
+}
+
+static const char *armada_37xx_pmx_get_func_name(struct udevice *dev,
+ unsigned selector)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev);
+
+ return info->funcs[selector].name;
+}
+
+static int armada_37xx_pmx_set_by_name(struct udevice *dev,
+ const char *name,
+ struct armada_37xx_pin_group *grp)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev);
+ unsigned int reg = SELECTION;
+ unsigned int mask = grp->reg_mask;
+ int func, val;
+
+ dev_dbg(info->dev, "enable function %s group %s\n",
+ name, grp->name);
+
+ func = armada_37xx_get_func_reg(grp, name);
+
+ if (func < 0)
+ return func;
+
+ val = grp->val[func];
+
+ clrsetbits_le32(info->base + reg, mask, val);
+
+ return 0;
+}
+
+static int armada_37xx_pmx_group_set(struct udevice *dev,
+ unsigned group_selector,
+ unsigned func_selector)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev);
+ struct armada_37xx_pin_group *grp = &info->groups[group_selector];
+ const char *name = info->funcs[func_selector].name;
+
+ return armada_37xx_pmx_set_by_name(dev, name, grp);
+}
+
+/**
+ * armada_37xx_add_function() - Add a new function to the list
+ * @funcs: array of function to add the new one
+ * @funcsize: size of the remaining space for the function
+ * @name: name of the function to add
+ *
+ * If it is a new function then create it by adding its name else
+ * increment the number of group associated to this function.
+ */
+static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
+ int *funcsize, const char *name)
+{
+ int i = 0;
+
+ if (*funcsize <= 0)
+ return -EOVERFLOW;
+
+ while (funcs->ngroups) {
+ /* function already there */
+ if (strcmp(funcs->name, name) == 0) {
+ funcs->ngroups++;
+
+ return -EEXIST;
+ }
+ funcs++;
+ i++;
+ }
+
+ /* append new unique function */
+ funcs->name = name;
+ funcs->ngroups = 1;
+ (*funcsize)--;
+
+ return 0;
+}
+
+/**
+ * armada_37xx_fill_group() - complete the group array
+ * @info: info driver instance
+ *
+ * Based on the data available from the armada_37xx_pin_group array
+ * completes the last member of the struct for each function: the list
+ * of the groups associated to this function.
+ *
+ */
+static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
+{
+ int n, num = 0, funcsize = info->data->nr_pins;
+
+ for (n = 0; n < info->ngroups; n++) {
+ struct armada_37xx_pin_group *grp = &info->groups[n];
+ int i, j, f;
+
+ grp->pins = devm_kzalloc(info->dev,
+ (grp->npins + grp->extra_npins) *
+ sizeof(*grp->pins), GFP_KERNEL);
+ if (!grp->pins)
+ return -ENOMEM;
+
+ for (i = 0; i < grp->npins; i++)
+ grp->pins[i] = grp->start_pin + i;
+
+ for (j = 0; j < grp->extra_npins; j++)
+ grp->pins[i+j] = grp->extra_pin + j;
+
+ for (f = 0; f < NB_FUNCS; f++) {
+ int ret;
+ /* check for unique functions and count groups */
+ ret = armada_37xx_add_function(info->funcs, &funcsize,
+ grp->funcs[f]);
+ if (ret == -EOVERFLOW)
+ dev_err(info->dev,
+ "More functions than pins(%d)\n",
+ info->data->nr_pins);
+ if (ret < 0)
+ continue;
+ num++;
+ }
+ }
+
+ info->nfuncs = num;
+
+ return 0;
+}
+
+/**
+ * armada_37xx_fill_funcs() - complete the funcs array
+ * @info: info driver instance
+ *
+ * Based on the data available from the armada_37xx_pin_group array
+ * completes the last two member of the struct for each group:
+ * - the list of the pins included in the group
+ * - the list of pinmux functions that can be selected for this group
+ *
+ */
+static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
+{
+ struct armada_37xx_pmx_func *funcs = info->funcs;
+ int n;
+
+ for (n = 0; n < info->nfuncs; n++) {
+ const char *name = funcs[n].name;
+ const char **groups;
+ int g;
+
+ funcs[n].groups = devm_kzalloc(info->dev, funcs[n].ngroups *
+ sizeof(*(funcs[n].groups)),
+ GFP_KERNEL);
+ if (!funcs[n].groups)
+ return -ENOMEM;
+
+ groups = funcs[n].groups;
+
+ for (g = 0; g < info->ngroups; g++) {
+ struct armada_37xx_pin_group *gp = &info->groups[g];
+ int f;
+
+ for (f = 0; f < NB_FUNCS; f++) {
+ if (strcmp(gp->funcs[f], name) == 0) {
+ *groups = gp->name;
+ groups++;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static int armada_37xx_gpio_get(struct udevice *dev, unsigned int offset)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
+ unsigned int reg = INPUT_VAL;
+ unsigned int val, mask;
+
+ armada_37xx_update_reg(&reg, offset);
+ mask = BIT(offset);
+
+ val = readl(info->base + reg);
+
+ return (val & mask) != 0;
+}
+
+static int armada_37xx_gpio_set(struct udevice *dev, unsigned int offset,
+ int value)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
+ unsigned int reg = OUTPUT_VAL;
+ unsigned int mask, val;
+
+ armada_37xx_update_reg(&reg, offset);
+ mask = BIT(offset);
+ val = value ? mask : 0;
+
+ clrsetbits_le32(info->base + reg, mask, val);
+
+ return 0;
+}
+
+static int armada_37xx_gpio_get_direction(struct udevice *dev,
+ unsigned int offset)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
+ unsigned int reg = OUTPUT_EN;
+ unsigned int val, mask;
+
+ armada_37xx_update_reg(&reg, offset);
+ mask = BIT(offset);
+ val = readl(info->base + reg);
+
+ if (val & mask)
+ return GPIOF_OUTPUT;
+ else
+ return GPIOF_INPUT;
+}
+
+static int armada_37xx_gpio_direction_input(struct udevice *dev,
+ unsigned int offset)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
+ unsigned int reg = OUTPUT_EN;
+ unsigned int mask;
+
+ armada_37xx_update_reg(&reg, offset);
+ mask = BIT(offset);
+
+ clrbits_le32(info->base + reg, mask);
+
+ return 0;
+}
+
+static int armada_37xx_gpio_direction_output(struct udevice *dev,
+ unsigned int offset, int value)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
+ unsigned int reg = OUTPUT_EN;
+ unsigned int mask;
+
+ armada_37xx_update_reg(&reg, offset);
+ mask = BIT(offset);
+
+ setbits_le32(info->base + reg, mask);
+
+ /* And set the requested value */
+ return armada_37xx_gpio_set(dev, offset, value);
+}
+
+static int armada_37xx_gpio_probe(struct udevice *dev)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
+ struct gpio_dev_priv *uc_priv;
+
+ uc_priv = dev_get_uclass_priv(dev);
+ uc_priv->bank_name = info->data->name;
+ uc_priv->gpio_count = info->data->nr_pins;
+
+ return 0;
+}
+
+static const struct dm_gpio_ops armada_37xx_gpio_ops = {
+ .set_value = armada_37xx_gpio_set,
+ .get_value = armada_37xx_gpio_get,
+ .get_function = armada_37xx_gpio_get_direction,
+ .direction_input = armada_37xx_gpio_direction_input,
+ .direction_output = armada_37xx_gpio_direction_output,
+};
+
+static struct driver armada_37xx_gpio_driver = {
+ .name = "armada-37xx-gpio",
+ .id = UCLASS_GPIO,
+ .probe = armada_37xx_gpio_probe,
+ .ops = &armada_37xx_gpio_ops,
+};
+
+static int armada_37xx_gpiochip_register(struct udevice *parent,
+ struct armada_37xx_pinctrl *info)
+{
+ const void *blob = gd->fdt_blob;
+ int node = dev_of_offset(parent);
+ struct uclass_driver *drv;
+ struct udevice *dev;
+ int ret = -ENODEV;
+ int subnode;
+ char *name;
+
+ /* Lookup GPIO driver */
+ drv = lists_uclass_lookup(UCLASS_GPIO);
+ if (!drv) {
+ puts("Cannot find GPIO driver\n");
+ return -ENOENT;
+ }
+
+ fdt_for_each_subnode(subnode, blob, node) {
+ if (fdtdec_get_bool(blob, subnode, "gpio-controller")) {
+ ret = 0;
+ break;
+ }
+ };
+ if (ret)
+ return ret;
+
+ name = calloc(1, 32);
+ sprintf(name, "armada-37xx-gpio");
+
+ /* Create child device UCLASS_GPIO and bind it */
+ device_bind(parent, &armada_37xx_gpio_driver, name, NULL, subnode,
+ &dev);
+ dev_set_of_offset(dev, subnode);
+
+ return 0;
+}
+
+const struct pinctrl_ops armada_37xx_pinctrl_ops = {
+ .get_groups_count = armada_37xx_pmx_get_groups_count,
+ .get_group_name = armada_37xx_pmx_get_group_name,
+ .get_functions_count = armada_37xx_pmx_get_funcs_count,
+ .get_function_name = armada_37xx_pmx_get_func_name,
+ .pinmux_group_set = armada_37xx_pmx_group_set,
+ .set_state = pinctrl_generic_set_state,
+};
+
+int armada_37xx_pinctrl_probe(struct udevice *dev)
+{
+ struct armada_37xx_pinctrl *info = dev_get_priv(dev);
+ const struct armada_37xx_pin_data *pin_data;
+ int ret;
+
+ info->data = (struct armada_37xx_pin_data *)dev_get_driver_data(dev);
+ pin_data = info->data;
+
+ info->base = (void __iomem *)devfdt_get_addr(dev);
+ if (!info->base) {
+ error("unable to find regmap\n");
+ return -ENODEV;
+ }
+
+ info->groups = pin_data->groups;
+ info->ngroups = pin_data->ngroups;
+
+ /*
+ * we allocate functions for number of pins and hope there are
+ * fewer unique functions than pins available
+ */
+ info->funcs = devm_kzalloc(info->dev, pin_data->nr_pins *
+ sizeof(struct armada_37xx_pmx_func), GFP_KERNEL);
+ if (!info->funcs)
+ return -ENOMEM;
+
+
+ ret = armada_37xx_fill_group(info);
+ if (ret)
+ return ret;
+
+ ret = armada_37xx_fill_func(info);
+ if (ret)
+ return ret;
+
+ ret = armada_37xx_gpiochip_register(dev, info);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct udevice_id armada_37xx_pinctrl_of_match[] = {
+ {
+ .compatible = "marvell,armada3710-sb-pinctrl",
+ .data = (ulong)&armada_37xx_pin_sb,
+ },
+ {
+ .compatible = "marvell,armada3710-nb-pinctrl",
+ .data = (ulong)&armada_37xx_pin_nb,
+ },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(armada_37xx_pinctrl) = {
+ .name = "armada-37xx-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = of_match_ptr(armada_37xx_pinctrl_of_match),
+ .probe = armada_37xx_pinctrl_probe,
+ .priv_auto_alloc_size = sizeof(struct armada_37xx_pinctrl),
+ .ops = &armada_37xx_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index 80f0dfaf91..ec1958382a 100644
--- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -137,7 +137,7 @@ int mvebu_pinctl_probe(struct udevice *dev)
return -EINVAL;
}
- priv->base_reg = dev_get_addr_ptr(dev);
+ priv->base_reg = devfdt_get_addr_ptr(dev);
if (priv->base_reg == (void *)FDT_ADDR_T_NONE) {
debug("%s: Failed to get base address\n", __func__);
return -EINVAL;
diff --git a/drivers/pinctrl/nxp/pinctrl-imx.c b/drivers/pinctrl/nxp/pinctrl-imx.c
index ebc14a31f1..1b6107fae6 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx.c
@@ -8,7 +8,7 @@
#include <mapmem.h>
#include <linux/io.h>
#include <linux/err.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
diff --git a/drivers/pinctrl/nxp/pinctrl-imx5.c b/drivers/pinctrl/nxp/pinctrl-imx5.c
index 6942f39670..f1c655f4cb 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx5.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx5.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
diff --git a/drivers/pinctrl/nxp/pinctrl-imx6.c b/drivers/pinctrl/nxp/pinctrl-imx6.c
index 4488b16011..0f767d9079 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx6.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx6.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
diff --git a/drivers/pinctrl/nxp/pinctrl-imx7.c b/drivers/pinctrl/nxp/pinctrl-imx7.c
index eeb79426df..1f3e4231bc 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx7.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx7.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
diff --git a/drivers/pinctrl/nxp/pinctrl-imx7ulp.c b/drivers/pinctrl/nxp/pinctrl-imx7ulp.c
index 5f011757d8..4a893e5a65 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx7ulp.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx7ulp.c
@@ -6,7 +6,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
index 5c6bff568a..1abfc50f66 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -8,7 +8,7 @@
*/
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include <linux/io.h>
#include <linux/err.h>
@@ -158,7 +158,7 @@ static int atmel_pinctrl_probe(struct udevice *dev)
fdt_addr_t addr_base;
dev = dev_get_parent(dev);
- addr_base = dev_get_addr(dev);
+ addr_base = devfdt_get_addr(dev);
if (addr_base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 904e1bdc68..38c435e37a 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -8,7 +8,7 @@
*/
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include <linux/io.h>
#include <linux/err.h>
@@ -364,7 +364,7 @@ static int at91_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
struct at91_pinctrl_priv *priv = dev_get_priv(dev);
const void *blob = gd->fdt_blob;
- int node = config->of_offset;
+ int node = dev_of_offset(config);
u32 cells[MAX_PINMUX_ENTRIES];
const u32 *list = cells;
u32 bank, pin;
@@ -424,7 +424,7 @@ static int at91_pinctrl_probe(struct udevice *dev)
int index;
for (index = 0; index < MAX_GPIO_BANKS; index++) {
- addr_base = dev_get_addr_index(dev, index);
+ addr_base = devfdt_get_addr_index(dev, index);
if (addr_base == FDT_ADDR_T_NONE)
break;
diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
index 0272496b51..49e36480df 100644
--- a/drivers/pinctrl/pinctrl-generic.c
+++ b/drivers/pinctrl/pinctrl-generic.c
@@ -5,8 +5,8 @@
*/
#include <common.h>
+#include <dm.h>
#include <linux/compat.h>
-#include <dm/device.h>
#include <dm/pinctrl.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/pinctrl/pinctrl-sandbox.c b/drivers/pinctrl/pinctrl-sandbox.c
index ab03d8bad4..e77b49c168 100644
--- a/drivers/pinctrl/pinctrl-sandbox.c
+++ b/drivers/pinctrl/pinctrl-sandbox.c
@@ -7,7 +7,7 @@
/* #define DEBUG */
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/pinctrl.h>
static const char * const sandbox_pins[] = {
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index f19f7791f0..a38d774ddc 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -5,7 +5,7 @@
*/
#include <common.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include <libfdt.h>
#include <asm/io.h>
@@ -79,7 +79,8 @@ static int single_set_state(struct udevice *dev,
const struct single_fdt_pin_cfg *prop;
int len;
- prop = fdt_getprop(fdt, config->of_offset, "pinctrl-single,pins", &len);
+ prop = fdt_getprop(fdt, dev_of_offset(config), "pinctrl-single,pins",
+ &len);
if (prop) {
dev_dbg(dev, "configuring pins for %s\n", config->name);
if (len % sizeof(struct single_fdt_pin_cfg)) {
@@ -100,23 +101,23 @@ static int single_ofdata_to_platdata(struct udevice *dev)
int res;
struct single_pdata *pdata = dev->platdata;
- pdata->width = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ pdata->width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"pinctrl-single,register-width", 0);
- res = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
+ res = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
"reg", of_reg, 2);
if (res)
return res;
pdata->offset = of_reg[1] - pdata->width / 8;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE) {
dev_dbg(dev, "no valid base register address\n");
return -EINVAL;
}
pdata->base = addr;
- pdata->mask = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ pdata->mask = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"pinctrl-single,function-mask",
0xffffffff);
return 0;
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index 9efad0623a..02e269020d 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -8,10 +8,9 @@
#include <libfdt.h>
#include <linux/err.h>
#include <linux/list.h>
-#include <dm/device.h>
+#include <dm.h>
#include <dm/lists.h>
#include <dm/pinctrl.h>
-#include <dm/uclass.h>
#include <dm/util.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -122,34 +121,31 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
*/
static int pinconfig_post_bind(struct udevice *dev)
{
- const void *fdt = gd->fdt_blob;
- int offset = dev_of_offset(dev);
bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
const char *name;
+ ofnode node;
int ret;
- for (offset = fdt_first_subnode(fdt, offset);
- offset > 0;
- offset = fdt_next_subnode(fdt, offset)) {
+ dev_for_each_subnode(node, dev) {
if (pre_reloc_only &&
- !dm_fdt_pre_reloc(fdt, offset))
+ !ofnode_pre_reloc(node))
continue;
/*
* If this node has "compatible" property, this is not
* a pin configuration node, but a normal device. skip.
*/
- fdt_get_property(fdt, offset, "compatible", &ret);
+ ofnode_read_prop(node, "compatible", &ret);
if (ret >= 0)
continue;
if (ret != -FDT_ERR_NOTFOUND)
return ret;
- name = fdt_get_name(fdt, offset, NULL);
+ name = ofnode_get_name(node);
if (!name)
return -EINVAL;
ret = device_bind_driver_to_node(dev, "pinconfig", name,
- offset, NULL);
+ node, NULL);
if (ret)
return ret;
}
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index d7b5ea3e1c..5bee7fb12a 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -101,7 +101,7 @@ static int stm32_pinctrl_set_state_simple(struct udevice *dev,
int rv, len;
/* Get node pinctrl-0 */
- rv = fdtdec_parse_phandle_with_args(gd->fdt_blob, periph->of_offset,
+ rv = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(periph),
"pinctrl-0", 0, 0, 0, &args);
if (rv)
return rv;
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 69eef4c024..a1c655d537 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -9,4 +9,6 @@ obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3036) += pinctrl_rk3036.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3188) += pinctrl_rk3188.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3288) += pinctrl_rk3288.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3328) += pinctrl_rk3328.o
+obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3368) += pinctrl_rk3368.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3399) += pinctrl_rk3399.o
+obj-$(CONFIG_PINCTRL_ROCKCHIP_RV1108) += pinctrl_rv1108.o
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3036.c b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
index 8d42584b31..9215d6c96e 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3036.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3036.c
@@ -26,19 +26,19 @@ static void pinctrl_rk3036_pwm_config(struct rk3036_grf *grf, int pwm_id)
{
switch (pwm_id) {
case PERIPH_ID_PWM0:
- rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK << GPIO0D2_SHIFT,
+ rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK,
GPIO0D2_PWM0 << GPIO0D2_SHIFT);
break;
case PERIPH_ID_PWM1:
- rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK << GPIO0A0_SHIFT,
+ rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK,
GPIO0A0_PWM1 << GPIO0A0_SHIFT);
break;
case PERIPH_ID_PWM2:
- rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK << GPIO0A1_SHIFT,
+ rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK,
GPIO0A1_PWM2 << GPIO0A1_SHIFT);
break;
case PERIPH_ID_PWM3:
- rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK << GPIO0D3_SHIFT,
+ rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK,
GPIO0D3_PWM3 << GPIO0D3_SHIFT);
break;
default:
@@ -52,23 +52,20 @@ static void pinctrl_rk3036_i2c_config(struct rk3036_grf *grf, int i2c_id)
switch (i2c_id) {
case PERIPH_ID_I2C0:
rk_clrsetreg(&grf->gpio0a_iomux,
- GPIO0A1_MASK << GPIO0A1_SHIFT |
- GPIO0A0_MASK << GPIO0A0_SHIFT,
+ GPIO0A1_MASK | GPIO0A0_MASK,
GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
break;
case PERIPH_ID_I2C1:
rk_clrsetreg(&grf->gpio0a_iomux,
- GPIO0A3_MASK << GPIO0A3_SHIFT |
- GPIO0A2_MASK << GPIO0A2_SHIFT,
+ GPIO0A3_MASK | GPIO0A2_MASK,
GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
break;
case PERIPH_ID_I2C2:
rk_clrsetreg(&grf->gpio2c_iomux,
- GPIO2C5_MASK << GPIO2C5_SHIFT |
- GPIO2C4_MASK << GPIO2C4_SHIFT,
+ GPIO2C5_MASK | GPIO2C4_MASK,
GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
@@ -80,24 +77,20 @@ static void pinctrl_rk3036_spi_config(struct rk3036_grf *grf, int cs)
{
switch (cs) {
case 0:
- rk_clrsetreg(&grf->gpio1d_iomux,
- GPIO1D6_MASK << GPIO1D6_SHIFT,
+ rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D6_MASK,
GPIO1D6_SPI_CSN0 << GPIO1D6_SHIFT);
break;
case 1:
- rk_clrsetreg(&grf->gpio1d_iomux,
- GPIO1D7_MASK << GPIO1D7_SHIFT,
+ rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D7_MASK,
GPIO1D7_SPI_CSN1 << GPIO1D7_SHIFT);
break;
}
rk_clrsetreg(&grf->gpio1d_iomux,
- GPIO1D5_MASK << GPIO1D5_SHIFT |
- GPIO1D4_MASK << GPIO1D4_SHIFT,
+ GPIO1D5_MASK | GPIO1D4_MASK,
GPIO1D5_SPI_TXD << GPIO1D5_SHIFT |
GPIO1D4_SPI_RXD << GPIO1D4_SHIFT);
- rk_clrsetreg(&grf->gpio2a_iomux,
- GPIO2A0_MASK << GPIO2A0_SHIFT,
+ rk_clrsetreg(&grf->gpio2a_iomux, GPIO2A0_MASK,
GPIO2A0_SPI_CLK << GPIO2A0_SHIFT);
}
@@ -106,10 +99,8 @@ static void pinctrl_rk3036_uart_config(struct rk3036_grf *grf, int uart_id)
switch (uart_id) {
case PERIPH_ID_UART0:
rk_clrsetreg(&grf->gpio0c_iomux,
- GPIO0C3_MASK << GPIO0C3_SHIFT |
- GPIO0C2_MASK << GPIO0C2_SHIFT |
- GPIO0C1_MASK << GPIO0C1_SHIFT |
- GPIO0C0_MASK << GPIO0C0_SHIFT,
+ GPIO0C3_MASK | GPIO0C2_MASK |
+ GPIO0C1_MASK | GPIO0C0_MASK,
GPIO0C3_UART0_CTSN << GPIO0C3_SHIFT |
GPIO0C2_UART0_RTSN << GPIO0C2_SHIFT |
GPIO0C1_UART0_SIN << GPIO0C1_SHIFT |
@@ -117,15 +108,13 @@ static void pinctrl_rk3036_uart_config(struct rk3036_grf *grf, int uart_id)
break;
case PERIPH_ID_UART1:
rk_clrsetreg(&grf->gpio2c_iomux,
- GPIO2C7_MASK << GPIO2C7_SHIFT |
- GPIO2C6_MASK << GPIO2C6_SHIFT,
+ GPIO2C7_MASK | GPIO2C6_MASK,
GPIO2C7_UART1_SOUT << GPIO2C7_SHIFT |
GPIO2C6_UART1_SIN << GPIO2C6_SHIFT);
break;
case PERIPH_ID_UART2:
rk_clrsetreg(&grf->gpio1c_iomux,
- GPIO1C3_MASK << GPIO1C3_SHIFT |
- GPIO1C2_MASK << GPIO1C2_SHIFT,
+ GPIO1C3_MASK | GPIO1C2_MASK,
GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
break;
@@ -146,8 +135,7 @@ static void pinctrl_rk3036_sdmmc_config(struct rk3036_grf *grf, int mmc_id)
GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
rk_clrsetreg(&grf->gpio2a_iomux,
- GPIO2A4_MASK << GPIO2A4_SHIFT |
- GPIO2A1_MASK << GPIO2A1_SHIFT,
+ GPIO2A4_MASK | GPIO2A1_MASK,
GPIO2A4_EMMC_CMD << GPIO2A4_SHIFT |
GPIO2A1_EMMC_CLKOUT << GPIO2A1_SHIFT);
break;
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3188.c b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
index ef94dab210..65c1f665ea 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3188.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
@@ -370,7 +370,7 @@ static int rk3188_pinctrl_get_periph_id(struct udevice *dev,
u32 cell[3];
int ret;
- ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
@@ -516,7 +516,7 @@ static int rk3188_pinctrl_set_state(struct udevice *dev, struct udevice *config)
u32 cell[60], *ptr;
debug("%s: %s %s\n", __func__, dev->name, config->name);
- ret = fdtdec_get_int_array_count(blob, config->of_offset,
+ ret = fdtdec_get_int_array_count(blob, dev_of_offset(config),
"rockchip,pins", cell,
ARRAY_SIZE(cell));
if (ret < 0) {
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3328.c b/drivers/pinctrl/rockchip/pinctrl_rk3328.c
index 5ca6782ccc..d0ffeb1f04 100644
--- a/drivers/pinctrl/rockchip/pinctrl_rk3328.c
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3328.c
@@ -21,135 +21,28 @@ struct rk3328_pinctrl_priv {
struct rk3328_grf_regs *grf;
};
-enum {
- /* GRF_GPIO0A_IOMUX */
- GRF_GPIO0A5_SEL_SHIFT = 10,
- GRF_GPIO0A5_SEL_MASK = 3 << GRF_GPIO0A5_SEL_SHIFT,
- GRF_I2C3_SCL = 2,
-
- GRF_GPIO0A6_SEL_SHIFT = 12,
- GRF_GPIO0A6_SEL_MASK = 3 << GRF_GPIO0A6_SEL_SHIFT,
- GRF_I2C3_SDA = 2,
-
- GRF_GPIO0A7_SEL_SHIFT = 14,
- GRF_GPIO0A7_SEL_MASK = 3 << GRF_GPIO0A7_SEL_SHIFT,
- GRF_EMMC_DATA0 = 2,
-
- /* GRF_GPIO1A_IOMUX */
- GRF_GPIO1A0_SEL_SHIFT = 0,
- GRF_GPIO1A0_SEL_MASK = 0x3fff << GRF_GPIO1A0_SEL_SHIFT,
- GRF_CARD_DATA_CLK_CMD_DETN = 0x1555,
-
- /* GRF_GPIO2A_IOMUX */
- GRF_GPIO2A0_SEL_SHIFT = 0,
- GRF_GPIO2A0_SEL_MASK = 3 << GRF_GPIO2A0_SEL_SHIFT,
- GRF_UART2_TX_M1 = 1,
-
- GRF_GPIO2A1_SEL_SHIFT = 2,
- GRF_GPIO2A1_SEL_MASK = 3 << GRF_GPIO2A1_SEL_SHIFT,
- GRF_UART2_RX_M1 = 1,
-
- GRF_GPIO2A2_SEL_SHIFT = 4,
- GRF_GPIO2A2_SEL_MASK = 3 << GRF_GPIO2A2_SEL_SHIFT,
- GRF_PWM_IR = 1,
-
- GRF_GPIO2A4_SEL_SHIFT = 8,
- GRF_GPIO2A4_SEL_MASK = 3 << GRF_GPIO2A4_SEL_SHIFT,
- GRF_PWM_0 = 1,
- GRF_I2C1_SDA,
-
- GRF_GPIO2A5_SEL_SHIFT = 10,
- GRF_GPIO2A5_SEL_MASK = 3 << GRF_GPIO2A5_SEL_SHIFT,
- GRF_PWM_1 = 1,
- GRF_I2C1_SCL,
-
- GRF_GPIO2A6_SEL_SHIFT = 12,
- GRF_GPIO2A6_SEL_MASK = 3 << GRF_GPIO2A6_SEL_SHIFT,
- GRF_PWM_2 = 1,
-
- GRF_GPIO2A7_SEL_SHIFT = 14,
- GRF_GPIO2A7_SEL_MASK = 3 << GRF_GPIO2A7_SEL_SHIFT,
- GRF_CARD_PWR_EN_M0 = 1,
-
- /* GRF_GPIO2BL_IOMUX */
- GRF_GPIO2BL0_SEL_SHIFT = 0,
- GRF_GPIO2BL0_SEL_MASK = 0x3f << GRF_GPIO2BL0_SEL_SHIFT,
- GRF_SPI_CLK_TX_RX_M0 = 0x15,
-
- GRF_GPIO2BL3_SEL_SHIFT = 6,
- GRF_GPIO2BL3_SEL_MASK = 3 << GRF_GPIO2BL3_SEL_SHIFT,
- GRF_SPI_CSN0_M0 = 1,
-
- GRF_GPIO2BL4_SEL_SHIFT = 8,
- GRF_GPIO2BL4_SEL_MASK = 3 << GRF_GPIO2BL4_SEL_SHIFT,
- GRF_SPI_CSN1_M0 = 1,
-
- GRF_GPIO2BL5_SEL_SHIFT = 10,
- GRF_GPIO2BL5_SEL_MASK = 3 << GRF_GPIO2BL5_SEL_SHIFT,
- GRF_I2C2_SDA = 1,
-
- GRF_GPIO2BL6_SEL_SHIFT = 12,
- GRF_GPIO2BL6_SEL_MASK = 3 << GRF_GPIO2BL6_SEL_SHIFT,
- GRF_I2C2_SCL = 1,
-
- /* GRF_GPIO2D_IOMUX */
- GRF_GPIO2D0_SEL_SHIFT = 0,
- GRF_GPIO2D0_SEL_MASK = 3 << GRF_GPIO2D0_SEL_SHIFT,
- GRF_I2C0_SCL = 1,
-
- GRF_GPIO2D1_SEL_SHIFT = 2,
- GRF_GPIO2D1_SEL_MASK = 3 << GRF_GPIO2D1_SEL_SHIFT,
- GRF_I2C0_SDA = 1,
-
- GRF_GPIO2D4_SEL_SHIFT = 8,
- GRF_GPIO2D4_SEL_MASK = 0xff << GRF_GPIO2D4_SEL_SHIFT,
- GRF_EMMC_DATA123 = 0xaa,
-
- /* GRF_GPIO3C_IOMUX */
- GRF_GPIO3C0_SEL_SHIFT = 0,
- GRF_GPIO3C0_SEL_MASK = 0x3fff << GRF_GPIO3C0_SEL_SHIFT,
- GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD = 0x2aaa,
-
- /* GRF_COM_IOMUX */
- GRF_UART2_IOMUX_SEL_SHIFT = 0,
- GRF_UART2_IOMUX_SEL_MASK = 3 << GRF_UART2_IOMUX_SEL_SHIFT,
- GRF_UART2_IOMUX_SEL_M0 = 0,
- GRF_UART2_IOMUX_SEL_M1,
-
- GRF_SPI_IOMUX_SEL_SHIFT = 4,
- GRF_SPI_IOMUX_SEL_MASK = 3 << GRF_SPI_IOMUX_SEL_SHIFT,
- GRF_SPI_IOMUX_SEL_M0 = 0,
- GRF_SPI_IOMUX_SEL_M1,
- GRF_SPI_IOMUX_SEL_M2,
-
- GRF_CARD_IOMUX_SEL_SHIFT = 7,
- GRF_CARD_IOMUX_SEL_MASK = 1 << GRF_CARD_IOMUX_SEL_SHIFT,
- GRF_CARD_IOMUX_SEL_M0 = 0,
- GRF_CARD_IOMUX_SEL_M1,
-};
-
static void pinctrl_rk3328_pwm_config(struct rk3328_grf_regs *grf, int pwm_id)
{
switch (pwm_id) {
case PERIPH_ID_PWM0:
rk_clrsetreg(&grf->gpio2a_iomux,
- GRF_GPIO2A4_SEL_MASK,
- GRF_PWM_0 << GRF_GPIO2A4_SEL_SHIFT);
+ GPIO2A4_SEL_MASK,
+ GPIO2A4_PWM_0 << GPIO2A4_SEL_SHIFT);
break;
case PERIPH_ID_PWM1:
rk_clrsetreg(&grf->gpio2a_iomux,
- GRF_GPIO2A5_SEL_MASK,
- GRF_PWM_1 << GRF_GPIO2A5_SEL_SHIFT);
+ GPIO2A5_SEL_MASK,
+ GPIO2A5_PWM_1 << GPIO2A5_SEL_SHIFT);
break;
case PERIPH_ID_PWM2:
rk_clrsetreg(&grf->gpio2a_iomux,
- GRF_GPIO2A6_SEL_MASK,
- GRF_PWM_2 << GRF_GPIO2A6_SEL_SHIFT);
+ GPIO2A6_SEL_MASK,
+ GPIO2A6_PWM_2 << GPIO2A6_SEL_SHIFT);
break;
case PERIPH_ID_PWM3:
rk_clrsetreg(&grf->gpio2a_iomux,
- GRF_GPIO2A2_SEL_MASK,
- GRF_PWM_IR << GRF_GPIO2A2_SEL_SHIFT);
+ GPIO2A2_SEL_MASK,
+ GPIO2A2_PWM_IR << GPIO2A2_SEL_SHIFT);
break;
default:
debug("pwm id = %d iomux error!\n", pwm_id);
@@ -162,27 +55,27 @@ static void pinctrl_rk3328_i2c_config(struct rk3328_grf_regs *grf, int i2c_id)
switch (i2c_id) {
case PERIPH_ID_I2C0:
rk_clrsetreg(&grf->gpio2d_iomux,
- GRF_GPIO2D0_SEL_MASK | GRF_GPIO2D1_SEL_MASK,
- GRF_I2C0_SCL << GRF_GPIO2D0_SEL_SHIFT
- | GRF_I2C0_SDA << GRF_GPIO2D1_SEL_SHIFT);
+ GPIO2D0_SEL_MASK | GPIO2D1_SEL_MASK,
+ GPIO2D0_I2C0_SCL << GPIO2D0_SEL_SHIFT |
+ GPIO2D1_I2C0_SDA << GPIO2D1_SEL_SHIFT);
break;
case PERIPH_ID_I2C1:
rk_clrsetreg(&grf->gpio2a_iomux,
- GRF_GPIO2A4_SEL_MASK | GRF_GPIO2A5_SEL_MASK,
- GRF_I2C1_SCL << GRF_GPIO2A5_SEL_SHIFT
- | GRF_I2C1_SDA << GRF_GPIO2A4_SEL_SHIFT);
+ GPIO2A4_SEL_MASK | GPIO2A5_SEL_MASK,
+ GPIO2A5_I2C1_SCL << GPIO2A5_SEL_SHIFT |
+ GPIO2A4_I2C1_SDA << GPIO2A4_SEL_SHIFT);
break;
case PERIPH_ID_I2C2:
rk_clrsetreg(&grf->gpio2bl_iomux,
- GRF_GPIO2BL5_SEL_MASK | GRF_GPIO2BL6_SEL_MASK,
- GRF_I2C2_SCL << GRF_GPIO2BL6_SEL_SHIFT
- | GRF_I2C2_SDA << GRF_GPIO2BL6_SEL_SHIFT);
+ GPIO2BL5_SEL_MASK | GPIO2BL6_SEL_MASK,
+ GPIO2BL6_I2C2_SCL << GPIO2BL6_SEL_SHIFT |
+ GPIO2BL5_I2C2_SDA << GPIO2BL5_SEL_SHIFT);
break;
case PERIPH_ID_I2C3:
rk_clrsetreg(&grf->gpio0a_iomux,
- GRF_GPIO0A5_SEL_MASK | GRF_GPIO0A6_SEL_MASK,
- GRF_I2C3_SCL << GRF_GPIO0A5_SEL_SHIFT
- | GRF_I2C3_SDA << GRF_GPIO0A6_SEL_SHIFT);
+ GPIO0A5_SEL_MASK | GPIO0A6_SEL_MASK,
+ GPIO0A5_I2C3_SCL << GPIO0A5_SEL_SHIFT |
+ GPIO0A6_I2C3_SDA << GPIO0A6_SEL_SHIFT);
break;
default:
debug("i2c id = %d iomux error!\n", i2c_id);
@@ -204,29 +97,35 @@ static void pinctrl_rk3328_lcdc_config(struct rk3328_grf_regs *grf, int lcd_id)
static int pinctrl_rk3328_spi_config(struct rk3328_grf_regs *grf,
enum periph_id spi_id, int cs)
{
- rk_clrsetreg(&grf->com_iomux,
- GRF_SPI_IOMUX_SEL_MASK,
- GRF_SPI_IOMUX_SEL_M0 << GRF_SPI_IOMUX_SEL_SHIFT);
+ u32 com_iomux = readl(&grf->com_iomux);
+
+ if ((com_iomux & IOMUX_SEL_SPI_MASK) !=
+ IOMUX_SEL_SPI_M0 << IOMUX_SEL_SPI_SHIFT) {
+ debug("driver do not support iomux other than m0\n");
+ goto err;
+ }
switch (spi_id) {
case PERIPH_ID_SPI0:
switch (cs) {
case 0:
rk_clrsetreg(&grf->gpio2bl_iomux,
- GRF_GPIO2BL3_SEL_MASK,
- GRF_SPI_CSN0_M0 << GRF_GPIO2BL3_SEL_SHIFT);
+ GPIO2BL3_SEL_MASK,
+ GPIO2BL3_SPI_CSN0_M0
+ << GPIO2BL3_SEL_SHIFT);
break;
case 1:
rk_clrsetreg(&grf->gpio2bl_iomux,
- GRF_GPIO2BL4_SEL_MASK,
- GRF_SPI_CSN1_M0 << GRF_GPIO2BL4_SEL_SHIFT);
+ GPIO2BL4_SEL_MASK,
+ GPIO2BL4_SPI_CSN1_M0
+ << GPIO2BL4_SEL_SHIFT);
break;
default:
goto err;
}
rk_clrsetreg(&grf->gpio2bl_iomux,
- GRF_GPIO2BL0_SEL_MASK,
- GRF_SPI_CLK_TX_RX_M0 << GRF_GPIO2BL0_SEL_SHIFT);
+ GPIO2BL0_SEL_MASK,
+ GPIO2BL0_SPI_CLK_TX_RX_M0 << GPIO2BL0_SEL_SHIFT);
break;
default:
goto err;
@@ -240,18 +139,17 @@ err:
static void pinctrl_rk3328_uart_config(struct rk3328_grf_regs *grf, int uart_id)
{
+ u32 com_iomux = readl(&grf->com_iomux);
+
switch (uart_id) {
case PERIPH_ID_UART2:
break;
- /* uart2 iomux select m1 */
- rk_clrsetreg(&grf->com_iomux,
- GRF_UART2_IOMUX_SEL_MASK,
- GRF_UART2_IOMUX_SEL_M1
- << GRF_UART2_IOMUX_SEL_SHIFT);
- rk_clrsetreg(&grf->gpio2a_iomux,
- GRF_GPIO2A0_SEL_MASK | GRF_GPIO2A1_SEL_MASK,
- GRF_UART2_TX_M1 << GRF_GPIO2A0_SEL_SHIFT |
- GRF_UART2_RX_M1 << GRF_GPIO2A1_SEL_SHIFT);
+ if (com_iomux & IOMUX_SEL_UART2_MASK)
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A0_SEL_MASK | GPIO2A1_SEL_MASK,
+ GPIO2A0_UART2_TX_M1 << GPIO2A0_SEL_SHIFT |
+ GPIO2A1_UART2_RX_M1 << GPIO2A1_SEL_SHIFT);
+
break;
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
@@ -266,31 +164,37 @@ static void pinctrl_rk3328_uart_config(struct rk3328_grf_regs *grf, int uart_id)
static void pinctrl_rk3328_sdmmc_config(struct rk3328_grf_regs *grf,
int mmc_id)
{
+ u32 com_iomux = readl(&grf->com_iomux);
+
switch (mmc_id) {
case PERIPH_ID_EMMC:
rk_clrsetreg(&grf->gpio0a_iomux,
- GRF_GPIO0A7_SEL_MASK,
- GRF_EMMC_DATA0 << GRF_GPIO0A7_SEL_SHIFT);
+ GPIO0A7_SEL_MASK,
+ GPIO0A7_EMMC_DATA0 << GPIO0A7_SEL_SHIFT);
rk_clrsetreg(&grf->gpio2d_iomux,
- GRF_GPIO2D4_SEL_MASK,
- GRF_EMMC_DATA123 << GRF_GPIO2D4_SEL_SHIFT);
+ GPIO2D4_SEL_MASK,
+ GPIO2D4_EMMC_DATA1234 << GPIO2D4_SEL_SHIFT);
rk_clrsetreg(&grf->gpio3c_iomux,
- GRF_GPIO3C0_SEL_MASK,
- GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD
- << GRF_GPIO3C0_SEL_SHIFT);
+ GPIO3C0_SEL_MASK,
+ GPIO3C0_EMMC_DATA567_PWR_CLK_RSTN_CMD
+ << GPIO3C0_SEL_SHIFT);
break;
case PERIPH_ID_SDCARD:
- /* sdcard iomux select m0 */
- rk_clrsetreg(&grf->com_iomux,
- GRF_CARD_IOMUX_SEL_MASK,
- GRF_CARD_IOMUX_SEL_M0 << GRF_CARD_IOMUX_SEL_SHIFT);
- rk_clrsetreg(&grf->gpio2a_iomux,
- GRF_GPIO2A7_SEL_MASK,
- GRF_CARD_PWR_EN_M0 << GRF_GPIO2A7_SEL_SHIFT);
+ /* SDMMC_PWREN use GPIO and init as regulator-fiexed */
+ if (com_iomux & IOMUX_SEL_SDMMC_MASK)
+ rk_clrsetreg(&grf->gpio0d_iomux,
+ GPIO0D6_SEL_MASK,
+ GPIO0D6_SDMMC0_PWRENM1
+ << GPIO0D6_SEL_SHIFT);
+ else
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A7_SEL_MASK,
+ GPIO2A7_SDMMC0_PWRENM0
+ << GPIO2A7_SEL_SHIFT);
rk_clrsetreg(&grf->gpio1a_iomux,
- GRF_GPIO1A0_SEL_MASK,
- GRF_CARD_DATA_CLK_CMD_DETN
- << GRF_GPIO1A0_SEL_SHIFT);
+ GPIO1A0_SEL_MASK,
+ GPIO1A0_CARD_DATA_CLK_CMD_DETN
+ << GPIO1A0_SEL_SHIFT);
break;
default:
debug("mmc id = %d iomux error!\n", mmc_id);
@@ -347,7 +251,7 @@ static int rk3328_pinctrl_get_periph_id(struct udevice *dev,
u32 cell[3];
int ret;
- ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3368.c b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
new file mode 100644
index 0000000000..bdf0758c0c
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3368.c
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/grf_rk3368.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3368_pinctrl_priv {
+ struct rk3368_grf *grf;
+ struct rk3368_pmu_grf *pmugrf;
+};
+
+static void pinctrl_rk3368_uart_config(struct rk3368_pinctrl_priv *priv,
+ int uart_id)
+{
+ struct rk3368_grf *grf = priv->grf;
+ struct rk3368_pmu_grf *pmugrf = priv->pmugrf;
+
+ switch (uart_id) {
+ case PERIPH_ID_UART2:
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A6_MASK | GPIO2A5_MASK,
+ GPIO2A6_UART2_SIN << GPIO2A6_SHIFT |
+ GPIO2A5_UART2_SOUT << GPIO2A5_SHIFT);
+ break;
+ case PERIPH_ID_UART0:
+ break;
+ case PERIPH_ID_UART1:
+ break;
+ case PERIPH_ID_UART3:
+ break;
+ case PERIPH_ID_UART4:
+ rk_clrsetreg(&pmugrf->gpio0d_iomux,
+ GPIO0D0_MASK | GPIO0D1_MASK |
+ GPIO0D2_MASK | GPIO0D3_MASK,
+ GPIO0D0_GPIO << GPIO0D0_SHIFT |
+ GPIO0D1_GPIO << GPIO0D1_SHIFT |
+ GPIO0D2_UART4_SOUT << GPIO0D2_SHIFT |
+ GPIO0D3_UART4_SIN << GPIO0D3_SHIFT);
+ break;
+ default:
+ debug("uart id = %d iomux error!\n", uart_id);
+ break;
+ }
+}
+
+static int rk3368_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
+
+ debug("%s: func=%d, flags=%x\n", __func__, func, flags);
+ switch (func) {
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART2:
+ case PERIPH_ID_UART3:
+ case PERIPH_ID_UART4:
+ pinctrl_rk3368_uart_config(priv, func);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk3368_pinctrl_get_periph_id(struct udevice *dev,
+ struct udevice *periph)
+{
+ u32 cell[3];
+ int ret;
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
+ "interrupts", cell, ARRAY_SIZE(cell));
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (cell[1]) {
+ case 59:
+ return PERIPH_ID_UART4;
+ case 58:
+ return PERIPH_ID_UART3;
+ case 57:
+ return PERIPH_ID_UART2;
+ case 56:
+ return PERIPH_ID_UART1;
+ case 55:
+ return PERIPH_ID_UART0;
+ }
+
+ return -ENOENT;
+}
+
+static int rk3368_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rk3368_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+
+ return rk3368_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rk3368_pinctrl_ops = {
+ .set_state_simple = rk3368_pinctrl_set_state_simple,
+ .request = rk3368_pinctrl_request,
+ .get_periph_id = rk3368_pinctrl_get_periph_id,
+};
+
+static int rk3368_pinctrl_probe(struct udevice *dev)
+{
+ struct rk3368_pinctrl_priv *priv = dev_get_priv(dev);
+ int ret = 0;
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+
+ debug("%s: grf=%p pmugrf:%p\n", __func__, priv->grf, priv->pmugrf);
+
+ return ret;
+}
+
+static const struct udevice_id rk3368_pinctrl_ids[] = {
+ { .compatible = "rockchip,rk3368-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3368) = {
+ .name = "rockchip_rk3368_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = rk3368_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3368_pinctrl_priv),
+ .ops = &rk3368_pinctrl_ops,
+ .bind = dm_scan_fdt_dev,
+ .probe = rk3368_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/rockchip/pinctrl_rv1108.c b/drivers/pinctrl/rockchip/pinctrl_rv1108.c
new file mode 100644
index 0000000000..bdf3910a88
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rv1108.c
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rv1108.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rv1108_pinctrl_priv {
+ struct rv1108_grf *grf;
+};
+
+static void pinctrl_rv1108_uart_config(struct rv1108_grf *grf, int uart_id)
+{
+ switch (uart_id) {
+ case PERIPH_ID_UART0:
+ rk_clrsetreg(&grf->gpio3a_iomux,
+ GPIO3A6_MASK | GPIO3A5_MASK,
+ GPIO3A6_UART1_SOUT << GPIO3A6_SHIFT |
+ GPIO3A5_UART1_SIN << GPIO3A5_SHIFT);
+ break;
+ case PERIPH_ID_UART1:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D3_MASK | GPIO1D2_MASK | GPIO1D1_MASK |
+ GPIO1D0_MASK,
+ GPIO1D3_UART0_SOUT << GPIO1D3_SHIFT |
+ GPIO1D2_UART0_SIN << GPIO1D2_SHIFT |
+ GPIO1D1_UART0_RTSN << GPIO1D1_SHIFT |
+ GPIO1D0_UART0_CTSN << GPIO1D0_SHIFT);
+ break;
+ case PERIPH_ID_UART2:
+ rk_clrsetreg(&grf->gpio2d_iomux,
+ GPIO2D2_MASK | GPIO2D1_MASK,
+ GPIO2D2_UART2_SOUT_M0 << GPIO2D2_SHIFT |
+ GPIO2D1_UART2_SIN_M0 << GPIO2D1_SHIFT);
+ break;
+ }
+}
+
+static void pinctrl_rv1108_gmac_config(struct rv1108_grf *grf, int func)
+{
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B7_MASK | GPIO1B6_MASK | GPIO1B5_MASK |
+ GPIO1B4_MASK | GPIO1B3_MASK | GPIO1B2_MASK,
+ GPIO1B7_GMAC_RXDV << GPIO1B7_SHIFT |
+ GPIO1B6_GMAC_RXD1 << GPIO1B6_SHIFT |
+ GPIO1B5_GMAC_RXD0 << GPIO1B5_SHIFT |
+ GPIO1B4_GMAC_TXEN << GPIO1B4_SHIFT |
+ GPIO1B3_GMAC_TXD1 << GPIO1B3_SHIFT |
+ GPIO1B2_GMAC_TXD0 << GPIO1B2_SHIFT);
+ rk_clrsetreg(&grf->gpio1c_iomux,
+ GPIO1C5_MASK | GPIO1C4_MASK |
+ GPIO1C3_MASK | GPIO1C2_MASK,
+ GPIO1C5_GMAC_CLK << GPIO1C5_SHIFT |
+ GPIO1C4_GMAC_MDC << GPIO1C4_SHIFT |
+ GPIO1C3_GMAC_MDIO << GPIO1C3_SHIFT |
+ GPIO1C2_GMAC_RXER << GPIO1C2_SHIFT);
+ writel(0xffff57f5, &grf->gpio1b_drv);
+}
+
+static void pinctrl_rv1108_sfc_config(struct rv1108_grf *grf)
+{
+ rk_clrsetreg(&grf->gpio2a_iomux, GPIO2A3_MASK | GPIO2A2_MASK |
+ GPIO2A1_MASK | GPIO2A0_MASK,
+ GPIO2A3_SFC_HOLD_IO3 << GPIO2A3_SHIFT |
+ GPIO2A2_SFC_WP_IO2 << GPIO2A2_SHIFT |
+ GPIO2A1_SFC_SO_IO1 << GPIO2A1_SHIFT |
+ GPIO2A0_SFC_SI_IO0 << GPIO2A0_SHIFT);
+ rk_clrsetreg(&grf->gpio2b_iomux, GPIO2B7_MASK | GPIO2B4_MASK,
+ GPIO2B7_SFC_CLK << GPIO2B7_SHIFT |
+ GPIO2B4_SFC_CSN0 << GPIO2B4_SHIFT);
+}
+
+static int rv1108_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rv1108_pinctrl_priv *priv = dev_get_priv(dev);
+
+ switch (func) {
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART2:
+ pinctrl_rv1108_uart_config(priv->grf, func);
+ break;
+ case PERIPH_ID_GMAC:
+ pinctrl_rv1108_gmac_config(priv->grf, func);
+ case PERIPH_ID_SFC:
+ pinctrl_rv1108_sfc_config(priv->grf);
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rv1108_pinctrl_get_periph_id(struct udevice *dev,
+ struct udevice *periph)
+{
+ u32 cell[3];
+ int ret;
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
+ "interrupts", cell, ARRAY_SIZE(cell));
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (cell[1]) {
+ case 11:
+ return PERIPH_ID_SDCARD;
+ case 13:
+ return PERIPH_ID_EMMC;
+ case 19:
+ return PERIPH_ID_GMAC;
+ case 30:
+ return PERIPH_ID_I2C0;
+ case 31:
+ return PERIPH_ID_I2C1;
+ case 32:
+ return PERIPH_ID_I2C2;
+ case 39:
+ return PERIPH_ID_PWM0;
+ case 44:
+ return PERIPH_ID_UART0;
+ case 45:
+ return PERIPH_ID_UART1;
+ case 46:
+ return PERIPH_ID_UART2;
+ case 56:
+ return PERIPH_ID_SFC;
+ }
+
+ return -ENOENT;
+}
+
+static int rv1108_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rv1108_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+
+ return rv1108_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rv1108_pinctrl_ops = {
+ .set_state_simple = rv1108_pinctrl_set_state_simple,
+ .request = rv1108_pinctrl_request,
+ .get_periph_id = rv1108_pinctrl_get_periph_id,
+};
+
+static int rv1108_pinctrl_probe(struct udevice *dev)
+{
+ struct rv1108_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+ return 0;
+}
+
+static const struct udevice_id rv1108_pinctrl_ids[] = {
+ {.compatible = "rockchip,rv1108-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rv1108) = {
+ .name = "pinctrl_rv1108",
+ .id = UCLASS_PINCTRL,
+ .of_match = rv1108_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rv1108_pinctrl_priv),
+ .ops = &rv1108_pinctrl_ops,
+ .bind = dm_scan_fdt_dev,
+ .probe = rv1108_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
index d8e9948ee7..d314482acf 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
@@ -6,10 +6,10 @@
*/
#include <common.h>
+#include <dm.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/sizes.h>
-#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
@@ -299,7 +299,7 @@ int uniphier_pinctrl_probe(struct udevice *dev,
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev->parent);
+ addr = devfdt_get_addr(dev->parent);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
index 53c37cda7a..9c2db1afc8 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
index 5a7d142865..0b0af1c018 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c
index 9b3db9d812..709b005298 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
index b25c7ea16e..6ade131385 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
index f1624dab3f..df5f2d86fa 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
index 70c90bae54..7b14662a71 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index 60777c3045..90d632903c 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
index 65b56dac3f..86752d91ff 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld3.c
index d3a507edc1..e9cc9d205d 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld3.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld3.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c
index 471fb673f7..897ce15131 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c
@@ -5,7 +5,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
diff --git a/drivers/power/domain/bcm6328-power-domain.c b/drivers/power/domain/bcm6328-power-domain.c
index 15638bf3ba..776afa3d43 100644
--- a/drivers/power/domain/bcm6328-power-domain.c
+++ b/drivers/power/domain/bcm6328-power-domain.c
@@ -52,7 +52,7 @@ static int bcm6328_power_domain_probe(struct udevice *dev)
fdt_addr_t addr;
fdt_size_t size;
- addr = dev_get_addr_size_index(dev, 0, &size);
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c
index 3dabbe4ac0..1847a492a3 100644
--- a/drivers/power/domain/power-domain-uclass.c
+++ b/drivers/power/domain/power-domain-uclass.c
@@ -6,7 +6,6 @@
#include <common.h>
#include <dm.h>
-#include <fdtdec.h>
#include <power-domain.h>
#include <power-domain-uclass.h>
@@ -18,7 +17,7 @@ static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev)
}
static int power_domain_of_xlate_default(struct power_domain *power_domain,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
debug("%s(power_domain=%p)\n", __func__, power_domain);
@@ -34,27 +33,25 @@ static int power_domain_of_xlate_default(struct power_domain *power_domain,
int power_domain_get(struct udevice *dev, struct power_domain *power_domain)
{
- struct fdtdec_phandle_args args;
+ struct ofnode_phandle_args args;
int ret;
struct udevice *dev_power_domain;
struct power_domain_ops *ops;
debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain);
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
- "power-domains",
- "#power-domain-cells", 0, 0,
- &args);
+ ret = dev_read_phandle_with_args(dev, "power-domains",
+ "#power-domain-cells", 0, 0, &args);
if (ret) {
- debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
+ debug("%s: dev_read_phandle_with_args failed: %d\n",
__func__, ret);
return ret;
}
- ret = uclass_get_device_by_of_offset(UCLASS_POWER_DOMAIN, args.node,
- &dev_power_domain);
+ ret = uclass_get_device_by_ofnode(UCLASS_POWER_DOMAIN, args.node,
+ &dev_power_domain);
if (ret) {
- debug("%s: uclass_get_device_by_of_offset failed: %d\n",
+ debug("%s: uclass_get_device_by_ofnode failed: %d\n",
__func__, ret);
return ret;
}
diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig
index 3f50c12157..e3f9e4dfc0 100644
--- a/drivers/power/pmic/Kconfig
+++ b/drivers/power/pmic/Kconfig
@@ -188,6 +188,13 @@ config PMIC_LP873X
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"
+ depends on DM_PMIC
+ ---help---
+ The LP87565 is a PMIC containing a bunch of SMPS.
+ This driver binds the pmic children.
+
config POWER_MC34VR500
bool "Enable driver for Freescale MC34VR500 PMIC"
---help---
diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile
index f409e3a0b3..f488799a92 100644
--- a/drivers/power/pmic/Makefile
+++ b/drivers/power/pmic/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o
obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o
+obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o
obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o
obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o
diff --git a/drivers/power/pmic/act8846.c b/drivers/power/pmic/act8846.c
index 15da12edea..a6b0940956 100644
--- a/drivers/power/pmic/act8846.c
+++ b/drivers/power/pmic/act8846.c
@@ -48,13 +48,11 @@ static int act8846_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
static int act8846_bind(struct udevice *dev)
{
- const void *blob = gd->fdt_blob;
- int regulators_node;
+ ofnode regulators_node;
int children;
- regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
- "regulators");
- if (regulators_node <= 0) {
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
debug("%s: %s regulators subnode not found!", __func__,
dev->name);
return -ENXIO;
diff --git a/drivers/power/pmic/i2c_pmic_emul.c b/drivers/power/pmic/i2c_pmic_emul.c
index 4f92e3dad8..2d35d09d45 100644
--- a/drivers/power/pmic/i2c_pmic_emul.c
+++ b/drivers/power/pmic/i2c_pmic_emul.c
@@ -6,7 +6,6 @@
*/
#include <common.h>
-#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <i2c.h>
@@ -108,9 +107,8 @@ static int sandbox_i2c_pmic_ofdata_to_platdata(struct udevice *emul)
debug("%s:%d Setting PMIC default registers\n", __func__, __LINE__);
- reg_defaults = fdtdec_locate_byte_array(gd->fdt_blob,
- dev_of_offset(emul), "reg-defaults",
- SANDBOX_PMIC_REG_COUNT);
+ reg_defaults = dev_read_u8_array_ptr(emul, "reg-defaults",
+ SANDBOX_PMIC_REG_COUNT);
if (!reg_defaults) {
error("Property \"reg-defaults\" not found for device: %s!",
diff --git a/drivers/power/pmic/lp873x.c b/drivers/power/pmic/lp873x.c
index d8f30df371..f505468313 100644
--- a/drivers/power/pmic/lp873x.c
+++ b/drivers/power/pmic/lp873x.c
@@ -46,15 +46,13 @@ static int lp873x_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
static int lp873x_bind(struct udevice *dev)
{
- int regulators_node;
- const void *blob = gd->fdt_blob;
+ ofnode regulators_node;
int children;
- int node = dev_of_offset(dev);
- regulators_node = fdt_subnode_offset(blob, node, "regulators");
-
- if (regulators_node <= 0) {
- printf("%s: %s reg subnode not found!", __func__, dev->name);
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
+ debug("%s: %s regulators subnode not found!", __func__,
+ dev->name);
return -ENXIO;
}
diff --git a/drivers/power/pmic/lp87565.c b/drivers/power/pmic/lp87565.c
new file mode 100644
index 0000000000..782a46c4cc
--- /dev/null
+++ b/drivers/power/pmic/lp87565.c
@@ -0,0 +1,87 @@
+/*
+ * (C) Copyright 2017 Texas Instruments Incorporated, <www.ti.com>
+ * Keerthy <j-keerthy@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/lp87565.h>
+#include <dm/device.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct pmic_child_info pmic_children_info[] = {
+ { .prefix = "buck", .driver = LP87565_BUCK_DRIVER },
+ { },
+};
+
+static int lp87565_write(struct udevice *dev, uint reg, const uint8_t *buff,
+ int len)
+{
+ int ret;
+
+ ret = dm_i2c_write(dev, reg, buff, len);
+ if (ret)
+ error("write error to device: %p register: %#x!", dev, reg);
+
+ return ret;
+}
+
+static int lp87565_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+ int ret;
+
+ ret = dm_i2c_read(dev, reg, buff, len);
+ if (ret)
+ error("read error from device: %p register: %#x!", dev, reg);
+
+ return ret;
+}
+
+static int lp87565_bind(struct udevice *dev)
+{
+ ofnode regulators_node;
+ int children;
+
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
+ debug("%s: %s regulators subnode not found!", __func__,
+ dev->name);
+ return -ENXIO;
+ }
+
+ debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
+
+ children = pmic_bind_children(dev, regulators_node, pmic_children_info);
+ if (!children)
+ printf("%s: %s - no child found\n", __func__, dev->name);
+
+ /* Always return success for this device */
+ return 0;
+}
+
+static struct dm_pmic_ops lp87565_ops = {
+ .read = lp87565_read,
+ .write = lp87565_write,
+};
+
+static const struct udevice_id lp87565_ids[] = {
+ { .compatible = "ti,lp87565", .data = LP87565 },
+ { .compatible = "ti,lp87565-q1", .data = LP87565_Q1 },
+ { }
+};
+
+U_BOOT_DRIVER(pmic_lp87565) = {
+ .name = "lp87565_pmic",
+ .id = UCLASS_PMIC,
+ .of_match = lp87565_ids,
+ .bind = lp87565_bind,
+ .ops = &lp87565_ops,
+};
diff --git a/drivers/power/pmic/max77686.c b/drivers/power/pmic/max77686.c
index 8295fab3f0..ceca9f96a7 100644
--- a/drivers/power/pmic/max77686.c
+++ b/drivers/power/pmic/max77686.c
@@ -50,13 +50,11 @@ static int max77686_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
static int max77686_bind(struct udevice *dev)
{
- int regulators_node;
- const void *blob = gd->fdt_blob;
+ ofnode regulators_node;
int children;
- regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
- "voltage-regulators");
- if (regulators_node <= 0) {
+ regulators_node = dev_read_subnode(dev, "voltage-regulators");
+ if (!ofnode_valid(regulators_node)) {
debug("%s: %s regulators subnode not found!", __func__,
dev->name);
return -ENXIO;
diff --git a/drivers/power/pmic/palmas.c b/drivers/power/pmic/palmas.c
index f5a23073c4..804c0d13a0 100644
--- a/drivers/power/pmic/palmas.c
+++ b/drivers/power/pmic/palmas.c
@@ -46,17 +46,15 @@ static int palmas_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
static int palmas_bind(struct udevice *dev)
{
- int pmic_node = -1, regulators_node;
- const void *blob = gd->fdt_blob;
+ ofnode pmic_node = ofnode_null(), regulators_node;
+ ofnode subnode;
int children;
- int node = dev_of_offset(dev);
- int subnode, len;
- fdt_for_each_subnode(subnode, blob, node) {
+ dev_for_each_subnode(subnode, dev) {
const char *name;
char *temp;
- name = fdt_get_name(blob, subnode, &len);
+ name = ofnode_get_name(subnode);
temp = strstr(name, "pmic");
if (temp) {
pmic_node = subnode;
@@ -64,14 +62,14 @@ static int palmas_bind(struct udevice *dev)
}
}
- if (pmic_node <= 0) {
+ if (!ofnode_valid(pmic_node)) {
debug("%s: %s pmic subnode not found!", __func__, dev->name);
return -ENXIO;
}
- regulators_node = fdt_subnode_offset(blob, pmic_node, "regulators");
+ regulators_node = ofnode_find_subnode(pmic_node, "regulators");
- if (regulators_node <= 0) {
+ if (!ofnode_valid(regulators_node)) {
debug("%s: %s reg subnode not found!", __func__, dev->name);
return -ENXIO;
}
diff --git a/drivers/power/pmic/pfuze100.c b/drivers/power/pmic/pfuze100.c
index 90a43f2fe5..5f361c7696 100644
--- a/drivers/power/pmic/pfuze100.c
+++ b/drivers/power/pmic/pfuze100.c
@@ -52,13 +52,11 @@ static int pfuze100_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
static int pfuze100_bind(struct udevice *dev)
{
+ ofnode regulators_node;
int children;
- int regulators_node;
- const void *blob = gd->fdt_blob;
- regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
- "regulators");
- if (regulators_node <= 0) {
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
debug("%s: %s regulators subnode not found!", __func__,
dev->name);
return -ENXIO;
diff --git a/drivers/power/pmic/pm8916.c b/drivers/power/pmic/pm8916.c
index 2b65c697ec..a048bbe7ce 100644
--- a/drivers/power/pmic/pm8916.c
+++ b/drivers/power/pmic/pm8916.c
@@ -70,7 +70,7 @@ static int pm8916_probe(struct udevice *dev)
{
struct pm8916_priv *priv = dev_get_priv(dev);
- priv->usid = dev_get_addr(dev);
+ priv->usid = dev_read_addr(dev);
if (priv->usid == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/power/pmic/pmic-uclass.c b/drivers/power/pmic/pmic-uclass.c
index 0f7fa517f9..953bbe5026 100644
--- a/drivers/power/pmic/pmic-uclass.c
+++ b/drivers/power/pmic/pmic-uclass.c
@@ -19,29 +19,27 @@
DECLARE_GLOBAL_DATA_PTR;
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
-int pmic_bind_children(struct udevice *pmic, int offset,
+int pmic_bind_children(struct udevice *pmic, ofnode parent,
const struct pmic_child_info *child_info)
{
const struct pmic_child_info *info;
- const void *blob = gd->fdt_blob;
struct driver *drv;
struct udevice *child;
const char *node_name;
int bind_count = 0;
- int node;
+ ofnode node;
int prefix_len;
int ret;
debug("%s for '%s' at node offset: %d\n", __func__, pmic->name,
dev_of_offset(pmic));
- for (node = fdt_first_subnode(blob, offset);
- node > 0;
- node = fdt_next_subnode(blob, node)) {
- node_name = fdt_get_name(blob, node, NULL);
+ for (node = ofnode_first_subnode(parent);
+ ofnode_valid(node);
+ node = ofnode_next_subnode(node)) {
+ node_name = ofnode_get_name(node);
- debug("* Found child node: '%s' at offset:%d\n", node_name,
- node);
+ debug("* Found child node: '%s'\n", node_name);
child = NULL;
for (info = child_info; info->prefix && info->driver; info++) {
@@ -60,8 +58,8 @@ int pmic_bind_children(struct udevice *pmic, int offset,
debug(" - found child driver: '%s'\n", drv->name);
- ret = device_bind(pmic, drv, node_name, NULL,
- node, &child);
+ ret = device_bind_with_driver_data(pmic, drv, node_name,
+ 0, node, &child);
if (ret) {
debug(" - child binding error: %d\n", ret);
continue;
@@ -82,7 +80,7 @@ int pmic_bind_children(struct udevice *pmic, int offset,
debug(" - compatible prefix not found\n");
}
- debug("Bound: %d childs for PMIC: '%s'\n", bind_count, pmic->name);
+ debug("Bound: %d children for PMIC: '%s'\n", bind_count, pmic->name);
return bind_count;
}
#endif
diff --git a/drivers/power/pmic/pmic_tps65218.c b/drivers/power/pmic/pmic_tps65218.c
index c5e768ae4b..911f63942d 100644
--- a/drivers/power/pmic/pmic_tps65218.c
+++ b/drivers/power/pmic/pmic_tps65218.c
@@ -96,7 +96,8 @@ int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
{
if ((dc_cntrl_reg != TPS65218_DCDC1) &&
- (dc_cntrl_reg != TPS65218_DCDC2))
+ (dc_cntrl_reg != TPS65218_DCDC2) &&
+ (dc_cntrl_reg != TPS65218_DCDC3))
return 1;
/* set voltage level */
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 394e2ff9db..eb3ec0f601 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -57,13 +57,11 @@ static int rk8xx_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
static int rk8xx_bind(struct udevice *dev)
{
- const void *blob = gd->fdt_blob;
- int regulators_node;
+ ofnode regulators_node;
int children;
- regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
- "regulators");
- if (regulators_node <= 0) {
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
debug("%s: %s regulators subnode not found!", __func__,
dev->name);
return -ENXIO;
@@ -113,6 +111,7 @@ U_BOOT_DRIVER(pmic_rk8xx) = {
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
.bind = rk8xx_bind,
#endif
+ .priv_auto_alloc_size = sizeof(struct rk8xx_priv),
.probe = rk8xx_probe,
.ops = &rk8xx_ops,
};
diff --git a/drivers/power/pmic/s5m8767.c b/drivers/power/pmic/s5m8767.c
index 25d673b998..f8ae5ea2db 100644
--- a/drivers/power/pmic/s5m8767.c
+++ b/drivers/power/pmic/s5m8767.c
@@ -54,12 +54,11 @@ int s5m8767_enable_32khz_cp(struct udevice *dev)
static int s5m8767_bind(struct udevice *dev)
{
- int node;
- const void *blob = gd->fdt_blob;
int children;
+ ofnode node;
- node = fdt_subnode_offset(blob, dev_of_offset(dev), "regulators");
- if (node <= 0) {
+ node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(node)) {
debug("%s: %s regulators subnode not found!", __func__,
dev->name);
return -ENXIO;
diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c
index b4e412eb3e..6763303c66 100644
--- a/drivers/power/pmic/sandbox.c
+++ b/drivers/power/pmic/sandbox.c
@@ -51,7 +51,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg,
static int sandbox_pmic_bind(struct udevice *dev)
{
- if (!pmic_bind_children(dev, dev_of_offset(dev), pmic_children_info))
+ if (!pmic_bind_children(dev, dev_ofnode(dev), pmic_children_info))
error("%s:%d PMIC: %s - no child found!", __func__, __LINE__,
dev->name);
diff --git a/drivers/power/pmic/tps65090.c b/drivers/power/pmic/tps65090.c
index b30a7f08e9..4565e3b54c 100644
--- a/drivers/power/pmic/tps65090.c
+++ b/drivers/power/pmic/tps65090.c
@@ -52,13 +52,11 @@ static int tps65090_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
static int tps65090_bind(struct udevice *dev)
{
- int regulators_node;
- const void *blob = gd->fdt_blob;
+ ofnode regulators_node;
int children;
- regulators_node = fdt_subnode_offset(blob, dev_of_offset(dev),
- "regulators");
- if (regulators_node <= 0) {
+ regulators_node = dev_read_subnode(dev, "regulators");
+ if (!ofnode_valid(regulators_node)) {
debug("%s: %s regulators subnode not found!", __func__,
dev->name);
return -ENXIO;
diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig
index ef057e0e2f..f2134874c2 100644
--- a/drivers/power/regulator/Kconfig
+++ b/drivers/power/regulator/Kconfig
@@ -149,3 +149,13 @@ config DM_REGULATOR_LP873X
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.
diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile
index 3e01021b76..ce14d08fd4 100644
--- a/drivers/power/regulator/Makefile
+++ b/drivers/power/regulator/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o
obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
+obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o
diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c
index cd5213766d..656371b235 100644
--- a/drivers/power/regulator/fixed.c
+++ b/drivers/power/regulator/fixed.c
@@ -7,7 +7,6 @@
*/
#include <common.h>
-#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <i2c.h>
@@ -27,8 +26,7 @@ static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
struct dm_regulator_uclass_platdata *uc_pdata;
struct fixed_regulator_platdata *dev_pdata;
struct gpio_desc *gpio;
- const void *blob = gd->fdt_blob;
- int node = dev_of_offset(dev), flags = GPIOD_IS_OUT;
+ int flags = GPIOD_IS_OUT;
int ret;
dev_pdata = dev_get_platdata(dev);
@@ -39,7 +37,7 @@ static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
/* Set type to fixed */
uc_pdata->type = REGULATOR_TYPE_FIXED;
- if (fdtdec_get_bool(blob, node, "enable-active-high"))
+ if (dev_read_bool(dev, "enable-active-high"))
flags |= GPIOD_IS_OUT_ACTIVE;
/* Get fixed regulator optional enable GPIO desc */
@@ -53,9 +51,8 @@ static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
}
/* Get optional ramp up delay */
- dev_pdata->startup_delay_us = fdtdec_get_uint(gd->fdt_blob,
- dev_of_offset(dev),
- "startup-delay-us", 0);
+ dev_pdata->startup_delay_us = dev_read_u32_default(dev,
+ "startup-delay-us", 0);
return 0;
}
@@ -108,8 +105,11 @@ static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
int ret;
+ debug("%s: dev='%s', enable=%d, delay=%d, has_gpio=%d\n", __func__,
+ dev->name, enable, dev_pdata->startup_delay_us,
+ dm_gpio_is_valid(&dev_pdata->gpio));
/* Enable GPIO is optional */
- if (!dev_pdata->gpio.dev) {
+ if (!dm_gpio_is_valid(&dev_pdata->gpio)) {
if (!enable)
return -ENOSYS;
return 0;
@@ -124,6 +124,7 @@ static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
if (enable && dev_pdata->startup_delay_us)
udelay(dev_pdata->startup_delay_us);
+ debug("%s: done\n", __func__);
return 0;
}
diff --git a/drivers/power/regulator/lp87565_regulator.c b/drivers/power/regulator/lp87565_regulator.c
new file mode 100644
index 0000000000..2a0b8ca642
--- /dev/null
+++ b/drivers/power/regulator/lp87565_regulator.c
@@ -0,0 +1,199 @@
+/*
+ * (C) Copyright 2017
+ * Texas Instruments Incorporated, <www.ti.com>
+ *
+ * Keerthy <j-keerthy@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/lp87565.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char lp87565_buck_ctrl1[LP87565_BUCK_NUM] = {0x2, 0x4, 0x6, 0x8, 0x2, 0x6};
+static const char lp87565_buck_vout[LP87565_BUCK_NUM] = {0xA, 0xC, 0xE, 0x10, 0xA, 0xE };
+
+static int lp87565_buck_enable(struct udevice *dev, int op, bool *enable)
+{
+ int ret;
+ unsigned int adr;
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ adr = uc_pdata->ctrl_reg;
+
+ ret = pmic_reg_read(dev->parent, adr);
+ if (ret < 0)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ ret &= LP87565_BUCK_MODE_MASK;
+
+ if (ret)
+ *enable = true;
+ else
+ *enable = false;
+
+ return 0;
+ } else if (op == PMIC_OP_SET) {
+ if (*enable)
+ ret |= LP87565_BUCK_MODE_MASK;
+ else
+ ret &= ~LP87565_BUCK_MODE_MASK;
+ ret = pmic_reg_write(dev->parent, adr, ret);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int lp87565_buck_volt2val(int uV)
+{
+ if (uV > LP87565_BUCK_VOLT_MAX)
+ return -EINVAL;
+ else if (uV > 1400000)
+ return (uV - 1420000) / 20000 + 0x9E;
+ else if (uV > 730000)
+ return (uV - 735000) / 5000 + 0x18;
+ else if (uV >= 500000)
+ return (uV - 500000) / 10000;
+ else
+ return -EINVAL;
+}
+
+static int lp87565_buck_val2volt(int val)
+{
+ if (val > LP87565_BUCK_VOLT_MAX_HEX)
+ return -EINVAL;
+ else if (val > 0x9D)
+ return 1400000 + (val - 0x9D) * 20000;
+ else if (val > 0x17)
+ return 730000 + (val - 0x17) * 5000;
+ else if (val >= 0x0)
+ return 500000 + val * 10000;
+ else
+ return -EINVAL;
+}
+
+static int lp87565_buck_val(struct udevice *dev, int op, int *uV)
+{
+ unsigned int hex, adr;
+ int ret;
+ struct dm_regulator_uclass_platdata *uc_pdata;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+
+ if (op == PMIC_OP_GET)
+ *uV = 0;
+
+ adr = uc_pdata->volt_reg;
+
+ ret = pmic_reg_read(dev->parent, adr);
+ if (ret < 0)
+ return ret;
+
+ if (op == PMIC_OP_GET) {
+ ret &= LP87565_BUCK_VOLT_MASK;
+ ret = lp87565_buck_val2volt(ret);
+ if (ret < 0)
+ return ret;
+ *uV = ret;
+
+ return 0;
+ }
+
+ hex = lp87565_buck_volt2val(*uV);
+ if (hex < 0)
+ return hex;
+
+ ret &= 0x0;
+ ret = hex;
+
+ ret = pmic_reg_write(dev->parent, adr, ret);
+
+ return ret;
+}
+
+static int lp87565_buck_probe(struct udevice *dev)
+{
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ int idx;
+
+ uc_pdata = dev_get_uclass_platdata(dev);
+ uc_pdata->type = REGULATOR_TYPE_BUCK;
+
+ idx = dev->driver_data;
+ if (idx == 0 || idx == 1 || idx == 2 || idx == 3) {
+ debug("Single phase regulator\n");
+ } else if (idx == 23) {
+ idx = 5;
+ } else if (idx == 10) {
+ idx = 4;
+ } else {
+ printf("Wrong ID for regulator\n");
+ return -EINVAL;
+ }
+
+ uc_pdata->ctrl_reg = lp87565_buck_ctrl1[idx];
+ uc_pdata->volt_reg = lp87565_buck_vout[idx];
+
+ return 0;
+}
+
+static int buck_get_value(struct udevice *dev)
+{
+ int uV;
+ int ret;
+
+ ret = lp87565_buck_val(dev, PMIC_OP_GET, &uV);
+ if (ret)
+ return ret;
+
+ return uV;
+}
+
+static int buck_set_value(struct udevice *dev, int uV)
+{
+ return lp87565_buck_val(dev, PMIC_OP_SET, &uV);
+}
+
+static bool buck_get_enable(struct udevice *dev)
+{
+ bool enable = false;
+ int ret;
+
+
+ ret = lp87565_buck_enable(dev, PMIC_OP_GET, &enable);
+ if (ret)
+ return ret;
+
+ return enable;
+}
+
+static int buck_set_enable(struct udevice *dev, bool enable)
+{
+ return lp87565_buck_enable(dev, PMIC_OP_SET, &enable);
+}
+
+static const struct dm_regulator_ops lp87565_buck_ops = {
+ .get_value = buck_get_value,
+ .set_value = buck_set_value,
+ .get_enable = buck_get_enable,
+ .set_enable = buck_set_enable,
+};
+
+U_BOOT_DRIVER(lp87565_buck) = {
+ .name = LP87565_BUCK_DRIVER,
+ .id = UCLASS_REGULATOR,
+ .ops = &lp87565_buck_ops,
+ .probe = lp87565_buck_probe,
+};
diff --git a/drivers/power/regulator/palmas_regulator.c b/drivers/power/regulator/palmas_regulator.c
index 399f7a5f55..841c03a504 100644
--- a/drivers/power/regulator/palmas_regulator.c
+++ b/drivers/power/regulator/palmas_regulator.c
@@ -377,7 +377,11 @@ static int palmas_smps_probe(struct udevice *dev)
uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
uc_pdata->volt_reg = palmas_smps_volt[type][idx];
break;
-
+ case 12:
+ idx = 0;
+ uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
+ uc_pdata->volt_reg = palmas_smps_volt[type][idx];
+ break;
default:
printf("Wrong ID for regulator\n");
}
diff --git a/drivers/power/regulator/pwm_regulator.c b/drivers/power/regulator/pwm_regulator.c
index a6c9fccd68..00a7cca7f7 100644
--- a/drivers/power/regulator/pwm_regulator.c
+++ b/drivers/power/regulator/pwm_regulator.c
@@ -32,13 +32,13 @@ struct pwm_regulator_info {
bool polarity;
struct udevice *pwm;
/* initialize voltage of regulator */
- unsigned int init_voltage;
+ int init_voltage;
/* the maximum voltage of regulator */
- unsigned int max_voltage;
+ int max_voltage;
/* the minimum voltage of regulator */
- unsigned int min_voltage;
+ int min_voltage;
/* the current voltage of regulator */
- unsigned int volt_uV;
+ int volt_uV;
};
static int pwm_regulator_enable(struct udevice *dev, bool enable)
diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c
index 2e0b5ed307..0a1d1b36c0 100644
--- a/drivers/power/regulator/regulator-uclass.c
+++ b/drivers/power/regulator/regulator-uclass.c
@@ -4,8 +4,8 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
+
#include <common.h>
-#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <dm/uclass-internal.h>
@@ -146,8 +146,10 @@ int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev;
ret = uclass_find_next_device(&dev)) {
- if (ret)
+ if (ret) {
+ debug("regulator %s, ret=%d\n", dev->name, ret);
continue;
+ }
uc_pdata = dev_get_uclass_platdata(dev);
if (!uc_pdata || strcmp(plat_name, uc_pdata->name))
@@ -156,7 +158,7 @@ int regulator_get_by_platname(const char *plat_name, struct udevice **devp)
return uclass_get_device_tail(dev, 0, devp);
}
- debug("%s: can't find: %s\n", __func__, plat_name);
+ debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret);
return -ENODEV;
}
@@ -219,7 +221,7 @@ int regulator_autoset_by_name(const char *platname, struct udevice **devp)
if (devp)
*devp = dev;
if (ret) {
- debug("Can get the regulator: %s!", platname);
+ debug("Can get the regulator: %s (err=%d)\n", platname, ret);
return ret;
}
@@ -278,20 +280,16 @@ static bool regulator_name_is_unique(struct udevice *check_dev,
static int regulator_post_bind(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
- int offset = dev_of_offset(dev);
- const void *blob = gd->fdt_blob;
const char *property = "regulator-name";
uc_pdata = dev_get_uclass_platdata(dev);
- if (!uc_pdata)
- return -ENXIO;
/* Regulator's mandatory constraint */
- uc_pdata->name = fdt_getprop(blob, offset, property, NULL);
+ uc_pdata->name = dev_read_string(dev, property);
if (!uc_pdata->name) {
- debug("%s: dev: %s has no property 'regulator-name'\n",
- __func__, dev->name);
- uc_pdata->name = fdt_get_name(blob, offset, NULL);
+ debug("%s: dev '%s' has no property '%s'\n",
+ __func__, dev->name, property);
+ uc_pdata->name = dev_read_name(dev);
if (!uc_pdata->name)
return -EINVAL;
}
@@ -299,7 +297,7 @@ static int regulator_post_bind(struct udevice *dev)
if (regulator_name_is_unique(dev, uc_pdata->name))
return 0;
- debug("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
+ debug("'%s' of dev: '%s', has nonunique value: '%s\n",
property, dev->name, uc_pdata->name);
return -EINVAL;
@@ -308,25 +306,22 @@ static int regulator_post_bind(struct udevice *dev)
static int regulator_pre_probe(struct udevice *dev)
{
struct dm_regulator_uclass_platdata *uc_pdata;
- int offset = dev_of_offset(dev);
uc_pdata = dev_get_uclass_platdata(dev);
if (!uc_pdata)
return -ENXIO;
/* Regulator's optional constraints */
- uc_pdata->min_uV = fdtdec_get_int(gd->fdt_blob, offset,
- "regulator-min-microvolt", -ENODATA);
- uc_pdata->max_uV = fdtdec_get_int(gd->fdt_blob, offset,
- "regulator-max-microvolt", -ENODATA);
- uc_pdata->min_uA = fdtdec_get_int(gd->fdt_blob, offset,
- "regulator-min-microamp", -ENODATA);
- uc_pdata->max_uA = fdtdec_get_int(gd->fdt_blob, offset,
- "regulator-max-microamp", -ENODATA);
- uc_pdata->always_on = fdtdec_get_bool(gd->fdt_blob, offset,
- "regulator-always-on");
- uc_pdata->boot_on = fdtdec_get_bool(gd->fdt_blob, offset,
- "regulator-boot-on");
+ uc_pdata->min_uV = dev_read_u32_default(dev, "regulator-min-microvolt",
+ -ENODATA);
+ uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt",
+ -ENODATA);
+ uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp",
+ -ENODATA);
+ uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",
+ -ENODATA);
+ uc_pdata->always_on = dev_read_bool(dev, "regulator-always-on");
+ uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on");
/* Those values are optional (-ENODATA if unset) */
if ((uc_pdata->min_uV != -ENODATA) &&
diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c
index e655c2d91f..c1ece96b66 100644
--- a/drivers/power/regulator/rk8xx.c
+++ b/drivers/power/regulator/rk8xx.c
@@ -92,9 +92,9 @@ static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
struct rk8xx_priv *priv = dev_get_priv(pmic);
switch (priv->variant) {
case RK818_ID:
- return &rk818_ldo[num - 1];
+ return &rk818_ldo[num];
default:
- return &rk808_ldo[num - 1];
+ return &rk808_ldo[num];
}
}
diff --git a/drivers/pwm/exynos_pwm.c b/drivers/pwm/exynos_pwm.c
index a0edafce40..9520a14387 100644
--- a/drivers/pwm/exynos_pwm.c
+++ b/drivers/pwm/exynos_pwm.c
@@ -94,7 +94,7 @@ static int exynos_pwm_ofdata_to_platdata(struct udevice *dev)
{
struct exynos_pwm_priv *priv = dev_get_priv(dev);
- priv->regs = (struct s5p_timer *)dev_get_addr(dev);
+ priv->regs = (struct s5p_timer *)devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/pwm/rk_pwm.c b/drivers/pwm/rk_pwm.c
index f3b2f7615d..28de62d716 100644
--- a/drivers/pwm/rk_pwm.c
+++ b/drivers/pwm/rk_pwm.c
@@ -75,7 +75,7 @@ static int rk_pwm_ofdata_to_platdata(struct udevice *dev)
{
struct rk_pwm_priv *priv = dev_get_priv(dev);
- priv->regs = (struct rk3288_pwm *)dev_get_addr(dev);
+ priv->regs = (struct rk3288_pwm *)devfdt_get_addr(dev);
return 0;
}
@@ -92,6 +92,7 @@ static int rk_pwm_probe(struct udevice *dev)
return -EINVAL;
}
priv->freq = clk_get_rate(&clk);
+ priv->enable_conf = PWM_DUTY_POSTIVE | PWM_INACTIVE_POSTIVE;
return 0;
}
diff --git a/drivers/pwm/tegra_pwm.c b/drivers/pwm/tegra_pwm.c
index 10e1fdc9b5..d93ac28c31 100644
--- a/drivers/pwm/tegra_pwm.c
+++ b/drivers/pwm/tegra_pwm.c
@@ -59,7 +59,7 @@ static int tegra_pwm_ofdata_to_platdata(struct udevice *dev)
{
struct tegra_pwm_priv *priv = dev_get_priv(dev);
- priv->regs = (struct pwm_ctlr *)dev_get_addr(dev);
+ priv->regs = (struct pwm_ctlr *)devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c
index 4f0a27892f..24e764dc7c 100644
--- a/drivers/qe/qe.c
+++ b/drivers/qe/qe.c
@@ -8,6 +8,7 @@
*/
#include <common.h>
+#include <malloc.h>
#include <command.h>
#include <linux/errno.h>
#include <asm/io.h>
@@ -17,6 +18,10 @@
#include <asm/arch/immap_ls102xa.h>
#endif
+#ifdef CONFIG_SYS_QE_FMAN_FW_IN_MMC
+#include <mmc.h>
+#endif
+
#define MPC85xx_DEVDISR_QE_DISABLE 0x1
qe_map_t *qe_immr = NULL;
@@ -194,8 +199,37 @@ void u_qe_init(void)
{
qe_immr = (qe_map_t *)(CONFIG_SYS_IMMR + QE_IMMR_OFFSET);
- u_qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR);
+ void *addr = (void *)CONFIG_SYS_QE_FW_ADDR;
+#ifdef CONFIG_SYS_QE_FMAN_FW_IN_MMC
+ int dev = CONFIG_SYS_MMC_ENV_DEV;
+ u32 cnt = CONFIG_SYS_QE_FMAN_FW_LENGTH / 512;
+ u32 blk = CONFIG_SYS_QE_FW_ADDR / 512;
+
+ if (mmc_initialize(gd->bd)) {
+ printf("%s: mmc_initialize() failed\n", __func__);
+ return;
+ }
+ addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
+ struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
+
+ if (!mmc) {
+ free(addr);
+ printf("\nMMC cannot find device for ucode\n");
+ } else {
+ printf("\nMMC read: dev # %u, block # %u, count %u ...\n",
+ dev, blk, cnt);
+ mmc_init(mmc);
+ (void)mmc->block_dev.block_read(&mmc->block_dev, blk, cnt,
+ addr);
+ /* flush cache after read */
+ flush_cache((ulong)addr, cnt * 512);
+ }
+#endif
+ u_qe_upload_firmware(addr);
out_be32(&qe_immr->iram.iready, QE_IRAM_READY);
+#ifdef CONFIG_SYS_QE_FMAN_FW_IN_MMC
+ free(addr);
+#endif
}
#endif
diff --git a/drivers/ram/bmips_ram.c b/drivers/ram/bmips_ram.c
index d0f7cd7376..3f9d9a8566 100644
--- a/drivers/ram/bmips_ram.c
+++ b/drivers/ram/bmips_ram.c
@@ -9,10 +9,20 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <ram.h>
#include <asm/io.h>
-#include <dm/device.h>
+
+#define SDRAM_CFG_REG 0x0
+#define SDRAM_CFG_COL_SHIFT 4
+#define SDRAM_CFG_COL_MASK (0x3 << SDRAM_CFG_COL_SHIFT)
+#define SDRAM_CFG_ROW_SHIFT 6
+#define SDRAM_CFG_ROW_MASK (0x3 << SDRAM_CFG_ROW_SHIFT)
+#define SDRAM_CFG_32B_SHIFT 10
+#define SDRAM_CFG_32B_MASK (1 << SDRAM_CFG_32B_SHIFT)
+#define SDRAM_CFG_BANK_SHIFT 13
+#define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT)
#define MEMC_CFG_REG 0x4
#define MEMC_CFG_32B_SHIFT 1
@@ -40,24 +50,41 @@ static ulong bcm6328_get_ram_size(struct bmips_ram_priv *priv)
return readl_be(priv->regs + DDR_CSEND_REG) << 24;
}
+static ulong bmips_dram_size(unsigned int cols, unsigned int rows,
+ unsigned int is_32b, unsigned int banks)
+{
+ rows += 11; /* 0 => 11 address bits ... 2 => 13 address bits */
+ cols += 8; /* 0 => 8 address bits ... 2 => 10 address bits */
+ is_32b += 1;
+
+ return 1 << (cols + rows + is_32b + banks);
+}
+
+static ulong bcm6338_get_ram_size(struct bmips_ram_priv *priv)
+{
+ unsigned int cols = 0, rows = 0, is_32b = 0, banks = 0;
+ u32 val;
+
+ val = readl_be(priv->regs + SDRAM_CFG_REG);
+ rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
+ cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
+ is_32b = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
+ banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
+
+ return bmips_dram_size(cols, rows, is_32b, banks);
+}
+
static ulong bcm6358_get_ram_size(struct bmips_ram_priv *priv)
{
- unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
+ unsigned int cols = 0, rows = 0, is_32b = 0;
u32 val;
val = readl_be(priv->regs + MEMC_CFG_REG);
rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
- is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
- banks = 2;
-
- /* 0 => 11 address bits ... 2 => 13 address bits */
- rows += 11;
+ is_32b = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
- /* 0 => 8 address bits ... 2 => 10 address bits */
- cols += 8;
-
- return 1 << (cols + rows + (is_32bits + 1) + banks);
+ return bmips_dram_size(cols, rows, is_32b, 2);
}
static int bmips_ram_get_info(struct udevice *dev, struct ram_info *info)
@@ -79,6 +106,10 @@ static const struct bmips_ram_hw bmips_ram_bcm6328 = {
.get_ram_size = bcm6328_get_ram_size,
};
+static const struct bmips_ram_hw bmips_ram_bcm6338 = {
+ .get_ram_size = bcm6338_get_ram_size,
+};
+
static const struct bmips_ram_hw bmips_ram_bcm6358 = {
.get_ram_size = bcm6358_get_ram_size,
};
@@ -88,6 +119,9 @@ static const struct udevice_id bmips_ram_ids[] = {
.compatible = "brcm,bcm6328-mc",
.data = (ulong)&bmips_ram_bcm6328,
}, {
+ .compatible = "brcm,bcm6338-mc",
+ .data = (ulong)&bmips_ram_bcm6338,
+ }, {
.compatible = "brcm,bcm6358-mc",
.data = (ulong)&bmips_ram_bcm6358,
}, { /* sentinel */ }
@@ -101,7 +135,7 @@ static int bmips_ram_probe(struct udevice *dev)
fdt_addr_t addr;
fdt_size_t size;
- addr = dev_get_addr_size_index(dev, 0, &size);
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c
index 48b4979e62..902de2b6c4 100644
--- a/drivers/ram/stm32_sdram.c
+++ b/drivers/ram/stm32_sdram.c
@@ -104,7 +104,7 @@ int stm32_sdram_init(struct udevice *dev)
static int stm32_fmc_ofdata_to_platdata(struct udevice *dev)
{
int ret;
- int node = dev->of_offset;
+ int node = dev_of_offset(dev);
const void *blob = gd->fdt_blob;
struct stm32_sdram_params *params = dev_get_platdata(dev);
@@ -132,8 +132,8 @@ static int stm32_fmc_ofdata_to_platdata(struct udevice *dev)
static int stm32_fmc_probe(struct udevice *dev)
{
-#ifdef CONFIG_CLK
int ret;
+#ifdef CONFIG_CLK
struct clk clk;
ret = clk_get_by_index(dev, 0, &clk);
diff --git a/drivers/reset/reset-bcm6345.c b/drivers/reset/reset-bcm6345.c
index 774c2a7538..ebf6bee9e6 100644
--- a/drivers/reset/reset-bcm6345.c
+++ b/drivers/reset/reset-bcm6345.c
@@ -70,7 +70,7 @@ static int bcm6345_reset_probe(struct udevice *dev)
fdt_addr_t addr;
fdt_size_t size;
- addr = dev_get_addr_size_index(dev, 0, &size);
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
index e92b24fa34..de3695ffaa 100644
--- a/drivers/reset/reset-uclass.c
+++ b/drivers/reset/reset-uclass.c
@@ -18,7 +18,7 @@ static inline struct reset_ops *reset_dev_ops(struct udevice *dev)
}
static int reset_of_xlate_default(struct reset_ctl *reset_ctl,
- struct fdtdec_phandle_args *args)
+ struct ofnode_phandle_args *args)
{
debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
@@ -35,7 +35,7 @@ static int reset_of_xlate_default(struct reset_ctl *reset_ctl,
int reset_get_by_index(struct udevice *dev, int index,
struct reset_ctl *reset_ctl)
{
- struct fdtdec_phandle_args args;
+ struct ofnode_phandle_args args;
int ret;
struct udevice *dev_reset;
struct reset_ops *ops;
@@ -43,20 +43,20 @@ int reset_get_by_index(struct udevice *dev, int index,
debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index,
reset_ctl);
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
- "resets", "#reset-cells", 0,
- index, &args);
+ ret = dev_read_phandle_with_args(dev, "resets", "#reset-cells", 0,
+ index, &args);
if (ret) {
- debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
+ debug("%s: fdtdec_parse_phandle_with_args() failed: %d\n",
__func__, ret);
return ret;
}
- ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node,
- &dev_reset);
+ ret = uclass_get_device_by_ofnode(UCLASS_RESET, args.node,
+ &dev_reset);
if (ret) {
- debug("%s: uclass_get_device_by_of_offset failed: %d\n",
+ debug("%s: uclass_get_device_by_ofnode() failed: %d\n",
__func__, ret);
+ debug("%s %d\n", ofnode_get_name(args.node), args.args[0]);
return ret;
}
ops = reset_dev_ops(dev_reset);
@@ -88,8 +88,7 @@ int reset_get_by_name(struct udevice *dev, const char *name,
debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name,
reset_ctl);
- index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
- "reset-names", name);
+ index = dev_read_stringlist_search(dev, "reset-names", name);
if (index < 0) {
debug("fdt_stringlist_search() failed: %d\n", index);
return index;
diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
index 29c4d4db97..17e971a427 100644
--- a/drivers/reset/reset-uniphier.c
+++ b/drivers/reset/reset-uniphier.c
@@ -6,8 +6,8 @@
*/
#include <common.h>
+#include <dm.h>
#include <reset-uclass.h>
-#include <dm/device.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -56,12 +56,12 @@ struct uniphier_reset_data {
#define UNIPHIER_PRO4_SYS_RESET_USB3(id, ch) \
UNIPHIER_RESETX((id), 0x2000 + 0x4 * (ch), 17)
-const struct uniphier_reset_data uniphier_sld3_sys_reset_data[] = {
+static const struct uniphier_reset_data uniphier_sld3_sys_reset_data[] = {
UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* Ether, HSC, MIO */
UNIPHIER_RESET_END,
};
-const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
+static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, MIO, RLE */
UNIPHIER_PRO4_SYS_RESET_GIO(12), /* Ether, SATA, USB3 */
UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
@@ -69,7 +69,7 @@ const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
UNIPHIER_RESET_END,
};
-const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
+static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC */
UNIPHIER_PRO4_SYS_RESET_GIO(12), /* PCIe, USB3 */
UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
@@ -77,7 +77,7 @@ const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
UNIPHIER_RESET_END,
};
-const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
+static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, RLE */
UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
UNIPHIER_PRO4_SYS_RESET_USB3(15, 1),
@@ -91,12 +91,12 @@ const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
UNIPHIER_RESET_END,
};
-const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = {
+static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = {
UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC, MIO */
UNIPHIER_RESET_END,
};
-const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
+static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC */
UNIPHIER_LD20_SYS_RESET_GIO(12), /* PCIe, USB3 */
UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */
@@ -125,7 +125,7 @@ const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
#define UNIPHIER_MIO_RESET_DMAC(id) \
UNIPHIER_RESETX((id), 0x110, 17)
-const struct uniphier_reset_data uniphier_mio_reset_data[] = {
+static const struct uniphier_reset_data uniphier_mio_reset_data[] = {
UNIPHIER_MIO_RESET_SD(0, 0),
UNIPHIER_MIO_RESET_SD(1, 1),
UNIPHIER_MIO_RESET_SD(2, 2),
@@ -155,7 +155,7 @@ const struct uniphier_reset_data uniphier_mio_reset_data[] = {
#define UNIPHIER_PERI_RESET_FI2C(id, ch) \
UNIPHIER_RESETX((id), 0x114, 24 + (ch))
-const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
+static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
UNIPHIER_PERI_RESET_UART(0, 0),
UNIPHIER_PERI_RESET_UART(1, 1),
UNIPHIER_PERI_RESET_UART(2, 2),
@@ -168,7 +168,7 @@ const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
UNIPHIER_RESET_END,
};
-const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = {
+static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = {
UNIPHIER_PERI_RESET_UART(0, 0),
UNIPHIER_PERI_RESET_UART(1, 1),
UNIPHIER_PERI_RESET_UART(2, 2),
@@ -254,7 +254,7 @@ static int uniphier_reset_probe(struct udevice *dev)
struct uniphier_reset_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev->parent);
+ addr = devfdt_get_addr(dev->parent);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/reset/sti-reset.c b/drivers/reset/sti-reset.c
index 0c32a3d8c9..a79708cde2 100644
--- a/drivers/reset/sti-reset.c
+++ b/drivers/reset/sti-reset.c
@@ -30,6 +30,8 @@ struct sti_reset {
* @reset_bit: Bit number in reset register.
* @ack_offset: Ack reset register offset in syscon bank.
* @ack_bit: Bit number in Ack reset register.
+ * @deassert_cnt: incremented when reset is deasserted, reset can only be
+ * asserted when equal to 0
*/
struct syscfg_reset_channel_data {
@@ -38,6 +40,7 @@ struct syscfg_reset_channel_data {
int reset_bit;
int ack_offset;
int ack_bit;
+ int deassert_cnt;
};
/**
@@ -54,7 +57,7 @@ struct syscfg_reset_controller_data {
bool wait_for_ack;
bool active_low;
int nr_channels;
- const struct syscfg_reset_channel_data *channels;
+ struct syscfg_reset_channel_data *channels;
};
/* STiH407 Peripheral powerdown definitions. */
@@ -102,7 +105,7 @@ static const char stih407_lpm[] = "st,stih407-lpm-syscfg";
#define SYSSTAT_4520 0x820
#define SYSCFG_4002 0x8
-static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
+static struct syscfg_reset_channel_data stih407_powerdowns[] = {
[STIH407_EMISS_POWERDOWN] = STIH407_PDN_0(1),
[STIH407_NAND_POWERDOWN] = STIH407_PDN_0(0),
[STIH407_USB3_POWERDOWN] = STIH407_PDN_1(6),
@@ -122,7 +125,7 @@ static const struct syscfg_reset_channel_data stih407_powerdowns[] = {
#define LPM_SYSCFG_1 0x4 /* Softreset IRB & SBC UART */
-static const struct syscfg_reset_channel_data stih407_softresets[] = {
+static struct syscfg_reset_channel_data stih407_softresets[] = {
[STIH407_ETH1_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 4),
[STIH407_MMC1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 3),
[STIH407_USB2_PORT0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 28),
@@ -161,7 +164,7 @@ static const struct syscfg_reset_channel_data stih407_softresets[] = {
/* PicoPHY reset/control */
#define SYSCFG_5061 0x0f4
-static const struct syscfg_reset_channel_data stih407_picophyresets[] = {
+static struct syscfg_reset_channel_data stih407_picophyresets[] = {
[STIH407_PICOPHY0_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 5),
[STIH407_PICOPHY1_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 6),
[STIH407_PICOPHY2_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 7),
@@ -223,7 +226,7 @@ static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert)
struct udevice *dev = reset_ctl->dev;
struct syscfg_reset_controller_data *reset_desc =
(struct syscfg_reset_controller_data *)(dev->driver_data);
- struct syscfg_reset_channel_data ch;
+ struct syscfg_reset_channel_data *ch;
phys_addr_t base;
u32 ctrl_val = reset_desc->active_low ? !assert : !!assert;
void __iomem *reg;
@@ -235,19 +238,35 @@ static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert)
/* get reset sysconf register base address */
base = sti_reset_get_regmap(reset_desc->channels[reset_ctl->id].compatible);
- ch = reset_desc->channels[reset_ctl->id];
- reg = (void __iomem *)base + ch.reset_offset;
+ ch = &reset_desc->channels[reset_ctl->id];
+
+ /* check the deassert counter to assert reset when it reaches 0 */
+ if (!assert) {
+ ch->deassert_cnt++;
+ if (ch->deassert_cnt > 1)
+ return 0;
+ } else {
+ if (ch->deassert_cnt > 0) {
+ ch->deassert_cnt--;
+ if (ch->deassert_cnt > 0)
+ return 0;
+ } else
+ error("Reset balancing error: reset_ctl=%p dev=%p id=%lu\n",
+ reset_ctl, reset_ctl->dev, reset_ctl->id);
+ }
+
+ reg = (void __iomem *)base + ch->reset_offset;
if (ctrl_val)
- generic_set_bit(ch.reset_bit, reg);
+ generic_set_bit(ch->reset_bit, reg);
else
- generic_clear_bit(ch.reset_bit, reg);
+ generic_clear_bit(ch->reset_bit, reg);
if (!reset_desc->wait_for_ack)
return 0;
- reg = (void __iomem *)base + ch.ack_offset;
- if (wait_for_bit(__func__, reg, BIT(ch.ack_bit), ctrl_val,
+ reg = (void __iomem *)base + ch->ack_offset;
+ if (wait_for_bit(__func__, reg, BIT(ch->ack_bit), ctrl_val,
1000, false)) {
error("Stuck on waiting ack reset_ctl=%p dev=%p id=%lu\n",
reset_ctl, reset_ctl->dev, reset_ctl->id);
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 438681da7a..003e31aeba 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -38,8 +38,6 @@ obj-$(CONFIG_RTC_MC146818) += mc146818.o
obj-$(CONFIG_RTC_MCP79411) += ds1307.o
obj-$(CONFIG_MCFRTC) += mcfrtc.o
obj-$(CONFIG_RTC_MK48T59) += mk48t59.o
-obj-$(CONFIG_RTC_MPC5200) += mpc5xxx.o
-obj-$(CONFIG_RTC_MPC8xx) += mpc8xx.o
obj-$(CONFIG_RTC_MV) += mvrtc.o
obj-$(CONFIG_RTC_MX27) += mx27rtc.o
obj-$(CONFIG_RTC_MXS) += mxsrtc.o
diff --git a/drivers/rtc/ds1337.c b/drivers/rtc/ds1337.c
index dae1b3c5cf..4b73d1718c 100644
--- a/drivers/rtc/ds1337.c
+++ b/drivers/rtc/ds1337.c
@@ -150,11 +150,11 @@ int rtc_set (struct rtc_time *tmp)
* SQW/INTB* pin and program it for 32,768 Hz output. Note that
* according to the datasheet, turning on the square wave output
* increases the current drain on the backup battery from about
- * 600 nA to 2uA. Define CONFIG_SYS_RTC_DS1337_NOOSC if you wish to turn
+ * 600 nA to 2uA. Define CONFIG_RTC_DS1337_NOOSC if you wish to turn
* off the OSC output.
*/
-#ifdef CONFIG_SYS_RTC_DS1337_NOOSC
+#ifdef CONFIG_RTC_DS1337_NOOSC
#define RTC_DS1337_RESET_VAL \
(RTC_CTL_BIT_INTCN | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2)
#else
@@ -162,16 +162,16 @@ int rtc_set (struct rtc_time *tmp)
#endif
void rtc_reset (void)
{
-#ifdef CONFIG_SYS_RTC_DS1337
+#ifdef CONFIG_RTC_DS1337
rtc_write (RTC_CTL_REG_ADDR, RTC_DS1337_RESET_VAL);
-#elif defined CONFIG_SYS_RTC_DS1388
+#elif defined CONFIG_RTC_DS1388
rtc_write(RTC_CTL_REG_ADDR, 0x0); /* hw default */
#endif
-#ifdef CONFIG_SYS_DS1339_TCR_VAL
- rtc_write (RTC_TC_REG_ADDR, CONFIG_SYS_DS1339_TCR_VAL);
+#ifdef CONFIG_RTC_DS1339_TCR_VAL
+ rtc_write (RTC_TC_REG_ADDR, CONFIG_RTC_DS1339_TCR_VAL);
#endif
-#ifdef CONFIG_SYS_DS1388_TCR_VAL
- rtc_write(RTC_TC_REG_ADDR, CONFIG_SYS_DS1388_TCR_VAL);
+#ifdef CONFIG_RTC_DS1388_TCR_VAL
+ rtc_write(RTC_TC_REG_ADDR, CONFIG_RTC_DS1388_TCR_VAL);
#endif
}
diff --git a/drivers/rtc/i2c_rtc_emul.c b/drivers/rtc/i2c_rtc_emul.c
index 20827fdff1..0e06c97367 100644
--- a/drivers/rtc/i2c_rtc_emul.c
+++ b/drivers/rtc/i2c_rtc_emul.c
@@ -16,7 +16,6 @@
#include <common.h>
#include <dm.h>
-#include <fdtdec.h>
#include <i2c.h>
#include <os.h>
#include <rtc.h>
diff --git a/drivers/rtc/mpc5xxx.c b/drivers/rtc/mpc5xxx.c
deleted file mode 100644
index 929783e15f..0000000000
--- a/drivers/rtc/mpc5xxx.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * (C) Copyright 2004
- * Reinhard Meyer, EMK Elektronik GmbH
- * r.meyer@emk-elektronik.de
- * www.emk-elektronik.de
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*****************************************************************************
- * Date & Time support for internal RTC of MPC52xx
- *****************************************************************************/
-/*#define DEBUG*/
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_CMD_DATE)
-
-/*****************************************************************************
- * this structure should be defined in mpc5200.h ...
- *****************************************************************************/
-typedef struct rtc5200 {
- volatile ulong tsr; /* MBAR+0x800: time set register */
- volatile ulong dsr; /* MBAR+0x804: data set register */
- volatile ulong nysr; /* MBAR+0x808: new year and stopwatch register */
- volatile ulong aier; /* MBAR+0x80C: alarm and interrupt enable register */
- volatile ulong ctr; /* MBAR+0x810: current time register */
- volatile ulong cdr; /* MBAR+0x814: current data register */
- volatile ulong asir; /* MBAR+0x818: alarm and stopwatch interrupt register */
- volatile ulong piber; /* MBAR+0x81C: periodic interrupt and bus error register */
- volatile ulong trdr; /* MBAR+0x820: test register/divides register */
-} RTC5200;
-
-#define RTC_SET 0x02000000
-#define RTC_PAUSE 0x01000000
-
-/*****************************************************************************
- * get time
- *****************************************************************************/
-int rtc_get (struct rtc_time *tmp)
-{
- RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
- ulong time, date, time2;
-
- /* read twice to avoid getting a funny time when the second is just changing */
- do {
- time = rtc->ctr;
- date = rtc->cdr;
- time2 = rtc->ctr;
- } while (time != time2);
-
- tmp->tm_year = date & 0xfff;
- tmp->tm_mon = (date >> 24) & 0xf;
- tmp->tm_mday = (date >> 16) & 0x1f;
- tmp->tm_wday = (date >> 21) & 7;
- /* sunday is 7 in 5200 but 0 in rtc_time */
- if (tmp->tm_wday == 7)
- tmp->tm_wday = 0;
- tmp->tm_hour = (time >> 16) & 0x1f;
- tmp->tm_min = (time >> 8) & 0x3f;
- tmp->tm_sec = time & 0x3f;
-
- debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
- tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
- return 0;
-}
-
-/*****************************************************************************
- * set time
- *****************************************************************************/
-int rtc_set (struct rtc_time *tmp)
-{
- RTC5200 *rtc = (RTC5200 *) (CONFIG_SYS_MBAR+0x800);
- ulong time, date, year;
-
- debug ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
- tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
- time = (tmp->tm_hour << 16) | (tmp->tm_min << 8) | tmp->tm_sec;
- date = (tmp->tm_mon << 16) | tmp->tm_mday;
- if (tmp->tm_wday == 0)
- date |= (7 << 8);
- else
- date |= (tmp->tm_wday << 8);
- year = tmp->tm_year;
-
- /* mask unwanted bits that might show up when rtc_time is corrupt */
- time &= 0x001f3f3f;
- date &= 0x001f071f;
- year &= 0x00000fff;
-
- /* pause and set the RTC */
- rtc->nysr = year;
- rtc->dsr = date | RTC_PAUSE;
- udelay (1000);
- rtc->dsr = date | RTC_PAUSE | RTC_SET;
- udelay (1000);
- rtc->dsr = date | RTC_PAUSE;
- udelay (1000);
- rtc->dsr = date;
- udelay (1000);
-
- rtc->tsr = time | RTC_PAUSE;
- udelay (1000);
- rtc->tsr = time | RTC_PAUSE | RTC_SET;
- udelay (1000);
- rtc->tsr = time | RTC_PAUSE;
- udelay (1000);
- rtc->tsr = time;
- udelay (1000);
-
- return 0;
-}
-
-/*****************************************************************************
- * reset rtc circuit
- *****************************************************************************/
-void rtc_reset (void)
-{
- return; /* nothing to do */
-}
-
-#endif
diff --git a/drivers/rtc/mpc8xx.c b/drivers/rtc/mpc8xx.c
deleted file mode 100644
index 147a225c6b..0000000000
--- a/drivers/rtc/mpc8xx.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*
- * Date & Time support for internal RTC of MPC8xx
- */
-
-/*#define DEBUG*/
-
-#include <common.h>
-#include <command.h>
-#include <rtc.h>
-
-#if defined(CONFIG_CMD_DATE)
-
-/* ------------------------------------------------------------------------- */
-
-int rtc_get (struct rtc_time *tmp)
-{
- volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
- ulong tim;
-
- tim = immr->im_sit.sit_rtc;
-
- rtc_to_tm(tim, tmp);
-
- debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
- tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
- return 0;
-}
-
-int rtc_set (struct rtc_time *tmp)
-{
- volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
- ulong tim;
-
- debug ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
- tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
- tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-
- tim = rtc_mktime(tmp);
-
- immr->im_sitk.sitk_rtck = KAPWR_KEY;
- immr->im_sit.sit_rtc = tim;
-
- return 0;
-}
-
-void rtc_reset (void)
-{
- return; /* nothing to do */
-}
-
-#endif
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 58fc7cd2e6..c64f4a6d7b 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -65,7 +65,7 @@ config DM_SERIAL
defined in include/serial.h.
config SPL_DM_SERIAL
- bool "Enable Driver Model for serial drivers"
+ bool "Enable Driver Model for serial drivers in SPL"
depends on DM_SERIAL
default y if SPL && DM_SERIAL
help
@@ -75,7 +75,7 @@ config SPL_DM_SERIAL
defined in include/serial.h.
config TPL_DM_SERIAL
- bool "Enable Driver Model for serial drivers"
+ bool "Enable Driver Model for serial drivers in TPL"
depends on DM_SERIAL
default y if TPL && DM_SERIAL
help
diff --git a/drivers/serial/altera_jtag_uart.c b/drivers/serial/altera_jtag_uart.c
index cb11b31326..4a6e60f87e 100644
--- a/drivers/serial/altera_jtag_uart.c
+++ b/drivers/serial/altera_jtag_uart.c
@@ -97,7 +97,7 @@ static int altera_jtaguart_ofdata_to_platdata(struct udevice *dev)
{
struct altera_jtaguart_platdata *plat = dev_get_platdata(dev);
- plat->regs = map_physmem(dev_get_addr(dev),
+ plat->regs = map_physmem(devfdt_get_addr(dev),
sizeof(struct altera_jtaguart_regs),
MAP_NOCACHE);
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index 8344940282..75c035285e 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -89,7 +89,7 @@ static int altera_uart_ofdata_to_platdata(struct udevice *dev)
{
struct altera_uart_platdata *plat = dev_get_platdata(dev);
- plat->regs = map_physmem(dev_get_addr(dev),
+ plat->regs = map_physmem(devfdt_get_addr(dev),
sizeof(struct altera_uart_regs),
MAP_NOCACHE);
plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 453f8eb451..bb294ff94f 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -255,7 +255,7 @@ static int atmel_serial_probe(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL)
fdt_addr_t addr_base;
- addr_base = dev_get_addr(dev);
+ addr_base = devfdt_get_addr(dev);
if (addr_base == FDT_ADDR_T_NONE)
return -ENODEV;
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 0eb7c02561..52c52c1ad1 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -395,7 +395,7 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
int err;
/* try Processor Local Bus device first */
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI)
if (addr == FDT_ADDR_T_NONE) {
/* then try pci device */
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index c2b9c5f12f..a9c4f89e1a 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -74,7 +74,8 @@ static void serial_find_console_or_panic(void)
* bind it anyway.
*/
if (node > 0 &&
- !lists_bind_fdt(gd->dm_root, blob, node, &dev)) {
+ !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
+ &dev)) {
if (!device_probe(dev)) {
gd->cur_serial_dev = dev;
return;
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index f1bd15b002..f2bd0e404c 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -133,7 +133,6 @@ serial_initfunc(marvell_serial_initialize);
serial_initfunc(max3100_serial_initialize);
serial_initfunc(mcf_serial_initialize);
serial_initfunc(ml2_serial_initialize);
-serial_initfunc(mpc512x_serial_initialize);
serial_initfunc(mpc5xx_serial_initialize);
serial_initfunc(mpc8260_scc_serial_initialize);
serial_initfunc(mpc8260_smc_serial_initialize);
@@ -224,10 +223,6 @@ void serial_initialize(void)
max3100_serial_initialize();
mcf_serial_initialize();
ml2_serial_initialize();
- mpc512x_serial_initialize();
- mpc5xx_serial_initialize();
- mpc8260_scc_serial_initialize();
- mpc8260_smc_serial_initialize();
mpc85xx_serial_initialize();
mpc8xx_serial_initialize();
mxc_serial_initialize();
diff --git a/drivers/serial/serial_ar933x.c b/drivers/serial/serial_ar933x.c
index aae66dc682..09d2efefdf 100644
--- a/drivers/serial/serial_ar933x.c
+++ b/drivers/serial/serial_ar933x.c
@@ -149,7 +149,7 @@ static int ar933x_serial_probe(struct udevice *dev)
fdt_addr_t addr;
u32 val;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c
index fc91977b4c..da4a07ab2f 100644
--- a/drivers/serial/serial_arc.c
+++ b/drivers/serial/serial_arc.c
@@ -114,7 +114,7 @@ static int arc_serial_ofdata_to_platdata(struct udevice *dev)
struct arc_serial_platdata *plat = dev_get_platdata(dev);
DECLARE_GLOBAL_DATA_PTR;
- plat->reg = (struct arc_serial_regs *)dev_get_addr(dev);
+ plat->reg = (struct arc_serial_regs *)devfdt_get_addr(dev);
plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"clock-frequency", 0);
diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c
index e7ed8993b8..41c26b3d93 100644
--- a/drivers/serial/serial_bcm283x_mu.c
+++ b/drivers/serial/serial_bcm283x_mu.c
@@ -159,7 +159,7 @@ static int bcm283x_mu_serial_ofdata_to_platdata(struct udevice *dev)
struct bcm283x_mu_serial_platdata *plat = dev_get_platdata(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c
index db270e3b21..20f67f4b7e 100644
--- a/drivers/serial/serial_bcm6345.c
+++ b/drivers/serial/serial_bcm6345.c
@@ -8,12 +8,12 @@
*/
#include <clk.h>
+#include <dm.h>
#include <debug_uart.h>
#include <errno.h>
#include <serial.h>
#include <asm/io.h>
#include <asm/types.h>
-#include <dm/device.h>
/* UART Control register */
#define UART_CTL_REG 0x0
@@ -141,6 +141,8 @@ static int bcm6345_serial_init(void __iomem *base, ulong clk, u32 baudrate)
UART_CTL_RXTIMEOUT_5 |
/* set 8 bits/symbol */
UART_CTL_BITSPERSYM_8 |
+ /* set 1 stop bit */
+ UART_CTL_STOPBITS_1 |
/* set parity to even */
UART_CTL_RXPAREVEN_MASK |
UART_CTL_TXPAREVEN_MASK);
@@ -155,11 +157,11 @@ static int bcm6345_serial_init(void __iomem *base, ulong clk, u32 baudrate)
UART_FIFO_CFG_TX_4);
/* set baud rate */
- val = (clk / baudrate) / 16;
+ val = ((clk / baudrate) >> 4);
if (val & 0x1)
- val = val;
+ val = (val >> 1);
else
- val = val / 2 - 1;
+ val = (val >> 1) - 1;
writel_be(val, base + UART_BAUD_REG);
/* clear interrupts */
@@ -231,7 +233,7 @@ static int bcm6345_serial_probe(struct udevice *dev)
int ret;
/* get address */
- addr = dev_get_addr_size_index(dev, 0, &size);
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -241,7 +243,7 @@ static int bcm6345_serial_probe(struct udevice *dev)
ret = clk_get_by_index(dev, 0, &clk);
if (ret < 0)
return ret;
- priv->uartclk = clk_get_rate(&clk) / 2;
+ priv->uartclk = clk_get_rate(&clk);
clk_free(&clk);
/* initialize serial */
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index 95e002ea4b..382f8ba5b5 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -416,10 +416,10 @@ static int lpuart_serial_ofdata_to_platdata(struct udevice *dev)
{
struct lpuart_serial_platdata *plat = dev->platdata;
const void *blob = gd->fdt_blob;
- int node = dev->of_offset;
+ int node = dev_of_offset(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c
index 1b494265ce..363affb8c5 100644
--- a/drivers/serial/serial_meson.c
+++ b/drivers/serial/serial_meson.c
@@ -108,7 +108,7 @@ static int meson_serial_ofdata_to_platdata(struct udevice *dev)
struct meson_serial_platdata *plat = dev->platdata;
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index 63b3006c63..7bed756a71 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -201,7 +201,7 @@ static int msm_serial_ofdata_to_platdata(struct udevice *dev)
{
struct msm_serial_data *priv = dev_get_priv(dev);
- priv->base = dev_get_addr(dev);
+ priv->base = devfdt_get_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_mvebu_a3700.c b/drivers/serial/serial_mvebu_a3700.c
index 192e79a3d3..4f9de88c1b 100644
--- a/drivers/serial/serial_mvebu_a3700.c
+++ b/drivers/serial/serial_mvebu_a3700.c
@@ -105,7 +105,7 @@ static int mvebu_serial_ofdata_to_platdata(struct udevice *dev)
{
struct mvebu_platdata *plat = dev_get_platdata(dev);
- plat->base = dev_get_addr_ptr(dev);
+ plat->base = devfdt_get_addr_ptr(dev);
return 0;
}
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 64126e25bf..75264fb781 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -353,7 +353,7 @@ static int mxc_serial_ofdata_to_platdata(struct udevice *dev)
struct mxc_serial_platdata *plat = dev->platdata;
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 941b424a4c..4ec0f29c42 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -349,7 +349,7 @@ static int pl01x_serial_ofdata_to_platdata(struct udevice *dev)
struct pl01x_serial_platdata *plat = dev_get_platdata(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 96842de8d4..a2f692bf05 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -182,7 +182,7 @@ static int s5p_serial_ofdata_to_platdata(struct udevice *dev)
struct s5p_serial_platdata *plat = dev->platdata;
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_sti_asc.c b/drivers/serial/serial_sti_asc.c
index ce26c94710..8dcd4f8d25 100644
--- a/drivers/serial/serial_sti_asc.c
+++ b/drivers/serial/serial_sti_asc.c
@@ -170,7 +170,7 @@ static int sti_asc_serial_probe(struct udevice *dev)
unsigned long val;
fdt_addr_t base;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_stm32x7.c b/drivers/serial/serial_stm32x7.c
index 1907cef5b3..61e8167a3b 100644
--- a/drivers/serial/serial_stm32x7.c
+++ b/drivers/serial/serial_stm32x7.c
@@ -20,7 +20,7 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
{
struct stm32x7_serial_platdata *plat = dev->platdata;
struct stm32_usart *const usart = plat->base;
- u32 clock, int_div, frac_div, tmp;
+ u32 clock, int_div, mantissa, fraction, oversampling;
if (((u32)usart & STM32_BUS_MASK) == APB1_PERIPH_BASE)
clock = clock_get(CLOCK_APB1);
@@ -29,11 +29,20 @@ static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
else
return -EINVAL;
- int_div = (25 * clock) / (4 * baudrate);
- tmp = ((int_div / 100) << USART_BRR_M_SHIFT) & USART_BRR_M_MASK;
- frac_div = int_div - (100 * (tmp >> USART_BRR_M_SHIFT));
- tmp |= (((frac_div * 16) + 50) / 100) & USART_BRR_F_MASK;
- writel(tmp, &usart->brr);
+ int_div = DIV_ROUND_CLOSEST(clock, baudrate);
+
+ if (int_div < 16) {
+ oversampling = 8;
+ setbits_le32(&usart->cr1, USART_CR1_OVER8);
+ } else {
+ oversampling = 16;
+ clrbits_le32(&usart->cr1, USART_CR1_OVER8);
+ }
+
+ mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT;
+ fraction = int_div % oversampling;
+
+ writel(mantissa | fraction, &usart->brr);
return 0;
}
@@ -93,6 +102,9 @@ static int stm32_serial_probe(struct udevice *dev)
}
#endif
+ /* Disable usart-> disable overrun-> enable usart */
+ clrbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE);
+ setbits_le32(&usart->cr3, USART_CR3_OVRDIS);
setbits_le32(&usart->cr1, USART_CR1_RE | USART_CR1_TE | USART_CR1_UE);
return 0;
@@ -100,8 +112,8 @@ static int stm32_serial_probe(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL)
static const struct udevice_id stm32_serial_id[] = {
- {.compatible = "st,stm32-usart"},
- {.compatible = "st,stm32-uart"},
+ {.compatible = "st,stm32f7-usart"},
+ {.compatible = "st,stm32f7-uart"},
{}
};
@@ -110,7 +122,7 @@ static int stm32_serial_ofdata_to_platdata(struct udevice *dev)
struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_stm32x7.h b/drivers/serial/serial_stm32x7.h
index 6190d67406..facfdbabe8 100644
--- a/drivers/serial/serial_stm32x7.h
+++ b/drivers/serial/serial_stm32x7.h
@@ -23,10 +23,13 @@ struct stm32_usart {
};
-#define USART_CR1_RE (1 << 2)
+#define USART_CR1_OVER8 (1 << 15)
#define USART_CR1_TE (1 << 3)
+#define USART_CR1_RE (1 << 2)
#define USART_CR1_UE (1 << 0)
+#define USART_CR3_OVRDIS (1 << 12)
+
#define USART_SR_FLAG_RXNE (1 << 5)
#define USART_SR_FLAG_TXE (1 << 7)
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index 0e25cba6ac..68895bde8e 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -6,11 +6,12 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <common.h>
+#include <dm.h>
#include <linux/io.h>
#include <linux/serial_reg.h>
#include <linux/sizes.h>
#include <linux/errno.h>
-#include <dm/device.h>
#include <serial.h>
#include <fdtdec.h>
@@ -95,7 +96,7 @@ static int uniphier_serial_probe(struct udevice *dev)
fdt_addr_t base;
u32 tmp;
- base = dev_get_addr(dev);
+ base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
index a2e9303925..fedd2a9df5 100644
--- a/drivers/serial/serial_xuartlite.c
+++ b/drivers/serial/serial_xuartlite.c
@@ -87,7 +87,7 @@ static int uartlite_serial_ofdata_to_platdata(struct udevice *dev)
{
struct uartlite_platdata *plat = dev_get_platdata(dev);
- plat->regs = (struct uartlite *)dev_get_addr(dev);
+ plat->regs = (struct uartlite *)devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index a2967c03c7..4e86e5c2a1 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -179,7 +179,7 @@ static int zynq_serial_ofdata_to_platdata(struct udevice *dev)
{
struct zynq_uart_priv *priv = dev_get_priv(dev);
- priv->regs = (struct uart_zynq *)dev_get_addr(dev);
+ priv->regs = (struct uart_zynq *)devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/sound/max98095.c b/drivers/sound/max98095.c
index 35829f88c9..7c37bd0701 100644
--- a/drivers/sound/max98095.c
+++ b/drivers/sound/max98095.c
@@ -9,6 +9,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+
+#include <common.h>
#include <asm/arch/clk.h>
#include <asm/arch/cpu.h>
#include <asm/arch/power.h>
diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c
index d378442c50..b8208cdc87 100644
--- a/drivers/sound/wm8994.c
+++ b/drivers/sound/wm8994.c
@@ -4,11 +4,11 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <common.h>
#include <asm/arch/clk.h>
#include <asm/arch/cpu.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <common.h>
#include <div64.h>
#include <fdtdec.h>
#include <i2c.h>
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index eb1ba27acc..c8dcb82150 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -174,7 +174,7 @@ static int altera_spi_ofdata_to_platdata(struct udevice *bus)
{
struct altera_spi_platdata *plat = dev_get_platdata(bus);
- plat->regs = map_physmem(dev_get_addr(bus),
+ plat->regs = map_physmem(devfdt_get_addr(bus),
sizeof(struct altera_spi_regs),
MAP_NOCACHE);
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index b18c733b67..f4b92aae28 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -177,7 +177,7 @@ static int ath79_spi_probe(struct udevice *bus)
struct ath79_spi_priv *priv = dev_get_priv(bus);
fdt_addr_t addr;
- addr = dev_get_addr(bus);
+ addr = devfdt_get_addr(bus);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 4701b79f16..e2f8342e88 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -469,7 +469,7 @@ static int atmel_spi_probe(struct udevice *bus)
if (ret)
return ret;
- bus_plat->regs = (struct at91_spi *)dev_get_addr(bus);
+ bus_plat->regs = (struct at91_spi *)devfdt_get_addr(bus);
ret = gpio_request_list_by_name(bus, "cs-gpios", priv->cs_gpios,
ARRAY_SIZE(priv->cs_gpios), 0);
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 65d37b0b9f..291ef9576a 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -542,7 +542,7 @@ static int davinci_ofdata_to_platadata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- ds->regs = dev_map_physmem(bus, sizeof(struct davinci_spi_regs));
+ ds->regs = devfdt_map_physmem(bus, sizeof(struct davinci_spi_regs));
if (!ds->regs) {
printf("%s: could not map device address\n", __func__);
return -EINVAL;
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 9d5e29c6c3..5aa507b2d8 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -134,7 +134,7 @@ static int dw_spi_ofdata_to_platdata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- plat->regs = (struct dw_spi *)dev_get_addr(bus);
+ plat->regs = (struct dw_spi *)devfdt_get_addr(bus);
/* Use 500KHz as a suitable default */
plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c
index aa0784c04a..89490f70d4 100644
--- a/drivers/spi/exynos_spi.c
+++ b/drivers/spi/exynos_spi.c
@@ -255,7 +255,7 @@ static int exynos_spi_ofdata_to_platdata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- plat->regs = (struct exynos_spi *)dev_get_addr(bus);
+ plat->regs = (struct exynos_spi *)devfdt_get_addr(bus);
plat->periph_id = pinmux_decode_periph_id(blob, node);
if (plat->periph_id == PERIPH_ID_NONE) {
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
index e09985ef2b..42086197d9 100644
--- a/drivers/spi/fsl_dspi.c
+++ b/drivers/spi/fsl_dspi.c
@@ -9,6 +9,8 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
+
+#include <common.h>
#include <dm.h>
#include <errno.h>
#include <common.h>
@@ -654,7 +656,7 @@ static int fsl_dspi_ofdata_to_platdata(struct udevice *bus)
plat->num_chipselect =
fdtdec_get_int(blob, node, "num-cs", FSL_DSPI_MAX_CHIPSELECT);
- addr = dev_get_addr(bus);
+ addr = devfdt_get_addr(bus);
if (addr == FDT_ADDR_T_NONE) {
debug("DSPI: Can't get base address or size\n");
return -ENOMEM;
diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c
index 791f3e8099..0c6bd295cd 100644
--- a/drivers/spi/kirkwood_spi.c
+++ b/drivers/spi/kirkwood_spi.c
@@ -327,7 +327,7 @@ static int mvebu_spi_ofdata_to_platdata(struct udevice *bus)
{
struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
- plat->spireg = (struct kwspi_registers *)dev_get_addr(bus);
+ plat->spireg = (struct kwspi_registers *)devfdt_get_addr(bus);
return 0;
}
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index ee847e4610..ec4907391c 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -251,7 +251,7 @@ static int mvebu_spi_ofdata_to_platdata(struct udevice *bus)
{
struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
- plat->spireg = (struct spi_reg *)dev_get_addr(bus);
+ plat->spireg = (struct spi_reg *)devfdt_get_addr(bus);
/*
* FIXME
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 3caea151c5..ebbdcaf14a 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -633,7 +633,7 @@ static int omap3_spi_probe(struct udevice *dev)
struct omap2_mcspi_platform_config* data =
(struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
- priv->regs = (struct mcspi *)(dev_get_addr(dev) + data->regs_offset);
+ priv->regs = (struct mcspi *)(devfdt_get_addr(dev) + data->regs_offset);
priv->pin_dir = fdtdec_get_uint(blob, node, "ti,pindir-d0-out-d1-in",
MCSPI_PINDIR_D0_IN_D1_OUT);
priv->wordlen = SPI_DEFAULT_WORDLEN;
diff --git a/drivers/spi/pic32_spi.c b/drivers/spi/pic32_spi.c
index 78d78bc54b..15266b048c 100644
--- a/drivers/spi/pic32_spi.c
+++ b/drivers/spi/pic32_spi.c
@@ -414,7 +414,7 @@ static int pic32_spi_probe(struct udevice *bus)
* of the ongoing transfer. To avoid this sort of error we will drive
* /CS manually by toggling cs-gpio pins.
*/
- ret = gpio_request_by_name_nodev(gd->fdt_blob, node, "cs-gpios", 0,
+ ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "cs-gpios", 0,
&priv->cs_gpio, GPIOD_IS_OUT);
if (ret) {
printf("pic32-spi: error, cs-gpios not found\n");
diff --git a/drivers/spi/rk_spi.c b/drivers/spi/rk_spi.c
index ea209801a7..a8f0eb0be6 100644
--- a/drivers/spi/rk_spi.c
+++ b/drivers/spi/rk_spi.c
@@ -186,7 +186,7 @@ static int rockchip_spi_ofdata_to_platdata(struct udevice *bus)
int node = dev_of_offset(bus);
int ret;
- plat->base = dev_get_addr(bus);
+ plat->base = devfdt_get_addr(bus);
ret = clk_get_by_index(bus, 0, &priv->clk);
if (ret < 0) {
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index c061c05443..e06a603ab1 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -7,7 +7,6 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <fdtdec.h>
#include <malloc.h>
#include <spi.h>
#include <dm/device-internal.h>
@@ -113,11 +112,10 @@ static int spi_child_post_bind(struct udevice *dev)
{
struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
- if (dev_of_offset(dev) == -1)
+ if (!dev_of_valid(dev))
return 0;
- return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev_of_offset(dev),
- plat);
+ return spi_slave_ofdata_to_platdata(dev, plat);
}
#endif
@@ -126,8 +124,7 @@ static int spi_post_probe(struct udevice *bus)
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
- spi->max_hz = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
- "spi-max-frequency", 0);
+ spi->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
#endif
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
struct dm_spi_ops *ops = spi_get_ops(bus);
@@ -375,7 +372,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
int ret;
ret = spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &dev,
- &slave);
+ &slave);
if (ret)
return NULL;
@@ -388,27 +385,27 @@ void spi_free_slave(struct spi_slave *slave)
slave->dev = NULL;
}
-int spi_slave_ofdata_to_platdata(const void *blob, int node,
+int spi_slave_ofdata_to_platdata(struct udevice *dev,
struct dm_spi_slave_platdata *plat)
{
int mode = 0;
int value;
- plat->cs = fdtdec_get_int(blob, node, "reg", -1);
- plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0);
- if (fdtdec_get_bool(blob, node, "spi-cpol"))
+ plat->cs = dev_read_u32_default(dev, "reg", -1);
+ plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", 0);
+ if (dev_read_bool(dev, "spi-cpol"))
mode |= SPI_CPOL;
- if (fdtdec_get_bool(blob, node, "spi-cpha"))
+ if (dev_read_bool(dev, "spi-cpha"))
mode |= SPI_CPHA;
- if (fdtdec_get_bool(blob, node, "spi-cs-high"))
+ if (dev_read_bool(dev, "spi-cs-high"))
mode |= SPI_CS_HIGH;
- if (fdtdec_get_bool(blob, node, "spi-3wire"))
+ if (dev_read_bool(dev, "spi-3wire"))
mode |= SPI_3WIRE;
- if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
+ if (dev_read_bool(dev, "spi-half-duplex"))
mode |= SPI_PREAMBLE;
/* Device DUAL/QUAD mode */
- value = fdtdec_get_uint(blob, node, "spi-tx-bus-width", 1);
+ value = dev_read_u32_default(dev, "spi-tx-bus-width", 1);
switch (value) {
case 1:
break;
@@ -423,7 +420,7 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node,
break;
}
- value = fdtdec_get_uint(blob, node, "spi-rx-bus-width", 1);
+ value = dev_read_u32_default(dev, "spi-rx-bus-width", 1);
switch (value) {
case 1:
break;
diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c
index 897409ca02..91659349a3 100644
--- a/drivers/spi/tegra114_spi.c
+++ b/drivers/spi/tegra114_spi.c
@@ -103,7 +103,7 @@ static int tegra114_spi_ofdata_to_platdata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- plat->base = dev_get_addr(bus);
+ plat->base = devfdt_get_addr(bus);
plat->periph_id = clock_decode_periph_id(blob, node);
if (plat->periph_id == PERIPH_ID_NONE) {
@@ -152,6 +152,7 @@ static int tegra114_spi_probe(struct udevice *bus)
bus->name, priv->freq, rate);
}
}
+ udelay(plat->deactivate_delay_us);
/* Clear stale status here */
setbits_le32(&regs->fifo_status,
diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c
index ecbf4c16f3..299e1b44fa 100644
--- a/drivers/spi/tegra20_sflash.c
+++ b/drivers/spi/tegra20_sflash.c
@@ -90,7 +90,7 @@ static int tegra20_sflash_ofdata_to_platdata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- plat->base = dev_get_addr(bus);
+ plat->base = devfdt_get_addr(bus);
plat->periph_id = clock_decode_periph_id(blob, node);
if (plat->periph_id == PERIPH_ID_NONE) {
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index 1d99a1e910..4cbde7b22f 100644
--- a/drivers/spi/tegra20_slink.c
+++ b/drivers/spi/tegra20_slink.c
@@ -96,7 +96,7 @@ static int tegra30_spi_ofdata_to_platdata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- plat->base = dev_get_addr(bus);
+ plat->base = devfdt_get_addr(bus);
plat->periph_id = clock_decode_periph_id(blob, node);
if (plat->periph_id == PERIPH_ID_NONE) {
diff --git a/drivers/spi/tegra210_qspi.c b/drivers/spi/tegra210_qspi.c
index 1e094cbc8b..6d0b5da261 100644
--- a/drivers/spi/tegra210_qspi.c
+++ b/drivers/spi/tegra210_qspi.c
@@ -99,7 +99,7 @@ static int tegra210_qspi_ofdata_to_platdata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- plat->base = dev_get_addr(bus);
+ plat->base = devfdt_get_addr(bus);
plat->periph_id = clock_decode_periph_id(blob, node);
if (plat->periph_id == PERIPH_ID_NONE) {
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index 3c4c9dd986..bea3aff943 100644
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
@@ -574,8 +574,8 @@ static void *map_syscon_chipselects(struct udevice *bus)
return NULL;
}
- cell = fdt_getprop(gd->fdt_blob, bus->of_offset, "syscon-chipselects",
- &len);
+ cell = fdt_getprop(gd->fdt_blob, dev_of_offset(bus),
+ "syscon-chipselects", &len);
if (len < 2*sizeof(fdt32_t)) {
debug("%s: offset not available\n", __func__);
return NULL;
@@ -584,7 +584,7 @@ static void *map_syscon_chipselects(struct udevice *bus)
return fdtdec_get_number(cell + 1, 1) + regmap_get_range(regmap, 0);
#else
fdt_addr_t addr;
- addr = dev_get_addr_index(bus, 2);
+ addr = devfdt_get_addr_index(bus, 2);
return (addr == FDT_ADDR_T_NONE) ? NULL :
map_physmem(addr, 0, MAP_NOCACHE);
#endif
@@ -597,9 +597,9 @@ static int ti_qspi_ofdata_to_platdata(struct udevice *bus)
int node = dev_of_offset(bus);
priv->ctrl_mod_mmap = map_syscon_chipselects(bus);
- priv->base = map_physmem(dev_get_addr(bus), sizeof(struct ti_qspi_regs),
- MAP_NOCACHE);
- priv->memory_map = map_physmem(dev_get_addr_index(bus, 1), 0,
+ priv->base = map_physmem(devfdt_get_addr(bus),
+ sizeof(struct ti_qspi_regs), MAP_NOCACHE);
+ priv->memory_map = map_physmem(devfdt_get_addr_index(bus, 1), 0,
MAP_NOCACHE);
priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1);
diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c
index 2b77f1ccdc..ed2b8cb52f 100644
--- a/drivers/spi/zynq_spi.c
+++ b/drivers/spi/zynq_spi.c
@@ -76,7 +76,7 @@ static int zynq_spi_ofdata_to_platdata(struct udevice *bus)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(bus);
- plat->regs = (struct zynq_spi_regs *)dev_get_addr(bus);
+ plat->regs = (struct zynq_spi_regs *)devfdt_get_addr(bus);
/* FIXME: Use 250MHz as a suitable default */
plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
index 605683fc0e..ca27ee5736 100644
--- a/drivers/spmi/spmi-msm.c
+++ b/drivers/spmi/spmi-msm.c
@@ -150,7 +150,7 @@ static int msm_spmi_probe(struct udevice *dev)
int node = dev_of_offset(dev);
int i;
- priv->arb_chnl = dev_get_addr(dev);
+ priv->arb_chnl = devfdt_get_addr(dev);
priv->spmi_core = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
dev_of_offset(parent), node, "reg", 1, NULL, false);
priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index b2f746494d..a6d48e8a66 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -31,4 +31,10 @@ config SYSRESET_SYSCON
help
Reboot support for generic SYSCON mapped register reset.
+config SYSRESET_WATCHDOG
+ bool "Enable support for watchdog reboot driver"
+ select WDT
+ help
+ Reboot support for generic watchdog reset.
+
endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index bd352e7541..a5200d377d 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -7,6 +7,7 @@
obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
+obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
@@ -14,7 +15,9 @@ endif
obj-$(CONFIG_ROCKCHIP_RK3188) += sysreset_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288) += sysreset_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328) += sysreset_rk3328.o
+obj-$(CONFIG_ROCKCHIP_RK3368) += sysreset_rk3368.o
obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
+obj-$(CONFIG_ROCKCHIP_RV1108) += sysreset_rv1108.o
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
diff --git a/drivers/sysreset/sysreset_psci.c b/drivers/sysreset/sysreset_psci.c
index a4911b7d8f..4656d273c1 100644
--- a/drivers/sysreset/sysreset_psci.c
+++ b/drivers/sysreset/sysreset_psci.c
@@ -4,7 +4,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <dm/device.h>
+#include <common.h>
+#include <dm.h>
#include <sysreset.h>
#include <linux/errno.h>
#include <linux/psci.h>
diff --git a/drivers/sysreset/sysreset_rk3368.c b/drivers/sysreset/sysreset_rk3368.c
new file mode 100644
index 0000000000..de62921b78
--- /dev/null
+++ b/drivers/sysreset/sysreset_rk3368.c
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3368.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+static void rk3368_pll_enter_slow_mode(struct rk3368_cru *cru)
+{
+ struct rk3368_pll *pll;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ pll = &cru->pll[i];
+ rk_clrreg(&pll->con3, PLL_MODE_MASK);
+ }
+}
+
+static int rk3368_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct rk3368_cru *cru = rockchip_get_cru();
+
+ if (IS_ERR(cru))
+ return PTR_ERR(cru);
+ switch (type) {
+ case SYSRESET_WARM:
+ rk3368_pll_enter_slow_mode(cru);
+ rk_clrsetreg(&cru->glb_rst_con, PMU_GLB_SRST_CTRL_MASK,
+ PMU_RST_BY_SND_GLB_SRST << PMU_GLB_SRST_CTRL_SHIFT);
+ writel(0xeca8, &cru->glb_srst_snd_val);
+ break;
+ case SYSRESET_COLD:
+ rk3368_pll_enter_slow_mode(cru);
+ rk_clrsetreg(&cru->glb_rst_con, PMU_GLB_SRST_CTRL_MASK,
+ PMU_RST_BY_FST_GLB_SRST << PMU_GLB_SRST_CTRL_SHIFT);
+ writel(0xfdb9, &cru->glb_srst_fst_val);
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops rk3368_sysreset = {
+ .request = rk3368_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_rk3368) = {
+ .name = "rk3368_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &rk3368_sysreset,
+};
diff --git a/drivers/sysreset/sysreset_rv1108.c b/drivers/sysreset/sysreset_rv1108.c
new file mode 100644
index 0000000000..9d8e9f7ade
--- /dev/null
+++ b/drivers/sysreset/sysreset_rv1108.c
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rv1108.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+int rv1108_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct rv1108_cru *cru = rockchip_get_cru();
+
+ if (IS_ERR(cru))
+ return PTR_ERR(cru);
+
+ switch (type) {
+ case SYSRESET_WARM:
+ writel(0xeca8, &cru->glb_srst_snd_val);
+ break;
+ case SYSRESET_COLD:
+ writel(0xfdb9, &cru->glb_srst_fst_val);
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops rv1108_sysreset = {
+ .request = rv1108_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_rv1108) = {
+ .name = "rv1108_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &rv1108_sysreset,
+};
diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c
index 0c4e2e1a93..12b3e5f86e 100644
--- a/drivers/sysreset/sysreset_sandbox.c
+++ b/drivers/sysreset/sysreset_sandbox.c
@@ -41,7 +41,7 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
* (see the U_BOOT_DEVICE() declaration below) should not do anything.
* If we are that device, return an error.
*/
- if (state->fdt_fname && dev_of_offset(dev) == -1)
+ if (state->fdt_fname && !dev_of_valid(dev))
return -ENODEV;
switch (type) {
diff --git a/drivers/sysreset/sysreset_snapdragon.c b/drivers/sysreset/sysreset_snapdragon.c
index a6cabfb8b0..9869813978 100644
--- a/drivers/sysreset/sysreset_snapdragon.c
+++ b/drivers/sysreset/sysreset_snapdragon.c
@@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int msm_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
- phys_addr_t addr = dev_get_addr(dev);
+ phys_addr_t addr = devfdt_get_addr(dev);
if (!addr)
return -EINVAL;
writel(0, addr);
diff --git a/drivers/sysreset/sysreset_watchdog.c b/drivers/sysreset/sysreset_watchdog.c
new file mode 100644
index 0000000000..304ed052a2
--- /dev/null
+++ b/drivers/sysreset/sysreset_watchdog.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <wdt.h>
+
+struct wdt_reboot_priv {
+ struct udevice *wdt;
+};
+
+static int wdt_reboot_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct wdt_reboot_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = wdt_expire_now(priv->wdt, 0);
+ if (ret)
+ return ret;
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops wdt_reboot_ops = {
+ .request = wdt_reboot_request,
+};
+
+int wdt_reboot_probe(struct udevice *dev)
+{
+ struct wdt_reboot_priv *priv = dev_get_priv(dev);
+ int err;
+
+ err = uclass_get_device_by_phandle(UCLASS_WDT, dev,
+ "wdt", &priv->wdt);
+ if (err) {
+ error("unable to find wdt device\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id wdt_reboot_ids[] = {
+ { .compatible = "wdt-reboot" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(wdt_reboot) = {
+ .name = "wdt_reboot",
+ .id = UCLASS_SYSRESET,
+ .of_match = wdt_reboot_ids,
+ .ops = &wdt_reboot_ops,
+ .priv_auto_alloc_size = sizeof(struct wdt_reboot_priv),
+ .probe = wdt_reboot_probe,
+};
diff --git a/drivers/timer/ae3xx_timer.c b/drivers/timer/ae3xx_timer.c
index 7ccb3eb446..bcc07a0c86 100644
--- a/drivers/timer/ae3xx_timer.c
+++ b/drivers/timer/ae3xx_timer.c
@@ -92,7 +92,7 @@ static int atctmr_timer_probe(struct udevice *dev)
static int atctme_timer_ofdata_to_platdata(struct udevice *dev)
{
struct atftmr_timer_platdata *plat = dev_get_platdata(dev);
- plat->regs = map_physmem(dev_get_addr(dev) , 0x100 , MAP_NOCACHE);
+ plat->regs = map_physmem(devfdt_get_addr(dev) , 0x100 , MAP_NOCACHE);
return 0;
}
diff --git a/drivers/timer/ag101p_timer.c b/drivers/timer/ag101p_timer.c
index 163402f8ce..8dc85c4183 100644
--- a/drivers/timer/ag101p_timer.c
+++ b/drivers/timer/ag101p_timer.c
@@ -95,7 +95,7 @@ static int atftmr_timer_probe(struct udevice *dev)
static int atftme_timer_ofdata_to_platdata(struct udevice *dev)
{
struct atftmr_timer_platdata *plat = dev_get_platdata(dev);
- plat->regs = map_physmem(dev_get_addr(dev),
+ plat->regs = map_physmem(devfdt_get_addr(dev),
sizeof(struct atftmr_timer_regs),
MAP_NOCACHE);
return 0;
diff --git a/drivers/timer/altera_timer.c b/drivers/timer/altera_timer.c
index 89fe05b704..1ba85c4399 100644
--- a/drivers/timer/altera_timer.c
+++ b/drivers/timer/altera_timer.c
@@ -71,7 +71,7 @@ static int altera_timer_ofdata_to_platdata(struct udevice *dev)
{
struct altera_timer_platdata *plat = dev_get_platdata(dev);
- plat->regs = map_physmem(dev_get_addr(dev),
+ plat->regs = map_physmem(devfdt_get_addr(dev),
sizeof(struct altera_timer_regs),
MAP_NOCACHE);
diff --git a/drivers/timer/arc_timer.c b/drivers/timer/arc_timer.c
index e94e4a4bca..a5f6b345c8 100644
--- a/drivers/timer/arc_timer.c
+++ b/drivers/timer/arc_timer.c
@@ -51,7 +51,7 @@ static int arc_timer_probe(struct udevice *dev)
struct arc_timer_priv *priv = dev_get_priv(dev);
/* Get registers offset and size */
- id = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+ id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
if (id < 0)
return -EINVAL;
diff --git a/drivers/timer/ast_timer.c b/drivers/timer/ast_timer.c
index d7c5460cd3..e194c50f4a 100644
--- a/drivers/timer/ast_timer.c
+++ b/drivers/timer/ast_timer.c
@@ -66,7 +66,7 @@ static int ast_timer_ofdata_to_platdata(struct udevice *dev)
{
struct ast_timer_priv *priv = dev_get_priv(dev);
- priv->regs = dev_get_addr_ptr(dev);
+ priv->regs = devfdt_get_addr_ptr(dev);
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
diff --git a/drivers/timer/omap-timer.c b/drivers/timer/omap-timer.c
index 7422e0a653..4cc6105505 100644
--- a/drivers/timer/omap-timer.c
+++ b/drivers/timer/omap-timer.c
@@ -79,7 +79,7 @@ static int omap_timer_ofdata_to_platdata(struct udevice *dev)
{
struct omap_timer_priv *priv = dev_get_priv(dev);
- priv->regs = map_physmem(dev_get_addr(dev),
+ priv->regs = map_physmem(devfdt_get_addr(dev),
sizeof(struct omap_gptimer_regs), MAP_NOCACHE);
return 0;
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index 1caf3cd288..ec10b28288 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -103,7 +103,8 @@ int notrace dm_timer_init(void)
* relocation, bind it anyway.
*/
if (node > 0 &&
- !lists_bind_fdt(gd->dm_root, blob, node, &dev)) {
+ !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
+ &dev)) {
ret = device_probe(dev);
if (ret)
return ret;
diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c
index d2b3783673..c00a2d030b 100644
--- a/drivers/tpm/tpm_tis_lpc.c
+++ b/drivers/tpm/tpm_tis_lpc.c
@@ -165,7 +165,7 @@ static int tpm_tis_lpc_probe(struct udevice *dev)
u32 didvid;
ulong chip_type = dev_get_driver_data(dev);
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->regs = map_sysmem(addr, 0);
diff --git a/drivers/usb/common/fsl-errata.c b/drivers/usb/common/fsl-errata.c
index 338ac08d8a..4e642ae435 100644
--- a/drivers/usb/common/fsl-errata.c
+++ b/drivers/usb/common/fsl-errata.c
@@ -9,6 +9,10 @@
#include <common.h>
#include <fsl_errata.h>
#include<fsl_usb.h>
+#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
+ defined(CONFIG_ARM)
+#include <asm/arch/clock.h>
+#endif
/* USB Erratum Checking code */
#if defined(CONFIG_PPC) || defined(CONFIG_ARM)
diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c
index 9abb323745..73fa82b8e6 100644
--- a/drivers/usb/emul/sandbox_flash.c
+++ b/drivers/usb/emul/sandbox_flash.c
@@ -371,10 +371,8 @@ err:
static int sandbox_flash_ofdata_to_platdata(struct udevice *dev)
{
struct sandbox_flash_plat *plat = dev_get_platdata(dev);
- const void *blob = gd->fdt_blob;
- plat->pathname = fdt_getprop(blob, dev_of_offset(dev),
- "sandbox,filepath", NULL);
+ plat->pathname = dev_read_string(dev, "sandbox,filepath");
return 0;
}
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
index f0939b19f4..9ffda9cc74 100644
--- a/drivers/usb/emul/sandbox_hub.c
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -277,8 +277,7 @@ static int sandbox_child_post_bind(struct udevice *dev)
{
struct sandbox_hub_platdata *plat = dev_get_parent_platdata(dev);
- plat->port = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg",
- -1);
+ plat->port = dev_read_u32_default(dev, "reg", -1);
return 0;
}
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 0fbbb7c82c..5e316a7cff 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -41,7 +41,6 @@ ifdef CONFIG_USB_DEVICE
obj-y += core.o
obj-y += ep0.o
obj-$(CONFIG_DW_UDC) += designware_udc.o
-obj-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o
obj-$(CONFIG_CPU_PXA27X) += pxa27x_udc.o
endif
endif
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index f5bc277fa6..01a59078b8 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1386,11 +1386,6 @@ static void at91rm9200_udc_pullup(struct at91_udc *udc, int is_on)
gpio_set_value(udc->board.pullup_pin, !active);
}
-static const struct at91_udc_caps at91rm9200_udc_caps = {
- .init = at91rm9200_udc_init,
- .pullup = at91rm9200_udc_pullup,
-};
-
static int at91sam9260_udc_init(struct at91_udc *udc)
{
struct at91_ep *ep;
@@ -1503,11 +1498,6 @@ static int at91sam9263_udc_init(struct at91_udc *udc)
return 0;
}
-static const struct at91_udc_caps at91sam9263_udc_caps = {
- .init = at91sam9263_udc_init,
- .pullup = at91sam9260_udc_pullup,
-};
-
int usb_gadget_handle_interrupts(int index)
{
struct at91_udc *udc = controller;
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 973cd971ad..f320708431 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -91,12 +91,6 @@
#define gadget_is_atmel_usba(g) 0
#endif
-#ifdef CONFIG_USB_GADGET_S3C2410
-#define gadget_is_s3c2410(g) (!strcmp("s3c2410_udc", (g)->name))
-#else
-#define gadget_is_s3c2410(g) 0
-#endif
-
#ifdef CONFIG_USB_GADGET_AT91
#define gadget_is_at91(g) (!strcmp("at91_udc", (g)->name))
#else
@@ -131,13 +125,6 @@
#define gadget_is_musbhdrc(g) 0
#endif
-/* from Montavista kernel (?) */
-#ifdef CONFIG_USB_GADGET_MPC8272
-#define gadget_is_mpc8272(g) (!strcmp("mpc8272_udc", (g)->name))
-#else
-#define gadget_is_mpc8272(g) 0
-#endif
-
#ifdef CONFIG_USB_GADGET_M66592
#define gadget_is_m66592(g) (!strcmp("m66592_udc", (g)->name))
#else
@@ -207,8 +194,6 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x09;
else if (gadget_is_pxa27x(gadget))
return 0x10;
- else if (gadget_is_s3c2410(gadget))
- return 0x11;
else if (gadget_is_at91(gadget))
return 0x12;
else if (gadget_is_imx(gadget))
@@ -217,8 +202,6 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x14;
else if (gadget_is_musbhdrc(gadget))
return 0x15;
- else if (gadget_is_mpc8272(gadget))
- return 0x16;
else if (gadget_is_atmel_usba(gadget))
return 0x17;
else if (gadget_is_fsl_usb2(gadget))
diff --git a/drivers/usb/gadget/mpc8xx_udc.c b/drivers/usb/gadget/mpc8xx_udc.c
deleted file mode 100644
index ad5ea7a6b8..0000000000
--- a/drivers/usb/gadget/mpc8xx_udc.c
+++ /dev/null
@@ -1,1386 +0,0 @@
-/*
- * Copyright (C) 2006 by Bryan O'Donoghue, CodeHermit
- * bodonoghue@CodeHermit.ie
- *
- * References
- * DasUBoot/drivers/usb/gadget/omap1510_udc.c, for design and implementation
- * ideas.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*
- * Notes :
- * 1. #define __SIMULATE_ERROR__ to inject a CRC error into every 2nd TX
- * packet to force the USB re-transmit protocol.
- *
- * 2. #define __DEBUG_UDC__ to switch on debug tracing to serial console
- * be careful that tracing doesn't create Hiesen-bugs with respect to
- * response timeouts to control requests.
- *
- * 3. This driver should be able to support any higher level driver that
- * that wants to do either of the two standard UDC implementations
- * Control-Bulk-Interrupt or Bulk-IN/Bulk-Out standards. Hence
- * gserial and cdc_acm should work with this code.
- *
- * 4. NAK events never actually get raised at all, the documentation
- * is just wrong !
- *
- * 5. For some reason, cbd_datlen is *always* +2 the value it should be.
- * this means that having an RX cbd of 16 bytes is not possible, since
- * the same size is reported for 14 bytes received as 16 bytes received
- * until we can find out why this happens, RX cbds must be limited to 8
- * bytes. TODO: check errata for this behaviour.
- *
- * 6. Right now this code doesn't support properly powering up with the USB
- * cable attached to the USB host my development board the Adder87x doesn't
- * have a pull-up fitted to allow this, so it is necessary to power the
- * board and *then* attached the USB cable to the host. However somebody
- * with a different design in their board may be able to keep the cable
- * constantly connected and simply enable/disable a pull-up re
- * figure 31.1 in MPC885RM.pdf instead of having to power up the board and
- * then attach the cable !
- *
- */
-#include <common.h>
-#include <config.h>
-#include <commproc.h>
-#include <usbdevice.h>
-#include <usb/mpc8xx_udc.h>
-#include <usb/udc.h>
-
-#include "ep0.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#define ERR(fmt, args...)\
- serial_printf("ERROR : [%s] %s:%d: "fmt,\
- __FILE__,__FUNCTION__,__LINE__, ##args)
-#ifdef __DEBUG_UDC__
-#define DBG(fmt,args...)\
- serial_printf("[%s] %s:%d: "fmt,\
- __FILE__,__FUNCTION__,__LINE__, ##args)
-#else
-#define DBG(fmt,args...)
-#endif
-
-/* Static Data */
-#ifdef __SIMULATE_ERROR__
-static char err_poison_test = 0;
-#endif
-static struct mpc8xx_ep ep_ref[MAX_ENDPOINTS];
-static u32 address_base = STATE_NOT_READY;
-static mpc8xx_udc_state_t udc_state = 0;
-static struct usb_device_instance *udc_device = 0;
-static volatile usb_epb_t *endpoints[MAX_ENDPOINTS];
-static volatile cbd_t *tx_cbd[TX_RING_SIZE];
-static volatile cbd_t *rx_cbd[RX_RING_SIZE];
-static volatile immap_t *immr = 0;
-static volatile cpm8xx_t *cp = 0;
-static volatile usb_pram_t *usb_paramp = 0;
-static volatile usb_t *usbp = 0;
-static int rx_ct = 0;
-static int tx_ct = 0;
-
-/* Static Function Declarations */
-static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
- usb_device_state_t final);
-static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
- usb_device_state_t final);
-static void mpc8xx_udc_stall (unsigned int ep);
-static void mpc8xx_udc_flush_tx_fifo (int epid);
-static void mpc8xx_udc_flush_rx_fifo (void);
-static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
- struct urb *tx_urb);
-static void mpc8xx_udc_dump_request (struct usb_device_request *request);
-static void mpc8xx_udc_clock_init (volatile immap_t * immr,
- volatile cpm8xx_t * cp);
-static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi);
-static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_cbd_init (void);
-static void mpc8xx_udc_endpoint_init (void);
-static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size);
-static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment);
-static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp);
-static void mpc8xx_udc_set_nak (unsigned int ep);
-static short mpc8xx_udc_handle_txerr (void);
-static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid);
-
-/******************************************************************************
- Global Linkage
- *****************************************************************************/
-
-/* udc_init
- *
- * Do initial bus gluing
- */
-int udc_init (void)
-{
- /* Init various pointers */
- immr = (immap_t *) CONFIG_SYS_IMMR;
- cp = (cpm8xx_t *) & (immr->im_cpm);
- usb_paramp = (usb_pram_t *) & (cp->cp_dparam[PROFF_USB]);
- usbp = (usb_t *) & (cp->cp_scc[0]);
-
- memset (ep_ref, 0x00, (sizeof (struct mpc8xx_ep) * MAX_ENDPOINTS));
-
- udc_device = 0;
- udc_state = STATE_NOT_READY;
-
- usbp->usmod = 0x00;
- usbp->uscom = 0;
-
- /* Set USB Frame #0, Respond at Address & Get a clock source */
- usbp->usaddr = 0x00;
- mpc8xx_udc_clock_init (immr, cp);
-
- /* PA15, PA14 as perhiperal USBRXD and USBOE */
- immr->im_ioport.iop_padir &= ~0x0003;
- immr->im_ioport.iop_papar |= 0x0003;
-
- /* PC11/PC10 as peripheral USBRXP USBRXN */
- immr->im_ioport.iop_pcso |= 0x0030;
-
- /* PC7/PC6 as perhiperal USBTXP and USBTXN */
- immr->im_ioport.iop_pcdir |= 0x0300;
- immr->im_ioport.iop_pcpar |= 0x0300;
-
- /* Set the base address */
- address_base = (u32) (cp->cp_dpmem + CPM_USB_BASE);
-
- /* Initialise endpoints and circular buffers */
- mpc8xx_udc_endpoint_init ();
- mpc8xx_udc_cbd_init ();
-
- /* Assign allocated Dual Port Endpoint descriptors */
- usb_paramp->ep0ptr = (u32) endpoints[0];
- usb_paramp->ep1ptr = (u32) endpoints[1];
- usb_paramp->ep2ptr = (u32) endpoints[2];
- usb_paramp->ep3ptr = (u32) endpoints[3];
- usb_paramp->frame_n = 0;
-
- DBG ("ep0ptr=0x%08x ep1ptr=0x%08x ep2ptr=0x%08x ep3ptr=0x%08x\n",
- usb_paramp->ep0ptr, usb_paramp->ep1ptr, usb_paramp->ep2ptr,
- usb_paramp->ep3ptr);
-
- return 0;
-}
-
-/* udc_irq
- *
- * Poll for whatever events may have occurred
- */
-void udc_irq (void)
-{
- int epid = 0;
- volatile cbd_t *rx_cbdp = 0;
- volatile cbd_t *rx_cbdp_base = 0;
-
- if (udc_state != STATE_READY) {
- return;
- }
-
- if (usbp->usber & USB_E_BSY) {
- /* This shouldn't happen. If it does then it's a bug ! */
- usbp->usber |= USB_E_BSY;
- mpc8xx_udc_flush_rx_fifo ();
- }
-
- /* Scan all RX/Bidirectional Endpoints for RX data. */
- for (epid = 0; epid < MAX_ENDPOINTS; epid++) {
- if (!ep_ref[epid].prx) {
- continue;
- }
- rx_cbdp = rx_cbdp_base = ep_ref[epid].prx;
-
- do {
- if (!(rx_cbdp->cbd_sc & RX_BD_E)) {
-
- if (rx_cbdp->cbd_sc & 0x1F) {
- /* Corrupt data discard it.
- * Controller has NAK'd this packet.
- */
- mpc8xx_udc_clear_rxbd (rx_cbdp);
-
- } else {
- if (!epid) {
- mpc8xx_udc_ep0_rx (rx_cbdp);
-
- } else {
- /* Process data */
- mpc8xx_udc_set_nak (epid);
- mpc8xx_udc_epn_rx (epid, rx_cbdp);
- mpc8xx_udc_clear_rxbd (rx_cbdp);
- }
- }
-
- /* Advance RX CBD pointer */
- mpc8xx_udc_advance_rx (&rx_cbdp, epid);
- ep_ref[epid].prx = rx_cbdp;
- } else {
- /* Advance RX CBD pointer */
- mpc8xx_udc_advance_rx (&rx_cbdp, epid);
- }
-
- } while (rx_cbdp != rx_cbdp_base);
- }
-
- /* Handle TX events as appropiate, the correct place to do this is
- * in a tx routine. Perhaps TX on epn was pre-empted by ep0
- */
-
- if (usbp->usber & USB_E_TXB) {
- usbp->usber |= USB_E_TXB;
- }
-
- if (usbp->usber & (USB_TX_ERRMASK)) {
- mpc8xx_udc_handle_txerr ();
- }
-
- /* Switch to the default state, respond at the default address */
- if (usbp->usber & USB_E_RESET) {
- usbp->usber |= USB_E_RESET;
- usbp->usaddr = 0x00;
- udc_device->device_state = STATE_DEFAULT;
- }
-
- /* if(usbp->usber&USB_E_IDLE){
- We could suspend here !
- usbp->usber|=USB_E_IDLE;
- DBG("idle state change\n");
- }
- if(usbp->usbs){
- We could resume here when IDLE is deasserted !
- Not worth doing, so long as we are self powered though.
- }
- */
-
- return;
-}
-
-/* udc_endpoint_write
- *
- * Write some data to an endpoint
- */
-int udc_endpoint_write (struct usb_endpoint_instance *epi)
-{
- int ep = 0;
- short epid = 1, unnak = 0, ret = 0;
-
- if (udc_state != STATE_READY) {
- ERR ("invalid udc_state != STATE_READY!\n");
- return -1;
- }
-
- if (!udc_device || !epi) {
- return -1;
- }
-
- if (udc_device->device_state != STATE_CONFIGURED) {
- return -1;
- }
-
- ep = epi->endpoint_address & 0x03;
- if (ep >= MAX_ENDPOINTS) {
- return -1;
- }
-
- /* Set NAK for all RX endpoints during TX */
- for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
-
- /* Don't set NAK on DATA IN/CONTROL endpoints */
- if (ep_ref[epid].sc & USB_DIR_IN) {
- continue;
- }
-
- if (!(usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK))) {
- unnak |= 1 << epid;
- }
-
- mpc8xx_udc_set_nak (epid);
- }
-
- mpc8xx_udc_init_tx (&udc_device->bus->endpoint_array[ep],
- epi->tx_urb);
- ret = mpc8xx_udc_ep_tx (&udc_device->bus->endpoint_array[ep]);
-
- /* Remove temporary NAK */
- for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
- if (unnak & (1 << epid)) {
- udc_unset_nak (epid);
- }
- }
-
- return ret;
-}
-
-/* mpc8xx_udc_assign_urb
- *
- * Associate a given urb to an endpoint TX or RX transmit/receive buffers
- */
-static int mpc8xx_udc_assign_urb (int ep, char direction)
-{
- struct usb_endpoint_instance *epi = 0;
-
- if (ep >= MAX_ENDPOINTS) {
- goto err;
- }
- epi = &udc_device->bus->endpoint_array[ep];
- if (!epi) {
- goto err;
- }
-
- if (!ep_ref[ep].urb) {
- ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array);
- if (!ep_ref[ep].urb) {
- goto err;
- }
- } else {
- ep_ref[ep].urb->actual_length = 0;
- }
-
- switch (direction) {
- case USB_DIR_IN:
- epi->tx_urb = ep_ref[ep].urb;
- break;
- case USB_DIR_OUT:
- epi->rcv_urb = ep_ref[ep].urb;
- break;
- default:
- goto err;
- }
- return 0;
-
- err:
- udc_state = STATE_ERROR;
- return -1;
-}
-
-/* udc_setup_ep
- *
- * Associate U-Boot software endpoints to mpc8xx endpoint parameter ram
- * Isochronous endpoints aren't yet supported!
- */
-void udc_setup_ep (struct usb_device_instance *device, unsigned int ep,
- struct usb_endpoint_instance *epi)
-{
- uchar direction = 0;
- int ep_attrib = 0;
-
- if (epi && (ep < MAX_ENDPOINTS)) {
-
- if (ep == 0) {
- if (epi->rcv_attributes != USB_ENDPOINT_XFER_CONTROL
- || epi->tx_attributes !=
- USB_ENDPOINT_XFER_CONTROL) {
-
- /* ep0 must be a control endpoint */
- udc_state = STATE_ERROR;
- return;
-
- }
- if (!(ep_ref[ep].sc & EP_ATTACHED)) {
- mpc8xx_udc_cbd_attach (ep, epi->tx_packetSize,
- epi->rcv_packetSize);
- }
- usbp->usep[ep] = 0x0000;
- return;
- }
-
- if ((epi->endpoint_address & USB_ENDPOINT_DIR_MASK)
- == USB_DIR_IN) {
-
- direction = 1;
- ep_attrib = epi->tx_attributes;
- epi->rcv_packetSize = 0;
- ep_ref[ep].sc |= USB_DIR_IN;
- } else {
-
- direction = 0;
- ep_attrib = epi->rcv_attributes;
- epi->tx_packetSize = 0;
- ep_ref[ep].sc &= ~USB_DIR_IN;
- }
-
- if (mpc8xx_udc_assign_urb (ep, epi->endpoint_address
- & USB_ENDPOINT_DIR_MASK)) {
- return;
- }
-
- switch (ep_attrib) {
- case USB_ENDPOINT_XFER_CONTROL:
- if (!(ep_ref[ep].sc & EP_ATTACHED)) {
- mpc8xx_udc_cbd_attach (ep,
- epi->tx_packetSize,
- epi->rcv_packetSize);
- }
- usbp->usep[ep] = ep << 12;
- epi->rcv_urb = epi->tx_urb = ep_ref[ep].urb;
-
- break;
- case USB_ENDPOINT_XFER_BULK:
- case USB_ENDPOINT_XFER_INT:
- if (!(ep_ref[ep].sc & EP_ATTACHED)) {
- if (direction) {
- mpc8xx_udc_cbd_attach (ep,
- epi->tx_packetSize,
- 0);
- } else {
- mpc8xx_udc_cbd_attach (ep,
- 0,
- epi->rcv_packetSize);
- }
- }
- usbp->usep[ep] = (ep << 12) | ((ep_attrib) << 8);
-
- break;
- case USB_ENDPOINT_XFER_ISOC:
- default:
- serial_printf ("Error endpoint attrib %d>3\n", ep_attrib);
- udc_state = STATE_ERROR;
- break;
- }
- }
-
-}
-
-/* udc_connect
- *
- * Move state, switch on the USB
- */
-void udc_connect (void)
-{
- /* Enable pull-up resistor on D+
- * TODO: fit a pull-up resistor to drive SE0 for > 2.5us
- */
-
- if (udc_state != STATE_ERROR) {
- udc_state = STATE_READY;
- usbp->usmod |= USMOD_EN;
- }
-}
-
-/* udc_disconnect
- *
- * Disconnect is not used but, is included for completeness
- */
-void udc_disconnect (void)
-{
- /* Disable pull-up resistor on D-
- * TODO: fix a pullup resistor to control this
- */
-
- if (udc_state != STATE_ERROR) {
- udc_state = STATE_NOT_READY;
- }
- usbp->usmod &= ~USMOD_EN;
-}
-
-/* udc_enable
- *
- * Grab an EP0 URB, register interest in a subset of USB events
- */
-void udc_enable (struct usb_device_instance *device)
-{
- if (udc_state == STATE_ERROR) {
- return;
- }
-
- udc_device = device;
-
- if (!ep_ref[0].urb) {
- ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array);
- }
-
- /* Register interest in all events except SOF, enable transceiver */
- usbp->usber = 0x03FF;
- usbp->usbmr = 0x02F7;
-
- return;
-}
-
-/* udc_disable
- *
- * disable the currently hooked device
- */
-void udc_disable (void)
-{
- int i = 0;
-
- if (udc_state == STATE_ERROR) {
- DBG ("Won't disable UDC. udc_state==STATE_ERROR !\n");
- return;
- }
-
- udc_device = 0;
-
- for (; i < MAX_ENDPOINTS; i++) {
- if (ep_ref[i].urb) {
- usbd_dealloc_urb (ep_ref[i].urb);
- ep_ref[i].urb = 0;
- }
- }
-
- usbp->usbmr = 0x00;
- usbp->usmod = ~USMOD_EN;
- udc_state = STATE_NOT_READY;
-}
-
-/* udc_startup_events
- *
- * Enable the specified device
- */
-void udc_startup_events (struct usb_device_instance *device)
-{
- udc_enable (device);
- if (udc_state == STATE_READY) {
- usbd_device_event_irq (device, DEVICE_CREATE, 0);
- }
-}
-
-/* udc_set_nak
- *
- * Allow upper layers to signal lower layers should not accept more RX data
- *
- */
-void udc_set_nak (int epid)
-{
- if (epid) {
- mpc8xx_udc_set_nak (epid);
- }
-}
-
-/* udc_unset_nak
- *
- * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
- * Switch off NAKing on this endpoint to accept more data output from host.
- *
- */
-void udc_unset_nak (int epid)
-{
- if (epid > MAX_ENDPOINTS) {
- return;
- }
-
- if (usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK)) {
- usbp->usep[epid] &= ~(USEP_THS_NAK | USEP_RHS_NAK);
- __asm__ ("eieio");
- }
-}
-
-/******************************************************************************
- Static Linkage
-******************************************************************************/
-
-/* udc_state_transition_up
- * udc_state_transition_down
- *
- * Helper functions to implement device state changes. The device states and
- * the events that transition between them are:
- *
- * STATE_ATTACHED
- * || /\
- * \/ ||
- * DEVICE_HUB_CONFIGURED DEVICE_HUB_RESET
- * || /\
- * \/ ||
- * STATE_POWERED
- * || /\
- * \/ ||
- * DEVICE_RESET DEVICE_POWER_INTERRUPTION
- * || /\
- * \/ ||
- * STATE_DEFAULT
- * || /\
- * \/ ||
- * DEVICE_ADDRESS_ASSIGNED DEVICE_RESET
- * || /\
- * \/ ||
- * STATE_ADDRESSED
- * || /\
- * \/ ||
- * DEVICE_CONFIGURED DEVICE_DE_CONFIGURED
- * || /\
- * \/ ||
- * STATE_CONFIGURED
- *
- * udc_state_transition_up transitions up (in the direction from STATE_ATTACHED
- * to STATE_CONFIGURED) from the specified initial state to the specified final
- * state, passing through each intermediate state on the way. If the initial
- * state is at or above (i.e. nearer to STATE_CONFIGURED) the final state, then
- * no state transitions will take place.
- *
- * udc_state_transition_down transitions down (in the direction from
- * STATE_CONFIGURED to STATE_ATTACHED) from the specified initial state to the
- * specified final state, passing through each intermediate state on the way.
- * If the initial state is at or below (i.e. nearer to STATE_ATTACHED) the final
- * state, then no state transitions will take place.
- *
- */
-
-static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
- usb_device_state_t final)
-{
- if (initial < final) {
- switch (initial) {
- case STATE_ATTACHED:
- usbd_device_event_irq (udc_device,
- DEVICE_HUB_CONFIGURED, 0);
- if (final == STATE_POWERED)
- break;
- case STATE_POWERED:
- usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
- if (final == STATE_DEFAULT)
- break;
- case STATE_DEFAULT:
- usbd_device_event_irq (udc_device,
- DEVICE_ADDRESS_ASSIGNED, 0);
- if (final == STATE_ADDRESSED)
- break;
- case STATE_ADDRESSED:
- usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
- 0);
- case STATE_CONFIGURED:
- break;
- default:
- break;
- }
- }
-}
-
-static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
- usb_device_state_t final)
-{
- if (initial > final) {
- switch (initial) {
- case STATE_CONFIGURED:
- usbd_device_event_irq (udc_device,
- DEVICE_DE_CONFIGURED, 0);
- if (final == STATE_ADDRESSED)
- break;
- case STATE_ADDRESSED:
- usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
- if (final == STATE_DEFAULT)
- break;
- case STATE_DEFAULT:
- usbd_device_event_irq (udc_device,
- DEVICE_POWER_INTERRUPTION, 0);
- if (final == STATE_POWERED)
- break;
- case STATE_POWERED:
- usbd_device_event_irq (udc_device, DEVICE_HUB_RESET,
- 0);
- case STATE_ATTACHED:
- break;
- default:
- break;
- }
- }
-}
-
-/* mpc8xx_udc_stall
- *
- * Force returning of STALL tokens on the given endpoint. Protocol or function
- * STALL conditions are permissable here
- */
-static void mpc8xx_udc_stall (unsigned int ep)
-{
- usbp->usep[ep] |= STALL_BITMASK;
-}
-
-/* mpc8xx_udc_set_nak
- *
- * Force returning of NAK responses for the given endpoint as a kind of very
- * simple flow control
- */
-static void mpc8xx_udc_set_nak (unsigned int ep)
-{
- usbp->usep[ep] |= NAK_BITMASK;
- __asm__ ("eieio");
-}
-
-/* mpc8xx_udc_handle_txerr
- *
- * Handle errors relevant to TX. Return a status code to allow calling
- * indicative of what if anything happened
- */
-static short mpc8xx_udc_handle_txerr ()
-{
- short ep = 0, ret = 0;
-
- for (; ep < TX_RING_SIZE; ep++) {
- if (usbp->usber & (0x10 << ep)) {
-
- /* Timeout or underrun */
- if (tx_cbd[ep]->cbd_sc & 0x06) {
- ret = 1;
- mpc8xx_udc_flush_tx_fifo (ep);
-
- } else {
- if (usbp->usep[ep] & STALL_BITMASK) {
- if (!ep) {
- usbp->usep[ep] &= ~STALL_BITMASK;
- }
- } /* else NAK */
- }
- usbp->usber |= (0x10 << ep);
- }
- }
- return ret;
-}
-
-/* mpc8xx_udc_advance_rx
- *
- * Advance cbd rx
- */
-static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid)
-{
- if ((*rx_cbdp)->cbd_sc & RX_BD_W) {
- *rx_cbdp = (volatile cbd_t *) (endpoints[epid]->rbase + CONFIG_SYS_IMMR);
-
- } else {
- (*rx_cbdp)++;
- }
-}
-
-
-/* mpc8xx_udc_flush_tx_fifo
- *
- * Flush a given TX fifo. Assumes one tx cbd per endpoint
- */
-static void mpc8xx_udc_flush_tx_fifo (int epid)
-{
- volatile cbd_t *tx_cbdp = 0;
-
- if (epid > MAX_ENDPOINTS) {
- return;
- }
-
- /* TX stop */
- immr->im_cpm.cp_cpcr = ((epid << 2) | 0x1D01);
- __asm__ ("eieio");
- while (immr->im_cpm.cp_cpcr & 0x01);
-
- usbp->uscom = 0x40 | 0;
-
- /* reset ring */
- tx_cbdp = (cbd_t *) (endpoints[epid]->tbptr + CONFIG_SYS_IMMR);
- tx_cbdp->cbd_sc = (TX_BD_I | TX_BD_W);
-
-
- endpoints[epid]->tptr = endpoints[epid]->tbase;
- endpoints[epid]->tstate = 0x00;
- endpoints[epid]->tbcnt = 0x00;
-
- /* TX start */
- immr->im_cpm.cp_cpcr = ((epid << 2) | 0x2D01);
- __asm__ ("eieio");
- while (immr->im_cpm.cp_cpcr & 0x01);
-
- return;
-}
-
-/* mpc8xx_udc_flush_rx_fifo
- *
- * For the sake of completeness of the namespace, it seems like
- * a good-design-decision (tm) to include mpc8xx_udc_flush_rx_fifo();
- * If RX_BD_E is true => a driver bug either here or in an upper layer
- * not polling frequently enough. If RX_BD_E is true we have told the host
- * we have accepted data but, the CPM found it had no-where to put that data
- * which needless to say would be a bad thing.
- */
-static void mpc8xx_udc_flush_rx_fifo ()
-{
- int i = 0;
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
- ERR ("buf %p used rx data len = 0x%x sc=0x%x!\n",
- rx_cbd[i], rx_cbd[i]->cbd_datlen,
- rx_cbd[i]->cbd_sc);
-
- }
- }
- ERR ("BUG : Input over-run\n");
-}
-
-/* mpc8xx_udc_clear_rxbd
- *
- * Release control of RX CBD to CP.
- */
-static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp)
-{
- rx_cbdp->cbd_datlen = 0x0000;
- rx_cbdp->cbd_sc = ((rx_cbdp->cbd_sc & RX_BD_W) | (RX_BD_E | RX_BD_I));
- __asm__ ("eieio");
-}
-
-/* mpc8xx_udc_tx_irq
- *
- * Parse for tx timeout, control RX or USB reset/busy conditions
- * Return -1 on timeout, -2 on fatal error, else return zero
- */
-static int mpc8xx_udc_tx_irq (int ep)
-{
- int i = 0;
-
- if (usbp->usber & (USB_TX_ERRMASK)) {
- if (mpc8xx_udc_handle_txerr ()) {
- /* Timeout, controlling function must retry send */
- return -1;
- }
- }
-
- if (usbp->usber & (USB_E_RESET | USB_E_BSY)) {
- /* Fatal, abandon TX transaction */
- return -2;
- }
-
- if (usbp->usber & USB_E_RXB) {
- for (i = 0; i < RX_RING_SIZE; i++) {
- if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
- if ((rx_cbd[i] == ep_ref[0].prx) || ep) {
- return -2;
- }
- }
- }
- }
-
- return 0;
-}
-
-/* mpc8xx_udc_ep_tx
- *
- * Transmit in a re-entrant fashion outbound USB packets.
- * Implement retry/timeout mechanism described in USB specification
- * Toggle DATA0/DATA1 pids as necessary
- * Introduces non-standard tx_retry. The USB standard has no scope for slave
- * devices to give up TX, however tx_retry stops us getting stuck in an endless
- * TX loop.
- */
-static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi)
-{
- struct urb *urb = epi->tx_urb;
- volatile cbd_t *tx_cbdp = 0;
- unsigned int ep = 0, pkt_len = 0, x = 0, tx_retry = 0;
- int ret = 0;
-
- if (!epi || (epi->endpoint_address & 0x03) >= MAX_ENDPOINTS || !urb) {
- return -1;
- }
-
- ep = epi->endpoint_address & 0x03;
- tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CONFIG_SYS_IMMR);
-
- if (tx_cbdp->cbd_sc & TX_BD_R || usbp->usber & USB_E_TXB) {
- mpc8xx_udc_flush_tx_fifo (ep);
- usbp->usber |= USB_E_TXB;
- };
-
- while (tx_retry++ < 100) {
- ret = mpc8xx_udc_tx_irq (ep);
- if (ret == -1) {
- /* ignore timeout here */
- } else if (ret == -2) {
- /* Abandon TX */
- mpc8xx_udc_flush_tx_fifo (ep);
- return -1;
- }
-
- tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CONFIG_SYS_IMMR);
- while (tx_cbdp->cbd_sc & TX_BD_R) {
- };
- tx_cbdp->cbd_sc = (tx_cbdp->cbd_sc & TX_BD_W);
-
- pkt_len = urb->actual_length - epi->sent;
-
- if (pkt_len > epi->tx_packetSize || pkt_len > EP_MAX_PKT) {
- pkt_len = min(epi->tx_packetSize, EP_MAX_PKT);
- }
-
- for (x = 0; x < pkt_len; x++) {
- *((unsigned char *) (tx_cbdp->cbd_bufaddr + x)) =
- urb->buffer[epi->sent + x];
- }
- tx_cbdp->cbd_datlen = pkt_len;
- tx_cbdp->cbd_sc |= (CBD_TX_BITMASK | ep_ref[ep].pid);
- __asm__ ("eieio");
-
-#ifdef __SIMULATE_ERROR__
- if (++err_poison_test == 2) {
- err_poison_test = 0;
- tx_cbdp->cbd_sc &= ~TX_BD_TC;
- }
-#endif
-
- usbp->uscom = (USCOM_STR | ep);
-
- while (!(usbp->usber & USB_E_TXB)) {
- ret = mpc8xx_udc_tx_irq (ep);
- if (ret == -1) {
- /* TX timeout */
- break;
- } else if (ret == -2) {
- if (usbp->usber & USB_E_TXB) {
- usbp->usber |= USB_E_TXB;
- }
- mpc8xx_udc_flush_tx_fifo (ep);
- return -1;
- }
- };
-
- if (usbp->usber & USB_E_TXB) {
- usbp->usber |= USB_E_TXB;
- }
-
- /* ACK must be present <= 18bit times from TX */
- if (ret == -1) {
- continue;
- }
-
- /* TX ACK : USB 2.0 8.7.2, Toggle PID, Advance TX */
- epi->sent += pkt_len;
- epi->last = min(urb->actual_length - epi->sent, epi->tx_packetSize);
- TOGGLE_TX_PID (ep_ref[ep].pid);
-
- if (epi->sent >= epi->tx_urb->actual_length) {
-
- epi->tx_urb->actual_length = 0;
- epi->sent = 0;
-
- if (ep_ref[ep].sc & EP_SEND_ZLP) {
- ep_ref[ep].sc &= ~EP_SEND_ZLP;
- } else {
- return 0;
- }
- }
- }
-
- ERR ("TX fail, endpoint 0x%x tx bytes 0x%x/0x%x\n", ep, epi->sent,
- epi->tx_urb->actual_length);
-
- return -1;
-}
-
-/* mpc8xx_udc_dump_request
- *
- * Dump a control request to console
- */
-static void mpc8xx_udc_dump_request (struct usb_device_request *request)
-{
- DBG ("bmRequestType:%02x bRequest:%02x wValue:%04x "
- "wIndex:%04x wLength:%04x ?\n",
- request->bmRequestType,
- request->bRequest,
- request->wValue, request->wIndex, request->wLength);
-
- return;
-}
-
-/* mpc8xx_udc_ep0_rx_setup
- *
- * Decode received ep0 SETUP packet. return non-zero on error
- */
-static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp)
-{
- unsigned int x = 0;
- struct urb *purb = ep_ref[0].urb;
- struct usb_endpoint_instance *epi =
- &udc_device->bus->endpoint_array[0];
-
- for (; x < rx_cbdp->cbd_datlen; x++) {
- *(((unsigned char *) &ep_ref[0].urb->device_request) + x) =
- *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
- }
-
- mpc8xx_udc_clear_rxbd (rx_cbdp);
-
- if (ep0_recv_setup (purb)) {
- mpc8xx_udc_dump_request (&purb->device_request);
- return -1;
- }
-
- if ((purb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
- == USB_REQ_HOST2DEVICE) {
-
- switch (purb->device_request.bRequest) {
- case USB_REQ_SET_ADDRESS:
- /* Send the Status OUT ZLP */
- ep_ref[0].pid = TX_BD_PID_DATA1;
- purb->actual_length = 0;
- mpc8xx_udc_init_tx (epi, purb);
- mpc8xx_udc_ep_tx (epi);
-
- /* Move to the addressed state */
- usbp->usaddr = udc_device->address;
- mpc8xx_udc_state_transition_up (udc_device->device_state,
- STATE_ADDRESSED);
- return 0;
-
- case USB_REQ_SET_CONFIGURATION:
- if (!purb->device_request.wValue) {
- /* Respond at default address */
- usbp->usaddr = 0x00;
- mpc8xx_udc_state_transition_down (udc_device->device_state,
- STATE_ADDRESSED);
- } else {
- /* TODO: Support multiple configurations */
- mpc8xx_udc_state_transition_up (udc_device->device_state,
- STATE_CONFIGURED);
- for (x = 1; x < MAX_ENDPOINTS; x++) {
- if ((udc_device->bus->endpoint_array[x].endpoint_address & USB_ENDPOINT_DIR_MASK)
- == USB_DIR_IN) {
- ep_ref[x].pid = TX_BD_PID_DATA0;
- } else {
- ep_ref[x].pid = RX_BD_PID_DATA0;
- }
- /* Set configuration must unstall endpoints */
- usbp->usep[x] &= ~STALL_BITMASK;
- }
- }
- break;
- default:
- /* CDC/Vendor specific */
- break;
- }
-
- /* Send ZLP as ACK in Status OUT phase */
- ep_ref[0].pid = TX_BD_PID_DATA1;
- purb->actual_length = 0;
- mpc8xx_udc_init_tx (epi, purb);
- mpc8xx_udc_ep_tx (epi);
-
- } else {
-
- if (purb->actual_length) {
- ep_ref[0].pid = TX_BD_PID_DATA1;
- mpc8xx_udc_init_tx (epi, purb);
-
- if (!(purb->actual_length % EP0_MAX_PACKET_SIZE)) {
- ep_ref[0].sc |= EP_SEND_ZLP;
- }
-
- if (purb->device_request.wValue ==
- USB_DESCRIPTOR_TYPE_DEVICE) {
- if (le16_to_cpu (purb->device_request.wLength)
- > purb->actual_length) {
- /* Send EP0_MAX_PACKET_SIZE bytes
- * unless correct size requested.
- */
- if (purb->actual_length > epi->tx_packetSize) {
- purb->actual_length = epi->tx_packetSize;
- }
- }
- }
- mpc8xx_udc_ep_tx (epi);
-
- } else {
- /* Corrupt SETUP packet? */
- ERR ("Zero length data or SETUP with DATA-IN phase ?\n");
- return 1;
- }
- }
- return 0;
-}
-
-/* mpc8xx_udc_init_tx
- *
- * Setup some basic parameters for a TX transaction
- */
-static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
- struct urb *tx_urb)
-{
- epi->sent = 0;
- epi->last = 0;
- epi->tx_urb = tx_urb;
-}
-
-/* mpc8xx_udc_ep0_rx
- *
- * Receive ep0/control USB data. Parse and possibly send a response.
- */
-static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp)
-{
- if (rx_cbdp->cbd_sc & RX_BD_PID_SETUP) {
-
- /* Unconditionally accept SETUP packets */
- if (mpc8xx_udc_ep0_rx_setup (rx_cbdp)) {
- mpc8xx_udc_stall (0);
- }
-
- } else {
-
- mpc8xx_udc_clear_rxbd (rx_cbdp);
-
- if ((rx_cbdp->cbd_datlen - 2)) {
- /* SETUP with a DATA phase
- * outside of SETUP packet.
- * Reply with STALL.
- */
- mpc8xx_udc_stall (0);
- }
- }
-}
-
-/* mpc8xx_udc_epn_rx
- *
- * Receive some data from cbd into USB system urb data abstraction
- * Upper layers should NAK if there is insufficient RX data space
- */
-static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp)
-{
- struct usb_endpoint_instance *epi = 0;
- struct urb *urb = 0;
- unsigned int x = 0;
-
- if (epid >= MAX_ENDPOINTS || !rx_cbdp->cbd_datlen) {
- return 0;
- }
-
- /* USB 2.0 PDF section 8.6.4
- * Discard data with invalid PID it is a resend.
- */
- if (ep_ref[epid].pid != (rx_cbdp->cbd_sc & 0xC0)) {
- return 1;
- }
- TOGGLE_RX_PID (ep_ref[epid].pid);
-
- epi = &udc_device->bus->endpoint_array[epid];
- urb = epi->rcv_urb;
-
- for (; x < (rx_cbdp->cbd_datlen - 2); x++) {
- *((unsigned char *) (urb->buffer + urb->actual_length + x)) =
- *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
- }
-
- if (x) {
- usbd_rcv_complete (epi, x, 0);
- if (ep_ref[epid].urb->status == RECV_ERROR) {
- DBG ("RX error unset NAK\n");
- udc_unset_nak (epid);
- }
- }
- return x;
-}
-
-/* mpc8xx_udc_clock_init
- *
- * Obtain a clock reference for Full Speed Signaling
- */
-static void mpc8xx_udc_clock_init (volatile immap_t * immr,
- volatile cpm8xx_t * cp)
-{
-
-#if defined(CONFIG_SYS_USB_EXTC_CLK)
-
- /* This has been tested with a 48MHz crystal on CLK6 */
- switch (CONFIG_SYS_USB_EXTC_CLK) {
- case 1:
- immr->im_ioport.iop_papar |= 0x0100;
- immr->im_ioport.iop_padir &= ~0x0100;
- cp->cp_sicr |= 0x24;
- break;
- case 2:
- immr->im_ioport.iop_papar |= 0x0200;
- immr->im_ioport.iop_padir &= ~0x0200;
- cp->cp_sicr |= 0x2D;
- break;
- case 3:
- immr->im_ioport.iop_papar |= 0x0400;
- immr->im_ioport.iop_padir &= ~0x0400;
- cp->cp_sicr |= 0x36;
- break;
- case 4:
- immr->im_ioport.iop_papar |= 0x0800;
- immr->im_ioport.iop_padir &= ~0x0800;
- cp->cp_sicr |= 0x3F;
- break;
- default:
- udc_state = STATE_ERROR;
- break;
- }
-
-#elif defined(CONFIG_SYS_USB_BRGCLK)
-
- /* This has been tested with brgclk == 50MHz */
- int divisor = 0;
-
- if (gd->cpu_clk < 48000000L) {
- ERR ("brgclk is too slow for full-speed USB!\n");
- udc_state = STATE_ERROR;
- return;
- }
-
- /* Assume the brgclk is 'good enough', we want !(gd->cpu_clk%48MHz)
- * but, can /probably/ live with close-ish alternative rates.
- */
- divisor = (gd->cpu_clk / 48000000L) - 1;
- cp->cp_sicr &= ~0x0000003F;
-
- switch (CONFIG_SYS_USB_BRGCLK) {
- case 1:
- cp->cp_brgc1 |= (divisor | CPM_BRG_EN);
- cp->cp_sicr &= ~0x2F;
- break;
- case 2:
- cp->cp_brgc2 |= (divisor | CPM_BRG_EN);
- cp->cp_sicr |= 0x00000009;
- break;
- case 3:
- cp->cp_brgc3 |= (divisor | CPM_BRG_EN);
- cp->cp_sicr |= 0x00000012;
- break;
- case 4:
- cp->cp_brgc4 = (divisor | CPM_BRG_EN);
- cp->cp_sicr |= 0x0000001B;
- break;
- default:
- udc_state = STATE_ERROR;
- break;
- }
-
-#else
-#error "CONFIG_SYS_USB_EXTC_CLK or CONFIG_SYS_USB_BRGCLK must be defined"
-#endif
-
-}
-
-/* mpc8xx_udc_cbd_attach
- *
- * attach a cbd to and endpoint
- */
-static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size)
-{
-
- if (!tx_cbd[ep] || !rx_cbd[ep] || ep >= MAX_ENDPOINTS) {
- udc_state = STATE_ERROR;
- return;
- }
-
- if (tx_size > USB_MAX_PKT || rx_size > USB_MAX_PKT ||
- (!tx_size && !rx_size)) {
- udc_state = STATE_ERROR;
- return;
- }
-
- /* Attach CBD to appropiate Parameter RAM Endpoint data structure */
- if (rx_size) {
- endpoints[ep]->rbase = (u32) rx_cbd[rx_ct];
- endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
- rx_ct++;
-
- if (!ep) {
-
- endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
- rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
- rx_ct++;
-
- } else {
- rx_ct += 2;
- endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
- rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
- rx_ct++;
- }
-
- /* Where we expect to RX data on this endpoint */
- ep_ref[ep].prx = rx_cbd[rx_ct - 1];
- } else {
-
- ep_ref[ep].prx = 0;
- endpoints[ep]->rbase = 0;
- endpoints[ep]->rbptr = 0;
- }
-
- if (tx_size) {
- endpoints[ep]->tbase = (u32) tx_cbd[tx_ct];
- endpoints[ep]->tbptr = (u32) tx_cbd[tx_ct];
- tx_ct++;
- } else {
- endpoints[ep]->tbase = 0;
- endpoints[ep]->tbptr = 0;
- }
-
- endpoints[ep]->tstate = 0;
- endpoints[ep]->tbcnt = 0;
- endpoints[ep]->mrblr = EP_MAX_PKT;
- endpoints[ep]->rfcr = 0x18;
- endpoints[ep]->tfcr = 0x18;
- ep_ref[ep].sc |= EP_ATTACHED;
-
- DBG ("ep %d rbase 0x%08x rbptr 0x%08x tbase 0x%08x tbptr 0x%08x prx = %p\n",
- ep, endpoints[ep]->rbase, endpoints[ep]->rbptr,
- endpoints[ep]->tbase, endpoints[ep]->tbptr,
- ep_ref[ep].prx);
-
- return;
-}
-
-/* mpc8xx_udc_cbd_init
- *
- * Allocate space for a cbd and allocate TX/RX data space
- */
-static void mpc8xx_udc_cbd_init (void)
-{
- int i = 0;
-
- for (; i < TX_RING_SIZE; i++) {
- tx_cbd[i] = (cbd_t *)
- mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
- }
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- rx_cbd[i] = (cbd_t *)
- mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
- }
-
- for (i = 0; i < TX_RING_SIZE; i++) {
- tx_cbd[i]->cbd_bufaddr =
- mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
-
- tx_cbd[i]->cbd_sc = (TX_BD_I | TX_BD_W);
- tx_cbd[i]->cbd_datlen = 0x0000;
- }
-
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- rx_cbd[i]->cbd_bufaddr =
- mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
- rx_cbd[i]->cbd_sc = (RX_BD_I | RX_BD_E);
- rx_cbd[i]->cbd_datlen = 0x0000;
-
- }
-
- return;
-}
-
-/* mpc8xx_udc_endpoint_init
- *
- * Attach an endpoint to some dpram
- */
-static void mpc8xx_udc_endpoint_init (void)
-{
- int i = 0;
-
- for (; i < MAX_ENDPOINTS; i++) {
- endpoints[i] = (usb_epb_t *)
- mpc8xx_udc_alloc (sizeof (usb_epb_t), 32);
- }
-}
-
-/* mpc8xx_udc_alloc
- *
- * Grab the address of some dpram
- */
-static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment)
-{
- u32 retaddr = address_base;
-
- while (retaddr % alignment) {
- retaddr++;
- }
- address_base += data_size;
-
- return retaddr;
-}
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 4ece0a2e4b..ab5a99faa8 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -17,7 +17,6 @@ obj-$(CONFIG_USB_OHCI_DA8XX) += ohci-da8xx.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
obj-$(CONFIG_USB_SL811HS) += sl811-hcd.o
-obj-$(CONFIG_USB_OHCI_S3C24XX) += ohci-s3c24xx.o
obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o
obj-$(CONFIG_USB_OHCI_SUNXI) += ohci-sunxi.o
obj-$(CONFIG_USB_OHCI_LPC32XX) += ohci-lpc32xx.o
@@ -27,11 +26,7 @@ obj-$(CONFIG_USB_OHCI_GENERIC) += ohci-generic.o
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_EHCI_ARMADA100) += ehci-armada100.o utmi-armada100.o
obj-$(CONFIG_USB_EHCI_ATMEL) += ehci-atmel.o
-ifdef CONFIG_MPC512X
-obj-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
-else
obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
-endif
obj-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o
obj-$(CONFIG_USB_EHCI_GENERIC) += ehci-generic.o
obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index 0e5df15a0d..841e596700 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -43,6 +43,7 @@ struct dwc2_priv {
struct dwc2_core_regs *regs;
int root_hub_devnum;
bool ext_vbus;
+ bool hnp_srp_disable;
bool oc_disable;
};
@@ -394,6 +395,9 @@ static void dwc_otg_core_init(struct dwc2_priv *priv)
usbcfg |= DWC2_GUSBCFG_ULPI_CLK_SUS_M;
}
#endif
+ if (priv->hnp_srp_disable)
+ usbcfg |= DWC2_GUSBCFG_FORCEHOSTMODE;
+
writel(usbcfg, &regs->gusbcfg);
/* Program the GAHBCFG Register. */
@@ -422,12 +426,16 @@ static void dwc_otg_core_init(struct dwc2_priv *priv)
writel(ahbcfg, &regs->gahbcfg);
- /* Program the GUSBCFG register for HNP/SRP. */
- setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_HNPCAP | DWC2_GUSBCFG_SRPCAP);
+ /* Program the capabilities in GUSBCFG Register */
+ usbcfg = 0;
+ if (!priv->hnp_srp_disable)
+ usbcfg |= DWC2_GUSBCFG_HNPCAP | DWC2_GUSBCFG_SRPCAP;
#ifdef CONFIG_DWC2_IC_USB_CAP
- setbits_le32(&regs->gusbcfg, DWC2_GUSBCFG_IC_USB_CAP);
+ usbcfg |= DWC2_GUSBCFG_IC_USB_CAP;
#endif
+
+ setbits_le32(&regs->gusbcfg, usbcfg);
}
/*
@@ -1234,7 +1242,7 @@ static int dwc2_usb_ofdata_to_platdata(struct udevice *dev)
const void *prop;
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->regs = (struct dwc2_core_regs *)addr;
@@ -1244,6 +1252,11 @@ static int dwc2_usb_ofdata_to_platdata(struct udevice *dev)
if (prop)
priv->oc_disable = true;
+ prop = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
+ "hnp-srp-disable", NULL);
+ if (prop)
+ priv->hnp_srp_disable = true;
+
return 0;
}
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index a5c6d34974..f6c6b019ca 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -96,7 +96,7 @@ static int ehci_atmel_probe(struct udevice *dev)
/*
* Get the base address for EHCI controller from the device node
*/
- hcd_base = dev_get_addr(dev);
+ hcd_base = devfdt_get_addr(dev);
if (hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the EHCI register base address\n");
return -ENXIO;
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 981543e315..30297b02d3 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -52,7 +52,7 @@ static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
/*
* Get the base address for XHCI controller from the device node
*/
- plat->hcd_base = dev_get_addr(dev);
+ plat->hcd_base = devfdt_get_addr(dev);
if (plat->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the XHCI register base address\n");
return -ENXIO;
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 7ad50fccee..b57c6cd35a 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -98,7 +98,7 @@ static int ehci_fsl_probe(struct udevice *dev)
/*
* Get the base address for EHCI controller from the device node
*/
- priv->hcd_base = dev_get_addr(dev);
+ priv->hcd_base = devfdt_get_addr(dev);
if (priv->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the EHCI register base address\n");
return -ENXIO;
diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 2190adba67..fb78462893 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -50,7 +50,7 @@ static int ehci_usb_probe(struct udevice *dev)
reset_free(&reset);
}
- hccr = map_physmem(dev_get_addr(dev), 0x100, MAP_NOCACHE);
+ hccr = map_physmem(devfdt_get_addr(dev), 0x100, MAP_NOCACHE);
hcor = (struct ehci_hcor *)((uintptr_t)hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
index 464247035e..7a0f2083ad 100644
--- a/drivers/usb/host/ehci-marvell.c
+++ b/drivers/usb/host/ehci-marvell.c
@@ -108,7 +108,7 @@ static int ehci_mvebu_probe(struct udevice *dev)
/*
* Get the base address for EHCI controller from the device node
*/
- priv->hcd_base = dev_get_addr(dev);
+ priv->hcd_base = devfdt_get_addr(dev);
if (priv->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the EHCI register base address\n");
return -ENXIO;
@@ -121,7 +121,7 @@ static int ehci_mvebu_probe(struct udevice *dev)
* Also, the address decoder doesn't need to get setup with this
* SoC, so don't call usb_brg_adrdec_setup().
*/
- if (of_device_is_compatible(dev, "marvell,armada3700-ehci"))
+ if (device_is_compatible(dev, "marvell,armada3700-ehci"))
marvell_ehci_ops.powerup_fixup = marvell_ehci_powerup_fixup;
else
usb_brg_adrdec_setup((void *)priv->hcd_base);
diff --git a/drivers/usb/host/ehci-mpc512x.c b/drivers/usb/host/ehci-mpc512x.c
deleted file mode 100644
index bb4f461613..0000000000
--- a/drivers/usb/host/ehci-mpc512x.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * (C) Copyright 2010, Damien Dusha, <d.dusha@gmail.com>
- *
- * (C) Copyright 2009, Value Team S.p.A.
- * Francesco Rendine, <francesco.rendine@valueteam.com>
- *
- * (C) Copyright 2009 Freescale Semiconductor, Inc.
- *
- * (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB
- *
- * Author: Tor Krill tor@excito.com
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <pci.h>
-#include <usb.h>
-#include <asm/io.h>
-#include <usb/ehci-ci.h>
-
-#include "ehci.h"
-
-static void fsl_setup_phy(volatile struct ehci_hcor *);
-static void fsl_platform_set_host_mode(volatile struct usb_ehci *ehci);
-static int reset_usb_controller(volatile struct usb_ehci *ehci);
-static void usb_platform_dr_init(volatile struct usb_ehci *ehci);
-
-/*
- * Initialize SOC FSL EHCI Controller
- *
- * This code is derived from EHCI FSL USB Linux driver for MPC5121
- *
- */
-int ehci_hcd_init(int index, enum usb_init_type init,
- struct ehci_hccr **hccr, struct ehci_hcor **hcor)
-{
- volatile struct usb_ehci *ehci;
-
- /* Hook the memory mapped registers for EHCI-Controller */
- ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB1_ADDR;
- *hccr = (struct ehci_hccr *)((uint32_t)&(ehci->caplength));
- *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
- HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
-
- /* configure interface for UTMI_WIDE */
- usb_platform_dr_init(ehci);
-
- /* Init Phy USB0 to UTMI+ */
- fsl_setup_phy(*hcor);
-
- /* Set to host mode */
- fsl_platform_set_host_mode(ehci);
-
- /*
- * Setting the burst size seems to be required to prevent the
- * USB from hanging when communicating with certain USB Mass
- * storage devices. This was determined by analysing the
- * EHCI registers under Linux vs U-Boot and burstsize was the
- * major non-interrupt related difference between the two
- * implementations.
- *
- * Some USB sticks behave better than others. In particular,
- * the following USB stick is especially problematic:
- * 0930:6545 Toshiba Corp
- *
- * The burstsize is set here to match the Linux implementation.
- */
- out_be32(&ehci->burstsize, FSL_EHCI_TXPBURST(8) |
- FSL_EHCI_RXPBURST(8));
-
- return 0;
-}
-
-/*
- * Destroy the appropriate control structures corresponding
- * the the EHCI host controller.
- */
-int ehci_hcd_stop(int index)
-{
- volatile struct usb_ehci *ehci;
- int exit_status = 0;
-
- /* Reset the USB controller */
- ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB1_ADDR;
- exit_status = reset_usb_controller(ehci);
-
- return exit_status;
-}
-
-static int reset_usb_controller(volatile struct usb_ehci *ehci)
-{
- unsigned int i;
-
- /* Command a reset of the USB Controller */
- out_be32(&(ehci->usbcmd), CMD_RESET);
-
- /* Wait for the reset process to finish */
- for (i = 65535 ; i > 0 ; i--) {
- /*
- * The host will set this bit to zero once the
- * reset process is complete
- */
- if ((in_be32(&(ehci->usbcmd)) & CMD_RESET) == 0)
- return 0;
- }
-
- /* Hub did not reset in time */
- return -1;
-}
-
-static void fsl_setup_phy(volatile struct ehci_hcor *hcor)
-{
- uint32_t portsc;
-
- portsc = ehci_readl(&hcor->or_portsc[0]);
- portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
-
- /* Enable the phy mode to UTMI Wide */
- portsc |= PORT_PTS_PTW;
- portsc |= PORT_PTS_UTMI;
-
- ehci_writel(&hcor->or_portsc[0], portsc);
-}
-
-static void fsl_platform_set_host_mode(volatile struct usb_ehci *ehci)
-{
- uint32_t temp;
-
- temp = in_le32(&ehci->usbmode);
- temp |= CM_HOST | ES_BE;
- out_le32(&ehci->usbmode, temp);
-}
-
-static void usb_platform_dr_init(volatile struct usb_ehci *ehci)
-{
- /* Configure interface for UTMI_WIDE */
- out_be32(&ehci->isiphyctrl, PHYCTRL_PHYE | PHYCTRL_PXE);
- out_be32(&ehci->usbgenctrl, GC_PPP | GC_PFP );
-}
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 6484c1c334..2c0c63322c 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -147,7 +147,7 @@ static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
struct msm_ehci_priv *priv = dev_get_priv(dev);
priv->ulpi_vp.port_num = 0;
- priv->ehci = (void *)dev_get_addr(dev);
+ priv->ehci = (void *)devfdt_get_addr(dev);
if (priv->ehci == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 55ac162a3c..f348ec9bca 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -17,6 +17,7 @@
#include <asm/imx-common/iomux-v3.h>
#include <asm/imx-common/sys_proto.h>
#include <dm.h>
+#include <asm/mach-types.h>
#include <power/regulator.h>
#include "ehci.h"
@@ -434,7 +435,7 @@ static const struct ehci_ops mx6_ehci_ops = {
static int ehci_usb_phy_mode(struct udevice *dev)
{
struct usb_platdata *plat = dev_get_platdata(dev);
- void *__iomem addr = (void *__iomem)dev_get_addr(dev);
+ void *__iomem addr = (void *__iomem)devfdt_get_addr(dev);
void *__iomem phy_ctrl, *__iomem phy_status;
const void *blob = gd->fdt_blob;
int offset = dev_of_offset(dev), phy_off;
@@ -504,7 +505,7 @@ static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
static int ehci_usb_probe(struct udevice *dev)
{
struct usb_platdata *plat = dev_get_platdata(dev);
- struct usb_ehci *ehci = (struct usb_ehci *)dev_get_addr(dev);
+ struct usb_ehci *ehci = (struct usb_ehci *)devfdt_get_addr(dev);
struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
enum usb_init_type type = plat->init_type;
struct ehci_hccr *hccr;
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index f20fc3354c..dceba4bd7a 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -10,6 +10,7 @@
#include <errno.h>
#include <pci.h>
#include <usb.h>
+#include <asm/io.h>
#include "ehci.h"
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
index 068f24f483..6ecb7c4d12 100644
--- a/drivers/usb/host/ehci-sunxi.c
+++ b/drivers/usb/host/ehci-sunxi.c
@@ -36,7 +36,7 @@ static int ehci_usb_probe(struct udevice *dev)
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct usb_platdata *plat = dev_get_platdata(dev);
struct ehci_sunxi_priv *priv = dev_get_priv(dev);
- struct ehci_hccr *hccr = (struct ehci_hccr *)dev_get_addr(dev);
+ struct ehci_hccr *hccr = (struct ehci_hccr *)devfdt_get_addr(dev);
struct ehci_hcor *hcor;
int extra_ahb_gate_mask = 0;
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index beb3b02796..7dc37f045d 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -699,7 +699,7 @@ static int fdt_decode_usb(struct udevice *dev, struct fdt_usb *config)
int node = dev_of_offset(dev);
const char *phy, *mode;
- config->reg = (struct usb_ctlr *)dev_get_addr(dev);
+ config->reg = (struct usb_ctlr *)devfdt_get_addr(dev);
mode = fdt_getprop(blob, node, "dr_mode", NULL);
if (mode) {
if (0 == strcmp(mode, "host"))
@@ -728,9 +728,10 @@ static int fdt_decode_usb(struct udevice *dev, struct fdt_usb *config)
debug("%s: Missing/invalid peripheral ID\n", __func__);
return -EINVAL;
}
- gpio_request_by_name_nodev(blob, node, "nvidia,vbus-gpio", 0,
- &config->vbus_gpio, GPIOD_IS_OUT);
- gpio_request_by_name_nodev(blob, node, "nvidia,phy-reset-gpio", 0,
+ gpio_request_by_name_nodev(offset_to_ofnode(node), "nvidia,vbus-gpio",
+ 0, &config->vbus_gpio, GPIOD_IS_OUT);
+ gpio_request_by_name_nodev(offset_to_ofnode(node),
+ "nvidia,phy-reset-gpio", 0,
&config->phy_reset_gpio, GPIOD_IS_OUT);
debug("enabled=%d, legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, "
"vbus=%d, phy_reset=%d, dr_mode=%d\n",
diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index 84241cd173..a7f6f21fa2 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -223,7 +223,7 @@ static int vf_usb_ofdata_to_platdata(struct udevice *dev)
priv->portnr = dev->seq;
- priv->ehci = (struct usb_ehci *)dev_get_addr(dev);
+ priv->ehci = (struct usb_ehci *)devfdt_get_addr(dev);
mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
if (mode) {
if (0 == strcmp(mode, "host")) {
@@ -252,8 +252,9 @@ static int vf_usb_ofdata_to_platdata(struct udevice *dev)
}
if (priv->dr_mode == DR_MODE_OTG) {
- gpio_request_by_name_nodev(dt_blob, node, "fsl,cdet-gpio", 0,
- &priv->cdet_gpio, GPIOD_IS_IN);
+ gpio_request_by_name_nodev(offset_to_ofnode(node),
+ "fsl,cdet-gpio", 0, &priv->cdet_gpio,
+ GPIOD_IS_IN);
if (dm_gpio_is_valid(&priv->cdet_gpio)) {
if (dm_gpio_get_value(&priv->cdet_gpio))
priv->init_type = USB_INIT_DEVICE;
diff --git a/drivers/usb/host/ehci-zynq.c b/drivers/usb/host/ehci-zynq.c
index 1e3b8001f3..4f127d5afa 100644
--- a/drivers/usb/host/ehci-zynq.c
+++ b/drivers/usb/host/ehci-zynq.c
@@ -26,7 +26,7 @@ static int ehci_zynq_ofdata_to_platdata(struct udevice *dev)
{
struct zynq_ehci_priv *priv = dev_get_priv(dev);
- priv->ehci = (struct usb_ehci *)dev_get_addr_ptr(dev);
+ priv->ehci = (struct usb_ehci *)devfdt_get_addr_ptr(dev);
if (!priv->ehci)
return -EINVAL;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 734d7f0362..2ab830df51 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -102,13 +102,11 @@ struct usb_linux_config_descriptor {
} __attribute__ ((packed));
#if defined CONFIG_EHCI_DESC_BIG_ENDIAN
-#define ehci_readl(x) cpu_to_be32((*((volatile u32 *)(x))))
-#define ehci_writel(a, b) (*((volatile u32 *)(a)) = \
- cpu_to_be32(((volatile u32)b)))
+#define ehci_readl(x) cpu_to_be32(readl(x))
+#define ehci_writel(a, b) writel(cpu_to_be32(b), a)
#else
-#define ehci_readl(x) cpu_to_le32((*((volatile u32 *)(x))))
-#define ehci_writel(a, b) (*((volatile u32 *)(a)) = \
- cpu_to_le32(((volatile u32)b)))
+#define ehci_readl(x) cpu_to_le32(readl(x))
+#define ehci_writel(a, b) writel(cpu_to_le32(b), a)
#endif
#if defined CONFIG_EHCI_MMIO_BIG_ENDIAN
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index f3307f47a7..f85738fb05 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -18,7 +18,7 @@ struct generic_ohci {
static int ohci_usb_probe(struct udevice *dev)
{
- struct ohci_regs *regs = (struct ohci_regs *)dev_get_addr(dev);
+ struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
return ohci_register(dev, regs);
}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 80cfe11290..272df0784a 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -51,10 +51,8 @@
#endif
#if defined(CONFIG_CPU_ARM920T) || \
- defined(CONFIG_S3C24X0) || \
defined(CONFIG_440EP) || \
defined(CONFIG_PCI_OHCI) || \
- defined(CONFIG_MPC5200) || \
defined(CONFIG_SYS_OHCI_USE_NPS)
# define OHCI_USE_NPS /* force NoPowerSwitching mode */
#endif
@@ -1089,10 +1087,6 @@ static void check_status(td_t *td_list)
*phwHeadP &= m32_swap(0xfffffff2);
flush_dcache_ed(td_list->ed);
}
-#ifdef CONFIG_MPC5200
- td_list->hwNextTD = 0;
- flush_dcache_td(td_list);
-#endif
}
}
diff --git a/drivers/usb/host/ohci-s3c24xx.c b/drivers/usb/host/ohci-s3c24xx.c
deleted file mode 100644
index 28b9ab5176..0000000000
--- a/drivers/usb/host/ohci-s3c24xx.c
+++ /dev/null
@@ -1,1688 +0,0 @@
-/*
- * URB OHCI HCD (Host Controller Driver) for USB on the S3C2400.
- *
- * (C) Copyright 2003
- * Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
- *
- * Note: Much of this code has been derived from Linux 2.4
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-/*
- * IMPORTANT NOTES
- * 1 - this driver is intended for use with USB Mass Storage Devices
- * (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes!
- */
-
-#include <common.h>
-/* #include <pci.h> no PCI on the S3C24X0 */
-
-#if defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0)
-
-#include <asm/arch/s3c24x0_cpu.h>
-#include <asm/io.h>
-#include <malloc.h>
-#include <usb.h>
-#include "ohci-s3c24xx.h"
-
-#define OHCI_USE_NPS /* force NoPowerSwitching mode */
-#undef OHCI_VERBOSE_DEBUG /* not always helpful */
-
-
-/* For initializing controller (mask in an HCFS mode too) */
-#define OHCI_CONTROL_INIT \
- (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-
-#undef DEBUG
-#ifdef DEBUG
-#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
-#else
-#define dbg(format, arg...) do {} while(0)
-#endif /* DEBUG */
-#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
-#undef SHOW_INFO
-#ifdef SHOW_INFO
-#define info(format, arg...) printf("INFO: " format "\n", ## arg)
-#else
-#define info(format, arg...) do {} while(0)
-#endif
-
-#define m16_swap(x) swap_16(x)
-#define m32_swap(x) swap_32(x)
-
-/* global struct ohci */
-static struct ohci gohci;
-/* this must be aligned to a 256 byte boundary */
-struct ohci_hcca ghcca[1];
-/* a pointer to the aligned storage */
-struct ohci_hcca *phcca;
-/* this allocates EDs for all possible endpoints */
-struct ohci_device ohci_dev;
-/* urb_priv */
-struct urb_priv urb_priv;
-/* RHSC flag */
-int got_rhsc;
-/* device which was disconnected */
-struct usb_device *devgone;
-/* flag guarding URB transation */
-int urb_finished = 0;
-
-/*-------------------------------------------------------------------------*/
-
-/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
- * The erratum (#4) description is incorrect. AMD's workaround waits
- * till some bits (mostly reserved) are clear; ok for all revs.
- */
-#define OHCI_QUIRK_AMD756 0xabcd
-#define read_roothub(hc, register, mask) ({ \
- u32 temp = readl (&hc->regs->roothub.register); \
- if (hc->flags & OHCI_QUIRK_AMD756) \
- while (temp & mask) \
- temp = readl (&hc->regs->roothub.register); \
- temp; })
-
-static u32 roothub_a(struct ohci *hc)
-{
- return read_roothub(hc, a, 0xfc0fe000);
-}
-static inline u32 roothub_b(struct ohci *hc)
-{
- return readl(&hc->regs->roothub.b);
-}
-static inline u32 roothub_status(struct ohci *hc)
-{
- return readl(&hc->regs->roothub.status);
-}
-static u32 roothub_portstatus(struct ohci *hc, int i)
-{
- return read_roothub(hc, portstatus[i], 0xffe0fce0);
-}
-
-/* forward declaration */
-static int hc_interrupt(void);
-static void td_submit_job(struct usb_device *dev, unsigned long pipe,
- void *buffer, int transfer_len,
- struct devrequest *setup, struct urb_priv *urb,
- int interval);
-
-/*-------------------------------------------------------------------------*
- * URB support functions
- *-------------------------------------------------------------------------*/
-
-/* free HCD-private data associated with this URB */
-
-static void urb_free_priv(struct urb_priv *urb)
-{
- int i;
- int last;
- struct td *td;
-
- last = urb->length - 1;
- if (last >= 0) {
- for (i = 0; i <= last; i++) {
- td = urb->td[i];
- if (td) {
- td->usb_dev = NULL;
- urb->td[i] = NULL;
- }
- }
- }
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef DEBUG
-static int sohci_get_current_frame_number(struct usb_device *dev);
-
-/* debug| print the main components of an URB
- * small: 0) header + data packets 1) just header */
-
-static void pkt_print(struct usb_device *dev, unsigned long pipe, void *buffer,
- int transfer_len, struct devrequest *setup, char *str,
- int small)
-{
- struct urb_priv *purb = &urb_priv;
-
- dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
- str,
- sohci_get_current_frame_number(dev),
- usb_pipedevice(pipe),
- usb_pipeendpoint(pipe),
- usb_pipeout(pipe) ? 'O' : 'I',
- usb_pipetype(pipe) < 2 ?
- (usb_pipeint(pipe) ? "INTR" : "ISOC") :
- (usb_pipecontrol(pipe) ? "CTRL" : "BULK"),
- purb->actual_length, transfer_len, dev->status);
-#ifdef OHCI_VERBOSE_DEBUG
- if (!small) {
- int i, len;
-
- if (usb_pipecontrol(pipe)) {
- printf(__FILE__ ": cmd(8):");
- for (i = 0; i < 8; i++)
- printf(" %02x", ((__u8 *) setup)[i]);
- printf("\n");
- }
- if (transfer_len > 0 && buffer) {
- printf(__FILE__ ": data(%d/%d):",
- purb->actual_length, transfer_len);
- len = usb_pipeout(pipe) ?
- transfer_len : purb->actual_length;
- for (i = 0; i < 16 && i < len; i++)
- printf(" %02x", ((__u8 *) buffer)[i]);
- printf("%s\n", i < len ? "..." : "");
- }
- }
-#endif
-}
-
-/* just for debugging; prints non-empty branches of the
- int ed tree inclusive iso eds*/
-void ep_print_int_eds(struct ohci *ohci, char *str)
-{
- int i, j;
- __u32 *ed_p;
- for (i = 0; i < 32; i++) {
- j = 5;
- ed_p = &(ohci->hcca->int_table[i]);
- if (*ed_p == 0)
- continue;
- printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i);
- while (*ed_p != 0 && j--) {
- struct ed *ed = (struct ed *) m32_swap(ed_p);
- printf(" ed: %4x;", ed->hwINFO);
- ed_p = &ed->hwNextED;
- }
- printf("\n");
- }
-}
-
-static void ohci_dump_intr_mask(char *label, __u32 mask)
-{
- dbg("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
- label,
- mask,
- (mask & OHCI_INTR_MIE) ? " MIE" : "",
- (mask & OHCI_INTR_OC) ? " OC" : "",
- (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
- (mask & OHCI_INTR_FNO) ? " FNO" : "",
- (mask & OHCI_INTR_UE) ? " UE" : "",
- (mask & OHCI_INTR_RD) ? " RD" : "",
- (mask & OHCI_INTR_SF) ? " SF" : "",
- (mask & OHCI_INTR_WDH) ? " WDH" : "",
- (mask & OHCI_INTR_SO) ? " SO" : "");
-}
-
-static void maybe_print_eds(char *label, __u32 value)
-{
- struct ed *edp = (struct ed *) value;
-
- if (value) {
- dbg("%s %08x", label, value);
- dbg("%08x", edp->hwINFO);
- dbg("%08x", edp->hwTailP);
- dbg("%08x", edp->hwHeadP);
- dbg("%08x", edp->hwNextED);
- }
-}
-
-static char *hcfs2string(int state)
-{
- switch (state) {
- case OHCI_USB_RESET:
- return "reset";
- case OHCI_USB_RESUME:
- return "resume";
- case OHCI_USB_OPER:
- return "operational";
- case OHCI_USB_SUSPEND:
- return "suspend";
- }
- return "?";
-}
-
-/* dump control and status registers */
-static void ohci_dump_status(struct ohci *controller)
-{
- struct ohci_regs *regs = controller->regs;
- __u32 temp;
-
- temp = readl(&regs->revision) & 0xff;
- if (temp != 0x10)
- dbg("spec %d.%d", (temp >> 4), (temp & 0x0f));
-
- temp = readl(&regs->control);
- dbg("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
- (temp & OHCI_CTRL_RWE) ? " RWE" : "",
- (temp & OHCI_CTRL_RWC) ? " RWC" : "",
- (temp & OHCI_CTRL_IR) ? " IR" : "",
- hcfs2string(temp & OHCI_CTRL_HCFS),
- (temp & OHCI_CTRL_BLE) ? " BLE" : "",
- (temp & OHCI_CTRL_CLE) ? " CLE" : "",
- (temp & OHCI_CTRL_IE) ? " IE" : "",
- (temp & OHCI_CTRL_PLE) ? " PLE" : "", temp & OHCI_CTRL_CBSR);
-
- temp = readl(&regs->cmdstatus);
- dbg("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
- (temp & OHCI_SOC) >> 16,
- (temp & OHCI_OCR) ? " OCR" : "",
- (temp & OHCI_BLF) ? " BLF" : "",
- (temp & OHCI_CLF) ? " CLF" : "", (temp & OHCI_HCR) ? " HCR" : "");
-
- ohci_dump_intr_mask("intrstatus", readl(&regs->intrstatus));
- ohci_dump_intr_mask("intrenable", readl(&regs->intrenable));
-
- maybe_print_eds("ed_periodcurrent", readl(&regs->ed_periodcurrent));
-
- maybe_print_eds("ed_controlhead", readl(&regs->ed_controlhead));
- maybe_print_eds("ed_controlcurrent", readl(&regs->ed_controlcurrent));
-
- maybe_print_eds("ed_bulkhead", readl(&regs->ed_bulkhead));
- maybe_print_eds("ed_bulkcurrent", readl(&regs->ed_bulkcurrent));
-
- maybe_print_eds("donehead", readl(&regs->donehead));
-}
-
-static void ohci_dump_roothub(struct ohci *controller, int verbose)
-{
- __u32 temp, ndp, i;
-
- temp = roothub_a(controller);
- ndp = (temp & RH_A_NDP);
-
- if (verbose) {
- dbg("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
- ((temp & RH_A_POTPGT) >> 24) & 0xff,
- (temp & RH_A_NOCP) ? " NOCP" : "",
- (temp & RH_A_OCPM) ? " OCPM" : "",
- (temp & RH_A_DT) ? " DT" : "",
- (temp & RH_A_NPS) ? " NPS" : "",
- (temp & RH_A_PSM) ? " PSM" : "", ndp);
- temp = roothub_b(controller);
- dbg("roothub.b: %08x PPCM=%04x DR=%04x",
- temp, (temp & RH_B_PPCM) >> 16, (temp & RH_B_DR)
- );
- temp = roothub_status(controller);
- dbg("roothub.status: %08x%s%s%s%s%s%s",
- temp,
- (temp & RH_HS_CRWE) ? " CRWE" : "",
- (temp & RH_HS_OCIC) ? " OCIC" : "",
- (temp & RH_HS_LPSC) ? " LPSC" : "",
- (temp & RH_HS_DRWE) ? " DRWE" : "",
- (temp & RH_HS_OCI) ? " OCI" : "",
- (temp & RH_HS_LPS) ? " LPS" : "");
- }
-
- for (i = 0; i < ndp; i++) {
- temp = roothub_portstatus(controller, i);
- dbg("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
- i,
- temp,
- (temp & RH_PS_PRSC) ? " PRSC" : "",
- (temp & RH_PS_OCIC) ? " OCIC" : "",
- (temp & RH_PS_PSSC) ? " PSSC" : "",
- (temp & RH_PS_PESC) ? " PESC" : "",
- (temp & RH_PS_CSC) ? " CSC" : "",
- (temp & RH_PS_LSDA) ? " LSDA" : "",
- (temp & RH_PS_PPS) ? " PPS" : "",
- (temp & RH_PS_PRS) ? " PRS" : "",
- (temp & RH_PS_POCI) ? " POCI" : "",
- (temp & RH_PS_PSS) ? " PSS" : "",
- (temp & RH_PS_PES) ? " PES" : "",
- (temp & RH_PS_CCS) ? " CCS" : "");
- }
-}
-
-static void ohci_dump(struct ohci *controller, int verbose)
-{
- dbg("OHCI controller usb-%s state", controller->slot_name);
-
- /* dumps some of the state we know about */
- ohci_dump_status(controller);
- if (verbose)
- ep_print_int_eds(controller, "hcca");
- dbg("hcca frame #%04x", controller->hcca->frame_no);
- ohci_dump_roothub(controller, 1);
-}
-
-#endif /* DEBUG */
-
-/*-------------------------------------------------------------------------*
- * Interface functions (URB)
- *-------------------------------------------------------------------------*/
-
-/* get a transfer request */
-
-int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
- int transfer_len, struct devrequest *setup, int interval)
-{
- struct ohci *ohci;
- struct ed *ed;
- struct urb_priv *purb_priv;
- int i, size = 0;
-
- ohci = &gohci;
-
- /* when controller's hung, permit only roothub cleanup attempts
- * such as powering down ports */
- if (ohci->disabled) {
- err("sohci_submit_job: EPIPE");
- return -1;
- }
-
- /* if we have an unfinished URB from previous transaction let's
- * fail and scream as quickly as possible so as not to corrupt
- * further communication */
- if (!urb_finished) {
- err("sohci_submit_job: URB NOT FINISHED");
- return -1;
- }
- /* we're about to begin a new transaction here
- so mark the URB unfinished */
- urb_finished = 0;
-
- /* every endpoint has a ed, locate and fill it */
- ed = ep_add_ed(dev, pipe);
- if (!ed) {
- err("sohci_submit_job: ENOMEM");
- return -1;
- }
-
- /* for the private part of the URB we need the number of TDs (size) */
- switch (usb_pipetype(pipe)) {
- case PIPE_BULK:
- /* one TD for every 4096 Byte */
- size = (transfer_len - 1) / 4096 + 1;
- break;
- case PIPE_CONTROL:
- /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
- size = (transfer_len == 0) ? 2 : (transfer_len - 1) / 4096 + 3;
- break;
- }
-
- if (size >= (N_URB_TD - 1)) {
- err("need %d TDs, only have %d", size, N_URB_TD);
- return -1;
- }
- purb_priv = &urb_priv;
- purb_priv->pipe = pipe;
-
- /* fill the private part of the URB */
- purb_priv->length = size;
- purb_priv->ed = ed;
- purb_priv->actual_length = 0;
-
- /* allocate the TDs */
- /* note that td[0] was allocated in ep_add_ed */
- for (i = 0; i < size; i++) {
- purb_priv->td[i] = td_alloc(dev);
- if (!purb_priv->td[i]) {
- purb_priv->length = i;
- urb_free_priv(purb_priv);
- err("sohci_submit_job: ENOMEM");
- return -1;
- }
- }
-
- if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
- urb_free_priv(purb_priv);
- err("sohci_submit_job: EINVAL");
- return -1;
- }
-
- /* link the ed into a chain if is not already */
- if (ed->state != ED_OPER)
- ep_link(ohci, ed);
-
- /* fill the TDs and link it to the ed */
- td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv,
- interval);
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef DEBUG
-/* tell us the current USB frame number */
-
-static int sohci_get_current_frame_number(struct usb_device *usb_dev)
-{
- struct ohci *ohci = &gohci;
-
- return m16_swap(ohci->hcca->frame_no);
-}
-#endif
-
-/*-------------------------------------------------------------------------*
- * ED handling functions
- *-------------------------------------------------------------------------*/
-
-/* link an ed into one of the HC chains */
-
-static int ep_link(struct ohci *ohci, struct ed *edi)
-{
- struct ed *ed = edi;
-
- ed->state = ED_OPER;
-
- switch (ed->type) {
- case PIPE_CONTROL:
- ed->hwNextED = 0;
- if (ohci->ed_controltail == NULL) {
- writel((u32)ed, &ohci->regs->ed_controlhead);
- } else {
- ohci->ed_controltail->hwNextED = (__u32) m32_swap(ed);
- }
- ed->ed_prev = ohci->ed_controltail;
- if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
- !ohci->ed_rm_list[1] && !ohci->sleeping) {
- ohci->hc_control |= OHCI_CTRL_CLE;
- writel(ohci->hc_control, &ohci->regs->control);
- }
- ohci->ed_controltail = edi;
- break;
-
- case PIPE_BULK:
- ed->hwNextED = 0;
- if (ohci->ed_bulktail == NULL) {
- writel((u32)ed, &ohci->regs->ed_bulkhead);
- } else {
- ohci->ed_bulktail->hwNextED = (__u32) m32_swap(ed);
- }
- ed->ed_prev = ohci->ed_bulktail;
- if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
- !ohci->ed_rm_list[1] && !ohci->sleeping) {
- ohci->hc_control |= OHCI_CTRL_BLE;
- writel(ohci->hc_control, &ohci->regs->control);
- }
- ohci->ed_bulktail = edi;
- break;
- }
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* unlink an ed from one of the HC chains.
- * just the link to the ed is unlinked.
- * the link from the ed still points to another operational ed or 0
- * so the HC can eventually finish the processing of the unlinked ed */
-
-static int ep_unlink(struct ohci *ohci, struct ed *ed)
-{
- struct ed *next;
- ed->hwINFO |= m32_swap(OHCI_ED_SKIP);
-
- switch (ed->type) {
- case PIPE_CONTROL:
- if (ed->ed_prev == NULL) {
- if (!ed->hwNextED) {
- ohci->hc_control &= ~OHCI_CTRL_CLE;
- writel(ohci->hc_control, &ohci->regs->control);
- }
- writel(m32_swap(*((__u32 *) &ed->hwNextED)),
- &ohci->regs->ed_controlhead);
- } else {
- ed->ed_prev->hwNextED = ed->hwNextED;
- }
- if (ohci->ed_controltail == ed) {
- ohci->ed_controltail = ed->ed_prev;
- } else {
- next = (struct ed *)m32_swap(*((__u32 *)&ed->hwNextED));
- next->ed_prev = ed->ed_prev;
- }
- break;
-
- case PIPE_BULK:
- if (ed->ed_prev == NULL) {
- if (!ed->hwNextED) {
- ohci->hc_control &= ~OHCI_CTRL_BLE;
- writel(ohci->hc_control, &ohci->regs->control);
- }
- writel(m32_swap(*((__u32 *) &ed->hwNextED)),
- &ohci->regs->ed_bulkhead);
- } else {
- ed->ed_prev->hwNextED = ed->hwNextED;
- }
- if (ohci->ed_bulktail == ed) {
- ohci->ed_bulktail = ed->ed_prev;
- } else {
- next = (struct ed *)m32_swap(*((__u32 *)&ed->hwNextED));
- next->ed_prev = ed->ed_prev;
- }
- break;
- }
- ed->state = ED_UNLINK;
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* add/reinit an endpoint; this should be done once at the usb_set_configuration
- * command, but the USB stack is a little bit stateless so we do it at every
- * transaction. If the state of the ed is ED_NEW then a dummy td is added and
- * the state is changed to ED_UNLINK. In all other cases the state is left
- * unchanged. The ed info fields are setted anyway even though most of them
- * should not change */
-
-static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe)
-{
- struct td *td;
- struct ed *ed_ret;
- struct ed *ed;
-
- ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint(pipe) << 1) |
- (usb_pipecontrol(pipe) ? 0 :
- usb_pipeout(pipe))];
-
- if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
- err("ep_add_ed: pending delete");
- /* pending delete request */
- return NULL;
- }
-
- if (ed->state == ED_NEW) {
- ed->hwINFO = m32_swap(OHCI_ED_SKIP); /* skip ed */
- /* dummy td; end of td list for ed */
- td = td_alloc(usb_dev);
- ed->hwTailP = (__u32) m32_swap(td);
- ed->hwHeadP = ed->hwTailP;
- ed->state = ED_UNLINK;
- ed->type = usb_pipetype(pipe);
- ohci_dev.ed_cnt++;
- }
-
- ed->hwINFO = m32_swap(usb_pipedevice(pipe)
- | usb_pipeendpoint(pipe) << 7
- | (usb_pipeisoc(pipe) ? 0x8000 : 0)
- | (usb_pipecontrol(pipe) ? 0 :
- (usb_pipeout(pipe) ? 0x800 : 0x1000))
- | (usb_dev->speed == USB_SPEED_LOW) << 13 |
- usb_maxpacket(usb_dev, pipe) << 16);
-
- return ed_ret;
-}
-
-/*-------------------------------------------------------------------------*
- * TD handling functions
- *-------------------------------------------------------------------------*/
-
-/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
-
-static void td_fill(struct ohci *ohci, unsigned int info, void *data, int len,
- struct usb_device *dev, int index,
- struct urb_priv *urb_priv)
-{
- struct td *td, *td_pt;
-#ifdef OHCI_FILL_TRACE
- int i;
-#endif
-
- if (index > urb_priv->length) {
- err("index > length");
- return;
- }
- /* use this td as the next dummy */
- td_pt = urb_priv->td[index];
- td_pt->hwNextTD = 0;
-
- /* fill the old dummy TD */
- td = urb_priv->td[index] =
- (struct td *) (m32_swap(urb_priv->ed->hwTailP) & ~0xf);
-
- td->ed = urb_priv->ed;
- td->next_dl_td = NULL;
- td->index = index;
- td->data = (__u32) data;
-#ifdef OHCI_FILL_TRACE
- if (usb_pipebulk(urb_priv->pipe) && usb_pipeout(urb_priv->pipe)) {
- for (i = 0; i < len; i++)
- printf("td->data[%d] %#2x ", i,
- ((unsigned char *)td->data)[i]);
- printf("\n");
- }
-#endif
- if (!len)
- data = 0;
-
- td->hwINFO = (__u32) m32_swap(info);
- td->hwCBP = (__u32) m32_swap(data);
- if (data)
- td->hwBE = (__u32) m32_swap(data + len - 1);
- else
- td->hwBE = 0;
- td->hwNextTD = (__u32) m32_swap(td_pt);
-
- /* append to queue */
- td->ed->hwTailP = td->hwNextTD;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* prepare all TDs of a transfer */
-
-static void td_submit_job(struct usb_device *dev, unsigned long pipe,
- void *buffer, int transfer_len,
- struct devrequest *setup, struct urb_priv *urb,
- int interval)
-{
- struct ohci *ohci = &gohci;
- int data_len = transfer_len;
- void *data;
- int cnt = 0;
- __u32 info = 0;
- unsigned int toggle = 0;
-
- /* OHCI handles the DATA-toggles itself, we just
- use the USB-toggle bits for resetting */
- if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
- toggle = TD_T_TOGGLE;
- } else {
- toggle = TD_T_DATA0;
- usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe),
- 1);
- }
- urb->td_cnt = 0;
- if (data_len)
- data = buffer;
- else
- data = 0;
-
- switch (usb_pipetype(pipe)) {
- case PIPE_BULK:
- info = usb_pipeout(pipe) ? TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN;
- while (data_len > 4096) {
- td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data,
- 4096, dev, cnt, urb);
- data += 4096;
- data_len -= 4096;
- cnt++;
- }
- info = usb_pipeout(pipe) ?
- TD_CC | TD_DP_OUT :
- TD_CC | TD_R | TD_DP_IN;
- td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data,
- data_len, dev, cnt, urb);
- cnt++;
-
- if (!ohci->sleeping)
- /* start bulk list */
- writel(OHCI_BLF, &ohci->regs->cmdstatus);
- break;
-
- case PIPE_CONTROL:
- info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
- td_fill(ohci, info, setup, 8, dev, cnt++, urb);
- if (data_len > 0) {
- info = usb_pipeout(pipe) ?
- TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 :
- TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
- /* NOTE: mishandles transfers >8K, some >4K */
- td_fill(ohci, info, data, data_len, dev, cnt++, urb);
- }
- info = usb_pipeout(pipe) ?
- TD_CC | TD_DP_IN | TD_T_DATA1 :
- TD_CC | TD_DP_OUT | TD_T_DATA1;
- td_fill(ohci, info, data, 0, dev, cnt++, urb);
- if (!ohci->sleeping)
- /* start Control list */
- writel(OHCI_CLF, &ohci->regs->cmdstatus);
- break;
- }
- if (urb->length != cnt)
- dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
-}
-
-/*-------------------------------------------------------------------------*
- * Done List handling functions
- *-------------------------------------------------------------------------*/
-
-
-/* calculate the transfer length and update the urb */
-
-static void dl_transfer_length(struct td *td)
-{
- __u32 tdBE, tdCBP;
- struct urb_priv *lurb_priv = &urb_priv;
-
- tdBE = m32_swap(td->hwBE);
- tdCBP = m32_swap(td->hwCBP);
-
- if (!(usb_pipecontrol(lurb_priv->pipe) &&
- ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
- if (tdBE != 0) {
- if (td->hwCBP == 0)
- lurb_priv->actual_length += tdBE - td->data + 1;
- else
- lurb_priv->actual_length += tdCBP - td->data;
- }
- }
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* replies to the request have to be on a FIFO basis so
- * we reverse the reversed done-list */
-
-static struct td *dl_reverse_done_list(struct ohci *ohci)
-{
- __u32 td_list_hc;
- __u32 tmp;
- struct td *td_rev = NULL;
- struct td *td_list = NULL;
- struct urb_priv *lurb_priv = NULL;
-
- td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0;
- ohci->hcca->done_head = 0;
-
- while (td_list_hc) {
- td_list = (struct td *) td_list_hc;
-
- if (TD_CC_GET(m32_swap(td_list->hwINFO))) {
- lurb_priv = &urb_priv;
- dbg(" USB-error/status: %x : %p",
- TD_CC_GET(m32_swap(td_list->hwINFO)), td_list);
- if (td_list->ed->hwHeadP & m32_swap(0x1)) {
- if (lurb_priv &&
- ((td_list->index+1) < lurb_priv->length)) {
- tmp = lurb_priv->length - 1;
- td_list->ed->hwHeadP =
- (lurb_priv->td[tmp]->hwNextTD &
- m32_swap(0xfffffff0)) |
- (td_list->ed->hwHeadP &
- m32_swap(0x2));
- lurb_priv->td_cnt += lurb_priv->length -
- td_list->index - 1;
- } else
- td_list->ed->hwHeadP &=
- m32_swap(0xfffffff2);
- }
- }
-
- td_list->next_dl_td = td_rev;
- td_rev = td_list;
- td_list_hc = m32_swap(td_list->hwNextTD) & 0xfffffff0;
- }
-
- return td_list;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* td done list */
-static int dl_done_list(struct ohci *ohci, struct td *td_list)
-{
- struct td *td_list_next = NULL;
- struct ed *ed;
- int cc = 0;
- int stat = 0;
- /* urb_t *urb; */
- struct urb_priv *lurb_priv;
- __u32 tdINFO, edHeadP, edTailP;
-
- while (td_list) {
- td_list_next = td_list->next_dl_td;
-
- lurb_priv = &urb_priv;
- tdINFO = m32_swap(td_list->hwINFO);
-
- ed = td_list->ed;
-
- dl_transfer_length(td_list);
-
- /* error code of transfer */
- cc = TD_CC_GET(tdINFO);
- if (cc != 0) {
- dbg("ConditionCode %#x", cc);
- stat = cc_to_error[cc];
- }
-
- /* see if this done list makes for all TD's of current URB,
- * and mark the URB finished if so */
- if (++(lurb_priv->td_cnt) == lurb_priv->length) {
- if ((ed->state & (ED_OPER | ED_UNLINK)))
- urb_finished = 1;
- else
- dbg("dl_done_list: strange.., ED state %x, "
- "ed->state\n");
- } else
- dbg("dl_done_list: processing TD %x, len %x\n",
- lurb_priv->td_cnt, lurb_priv->length);
-
- if (ed->state != ED_NEW) {
- edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0;
- edTailP = m32_swap(ed->hwTailP);
-
- /* unlink eds if they are not busy */
- if ((edHeadP == edTailP) && (ed->state == ED_OPER))
- ep_unlink(ohci, ed);
- }
-
- td_list = td_list_next;
- }
- return stat;
-}
-
-/*-------------------------------------------------------------------------*
- * Virtual Root Hub
- *-------------------------------------------------------------------------*/
-
-#include <usbroothubdes.h>
-
-/* Hub class-specific descriptor is constructed dynamically */
-
-
-/*-------------------------------------------------------------------------*/
-
-#define OK(x) len = (x); break
-#ifdef DEBUG
-#define WR_RH_STAT(x) \
-{ \
- info("WR:status %#8x", (x)); \
- writel((x), &gohci.regs->roothub.status); \
-}
-#define WR_RH_PORTSTAT(x) \
-{ \
- info("WR:portstatus[%d] %#8x", wIndex-1, (x)); \
- writel((x), &gohci.regs->roothub.portstatus[wIndex-1]); \
-}
-#else
-#define WR_RH_STAT(x) \
- writel((x), &gohci.regs->roothub.status)
-#define WR_RH_PORTSTAT(x)\
- writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
-#endif
-#define RD_RH_STAT roothub_status(&gohci)
-#define RD_RH_PORTSTAT roothub_portstatus(&gohci, wIndex-1)
-
-/* request to virtual root hub */
-
-int rh_check_port_status(struct ohci *controller)
-{
- __u32 temp, ndp, i;
- int res;
-
- res = -1;
- temp = roothub_a(controller);
- ndp = (temp & RH_A_NDP);
- for (i = 0; i < ndp; i++) {
- temp = roothub_portstatus(controller, i);
- /* check for a device disconnect */
- if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
- (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
- res = i;
- break;
- }
- }
- return res;
-}
-
-static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
- void *buffer, int transfer_len,
- struct devrequest *cmd)
-{
- void *data = buffer;
- int leni = transfer_len;
- int len = 0;
- int stat = 0;
- union {
- __u32 word[4];
- __u16 hword[8];
- __u8 byte[16];
- } datab;
- __u8 *data_buf = datab.byte;
- __u16 bmRType_bReq;
- __u16 wValue;
- __u16 wIndex;
- __u16 wLength;
-
-#ifdef DEBUG
- urb_priv.actual_length = 0;
- pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)",
- usb_pipein(pipe));
-#else
- mdelay(1);
-#endif
- if (usb_pipeint(pipe)) {
- info("Root-Hub submit IRQ: NOT implemented");
- return 0;
- }
-
- bmRType_bReq = cmd->requesttype | (cmd->request << 8);
- wValue = m16_swap(cmd->value);
- wIndex = m16_swap(cmd->index);
- wLength = m16_swap(cmd->length);
-
- info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
- dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
-
- switch (bmRType_bReq) {
- /* Request Destination:
- without flags: Device,
- RH_INTERFACE: interface,
- RH_ENDPOINT: endpoint,
- RH_CLASS means HUB here,
- RH_OTHER | RH_CLASS almost ever means HUB_PORT here
- */
-
- case RH_GET_STATUS:
- datab.hword[0] = m16_swap(1);
- OK(2);
- case RH_GET_STATUS | RH_INTERFACE:
- datab.hword[0] = m16_swap(0);
- OK(2);
- case RH_GET_STATUS | RH_ENDPOINT:
- datab.hword[0] = m16_swap(0);
- OK(2);
- case RH_GET_STATUS | RH_CLASS:
- datab.word[0] =
- m32_swap(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
- OK(4);
- case RH_GET_STATUS | RH_OTHER | RH_CLASS:
- datab.word[0] = m32_swap(RD_RH_PORTSTAT);
- OK(4);
-
- case RH_CLEAR_FEATURE | RH_ENDPOINT:
- switch (wValue) {
- case (RH_ENDPOINT_STALL):
- OK(0);
- }
- break;
-
- case RH_CLEAR_FEATURE | RH_CLASS:
- switch (wValue) {
- case RH_C_HUB_LOCAL_POWER:
- OK(0);
- case (RH_C_HUB_OVER_CURRENT):
- WR_RH_STAT(RH_HS_OCIC);
- OK(0);
- }
- break;
-
- case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
- switch (wValue) {
- case (RH_PORT_ENABLE):
- WR_RH_PORTSTAT(RH_PS_CCS);
- OK(0);
- case (RH_PORT_SUSPEND):
- WR_RH_PORTSTAT(RH_PS_POCI);
- OK(0);
- case (RH_PORT_POWER):
- WR_RH_PORTSTAT(RH_PS_LSDA);
- OK(0);
- case (RH_C_PORT_CONNECTION):
- WR_RH_PORTSTAT(RH_PS_CSC);
- OK(0);
- case (RH_C_PORT_ENABLE):
- WR_RH_PORTSTAT(RH_PS_PESC);
- OK(0);
- case (RH_C_PORT_SUSPEND):
- WR_RH_PORTSTAT(RH_PS_PSSC);
- OK(0);
- case (RH_C_PORT_OVER_CURRENT):
- WR_RH_PORTSTAT(RH_PS_OCIC);
- OK(0);
- case (RH_C_PORT_RESET):
- WR_RH_PORTSTAT(RH_PS_PRSC);
- OK(0);
- }
- break;
-
- case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
- switch (wValue) {
- case (RH_PORT_SUSPEND):
- WR_RH_PORTSTAT(RH_PS_PSS);
- OK(0);
- case (RH_PORT_RESET): /* BUG IN HUP CODE ******** */
- if (RD_RH_PORTSTAT & RH_PS_CCS)
- WR_RH_PORTSTAT(RH_PS_PRS);
- OK(0);
- case (RH_PORT_POWER):
- WR_RH_PORTSTAT(RH_PS_PPS);
- OK(0);
- case (RH_PORT_ENABLE): /* BUG IN HUP CODE ******** */
- if (RD_RH_PORTSTAT & RH_PS_CCS)
- WR_RH_PORTSTAT(RH_PS_PES);
- OK(0);
- }
- break;
-
- case RH_SET_ADDRESS:
- gohci.rh.devnum = wValue;
- OK(0);
-
- case RH_GET_DESCRIPTOR:
- switch ((wValue & 0xff00) >> 8) {
- case (0x01): /* device descriptor */
- len = min_t(unsigned int,
- leni,
- min_t(unsigned int,
- sizeof(root_hub_dev_des), wLength));
- data_buf = root_hub_dev_des;
- OK(len);
- case (0x02): /* configuration descriptor */
- len = min_t(unsigned int,
- leni,
- min_t(unsigned int,
- sizeof(root_hub_config_des),
- wLength));
- data_buf = root_hub_config_des;
- OK(len);
- case (0x03): /* string descriptors */
- if (wValue == 0x0300) {
- len = min_t(unsigned int,
- leni,
- min_t(unsigned int,
- sizeof(root_hub_str_index0),
- wLength));
- data_buf = root_hub_str_index0;
- OK(len);
- }
- if (wValue == 0x0301) {
- len = min_t(unsigned int,
- leni,
- min_t(unsigned int,
- sizeof(root_hub_str_index1),
- wLength));
- data_buf = root_hub_str_index1;
- OK(len);
- }
- default:
- stat = USB_ST_STALLED;
- }
- break;
-
- case RH_GET_DESCRIPTOR | RH_CLASS:
- {
- __u32 temp = roothub_a(&gohci);
-
- data_buf[0] = 9; /* min length; */
- data_buf[1] = 0x29;
- data_buf[2] = temp & RH_A_NDP;
- data_buf[3] = 0;
- if (temp & RH_A_PSM)
- /* per-port power switching? */
- data_buf[3] |= 0x1;
- if (temp & RH_A_NOCP)
- /* no overcurrent reporting? */
- data_buf[3] |= 0x10;
- else if (temp & RH_A_OCPM)
- /* per-port overcurrent reporting? */
- data_buf[3] |= 0x8;
-
- /* corresponds to data_buf[4-7] */
- datab.word[1] = 0;
- data_buf[5] = (temp & RH_A_POTPGT) >> 24;
- temp = roothub_b(&gohci);
- data_buf[7] = temp & RH_B_DR;
- if (data_buf[2] < 7) {
- data_buf[8] = 0xff;
- } else {
- data_buf[0] += 2;
- data_buf[8] = (temp & RH_B_DR) >> 8;
- data_buf[10] = data_buf[9] = 0xff;
- }
-
- len = min_t(unsigned int, leni,
- min_t(unsigned int, data_buf[0], wLength));
- OK(len);
- }
-
- case RH_GET_CONFIGURATION:
- *(__u8 *) data_buf = 0x01;
- OK(1);
-
- case RH_SET_CONFIGURATION:
- WR_RH_STAT(0x10000);
- OK(0);
-
- default:
- dbg("unsupported root hub command");
- stat = USB_ST_STALLED;
- }
-
-#ifdef DEBUG
- ohci_dump_roothub(&gohci, 1);
-#else
- mdelay(1);
-#endif
-
- len = min_t(int, len, leni);
- if (data != data_buf)
- memcpy(data, data_buf, len);
- dev->act_len = len;
- dev->status = stat;
-
-#ifdef DEBUG
- if (transfer_len)
- urb_priv.actual_length = transfer_len;
- pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)",
- 0 /*usb_pipein(pipe) */);
-#else
- mdelay(1);
-#endif
-
- return stat;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* common code for handling submit messages - used for all but root hub */
-/* accesses. */
-int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int transfer_len, struct devrequest *setup, int interval)
-{
- int stat = 0;
- int maxsize = usb_maxpacket(dev, pipe);
- int timeout;
-
- /* device pulled? Shortcut the action. */
- if (devgone == dev) {
- dev->status = USB_ST_CRC_ERR;
- return 0;
- }
-#ifdef DEBUG
- urb_priv.actual_length = 0;
- pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB",
- usb_pipein(pipe));
-#else
- mdelay(1);
-#endif
- if (!maxsize) {
- err("submit_common_message: pipesize for pipe %lx is zero",
- pipe);
- return -1;
- }
-
- if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) <
- 0) {
- err("sohci_submit_job failed");
- return -1;
- }
-
- mdelay(10);
- /* ohci_dump_status(&gohci); */
-
- /* allow more time for a BULK device to react - some are slow */
-#define BULK_TO 5000 /* timeout in milliseconds */
- if (usb_pipebulk(pipe))
- timeout = BULK_TO;
- else
- timeout = 100;
-
- /* wait for it to complete */
- for (;;) {
- /* check whether the controller is done */
- stat = hc_interrupt();
-
- if (stat < 0) {
- stat = USB_ST_CRC_ERR;
- break;
- }
-
- /* NOTE: since we are not interrupt driven in U-Boot and always
- * handle only one URB at a time, we cannot assume the
- * transaction finished on the first successful return from
- * hc_interrupt().. unless the flag for current URB is set,
- * meaning that all TD's to/from device got actually
- * transferred and processed. If the current URB is not
- * finished we need to re-iterate this loop so as
- * hc_interrupt() gets called again as there needs to be some
- * more TD's to process still */
- if ((stat >= 0) && (stat != 0xff) && (urb_finished)) {
- /* 0xff is returned for an SF-interrupt */
- break;
- }
-
- if (--timeout) {
- mdelay(1);
- if (!urb_finished)
- dbg("\%");
-
- } else {
- err("CTL:TIMEOUT ");
- dbg("submit_common_msg: TO status %x\n", stat);
- stat = USB_ST_CRC_ERR;
- urb_finished = 1;
- break;
- }
- }
-
-#if 0
- /* we got an Root Hub Status Change interrupt */
- if (got_rhsc) {
-#ifdef DEBUG
- ohci_dump_roothub(&gohci, 1);
-#endif
- got_rhsc = 0;
- /* abuse timeout */
- timeout = rh_check_port_status(&gohci);
- if (timeout >= 0) {
-#if 0 /* this does nothing useful, but leave it here
- in case that changes */
- /* the called routine adds 1 to the passed value */
- usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
-#endif
- /*
- * XXX
- * This is potentially dangerous because it assumes
- * that only one device is ever plugged in!
- */
- devgone = dev;
- }
- }
-#endif
-
- dev->status = stat;
- dev->act_len = transfer_len;
-
-#ifdef DEBUG
- pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)",
- usb_pipein(pipe));
-#else
- mdelay(1);
-#endif
-
- /* free TDs in urb_priv */
- urb_free_priv(&urb_priv);
- return 0;
-}
-
-/* submit routines called from usb.c */
-int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int transfer_len)
-{
- info("submit_bulk_msg");
- return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
-}
-
-int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int transfer_len, struct devrequest *setup)
-{
- int maxsize = usb_maxpacket(dev, pipe);
-
- info("submit_control_msg");
-#ifdef DEBUG
- urb_priv.actual_length = 0;
- pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB",
- usb_pipein(pipe));
-#else
- mdelay(1);
-#endif
- if (!maxsize) {
- err("submit_control_message: pipesize for pipe %lx is zero",
- pipe);
- return -1;
- }
- if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
- gohci.rh.dev = dev;
- /* root hub - redirect */
- return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
- setup);
- }
-
- return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
-}
-
-int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int transfer_len, int interval)
-{
- info("submit_int_msg");
- return -1;
-}
-
-/*-------------------------------------------------------------------------*
- * HC functions
- *-------------------------------------------------------------------------*/
-
-/* reset the HC and BUS */
-
-static int hc_reset(struct ohci *ohci)
-{
- int timeout = 30;
- int smm_timeout = 50; /* 0,5 sec */
-
- if (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
- /* SMM owns the HC - request ownership */
- writel(OHCI_OCR, &ohci->regs->cmdstatus);
- info("USB HC TakeOver from SMM");
- while (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
- mdelay(10);
- if (--smm_timeout == 0) {
- err("USB HC TakeOver failed!");
- return -1;
- }
- }
- }
-
- /* Disable HC interrupts */
- writel(OHCI_INTR_MIE, &ohci->regs->intrdisable);
-
- dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;",
- ohci->slot_name, readl(&ohci->regs->control));
-
- /* Reset USB (needed by some controllers) */
- writel(0, &ohci->regs->control);
-
- /* HC Reset requires max 10 us delay */
- writel(OHCI_HCR, &ohci->regs->cmdstatus);
- while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
- if (--timeout == 0) {
- err("USB HC reset timed out!");
- return -1;
- }
- udelay(1);
- }
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* Start an OHCI controller, set the BUS operational
- * enable interrupts
- * connect the virtual root hub */
-
-static int hc_start(struct ohci *ohci)
-{
- __u32 mask;
- unsigned int fminterval;
-
- ohci->disabled = 1;
-
- /* Tell the controller where the control and bulk lists are
- * The lists are empty now. */
-
- writel(0, &ohci->regs->ed_controlhead);
- writel(0, &ohci->regs->ed_bulkhead);
-
- /* a reset clears this */
- writel((__u32) ohci->hcca, &ohci->regs->hcca);
-
- fminterval = 0x2edf;
- writel((fminterval * 9) / 10, &ohci->regs->periodicstart);
- fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
- writel(fminterval, &ohci->regs->fminterval);
- writel(0x628, &ohci->regs->lsthresh);
-
- /* start controller operations */
- ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
- ohci->disabled = 0;
- writel(ohci->hc_control, &ohci->regs->control);
-
- /* disable all interrupts */
- mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
- OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
- OHCI_INTR_OC | OHCI_INTR_MIE);
- writel(mask, &ohci->regs->intrdisable);
- /* clear all interrupts */
- mask &= ~OHCI_INTR_MIE;
- writel(mask, &ohci->regs->intrstatus);
- /* Choose the interrupts we care about now - but w/o MIE */
- mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
- writel(mask, &ohci->regs->intrenable);
-
-#ifdef OHCI_USE_NPS
- /* required for AMD-756 and some Mac platforms */
- writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM,
- &ohci->regs->roothub.a);
- writel(RH_HS_LPSC, &ohci->regs->roothub.status);
-#endif /* OHCI_USE_NPS */
-
- /* POTPGT delay is bits 24-31, in 2 ms units. */
- mdelay((roothub_a(ohci) >> 23) & 0x1fe);
-
- /* connect the virtual root hub */
- ohci->rh.devnum = 0;
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* an interrupt happens */
-
-static int hc_interrupt(void)
-{
- struct ohci *ohci = &gohci;
- struct ohci_regs *regs = ohci->regs;
- int ints;
- int stat = -1;
-
- if ((ohci->hcca->done_head != 0) &&
- !(m32_swap(ohci->hcca->done_head) & 0x01)) {
-
- ints = OHCI_INTR_WDH;
-
- } else {
- ints = readl(&regs->intrstatus);
- if (ints == ~(u32) 0) {
- ohci->disabled++;
- err("%s device removed!", ohci->slot_name);
- return -1;
- }
- ints &= readl(&regs->intrenable);
- if (ints == 0) {
- dbg("hc_interrupt: returning..\n");
- return 0xff;
- }
- }
-
- /* dbg("Interrupt: %x frame: %x", ints,
- le16_to_cpu(ohci->hcca->frame_no)); */
-
- if (ints & OHCI_INTR_RHSC) {
- got_rhsc = 1;
- stat = 0xff;
- }
-
- if (ints & OHCI_INTR_UE) {
- ohci->disabled++;
- err("OHCI Unrecoverable Error, controller usb-%s disabled",
- ohci->slot_name);
- /* e.g. due to PCI Master/Target Abort */
-
-#ifdef DEBUG
- ohci_dump(ohci, 1);
-#else
- mdelay(1);
-#endif
- /* FIXME: be optimistic, hope that bug won't repeat often. */
- /* Make some non-interrupt context restart the controller. */
- /* Count and limit the retries though; either hardware or */
- /* software errors can go forever... */
- hc_reset(ohci);
- return -1;
- }
-
- if (ints & OHCI_INTR_WDH) {
- mdelay(1);
-
- writel(OHCI_INTR_WDH, &regs->intrdisable);
- stat = dl_done_list(&gohci, dl_reverse_done_list(&gohci));
- writel(OHCI_INTR_WDH, &regs->intrenable);
- }
-
- if (ints & OHCI_INTR_SO) {
- dbg("USB Schedule overrun\n");
- writel(OHCI_INTR_SO, &regs->intrenable);
- stat = -1;
- }
-
- /* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
- if (ints & OHCI_INTR_SF) {
- unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1;
- mdelay(1);
- writel(OHCI_INTR_SF, &regs->intrdisable);
- if (ohci->ed_rm_list[frame] != NULL)
- writel(OHCI_INTR_SF, &regs->intrenable);
- stat = 0xff;
- }
-
- writel(ints, &regs->intrstatus);
- return stat;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-
-/* De-allocate all resources.. */
-
-static void hc_release_ohci(struct ohci *ohci)
-{
- dbg("USB HC release ohci usb-%s", ohci->slot_name);
-
- if (!ohci->disabled)
- hc_reset(ohci);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * low level initalisation routine, called from usb.c
- */
-static char ohci_inited = 0;
-
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
-{
- struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
- struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
-
- /*
- * Set the 48 MHz UPLL clocking. Values are taken from
- * "PLL value selection guide", 6-23, s3c2400_UM.pdf.
- */
- clk_power->upllcon = ((40 << 12) + (1 << 4) + 2);
- gpio->misccr |= 0x8; /* 1 = use pads related USB for USB host */
-
- /*
- * Enable USB host clock.
- */
- clk_power->clkcon |= (1 << 4);
-
- memset(&gohci, 0, sizeof(struct ohci));
- memset(&urb_priv, 0, sizeof(struct urb_priv));
-
- /* align the storage */
- if ((__u32) &ghcca[0] & 0xff) {
- err("HCCA not aligned!!");
- return -1;
- }
- phcca = &ghcca[0];
- info("aligned ghcca %p", phcca);
- memset(&ohci_dev, 0, sizeof(struct ohci_device));
- if ((__u32) &ohci_dev.ed[0] & 0x7) {
- err("EDs not aligned!!");
- return -1;
- }
- memset(gtd, 0, sizeof(struct td) * (NUM_TD + 1));
- if ((__u32) gtd & 0x7) {
- err("TDs not aligned!!");
- return -1;
- }
- ptd = gtd;
- gohci.hcca = phcca;
- memset(phcca, 0, sizeof(struct ohci_hcca));
-
- gohci.disabled = 1;
- gohci.sleeping = 0;
- gohci.irq = -1;
- gohci.regs = (struct ohci_regs *)S3C24X0_USB_HOST_BASE;
-
- gohci.flags = 0;
- gohci.slot_name = "s3c2400";
-
- if (hc_reset(&gohci) < 0) {
- hc_release_ohci(&gohci);
- /* Initialization failed */
- clk_power->clkcon &= ~(1 << 4);
- return -1;
- }
-
- /* FIXME this is a second HC reset; why?? */
- gohci.hc_control = OHCI_USB_RESET;
- writel(gohci.hc_control, &gohci.regs->control);
- mdelay(10);
-
- if (hc_start(&gohci) < 0) {
- err("can't start usb-%s", gohci.slot_name);
- hc_release_ohci(&gohci);
- /* Initialization failed */
- clk_power->clkcon &= ~(1 << 4);
- return -1;
- }
-#ifdef DEBUG
- ohci_dump(&gohci, 1);
-#else
- mdelay(1);
-#endif
- ohci_inited = 1;
- urb_finished = 1;
-
- return 0;
-}
-
-int usb_lowlevel_stop(int index)
-{
- struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
-
- /* this gets called really early - before the controller has */
- /* even been initialized! */
- if (!ohci_inited)
- return 0;
- /* TODO release any interrupts, etc. */
- /* call hc_release_ohci() here ? */
- hc_reset(&gohci);
- /* may not want to do this */
- clk_power->clkcon &= ~(1 << 4);
- return 0;
-}
-
-#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_S3C24X0) */
-
-#if defined(CONFIG_USB_OHCI_NEW) && \
- defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \
- defined(CONFIG_S3C24X0)
-
-int usb_cpu_init(void)
-{
- struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
- struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
-
- /*
- * Set the 48 MHz UPLL clocking. Values are taken from
- * "PLL value selection guide", 6-23, s3c2400_UM.pdf.
- */
- writel((40 << 12) + (1 << 4) + 2, &clk_power->upllcon);
- /* 1 = use pads related USB for USB host */
- writel(readl(&gpio->misccr) | 0x8, &gpio->misccr);
-
- /*
- * Enable USB host clock.
- */
- writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
-
- return 0;
-}
-
-int usb_cpu_stop(void)
-{
- struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
- /* may not want to do this */
- writel(readl(&clk_power->clkcon) & ~(1 << 4), &clk_power->clkcon);
- return 0;
-}
-
-int usb_cpu_init_fail(void)
-{
- struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
- writel(readl(&clk_power->clkcon) & ~(1 << 4), &clk_power->clkcon);
- return 0;
-}
-
-#endif /* defined(CONFIG_USB_OHCI_NEW) && \
- defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \
- defined(CONFIG_S3C24X0) */
diff --git a/drivers/usb/host/ohci-s3c24xx.h b/drivers/usb/host/ohci-s3c24xx.h
deleted file mode 100644
index f272d78859..0000000000
--- a/drivers/usb/host/ohci-s3c24xx.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * URB OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
- *
- * usb-ohci.h
- */
-
-
-static int cc_to_error[16] = {
-
-/* mapping of the OHCI CC status to error codes */
- /* No Error */ 0,
- /* CRC Error */ USB_ST_CRC_ERR,
- /* Bit Stuff */ USB_ST_BIT_ERR,
- /* Data Togg */ USB_ST_CRC_ERR,
- /* Stall */ USB_ST_STALLED,
- /* DevNotResp */ -1,
- /* PIDCheck */ USB_ST_BIT_ERR,
- /* UnExpPID */ USB_ST_BIT_ERR,
- /* DataOver */ USB_ST_BUF_ERR,
- /* DataUnder */ USB_ST_BUF_ERR,
- /* reservd */ -1,
- /* reservd */ -1,
- /* BufferOver */ USB_ST_BUF_ERR,
- /* BuffUnder */ USB_ST_BUF_ERR,
- /* Not Access */ -1,
- /* Not Access */ -1
-};
-
-/* ED States */
-#define ED_NEW 0x00
-#define ED_UNLINK 0x01
-#define ED_OPER 0x02
-#define ED_DEL 0x04
-#define ED_URB_DEL 0x08
-
-/* usb_ohci_ed */
-struct ed {
- __u32 hwINFO;
- __u32 hwTailP;
- __u32 hwHeadP;
- __u32 hwNextED;
-
- struct ed *ed_prev;
- __u8 int_period;
- __u8 int_branch;
- __u8 int_load;
- __u8 int_interval;
- __u8 state;
- __u8 type;
- __u16 last_iso;
- struct ed *ed_rm_list;
-
- struct usb_device *usb_dev;
- __u32 unused[3];
-} __attribute__ ((aligned(16)));
-
-/* TD info field */
-#define TD_CC 0xf0000000
-#define TD_CC_GET(td_p) (((td_p) >> 28) & 0x0f)
-#define TD_CC_SET(td_p, cc) \
- {(td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)}
-#define TD_EC 0x0C000000
-#define TD_T 0x03000000
-#define TD_T_DATA0 0x02000000
-#define TD_T_DATA1 0x03000000
-#define TD_T_TOGGLE 0x00000000
-#define TD_R 0x00040000
-#define TD_DI 0x00E00000
-#define TD_DI_SET(X) (((X) & 0x07)<< 21)
-#define TD_DP 0x00180000
-#define TD_DP_SETUP 0x00000000
-#define TD_DP_IN 0x00100000
-#define TD_DP_OUT 0x00080000
-
-#define TD_ISO 0x00010000
-#define TD_DEL 0x00020000
-
-/* CC Codes */
-#define TD_CC_NOERROR 0x00
-#define TD_CC_CRC 0x01
-#define TD_CC_BITSTUFFING 0x02
-#define TD_CC_DATATOGGLEM 0x03
-#define TD_CC_STALL 0x04
-#define TD_DEVNOTRESP 0x05
-#define TD_PIDCHECKFAIL 0x06
-#define TD_UNEXPECTEDPID 0x07
-#define TD_DATAOVERRUN 0x08
-#define TD_DATAUNDERRUN 0x09
-#define TD_BUFFEROVERRUN 0x0C
-#define TD_BUFFERUNDERRUN 0x0D
-#define TD_NOTACCESSED 0x0F
-
-
-#define MAXPSW 1
-
-struct td {
- __u32 hwINFO;
- __u32 hwCBP; /* Current Buffer Pointer */
- __u32 hwNextTD; /* Next TD Pointer */
- __u32 hwBE; /* Memory Buffer End Pointer */
-
- __u8 unused;
- __u8 index;
- struct ed *ed;
- struct td *next_dl_td;
- struct usb_device *usb_dev;
- int transfer_len;
- __u32 data;
-
- __u32 unused2[2];
-} __attribute__ ((aligned(32)));
-
-#define OHCI_ED_SKIP (1 << 14)
-
-/*
- * The HCCA (Host Controller Communications Area) is a 256 byte
- * structure defined in the OHCI spec. that the host controller is
- * told the base address of. It must be 256-byte aligned.
- */
-
-#define NUM_INTS 32 /* part of the OHCI standard */
-struct ohci_hcca {
- __u32 int_table[NUM_INTS]; /* Interrupt ED table */
- __u16 frame_no; /* current frame number */
- __u16 pad1; /* set to 0 on each frame_no change */
- __u32 done_head; /* info returned for an interrupt */
- u8 reserved_for_hc[116];
-} __attribute__ ((aligned(256)));
-
-/*
- * Maximum number of root hub ports.
- */
-#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
-
-/*
- * This is the structure of the OHCI controller's memory mapped I/O
- * region. This is Memory Mapped I/O. You must use the readl() and
- * writel() macros defined in asm/io.h to access these!!
- */
-struct ohci_regs {
- /* control and status registers */
- __u32 revision;
- __u32 control;
- __u32 cmdstatus;
- __u32 intrstatus;
- __u32 intrenable;
- __u32 intrdisable;
- /* memory pointers */
- __u32 hcca;
- __u32 ed_periodcurrent;
- __u32 ed_controlhead;
- __u32 ed_controlcurrent;
- __u32 ed_bulkhead;
- __u32 ed_bulkcurrent;
- __u32 donehead;
- /* frame counters */
- __u32 fminterval;
- __u32 fmremaining;
- __u32 fmnumber;
- __u32 periodicstart;
- __u32 lsthresh;
- /* Root hub ports */
- struct ohci_roothub_regs {
- __u32 a;
- __u32 b;
- __u32 status;
- __u32 portstatus[MAX_ROOT_PORTS];
- } roothub;
-} __attribute__ ((aligned(32)));
-
-/* OHCI CONTROL AND STATUS REGISTER MASKS */
-
-/*
- * HcControl (control) register masks
- */
-#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
-#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
-#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
-#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
-#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
-#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
-#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
-#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
-#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
-
-/* pre-shifted values for HCFS */
-# define OHCI_USB_RESET (0 << 6)
-# define OHCI_USB_RESUME (1 << 6)
-# define OHCI_USB_OPER (2 << 6)
-# define OHCI_USB_SUSPEND (3 << 6)
-
-/*
- * HcCommandStatus (cmdstatus) register masks
- */
-#define OHCI_HCR (1 << 0) /* host controller reset */
-#define OHCI_CLF (1 << 1) /* control list filled */
-#define OHCI_BLF (1 << 2) /* bulk list filled */
-#define OHCI_OCR (1 << 3) /* ownership change request */
-#define OHCI_SOC (3 << 16) /* scheduling overrun count */
-
-/*
- * masks used with interrupt registers:
- * HcInterruptStatus (intrstatus)
- * HcInterruptEnable (intrenable)
- * HcInterruptDisable (intrdisable)
- */
-#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
-#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
-#define OHCI_INTR_SF (1 << 2) /* start frame */
-#define OHCI_INTR_RD (1 << 3) /* resume detect */
-#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
-#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
-#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
-#define OHCI_INTR_OC (1 << 30) /* ownership change */
-#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
-
-/* Virtual Root HUB */
-struct virt_root_hub {
- int devnum; /* Address of Root Hub endpoint */
- void *dev; /* was urb */
- void *int_addr;
- int send;
- int interval;
-};
-
-/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
-
-/* destination of request */
-#define RH_INTERFACE 0x01
-#define RH_ENDPOINT 0x02
-#define RH_OTHER 0x03
-
-#define RH_CLASS 0x20
-#define RH_VENDOR 0x40
-
-/* Requests: bRequest << 8 | bmRequestType */
-#define RH_GET_STATUS 0x0080
-#define RH_CLEAR_FEATURE 0x0100
-#define RH_SET_FEATURE 0x0300
-#define RH_SET_ADDRESS 0x0500
-#define RH_GET_DESCRIPTOR 0x0680
-#define RH_SET_DESCRIPTOR 0x0700
-#define RH_GET_CONFIGURATION 0x0880
-#define RH_SET_CONFIGURATION 0x0900
-#define RH_GET_STATE 0x0280
-#define RH_GET_INTERFACE 0x0A80
-#define RH_SET_INTERFACE 0x0B00
-#define RH_SYNC_FRAME 0x0C80
-/* Our Vendor Specific Request */
-#define RH_SET_EP 0x2000
-
-
-/* Hub port features */
-#define RH_PORT_CONNECTION 0x00
-#define RH_PORT_ENABLE 0x01
-#define RH_PORT_SUSPEND 0x02
-#define RH_PORT_OVER_CURRENT 0x03
-#define RH_PORT_RESET 0x04
-#define RH_PORT_POWER 0x08
-#define RH_PORT_LOW_SPEED 0x09
-
-#define RH_C_PORT_CONNECTION 0x10
-#define RH_C_PORT_ENABLE 0x11
-#define RH_C_PORT_SUSPEND 0x12
-#define RH_C_PORT_OVER_CURRENT 0x13
-#define RH_C_PORT_RESET 0x14
-
-/* Hub features */
-#define RH_C_HUB_LOCAL_POWER 0x00
-#define RH_C_HUB_OVER_CURRENT 0x01
-
-#define RH_DEVICE_REMOTE_WAKEUP 0x00
-#define RH_ENDPOINT_STALL 0x01
-
-#define RH_ACK 0x01
-#define RH_REQ_ERR -1
-#define RH_NACK 0x00
-
-
-/* OHCI ROOT HUB REGISTER MASKS */
-
-/* roothub.portstatus [i] bits */
-#define RH_PS_CCS 0x00000001 /* current connect status */
-#define RH_PS_PES 0x00000002 /* port enable status */
-#define RH_PS_PSS 0x00000004 /* port suspend status */
-#define RH_PS_POCI 0x00000008 /* port over current indicator */
-#define RH_PS_PRS 0x00000010 /* port reset status */
-#define RH_PS_PPS 0x00000100 /* port power status */
-#define RH_PS_LSDA 0x00000200 /* low speed device attached */
-#define RH_PS_CSC 0x00010000 /* connect status change */
-#define RH_PS_PESC 0x00020000 /* port enable status change */
-#define RH_PS_PSSC 0x00040000 /* port suspend status change */
-#define RH_PS_OCIC 0x00080000 /* over current indicator change */
-#define RH_PS_PRSC 0x00100000 /* port reset status change */
-
-/* roothub.status bits */
-#define RH_HS_LPS 0x00000001 /* local power status */
-#define RH_HS_OCI 0x00000002 /* over current indicator */
-#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
-#define RH_HS_LPSC 0x00010000 /* local power status change */
-#define RH_HS_OCIC 0x00020000 /* over current indicator change */
-#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
-
-/* roothub.b masks */
-#define RH_B_DR 0x0000ffff /* device removable flags */
-#define RH_B_PPCM 0xffff0000 /* port power control mask */
-
-/* roothub.a masks */
-#define RH_A_NDP (0xff << 0) /* number of downstream ports */
-#define RH_A_PSM (1 << 8) /* power switching mode */
-#define RH_A_NPS (1 << 9) /* no power switching */
-#define RH_A_DT (1 << 10) /* device type (mbz) */
-#define RH_A_OCPM (1 << 11) /* over current protection mode */
-#define RH_A_NOCP (1 << 12) /* no over current protection */
-#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
-
-/* urb */
-#define N_URB_TD 48
-struct urb_priv {
- struct ed *ed;
- __u16 length; /* number of tds associated with this request */
- __u16 td_cnt; /* number of tds already serviced */
- int state;
- unsigned long pipe;
- int actual_length;
- struct td *td[N_URB_TD]; /* list pointer to all corresponding TDs
- associated with this request */
-};
-#define URB_DEL 1
-
-/*
- * This is the full ohci controller description
- *
- * Note how the "proper" USB information is just
- * a subset of what the full implementation needs. (Linus)
- */
-
-
-struct ohci {
- struct ohci_hcca *hcca; /* hcca */
- /*dma_addr_t hcca_dma; */
-
- int irq;
- int disabled; /* e.g. got a UE, we're hung */
- int sleeping;
- unsigned long flags; /* for HC bugs */
-
- struct ohci_regs *regs; /* OHCI controller's memory */
-
- struct ed *ed_rm_list[2]; /* lists of all endpoints to be removed */
- struct ed *ed_bulktail; /* last endpoint of bulk list */
- struct ed *ed_controltail; /* last endpoint of control list */
- int intrstatus;
- __u32 hc_control; /* copy of the hc control reg */
- struct usb_device *dev[32];
- struct virt_root_hub rh;
-
- const char *slot_name;
-};
-
-#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
-
-struct ohci_device {
- struct ed ed[NUM_EDS];
- int ed_cnt;
-};
-
-/* hcd */
-/* endpoint */
-static int ep_link(struct ohci *ohci, struct ed *ed);
-static int ep_unlink(struct ohci *ohci, struct ed *ed);
-static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe);
-
-/*-------------------------------------------------------------------------*/
-
-/* we need more TDs than EDs */
-#define NUM_TD 64
-
-/* +1 so we can align the storage */
-struct td gtd[NUM_TD + 1];
-
-/* pointers to aligned storage */
-struct td *ptd;
-
-/* TDs ... */
-static inline struct td *td_alloc(struct usb_device *usb_dev)
-{
- int i;
- struct td *td;
-
- td = NULL;
- for (i = 0; i < NUM_TD; i++) {
- if (ptd[i].usb_dev == NULL) {
- td = &ptd[i];
- td->usb_dev = usb_dev;
- break;
- }
- }
-
- return td;
-}
-
-static inline void ed_free(struct ed *ed)
-{
- ed->usb_dev = NULL;
-}
diff --git a/drivers/usb/host/ohci-sunxi.c b/drivers/usb/host/ohci-sunxi.c
index 0c45eec04a..133774f6e6 100644
--- a/drivers/usb/host/ohci-sunxi.c
+++ b/drivers/usb/host/ohci-sunxi.c
@@ -37,7 +37,7 @@ static int ohci_usb_probe(struct udevice *dev)
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct usb_bus_priv *bus_priv = dev_get_uclass_priv(dev);
struct ohci_sunxi_priv *priv = dev_get_priv(dev);
- struct ohci_regs *regs = (struct ohci_regs *)dev_get_addr(dev);
+ struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
int extra_ahb_gate_mask = 0;
bus_priv->companion = true;
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index db0924c943..2350831932 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -115,9 +115,7 @@ struct td {
__u32 hwNextTD; /* Next TD Pointer */
__u32 hwBE; /* Memory Buffer End Pointer */
-/* #ifndef CONFIG_MPC5200 /\* this seems wrong *\/ */
__u16 hwPSW[MAXPSW];
-/* #endif */
__u8 unused;
__u8 index;
struct ed *ed;
@@ -141,13 +139,8 @@ typedef struct td td_t;
#define NUM_INTS 32 /* part of the OHCI standard */
struct ohci_hcca {
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
-#if defined(CONFIG_MPC5200)
- __u16 pad1; /* set to 0 on each frame_no change */
- __u16 frame_no; /* current frame number */
-#else
__u16 frame_no; /* current frame number */
__u16 pad1; /* set to 0 on each frame_no change */
-#endif
__u32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc[116];
} __attribute__((aligned(256)));
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 6eded4abad..110ddc92fa 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -683,20 +683,18 @@ int usb_detect_change(void)
int usb_child_post_bind(struct udevice *dev)
{
struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
- const void *blob = gd->fdt_blob;
int val;
- if (dev_of_offset(dev) == -1)
+ if (!dev_of_valid(dev))
return 0;
/* We only support matching a few things */
- val = fdtdec_get_int(blob, dev_of_offset(dev), "usb,device-class", -1);
+ val = dev_read_u32_default(dev, "usb,device-class", -1);
if (val != -1) {
plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS;
plat->id.bDeviceClass = val;
}
- val = fdtdec_get_int(blob, dev_of_offset(dev), "usb,interface-class",
- -1);
+ val = dev_read_u32_default(dev, "usb,interface-class", -1);
if (val != -1) {
plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
plat->id.bInterfaceClass = val;
diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index b3f48b34e2..bf7286554e 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -61,7 +61,7 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
/*
* Get the base address for XHCI controller from the device node
*/
- plat->hcd_base = dev_get_addr(dev);
+ plat->hcd_base = devfdt_get_addr(dev);
if (plat->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the XHCI register base address\n");
return -ENXIO;
diff --git a/drivers/usb/host/xhci-fsl.c b/drivers/usb/host/xhci-fsl.c
index 3a16624713..f77c78d422 100644
--- a/drivers/usb/host/xhci-fsl.c
+++ b/drivers/usb/host/xhci-fsl.c
@@ -122,7 +122,7 @@ static int xhci_fsl_probe(struct udevice *dev)
/*
* Get the base address for XHCI controller from the device node
*/
- priv->hcd_base = dev_get_addr(dev);
+ priv->hcd_base = devfdt_get_addr(dev);
if (priv->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the XHCI register base address\n");
return -ENXIO;
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index d880af1113..b9201a5a6a 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -74,7 +74,7 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
/*
* Get the base address for XHCI controller from the device node
*/
- plat->hcd_base = dev_get_addr(dev);
+ plat->hcd_base = devfdt_get_addr(dev);
if (plat->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the XHCI register base address\n");
return -ENXIO;
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index f559830185..c4ae55fc39 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -11,10 +11,10 @@
#include <malloc.h>
#include <usb.h>
#include <watchdog.h>
-#include <asm/gpio.h>
#include <linux/errno.h>
#include <linux/compat.h>
#include <linux/usb/dwc3.h>
+#include <power/regulator.h>
#include "xhci.h"
@@ -23,7 +23,7 @@ DECLARE_GLOBAL_DATA_PTR;
struct rockchip_xhci_platdata {
fdt_addr_t hcd_base;
fdt_addr_t phy_base;
- struct gpio_desc vbus_gpio;
+ struct udevice *vbus_supply;
};
/*
@@ -46,7 +46,7 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
/*
* Get the base address for XHCI controller from the device node
*/
- plat->hcd_base = dev_get_addr(dev);
+ plat->hcd_base = devfdt_get_addr(dev);
if (plat->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the XHCI register base address\n");
return -ENXIO;
@@ -55,9 +55,9 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
/* Get the base address for usbphy from the device node */
for (device_find_first_child(dev, &child); child;
device_find_next_child(&child)) {
- if (!of_device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
+ if (!device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
continue;
- plat->phy_base = dev_get_addr(child);
+ plat->phy_base = devfdt_get_addr(child);
break;
}
@@ -66,11 +66,13 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
return -ENXIO;
}
- /* Vbus gpio */
- ret = gpio_request_by_name(dev, "rockchip,vbus-gpio", 0,
- &plat->vbus_gpio, GPIOD_IS_OUT);
+#if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
+ /* Vbus regulator */
+ ret = device_get_supply_regulator(dev, "vbus-supply",
+ &plat->vbus_supply);
if (ret)
- debug("rockchip,vbus-gpio node missing!");
+ debug("Can't get vbus supply\n");
+#endif
return 0;
}
@@ -153,9 +155,11 @@ static int xhci_usb_probe(struct udevice *dev)
hcor = (struct xhci_hcor *)((uint64_t)ctx->hcd +
HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
- /* setup the Vbus gpio here */
- if (dm_gpio_is_valid(&plat->vbus_gpio))
- dm_gpio_set_value(&plat->vbus_gpio, 1);
+#if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
+ ret = regulator_set_enable(plat->vbus_supply, true);
+ if (ret)
+ debug("XHCI: Failed to enable vbus supply\n");
+#endif
ret = rockchip_xhci_core_init(ctx, dev);
if (ret) {
@@ -168,6 +172,7 @@ static int xhci_usb_probe(struct udevice *dev)
static int xhci_usb_remove(struct udevice *dev)
{
+ struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
struct rockchip_xhci *ctx = dev_get_priv(dev);
int ret;
@@ -178,11 +183,18 @@ static int xhci_usb_remove(struct udevice *dev)
if (ret)
return ret;
+#if defined(CONFIG_DM_USB) && defined(CONFIG_DM_REGULATOR)
+ ret = regulator_set_enable(plat->vbus_supply, false);
+ if (ret)
+ debug("XHCI: Failed to disable vbus supply\n");
+#endif
+
return 0;
}
static const struct udevice_id xhci_usb_ids[] = {
{ .compatible = "rockchip,rk3399-xhci" },
+ { .compatible = "rockchip,rk3328-xhci" },
{ }
};
@@ -202,6 +214,7 @@ U_BOOT_DRIVER(usb_xhci) = {
static const struct udevice_id usb_phy_ids[] = {
{ .compatible = "rockchip,rk3399-usb3-phy" },
+ { .compatible = "rockchip,rk3328-usb3-phy" },
{ }
};
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index 469377fe4e..5c1a902e42 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -17,6 +17,7 @@
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
+#include <dm.h>
#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c
index 852f07facc..de101319cd 100644
--- a/drivers/usb/musb-new/ti-musb.c
+++ b/drivers/usb/musb-new/ti-musb.c
@@ -88,7 +88,7 @@ static int ti_musb_ofdata_to_platdata(struct udevice *dev)
int ctrl_mod;
int usb_index;
- platdata->base = (void *)dev_get_addr_index(dev, 1);
+ platdata->base = (void *)devfdt_get_addr_index(dev, 1);
phys = fdtdec_lookup_phandle(fdt, node, "phys");
ctrl_mod = fdtdec_lookup_phandle(fdt, phys, "ti,ctrl_mod");
@@ -227,7 +227,7 @@ static int ti_musb_wrapper_bind(struct udevice *parent)
case USB_DR_MODE_HOST:
/* Bind MUSB host */
ret = device_bind_driver_to_node(parent, "ti-musb-host",
- name, node, &dev);
+ name, offset_to_ofnode(node), &dev);
if (ret) {
error("musb - not able to bind usb host node\n");
return ret;
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 58f5de5200..ac5371f2ae 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_CFB_CONSOLE) += cfb_console.o
obj-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
obj-$(CONFIG_VIDEO_FSL_DCU_FB) += fsl_dcu_fb.o videomodes.o
obj-$(CONFIG_L5F31188) += l5f31188.o
-obj-$(CONFIG_MPC8XX_LCD) += mpc8xx_lcd.o
obj-$(CONFIG_PXA_LCD) += pxa_lcd.o
obj-$(CONFIG_SCF0403_LCD) += scf0403_lcd.o
obj-$(CONFIG_S6E8AX0) += s6e8ax0.o
diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c
index 59b9c45616..f77da2ec97 100644
--- a/drivers/video/atmel_hlcdfb.c
+++ b/drivers/video/atmel_hlcdfb.c
@@ -426,7 +426,9 @@ static void atmel_hlcdc_init(struct udevice *dev)
writel(~0UL, &regs->lcdc_baseidr);
/* Setup the DMA descriptor, this descriptor will loop to itself */
- desc = (struct lcd_dma_desc *)(uc_plat->base - 16);
+ desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc));
+ if (!desc)
+ return;
desc->address = (u32)uc_plat->base;
@@ -436,7 +438,9 @@ static void atmel_hlcdc_init(struct udevice *dev)
desc->next = (u32)desc;
/* Flush the DMA descriptor if we enabled dcache */
- flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc));
+ flush_dcache_range((u32)desc,
+ ALIGN(((u32)desc + sizeof(*desc)),
+ CONFIG_SYS_CACHELINE_SIZE));
writel(desc->address, &regs->lcdc_baseaddr);
writel(desc->control, &regs->lcdc_basectrl);
@@ -497,15 +501,15 @@ static int atmel_hlcdc_ofdata_to_platdata(struct udevice *dev)
{
struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
const void *blob = gd->fdt_blob;
- int node = dev->of_offset;
+ int node = dev_of_offset(dev);
- priv->regs = (struct atmel_hlcd_regs *)dev_get_addr(dev);
+ priv->regs = (struct atmel_hlcd_regs *)devfdt_get_addr(dev);
if (!priv->regs) {
debug("%s: No display controller address\n", __func__);
return -EINVAL;
}
- if (fdtdec_decode_display_timing(blob, dev->of_offset,
+ if (fdtdec_decode_display_timing(blob, dev_of_offset(dev),
0, &priv->timing)) {
debug("%s: Failed to decode display timing\n", __func__);
return -EINVAL;
diff --git a/drivers/video/exynos/exynos_dp.c b/drivers/video/exynos/exynos_dp.c
index c5039e7b43..092342e7ad 100644
--- a/drivers/video/exynos/exynos_dp.c
+++ b/drivers/video/exynos/exynos_dp.c
@@ -6,7 +6,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <config.h>
+#include <common.h>
#include <dm.h>
#include <common.h>
#include <display.h>
@@ -883,7 +883,7 @@ static int exynos_dp_ofdata_to_platdata(struct udevice *dev)
unsigned int node = dev_of_offset(dev);
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE) {
debug("Can't get the DP base address\n");
return -EINVAL;
diff --git a/drivers/video/exynos/exynos_fb.c b/drivers/video/exynos/exynos_fb.c
index 46320e7f02..6ca17f2db2 100644
--- a/drivers/video/exynos/exynos_fb.c
+++ b/drivers/video/exynos/exynos_fb.c
@@ -486,7 +486,7 @@ int exynos_fb_ofdata_to_platdata(struct udevice *dev)
const void *blob = gd->fdt_blob;
fdt_addr_t addr;
- addr = dev_get_addr(dev);
+ addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE) {
debug("Can't get the FIMD base address\n");
return -EINVAL;
diff --git a/drivers/video/mpc8xx_lcd.c b/drivers/video/mpc8xx_lcd.c
deleted file mode 100644
index b08576eab2..0000000000
--- a/drivers/video/mpc8xx_lcd.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * (C) Copyright 2001-2002
- * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/************************************************************************/
-/* ** HEADER FILES */
-/************************************************************************/
-
-/* #define DEBUG */
-
-#include <config.h>
-#include <common.h>
-#include <command.h>
-#include <watchdog.h>
-#include <stdarg.h>
-#include <lcdvideo.h>
-#include <linux/types.h>
-#include <stdio_dev.h>
-#if defined(CONFIG_POST)
-#include <post.h>
-#endif
-#include <lcd.h>
-
-#ifdef CONFIG_LCD
-
-/************************************************************************/
-/* ** CONFIG STUFF -- should be moved to board config file */
-/************************************************************************/
-#ifndef CONFIG_LCD_INFO
-#define CONFIG_LCD_INFO /* Display Logo, (C) and system info */
-#endif
-
-/*----------------------------------------------------------------------*/
-#ifdef CONFIG_KYOCERA_KCS057QV1AJ
-/*
- * Kyocera KCS057QV1AJ-G23. Passive, color, single scan.
- */
-#define LCD_BPP LCD_COLOR4
-
-vidinfo_t panel_info = {
- 640, 480, 132, 99, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH,
- LCD_BPP, 1, 0, 1, 0, 5, 0, 0, 0
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_KYOCERA_KCS057QV1AJ */
-/*----------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------*/
-#ifdef CONFIG_HITACHI_SP19X001_Z1A
-/*
- * Hitachi SP19X001-. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 154, 116, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH,
- LCD_COLOR8, 1, 0, 1, 0, 0, 0, 0, 0
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_HITACHI_SP19X001_Z1A */
-/*----------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------*/
-#ifdef CONFIG_NEC_NL6448AC33
-/*
- * NEC NL6448AC33-18. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 132, 99, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 144, 2, 0, 33
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_NEC_NL6448AC33 */
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_NEC_NL6448BC20
-/*
- * NEC NL6448BC20-08. 6.5", 640x480. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 132, 99, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 144, 2, 0, 33
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_NEC_NL6448BC20 */
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_NEC_NL6448BC33_54
-/*
- * NEC NL6448BC33-54. 10.4", 640x480. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 212, 158, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 144, 2, 0, 33
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_NEC_NL6448BC33_54 */
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_SHARP_LQ104V7DS01
-/*
- * SHARP LQ104V7DS01. 6.5", 640x480. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 132, 99, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_LOW,
- 3, 0, 0, 1, 1, 25, 1, 0, 33
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_SHARP_LQ104V7DS01 */
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_SHARP_16x9
-/*
- * Sharp 320x240. Active, color, single scan. It isn't 16x9, and I am
- * not sure what it is.......
- */
-vidinfo_t panel_info = {
- 320, 240, 0, 0, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 15, 4, 0, 3
-};
-#endif /* CONFIG_SHARP_16x9 */
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_SHARP_LQ057Q3DC02
-/*
- * Sharp LQ057Q3DC02 display. Active, color, single scan.
- */
-#undef LCD_DF
-#define LCD_DF 12
-
-vidinfo_t panel_info = {
- 320, 240, 0, 0, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 15, 4, 0, 3
- /* wbl, vpw, lcdac, wbf */
-};
-#define CONFIG_LCD_INFO_BELOW_LOGO
-#endif /* CONFIG_SHARP_LQ057Q3DC02 */
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_SHARP_LQ64D341
-/*
- * Sharp LQ64D341 display, 640x480. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 0, 0, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 128, 16, 0, 32
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_SHARP_LQ64D341 */
-
-#ifdef CONFIG_SHARP_LQ065T9DR51U
-/*
- * Sharp LQ065T9DR51U display, 400x240. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 400, 240, 143, 79, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 248, 4, 0, 35
- /* wbl, vpw, lcdac, wbf */
-};
-#define CONFIG_LCD_INFO_BELOW_LOGO
-#endif /* CONFIG_SHARP_LQ065T9DR51U */
-
-#ifdef CONFIG_SHARP_LQ084V1DG21
-/*
- * Sharp LQ084V1DG21 display, 640x480. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 171, 129, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_LOW,
- 3, 0, 0, 1, 1, 160, 3, 0, 48
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_SHARP_LQ084V1DG21 */
-
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_HLD1045
-/*
- * HLD1045 display, 640x480. Active, color, single scan.
- */
-vidinfo_t panel_info = {
- 640, 480, 0, 0, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 160, 3, 0, 48
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_HLD1045 */
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_PRIMEVIEW_V16C6448AC
-/*
- * Prime View V16C6448AC
- */
-vidinfo_t panel_info = {
- 640, 480, 130, 98, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW, CONFIG_SYS_LOW, CONFIG_SYS_HIGH,
- 3, 0, 0, 1, 1, 144, 2, 0, 35
- /* wbl, vpw, lcdac, wbf */
-};
-#endif /* CONFIG_PRIMEVIEW_V16C6448AC */
-
-/*----------------------------------------------------------------------*/
-
-#ifdef CONFIG_OPTREX_BW
-/*
- * Optrex CBL50840-2 NF-FW 99 22 M5
- * or
- * Hitachi LMG6912RPFC-00T
- * or
- * Hitachi SP14Q002
- *
- * 320x240. Black & white.
- */
-#define OPTREX_BPP 0 /* 0 - monochrome, 1 bpp */
- /* 1 - 4 grey levels, 2 bpp */
- /* 2 - 16 grey levels, 4 bpp */
-vidinfo_t panel_info = {
- 320, 240, 0, 0, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_HIGH, CONFIG_SYS_LOW,
- OPTREX_BPP, 0, 0, 0, 0, 0, 0, 0, 0, 4
-};
-#endif /* CONFIG_OPTREX_BW */
-
-/************************************************************************/
-/* ----------------- chipset specific functions ----------------------- */
-/************************************************************************/
-
-/*
- * Calculate fb size for VIDEOLFB_ATAG.
- */
-ulong calc_fbsize (void)
-{
- ulong size;
- int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
-
- size = line_length * panel_info.vl_row;
-
- return size;
-}
-
-void lcd_ctrl_init (void *lcdbase)
-{
- volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
- volatile lcd823_t *lcdp = &immr->im_lcd;
-
- uint lccrtmp;
- uint lchcr_hpc_tmp;
-
- /* Initialize the LCD control register according to the LCD
- * parameters defined. We do everything here but enable
- * the controller.
- */
-
- lccrtmp = LCDBIT (LCCR_BNUM_BIT,
- (((panel_info.vl_row * panel_info.vl_col) * (1 << LCD_BPP)) / 128));
-
- lccrtmp |= LCDBIT (LCCR_CLKP_BIT, panel_info.vl_clkp) |
- LCDBIT (LCCR_OEP_BIT, panel_info.vl_oep) |
- LCDBIT (LCCR_HSP_BIT, panel_info.vl_hsp) |
- LCDBIT (LCCR_VSP_BIT, panel_info.vl_vsp) |
- LCDBIT (LCCR_DP_BIT, panel_info.vl_dp) |
- LCDBIT (LCCR_BPIX_BIT, panel_info.vl_bpix) |
- LCDBIT (LCCR_LBW_BIT, panel_info.vl_lbw) |
- LCDBIT (LCCR_SPLT_BIT, panel_info.vl_splt) |
- LCDBIT (LCCR_CLOR_BIT, panel_info.vl_clor) |
- LCDBIT (LCCR_TFT_BIT, panel_info.vl_tft);
-
-#if 0
- lccrtmp |= ((SIU_LEVEL5 / 2) << 12);
- lccrtmp |= LCCR_EIEN;
-#endif
-
- lcdp->lcd_lccr = lccrtmp;
- lcdp->lcd_lcsr = 0xFF; /* Clear pending interrupts */
-
- /* Initialize LCD controller bus priorities.
- */
- immr->im_siu_conf.sc_sdcr &= ~0x0f; /* RAID = LAID = 0 */
-
- /* set SHFT/CLOCK division factor 4
- * This needs to be set based upon display type and processor
- * speed. The TFT displays run about 20 to 30 MHz.
- * I was running 64 MHz processor speed.
- * The value for this divider must be chosen so the result is
- * an integer of the processor speed (i.e., divide by 3 with
- * 64 MHz would be bad).
- */
- immr->im_clkrst.car_sccr &= ~0x1F;
- immr->im_clkrst.car_sccr |= LCD_DF; /* was 8 */
-
- /* Enable LCD on port D.
- */
- immr->im_ioport.iop_pdpar |= 0x1FFF;
- immr->im_ioport.iop_pddir |= 0x1FFF;
-
- /* Enable LCD_A/B/C on port B.
- */
- immr->im_cpm.cp_pbpar |= 0x00005001;
- immr->im_cpm.cp_pbdir |= 0x00005001;
-
- /* Load the physical address of the linear frame buffer
- * into the LCD controller.
- * BIG NOTE: This has to be modified to load A and B depending
- * upon the split mode of the LCD.
- */
- lcdp->lcd_lcfaa = (ulong)lcdbase;
- lcdp->lcd_lcfba = (ulong)lcdbase;
-
- /* MORE HACKS...This must be updated according to 823 manual
- * for different panels.
- * Udi Finkelstein - done - see below:
- * Note: You better not try unsupported combinations such as
- * 4-bit wide passive dual scan LCD at 4/8 Bit color.
- */
- lchcr_hpc_tmp =
- (panel_info.vl_col *
- (panel_info.vl_tft ? 8 :
- (((2 - panel_info.vl_lbw) << /* 4 bit=2, 8-bit = 1 */
- /* use << to mult by: single scan = 1, dual scan = 2 */
- panel_info.vl_splt) *
- (panel_info.vl_bpix | 1)))) >> 3; /* 2/4 BPP = 1, 8/16 BPP = 3 */
-
- lcdp->lcd_lchcr = LCHCR_BO |
- LCDBIT (LCHCR_AT_BIT, 4) |
- LCDBIT (LCHCR_HPC_BIT, lchcr_hpc_tmp) |
- panel_info.vl_wbl;
-
- lcdp->lcd_lcvcr = LCDBIT (LCVCR_VPW_BIT, panel_info.vl_vpw) |
- LCDBIT (LCVCR_LCD_AC_BIT, panel_info.vl_lcdac) |
- LCDBIT (LCVCR_VPC_BIT, panel_info.vl_row) |
- panel_info.vl_wbf;
-
-}
-
-/*----------------------------------------------------------------------*/
-
-#if LCD_BPP == LCD_COLOR8
-void
-lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
-{
- volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
- volatile cpm8xx_t *cp = &(immr->im_cpm);
- unsigned short colreg, *cmap_ptr;
-
- cmap_ptr = (unsigned short *)&cp->lcd_cmap[regno * 2];
-
- colreg = ((red & 0x0F) << 8) |
- ((green & 0x0F) << 4) |
- (blue & 0x0F) ;
-
- *cmap_ptr = colreg;
-
- debug ("setcolreg: reg %2d @ %p: R=%02X G=%02X B=%02X => %02X%02X\n",
- regno, &(cp->lcd_cmap[regno * 2]),
- red, green, blue,
- cp->lcd_cmap[ regno * 2 ], cp->lcd_cmap[(regno * 2) + 1]);
-}
-#endif /* LCD_COLOR8 */
-
-/*----------------------------------------------------------------------*/
-
-ushort *configuration_get_cmap(void)
-{
- immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
- cpm8xx_t *cp = &(immr->im_cpm);
- return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
-}
-
-#if defined(CONFIG_MPC823)
-void fb_put_byte(uchar **fb, uchar **from)
-{
- *(*fb)++ = (255 - *(*from)++);
-}
-#endif
-
-#ifdef CONFIG_LCD_LOGO
-#include <bmp_logo.h>
-void lcd_logo_set_cmap(void)
-{
- int i;
- ushort *cmap;
- immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
- cpm8xx_t *cp = &(immr->im_cpm);
- cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]);
-
- for (i = 0; i < BMP_LOGO_COLORS; ++i)
- *cmap++ = bmp_logo_palette[i];
-}
-#endif
-
-void lcd_enable (void)
-{
- volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
- volatile lcd823_t *lcdp = &immr->im_lcd;
-
- /* Enable the LCD panel */
- immr->im_siu_conf.sc_sdcr |= (1 << (31 - 25)); /* LAM = 1 */
- lcdp->lcd_lccr |= LCCR_PON;
-}
-
-/************************************************************************/
-
-#endif /* CONFIG_LCD */
diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig
index 80e399f7d7..b1d7c62fca 100644
--- a/drivers/video/rockchip/Kconfig
+++ b/drivers/video/rockchip/Kconfig
@@ -12,11 +12,30 @@ menuconfig VIDEO_ROCKCHIP
bool "Enable Rockchip Video Support"
depends on DM_VIDEO
help
- Rockchip SoCs provide video output capabilities for High-Definition
- Multimedia Interface (HDMI), Low-voltage Differential Signalling
- (LVDS), embedded DisplayPort (eDP) and Display Serial Interface
- (DSI). This driver supports the on-chip video output device, and
- targets the Rockchip RK3288 and RK3399.
+ Rockchip SoCs provide video output capabilities for High-Definition
+ Multimedia Interface (HDMI), Low-voltage Differential Signalling
+ (LVDS), embedded DisplayPort (eDP) and Display Serial Interface (DSI).
+
+ This driver supports the on-chip video output device, and targets the
+ Rockchip RK3288 and RK3399.
+
+config VIDEO_ROCKCHIP_MAX_XRES
+ int "Maximum horizontal resolution (for memory allocation purposes)"
+ depends on VIDEO_ROCKCHIP
+ default 1920
+ help
+ The maximum horizontal resolution to support for the framebuffer.
+ This configuration is used for reserving/allocating memory for the
+ framebuffer during device-model binding/probing.
+
+config VIDEO_ROCKCHIP_MAX_YRES
+ int "Maximum vertical resolution (for memory allocation purposes)"
+ depends on VIDEO_ROCKCHIP
+ default 1080
+ help
+ The maximum vertical resolution to support for the framebuffer.
+ This configuration is used for reserving/allocating memory for the
+ framebuffer during device-model binding/probing.
if VIDEO_ROCKCHIP
diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile
index cd54b12a4e..872dc0f653 100644
--- a/drivers/video/rockchip/Makefile
+++ b/drivers/video/rockchip/Makefile
@@ -7,8 +7,12 @@
ifdef CONFIG_VIDEO_ROCKCHIP
obj-y += rk_vop.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288_vop.o
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399_vop.o
obj-$(CONFIG_DISPLAY_ROCKCHIP_EDP) += rk_edp.o
obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o
-obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o
+obj-hdmi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_hdmi.o
+obj-hdmi-$(CONFIG_ROCKCHIP_RK3399) += rk3399_hdmi.o
+obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o $(obj-hdmi-y)
obj-$(CONFIG_DISPLAY_ROCKCHIP_MIPI) += rk_mipi.o
endif
diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c
new file mode 100644
index 0000000000..eae0dd2abf
--- /dev/null
+++ b/drivers/video/rockchip/rk3288_hdmi.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <dw_hdmi.h>
+#include <edid.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/grf_rk3288.h>
+#include <power/regulator.h>
+#include "rk_hdmi.h"
+
+static int rk3288_hdmi_enable(struct udevice *dev, int panel_bpp,
+ const struct display_timing *edid)
+{
+ struct rk_hdmi_priv *priv = dev_get_priv(dev);
+ struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+ int vop_id = uc_plat->source_id;
+ struct rk3288_grf *grf = priv->grf;
+
+ /* hdmi source select hdmi controller */
+ rk_setreg(&grf->soc_con6, 1 << 15);
+
+ /* hdmi data from vop id */
+ rk_clrsetreg(&grf->soc_con6, 1 << 4, (vop_id == 1) ? (1 << 4) : 0);
+
+ return 0;
+}
+
+static int rk3288_hdmi_ofdata_to_platdata(struct udevice *dev)
+{
+ struct rk_hdmi_priv *priv = dev_get_priv(dev);
+ struct dw_hdmi *hdmi = &priv->hdmi;
+
+ hdmi->i2c_clk_high = 0x7a;
+ hdmi->i2c_clk_low = 0x8d;
+
+ /*
+ * TODO(sjg@chromium.org): The above values don't work - these
+ * ones work better, but generate lots of errors in the data.
+ */
+ hdmi->i2c_clk_high = 0x0d;
+ hdmi->i2c_clk_low = 0x0d;
+
+ return rk_hdmi_ofdata_to_platdata(dev);
+}
+
+static int rk3288_clk_config(struct udevice *dev)
+{
+ struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+ struct clk clk;
+ int ret;
+
+ /*
+ * Configure the maximum clock to permit whatever resolution the
+ * monitor wants
+ */
+ ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
+ if (ret >= 0) {
+ ret = clk_set_rate(&clk, 384000000);
+ clk_free(&clk);
+ }
+ if (ret < 0) {
+ debug("%s: Failed to set clock in source device '%s': ret=%d\n",
+ __func__, uc_plat->src_dev->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const char * const rk3288_regulator_names[] = {
+ "vcc50_hdmi"
+};
+
+static int rk3288_hdmi_probe(struct udevice *dev)
+{
+ /* Enable VOP clock for RK3288 */
+ rk3288_clk_config(dev);
+
+ /* Enable regulators required for HDMI */
+ rk_hdmi_probe_regulators(dev, rk3288_regulator_names,
+ ARRAY_SIZE(rk3288_regulator_names));
+
+ return rk_hdmi_probe(dev);
+}
+
+static const struct dm_display_ops rk3288_hdmi_ops = {
+ .read_edid = rk_hdmi_read_edid,
+ .enable = rk3288_hdmi_enable,
+};
+
+static const struct udevice_id rk3288_hdmi_ids[] = {
+ { .compatible = "rockchip,rk3288-dw-hdmi" },
+ { }
+};
+
+U_BOOT_DRIVER(rk3288_hdmi_rockchip) = {
+ .name = "rk3288_hdmi_rockchip",
+ .id = UCLASS_DISPLAY,
+ .of_match = rk3288_hdmi_ids,
+ .ops = &rk3288_hdmi_ops,
+ .ofdata_to_platdata = rk3288_hdmi_ofdata_to_platdata,
+ .probe = rk3288_hdmi_probe,
+ .priv_auto_alloc_size = sizeof(struct rk_hdmi_priv),
+};
diff --git a/drivers/video/rockchip/rk3288_vop.c b/drivers/video/rockchip/rk3288_vop.c
new file mode 100644
index 0000000000..3a5740a6cb
--- /dev/null
+++ b/drivers/video/rockchip/rk3288_vop.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ * Copyright (c) 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <display.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <video.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include "rk_vop.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void rk3288_set_pin_polarity(struct udevice *dev,
+ enum vop_modes mode, u32 polarity)
+{
+ struct rk_vop_priv *priv = dev_get_priv(dev);
+ struct rk3288_vop *regs = priv->regs;
+
+ /* The RK3328 VOP (v3.1) has its polarity configuration in ctrl0 */
+ clrsetbits_le32(&regs->dsp_ctrl0,
+ M_DSP_DCLK_POL | M_DSP_DEN_POL |
+ M_DSP_VSYNC_POL | M_DSP_HSYNC_POL,
+ V_DSP_PIN_POL(polarity));
+}
+
+static void rk3288_set_io_vsel(struct udevice *dev)
+{
+ struct rk3288_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+ /* lcdc(vop) iodomain select 1.8V */
+ rk_setreg(&grf->io_vsel, 1 << 0);
+}
+
+/*
+ * Try some common regulators. We should really get these from the
+ * device tree somehow.
+ */
+static const char * const rk3288_regulator_names[] = {
+ "vcc18_lcd",
+ "VCC18_LCD",
+ "vdd10_lcd_pwren_h",
+ "vdd10_lcd",
+ "VDD10_LCD",
+ "vcc33_lcd"
+};
+
+static int rk3288_vop_probe(struct udevice *dev)
+{
+ /* Before relocation we don't need to do anything */
+ if (!(gd->flags & GD_FLG_RELOC))
+ return 0;
+
+ /* Set the LCDC(vop) iodomain to 1.8V */
+ rk3288_set_io_vsel(dev);
+
+ /* Probe regulators required for the RK3288 VOP */
+ rk_vop_probe_regulators(dev, rk3288_regulator_names,
+ ARRAY_SIZE(rk3288_regulator_names));
+
+ return rk_vop_probe(dev);
+}
+
+static int rk_vop_remove(struct udevice *dev)
+{
+ struct rk_vop_priv *priv = dev_get_priv(dev);
+ struct rk3288_vop *regs = priv->regs;
+
+ setbits_le32(&regs->sys_ctrl, V_STANDBY_EN(1));
+
+ /* wait frame complete (60Hz) to enter standby */
+ mdelay(17);
+
+ return 0;
+}
+
+struct rkvop_driverdata rk3288_driverdata = {
+ .features = VOP_FEATURE_OUTPUT_10BIT,
+ .set_pin_polarity = rk3288_set_pin_polarity,
+};
+
+static const struct udevice_id rk3288_vop_ids[] = {
+ { .compatible = "rockchip,rk3288-vop",
+ .data = (ulong)&rk3288_driverdata },
+ { }
+};
+
+static const struct video_ops rk3288_vop_ops = {
+};
+
+U_BOOT_DRIVER(rk_vop) = {
+ .name = "rk3288_vop",
+ .id = UCLASS_VIDEO,
+ .of_match = rk3288_vop_ids,
+ .ops = &rk3288_vop_ops,
+ .bind = rk_vop_bind,
+ .probe = rk3288_vop_probe,
+ .remove = rk_vop_remove,
+ .priv_auto_alloc_size = sizeof(struct rk_vop_priv),
+};
diff --git a/drivers/video/rockchip/rk3399_hdmi.c b/drivers/video/rockchip/rk3399_hdmi.c
new file mode 100644
index 0000000000..b1e50974f6
--- /dev/null
+++ b/drivers/video/rockchip/rk3399_hdmi.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <dw_hdmi.h>
+#include <edid.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/grf_rk3399.h>
+#include <power/regulator.h>
+#include "rk_hdmi.h"
+
+static int rk3399_hdmi_enable(struct udevice *dev, int panel_bpp,
+ const struct display_timing *edid)
+{
+ struct rk_hdmi_priv *priv = dev_get_priv(dev);
+ struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
+ int vop_id = uc_plat->source_id;
+ struct rk3399_grf_regs *grf = priv->grf;
+
+ /* select the hdmi encoder input data from our source_id */
+ rk_clrsetreg(&grf->soc_con20, GRF_RK3399_HDMI_VOP_SEL_MASK,
+ (vop_id == 1) ? GRF_RK3399_HDMI_VOP_SEL_L : 0);
+
+ return dw_hdmi_enable(&priv->hdmi, edid);
+}
+
+static int rk3399_hdmi_ofdata_to_platdata(struct udevice *dev)
+{
+ struct rk_hdmi_priv *priv = dev_get_priv(dev);
+ struct dw_hdmi *hdmi = &priv->hdmi;
+
+ hdmi->i2c_clk_high = 0x7a;
+ hdmi->i2c_clk_low = 0x8d;
+
+ return rk_hdmi_ofdata_to_platdata(dev);
+}
+
+static const char * const rk3399_regulator_names[] = {
+ "vcc1v8_hdmi",
+ "vcc0v9_hdmi"
+};
+
+static int rk3399_hdmi_probe(struct udevice *dev)
+{
+ /* Enable regulators required for HDMI */
+ rk_hdmi_probe_regulators(dev, rk3399_regulator_names,
+ ARRAY_SIZE(rk3399_regulator_names));
+
+ return rk_hdmi_probe(dev);
+}
+
+static const struct dm_display_ops rk3399_hdmi_ops = {
+ .read_edid = rk_hdmi_read_edid,
+ .enable = rk3399_hdmi_enable,
+};
+
+static const struct udevice_id rk3399_hdmi_ids[] = {
+ { .compatible = "rockchip,rk3399-dw-hdmi" },
+ { }
+};
+
+U_BOOT_DRIVER(rk3399_hdmi_rockchip) = {
+ .name = "rk3399_hdmi_rockchip",
+ .id = UCLASS_DISPLAY,
+ .of_match = rk3399_hdmi_ids,
+ .ops = &rk3399_hdmi_ops,
+ .ofdata_to_platdata = rk3399_hdmi_ofdata_to_platdata,
+ .probe = rk3399_hdmi_probe,
+ .priv_auto_alloc_size = sizeof(struct rk_hdmi_priv),
+};
diff --git a/drivers/video/rockchip/rk3399_vop.c b/drivers/video/rockchip/rk3399_vop.c
new file mode 100644
index 0000000000..91a40ab9fe
--- /dev/null
+++ b/drivers/video/rockchip/rk3399_vop.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ * Copyright (c) 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <display.h>
+#include <dm.h>
+#include <regmap.h>
+#include <video.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include "rk_vop.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void rk3399_set_pin_polarity(struct udevice *dev,
+ enum vop_modes mode, u32 polarity)
+{
+ struct rk_vop_priv *priv = dev_get_priv(dev);
+ struct rk3288_vop *regs = priv->regs;
+
+ /*
+ * The RK3399 VOPs (v3.5 and v3.6) require a per-mode setting of
+ * the polarity configuration (in ctrl1).
+ */
+ switch (mode) {
+ case VOP_MODE_HDMI:
+ clrsetbits_le32(&regs->dsp_ctrl1,
+ M_RK3399_DSP_HDMI_POL,
+ V_RK3399_DSP_HDMI_POL(polarity));
+ break;
+
+ case VOP_MODE_EDP:
+ clrsetbits_le32(&regs->dsp_ctrl1,
+ M_RK3399_DSP_EDP_POL,
+ V_RK3399_DSP_EDP_POL(polarity));
+ break;
+
+ case VOP_MODE_MIPI:
+ clrsetbits_le32(&regs->dsp_ctrl1,
+ M_RK3399_DSP_MIPI_POL,
+ V_RK3399_DSP_MIPI_POL(polarity));
+ break;
+
+ case VOP_MODE_LVDS:
+ /* The RK3399 has neither parallel RGB nor LVDS output. */
+ default:
+ debug("%s: unsupported output mode %x\n", __func__, mode);
+ }
+}
+
+/*
+ * Try some common regulators. We should really get these from the
+ * device tree somehow.
+ */
+static const char * const rk3399_regulator_names[] = {
+ "vcc33_lcd"
+};
+
+static int rk3399_vop_probe(struct udevice *dev)
+{
+ /* Before relocation we don't need to do anything */
+ if (!(gd->flags & GD_FLG_RELOC))
+ return 0;
+
+ /* Probe regulators required for the RK3399 VOP */
+ rk_vop_probe_regulators(dev, rk3399_regulator_names,
+ ARRAY_SIZE(rk3399_regulator_names));
+
+ return rk_vop_probe(dev);
+}
+
+struct rkvop_driverdata rk3399_lit_driverdata = {
+ .set_pin_polarity = rk3399_set_pin_polarity,
+};
+
+struct rkvop_driverdata rk3399_big_driverdata = {
+ .features = VOP_FEATURE_OUTPUT_10BIT,
+ .set_pin_polarity = rk3399_set_pin_polarity,
+};
+
+static const struct udevice_id rk3399_vop_ids[] = {
+ { .compatible = "rockchip,rk3399-vop-big",
+ .data = (ulong)&rk3399_big_driverdata },
+ { .compatible = "rockchip,rk3399-vop-lit",
+ .data = (ulong)&rk3399_lit_driverdata },
+ { }
+};
+
+static const struct video_ops rk3399_vop_ops = {
+};
+
+U_BOOT_DRIVER(rk3399_vop) = {
+ .name = "rk3399_vop",
+ .id = UCLASS_VIDEO,
+ .of_match = rk3399_vop_ids,
+ .ops = &rk3399_vop_ops,
+ .bind = rk_vop_bind,
+ .probe = rk3399_vop_probe,
+ .priv_auto_alloc_size = sizeof(struct rk_vop_priv),
+};
diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c
index 7ece038c8f..1527f96eca 100644
--- a/drivers/video/rockchip/rk_edp.c
+++ b/drivers/video/rockchip/rk_edp.c
@@ -998,13 +998,26 @@ static int rk_edp_ofdata_to_platdata(struct udevice *dev)
{
struct rk_edp_priv *priv = dev_get_priv(dev);
- priv->regs = (struct rk3288_edp *)dev_get_addr(dev);
+ priv->regs = (struct rk3288_edp *)devfdt_get_addr(dev);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
return 0;
}
-int rk_edp_probe(struct udevice *dev)
+static int rk_edp_remove(struct udevice *dev)
+{
+ struct rk_edp_priv *priv = dev_get_priv(dev);
+ struct rk3288_edp *regs = priv->regs;
+
+ setbits_le32(&regs->video_ctl_1, VIDEO_MUTE);
+ clrbits_le32(&regs->video_ctl_1, VIDEO_EN);
+ clrbits_le32(&regs->sys_ctl_3, F_HPD | HPD_CTRL);
+ setbits_le32(&regs->func_en_1, SW_FUNC_EN_N);
+
+ return 0;
+}
+
+static int rk_edp_probe(struct udevice *dev)
{
struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
struct rk_edp_priv *priv = dev_get_priv(dev);
@@ -1080,5 +1093,6 @@ U_BOOT_DRIVER(dp_rockchip) = {
.ops = &dp_rockchip_ops,
.ofdata_to_platdata = rk_edp_ofdata_to_platdata,
.probe = rk_edp_probe,
+ .remove = rk_edp_remove,
.priv_auto_alloc_size = sizeof(struct rk_edp_priv),
};
diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c
index db07588302..a9c8fba7e4 100644
--- a/drivers/video/rockchip/rk_hdmi.c
+++ b/drivers/video/rockchip/rk_hdmi.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
* Copyright (c) 2015 Google, Inc
* Copyright 2014 Rockchip Inc.
*
@@ -14,15 +15,12 @@
#include <regmap.h>
#include <syscon.h>
#include <asm/gpio.h>
+#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
-#include <asm/arch/grf_rk3288.h>
-#include <power/regulator.h>
-
-struct rk_hdmi_priv {
- struct dw_hdmi hdmi;
- struct rk3288_grf *grf;
-};
+#include <asm/arch/hardware.h>
+#include "rk_hdmi.h"
+#include "rk_vop.h" /* for rk_vop_probe_regulators */
static const struct hdmi_phy_config rockchip_phy_config[] = {
{
@@ -35,6 +33,9 @@ static const struct hdmi_phy_config rockchip_phy_config[] = {
.mpixelclock = 297000000,
.sym_ctr = 0x8039, .term = 0x0005, .vlev_ctr = 0x028d,
}, {
+ .mpixelclock = 584000000,
+ .sym_ctr = 0x8039, .term = 0x0000, .vlev_ctr = 0x019d,
+ }, {
.mpixelclock = ~0ul,
.sym_ctr = 0x0000, .term = 0x0000, .vlev_ctr = 0x0000,
}
@@ -60,43 +61,35 @@ static const struct hdmi_mpll_config rockchip_mpll_cfg[] = {
.mpixelclock = 148500000,
.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
}, {
+ .mpixelclock = 272000000,
+ .cpce = 0x0040, .gmp = 0x0003, .curr = 0x0000,
+ }, {
+ .mpixelclock = 340000000,
+ .cpce = 0x0040, .gmp = 0x0003, .curr = 0x0000,
+ }, {
.mpixelclock = ~0ul,
.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
}
};
-static int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
+int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
{
struct rk_hdmi_priv *priv = dev_get_priv(dev);
return dw_hdmi_read_edid(&priv->hdmi, buf, buf_size);
}
-static int rk_hdmi_enable(struct udevice *dev, int panel_bpp,
- const struct display_timing *edid)
-{
- struct rk_hdmi_priv *priv = dev_get_priv(dev);
-
- return dw_hdmi_enable(&priv->hdmi, edid);
-}
-
-static int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
+int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
{
struct rk_hdmi_priv *priv = dev_get_priv(dev);
struct dw_hdmi *hdmi = &priv->hdmi;
- hdmi->ioaddr = (ulong)dev_get_addr(dev);
+ hdmi->ioaddr = (ulong)devfdt_get_addr(dev);
hdmi->mpll_cfg = rockchip_mpll_cfg;
hdmi->phy_cfg = rockchip_phy_config;
- hdmi->i2c_clk_high = 0x7a;
- hdmi->i2c_clk_low = 0x8d;
-
- /*
- * TODO(sjg@chromium.org): The above values don't work - these ones
- * work better, but generate lots of errors in the data.
- */
- hdmi->i2c_clk_high = 0x0d;
- hdmi->i2c_clk_low = 0x0d;
+
+ /* hdmi->i2c_clk_{high,low} are set up by the SoC driver */
+
hdmi->reg_io_width = 4;
hdmi->phy_set = dw_hdmi_phy_cfg;
@@ -105,53 +98,17 @@ static int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
return 0;
}
-static int rk_hdmi_probe(struct udevice *dev)
+void rk_hdmi_probe_regulators(struct udevice *dev,
+ const char * const *names, int cnt)
+{
+ rk_vop_probe_regulators(dev, names, cnt);
+}
+
+int rk_hdmi_probe(struct udevice *dev)
{
- struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
struct rk_hdmi_priv *priv = dev_get_priv(dev);
struct dw_hdmi *hdmi = &priv->hdmi;
- struct udevice *reg;
- struct clk clk;
int ret;
- int vop_id = uc_plat->source_id;
-
- ret = clk_get_by_index(dev, 0, &clk);
- if (ret >= 0) {
- ret = clk_set_rate(&clk, 0);
- clk_free(&clk);
- }
- if (ret) {
- debug("%s: Failed to set hdmi clock: ret=%d\n", __func__, ret);
- return ret;
- }
-
- /*
- * Configure the maximum clock to permit whatever resolution the
- * monitor wants
- */
- ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
- if (ret >= 0) {
- ret = clk_set_rate(&clk, 384000000);
- clk_free(&clk);
- }
- if (ret < 0) {
- debug("%s: Failed to set clock in source device '%s': ret=%d\n",
- __func__, uc_plat->src_dev->name, ret);
- return ret;
- }
-
- ret = regulator_get_by_platname("vcc50_hdmi", &reg);
- if (!ret)
- ret = regulator_set_enable(reg, true);
- if (ret)
- debug("%s: Cannot set regulator vcc50_hdmi\n", __func__);
-
- /* hdmi source select hdmi controller */
- rk_setreg(&priv->grf->soc_con6, 1 << 15);
-
- /* hdmi data from vop id */
- rk_clrsetreg(&priv->grf->soc_con6, 1 << 4,
- (vop_id == 1) ? (1 << 4) : 0);
ret = dw_hdmi_phy_wait_for_hpd(hdmi);
if (ret < 0) {
@@ -164,23 +121,3 @@ static int rk_hdmi_probe(struct udevice *dev)
return 0;
}
-
-static const struct dm_display_ops rk_hdmi_ops = {
- .read_edid = rk_hdmi_read_edid,
- .enable = rk_hdmi_enable,
-};
-
-static const struct udevice_id rk_hdmi_ids[] = {
- { .compatible = "rockchip,rk3288-dw-hdmi" },
- { }
-};
-
-U_BOOT_DRIVER(hdmi_rockchip) = {
- .name = "hdmi_rockchip",
- .id = UCLASS_DISPLAY,
- .of_match = rk_hdmi_ids,
- .ops = &rk_hdmi_ops,
- .ofdata_to_platdata = rk_hdmi_ofdata_to_platdata,
- .probe = rk_hdmi_probe,
- .priv_auto_alloc_size = sizeof(struct rk_hdmi_priv),
-};
diff --git a/drivers/video/rockchip/rk_hdmi.h b/drivers/video/rockchip/rk_hdmi.h
new file mode 100644
index 0000000000..ec396682f1
--- /dev/null
+++ b/drivers/video/rockchip/rk_hdmi.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __RK_HDMI_H__
+#define __RK_HDMI_H__
+
+struct rkhdmi_driverdata {
+ /* configuration */
+ u8 i2c_clk_high;
+ u8 i2c_clk_low;
+ const char * const *regulator_names;
+ u32 regulator_names_cnt;
+ /* setters/getters */
+ int (*set_input_vop)(struct udevice *dev);
+ int (*clk_config)(struct udevice *dev);
+};
+
+struct rk_hdmi_priv {
+ struct dw_hdmi hdmi;
+ void *grf;
+};
+
+/**
+ * rk_hdmi_read_edid() - read the attached HDMI/DVI monitor's EDID
+ *
+ * N.B.: The buffer should be large enough to hold 2 EDID blocks, as
+ * this function calls dw_hdmi_read_edid, which ignores buf_size
+ * argument and assumes that there's always enough space for 2
+ * EDID blocks.
+ *
+ * @dev: device
+ * @buf: output buffer for the EDID
+ * @buf_size: number of bytes in the buffer
+ * @return number of bytes read if OK, -ve if something went wrong
+ */
+int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size);
+
+/**
+ * rk_hdmi_probe_regulators() - probe (autoset + enable) regulators
+ *
+ * Probes a list of regulators by performing autoset and enable
+ * operations on them. The list of regulators is an array of string
+ * pointers and any individual regulator-probe may fail without
+ * counting as an error.
+ *
+ * @dev: device
+ * @names: array of string-pointers to regulator names to probe
+ * @cnt: number of elements in the 'names' array
+ */
+void rk_hdmi_probe_regulators(struct udevice *dev,
+ const char * const *names, int cnt);
+/**
+ * rk_hdmi_ofdata_to_platdata() - common ofdata_to_platdata implementation
+ *
+ * @dev: device
+ * @return 0 if OK, -ve if something went wrong
+ */
+int rk_hdmi_ofdata_to_platdata(struct udevice *dev);
+
+/**
+ * rk_hdmi_probe() - common probe implementation
+ *
+ * Performs the following, common initialisation steps:
+ * 1. checks for HPD (i.e. a HDMI monitor being attached)
+ * 2. initialises the Designware HDMI core
+ * 3. initialises the Designware HDMI PHY
+ *
+ * @dev: device
+ * @return 0 if OK, -ve if something went wrong
+ */
+int rk_hdmi_probe(struct udevice *dev);
+
+#endif
diff --git a/drivers/video/rockchip/rk_lvds.c b/drivers/video/rockchip/rk_lvds.c
index ee43255753..66418ddfad 100644
--- a/drivers/video/rockchip/rk_lvds.c
+++ b/drivers/video/rockchip/rk_lvds.c
@@ -176,7 +176,7 @@ static int rk_lvds_ofdata_to_platdata(struct udevice *dev)
const void *blob = gd->fdt_blob;
int node = dev_of_offset(dev);
int ret;
- priv->regs = (void *)dev_get_addr(dev);
+ priv->regs = (void *)devfdt_get_addr(dev);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
ret = fdtdec_get_int(blob, node, "rockchip,output", -1);
diff --git a/drivers/video/rockchip/rk_mipi.c b/drivers/video/rockchip/rk_mipi.c
index 4d9d12e1d7..ad003970d6 100644
--- a/drivers/video/rockchip/rk_mipi.c
+++ b/drivers/video/rockchip/rk_mipi.c
@@ -441,7 +441,7 @@ static int rk_mipi_ofdata_to_platdata(struct udevice *dev)
__func__, (u64)priv->grf);
return -ENXIO;
}
- priv->regs = (void *)dev_get_addr(dev);
+ priv->regs = (void *)devfdt_get_addr(dev);
if (priv->regs <= 0) {
debug("%s: Get MIPI dsi address failed (ret=%llu)\n", __func__,
(u64)priv->regs);
diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index aa6ca8c859..c979049b5b 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -17,24 +17,25 @@
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
#include <asm/arch/edp_rk3288.h>
#include <asm/arch/vop_rk3288.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
-#include <dt-bindings/clock/rk3288-cru.h>
#include <power/regulator.h>
+#include "rk_vop.h"
DECLARE_GLOBAL_DATA_PTR;
-struct rk_vop_priv {
- struct rk3288_vop *regs;
- struct rk3288_grf *grf;
+enum vop_pol {
+ HSYNC_POSITIVE = 0,
+ VSYNC_POSITIVE = 1,
+ DEN_NEGATIVE = 2,
+ DCLK_INVERT = 3
};
-void rkvop_enable(struct rk3288_vop *regs, ulong fbbase,
- int fb_bits_per_pixel, const struct display_timing *edid)
+static void rkvop_enable(struct rk3288_vop *regs, ulong fbbase,
+ int fb_bits_per_pixel,
+ const struct display_timing *edid)
{
u32 lb_mode;
u32 rgb_mode;
@@ -89,54 +90,86 @@ void rkvop_enable(struct rk3288_vop *regs, ulong fbbase,
writel(0x01, &regs->reg_cfg_done); /* enable reg config */
}
-void rkvop_mode_set(struct rk3288_vop *regs,
- const struct display_timing *edid, enum vop_modes mode)
+static void rkvop_set_pin_polarity(struct udevice *dev,
+ enum vop_modes mode, u32 polarity)
{
- u32 hactive = edid->hactive.typ;
- u32 vactive = edid->vactive.typ;
- u32 hsync_len = edid->hsync_len.typ;
- u32 hback_porch = edid->hback_porch.typ;
- u32 vsync_len = edid->vsync_len.typ;
- u32 vback_porch = edid->vback_porch.typ;
- u32 hfront_porch = edid->hfront_porch.typ;
- u32 vfront_porch = edid->vfront_porch.typ;
- uint flags;
- int mode_flags;
+ struct rkvop_driverdata *ops =
+ (struct rkvop_driverdata *)dev_get_driver_data(dev);
+
+ if (ops->set_pin_polarity)
+ ops->set_pin_polarity(dev, mode, polarity);
+}
+
+static void rkvop_enable_output(struct udevice *dev, enum vop_modes mode)
+{
+ struct rk_vop_priv *priv = dev_get_priv(dev);
+ struct rk3288_vop *regs = priv->regs;
+
+ /* remove from standby */
+ clrbits_le32(&regs->sys_ctrl, V_STANDBY_EN(1));
switch (mode) {
case VOP_MODE_HDMI:
clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
V_HDMI_OUT_EN(1));
break;
+
case VOP_MODE_EDP:
- default:
clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
V_EDP_OUT_EN(1));
break;
+
case VOP_MODE_LVDS:
clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
V_RGB_OUT_EN(1));
break;
+
case VOP_MODE_MIPI:
clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
V_MIPI_OUT_EN(1));
- break;
+ break;
+
+ default:
+ debug("%s: unsupported output mode %x\n", __func__, mode);
}
+}
- if (mode == VOP_MODE_HDMI || mode == VOP_MODE_EDP)
- /* RGBaaa */
- mode_flags = 15;
- else
- /* RGB888 */
- mode_flags = 0;
+static void rkvop_mode_set(struct udevice *dev,
+ const struct display_timing *edid,
+ enum vop_modes mode)
+{
+ struct rk_vop_priv *priv = dev_get_priv(dev);
+ struct rk3288_vop *regs = priv->regs;
+ struct rkvop_driverdata *data =
+ (struct rkvop_driverdata *)dev_get_driver_data(dev);
+
+ u32 hactive = edid->hactive.typ;
+ u32 vactive = edid->vactive.typ;
+ u32 hsync_len = edid->hsync_len.typ;
+ u32 hback_porch = edid->hback_porch.typ;
+ u32 vsync_len = edid->vsync_len.typ;
+ u32 vback_porch = edid->vback_porch.typ;
+ u32 hfront_porch = edid->hfront_porch.typ;
+ u32 vfront_porch = edid->vfront_porch.typ;
+ int mode_flags;
+ u32 pin_polarity;
+
+ pin_polarity = BIT(DCLK_INVERT);
+ if (edid->flags & DISPLAY_FLAGS_HSYNC_HIGH)
+ pin_polarity |= BIT(HSYNC_POSITIVE);
+ if (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH)
+ pin_polarity |= BIT(VSYNC_POSITIVE);
+
+ rkvop_set_pin_polarity(dev, mode, pin_polarity);
+ rkvop_enable_output(dev, mode);
- flags = V_DSP_OUT_MODE(mode_flags) |
- V_DSP_HSYNC_POL(!!(edid->flags & DISPLAY_FLAGS_HSYNC_HIGH)) |
- V_DSP_VSYNC_POL(!!(edid->flags & DISPLAY_FLAGS_VSYNC_HIGH));
+ mode_flags = 0; /* RGB888 */
+ if ((data->features & VOP_FEATURE_OUTPUT_10BIT) &&
+ (mode == VOP_MODE_HDMI || mode == VOP_MODE_EDP))
+ mode_flags = 15; /* RGBaaa */
- clrsetbits_le32(&regs->dsp_ctrl0,
- M_DSP_OUT_MODE | M_DSP_VSYNC_POL | M_DSP_HSYNC_POL,
- flags);
+ clrsetbits_le32(&regs->dsp_ctrl0, M_DSP_OUT_MODE,
+ V_DSP_OUT_MODE(mode_flags));
writel(V_HSYNC(hsync_len) |
V_HORPRD(hsync_len + hback_porch + hactive + hfront_porch),
@@ -185,7 +218,7 @@ void rkvop_mode_set(struct rk3288_vop *regs,
* node within the VOP's 'port' list.
* @return 0 if OK, -ve if something went wrong
*/
-int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node)
+static int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node)
{
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
const void *blob = gd->fdt_blob;
@@ -255,18 +288,18 @@ int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node)
/* Set bitwidth for vop display according to vop mode */
switch (vop_id) {
case VOP_MODE_EDP:
- case VOP_MODE_HDMI:
case VOP_MODE_LVDS:
l2bpp = VIDEO_BPP16;
break;
+ case VOP_MODE_HDMI:
case VOP_MODE_MIPI:
l2bpp = VIDEO_BPP32;
break;
default:
l2bpp = VIDEO_BPP16;
}
- rkvop_mode_set(regs, &timing, vop_id);
+ rkvop_mode_set(dev, &timing, vop_id);
rkvop_enable(regs, fbbase, 1 << l2bpp, &timing);
ret = display_enable(disp, 1 << l2bpp, &timing);
@@ -281,52 +314,36 @@ int rk_display_init(struct udevice *dev, ulong fbbase, int ep_node)
return 0;
}
-static int rk_vop_probe(struct udevice *dev)
+void rk_vop_probe_regulators(struct udevice *dev,
+ const char * const *names, int cnt)
+{
+ int i, ret;
+ const char *name;
+ struct udevice *reg;
+
+ for (i = 0; i < cnt; ++i) {
+ name = names[i];
+ debug("%s: probing regulator '%s'\n", dev->name, name);
+
+ ret = regulator_autoset_by_name(name, &reg);
+ if (!ret)
+ ret = regulator_set_enable(reg, true);
+ }
+}
+
+int rk_vop_probe(struct udevice *dev)
{
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
const void *blob = gd->fdt_blob;
struct rk_vop_priv *priv = dev_get_priv(dev);
- struct udevice *reg;
- int ret, port, node;
+ int ret = 0;
+ int port, node;
/* Before relocation we don't need to do anything */
if (!(gd->flags & GD_FLG_RELOC))
return 0;
- priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
- priv->regs = (struct rk3288_vop *)dev_get_addr(dev);
-
- /* lcdc(vop) iodomain select 1.8V */
- rk_setreg(&priv->grf->io_vsel, 1 << 0);
-
- /*
- * Try some common regulators. We should really get these from the
- * device tree somehow.
- */
- ret = regulator_autoset_by_name("vcc18_lcd", &reg);
- if (ret)
- debug("%s: Cannot autoset regulator vcc18_lcd\n", __func__);
- ret = regulator_autoset_by_name("VCC18_LCD", &reg);
- if (ret)
- debug("%s: Cannot autoset regulator VCC18_LCD\n", __func__);
- ret = regulator_autoset_by_name("vdd10_lcd_pwren_h", &reg);
- if (ret) {
- debug("%s: Cannot autoset regulator vdd10_lcd_pwren_h\n",
- __func__);
- }
- ret = regulator_autoset_by_name("vdd10_lcd", &reg);
- if (ret) {
- debug("%s: Cannot autoset regulator vdd10_lcd\n",
- __func__);
- }
- ret = regulator_autoset_by_name("VDD10_LCD", &reg);
- if (ret) {
- debug("%s: Cannot autoset regulator VDD10_LCD\n",
- __func__);
- }
- ret = regulator_autoset_by_name("vcc33_lcd", &reg);
- if (ret)
- debug("%s: Cannot autoset regulator vcc33_lcd\n", __func__);
+ priv->regs = (struct rk3288_vop *)devfdt_get_addr(dev);
/*
* Try all the ports until we find one that works. In practice this
@@ -353,31 +370,12 @@ static int rk_vop_probe(struct udevice *dev)
return ret;
}
-static int rk_vop_bind(struct udevice *dev)
+int rk_vop_bind(struct udevice *dev)
{
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
- plat->size = 1920 * 1200 * 4;
+ plat->size = 4 * (CONFIG_VIDEO_ROCKCHIP_MAX_XRES *
+ CONFIG_VIDEO_ROCKCHIP_MAX_YRES);
return 0;
}
-
-static const struct video_ops rk_vop_ops = {
-};
-
-static const struct udevice_id rk_vop_ids[] = {
- { .compatible = "rockchip,rk3399-vop-big" },
- { .compatible = "rockchip,rk3399-vop-lit" },
- { .compatible = "rockchip,rk3288-vop" },
- { }
-};
-
-U_BOOT_DRIVER(rk_vop) = {
- .name = "rk_vop",
- .id = UCLASS_VIDEO,
- .of_match = rk_vop_ids,
- .ops = &rk_vop_ops,
- .bind = rk_vop_bind,
- .probe = rk_vop_probe,
- .priv_auto_alloc_size = sizeof(struct rk_vop_priv),
-};
diff --git a/drivers/video/rockchip/rk_vop.h b/drivers/video/rockchip/rk_vop.h
new file mode 100644
index 0000000000..b2b29c452a
--- /dev/null
+++ b/drivers/video/rockchip/rk_vop.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __RK_VOP_H__
+#define __RK_VOP_H__
+
+#include <asm/arch/vop_rk3288.h>
+
+struct rk_vop_priv {
+ void *grf;
+ void *regs;
+};
+
+enum vop_features {
+ VOP_FEATURE_OUTPUT_10BIT = (1 << 0),
+};
+
+struct rkvop_driverdata {
+ /* configuration */
+ u32 features;
+ /* block-specific setters/getters */
+ void (*set_pin_polarity)(struct udevice *, enum vop_modes, u32);
+};
+
+/**
+ * rk_vop_probe() - common probe implementation
+ *
+ * Performs the rk_display_init on each port-subnode until finding a
+ * working port (or returning an error if none of the ports could be
+ * successfully initialised).
+ *
+ * @dev: device
+ * @return 0 if OK, -ve if something went wrong
+ */
+int rk_vop_probe(struct udevice *dev);
+
+/**
+ * rk_vop_bind() - common bind implementation
+ *
+ * Sets the plat->size field to the amount of memory to be reserved for
+ * the framebuffer: this is always
+ * (32 BPP) x VIDEO_ROCKCHIP_MAX_XRES x VIDEO_ROCKCHIP_MAX_YRES
+ *
+ * @dev: device
+ * @return 0 (always OK)
+ */
+int rk_vop_bind(struct udevice *dev);
+
+/**
+ * rk_vop_probe_regulators() - probe (autoset + enable) regulators
+ *
+ * Probes a list of regulators by performing autoset and enable
+ * operations on them. The list of regulators is an array of string
+ * pointers and any individual regulator-probe may fail without
+ * counting as an error.
+ *
+ * @dev: device
+ * @names: array of string-pointers to regulator names to probe
+ * @cnt: number of elements in the 'names' array
+ */
+void rk_vop_probe_regulators(struct udevice *dev,
+ const char * const *names, int cnt);
+
+#endif
diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c
index cafaae5f31..a468bd96ad 100644
--- a/drivers/video/sm501.c
+++ b/drivers/video/sm501.c
@@ -16,6 +16,7 @@
#include <common.h>
#include <asm/io.h>
+#include <pci.h>
#include <video_fb.h>
#include <sm501.h>
diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile
index dbaab61b59..0d64c2021f 100644
--- a/drivers/video/sunxi/Makefile
+++ b/drivers/video/sunxi/Makefile
@@ -5,5 +5,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve.o ../videomodes.o
+obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve_common.o ../videomodes.o
obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o
diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c
index 9a32c3a020..ee67764ac5 100644
--- a/drivers/video/sunxi/sunxi_de2.c
+++ b/drivers/video/sunxi/sunxi_de2.c
@@ -56,7 +56,7 @@ static void sunxi_de2_composer_init(void)
}
static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
- int bpp, ulong address)
+ int bpp, ulong address, bool is_composite)
{
ulong de_mux_base = (mux == 0) ?
SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE;
@@ -72,6 +72,9 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
(struct de_ui *)(de_mux_base +
SUNXI_DE2_MUX_CHAN_REGS +
SUNXI_DE2_MUX_CHAN_SZ * 1);
+ struct de_csc * const de_csc_regs =
+ (struct de_csc *)(de_mux_base +
+ SUNXI_DE2_MUX_DCSC_REGS);
u32 size = SUNXI_DE2_WH(mode->hactive.typ, mode->vactive.typ);
int channel;
u32 format;
@@ -128,7 +131,27 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
writel(0, de_mux_base + SUNXI_DE2_MUX_PEAK_REGS);
writel(0, de_mux_base + SUNXI_DE2_MUX_ASE_REGS);
writel(0, de_mux_base + SUNXI_DE2_MUX_FCC_REGS);
- writel(0, de_mux_base + SUNXI_DE2_MUX_DCSC_REGS);
+
+ if (is_composite) {
+ /* set CSC coefficients */
+ writel(0x107, &de_csc_regs->coef11);
+ writel(0x204, &de_csc_regs->coef12);
+ writel(0x64, &de_csc_regs->coef13);
+ writel(0x4200, &de_csc_regs->coef14);
+ writel(0x1f68, &de_csc_regs->coef21);
+ writel(0x1ed6, &de_csc_regs->coef22);
+ writel(0x1c2, &de_csc_regs->coef23);
+ writel(0x20200, &de_csc_regs->coef24);
+ writel(0x1c2, &de_csc_regs->coef31);
+ writel(0x1e87, &de_csc_regs->coef32);
+ writel(0x1fb7, &de_csc_regs->coef33);
+ writel(0x20200, &de_csc_regs->coef34);
+
+ /* enable CSC unit */
+ writel(1, &de_csc_regs->csc_ctl);
+ } else {
+ writel(0, &de_csc_regs->csc_ctl);
+ }
switch (bpp) {
case 16:
@@ -153,7 +176,7 @@ static void sunxi_de2_mode_set(int mux, const struct display_timing *mode,
static int sunxi_de2_init(struct udevice *dev, ulong fbbase,
enum video_log2_bpp l2bpp,
- struct udevice *disp, int mux)
+ struct udevice *disp, int mux, bool is_composite)
{
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
struct display_timing timing;
@@ -183,7 +206,7 @@ static int sunxi_de2_init(struct udevice *dev, ulong fbbase,
}
sunxi_de2_composer_init();
- sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase);
+ sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase, is_composite);
ret = display_enable(disp, 1 << l2bpp, &timing);
if (ret) {
@@ -204,7 +227,6 @@ static int sunxi_de2_probe(struct udevice *dev)
struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
struct udevice *disp;
int ret;
- int mux;
/* Before relocation we don't need to do anything */
if (!(gd->flags & GD_FLG_RELOC))
@@ -212,17 +234,31 @@ static int sunxi_de2_probe(struct udevice *dev)
ret = uclass_find_device_by_name(UCLASS_DISPLAY,
"sunxi_dw_hdmi", &disp);
+ if (!ret) {
+ int mux;
+ if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
+ mux = 0;
+ else
+ mux = 1;
+
+ ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux,
+ false);
+ if (!ret) {
+ video_set_flush_dcache(dev, 1);
+ return 0;
+ }
+ }
+
+ debug("%s: hdmi display not found (ret=%d)\n", __func__, ret);
+
+ ret = uclass_find_device_by_name(UCLASS_DISPLAY,
+ "sunxi_tve", &disp);
if (ret) {
- debug("%s: hdmi display not found (ret=%d)\n", __func__, ret);
+ debug("%s: tv not found (ret=%d)\n", __func__, ret);
return ret;
}
- if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
- mux = 0;
- else
- mux = 1;
-
- ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux);
+ ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, 1, true);
if (ret)
return ret;
diff --git a/drivers/video/sunxi/tve.c b/drivers/video/sunxi/tve_common.c
index adea78a69a..adea78a69a 100644
--- a/drivers/video/sunxi/tve.c
+++ b/drivers/video/sunxi/tve_common.c
diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
index 0ba3f2c2b4..ec62fc9e51 100644
--- a/drivers/video/tegra.c
+++ b/drivers/video/tegra.c
@@ -343,7 +343,7 @@ static int tegra_lcd_ofdata_to_platdata(struct udevice *dev)
int rgb;
int ret;
- priv->disp = (struct disp_ctlr *)dev_get_addr(dev);
+ priv->disp = (struct disp_ctlr *)devfdt_get_addr(dev);
if (!priv->disp) {
debug("%s: No display controller address\n", __func__);
return -EINVAL;
diff --git a/drivers/video/tegra124/dp.c b/drivers/video/tegra124/dp.c
index 5bf8524a5e..c38b3e5335 100644
--- a/drivers/video/tegra124/dp.c
+++ b/drivers/video/tegra124/dp.c
@@ -1572,7 +1572,7 @@ static int tegra_dp_ofdata_to_platdata(struct udevice *dev)
{
struct tegra_dp_plat *plat = dev_get_platdata(dev);
- plat->base = dev_get_addr(dev);
+ plat->base = devfdt_get_addr(dev);
return 0;
}
diff --git a/drivers/video/tegra124/sor.c b/drivers/video/tegra124/sor.c
index 5e4140ff53..4324071cdc 100644
--- a/drivers/video/tegra124/sor.c
+++ b/drivers/video/tegra124/sor.c
@@ -466,11 +466,20 @@ void tegra_dc_sor_set_lane_count(struct udevice *dev, u8 lane_count)
static int tegra_dc_sor_power_up(struct udevice *dev, int is_lvds)
{
struct tegra_dc_sor_data *sor = dev_get_priv(dev);
+ u32 reg;
int ret;
if (sor->power_is_up)
return 0;
+ /*
+ * If for some reason it is already powered up, don't do it again.
+ * This can happen if U-Boot is the secondary boot loader.
+ */
+ reg = tegra_sor_readl(sor, DP_PADCTL(sor->portnum));
+ if (reg & DP_PADCTL_PD_TXD_0_NO)
+ return 0;
+
/* Set link bw */
tegra_dc_sor_set_link_bandwidth(dev, is_lvds ?
CLK_CNTRL_DP_LINK_SPEED_LVDS :
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 22a7c4f801..b911233db3 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -54,4 +54,12 @@ config WDT_ASPEED
It currently does not support Boot Flash Addressing Mode Detection or
Second Boot.
+config WDT_BCM6345
+ bool "BCM6345 watchdog timer support"
+ depends on WDT && ARCH_BMIPS
+ help
+ Select this to enable watchdog timer for BCM6345 SoCs.
+ The watchdog timer is stopped when initialized.
+ It performs full SoC reset.
+
endmenu
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 8378601b33..4b19e4ccf6 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -18,4 +18,5 @@ obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o
obj-$(CONFIG_WDT) += wdt-uclass.o
obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
+obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c
index b2bd912ad5..aab077e3d1 100644
--- a/drivers/watchdog/ast_wdt.c
+++ b/drivers/watchdog/ast_wdt.c
@@ -84,7 +84,7 @@ static int ast_wdt_ofdata_to_platdata(struct udevice *dev)
{
struct ast_wdt_priv *priv = dev_get_priv(dev);
- priv->regs = dev_get_addr_ptr(dev);
+ priv->regs = devfdt_get_addr_ptr(dev);
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
diff --git a/drivers/watchdog/bcm6345_wdt.c b/drivers/watchdog/bcm6345_wdt.c
new file mode 100644
index 0000000000..3ef7d438a6
--- /dev/null
+++ b/drivers/watchdog/bcm6345_wdt.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Derived from linux/drivers/watchdog/bcm63xx_wdt.c:
+ * Copyright (C) 2007 Miguel Gaio <miguel.gaio@efixo.com>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <asm/io.h>
+
+/* WDT Value register */
+#define WDT_VAL_REG 0x0
+#define WDT_VAL_MIN 0x00000002
+#define WDT_VAL_MAX 0xfffffffe
+
+/* WDT Control register */
+#define WDT_CTL_REG 0x4
+#define WDT_CTL_START1_MASK 0x0000ff00
+#define WDT_CTL_START2_MASK 0x000000ff
+#define WDT_CTL_STOP1_MASK 0x0000ee00
+#define WDT_CTL_STOP2_MASK 0x000000ee
+
+struct bcm6345_wdt_priv {
+ void __iomem *regs;
+};
+
+static int bcm6345_wdt_reset(struct udevice *dev)
+{
+ struct bcm6345_wdt_priv *priv = dev_get_priv(dev);
+
+ writel_be(WDT_CTL_START1_MASK, priv->regs + WDT_CTL_REG);
+ writel_be(WDT_CTL_START2_MASK, priv->regs + WDT_CTL_REG);
+
+ return 0;
+}
+
+static int bcm6345_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+ struct bcm6345_wdt_priv *priv = dev_get_priv(dev);
+
+ if (timeout < WDT_VAL_MIN) {
+ debug("watchdog won't fire with less than 2 ticks\n");
+ timeout = WDT_VAL_MIN;
+ } else if (timeout > WDT_VAL_MAX) {
+ debug("maximum watchdog timeout exceeded\n");
+ timeout = WDT_VAL_MAX;
+ }
+
+ writel_be(timeout, priv->regs + WDT_VAL_REG);
+
+ return bcm6345_wdt_reset(dev);
+}
+
+static int bcm6345_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ return bcm6345_wdt_start(dev, WDT_VAL_MIN, flags);
+}
+
+static int bcm6345_wdt_stop(struct udevice *dev)
+{
+ struct bcm6345_wdt_priv *priv = dev_get_priv(dev);
+
+ writel_be(WDT_CTL_STOP1_MASK, priv->regs + WDT_CTL_REG);
+ writel_be(WDT_CTL_STOP2_MASK, priv->regs + WDT_CTL_REG);
+
+ return 0;
+}
+
+static const struct wdt_ops bcm6345_wdt_ops = {
+ .expire_now = bcm6345_wdt_expire_now,
+ .reset = bcm6345_wdt_reset,
+ .start = bcm6345_wdt_start,
+ .stop = bcm6345_wdt_stop,
+};
+
+static const struct udevice_id bcm6345_wdt_ids[] = {
+ { .compatible = "brcm,bcm6345-wdt" },
+ { /* sentinel */ }
+};
+
+static int bcm6345_wdt_probe(struct udevice *dev)
+{
+ struct bcm6345_wdt_priv *priv = dev_get_priv(dev);
+ fdt_addr_t addr;
+ fdt_size_t size;
+
+ addr = devfdt_get_addr_size_index(dev, 0, &size);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->regs = ioremap(addr, size);
+
+ bcm6345_wdt_stop(dev);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(wdt_bcm6345) = {
+ .name = "wdt_bcm6345",
+ .id = UCLASS_WDT,
+ .of_match = bcm6345_wdt_ids,
+ .ops = &bcm6345_wdt_ops,
+ .priv_auto_alloc_size = sizeof(struct bcm6345_wdt_priv),
+ .probe = bcm6345_wdt_probe,
+};